Skip to content
This repository has been archived by the owner on Jul 13, 2022. It is now read-only.
/ xpring4j Public archive

Xpring4j has been deprecated. Instead, use xrpl4j

License

Notifications You must be signed in to change notification settings

xpring-eng/xpring4j

Repository files navigation

This library has been deprecated. Instead, use xrpl4j.

Xpring4j is the Java client-side library of Xpring SDK.

Features

Xpring4j provides the following features:

  • XRP:
    • Wallet generation and derivation (Seed-based or HD Wallet-based)
    • Address validation
    • Account balance retrieval
    • Sending XRP payments
    • Retrieval of payment transactions and account payment history
    • Enabling of Deposit Authorization for an XRPL account
  • Interledger (ILP):
    • Account balance retrieval
    • Send ILP Payments

Installation

Client-Side Library

Xpring4j is available as a Java library from Maven Central. Simply add the following to your pom.xml:

<dependency>
  <groupId>io.xpring</groupId>
  <artifactId>xpring4j</artifactId>
  <version>LATEST</version>
</dependency>

rippled Node

Xpring SDK needs to communicate with a rippled node which has gRPC enabled. Consult the rippled documentation for details on how to build your own node.

To get developers started right away, Xpring currently provides nodes:

# Testnet
test.xrp.xpring.io:50051

# Mainnet
main.xrp.xpring.io:50051

Hermes Node

Xpring SDK's IlpClient needs to communicate with Xpring's ILP infrastructure through an instance of Hermes.

In order to connect to the Hermes instance that Xpring currently operates, you will need to create an ILP wallet here

Once your wallet has been created, you can use the gRPC URL specified in your wallet, as well as your access token to check your balance and send payments over ILP.

Usage: XRP

Note: Xpring SDK only works with the X-Address format. For more information about this format, see the Utilities section and http://xrpaddress.info.

Wallets

A wallet is a fundamental model object in Xpring4j. A wallet provides:

  • key management
  • address derivation
  • signing functionality

Wallets can be derived from either a seed or a mnemonic and derivation path. You can also generate a new random HD wallet.

Wallet Derivation

Xpring4j can derive a wallet from a seed or it can derive a hierarchical deterministic wallet (HD Wallet) from a mnemonic and derivation path.

Hierarchical Deterministic Wallets

A hierarchical deterministic wallet is created using a mnemonic and a derivation path. Simply pass the mnemonic and derivation path to the wallet generation function. Note that you can pass null for the derivation path and have a default path be used instead.

import io.xpring.xrpl.Wallet;

String mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";

Wallet hdWallet1 = new Wallet(mnemonic, null); // Has default derivation path
Wallet hdWallet2 = new Wallet(mnemonic, Wallet.getDefaultDerivationPath()); // Same as hdWallet1

Wallet hdWallet = new Wallet(mnemonic, "m/44'/144'/0'/0/1"); // Wallet with custom derivation path.
Seed-Based Wallets

You can construct a seed based wallet by passing a base58check encoded seed string.

import io.xpring.xrpl.Wallet;

Wallet seedWallet = new Wallet("snRiAJGeKCkPVddbjB3zRwwoiYDBm1M");

Wallet Generation

Xpring4j can generate a new and random HD Wallet. The result of a wallet generation call is a tuple which contains the following:

  • A randomly generated mnemonic
  • The derivation path used, which is the default path
  • A reference to the new wallet
import io.xpring.xrpl.Wallet;

// Generate a random wallet.
WalletGenerationResult generationResult = Wallet.generateRandomWallet();
Wallet newWallet = generationResult.getWallet();

// Wallet can be recreated with the artifacts of the initial generation.
Wallet copyOfNewWallet = new Wallet(generationResult.getMnemonic(), generationResult.getDerivationPath());

Wallet Properties

A generated wallet can provide its public key, private key, and address on the XRP ledger.

import io.xpring.xrpl.Wallet;

String mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";

Wallet wallet = new Wallet(mnemonic, null);

