convert existing xrpl library into a lerna monorepo

This commit is contained in:
Greg Weisbrod
2021-11-04 23:18:23 -04:00
parent 9647145150
commit 2b42427634
500 changed files with 24357 additions and 10294 deletions

View File

@@ -0,0 +1,74 @@
import {
AccountObjectsRequest,
Client,
PaymentChannelCreate,
PaymentChannelClaim,
hashes,
} from '../../dist/npm'
const client = new Client('wss://s.altnet.rippletest.net:51233')
void claimPayChannel()
// The snippet walks us through creating and claiming a Payment Channel.
async function claimPayChannel(): Promise<void> {
await client.connect()
// creating wallets as prerequisite
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
console.log('Balances of wallets before Payment Channel is claimed:')
console.log(await client.getXrpBalance(wallet1.classicAddress))
console.log(await client.getXrpBalance(wallet2.classicAddress))
// create a Payment Channel and submit and wait for tx to be validated
const paymentChannelCreate: PaymentChannelCreate = {
TransactionType: 'PaymentChannelCreate',
Account: wallet1.classicAddress,
Amount: '100',
Destination: wallet2.classicAddress,
SettleDelay: 86400,
PublicKey: wallet1.publicKey,
}
const paymentChannelResponse = await client.submitAndWait(
paymentChannelCreate,
{ wallet: wallet1 },
)
console.log(paymentChannelResponse)
// check that the object was actually created
const accountObjectsRequest: AccountObjectsRequest = {
command: 'account_objects',
account: wallet1.classicAddress,
}
const accountObjects = (await client.request(accountObjectsRequest)).result
.account_objects
console.log(accountObjects)
// destination claims the Payment Channel and we see the balances to verify.
const paymentChannelClaim: PaymentChannelClaim = {
Account: wallet2.classicAddress,
TransactionType: 'PaymentChannelClaim',
Channel: hashes.hashPaymentChannel(
wallet1.classicAddress,
wallet2.classicAddress,
paymentChannelResponse.result.Sequence ?? 0,
),
Amount: '100',
}
const channelClaimResponse = await client.submit(paymentChannelClaim, {
wallet: wallet1,
})
console.log(channelClaimResponse)
console.log('Balances of wallets after Payment Channel is claimed:')
console.log(await client.getXrpBalance(wallet1.classicAddress))
console.log(await client.getXrpBalance(wallet2.classicAddress))
await client.disconnect()
}

View File

@@ -0,0 +1,39 @@
import { Client, LedgerResponse, TxResponse } from '../../dist/npm'
const client = new Client('wss://s.altnet.rippletest.net:51233')
async function getTransaction(): Promise<void> {
await client.connect()
const ledger: LedgerResponse = await client.request({
command: 'ledger',
transactions: true,
ledger_index: 'validated',
})
console.log(ledger)
const transactions = ledger.result.ledger.transactions
if (transactions) {
const tx: TxResponse = await client.request({
command: 'tx',
transaction: transactions[0],
})
console.log(tx)
// The meta field would be a string(hex) when the `binary` parameter is `true` for the `tx` request.
if (tx.result.meta == null) {
throw new Error('meta not included in the response')
}
/*
* delivered_amount is the amount actually received by the destination account.
* Use this field to determine how much was delivered, regardless of whether the transaction is a partial payment.
* https://xrpl.org/transaction-metadata.html#delivered_amount
*/
if (typeof tx.result.meta !== 'string') {
console.log('delivered_amount:', tx.result.meta.delivered_amount)
}
}
await client.disconnect()
}
void getTransaction()

View File

@@ -0,0 +1,91 @@
import { Client, Payment, PaymentFlags, TrustSet } from '../../dist/npm'
const client = new Client('wss://s.altnet.rippletest.net:51233')
// This snippet walks us through partial payment.
async function partialPayment(): Promise<void> {
await client.connect()
// creating wallets as prerequisite
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
// create a trustline to issue an IOU `FOO` and set limit on it.
const trust_set_tx: TrustSet = {
TransactionType: 'TrustSet',
Account: wallet2.classicAddress,
LimitAmount: {
currency: 'FOO',
issuer: wallet1.classicAddress,
// Value for the new IOU - 10000000000 - is arbitarily chosen.
value: '10000000000',
},
}
await client.submitAndWait(trust_set_tx, {
wallet: wallet2,
})
console.log('Balances after trustline is created')
console.log(await client.getBalances(wallet1.classicAddress))
console.log(await client.getBalances(wallet2.classicAddress))
// Initially, the issuer(wallet1) sends an amount to the other account(wallet2)
const issue_quantity = '3840'
const payment: Payment = {
TransactionType: 'Payment',
Account: wallet1.classicAddress,
Amount: {
currency: 'FOO',
value: issue_quantity,
issuer: wallet1.classicAddress,
},
Destination: wallet2.classicAddress,
}
// submit payment
const initialPayment = await client.submitAndWait(payment, {
wallet: wallet1,
})
console.log(initialPayment)
console.log('Balances after issuer(wallet1) sends IOU("FOO") to wallet2')
console.log(await client.getBalances(wallet1.classicAddress))
console.log(await client.getBalances(wallet2.classicAddress))
/*
* Send money less than the amount specified on 2 conditions:
* 1. Sender has less money than the aamount specified in the payment Tx.
* 2. Sender has the tfPartialPayment flag activated.
*
* Other ways to specify flags are by using Hex code and decimal code.
* eg. For partial payment(tfPartialPayment)
* decimal ->131072, hex -> 0x00020000
*/
const partialPaymentTx: Payment = {
TransactionType: 'Payment',
Account: wallet2.classicAddress,
Amount: {
currency: 'FOO',
value: '4000',
issuer: wallet1.classicAddress,
},
Destination: wallet1.classicAddress,
Flags: PaymentFlags.tfPartialPayment,
}
// submit payment
const submitResponse = await client.submitAndWait(partialPaymentTx, {
wallet: wallet2,
})
console.log(submitResponse)
console.log(
"Balances after Partial Payment, when wallet2 tried to send 4000 FOO's",
)
console.log(await client.getBalances(wallet1.classicAddress))
console.log(await client.getBalances(wallet2.classicAddress))
await client.disconnect()
}
void partialPayment()

