Files
xahau.js/packages/xrpl/snippets/src/bridgeTransfer.ts
Mayukha Vadari 91e7369f1b feat: add support for current sidechain design (#2039)
* Update definitions.json

* add new st types

* add tests

* add XChainClaim tx

* add XChainCommit tx

* add XChainCreateBridge tx

* add XChainCreateClaimID tx

* update definitions.json

* rename Bridge -> XChainBridge in binary codec, fix tests

* rename Bridge -> XChainBridge in models

* add codec support for XChainAddAttestation

* add XChainAddAttestation model

* undo debugging change

* fix linting issues

* update definitions.json for new rippled code, add new tests/update old tests

* add/update models

* update history

* update binary-codec

* add XChainModifyBridge model

* update RPCs

* update to latest rippled

* more fixes

* fix definitions.json

* fix spacing

* update definitions.json to avoid conflict with amm

* update definitions.json to resolve amm conflicts

* audit code

* more updates

* update rpcs

* switch to beta version

* add destination tag to XChainClaim

* rename IssuedCurrency -> Issue to match rippled

* update Issue form

* fix account object filters

* fix issue from typing

* fix LedgerEntry types

* fix attestation destination type

* Update definitions.json

* rename XChainAddAttestation -> XChainAddAttestationBatch

* add XChainAddClaimAttestation

* add XChainAddAccountCreateAttestation

* remove XChainAddAttestationBatch

* update definitions

* fix attestation txns

* fix attestation object

* add validate for new txs

* add Bridge ledger object

* add XChainOwnedClaimID ledger object

* add XChainOwnedCreateAccountClaimID ledger object

* update account_objects

* update models to latest rippled

* fix minor issues

* fix bridge ledger_entry

* add XChainModifyBridge flag

* Update definitions.json

* add rbc tests for the new txs

* update validateXChainModifyBridge

* add validate methods to other xchain txs

* fix isXChainBridge

* fix isIssue typing

* fix model types

* update changelog

* switch prepare to prepublishOnly

* add docs

* fix AccountObjectsType filter

* export common types

* fix account_objects filter

* update LedgerEntry

* add sidechain faucet info

* add snippet

* improve snippet

* fix spacing issues

* update ledger_entry

* remove AMMDelete tests for now

* Update definitions.json

* fix unit tests

* convert createValidate script to JS
* remove unneeded linter ignores

* respond to comments

* more snippet fixes

* make validate functions more readable

* add getXChainClaimID method to parse metadata

* re-add linter rules

* clean up common

* fix getXChainClaimID test

* return undefined for failed tx

* test: add model tests for new sidechain transactions (#2059)

* add XChainAddAttestation tests, fix model

* add XChainClaim model tests

* add XChainCommit model tests, fix typo

* add XChainCreateBridge model tests

* add XChainCreateClaimID model tests

* add XChainModifyBridge tests

* update to most recent version of code

* remove XChainAddAttestationBatch tests

* add more validation tests

* switch createValidateTests to JS
2023-09-26 10:01:21 -04:00

173 lines
5.2 KiB
TypeScript

/* eslint-disable max-depth -- needed for attestation checking */
/* eslint-disable @typescript-eslint/consistent-type-assertions -- needed here */
/* eslint-disable no-await-in-loop -- needed here */
import {
AccountObjectsRequest,
LedgerEntry,
Client,
XChainAccountCreateCommit,
XChainBridge,
XChainCommit,
XChainCreateClaimID,
xrpToDrops,
Wallet,
getXChainClaimID,
} from '../../src'
async function sleep(sec: number): Promise<void> {
return new Promise((resolve) => {
setTimeout(resolve, sec * 1000)
})
}
const lockingClient = new Client(
'wss://sidechain-net1.devnet.rippletest.net:51233',
)
const issuingClient = new Client(
'wss://sidechain-net2.devnet.rippletest.net:51233',
)
const MAX_LEDGERS_WAITED = 5
const LEDGER_CLOSE_TIME = 4
void bridgeTransfer()
async function bridgeTransfer(): Promise<void> {
await lockingClient.connect()
await issuingClient.connect()
const lockingChainDoor = 'rMAXACCrp3Y8PpswXcg3bKggHX76V3F8M4'
const accountObjectsRequest: AccountObjectsRequest = {
command: 'account_objects',
account: lockingChainDoor,
type: 'bridge',
}
const lockingAccountObjects = (
await lockingClient.request(accountObjectsRequest)
).result.account_objects
// There will only be one here - a door account can only have one bridge per currency
const bridgeData = lockingAccountObjects.filter(
(obj) =>
obj.LedgerEntryType === 'Bridge' &&
obj.XChainBridge.LockingChainIssue.currency === 'XRP',
)[0] as LedgerEntry.Bridge
const bridge: XChainBridge = bridgeData.XChainBridge
console.log(bridge)
console.log('Creating wallet on the locking chain via the faucet...')
const { wallet: wallet1 } = await lockingClient.fundWallet()
console.log(wallet1)
const wallet2 = Wallet.generate()
console.log(
`Creating ${wallet2.classicAddress} on the issuing chain via the bridge...`,
)
const fundTx: XChainAccountCreateCommit = {
TransactionType: 'XChainAccountCreateCommit',
Account: wallet1.classicAddress,
XChainBridge: bridge,
SignatureReward: bridgeData.SignatureReward,
Destination: wallet2.classicAddress,
Amount: (
parseInt(bridgeData.MinAccountCreateAmount as string, 10) * 2
).toString(),
}
const fundResponse = await lockingClient.submitAndWait(fundTx, {
wallet: wallet1,
})
console.log(fundResponse)
console.log(
'Waiting for the attestation to go through... (usually 8-12 seconds)',
)
let ledgersWaited = 0
let initialBalance = '0'
while (ledgersWaited < MAX_LEDGERS_WAITED) {
await sleep(LEDGER_CLOSE_TIME)
try {
initialBalance = await issuingClient.getXrpBalance(wallet2.classicAddress)
console.log(
`Wallet ${wallet2.classicAddress} has been funded with a balance of ${initialBalance} XRP`,
)
break
} catch (_error) {
ledgersWaited += 1
if (ledgersWaited === MAX_LEDGERS_WAITED) {
// This error should never be hit if the bridge is running
throw Error('Destination account creation via the bridge failed.')
}
}
}
console.log(
`Transferring funds from ${wallet1.classicAddress} on the locking chain to ` +
`${wallet2.classicAddress} on the issuing_chain...`,
)
// Fetch the claim ID for the transfer
console.log('Step 1: Fetching the claim ID for the transfer...')
const claimIdTx: XChainCreateClaimID = {
TransactionType: 'XChainCreateClaimID',
Account: wallet2.classicAddress,
XChainBridge: bridge,
SignatureReward: bridgeData.SignatureReward,
OtherChainSource: wallet1.classicAddress,
}
const claimIdResult = await issuingClient.submitAndWait(claimIdTx, {
wallet: wallet2,
})
console.log(claimIdResult)
// Extract new claim ID from metadata
const xchainClaimId = getXChainClaimID(claimIdResult.result.meta)
if (xchainClaimId == null) {
// This shouldn't trigger assuming the transaction succeeded
throw Error('Could not extract XChainClaimID')
}
console.log(`Claim ID for the transfer: ${xchainClaimId}`)
console.log(
'Step 2: Locking the funds on the locking chain with an XChainCommit transaction...',
)
const commitTx: XChainCommit = {
TransactionType: 'XChainCommit',
Account: wallet1.classicAddress,
Amount: xrpToDrops(1),
XChainBridge: bridge,
XChainClaimID: xchainClaimId,
OtherChainDestination: wallet2.classicAddress,
}
const commitResult = await lockingClient.submitAndWait(commitTx, {
wallet: wallet1,
})
console.log(commitResult)
console.log(
'Waiting for the attestation to go through... (usually 8-12 seconds)',
)
ledgersWaited = 0
while (ledgersWaited < MAX_LEDGERS_WAITED) {
await sleep(LEDGER_CLOSE_TIME)
const currentBalance = await issuingClient.getXrpBalance(
wallet2.classicAddress,
)
console.log(initialBalance, currentBalance)
if (parseFloat(currentBalance) > parseFloat(initialBalance)) {
console.log('Transfer is complete')
console.log(
`New balance of ${wallet2.classicAddress} is ${currentBalance} XRP`,
)
break
}
ledgersWaited += 1
if (ledgersWaited === MAX_LEDGERS_WAITED) {
throw Error('Bridge transfer failed.')
}
}
await lockingClient.disconnect()
await issuingClient.disconnect()
}