System.out.println(wallet.getAddress()); // XVMFQQBMhdouRqhPMuawgBMN1AVFTofPAdRsXG5RkPtUPNQ
System.out.println(wallet.getPublicKey()); // 031D68BC1A142E6766B2BDFB006CCFE135EF2E0E2E94ABB5CF5C9AB6104776FBAE
System.out.println(wallet.getPrivateKey()); // 0090802A50AA84EFB6CDB225F17C27616EA94048C179142FECF03F4712A07EA7A4

Signing / Verifying

A wallet can also sign and verify arbitrary hex messages. Generally, users should use the functions on XrpClient to perform cryptographic functions rather than using these low level APIs.

import io.xpring.xrpl.Wallet;

String mnemonic = "abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";
String message = "deadbeef";

Wallet wallet = new Wallet(mnemonic, null);

String signature = wallet.sign(message);
wallet.verify(message, signature); // true

XrpClient

XrpClient is a gateway into the XRP Ledger. XrpClient is initialized with a two parameters:

  • The URL of the gRPC API on the remote rippled node
  • An enum representing the XRPL Network the remote rippled node is attached to
String grpcURL = "test.xrp.xpring.io:50051"; // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
XrpClient xrpClient = new XrpClient(grpcURL, XrplNetwork.TEST);

Retrieving a Balance

An XrpClient can check the balance of an account on the XRP Ledger.

import io.xpring.common.idiomatic.XrplLNetwork;

String grpcURL = "test.xrp.xpring.io:50051"; // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
XrpClient xrpClient = new XrpClient(grpcURL, XrplNetwork.TEST);

String address = "XVMFQQBMhdouRqhPMuawgBMN1AVFTofPAdRsXG5RkPtUPNQ";
BigInteger balance = xrpClient.getBalance(address);
System.out.println(balance); // Logs a balance in drops of XRP

Checking Transaction Status

A XrpClient can check the status of a payment on the XRP Ledger.

This method can only determine the status of payment transactions which do not have the partial payment flag (tfPartialPayment) set.

Xpring4J returns the following transaction states:

  • SUCCEEDED: The transaction was successfully validated and applied to the XRP Ledger.
  • FAILED: The transaction was successfully validated but not applied to the XRP Ledger. Or the operation will never be validated.
  • PENDING: The transaction has not yet been validated, but may be validated in the future.
  • UNKNOWN: The transaction status could not be determined, the hash represented a non-payment type transaction, or the hash represented a transaction with the tfPartialPayment flag set.

Note: For more information, see Reliable Transaction Submission and Transaction Results.

These states are determined by the TransactionStatus enum.

String grpcURL = "test.xrp.xpring.io:50051"; // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
XrpClient xrpClient = new XrpClient(grpcURL, XrplNetwork.TEST);

String transactionHash = "9FC7D277C1C8ED9CE133CC17AEA9978E71FC644CE6F5F0C8E26F1C635D97AF4A";
TransactionStatus transactionStatus = xrpClient.getPaymentStatus(transactionHash); // TransactionStatus.SUCCEEDED

Note: The example transactionHash may lead to a "Transaction not found." error because the Testnet is regularly reset, or the accessed node may only maintain one month of history. Recent transaction hashes can be found in the XRP Ledger Explorer

Retrieve specific payment

An XRPClient can return a specific payment transaction identified by hash.

String remoteURL = "test.xrp.xpring.io:50051"; // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
XRPClient xrpClient = new XRPClient(remoteURL, XRPLNetwork.TEST);
XRPTransaction payment = xrpClient.getPayment(transactionHash);

Note: The example transactionHash may lead to a "Transaction not found." error because the Testnet is regularly reset, or the accessed node may only maintain one month of history. Recent transaction hashes can be found in the XRP Ledger Explorer

Payment history

An XrpClient can return a list of payments to and from an account.