View File

@@ -0,0 +1,49 @@
import { Client, Payment, RipplePathFindResponse } from '../../dist/npm'
const client = new Client('wss://s.altnet.rippletest.net:51233')
async function createTxWithPaths(): Promise<void> {
await client.connect()
const { wallet } = await client.fundWallet()
const destination_account = 'rKT4JX4cCof6LcDYRz8o3rGRu7qxzZ2Zwj'
const destination_amount = {
value: '0.001',
currency: 'USD',
issuer: 'rVnYNK9yuxBz4uP8zC8LEFokM2nqH3poc',
}
const request = {
command: 'ripple_path_find',
source_account: wallet.classicAddress,
source_currencies: [
{
currency: 'XRP',
},
],
destination_account,
destination_amount,
}
const resp: RipplePathFindResponse = await client.request(request)
console.log(resp)
const paths = resp.result.alternatives[0].paths_computed
console.log(paths)
const tx: Payment = {
TransactionType: 'Payment',
Account: wallet.classicAddress,
Amount: destination_amount,
Destination: destination_account,
Paths: paths,
}
await client.autofill(tx)
const signed = wallet.sign(tx)
console.log('signed:', signed)
await client.disconnect()
}
void createTxWithPaths()

View File

@@ -0,0 +1,83 @@
import { Client, Payment } from '../../dist/npm'
/**
* When implementing Reliable Transaction Submission, there are many potential solutions, each with different trade-offs.
* The main decision points are:
* 1) Transaction preparation:
* - The autofill function as a part of the submitAndWait should be able to correctly populate
* values for the fields Sequence, LastLedgerSequence and Fee.
* 2) Transaction status retrieval. Options include:
* - Poll for transaction status:
* - On a regular interval (e.g. Every 3-5 seconds), or
* - When a new validated ledger is detected
* + (To accommodate an edge case in transaction retrieval,
* check the sending account's Sequence number to confirm that it has the expected value;
* alternatively, wait until a few additional ledgers have been validated before deciding that a
* transaction has definitively not been included in a validated ledger)
* - Listen for transaction status: scan all validated transactions to see if our transactions are among them
* 3) What do we do when a transaction fails? It is possible to implement retry logic, but caution is advised.
* Note that there are a few ways for a transaction to fail:
* A) `tec`: The transaction was included in a ledger but only claimed the transaction fee
* B) `tesSUCCESS` but unexpected result: The transaction was successful but did not have the expected result.
* This generally does not occur for XRP-to-XRP payments
* C) The transaction was not, and never will be, included in a validated ledger [3C].
*
* References:
* - https://xrpl.org/reliable-transaction-submission.html
* - https://xrpl.org/send-xrp.html
* - https://xrpl.org/look-up-transaction-results.html
* - https://xrpl.org/monitor-incoming-payments-with-websocket.html.
*
* For the implementation in this example, we have made the following decisions:
* 1) We allow the autofill function as a part of submitAndWait to fill up the account sequence,
* LastLedgerSequence and Fee. Payments are defined upfront, and idempotency is not needed.
* If the script is run a second time, duplicate payments will result.
* 2) We will rely on the xrpl.js submitAndWait function to get us the transaction submission result after the wait time.
* 3) Transactions will not be automatically retried. Transactions are limited to XRP-to-XRP payments
* and cannot "succeed" in an unexpected way.
*/
const client = new Client('wss://s.altnet.rippletest.net:51233')
void sendReliableTx()
async function sendReliableTx(): Promise<void> {
await client.connect()
// creating wallets as prerequisite
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
console.log('Balances of wallets before Payment tx')
console.log(
await client.getXrpBalance(wallet1.classicAddress),
await client.getXrpBalance(wallet2.classicAddress),
)
// create a Payment tx and submit and wait for tx to be validated
const payment: Payment = {
TransactionType: 'Payment',
Account: wallet1.classicAddress,
Amount: '1000',
Destination: wallet2.classicAddress,
}
const paymentResponse = await client.submitAndWait(payment, {
wallet: wallet1,
})
console.log('\nTransaction was submitted.\n')
const txResponse = await client.request({
command: 'tx',
transaction: paymentResponse.result.hash,
})
// With the following reponse we are able to see that the tx was indeed validated.
console.log('Validated:', txResponse.result.validated)
console.log('Balances of wallets after Payment tx:')
console.log(
await client.getXrpBalance(wallet1.classicAddress),
await client.getXrpBalance(wallet2.classicAddress),
)
await client.disconnect()
}