String remoteURL = "test.xrp.xpring.io:50051"; // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
XrpClient xrpClient = new XrpClient(remoteURL, XrplNetwork.TEST);
String address = "XVMFQQBMhdouRqhPMuawgBMN1AVFTofPAdRsXG5RkPtUPNQ";
List<XrpTransaction> paymentHistory = xrpClient.paymentHistory(address);

Sending XRP

An XrpClient can send XRP to other accounts on the XRP Ledger.

Note: The payment operation will block the calling thread until the operation reaches a definitive and irreversible success or failure state.

String grpcURL = "test.xrp.xpring.io:50051"; // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
XrpClient xrpClient = new XrpClient(grpcURL, XrplNetwork.TEST);

// Amount of XRP to send.
BigInteger amount = new BigInteger("1");

// Wallet to send from.
WalletGenerationResult walletGenerationResult = Wallet.generateRandomWallet();
Wallet wallet = walletGenerationResult.getWallet();

// Destination address.
String destinationAddress = "XVMFQQBMhdouRqhPMuawgBMN1AVFTofPAdRsXG5RkPtUPNQ";

String transactionHash = xrpClient.send(amount, destinationAddress, wallet);

Note: The above example will yield an "Account not found." error because the randomly generated wallet contains no XRP.

Enabling Deposit Authorization

String grpcURL = "test.xrp.xpring.io:50051"; // Testnet URL, use main.xrp.xpring.io:50051 for Mainnet
XrpClient xrpClient = new XrpClient(grpcURL, XrplNetwork.TEST);

// Wallet for which to enable Deposit Authorization
Wallet seedWallet = new Wallet("snRiAJGeKCkPVddbjB3zRwwoiYDBm1M");

TransactionResult transactionResult = xrpClient.enableDepositAuth(seedWallet);
String transactionHash = transactionResult.hash();
TransactionStatus transactionStatus = transactionResult.status();
Boolean validated = transactionResult.validated();

Utilities

Address validation

The Utils object provides an easy way to validate addresses.

import io.xpring.xrpl.Utils;

String rippleClassicAddress = "rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G";
String rippleXAddress = "X7jjQ4d6bz1qmjwxYUsw6gtxSyjYv5iWPqPEjGqqhn9Woti";
String bitcoinAddress = "1DiqLtKZZviDxccRpowkhVowsbLSNQWBE8";

Utils.isValidAddress(rippleClassicAddress); // returns true
Utils.isValidAddress(rippleXAddress); // returns true
Utils.isValidAddress(bitcoinAddress); // returns false

You can also validate if an address is an X-Address or a classic address.

import io.xpring.xrpl.Utils;

String rippleClassicAddress = "rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G";
String rippleXAddress = "X7jjQ4d6bz1qmjwxYUsw6gtxSyjYv5iWPqPEjGqqhn9Woti";
String bitcoinAddress = "1DiqLtKZZviDxccRpowkhVowsbLSNQWBE8";

Utils.isValidXAddress(rippleClassicAddress); // returns false
Utils.isValidXAddress(rippleXAddress); // returns true
Utils.isValidXAddress(bitcoinAddress); // returns false

Utils.isValidClassicAddress(rippleClassicAddress); // returns true
Utils.isValidClassicAddress(rippleXAddress); // returns false
Utils.isValidClassicAddress(bitcoinAddress); // returns false

X-Address Encoding

You can encode and decode X-Addresses with the SDK.

import io.xpring.xrpl.Utils;

String rippleClassicAddress = "rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G"
ClassicAddress classicAddress = ImmutableClassicAddress.builder()
  .address("rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G")
  .tag(12345)
  .build();

// Encode an X-Address.
String xAddress = Utils.encodeXAddress(rippleClassicAddress); // X7jjQ4d6bz1qmjwxYUsw6gtxSyjYv5xRB7JM3ht8XC4P45P

// Decode an X-Address.
ClassicAddressdecodedClassicAddress = Utils.decodeXAddress(xAddress);
System.out.println(decodedClassicAddress.address()); // rnysDDrRXxz9z66DmCmfWpq4Z5s4TyUP3G
System.out.println(decodedClassicAddress.tag()); // 12345