View File

@@ -0,0 +1,77 @@
import {
AccountObjectsRequest,
Client,
EscrowCreate,
EscrowFinish,
isoTimeToRippleTime,
} from '../../dist/npm'
const client = new Client('wss://s.altnet.rippletest.net:51233')
void sendEscrow()
// The snippet walks us through creating and finishing escrows.
async function sendEscrow(): Promise<void> {
await client.connect()
// creating wallets as prerequisite
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
console.log('Balances of wallets before Escrow tx was created:')
console.log(
await client.getXrpBalance(wallet1.classicAddress),
await client.getXrpBalance(wallet2.classicAddress),
)
// finish 2 seconds after the escrow is actually created and tx is validated.
const finishAfter = isoTimeToRippleTime(Date()) + 2
// creating an Escrow using `EscrowCreate` and submit and wait for tx to be validated.
const createTx: EscrowCreate = {
TransactionType: 'EscrowCreate',
Account: wallet1.address,
Destination: wallet2.address,
Amount: '1000000',
FinishAfter: finishAfter,
}
const createEscrowResponse = await client.submitAndWait(createTx, {
wallet: wallet1,
})
console.log(createEscrowResponse)
// check that the object was actually created
const accountObjectsRequest: AccountObjectsRequest = {
command: 'account_objects',
account: wallet1.classicAddress,
}
const accountObjects = (await client.request(accountObjectsRequest)).result
.account_objects
console.log("Escrow object exists in `wallet1`'s account")
console.log(accountObjects)
// the creator finishes the Escrow using `EscrowFinish` to release the Escrow
const finishTx: EscrowFinish = {
TransactionType: 'EscrowFinish',
Account: wallet1.classicAddress,
Owner: wallet1.classicAddress,
OfferSequence: Number(createEscrowResponse.result.Sequence),
}
await client.submit(finishTx, {
wallet: wallet1,
})
// we see the balances to verify.
console.log('Balances of wallets after Escrow was sent')
console.log(
await client.getXrpBalance(wallet1.classicAddress),
await client.getXrpBalance(wallet2.classicAddress),
)
await client.disconnect()
}

View File

@@ -0,0 +1,54 @@
import { Client, Payment, SetRegularKey } from '../../dist/npm'
const client = new Client('wss://s.altnet.rippletest.net:51233')
/*
* The snippet walks us through an example usage of RegularKey.
* Later,
*/
async function setRegularKey(): Promise<void> {
await client.connect()
const { wallet: wallet1 } = await client.fundWallet()
const { wallet: wallet2 } = await client.fundWallet()
const { wallet: regularKeyWallet } = await client.fundWallet()
console.log('Balances before payment')
console.log(await client.getXrpBalance(wallet1.classicAddress))
console.log(await client.getXrpBalance(wallet2.classicAddress))
// assigns key-pair(regularKeyWallet) to wallet1 using `SetRegularKey`.
const tx: SetRegularKey = {
TransactionType: 'SetRegularKey',
Account: wallet1.classicAddress,
RegularKey: regularKeyWallet.classicAddress,
}
const response = await client.submitAndWait(tx, {
wallet: wallet1,
})
console.log('Response for successful SetRegularKey tx')
console.log(response)
/*
* when wallet1 sends payment to wallet2 and
* signs using the regular key wallet, the transaction goes through.
*/
const payment: Payment = {
TransactionType: 'Payment',
Account: wallet1.classicAddress,
Destination: wallet2.classicAddress,
Amount: '1000',
}
const submitTx = await client.submit(payment, {
wallet: wallet1,
})
console.log('Response for tx signed using Regular Key:')
console.log(submitTx)
console.log('Balances after payment:')
console.log(await client.getXrpBalance(wallet1.classicAddress))
console.log(await client.getXrpBalance(wallet2.classicAddress))
await client.disconnect()
}
void setRegularKey()

View File

@@ -0,0 +1,9 @@
{
"extends": "../tsconfig.build.json",
"compilerOptions": {
"outDir": "./dist",
},
"include": [
"./src/**/*.ts"
]
}