Usage: PayID

Two classes are used to work with PayID: PayIDClient and XRPPayIDClient.

PayIDClient

PayIdClient can resolve addresses on arbitrary cryptocurrency networks.

// Resolve on Bitcoin Testnet.

PayIdClient payIdClient = new PayIdClient();
String payId = "georgewashington$xpring.money";
String btcNetwork = "btc-testnet";

CryptoAddressDetails btcAddressComponents = payIdClient.cryptoAddressForPayId(payId, btcNetwork);
System.out.println("Resolved to " + btcAddressComponents.getAddress());

Resolving All Addresses

PayIdClient can resolve all addresses associated with a PayID.

PayIdClient payIdClient = new PayIdClient();
String payId = "georgewashington$xpring.money";

List<Address> allAddress = payIdClient.allAddressesForPayId(payId);

XRPPayIDClient

XRPPayIDClient can resolve addresses on the XRP Ledger network. The class always coerces returned addresses into an X-Address. (See https://xrpaddress.info/)

XRPLNetwork xrpNetwork = XRPLNetwork.MAIN;

XRPPayIDClient xrpPayIdClient = new XRPPayIDClient(xrpNetwork);
String xrpAddress = xrpPayIdClient.xrpAddressForPayID(payId);

Usage: ILP

IlpClient

IlpClient is the main interface into the ILP network. IlpClient must be initialized with the URL of a Hermes instance. This can be found in your wallet.

All calls to IlpClient must pass an access token, which can be generated in your wallet.

import io.xpring.ilp.IlpClient;

String grpcUrl = "prod.grpcng.wallet.xpring.io"; // Testnet ILP Wallet URL
IlpClient ilpClient = new IlpClient(grpcUrl);

Retrieving a Balance

An IlpClient can check the balance of an account on a connector.

import io.xpring.ilp.IlpClient;
import io.xpring.ilp.model.AccountBalance;

String grpcUrl = "prod.grpcng.wallet.xpring.io"; // Testnet ILP Wallet URL
IlpClient ilpClient = new IlpClient(grpcUrl);

AccountBalance balance = ilpClient.getBalance("demo_user", "2S1PZh3fEKnKg"); // Just a demo user on Testnet
System.out.println("Net balance was " + balance.netBalance() + " with asset scale " + balance.assetScale());

Sending a Payment

An IlpClient can send an ILP payment to another ILP address by supplying a Payment Pointer and a sender's account ID

import io.xpring.ilp.IlpClient;
import io.xpring.ilp.model.PaymentRequest;
import io.xpring.ilp.model.PaymentResponse;

String grpcUrl = "prod.grpcng.wallet.xpring.io"; // Testnet ILP Wallet URL
IlpClient ilpClient = new IlpClient(grpcUrl);

PaymentRequest paymentRequest = PaymentRequest.builder()
  .amount(amountToSend)
  .destinationPaymentPointer("$xpring.money/demo_receiver")
  .senderAccountId("demo_user")
  .build();

PaymentResponse payment = ilpClient.sendPayment(paymentRequest, "2S1PZh3fEKnKg");

Usage: Xpring

Xpring components compose PayID and XRP components to make complex interactions easy.

// The expected address of the gRPC server.
String grpcURL = "test.xrp.xpring.io:50051";

// A wallet with funds on testnet.
Wallet wallet = new Wallet("snYP7oArxKepd3GPDcrjMsJYiJeJB", true);

// The number of drops to send.
BigInteger dropsToSend = BigInteger.valueOf(10);

// The Pay ID to resolve.
String payID = "georgewashington$xpring.money";

// The network to resolve on.
XRPLNetwork network = XRPLNetwork.TEST;

XRPClient xrpClient = new XRPClient(grpcURL, network);
XRPPayIDClient payIdClient = new XRPPayIDClient(network);
XpringClient xpringClient = new XpringClient(payIdClient, xrpClient);

String hash = xpringClient.send(dropsToSend, payID, wallet);