mirror of
https://github.com/Xahau/xahau.js.git
synced 2025-11-21 20:55:48 +00:00
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
This commit is contained in:
8
.vscode/settings.json
vendored
8
.vscode/settings.json
vendored
@@ -1,6 +1,9 @@
|
|||||||
{
|
{
|
||||||
"editor.tabSize": 2,
|
"editor.tabSize": 2,
|
||||||
"cSpell.words": [
|
"cSpell.words": [
|
||||||
|
"altnet",
|
||||||
|
"Autofills",
|
||||||
|
"Clawback",
|
||||||
"hostid",
|
"hostid",
|
||||||
"keypair",
|
"keypair",
|
||||||
"keypairs",
|
"keypairs",
|
||||||
@@ -8,8 +11,11 @@
|
|||||||
"multisigned",
|
"multisigned",
|
||||||
"multisigning",
|
"multisigning",
|
||||||
"preauthorization",
|
"preauthorization",
|
||||||
|
"rippletest",
|
||||||
"secp256k1",
|
"secp256k1",
|
||||||
"Setf"
|
"Setf",
|
||||||
|
"Sidechains",
|
||||||
|
"xchain"
|
||||||
],
|
],
|
||||||
"[javascript]": {
|
"[javascript]": {
|
||||||
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
# ripple-binary-codec Release History
|
# ripple-binary-codec Release History
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
### Added
|
||||||
|
- Support for the XChainBridge amendment.
|
||||||
|
|
||||||
## 1.9.0 (2023-08-24)
|
## 1.9.0 (2023-08-24)
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
"UInt384": 22,
|
"UInt384": 22,
|
||||||
"UInt512": 23,
|
"UInt512": 23,
|
||||||
"Issue": 24,
|
"Issue": 24,
|
||||||
|
"XChainBridge": 25,
|
||||||
"Transaction": 10001,
|
"Transaction": 10001,
|
||||||
"LedgerEntry": 10002,
|
"LedgerEntry": 10002,
|
||||||
"Validation": 10003,
|
"Validation": 10003,
|
||||||
@@ -35,8 +36,11 @@
|
|||||||
"Ticket": 84,
|
"Ticket": 84,
|
||||||
"SignerList": 83,
|
"SignerList": 83,
|
||||||
"Offer": 111,
|
"Offer": 111,
|
||||||
|
"Bridge": 105,
|
||||||
"LedgerHashes": 104,
|
"LedgerHashes": 104,
|
||||||
"Amendments": 102,
|
"Amendments": 102,
|
||||||
|
"XChainOwnedClaimID": 113,
|
||||||
|
"XChainOwnedCreateAccountClaimID": 116,
|
||||||
"FeeSettings": 115,
|
"FeeSettings": 115,
|
||||||
"Escrow": 117,
|
"Escrow": 117,
|
||||||
"PayChannel": 120,
|
"PayChannel": 120,
|
||||||
@@ -233,6 +237,16 @@
|
|||||||
"type": "UInt8"
|
"type": "UInt8"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"WasLockingChainSend",
|
||||||
|
{
|
||||||
|
"nth": 19,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "UInt8"
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"LedgerEntryType",
|
"LedgerEntryType",
|
||||||
{
|
{
|
||||||
@@ -983,6 +997,36 @@
|
|||||||
"type": "UInt64"
|
"type": "UInt64"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"XChainClaimID",
|
||||||
|
{
|
||||||
|
"nth": 20,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "UInt64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"XChainAccountCreateCount",
|
||||||
|
{
|
||||||
|
"nth": 21,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "UInt64"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"XChainAccountClaimCount",
|
||||||
|
{
|
||||||
|
"nth": 22,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "UInt64"
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"EmailHash",
|
"EmailHash",
|
||||||
{
|
{
|
||||||
@@ -1583,6 +1627,26 @@
|
|||||||
"type": "Amount"
|
"type": "Amount"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"SignatureReward",
|
||||||
|
{
|
||||||
|
"nth": 29,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "Amount"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"MinAccountCreateAmount",
|
||||||
|
{
|
||||||
|
"nth": 30,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "Amount"
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"LPTokenBalance",
|
"LPTokenBalance",
|
||||||
{
|
{
|
||||||
@@ -1933,6 +1997,66 @@
|
|||||||
"type": "AccountID"
|
"type": "AccountID"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"OtherChainSource",
|
||||||
|
{
|
||||||
|
"nth": 18,
|
||||||
|
"isVLEncoded": true,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "AccountID"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"OtherChainDestination",
|
||||||
|
{
|
||||||
|
"nth": 19,
|
||||||
|
"isVLEncoded": true,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "AccountID"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"AttestationSignerAccount",
|
||||||
|
{
|
||||||
|
"nth": 20,
|
||||||
|
"isVLEncoded": true,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "AccountID"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"AttestationRewardAccount",
|
||||||
|
{
|
||||||
|
"nth": 21,
|
||||||
|
"isVLEncoded": true,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "AccountID"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"LockingChainDoor",
|
||||||
|
{
|
||||||
|
"nth": 22,
|
||||||
|
"isVLEncoded": true,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "AccountID"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"IssuingChainDoor",
|
||||||
|
{
|
||||||
|
"nth": 23,
|
||||||
|
"isVLEncoded": true,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "AccountID"
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"Indexes",
|
"Indexes",
|
||||||
{
|
{
|
||||||
@@ -1983,6 +2107,26 @@
|
|||||||
"type": "PathSet"
|
"type": "PathSet"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"LockingChainIssue",
|
||||||
|
{
|
||||||
|
"nth": 1,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "Issue"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"IssuingChainIssue",
|
||||||
|
{
|
||||||
|
"nth": 2,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "Issue"
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"Asset",
|
"Asset",
|
||||||
{
|
{
|
||||||
@@ -2003,6 +2147,16 @@
|
|||||||
"type": "Issue"
|
"type": "Issue"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"XChainBridge",
|
||||||
|
{
|
||||||
|
"nth": 1,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "XChainBridge"
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"TransactionMetaData",
|
"TransactionMetaData",
|
||||||
{
|
{
|
||||||
@@ -2243,6 +2397,46 @@
|
|||||||
"type": "STObject"
|
"type": "STObject"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"XChainClaimProofSig",
|
||||||
|
{
|
||||||
|
"nth": 28,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "STObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"XChainCreateAccountProofSig",
|
||||||
|
{
|
||||||
|
"nth": 29,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "STObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"XChainClaimAttestationCollectionElement",
|
||||||
|
{
|
||||||
|
"nth": 30,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "STObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"XChainCreateAccountAttestationCollectionElement",
|
||||||
|
{
|
||||||
|
"nth": 31,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "STObject"
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"Signers",
|
"Signers",
|
||||||
{
|
{
|
||||||
@@ -2393,6 +2587,26 @@
|
|||||||
"type": "STArray"
|
"type": "STArray"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
"XChainClaimAttestations",
|
||||||
|
{
|
||||||
|
"nth": 21,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "STArray"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"XChainCreateAccountAttestations",
|
||||||
|
{
|
||||||
|
"nth": 22,
|
||||||
|
"isVLEncoded": false,
|
||||||
|
"isSerialized": true,
|
||||||
|
"isSigningField": true,
|
||||||
|
"type": "STArray"
|
||||||
|
}
|
||||||
|
],
|
||||||
[
|
[
|
||||||
"AuthAccounts",
|
"AuthAccounts",
|
||||||
{
|
{
|
||||||
@@ -2461,6 +2675,12 @@
|
|||||||
"temSEQ_AND_TICKET": -263,
|
"temSEQ_AND_TICKET": -263,
|
||||||
"temBAD_NFTOKEN_TRANSFER_FEE": -262,
|
"temBAD_NFTOKEN_TRANSFER_FEE": -262,
|
||||||
"temBAD_AMM_TOKENS": -261,
|
"temBAD_AMM_TOKENS": -261,
|
||||||
|
"temXCHAIN_EQUAL_DOOR_ACCOUNTS": -260,
|
||||||
|
"temXCHAIN_BAD_PROOF": -259,
|
||||||
|
"temXCHAIN_BRIDGE_BAD_ISSUES": -258,
|
||||||
|
"temXCHAIN_BRIDGE_NONDOOR_OWNER": -257,
|
||||||
|
"temXCHAIN_BRIDGE_BAD_MIN_ACCOUNT_CREATE_AMOUNT": -256,
|
||||||
|
"temXCHAIN_BRIDGE_BAD_REWARD_AMOUNT": -255,
|
||||||
|
|
||||||
"tefFAILURE": -199,
|
"tefFAILURE": -199,
|
||||||
"tefALREADY": -198,
|
"tefALREADY": -198,
|
||||||
@@ -2497,6 +2717,7 @@
|
|||||||
"terQUEUED": -89,
|
"terQUEUED": -89,
|
||||||
"terPRE_TICKET": -88,
|
"terPRE_TICKET": -88,
|
||||||
"terNO_AMM": -87,
|
"terNO_AMM": -87,
|
||||||
|
"terSUBMITTED": -86,
|
||||||
|
|
||||||
"tesSUCCESS": 0,
|
"tesSUCCESS": 0,
|
||||||
|
|
||||||
@@ -2538,6 +2759,7 @@
|
|||||||
"tecKILLED": 150,
|
"tecKILLED": 150,
|
||||||
"tecHAS_OBLIGATIONS": 151,
|
"tecHAS_OBLIGATIONS": 151,
|
||||||
"tecTOO_SOON": 152,
|
"tecTOO_SOON": 152,
|
||||||
|
"tecHOOK_ERROR": 153,
|
||||||
"tecMAX_SEQUENCE_REACHED": 154,
|
"tecMAX_SEQUENCE_REACHED": 154,
|
||||||
"tecNO_SUITABLE_NFTOKEN_PAGE": 155,
|
"tecNO_SUITABLE_NFTOKEN_PAGE": 155,
|
||||||
"tecNFTOKEN_BUY_SELL_MISMATCH": 156,
|
"tecNFTOKEN_BUY_SELL_MISMATCH": 156,
|
||||||
@@ -2553,7 +2775,24 @@
|
|||||||
"tecAMM_EMPTY": 166,
|
"tecAMM_EMPTY": 166,
|
||||||
"tecAMM_NOT_EMPTY": 167,
|
"tecAMM_NOT_EMPTY": 167,
|
||||||
"tecAMM_ACCOUNT": 168,
|
"tecAMM_ACCOUNT": 168,
|
||||||
"tecINCOMPLETE": 169
|
"tecINCOMPLETE": 169,
|
||||||
|
"tecXCHAIN_BAD_TRANSFER_ISSUE": 170,
|
||||||
|
"tecXCHAIN_NO_CLAIM_ID": 171,
|
||||||
|
"tecXCHAIN_BAD_CLAIM_ID": 172,
|
||||||
|
"tecXCHAIN_CLAIM_NO_QUORUM": 173,
|
||||||
|
"tecXCHAIN_PROOF_UNKNOWN_KEY": 174,
|
||||||
|
"tecXCHAIN_CREATE_ACCOUNT_NONXRP_ISSUE": 175,
|
||||||
|
"tecXCHAIN_WRONG_CHAIN": 176,
|
||||||
|
"tecXCHAIN_REWARD_MISMATCH": 177,
|
||||||
|
"tecXCHAIN_NO_SIGNERS_LIST": 178,
|
||||||
|
"tecXCHAIN_SENDING_ACCOUNT_MISMATCH": 179,
|
||||||
|
"tecXCHAIN_INSUFF_CREATE_AMOUNT": 180,
|
||||||
|
"tecXCHAIN_ACCOUNT_CREATE_PAST": 181,
|
||||||
|
"tecXCHAIN_ACCOUNT_CREATE_TOO_MANY": 182,
|
||||||
|
"tecXCHAIN_PAYMENT_FAILED": 183,
|
||||||
|
"tecXCHAIN_SELF_COMMIT": 184,
|
||||||
|
"tecXCHAIN_BAD_PUBLIC_KEY_ACCOUNT_PAIR": 185,
|
||||||
|
"tecXCHAIN_CREATE_ACCOUNT_DISABLED": 186
|
||||||
},
|
},
|
||||||
"TRANSACTION_TYPES": {
|
"TRANSACTION_TYPES": {
|
||||||
"Invalid": -1,
|
"Invalid": -1,
|
||||||
@@ -2592,6 +2831,14 @@
|
|||||||
"AMMVote": 38,
|
"AMMVote": 38,
|
||||||
"AMMBid": 39,
|
"AMMBid": 39,
|
||||||
"AMMDelete": 40,
|
"AMMDelete": 40,
|
||||||
|
"XChainCreateClaimID": 41,
|
||||||
|
"XChainCommit": 42,
|
||||||
|
"XChainClaim": 43,
|
||||||
|
"XChainAccountCreateCommit": 44,
|
||||||
|
"XChainAddClaimAttestation": 45,
|
||||||
|
"XChainAddAccountCreateAttestation": 46,
|
||||||
|
"XChainModifyBridge": 47,
|
||||||
|
"XChainCreateBridge": 48,
|
||||||
"EnableAmendment": 100,
|
"EnableAmendment": 100,
|
||||||
"SetFee": 101,
|
"SetFee": 101,
|
||||||
"UNLModify": 102
|
"UNLModify": 102
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { UInt32 } from './uint-32'
|
|||||||
import { UInt64 } from './uint-64'
|
import { UInt64 } from './uint-64'
|
||||||
import { UInt8 } from './uint-8'
|
import { UInt8 } from './uint-8'
|
||||||
import { Vector256 } from './vector-256'
|
import { Vector256 } from './vector-256'
|
||||||
|
import { XChainBridge } from './xchain-bridge'
|
||||||
import { type SerializedType } from './serialized-type'
|
import { type SerializedType } from './serialized-type'
|
||||||
import { DEFAULT_DEFINITIONS } from '../enums'
|
import { DEFAULT_DEFINITIONS } from '../enums'
|
||||||
|
|
||||||
@@ -34,6 +35,7 @@ const coreTypes: Record<string, typeof SerializedType> = {
|
|||||||
UInt32,
|
UInt32,
|
||||||
UInt64,
|
UInt64,
|
||||||
Vector256,
|
Vector256,
|
||||||
|
XChainBridge,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ensures that the DEFAULT_DEFINITIONS object connects these types to fields for serializing/deserializing
|
// Ensures that the DEFAULT_DEFINITIONS object connects these types to fields for serializing/deserializing
|
||||||
|
|||||||
128
packages/ripple-binary-codec/src/types/xchain-bridge.ts
Normal file
128
packages/ripple-binary-codec/src/types/xchain-bridge.ts
Normal file
@@ -0,0 +1,128 @@
|
|||||||
|
import { BinaryParser } from '../serdes/binary-parser'
|
||||||
|
|
||||||
|
import { AccountID } from './account-id'
|
||||||
|
import { JsonObject, SerializedType } from './serialized-type'
|
||||||
|
import { Buffer } from 'buffer/'
|
||||||
|
import { Issue, IssueObject } from './issue'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface for JSON objects that represent cross-chain bridges
|
||||||
|
*/
|
||||||
|
interface XChainBridgeObject extends JsonObject {
|
||||||
|
LockingChainDoor: string
|
||||||
|
LockingChainIssue: IssueObject | string
|
||||||
|
IssuingChainDoor: string
|
||||||
|
IssuingChainIssue: IssueObject | string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type guard for XChainBridgeObject
|
||||||
|
*/
|
||||||
|
function isXChainBridgeObject(arg): arg is XChainBridgeObject {
|
||||||
|
const keys = Object.keys(arg).sort()
|
||||||
|
return (
|
||||||
|
keys.length === 4 &&
|
||||||
|
keys[0] === 'IssuingChainDoor' &&
|
||||||
|
keys[1] === 'IssuingChainIssue' &&
|
||||||
|
keys[2] === 'LockingChainDoor' &&
|
||||||
|
keys[3] === 'LockingChainIssue'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class for serializing/deserializing XChainBridges
|
||||||
|
*/
|
||||||
|
class XChainBridge extends SerializedType {
|
||||||
|
static readonly ZERO_XCHAIN_BRIDGE: XChainBridge = new XChainBridge(
|
||||||
|
Buffer.concat([
|
||||||
|
Buffer.from([0x14]),
|
||||||
|
Buffer.alloc(40),
|
||||||
|
Buffer.from([0x14]),
|
||||||
|
Buffer.alloc(40),
|
||||||
|
]),
|
||||||
|
)
|
||||||
|
|
||||||
|
static readonly TYPE_ORDER: { name: string; type: typeof SerializedType }[] =
|
||||||
|
[
|
||||||
|
{ name: 'LockingChainDoor', type: AccountID },
|
||||||
|
{ name: 'LockingChainIssue', type: Issue },
|
||||||
|
{ name: 'IssuingChainDoor', type: AccountID },
|
||||||
|
{ name: 'IssuingChainIssue', type: Issue },
|
||||||
|
]
|
||||||
|
|
||||||
|
constructor(bytes: Buffer) {
|
||||||
|
super(bytes ?? XChainBridge.ZERO_XCHAIN_BRIDGE.bytes)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct a cross-chain bridge from a JSON
|
||||||
|
*
|
||||||
|
* @param value XChainBridge or JSON to parse into an XChainBridge
|
||||||
|
* @returns An XChainBridge object
|
||||||
|
*/
|
||||||
|
static from<T extends XChainBridge | XChainBridgeObject>(
|
||||||
|
value: T,
|
||||||
|
): XChainBridge {
|
||||||
|
if (value instanceof XChainBridge) {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isXChainBridgeObject(value)) {
|
||||||
|
const bytes: Array<Buffer> = []
|
||||||
|
this.TYPE_ORDER.forEach((item) => {
|
||||||
|
const { name, type } = item
|
||||||
|
if (type === AccountID) {
|
||||||
|
bytes.push(Buffer.from([0x14]))
|
||||||
|
}
|
||||||
|
const object = type.from(value[name])
|
||||||
|
bytes.push(object.toBytes())
|
||||||
|
})
|
||||||
|
return new XChainBridge(Buffer.concat(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('Invalid type to construct an XChainBridge')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Read an XChainBridge from a BinaryParser
|
||||||
|
*
|
||||||
|
* @param parser BinaryParser to read the XChainBridge from
|
||||||
|
* @returns An XChainBridge object
|
||||||
|
*/
|
||||||
|
static fromParser(parser: BinaryParser): XChainBridge {
|
||||||
|
const bytes: Array<Buffer> = []
|
||||||
|
|
||||||
|
this.TYPE_ORDER.forEach((item) => {
|
||||||
|
const { type } = item
|
||||||
|
if (type === AccountID) {
|
||||||
|
parser.skip(1)
|
||||||
|
bytes.push(Buffer.from([0x14]))
|
||||||
|
}
|
||||||
|
const object = type.fromParser(parser)
|
||||||
|
bytes.push(object.toBytes())
|
||||||
|
})
|
||||||
|
|
||||||
|
return new XChainBridge(Buffer.concat(bytes))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the JSON representation of this XChainBridge
|
||||||
|
*
|
||||||
|
* @returns the JSON interpretation of this.bytes
|
||||||
|
*/
|
||||||
|
toJSON(): XChainBridgeObject {
|
||||||
|
const parser = new BinaryParser(this.toString())
|
||||||
|
const json = {}
|
||||||
|
XChainBridge.TYPE_ORDER.forEach((item) => {
|
||||||
|
const { name, type } = item
|
||||||
|
if (type === AccountID) {
|
||||||
|
parser.skip(1)
|
||||||
|
}
|
||||||
|
const object = type.fromParser(parser).toJSON()
|
||||||
|
json[name] = object
|
||||||
|
})
|
||||||
|
return json as XChainBridgeObject
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { XChainBridge, XChainBridgeObject }
|
||||||
@@ -4435,227 +4435,414 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"transactions": [{
|
"transactions": [
|
||||||
"binary": "1200002200000000240000003E6140000002540BE40068400000000000000A7321034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E74473045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F17962646398114550FC62003E785DC231A1058A05E56E3F09CF4E68314D4CC8AB5B21D86A82C3E9E8D0ECF2404B77FECBA",
|
{
|
||||||
"json": {
|
"binary": "1200002200000000240000003E6140000002540BE40068400000000000000A7321034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E74473045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F17962646398114550FC62003E785DC231A1058A05E56E3F09CF4E68314D4CC8AB5B21D86A82C3E9E8D0ECF2404B77FECBA",
|
||||||
"Account": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
"json": {
|
||||||
"Destination": "rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj",
|
"Account": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
||||||
"TransactionType": "Payment",
|
"Destination": "rLQBHVhFnaC5gLEkgr6HgBJJ3bgeZHg9cj",
|
||||||
"TxnSignature": "3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639",
|
"TransactionType": "Payment",
|
||||||
"SigningPubKey": "034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E",
|
"TxnSignature": "3045022022EB32AECEF7C644C891C19F87966DF9C62B1F34BABA6BE774325E4BB8E2DD62022100A51437898C28C2B297112DF8131F2BB39EA5FE613487DDD611525F1796264639",
|
||||||
"Amount": "10000000000",
|
"SigningPubKey": "034AADB09CFF4A4804073701EC53C3510CDC95917C2BB0150FB742D0C66E6CEE9E",
|
||||||
"Fee": "10",
|
"Amount": "10000000000",
|
||||||
"Flags": 0,
|
"Fee": "10",
|
||||||
"Sequence": 62
|
"Flags": 0,
|
||||||
|
"Sequence": 62
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200302200000000240000000168400000000000000A601D40000000000003E8601E400000000000271073210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020744630440220101BCA4B5B5A37C6F44480F9A34752C9AA8B2CDF5AD47E3CB424DEDC21C06DB702206EEB257E82A89B1F46A0A2C7F070B0BD181D980FF86FE4269E369F6FC7A270918114B5F762798A53D543A014CAF8B297CFF8F2F937E8011914AF80285F637EE4AF3C20378F9DFB12511ACB8D27000000000000000000000000000000000000000014550FC62003E785DC231A1058A05E56E3F09CF4E60000000000000000000000000000000000000000",
|
||||||
|
"json": {
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"XChainBridge": {
|
||||||
|
"LockingChainDoor": "rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL",
|
||||||
|
"LockingChainIssue": {"currency": "XRP"},
|
||||||
|
"IssuingChainDoor": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
||||||
|
"IssuingChainIssue": {"currency": "XRP"}
|
||||||
|
},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 0,
|
||||||
|
"MinAccountCreateAmount": "10000",
|
||||||
|
"Sequence": 1,
|
||||||
|
"SignatureReward": "1000",
|
||||||
|
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||||
|
"TransactionType": "XChainCreateBridge",
|
||||||
|
"TxnSignature": "30440220101BCA4B5B5A37C6F44480F9A34752C9AA8B2CDF5AD47E3CB424DEDC21C06DB702206EEB257E82A89B1F46A0A2C7F070B0BD181D980FF86FE4269E369F6FC7A27091"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "12002F2200000000240000000168400000000000000A601D40000000000003E8601E400000000000271073210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074473045022100D2CABC1B0E0635A8EE2E6554F6D474C49BC292C995C5C9F83179F4A60634B04C02205D1DB569D9593136F2FBEA7140010C8F46794D653AFDBEA8D30B8750BA4805E58114B5F762798A53D543A014CAF8B297CFF8F2F937E8011914AF80285F637EE4AF3C20378F9DFB12511ACB8D27000000000000000000000000000000000000000014550FC62003E785DC231A1058A05E56E3F09CF4E60000000000000000000000000000000000000000",
|
||||||
|
"json": {
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"XChainBridge": {
|
||||||
|
"LockingChainDoor": "rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL",
|
||||||
|
"LockingChainIssue": {"currency": "XRP"},
|
||||||
|
"IssuingChainDoor": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
||||||
|
"IssuingChainIssue": {"currency": "XRP"}
|
||||||
|
},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 0,
|
||||||
|
"MinAccountCreateAmount": "10000",
|
||||||
|
"Sequence": 1,
|
||||||
|
"SignatureReward": "1000",
|
||||||
|
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||||
|
"TransactionType": "XChainModifyBridge",
|
||||||
|
"TxnSignature": "3045022100D2CABC1B0E0635A8EE2E6554F6D474C49BC292C995C5C9F83179F4A60634B04C02205D1DB569D9593136F2FBEA7140010C8F46794D653AFDBEA8D30B8750BA4805E5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200292280000000240000000168400000000000000A601D400000000000271073210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020744630440220247B20A1B9C48E21A374CB9B3E1FE2A7C528151868DF8D307E9FBE15237E531A02207C20C092DDCC525E583EF4AB7CB91E862A6DED19426997D3F0A2C84E2BE8C5DD8114B5F762798A53D543A014CAF8B297CFF8F2F937E8801214AF80285F637EE4AF3C20378F9DFB12511ACB8D27011914AF80285F637EE4AF3C20378F9DFB12511ACB8D27000000000000000000000000000000000000000014550FC62003E785DC231A1058A05E56E3F09CF4E60000000000000000000000000000000000000000",
|
||||||
|
"json": {
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"XChainBridge": {
|
||||||
|
"LockingChainDoor": "rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL",
|
||||||
|
"LockingChainIssue": {"currency": "XRP"},
|
||||||
|
"IssuingChainDoor": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
||||||
|
"IssuingChainIssue": {"currency": "XRP"}
|
||||||
|
},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 2147483648,
|
||||||
|
"OtherChainSource": "rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL",
|
||||||
|
"Sequence": 1,
|
||||||
|
"SignatureReward": "10000",
|
||||||
|
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||||
|
"TransactionType": "XChainCreateClaimID",
|
||||||
|
"TxnSignature": "30440220247B20A1B9C48E21A374CB9B3E1FE2A7C528151868DF8D307E9FBE15237E531A02207C20C092DDCC525E583EF4AB7CB91E862A6DED19426997D3F0A2C84E2BE8C5DD"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "12002A228000000024000000013014000000000000000161400000000000271068400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD02074453043021F177323F0D93612C82A4393A99B23905A7E675753FD80C52997AFAB13F5F9D002203BFFAF457E90BDA65AABE8F8762BD96162FAD98A0C030CCD69B06EE9B12BBFFE8114B5F762798A53D543A014CAF8B297CFF8F2F937E8011914AF80285F637EE4AF3C20378F9DFB12511ACB8D27000000000000000000000000000000000000000014550FC62003E785DC231A1058A05E56E3F09CF4E60000000000000000000000000000000000000000",
|
||||||
|
"json": {
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"Amount": "10000",
|
||||||
|
"XChainBridge": {
|
||||||
|
"LockingChainDoor": "rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL",
|
||||||
|
"LockingChainIssue": {"currency": "XRP"},
|
||||||
|
"IssuingChainDoor": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
||||||
|
"IssuingChainIssue": {"currency": "XRP"}
|
||||||
|
},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 2147483648,
|
||||||
|
"Sequence": 1,
|
||||||
|
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||||
|
"TransactionType": "XChainCommit",
|
||||||
|
"TxnSignature": "3043021F177323F0D93612C82A4393A99B23905A7E675753FD80C52997AFAB13F5F9D002203BFFAF457E90BDA65AABE8F8762BD96162FAD98A0C030CCD69B06EE9B12BBFFE",
|
||||||
|
"XChainClaimID": "0000000000000001"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "12002B228000000024000000013014000000000000000161400000000000271068400000000000000A73210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020744630440220445F7469FDA401787D9EE8A9B6E24DFF81E94F4C09FD311D2C0A58FCC02C684A022029E2EF34A5EA35F50D5BB57AC6320AD3AE12C13C8D1379B255A486D72CED142E8114B5F762798A53D543A014CAF8B297CFF8F2F937E88314550FC62003E785DC231A1058A05E56E3F09CF4E6011914AF80285F637EE4AF3C20378F9DFB12511ACB8D27000000000000000000000000000000000000000014550FC62003E785DC231A1058A05E56E3F09CF4E60000000000000000000000000000000000000000",
|
||||||
|
"json": {
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"Amount": "10000",
|
||||||
|
"XChainBridge": {
|
||||||
|
"LockingChainDoor": "rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL",
|
||||||
|
"LockingChainIssue": {"currency": "XRP"},
|
||||||
|
"IssuingChainDoor": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
||||||
|
"IssuingChainIssue": {"currency": "XRP"}
|
||||||
|
},
|
||||||
|
"Destination": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 2147483648,
|
||||||
|
"Sequence": 1,
|
||||||
|
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||||
|
"TransactionType": "XChainClaim",
|
||||||
|
"TxnSignature": "30440220445F7469FDA401787D9EE8A9B6E24DFF81E94F4C09FD311D2C0A58FCC02C684A022029E2EF34A5EA35F50D5BB57AC6320AD3AE12C13C8D1379B255A486D72CED142E",
|
||||||
|
"XChainClaimID": "0000000000000001"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "12002C228000000024000000016140000000000F424068400000000000000A601D400000000000271073210330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD0207446304402202984DDE7F0B566F081F7953D7212BF031ACBF8860FE114102E9512C4C8768C77022070113F4630B1DC3045E4A98DDD648CEBC31B12774F7B44A1B8123CD2C9F5CF188114B5F762798A53D543A014CAF8B297CFF8F2F937E88314AF80285F637EE4AF3C20378F9DFB12511ACB8D27011914AF80285F637EE4AF3C20378F9DFB12511ACB8D27000000000000000000000000000000000000000014550FC62003E785DC231A1058A05E56E3F09CF4E60000000000000000000000000000000000000000",
|
||||||
|
"json": {
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"XChainBridge": {
|
||||||
|
"LockingChainDoor": "rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL",
|
||||||
|
"LockingChainIssue": {"currency": "XRP"},
|
||||||
|
"IssuingChainDoor": "r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV",
|
||||||
|
"IssuingChainIssue": {"currency": "XRP"}
|
||||||
|
},
|
||||||
|
"Amount": "1000000",
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 2147483648,
|
||||||
|
"Destination": "rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL",
|
||||||
|
"Sequence": 1,
|
||||||
|
"SignatureReward": "10000",
|
||||||
|
"SigningPubKey": "0330E7FC9D56BB25D6893BA3F317AE5BCF33B3291BD63DB32654A313222F7FD020",
|
||||||
|
"TransactionType": "XChainAccountCreateCommit",
|
||||||
|
"TxnSignature": "304402202984DDE7F0B566F081F7953D7212BF031ACBF8860FE114102E9512C4C8768C77022070113F4630B1DC3045E4A98DDD648CEBC31B12774F7B44A1B8123CD2C9F5CF18"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "12002E2400000005201B0000000D30150000000000000006614000000000989680684000000000000014601D40000000000000647121ED1F4A024ACFEBDB6C7AA88DEDE3364E060487EA31B14CC9E0D610D152B31AADC27321EDF54108BA2E0A0D3DC2AE3897F8BE0EFE776AE8D0F9FB0D0B9D64233084A8DDD1744003E74AEF1F585F156786429D2FC87A89E5C6B5A56D68BFC9A6A329F3AC67CBF2B6958283C663A4522278CA162C69B23CF75149AF022B410EA0508C16F42058007640EEFCFA3DC2AB4AB7C4D2EBBC168CB621A11B82BABD86534DFC8EFA72439A49662D744073CD848E7A587A95B35162CDF9A69BB237E72C9537A987F5B8C394F30D81145E7A3E3D7200A794FA801C66CE3775B6416EE4128314C15F113E49BCC4B9FFF43CD0366C23ACD82F75638012143FD9ED9A79DEA67CB5D585111FEF0A29203FA0408014145E7A3E3D7200A794FA801C66CE3775B6416EE4128015145E7A3E3D7200A794FA801C66CE3775B6416EE4120010130101191486F0B1126CE1205E59FDFDD2661A9FB7505CA70F000000000000000000000000000000000000000014B5F762798A53D543A014CAF8B297CFF8F2F937E80000000000000000000000000000000000000000",
|
||||||
|
"json": {
|
||||||
|
"Account": "r9cYxdjQsoXAEz3qQJc961SNLaXRkWXCvT",
|
||||||
|
"Amount": "10000000",
|
||||||
|
"AttestationRewardAccount": "r9cYxdjQsoXAEz3qQJc961SNLaXRkWXCvT",
|
||||||
|
"AttestationSignerAccount": "r9cYxdjQsoXAEz3qQJc961SNLaXRkWXCvT",
|
||||||
|
"Destination": "rJdTJRJZ6GXCCRaamHJgEqVzB7Zy4557Pi",
|
||||||
|
"Fee": "20",
|
||||||
|
"LastLedgerSequence": 13,
|
||||||
|
"OtherChainSource": "raFcdz1g8LWJDJWJE2ZKLRGdmUmsTyxaym",
|
||||||
|
"PublicKey": "ED1F4A024ACFEBDB6C7AA88DEDE3364E060487EA31B14CC9E0D610D152B31AADC2",
|
||||||
|
"Sequence": 5,
|
||||||
|
"Signature": "EEFCFA3DC2AB4AB7C4D2EBBC168CB621A11B82BABD86534DFC8EFA72439A49662D744073CD848E7A587A95B35162CDF9A69BB237E72C9537A987F5B8C394F30D",
|
||||||
|
"SignatureReward": "100",
|
||||||
|
"SigningPubKey": "EDF54108BA2E0A0D3DC2AE3897F8BE0EFE776AE8D0F9FB0D0B9D64233084A8DDD1",
|
||||||
|
"TransactionType": "XChainAddAccountCreateAttestation",
|
||||||
|
"TxnSignature": "03E74AEF1F585F156786429D2FC87A89E5C6B5A56D68BFC9A6A329F3AC67CBF2B6958283C663A4522278CA162C69B23CF75149AF022B410EA0508C16F4205800",
|
||||||
|
"WasLockingChainSend": 1,
|
||||||
|
"XChainAccountCreateCount": "0000000000000006",
|
||||||
|
"XChainBridge": {
|
||||||
|
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"IssuingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
},
|
||||||
|
"LockingChainDoor": "rDJVtEuDKr4rj1B3qtW7R5TVWdXV2DY7Qg",
|
||||||
|
"LockingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "12002D2400000009201B00000013301400000000000000016140000000009896806840000000000000147121ED7541DEC700470F54276C90C333A13CDBB5D341FD43C60CEA12170F6D6D4E11367321ED0406B134786FE0751717226657F7BF8AFE96442C05D28ACEC66FB64852BA604C7440D0423649E48A44F181262CF5FC08A68E7FA5CD9E55843E4F09014B76E602574741E8553383A4B43CABD194BB96713647FC0B885BE248E4FFA068FA3E6994CF0476407C175050B08000AD35EEB2D87E16CD3F95A0AEEBF2A049474275153D9D4DD44528FE99AA50E71660A15B0B768E1B90E609BBD5DC7AFAFD45D9705D72D40EA10C81141F30A4D728AB98B0950EC3B9815E6C8D43A7D5598314C15F113E49BCC4B9FFF43CD0366C23ACD82F75638012143FD9ED9A79DEA67CB5D585111FEF0A29203FA0408014141F30A4D728AB98B0950EC3B9815E6C8D43A7D5598015141F30A4D728AB98B0950EC3B9815E6C8D43A7D5590010130101191486F0B1126CE1205E59FDFDD2661A9FB7505CA70F000000000000000000000000000000000000000014B5F762798A53D543A014CAF8B297CFF8F2F937E80000000000000000000000000000000000000000",
|
||||||
|
"json": {
|
||||||
|
"Account": "rsqvD8WFFEBBv4nztpoW9YYXJ7eRzLrtc3",
|
||||||
|
"Amount": "10000000",
|
||||||
|
"AttestationRewardAccount": "rsqvD8WFFEBBv4nztpoW9YYXJ7eRzLrtc3",
|
||||||
|
"AttestationSignerAccount": "rsqvD8WFFEBBv4nztpoW9YYXJ7eRzLrtc3",
|
||||||
|
"Destination": "rJdTJRJZ6GXCCRaamHJgEqVzB7Zy4557Pi",
|
||||||
|
"Fee": "20",
|
||||||
|
"LastLedgerSequence": 19,
|
||||||
|
"OtherChainSource": "raFcdz1g8LWJDJWJE2ZKLRGdmUmsTyxaym",
|
||||||
|
"PublicKey": "ED7541DEC700470F54276C90C333A13CDBB5D341FD43C60CEA12170F6D6D4E1136",
|
||||||
|
"Sequence": 9,
|
||||||
|
"Signature": "7C175050B08000AD35EEB2D87E16CD3F95A0AEEBF2A049474275153D9D4DD44528FE99AA50E71660A15B0B768E1B90E609BBD5DC7AFAFD45D9705D72D40EA10C",
|
||||||
|
"SigningPubKey": "ED0406B134786FE0751717226657F7BF8AFE96442C05D28ACEC66FB64852BA604C",
|
||||||
|
"TransactionType": "XChainAddClaimAttestation",
|
||||||
|
"TxnSignature": "D0423649E48A44F181262CF5FC08A68E7FA5CD9E55843E4F09014B76E602574741E8553383A4B43CABD194BB96713647FC0B885BE248E4FFA068FA3E6994CF04",
|
||||||
|
"WasLockingChainSend": 1,
|
||||||
|
"XChainBridge": {
|
||||||
|
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"IssuingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
},
|
||||||
|
"LockingChainDoor": "rDJVtEuDKr4rj1B3qtW7R5TVWdXV2DY7Qg",
|
||||||
|
"LockingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"XChainClaimID": "0000000000000001"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "12002315000A2200000000240015DAE161400000000000271068400000000000000A6BD5838D7EA4C680000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440B3154D968314FCEB58001E1B0C3A4CFB33DF9FF6C73207E5EAEB9BD07E2747672168E1A2786D950495C38BD8DEE3391BF45F3008DD36F4B12E7C07D82CA5250E8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMCreate",
|
||||||
|
"TxnSignature": "B3154D968314FCEB58001E1B0C3A4CFB33DF9FF6C73207E5EAEB9BD07E2747672168E1A2786D950495C38BD8DEE3391BF45F3008DD36F4B12E7C07D82CA5250E",
|
||||||
|
"Amount": "10000",
|
||||||
|
"Amount2": {
|
||||||
|
"currency": "ETH",
|
||||||
|
"issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9",
|
||||||
|
"value": "10000"
|
||||||
|
},
|
||||||
|
"TradingFee": 10,
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 0,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200242200010000240015DAE168400000000000000A6019D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B874408073C588E7EF672DD171E414638D9AF8DBE9A1359E030DE3E1C9AA6A38A2CE9E138CB56482BB844F7228D48B1E4AD7D09BB7E9F639C115958EEEA374749CA00B8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMDeposit",
|
||||||
|
"TxnSignature": "8073C588E7EF672DD171E414638D9AF8DBE9A1359E030DE3E1C9AA6A38A2CE9E138CB56482BB844F7228D48B1E4AD7D09BB7E9F639C115958EEEA374749CA00B",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 65536,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200242200080000240015DAE16140000000000003E868400000000000000A7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8744096CA066F42871C55088D2758D64148921B1ACAA5C6C648D0F7D675BBF47F87DF711F17C5BD172666D5AEC257520C587A849A6E063345609D91E121A78816EB048114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMDeposit",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"Amount": "1000",
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 524288,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "96CA066F42871C55088D2758D64148921B1ACAA5C6C648D0F7D675BBF47F87DF711F17C5BD172666D5AEC257520C587A849A6E063345609D91E121A78816EB04"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200242200100000240015DAE16140000000000003E868400000000000000A6BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440FC22B16A098C236ED7EDB3EBC983026DFD218A03C8BAA848F3E1D5389D5B8B00473C1178C5BA257BFA2DCD433C414690A430A5CFD71C1C0A7F7BF725EC1759018114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMDeposit",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"Amount": "1000",
|
||||||
|
"Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 1048576,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "FC22B16A098C236ED7EDB3EBC983026DFD218A03C8BAA848F3E1D5389D5B8B00473C1178C5BA257BFA2DCD433C414690A430A5CFD71C1C0A7F7BF725EC175901"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200242200200000240015DAE16140000000000003E868400000000000000A6019D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440117CF90F9B113AD3BD638B6DB63562B37C287D5180F278B3CCF58FC14A5BAEE98307EA0F6DFE19E2FBA887C92955BA5D1A04F92ADAAEB309DE89C3610D074C098114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMDeposit",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"Amount": "1000",
|
||||||
|
"LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 2097152,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "117CF90F9B113AD3BD638B6DB63562B37C287D5180F278B3CCF58FC14A5BAEE98307EA0F6DFE19E2FBA887C92955BA5D1A04F92ADAAEB309DE89C3610D074C09"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200242200400000240015DAE16140000000000003E868400000000000000A601B40000000000000197321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B874405E51EBC6B52A7C3BA5D0AE2FC8F62E779B80182009B3108A87AB6D770D68F56053C193DB0640128E4765565970625B1E2878E116AC854E6DED412202CCDE0B0D8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMDeposit",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"Amount": "1000",
|
||||||
|
"EPrice": "25",
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 4194304,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "5E51EBC6B52A7C3BA5D0AE2FC8F62E779B80182009B3108A87AB6D770D68F56053C193DB0640128E4765565970625B1E2878E116AC854E6DED412202CCDE0B0D"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200252200010000240015DAE168400000000000000A601AD5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B874409D4F41FC452526C0AD17191959D9B6D04A3C73B3A6C29E0F34C8459675A83A7A7D6E3021390EC8C9BE6C93E11C167E12016465E523F64F9EB3194B0A52E418028114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMWithdraw",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 65536,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "9D4F41FC452526C0AD17191959D9B6D04A3C73B3A6C29E0F34C8459675A83A7A7D6E3021390EC8C9BE6C93E11C167E12016465E523F64F9EB3194B0A52E41802"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200252200080000240015DAE16140000000000003E868400000000000000A7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440E2C60D56C337D6D73E4B7D53579C93C666605494E82A89DD58CFDE79E2A4866BCF52370A2146877A2EF748E98168373710001133A51B645D89491849079035018114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMWithdraw",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"Amount": "1000",
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 524288,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "E2C60D56C337D6D73E4B7D53579C93C666605494E82A89DD58CFDE79E2A4866BCF52370A2146877A2EF748E98168373710001133A51B645D8949184907903501"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200252200100000240015DAE16140000000000003E868400000000000000A6BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440D2FCD7D03E53358BC6188BA88A7BA4FF2519B639C3B5C0EBCBDCB704426CA2837111430E92A6003D1CD0D81C63682C74839320539EC4F89B82AA5607714952028114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMWithdraw",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"Amount": "1000",
|
||||||
|
"Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 1048576,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "D2FCD7D03E53358BC6188BA88A7BA4FF2519B639C3B5C0EBCBDCB704426CA2837111430E92A6003D1CD0D81C63682C74839320539EC4F89B82AA560771495202"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200252200200000240015DAE16140000000000003E868400000000000000A601AD5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8744042DA5620E924E2D2059BBB4E0C4F03244140ACED93B543136FEEDF802165F814D09F45C7E2A4618468442516F4712A23B1D3332D5DBDBAE830337F39F259C90F8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMWithdraw",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"Amount": "1000",
|
||||||
|
"LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 2097152,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "42DA5620E924E2D2059BBB4E0C4F03244140ACED93B543136FEEDF802165F814D09F45C7E2A4618468442516F4712A23B1D3332D5DBDBAE830337F39F259C90F"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200252200400000240015DAE16140000000000003E868400000000000000A601B40000000000000197321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8744045BCEE5A12E5F5F1FB085A24F2F7FD962BBCB0D89A44A5319E3F7E3799E1870341880B6F684132971DDDF2E6B15356B3F407962D6D4E8DE10989F3B16E3CB90D8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMWithdraw",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"Amount": "1000",
|
||||||
|
"EPrice": "25",
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 4194304,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "45BCEE5A12E5F5F1FB085A24F2F7FD962BBCB0D89A44A5319E3F7E3799E1870341880B6F684132971DDDF2E6B15356B3F407962D6D4E8DE10989F3B16E3CB90D"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200272200000000240015DAE168400000000000000A6CD4C8E1BC9BF04000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0486DD4CC6F3B40B6C000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440F8EAAFB5EC1A69275167589969F0B9764BACE6BC8CC81482C2FC5ACCE691EDBD0D88D141137B1253BB1B9AC90A8A52CB37F5B6F7E1028B06DD06F91BE06F5A0F8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653AF019E01B81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F10318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMBid",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"AuthAccounts": [{"AuthAccount": {"Account": "rEaHTti4HZsMBpxTAF4ncWxkcdqDh1h6P7"}}],
|
||||||
|
"BidMax": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "35"},
|
||||||
|
"BidMin": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "25"},
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 0,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "F8EAAFB5EC1A69275167589969F0B9764BACE6BC8CC81482C2FC5ACCE691EDBD0D88D141137B1253BB1B9AC90A8A52CB37F5B6F7E1028B06DD06F91BE06F5A0F"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"binary": "1200261500EA2200000000240015DAE168400000000000000A7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440BC2F6E76969E3747E9BDE183C97573B086212F09D5387460E6EE2F32953E85EAEB9618FBBEF077276E30E59D619FCF7C7BDCDDDD9EB94D7CE1DD5CE9246B21078114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
||||||
|
"json": {
|
||||||
|
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
||||||
|
"TransactionType": "AMMVote",
|
||||||
|
"Asset": {"currency": "XRP"},
|
||||||
|
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
||||||
|
"TradingFee": 234,
|
||||||
|
"Fee": "10",
|
||||||
|
"Flags": 0,
|
||||||
|
"Sequence": 1432289,
|
||||||
|
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
||||||
|
"TxnSignature": "BC2F6E76969E3747E9BDE183C97573B086212F09D5387460E6EE2F32953E85EAEB9618FBBEF077276E30E59D619FCF7C7BDCDDDD9EB94D7CE1DD5CE9246B2107"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
],
|
||||||
{
|
|
||||||
"binary": "12002315000A2200000000240015DAE161400000000000271068400000000000000A6BD5838D7EA4C680000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440B3154D968314FCEB58001E1B0C3A4CFB33DF9FF6C73207E5EAEB9BD07E2747672168E1A2786D950495C38BD8DEE3391BF45F3008DD36F4B12E7C07D82CA5250E8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMCreate",
|
|
||||||
"TxnSignature": "B3154D968314FCEB58001E1B0C3A4CFB33DF9FF6C73207E5EAEB9BD07E2747672168E1A2786D950495C38BD8DEE3391BF45F3008DD36F4B12E7C07D82CA5250E",
|
|
||||||
"Amount": "10000",
|
|
||||||
"Amount2": {
|
|
||||||
"currency": "ETH",
|
|
||||||
"issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9",
|
|
||||||
"value": "10000"
|
|
||||||
},
|
|
||||||
"TradingFee": 10,
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 0,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200242200010000240015DAE168400000000000000A6019D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B874408073C588E7EF672DD171E414638D9AF8DBE9A1359E030DE3E1C9AA6A38A2CE9E138CB56482BB844F7228D48B1E4AD7D09BB7E9F639C115958EEEA374749CA00B8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMDeposit",
|
|
||||||
"TxnSignature": "8073C588E7EF672DD171E414638D9AF8DBE9A1359E030DE3E1C9AA6A38A2CE9E138CB56482BB844F7228D48B1E4AD7D09BB7E9F639C115958EEEA374749CA00B",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"},
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 65536,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200242200080000240015DAE16140000000000003E868400000000000000A7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8744096CA066F42871C55088D2758D64148921B1ACAA5C6C648D0F7D675BBF47F87DF711F17C5BD172666D5AEC257520C587A849A6E063345609D91E121A78816EB048114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMDeposit",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"Amount": "1000",
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 524288,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "96CA066F42871C55088D2758D64148921B1ACAA5C6C648D0F7D675BBF47F87DF711F17C5BD172666D5AEC257520C587A849A6E063345609D91E121A78816EB04"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200242200100000240015DAE16140000000000003E868400000000000000A6BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440FC22B16A098C236ED7EDB3EBC983026DFD218A03C8BAA848F3E1D5389D5B8B00473C1178C5BA257BFA2DCD433C414690A430A5CFD71C1C0A7F7BF725EC1759018114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMDeposit",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"Amount": "1000",
|
|
||||||
"Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"},
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 1048576,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "FC22B16A098C236ED7EDB3EBC983026DFD218A03C8BAA848F3E1D5389D5B8B00473C1178C5BA257BFA2DCD433C414690A430A5CFD71C1C0A7F7BF725EC175901"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200242200200000240015DAE16140000000000003E868400000000000000A6019D5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440117CF90F9B113AD3BD638B6DB63562B37C287D5180F278B3CCF58FC14A5BAEE98307EA0F6DFE19E2FBA887C92955BA5D1A04F92ADAAEB309DE89C3610D074C098114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMDeposit",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"Amount": "1000",
|
|
||||||
"LPTokenOut": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"},
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 2097152,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "117CF90F9B113AD3BD638B6DB63562B37C287D5180F278B3CCF58FC14A5BAEE98307EA0F6DFE19E2FBA887C92955BA5D1A04F92ADAAEB309DE89C3610D074C09"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200242200400000240015DAE16140000000000003E868400000000000000A601B40000000000000197321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B874405E51EBC6B52A7C3BA5D0AE2FC8F62E779B80182009B3108A87AB6D770D68F56053C193DB0640128E4765565970625B1E2878E116AC854E6DED412202CCDE0B0D8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMDeposit",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"Amount": "1000",
|
|
||||||
"EPrice": "25",
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 4194304,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "5E51EBC6B52A7C3BA5D0AE2FC8F62E779B80182009B3108A87AB6D770D68F56053C193DB0640128E4765565970625B1E2878E116AC854E6DED412202CCDE0B0D"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200252200010000240015DAE168400000000000000A601AD5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B874409D4F41FC452526C0AD17191959D9B6D04A3C73B3A6C29E0F34C8459675A83A7A7D6E3021390EC8C9BE6C93E11C167E12016465E523F64F9EB3194B0A52E418028114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMWithdraw",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"},
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 65536,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "9D4F41FC452526C0AD17191959D9B6D04A3C73B3A6C29E0F34C8459675A83A7A7D6E3021390EC8C9BE6C93E11C167E12016465E523F64F9EB3194B0A52E41802"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200252200080000240015DAE16140000000000003E868400000000000000A7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440E2C60D56C337D6D73E4B7D53579C93C666605494E82A89DD58CFDE79E2A4866BCF52370A2146877A2EF748E98168373710001133A51B645D89491849079035018114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMWithdraw",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"Amount": "1000",
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 524288,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "E2C60D56C337D6D73E4B7D53579C93C666605494E82A89DD58CFDE79E2A4866BCF52370A2146877A2EF748E98168373710001133A51B645D8949184907903501"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200252200100000240015DAE16140000000000003E868400000000000000A6BD511C37937E080000000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440D2FCD7D03E53358BC6188BA88A7BA4FF2519B639C3B5C0EBCBDCB704426CA2837111430E92A6003D1CD0D81C63682C74839320539EC4F89B82AA5607714952028114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMWithdraw",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"Amount": "1000",
|
|
||||||
"Amount2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9", "value": "500"},
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 1048576,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "D2FCD7D03E53358BC6188BA88A7BA4FF2519B639C3B5C0EBCBDCB704426CA2837111430E92A6003D1CD0D81C63682C74839320539EC4F89B82AA560771495202"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200252200200000240015DAE16140000000000003E868400000000000000A601AD5438D7EA4C68000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8744042DA5620E924E2D2059BBB4E0C4F03244140ACED93B543136FEEDF802165F814D09F45C7E2A4618468442516F4712A23B1D3332D5DBDBAE830337F39F259C90F8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMWithdraw",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"Amount": "1000",
|
|
||||||
"LPTokenIn": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "1000"},
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 2097152,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "42DA5620E924E2D2059BBB4E0C4F03244140ACED93B543136FEEDF802165F814D09F45C7E2A4618468442516F4712A23B1D3332D5DBDBAE830337F39F259C90F"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200252200400000240015DAE16140000000000003E868400000000000000A601B40000000000000197321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8744045BCEE5A12E5F5F1FB085A24F2F7FD962BBCB0D89A44A5319E3F7E3799E1870341880B6F684132971DDDF2E6B15356B3F407962D6D4E8DE10989F3B16E3CB90D8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMWithdraw",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"Amount": "1000",
|
|
||||||
"EPrice": "25",
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 4194304,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "45BCEE5A12E5F5F1FB085A24F2F7FD962BBCB0D89A44A5319E3F7E3799E1870341880B6F684132971DDDF2E6B15356B3F407962D6D4E8DE10989F3B16E3CB90D"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200272200000000240015DAE168400000000000000A6CD4C8E1BC9BF04000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0486DD4CC6F3B40B6C000B3813FCAB4EE68B3D0D735D6849465A9113EE048B3813FCAB4EE68B3D0D735D6849465A9113EE0487321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440F8EAAFB5EC1A69275167589969F0B9764BACE6BC8CC81482C2FC5ACCE691EDBD0D88D141137B1253BB1B9AC90A8A52CB37F5B6F7E1028B06DD06F91BE06F5A0F8114F92F27CC5EE2F2760278FE096D0CBE32BDD3653AF019E01B81149A91957F8F16BC57F3F200CD8C98375BF1791586E1F10318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMBid",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"AuthAccounts": [{"AuthAccount": {"Account": "rEaHTti4HZsMBpxTAF4ncWxkcdqDh1h6P7"}}],
|
|
||||||
"BidMax": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "35"},
|
|
||||||
"BidMin": {"currency": "B3813FCAB4EE68B3D0D735D6849465A9113EE048", "issuer": "rH438jEAzTs5PYtV6CHZqpDpwCKQmPW9Cg", "value": "25"},
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 0,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "F8EAAFB5EC1A69275167589969F0B9764BACE6BC8CC81482C2FC5ACCE691EDBD0D88D141137B1253BB1B9AC90A8A52CB37F5B6F7E1028B06DD06F91BE06F5A0F"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"binary": "1200261500EA2200000000240015DAE168400000000000000A7321ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B87440BC2F6E76969E3747E9BDE183C97573B086212F09D5387460E6EE2F32953E85EAEB9618FBBEF077276E30E59D619FCF7C7BDCDDDD9EB94D7CE1DD5CE9246B21078114F92F27CC5EE2F2760278FE096D0CBE32BDD3653A0318000000000000000000000000000000000000000004180000000000000000000000004554480000000000FBEF9A3A2B814E807745FA3D9C32FFD155FA2E8C",
|
|
||||||
"json": {
|
|
||||||
"Account": "rP5ZkB5RZQaECsSVR4DeSFK4fAw52BYtbw",
|
|
||||||
"TransactionType": "AMMVote",
|
|
||||||
"Asset": {"currency": "XRP"},
|
|
||||||
"Asset2": {"currency": "ETH", "issuer": "rPyfep3gcLzkosKC9XiE77Y8DZWG6iWDT9"},
|
|
||||||
"TradingFee": 234,
|
|
||||||
"Fee": "10",
|
|
||||||
"Flags": 0,
|
|
||||||
"Sequence": 1432289,
|
|
||||||
"SigningPubKey": "ED7453D2572A2104E7B266A45888C53F503CEB1F11DC4BB3710EB2995238EC65B8",
|
|
||||||
"TxnSignature": "BC2F6E76969E3747E9BDE183C97573B086212F09D5387460E6EE2F32953E85EAEB9618FBBEF077276E30E59D619FCF7C7BDCDDDD9EB94D7CE1DD5CE9246B2107"
|
|
||||||
}
|
|
||||||
}],
|
|
||||||
"ledgerData": [{
|
"ledgerData": [{
|
||||||
"binary": "01E91435016340767BF1C4A3EACEB081770D8ADE216C85445DD6FB002C6B5A2930F2DECE006DA18150CB18F6DD33F6F0990754C962A7CCE62F332FF9C13939B03B864117F0BDA86B6E9B4F873B5C3E520634D343EF5D9D9A4246643D64DAD278BA95DC0EAC6EB5350CF970D521276CDE21276CE60A00",
|
"binary": "01E91435016340767BF1C4A3EACEB081770D8ADE216C85445DD6FB002C6B5A2930F2DECE006DA18150CB18F6DD33F6F0990754C962A7CCE62F332FF9C13939B03B864117F0BDA86B6E9B4F873B5C3E520634D343EF5D9D9A4246643D64DAD278BA95DC0EAC6EB5350CF970D521276CDE21276CE60A00",
|
||||||
"json": {
|
"json": {
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ module.exports = {
|
|||||||
'max-statements': 'off',
|
'max-statements': 'off',
|
||||||
// Snippets have logs on console to better understand the working.
|
// Snippets have logs on console to better understand the working.
|
||||||
'no-console': 'off',
|
'no-console': 'off',
|
||||||
'import/no-extraneous-dependencies': 'off',
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -147,5 +146,17 @@ module.exports = {
|
|||||||
'import/no-unused-modules': 'off',
|
'import/no-unused-modules': 'off',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
files: ['tools/*.ts', 'tools/*.js'],
|
||||||
|
rules: {
|
||||||
|
'no-console': ['off'],
|
||||||
|
'node/no-process-exit': ['off'],
|
||||||
|
'@typescript-eslint/no-magic-numbers': ['off'],
|
||||||
|
'max-lines-per-function': ['off'],
|
||||||
|
'max-statements': ['off'],
|
||||||
|
complexity: ['off'],
|
||||||
|
'max-depth': ['warn', 3],
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,9 @@
|
|||||||
Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xrpl-announce) for release announcements. We recommend that xrpl.js (ripple-lib) users stay up-to-date with the latest stable release.
|
Subscribe to [the **xrpl-announce** mailing list](https://groups.google.com/g/xrpl-announce) for release announcements. We recommend that xrpl.js (ripple-lib) users stay up-to-date with the latest stable release.
|
||||||
|
|
||||||
## Unreleased
|
## Unreleased
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
* Added `ports` field to `ServerInfoResponse`
|
* Added `ports` field to `ServerInfoResponse`
|
||||||
|
* Support for the XChainBridge amendment.
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
* Fix request model fields related to AMM
|
* Fix request model fields related to AMM
|
||||||
|
|||||||
172
packages/xrpl/snippets/src/bridgeTransfer.ts
Normal file
172
packages/xrpl/snippets/src/bridgeTransfer.ts
Normal file
@@ -0,0 +1,172 @@
|
|||||||
|
/* 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()
|
||||||
|
}
|
||||||
@@ -2,7 +2,7 @@ export type LedgerIndex = number | ('validated' | 'closed' | 'current')
|
|||||||
|
|
||||||
export interface XRP {
|
export interface XRP {
|
||||||
currency: 'XRP'
|
currency: 'XRP'
|
||||||
issuer: never
|
issuer?: never
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IssuedCurrency {
|
export interface IssuedCurrency {
|
||||||
@@ -148,3 +148,10 @@ export interface AuthAccount {
|
|||||||
Account: string
|
Account: string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface XChainBridge {
|
||||||
|
LockingChainDoor: string
|
||||||
|
LockingChainIssue: Currency
|
||||||
|
IssuingChainDoor: string
|
||||||
|
IssuingChainIssue: Currency
|
||||||
|
}
|
||||||
|
|||||||
84
packages/xrpl/src/models/ledger/Bridge.ts
Normal file
84
packages/xrpl/src/models/ledger/Bridge.ts
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
import { Amount, XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import BaseLedgerEntry from './BaseLedgerEntry'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Bridge objects represents a cross-chain bridge and includes information about
|
||||||
|
* the door accounts, assets, signature rewards, and the minimum account create
|
||||||
|
* amount.
|
||||||
|
*
|
||||||
|
* @category Ledger Entries
|
||||||
|
*/
|
||||||
|
export default interface Bridge extends BaseLedgerEntry {
|
||||||
|
LedgerEntryType: 'Bridge'
|
||||||
|
|
||||||
|
/** The door account that owns the bridge. */
|
||||||
|
Account: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The total amount, in XRP, to be rewarded for providing a signature for
|
||||||
|
* cross-chain transfer or for signing for the cross-chain reward. This amount
|
||||||
|
* will be split among the signers.
|
||||||
|
*/
|
||||||
|
SignatureReward: Amount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum amount, in XRP, required for an {@link XChainAccountCreateCommit}
|
||||||
|
* transaction. If this isn't present, the {@link XChainAccountCreateCommit}
|
||||||
|
* transaction will fail. This field can only be present on XRP-XRP bridges.
|
||||||
|
*/
|
||||||
|
MinAccountCreateAmount?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The door accounts and assets of the bridge this object correlates to.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The value of the next XChainClaimID to be created.
|
||||||
|
*/
|
||||||
|
XChainClaimID: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A counter used to order the execution of account create transactions. It is
|
||||||
|
* incremented every time a successful {@link XChainAccountCreateCommit}
|
||||||
|
* transaction is run for the source chain.
|
||||||
|
*/
|
||||||
|
XChainAccountCreateCount: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A counter used to order the execution of account create transactions. It is
|
||||||
|
* incremented every time a {@link XChainAccountCreateCommit} transaction is
|
||||||
|
* "claimed" on the destination chain. When the "claim" transaction is run on
|
||||||
|
* the destination chain, the XChainAccountClaimCount must match the value that
|
||||||
|
* the XChainAccountCreateCount had at the time the XChainAccountClaimCount was
|
||||||
|
* run on the source chain. This orders the claims so that they run in the same
|
||||||
|
* order that the XChainAccountCreateCommit transactions ran on the source chain,
|
||||||
|
* to prevent transaction replay.
|
||||||
|
*/
|
||||||
|
XChainAccountClaimCount: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit-map of boolean flags. No flags are defined for Bridges, so this value
|
||||||
|
* is always 0.
|
||||||
|
*/
|
||||||
|
Flags: 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A hint indicating which page of the sender's owner directory links to this
|
||||||
|
* object, in case the directory consists of multiple pages.
|
||||||
|
*/
|
||||||
|
OwnerNode: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The identifying hash of the transaction that most recently modified this
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
PreviousTxnID: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The index of the ledger that contains the transaction that most recently
|
||||||
|
* modified this object.
|
||||||
|
*/
|
||||||
|
PreviousTxnLgrSeq: number
|
||||||
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
import AccountRoot from './AccountRoot'
|
import AccountRoot from './AccountRoot'
|
||||||
import Amendments from './Amendments'
|
import Amendments from './Amendments'
|
||||||
import AMM from './AMM'
|
import AMM from './AMM'
|
||||||
|
import Bridge from './Bridge'
|
||||||
import Check from './Check'
|
import Check from './Check'
|
||||||
import DepositPreauth from './DepositPreauth'
|
import DepositPreauth from './DepositPreauth'
|
||||||
import DirectoryNode from './DirectoryNode'
|
import DirectoryNode from './DirectoryNode'
|
||||||
@@ -13,11 +14,14 @@ import PayChannel from './PayChannel'
|
|||||||
import RippleState from './RippleState'
|
import RippleState from './RippleState'
|
||||||
import SignerList from './SignerList'
|
import SignerList from './SignerList'
|
||||||
import Ticket from './Ticket'
|
import Ticket from './Ticket'
|
||||||
|
import XChainOwnedClaimID from './XChainOwnedClaimID'
|
||||||
|
import XChainOwnedCreateAccountClaimID from './XChainOwnedCreateAccountClaimID'
|
||||||
|
|
||||||
type LedgerEntry =
|
type LedgerEntry =
|
||||||
| AccountRoot
|
| AccountRoot
|
||||||
| Amendments
|
| Amendments
|
||||||
| AMM
|
| AMM
|
||||||
|
| Bridge
|
||||||
| Check
|
| Check
|
||||||
| DepositPreauth
|
| DepositPreauth
|
||||||
| DirectoryNode
|
| DirectoryNode
|
||||||
@@ -30,5 +34,7 @@ type LedgerEntry =
|
|||||||
| RippleState
|
| RippleState
|
||||||
| SignerList
|
| SignerList
|
||||||
| Ticket
|
| Ticket
|
||||||
|
| XChainOwnedClaimID
|
||||||
|
| XChainOwnedCreateAccountClaimID
|
||||||
|
|
||||||
export default LedgerEntry
|
export default LedgerEntry
|
||||||
|
|||||||
89
packages/xrpl/src/models/ledger/XChainOwnedClaimID.ts
Normal file
89
packages/xrpl/src/models/ledger/XChainOwnedClaimID.ts
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
import { Amount } from 'ripple-binary-codec/dist/types'
|
||||||
|
|
||||||
|
import { XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import BaseLedgerEntry from './BaseLedgerEntry'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An XChainOwnedClaimID object represents one cross-chain transfer of value
|
||||||
|
* and includes information of the account on the source chain that locks or
|
||||||
|
* burns the funds on the source chain.
|
||||||
|
*
|
||||||
|
* @category Ledger Entries
|
||||||
|
*/
|
||||||
|
export default interface XChainOwnedClaimID extends BaseLedgerEntry {
|
||||||
|
LedgerEntryType: 'XChainOwnedClaimID'
|
||||||
|
|
||||||
|
/** The account that checked out this unique claim ID value. */
|
||||||
|
Account: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The door accounts and assets of the bridge this object correlates to.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique sequence number for a cross-chain transfer.
|
||||||
|
*/
|
||||||
|
XChainClaimID: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The account that must send the corresponding {@link XChainCommit} on the
|
||||||
|
* source chain. The destination may be specified in the {@link XChainCommit}
|
||||||
|
* transaction, which means that if the OtherChainSource isn't specified,
|
||||||
|
* another account can try to specify a different destination and steal the
|
||||||
|
* funds. This also allows tracking only a single set of signatures, since we
|
||||||
|
* know which account will send the {@link XChainCommit} transaction.
|
||||||
|
*/
|
||||||
|
OtherChainSource: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attestations collected from the witness servers. This includes the parameters
|
||||||
|
* needed to recreate the message that was signed, including the amount, which
|
||||||
|
* chain (locking or issuing), optional destination, and reward account for that
|
||||||
|
* signature.
|
||||||
|
*/
|
||||||
|
XChainClaimAttestations: Array<{
|
||||||
|
// TODO: add docs
|
||||||
|
XChainClaimProofSig: {
|
||||||
|
Amount: Amount
|
||||||
|
|
||||||
|
AttestationRewardAccount: string
|
||||||
|
|
||||||
|
AttestationSignerAccount: string
|
||||||
|
|
||||||
|
Destination?: string
|
||||||
|
|
||||||
|
PublicKey: string
|
||||||
|
|
||||||
|
WasLockingChainSend: 0 | 1
|
||||||
|
}
|
||||||
|
}>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The total amount to pay the witness servers for their signatures. It must be at
|
||||||
|
* least the value of the SignatureReward in the {@link Bridge} ledger object.
|
||||||
|
*/
|
||||||
|
SignatureReward: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit-map of boolean flags. No flags are defined for XChainOwnedClaimIDs,
|
||||||
|
* so this value is always 0.
|
||||||
|
*/
|
||||||
|
Flags: 0
|
||||||
|
/**
|
||||||
|
* A hint indicating which page of the sender's owner directory links to this
|
||||||
|
* object, in case the directory consists of multiple pages.
|
||||||
|
*/
|
||||||
|
OwnerNode: string
|
||||||
|
/**
|
||||||
|
* The identifying hash of the transaction that most recently modified this
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
PreviousTxnID: string
|
||||||
|
/**
|
||||||
|
* The index of the ledger that contains the transaction that most recently
|
||||||
|
* modified this object.
|
||||||
|
*/
|
||||||
|
PreviousTxnLgrSeq: number
|
||||||
|
}
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
import { XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import BaseLedgerEntry from './BaseLedgerEntry'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainOwnedCreateAccountClaimID ledger object is used to collect attestations
|
||||||
|
* for creating an account via a cross-chain transfer.
|
||||||
|
*
|
||||||
|
* @category Ledger Entries
|
||||||
|
*/
|
||||||
|
export default interface XChainOwnedCreateAccountClaimID
|
||||||
|
extends BaseLedgerEntry {
|
||||||
|
LedgerEntryType: 'XChainOwnedCreateAccountClaimID'
|
||||||
|
|
||||||
|
/** The account that owns this object. */
|
||||||
|
Account: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The door accounts and assets of the bridge this object correlates to.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An integer that determines the order that accounts created through
|
||||||
|
* cross-chain transfers must be performed. Smaller numbers must execute
|
||||||
|
* before larger numbers.
|
||||||
|
*/
|
||||||
|
XChainAccountCreateCount: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attestations collected from the witness servers. This includes the parameters
|
||||||
|
* needed to recreate the message that was signed, including the amount, destination,
|
||||||
|
* signature reward amount, and reward account for that signature. With the
|
||||||
|
* exception of the reward account, all signatures must sign the message created with
|
||||||
|
* common parameters.
|
||||||
|
*/
|
||||||
|
XChainCreateAccountAttestations: Array<{
|
||||||
|
// TODO: add docs
|
||||||
|
XChainCreateAccountProofSig: {
|
||||||
|
Amount: string
|
||||||
|
|
||||||
|
AttestationRewardAccount: string
|
||||||
|
|
||||||
|
AttestationSignerAccount: string
|
||||||
|
|
||||||
|
Destination: string
|
||||||
|
|
||||||
|
PublicKey: string
|
||||||
|
|
||||||
|
WasLockingChainSend: 0 | 1
|
||||||
|
}
|
||||||
|
}>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A bit-map of boolean flags. No flags are defined for,
|
||||||
|
* XChainOwnedCreateAccountClaimIDs, so this value is always 0.
|
||||||
|
*/
|
||||||
|
Flags: 0
|
||||||
|
/**
|
||||||
|
* A hint indicating which page of the sender's owner directory links to this
|
||||||
|
* object, in case the directory consists of multiple pages.
|
||||||
|
*/
|
||||||
|
OwnerNode: string
|
||||||
|
/**
|
||||||
|
* The identifying hash of the transaction that most recently modified this
|
||||||
|
* object.
|
||||||
|
*/
|
||||||
|
PreviousTxnID: string
|
||||||
|
/**
|
||||||
|
* The index of the ledger that contains the transaction that most recently
|
||||||
|
* modified this object.
|
||||||
|
*/
|
||||||
|
PreviousTxnLgrSeq: number
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ import AccountRoot, {
|
|||||||
} from './AccountRoot'
|
} from './AccountRoot'
|
||||||
import Amendments, { Majority, AMENDMENTS_ID } from './Amendments'
|
import Amendments, { Majority, AMENDMENTS_ID } from './Amendments'
|
||||||
import AMM, { VoteSlot } from './AMM'
|
import AMM, { VoteSlot } from './AMM'
|
||||||
|
import Bridge from './Bridge'
|
||||||
import Check from './Check'
|
import Check from './Check'
|
||||||
import DepositPreauth from './DepositPreauth'
|
import DepositPreauth from './DepositPreauth'
|
||||||
import DirectoryNode from './DirectoryNode'
|
import DirectoryNode from './DirectoryNode'
|
||||||
@@ -24,6 +25,8 @@ import PayChannel from './PayChannel'
|
|||||||
import RippleState, { RippleStateFlags } from './RippleState'
|
import RippleState, { RippleStateFlags } from './RippleState'
|
||||||
import SignerList, { SignerListFlags } from './SignerList'
|
import SignerList, { SignerListFlags } from './SignerList'
|
||||||
import Ticket from './Ticket'
|
import Ticket from './Ticket'
|
||||||
|
import XChainOwnedClaimID from './XChainOwnedClaimID'
|
||||||
|
import XChainOwnedCreateAccountClaimID from './XChainOwnedCreateAccountClaimID'
|
||||||
|
|
||||||
export {
|
export {
|
||||||
AccountRoot,
|
AccountRoot,
|
||||||
@@ -32,6 +35,7 @@ export {
|
|||||||
AMENDMENTS_ID,
|
AMENDMENTS_ID,
|
||||||
Amendments,
|
Amendments,
|
||||||
AMM,
|
AMM,
|
||||||
|
Bridge,
|
||||||
Check,
|
Check,
|
||||||
DepositPreauth,
|
DepositPreauth,
|
||||||
DirectoryNode,
|
DirectoryNode,
|
||||||
@@ -57,5 +61,7 @@ export {
|
|||||||
SignerList,
|
SignerList,
|
||||||
SignerListFlags,
|
SignerListFlags,
|
||||||
Ticket,
|
Ticket,
|
||||||
|
XChainOwnedClaimID,
|
||||||
|
XChainOwnedCreateAccountClaimID,
|
||||||
VoteSlot,
|
VoteSlot,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import {
|
import {
|
||||||
AMM,
|
AMM,
|
||||||
|
Bridge,
|
||||||
Check,
|
Check,
|
||||||
DepositPreauth,
|
DepositPreauth,
|
||||||
Escrow,
|
Escrow,
|
||||||
@@ -8,12 +9,15 @@ import {
|
|||||||
RippleState,
|
RippleState,
|
||||||
SignerList,
|
SignerList,
|
||||||
Ticket,
|
Ticket,
|
||||||
|
XChainOwnedClaimID,
|
||||||
|
XChainOwnedCreateAccountClaimID,
|
||||||
} from '../ledger'
|
} from '../ledger'
|
||||||
|
|
||||||
import { BaseRequest, BaseResponse, LookupByLedgerRequest } from './baseMethod'
|
import { BaseRequest, BaseResponse, LookupByLedgerRequest } from './baseMethod'
|
||||||
|
|
||||||
export type AccountObjectType =
|
export type AccountObjectType =
|
||||||
| 'amm'
|
| 'amm'
|
||||||
|
| 'bridge'
|
||||||
| 'check'
|
| 'check'
|
||||||
| 'deposit_preauth'
|
| 'deposit_preauth'
|
||||||
| 'escrow'
|
| 'escrow'
|
||||||
@@ -23,6 +27,8 @@ export type AccountObjectType =
|
|||||||
| 'signer_list'
|
| 'signer_list'
|
||||||
| 'state'
|
| 'state'
|
||||||
| 'ticket'
|
| 'ticket'
|
||||||
|
| 'xchain_owned_create_account_claim_id'
|
||||||
|
| 'xchain_owned_claim_id'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The account_objects command returns the raw ledger format for all objects
|
* The account_objects command returns the raw ledger format for all objects
|
||||||
@@ -67,6 +73,7 @@ export interface AccountObjectsRequest
|
|||||||
*/
|
*/
|
||||||
export type AccountObject =
|
export type AccountObject =
|
||||||
| AMM
|
| AMM
|
||||||
|
| Bridge
|
||||||
| Check
|
| Check
|
||||||
| DepositPreauth
|
| DepositPreauth
|
||||||
| Escrow
|
| Escrow
|
||||||
@@ -75,6 +82,8 @@ export type AccountObject =
|
|||||||
| SignerList
|
| SignerList
|
||||||
| RippleState
|
| RippleState
|
||||||
| Ticket
|
| Ticket
|
||||||
|
| XChainOwnedClaimID
|
||||||
|
| XChainOwnedCreateAccountClaimID
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Response expected from an {@link AccountObjectsRequest}.
|
* Response expected from an {@link AccountObjectsRequest}.
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { Currency, XChainBridge } from '../common'
|
||||||
import { LedgerEntry } from '../ledger'
|
import { LedgerEntry } from '../ledger'
|
||||||
|
|
||||||
import { BaseRequest, BaseResponse, LookupByLedgerRequest } from './baseMethod'
|
import { BaseRequest, BaseResponse, LookupByLedgerRequest } from './baseMethod'
|
||||||
@@ -152,6 +153,30 @@ export interface LedgerEntryRequest extends BaseRequest, LookupByLedgerRequest {
|
|||||||
* Must be the object ID of the NFToken page, as hexadecimal
|
* Must be the object ID of the NFToken page, as hexadecimal
|
||||||
*/
|
*/
|
||||||
nft_page?: string
|
nft_page?: string
|
||||||
|
|
||||||
|
bridge_account?: string
|
||||||
|
|
||||||
|
bridge?: XChainBridge
|
||||||
|
|
||||||
|
xchain_owned_claim_id?:
|
||||||
|
| {
|
||||||
|
locking_chain_door: string
|
||||||
|
locking_chain_issue: Currency
|
||||||
|
issuing_chain_door: string
|
||||||
|
issuing_chain_issue: Currency
|
||||||
|
xchain_owned_claim_id: string | number
|
||||||
|
}
|
||||||
|
| string
|
||||||
|
|
||||||
|
xchain_owned_create_account_claim_id?:
|
||||||
|
| {
|
||||||
|
locking_chain_door: string
|
||||||
|
locking_chain_issue: Currency
|
||||||
|
issuing_chain_door: string
|
||||||
|
issuing_chain_issue: Currency
|
||||||
|
xchain_owned_create_account_claim_id: string | number
|
||||||
|
}
|
||||||
|
| string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
import { isString } from 'lodash'
|
||||||
|
|
||||||
|
import { Amount, XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import {
|
||||||
|
BaseTransaction,
|
||||||
|
isAmount,
|
||||||
|
isXChainBridge,
|
||||||
|
validateBaseTransaction,
|
||||||
|
validateRequiredField,
|
||||||
|
} from './common'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainAccountCreateCommit transaction creates a new account on one of the
|
||||||
|
* chains a bridge connects, which serves as the bridge entrance for that chain.
|
||||||
|
*
|
||||||
|
* Warning: This transaction should only be executed if the witness attestations
|
||||||
|
* will be reliably delivered to the destination chain. If the signatures aren't
|
||||||
|
* delivered, then account creation will be blocked until attestations are received.
|
||||||
|
* This can be used maliciously; to disable this transaction on XRP-XRP bridges,
|
||||||
|
* the bridge's MinAccountCreateAmount shouldn't be present.
|
||||||
|
*
|
||||||
|
* @category Transaction Models
|
||||||
|
*/
|
||||||
|
export interface XChainAccountCreateCommit extends BaseTransaction {
|
||||||
|
TransactionType: 'XChainAccountCreateCommit'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bridge to create accounts for.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount, in XRP, to be used to reward the witness servers for providing
|
||||||
|
* signatures. This must match the amount on the {@link Bridge} ledger object.
|
||||||
|
*/
|
||||||
|
SignatureReward: Amount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The destination account on the destination chain.
|
||||||
|
*/
|
||||||
|
Destination: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount, in XRP, to use for account creation. This must be greater than or
|
||||||
|
* equal to the MinAccountCreateAmount specified in the {@link Bridge} ledger object.
|
||||||
|
*/
|
||||||
|
Amount: Amount
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an XChainAccountCreateCommit at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - An XChainAccountCreateCommit Transaction.
|
||||||
|
* @throws When the XChainAccountCreateCommit is malformed.
|
||||||
|
*/
|
||||||
|
export function validateXChainAccountCreateCommit(
|
||||||
|
tx: Record<string, unknown>,
|
||||||
|
): void {
|
||||||
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'XChainBridge', isXChainBridge)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'SignatureReward', isAmount)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Destination', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Amount', isAmount)
|
||||||
|
}
|
||||||
@@ -0,0 +1,121 @@
|
|||||||
|
import { Amount, XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import {
|
||||||
|
BaseTransaction,
|
||||||
|
isAmount,
|
||||||
|
isNumber,
|
||||||
|
isString,
|
||||||
|
isXChainBridge,
|
||||||
|
validateBaseTransaction,
|
||||||
|
validateRequiredField,
|
||||||
|
} from './common'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainAddAccountCreateAttestation transaction provides an attestation
|
||||||
|
* from a witness server that a {@link XChainAccountCreateCommit} transaction
|
||||||
|
* occurred on the other chain.
|
||||||
|
*
|
||||||
|
* @category Transaction Models
|
||||||
|
*/
|
||||||
|
export interface XChainAddAccountCreateAttestation extends BaseTransaction {
|
||||||
|
TransactionType: 'XChainAddAccountCreateAttestation'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount committed by the {@link XChainAccountCreateCommit} transaction
|
||||||
|
* on the source chain.
|
||||||
|
*/
|
||||||
|
Amount: Amount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The account that should receive this signer's share of the SignatureReward.
|
||||||
|
*/
|
||||||
|
AttestationRewardAccount: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The account on the door account's signer list that is signing the transaction.
|
||||||
|
*/
|
||||||
|
AttestationSignerAccount: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The destination account for the funds on the destination chain.
|
||||||
|
*/
|
||||||
|
Destination: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The account on the source chain that submitted the {@link XChainAccountCreateCommit}
|
||||||
|
* transaction that triggered the event associated with the attestation.
|
||||||
|
*/
|
||||||
|
OtherChainSource: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The public key used to verify the signature.
|
||||||
|
*/
|
||||||
|
PublicKey: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signature attesting to the event on the other chain.
|
||||||
|
*/
|
||||||
|
Signature: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signature reward paid in the {@link XChainAccountCreateCommit} transaction.
|
||||||
|
*/
|
||||||
|
SignatureReward: Amount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing the chain where the event occurred.
|
||||||
|
*/
|
||||||
|
WasLockingChainSend: 0 | 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The counter that represents the order that the claims must be processed in.
|
||||||
|
*/
|
||||||
|
XChainAccountCreateCount: number | string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bridge associated with the attestation.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an XChainAddAccountCreateAttestation at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - An XChainAddAccountCreateAttestation Transaction.
|
||||||
|
* @throws When the XChainAddAccountCreateAttestation is malformed.
|
||||||
|
*/
|
||||||
|
export function validateXChainAddAccountCreateAttestation(
|
||||||
|
tx: Record<string, unknown>,
|
||||||
|
): void {
|
||||||
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Amount', isAmount)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'AttestationRewardAccount', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'AttestationSignerAccount', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Destination', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'OtherChainSource', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'PublicKey', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Signature', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'SignatureReward', isAmount)
|
||||||
|
|
||||||
|
validateRequiredField(
|
||||||
|
tx,
|
||||||
|
'WasLockingChainSend',
|
||||||
|
(inp) => inp === 0 || inp === 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
validateRequiredField(
|
||||||
|
tx,
|
||||||
|
'XChainAccountCreateCount',
|
||||||
|
(inp) => isNumber(inp) || isString(inp),
|
||||||
|
)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'XChainBridge', isXChainBridge)
|
||||||
|
}
|
||||||
@@ -0,0 +1,115 @@
|
|||||||
|
import { Amount, XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import {
|
||||||
|
BaseTransaction,
|
||||||
|
isAmount,
|
||||||
|
isNumber,
|
||||||
|
isString,
|
||||||
|
isXChainBridge,
|
||||||
|
validateBaseTransaction,
|
||||||
|
validateOptionalField,
|
||||||
|
validateRequiredField,
|
||||||
|
} from './common'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainAddClaimAttestation transaction provides proof from a witness server,
|
||||||
|
* attesting to an {@link XChainCommit} transaction.
|
||||||
|
*
|
||||||
|
* @category Transaction Models
|
||||||
|
*/
|
||||||
|
export interface XChainAddClaimAttestation extends BaseTransaction {
|
||||||
|
TransactionType: 'XChainAddClaimAttestation'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount committed by the {@link XChainCommit} transaction on the source chain.
|
||||||
|
*/
|
||||||
|
Amount: Amount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The account that should receive this signer's share of the SignatureReward.
|
||||||
|
*/
|
||||||
|
AttestationRewardAccount: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The account on the door account's signer list that is signing the transaction.
|
||||||
|
*/
|
||||||
|
AttestationSignerAccount: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The destination account for the funds on the destination chain (taken from
|
||||||
|
* the {@link XChainCommit} transaction).
|
||||||
|
*/
|
||||||
|
Destination?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The account on the source chain that submitted the {@link XChainCommit}
|
||||||
|
* transaction that triggered the event associated with the attestation.
|
||||||
|
*/
|
||||||
|
OtherChainSource: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The public key used to verify the attestation signature.
|
||||||
|
*/
|
||||||
|
PublicKey: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signature attesting to the event on the other chain.
|
||||||
|
*/
|
||||||
|
Signature: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A boolean representing the chain where the event occurred.
|
||||||
|
*/
|
||||||
|
WasLockingChainSend: 0 | 1
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bridge to use to transfer funds.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainClaimID associated with the transfer, which was included in the
|
||||||
|
* {@link XChainCommit} transaction.
|
||||||
|
*/
|
||||||
|
XChainClaimID: number | string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an XChainAddClaimAttestation at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - An XChainAddClaimAttestation Transaction.
|
||||||
|
* @throws When the XChainAddClaimAttestation is malformed.
|
||||||
|
*/
|
||||||
|
export function validateXChainAddClaimAttestation(
|
||||||
|
tx: Record<string, unknown>,
|
||||||
|
): void {
|
||||||
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Amount', isAmount)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'AttestationRewardAccount', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'AttestationSignerAccount', isString)
|
||||||
|
|
||||||
|
validateOptionalField(tx, 'Destination', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'OtherChainSource', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'PublicKey', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Signature', isString)
|
||||||
|
|
||||||
|
validateRequiredField(
|
||||||
|
tx,
|
||||||
|
'WasLockingChainSend',
|
||||||
|
(inp) => inp === 0 || inp === 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'XChainBridge', isXChainBridge)
|
||||||
|
|
||||||
|
validateRequiredField(
|
||||||
|
tx,
|
||||||
|
'XChainClaimID',
|
||||||
|
(inp) => isNumber(inp) || isString(inp),
|
||||||
|
)
|
||||||
|
}
|
||||||
77
packages/xrpl/src/models/transactions/XChainClaim.ts
Normal file
77
packages/xrpl/src/models/transactions/XChainClaim.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import { Amount, XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import {
|
||||||
|
BaseTransaction,
|
||||||
|
isAmount,
|
||||||
|
isNumber,
|
||||||
|
isString,
|
||||||
|
isXChainBridge,
|
||||||
|
validateBaseTransaction,
|
||||||
|
validateOptionalField,
|
||||||
|
validateRequiredField,
|
||||||
|
} from './common'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainClaim transaction completes a cross-chain transfer of value. It
|
||||||
|
* allows a user to claim the value on the destination chain - the equivalent
|
||||||
|
* of the value locked on the source chain.
|
||||||
|
*
|
||||||
|
* @category Transaction Models
|
||||||
|
*/
|
||||||
|
export interface XChainClaim extends BaseTransaction {
|
||||||
|
TransactionType: 'XChainClaim'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bridge to use for the transfer.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique integer ID for the cross-chain transfer that was referenced in the
|
||||||
|
* corresponding {@link XChainCommit} transaction.
|
||||||
|
*/
|
||||||
|
XChainClaimID: number | string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The destination account on the destination chain. It must exist or the
|
||||||
|
* transaction will fail. However, if the transaction fails in this case, the
|
||||||
|
* sequence number and collected signatures won't be destroyed, and the
|
||||||
|
* transaction can be rerun with a different destination.
|
||||||
|
*/
|
||||||
|
Destination: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An integer destination tag.
|
||||||
|
*/
|
||||||
|
DestinationTag?: number
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount to claim on the destination chain. This must match the amount
|
||||||
|
* attested to on the attestations associated with this XChainClaimID.
|
||||||
|
*/
|
||||||
|
Amount: Amount
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an XChainClaim at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - An XChainClaim Transaction.
|
||||||
|
* @throws When the XChainClaim is malformed.
|
||||||
|
*/
|
||||||
|
export function validateXChainClaim(tx: Record<string, unknown>): void {
|
||||||
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'XChainBridge', isXChainBridge)
|
||||||
|
|
||||||
|
validateRequiredField(
|
||||||
|
tx,
|
||||||
|
'XChainClaimID',
|
||||||
|
(inp) => isNumber(inp) || isString(inp),
|
||||||
|
)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Destination', isString)
|
||||||
|
|
||||||
|
validateOptionalField(tx, 'DestinationTag', isNumber)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Amount', isAmount)
|
||||||
|
}
|
||||||
74
packages/xrpl/src/models/transactions/XChainCommit.ts
Normal file
74
packages/xrpl/src/models/transactions/XChainCommit.ts
Normal file
@@ -0,0 +1,74 @@
|
|||||||
|
import { Amount, XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import {
|
||||||
|
BaseTransaction,
|
||||||
|
isAmount,
|
||||||
|
isNumber,
|
||||||
|
isString,
|
||||||
|
isXChainBridge,
|
||||||
|
validateBaseTransaction,
|
||||||
|
validateOptionalField,
|
||||||
|
validateRequiredField,
|
||||||
|
} from './common'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainCommit is the second step in a cross-chain transfer. It puts assets
|
||||||
|
* into trust on the locking chain so that they can be wrapped on the issuing
|
||||||
|
* chain, or burns wrapped assets on the issuing chain so that they can be returned
|
||||||
|
* on the locking chain.
|
||||||
|
*
|
||||||
|
* @category Transaction Models
|
||||||
|
*/
|
||||||
|
export interface XChainCommit extends BaseTransaction {
|
||||||
|
TransactionType: 'XChainCommit'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bridge to use to transfer funds.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique integer ID for a cross-chain transfer. This must be acquired on
|
||||||
|
* the destination chain (via a {@link XChainCreateClaimID} transaction) and
|
||||||
|
* checked from a validated ledger before submitting this transaction. If an
|
||||||
|
* incorrect sequence number is specified, the funds will be lost.
|
||||||
|
*/
|
||||||
|
XChainClaimID: number | string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The destination account on the destination chain. If this is not specified,
|
||||||
|
* the account that submitted the {@link XChainCreateClaimID} transaction on the
|
||||||
|
* destination chain will need to submit a {@link XChainClaim} transaction to
|
||||||
|
* claim the funds.
|
||||||
|
*/
|
||||||
|
OtherChainDestination?: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The asset to commit, and the quantity. This must match the door account's
|
||||||
|
* LockingChainIssue (if on the locking chain) or the door account's
|
||||||
|
* IssuingChainIssue (if on the issuing chain).
|
||||||
|
*/
|
||||||
|
Amount: Amount
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an XChainCommit at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - An XChainCommit Transaction.
|
||||||
|
* @throws When the XChainCommit is malformed.
|
||||||
|
*/
|
||||||
|
export function validateXChainCommit(tx: Record<string, unknown>): void {
|
||||||
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'XChainBridge', isXChainBridge)
|
||||||
|
|
||||||
|
validateRequiredField(
|
||||||
|
tx,
|
||||||
|
'XChainClaimID',
|
||||||
|
(inp) => isNumber(inp) || isString(inp),
|
||||||
|
)
|
||||||
|
|
||||||
|
validateOptionalField(tx, 'OtherChainDestination', isString)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'Amount', isAmount)
|
||||||
|
}
|
||||||
56
packages/xrpl/src/models/transactions/XChainCreateBridge.ts
Normal file
56
packages/xrpl/src/models/transactions/XChainCreateBridge.ts
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
import { Amount, XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import {
|
||||||
|
BaseTransaction,
|
||||||
|
isAmount,
|
||||||
|
isXChainBridge,
|
||||||
|
validateBaseTransaction,
|
||||||
|
validateOptionalField,
|
||||||
|
validateRequiredField,
|
||||||
|
} from './common'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainCreateBridge transaction creates a new {@link Bridge} ledger object
|
||||||
|
* and defines a new cross-chain bridge entrance on the chain that the transaction
|
||||||
|
* is submitted on. It includes information about door accounts and assets for the
|
||||||
|
* bridge.
|
||||||
|
*
|
||||||
|
* @category Transaction Models
|
||||||
|
*/
|
||||||
|
export interface XChainCreateBridge extends BaseTransaction {
|
||||||
|
TransactionType: 'XChainCreateBridge'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bridge (door accounts and assets) to create.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The total amount to pay the witness servers for their signatures. This amount
|
||||||
|
* will be split among the signers.
|
||||||
|
*/
|
||||||
|
SignatureReward: Amount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum amount, in XRP, required for a {@link XChainAccountCreateCommit}
|
||||||
|
* transaction. If this isn't present, the {@link XChainAccountCreateCommit}
|
||||||
|
* transaction will fail. This field can only be present on XRP-XRP bridges.
|
||||||
|
*/
|
||||||
|
MinAccountCreateAmount?: Amount
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an XChainCreateBridge at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - An XChainCreateBridge Transaction.
|
||||||
|
* @throws When the XChainCreateBridge is malformed.
|
||||||
|
*/
|
||||||
|
export function validateXChainCreateBridge(tx: Record<string, unknown>): void {
|
||||||
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'XChainBridge', isXChainBridge)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'SignatureReward', isAmount)
|
||||||
|
|
||||||
|
validateOptionalField(tx, 'MinAccountCreateAmount', isAmount)
|
||||||
|
}
|
||||||
53
packages/xrpl/src/models/transactions/XChainCreateClaimID.ts
Normal file
53
packages/xrpl/src/models/transactions/XChainCreateClaimID.ts
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
import { Amount, XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import {
|
||||||
|
BaseTransaction,
|
||||||
|
isAmount,
|
||||||
|
isString,
|
||||||
|
isXChainBridge,
|
||||||
|
validateBaseTransaction,
|
||||||
|
validateRequiredField,
|
||||||
|
} from './common'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainCreateClaimID transaction creates a new cross-chain claim ID that is
|
||||||
|
* used for a cross-chain transfer. A cross-chain claim ID represents one
|
||||||
|
* cross-chain transfer of value.
|
||||||
|
*
|
||||||
|
* @category Transaction Models
|
||||||
|
*/
|
||||||
|
export interface XChainCreateClaimID extends BaseTransaction {
|
||||||
|
TransactionType: 'XChainCreateClaimID'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bridge to create the claim ID for.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The amount, in XRP, to reward the witness servers for providing signatures.
|
||||||
|
* This must match the amount on the {@link Bridge} ledger object.
|
||||||
|
*/
|
||||||
|
SignatureReward: Amount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The account that must send the {@link XChainCommit} transaction on the source chain.
|
||||||
|
*/
|
||||||
|
OtherChainSource: string
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an XChainCreateClaimID at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - An XChainCreateClaimID Transaction.
|
||||||
|
* @throws When the XChainCreateClaimID is malformed.
|
||||||
|
*/
|
||||||
|
export function validateXChainCreateClaimID(tx: Record<string, unknown>): void {
|
||||||
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'XChainBridge', isXChainBridge)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'SignatureReward', isAmount)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'OtherChainSource', isString)
|
||||||
|
}
|
||||||
77
packages/xrpl/src/models/transactions/XChainModifyBridge.ts
Normal file
77
packages/xrpl/src/models/transactions/XChainModifyBridge.ts
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
import { Amount, XChainBridge } from '../common'
|
||||||
|
|
||||||
|
import {
|
||||||
|
BaseTransaction,
|
||||||
|
GlobalFlags,
|
||||||
|
isAmount,
|
||||||
|
isXChainBridge,
|
||||||
|
validateBaseTransaction,
|
||||||
|
validateOptionalField,
|
||||||
|
validateRequiredField,
|
||||||
|
} from './common'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Enum representing values of {@link XChainModifyBridge} transaction flags.
|
||||||
|
*
|
||||||
|
* @category Transaction Flags
|
||||||
|
*/
|
||||||
|
export enum XChainModifyBridgeFlags {
|
||||||
|
/** Clears the MinAccountCreateAmount of the bridge. */
|
||||||
|
tfClearAccountCreateAmount = 0x00010000,
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Map of flags to boolean values representing {@link XChainModifyBridge} transaction
|
||||||
|
* flags.
|
||||||
|
*
|
||||||
|
* @category Transaction Flags
|
||||||
|
*/
|
||||||
|
export interface XChainModifyBridgeFlagsInterface extends GlobalFlags {
|
||||||
|
/** Clears the MinAccountCreateAmount of the bridge. */
|
||||||
|
tfClearAccountCreateAmount?: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The XChainModifyBridge transaction allows bridge managers to modify the parameters
|
||||||
|
* of the bridge.
|
||||||
|
*
|
||||||
|
* @category Transaction Models
|
||||||
|
*/
|
||||||
|
export interface XChainModifyBridge extends BaseTransaction {
|
||||||
|
TransactionType: 'XChainModifyBridge'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bridge to modify.
|
||||||
|
*/
|
||||||
|
XChainBridge: XChainBridge
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The signature reward split between the witnesses for submitting attestations.
|
||||||
|
*/
|
||||||
|
SignatureReward?: Amount
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The minimum amount, in XRP, required for a {@link XChainAccountCreateCommit}
|
||||||
|
* transaction. If this is not present, the {@link XChainAccountCreateCommit}
|
||||||
|
* transaction will fail. This field can only be present on XRP-XRP bridges.
|
||||||
|
*/
|
||||||
|
MinAccountCreateAmount?: Amount
|
||||||
|
|
||||||
|
Flags?: number | XChainModifyBridgeFlagsInterface
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an XChainModifyBridge at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - An XChainModifyBridge Transaction.
|
||||||
|
* @throws When the XChainModifyBridge is malformed.
|
||||||
|
*/
|
||||||
|
export function validateXChainModifyBridge(tx: Record<string, unknown>): void {
|
||||||
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
validateRequiredField(tx, 'XChainBridge', isXChainBridge)
|
||||||
|
|
||||||
|
validateOptionalField(tx, 'SignatureReward', isAmount)
|
||||||
|
|
||||||
|
validateOptionalField(tx, 'MinAccountCreateAmount', isAmount)
|
||||||
|
}
|
||||||
@@ -1,9 +1,14 @@
|
|||||||
/* eslint-disable max-lines-per-function -- Necessary for validateBaseTransaction */
|
|
||||||
/* eslint-disable max-statements -- Necessary for validateBaseTransaction */
|
|
||||||
import { TRANSACTION_TYPES } from 'ripple-binary-codec'
|
import { TRANSACTION_TYPES } from 'ripple-binary-codec'
|
||||||
|
|
||||||
import { ValidationError } from '../../errors'
|
import { ValidationError } from '../../errors'
|
||||||
import { Amount, Currency, IssuedCurrencyAmount, Memo, Signer } from '../common'
|
import {
|
||||||
|
Amount,
|
||||||
|
Currency,
|
||||||
|
IssuedCurrencyAmount,
|
||||||
|
Memo,
|
||||||
|
Signer,
|
||||||
|
XChainBridge,
|
||||||
|
} from '../common'
|
||||||
import { onlyHasFields } from '../utils'
|
import { onlyHasFields } from '../utils'
|
||||||
|
|
||||||
const MEMO_SIZE = 3
|
const MEMO_SIZE = 3
|
||||||
@@ -52,11 +57,32 @@ function isSigner(obj: unknown): boolean {
|
|||||||
const XRP_CURRENCY_SIZE = 1
|
const XRP_CURRENCY_SIZE = 1
|
||||||
const ISSUE_SIZE = 2
|
const ISSUE_SIZE = 2
|
||||||
const ISSUED_CURRENCY_SIZE = 3
|
const ISSUED_CURRENCY_SIZE = 3
|
||||||
|
const XCHAIN_BRIDGE_SIZE = 4
|
||||||
|
|
||||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||||
return value !== null && typeof value === 'object'
|
return value !== null && typeof value === 'object'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of a string at runtime.
|
||||||
|
*
|
||||||
|
* @param str - The object to check the form and type of.
|
||||||
|
* @returns Whether the string is properly formed.
|
||||||
|
*/
|
||||||
|
export function isString(str: unknown): str is string {
|
||||||
|
return typeof str === 'string'
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of a number at runtime.
|
||||||
|
*
|
||||||
|
* @param num - The object to check the form and type of.
|
||||||
|
* @returns Whether the number is properly formed.
|
||||||
|
*/
|
||||||
|
export function isNumber(num: unknown): num is number {
|
||||||
|
return typeof num === 'number'
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Verify the form and type of an IssuedCurrency at runtime.
|
* Verify the form and type of an IssuedCurrency at runtime.
|
||||||
*
|
*
|
||||||
@@ -102,6 +128,73 @@ export function isAmount(amount: unknown): amount is Amount {
|
|||||||
return typeof amount === 'string' || isIssuedCurrency(amount)
|
return typeof amount === 'string' || isIssuedCurrency(amount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an XChainBridge at runtime.
|
||||||
|
*
|
||||||
|
* @param input - The input to check the form and type of.
|
||||||
|
* @returns Whether the XChainBridge is properly formed.
|
||||||
|
*/
|
||||||
|
export function isXChainBridge(input: unknown): input is XChainBridge {
|
||||||
|
return (
|
||||||
|
isRecord(input) &&
|
||||||
|
Object.keys(input).length === XCHAIN_BRIDGE_SIZE &&
|
||||||
|
typeof input.LockingChainDoor === 'string' &&
|
||||||
|
isCurrency(input.LockingChainIssue) &&
|
||||||
|
typeof input.IssuingChainDoor === 'string' &&
|
||||||
|
isCurrency(input.IssuingChainIssue)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint-disable @typescript-eslint/restrict-template-expressions -- tx.TransactionType is checked before any calls */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of a required type for a transaction at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - The transaction input to check the form and type of.
|
||||||
|
* @param paramName - The name of the transaction parameter.
|
||||||
|
* @param checkValidity - The function to use to check the type.
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
export function validateRequiredField(
|
||||||
|
tx: Record<string, unknown>,
|
||||||
|
paramName: string,
|
||||||
|
checkValidity: (inp: unknown) => boolean,
|
||||||
|
): void {
|
||||||
|
if (tx[paramName] == null) {
|
||||||
|
throw new ValidationError(
|
||||||
|
`${tx.TransactionType}: missing field ${paramName}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!checkValidity(tx[paramName])) {
|
||||||
|
throw new ValidationError(
|
||||||
|
`${tx.TransactionType}: invalid field ${paramName}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verify the form and type of an optional type for a transaction at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - The transaction input to check the form and type of.
|
||||||
|
* @param paramName - The name of the transaction parameter.
|
||||||
|
* @param checkValidity - The function to use to check the type.
|
||||||
|
* @throws
|
||||||
|
*/
|
||||||
|
export function validateOptionalField(
|
||||||
|
tx: Record<string, unknown>,
|
||||||
|
paramName: string,
|
||||||
|
checkValidity: (inp: unknown) => boolean,
|
||||||
|
): void {
|
||||||
|
if (tx[paramName] !== undefined && !checkValidity(tx[paramName])) {
|
||||||
|
throw new ValidationError(
|
||||||
|
`${tx.TransactionType}: invalid field ${paramName}`,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* eslint-enable @typescript-eslint/restrict-template-expressions -- checked before */
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface -- no global flags right now, so this is fine
|
// eslint-disable-next-line @typescript-eslint/no-empty-interface -- no global flags right now, so this is fine
|
||||||
export interface GlobalFlags {}
|
export interface GlobalFlags {}
|
||||||
|
|
||||||
@@ -190,14 +283,6 @@ export interface BaseTransaction {
|
|||||||
* @throws When the common param is malformed.
|
* @throws When the common param is malformed.
|
||||||
*/
|
*/
|
||||||
export function validateBaseTransaction(common: Record<string, unknown>): void {
|
export function validateBaseTransaction(common: Record<string, unknown>): void {
|
||||||
if (common.Account === undefined) {
|
|
||||||
throw new ValidationError('BaseTransaction: missing field Account')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof common.Account !== 'string') {
|
|
||||||
throw new ValidationError('BaseTransaction: Account not string')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (common.TransactionType === undefined) {
|
if (common.TransactionType === undefined) {
|
||||||
throw new ValidationError('BaseTransaction: missing field TransactionType')
|
throw new ValidationError('BaseTransaction: missing field TransactionType')
|
||||||
}
|
}
|
||||||
@@ -210,27 +295,15 @@ export function validateBaseTransaction(common: Record<string, unknown>): void {
|
|||||||
throw new ValidationError('BaseTransaction: Unknown TransactionType')
|
throw new ValidationError('BaseTransaction: Unknown TransactionType')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (common.Fee !== undefined && typeof common.Fee !== 'string') {
|
validateRequiredField(common, 'Account', isString)
|
||||||
throw new ValidationError('BaseTransaction: invalid Fee')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (common.Sequence !== undefined && typeof common.Sequence !== 'number') {
|
validateOptionalField(common, 'Fee', isString)
|
||||||
throw new ValidationError('BaseTransaction: invalid Sequence')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
validateOptionalField(common, 'Sequence', isNumber)
|
||||||
common.AccountTxnID !== undefined &&
|
|
||||||
typeof common.AccountTxnID !== 'string'
|
|
||||||
) {
|
|
||||||
throw new ValidationError('BaseTransaction: invalid AccountTxnID')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
validateOptionalField(common, 'AccountTxnID', isString)
|
||||||
common.LastLedgerSequence !== undefined &&
|
|
||||||
typeof common.LastLedgerSequence !== 'number'
|
validateOptionalField(common, 'LastLedgerSequence', isNumber)
|
||||||
) {
|
|
||||||
throw new ValidationError('BaseTransaction: invalid LastLedgerSequence')
|
|
||||||
}
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Only used by JS
|
||||||
const memos = common.Memos as Array<{ Memo?: unknown }> | undefined
|
const memos = common.Memos as Array<{ Memo?: unknown }> | undefined
|
||||||
@@ -248,33 +321,15 @@ export function validateBaseTransaction(common: Record<string, unknown>): void {
|
|||||||
throw new ValidationError('BaseTransaction: invalid Signers')
|
throw new ValidationError('BaseTransaction: invalid Signers')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (common.SourceTag !== undefined && typeof common.SourceTag !== 'number') {
|
validateOptionalField(common, 'SourceTag', isNumber)
|
||||||
throw new ValidationError('BaseTransaction: invalid SourceTag')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
validateOptionalField(common, 'SigningPubKey', isString)
|
||||||
common.SigningPubKey !== undefined &&
|
|
||||||
typeof common.SigningPubKey !== 'string'
|
|
||||||
) {
|
|
||||||
throw new ValidationError('BaseTransaction: invalid SigningPubKey')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
validateOptionalField(common, 'TicketSequence', isNumber)
|
||||||
common.TicketSequence !== undefined &&
|
|
||||||
typeof common.TicketSequence !== 'number'
|
|
||||||
) {
|
|
||||||
throw new ValidationError('BaseTransaction: invalid TicketSequence')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
validateOptionalField(common, 'TxnSignature', isString)
|
||||||
common.TxnSignature !== undefined &&
|
|
||||||
typeof common.TxnSignature !== 'string'
|
validateOptionalField(common, 'NetworkID', isNumber)
|
||||||
) {
|
|
||||||
throw new ValidationError('BaseTransaction: invalid TxnSignature')
|
|
||||||
}
|
|
||||||
if (common.NetworkID !== undefined && typeof common.NetworkID !== 'number') {
|
|
||||||
throw new ValidationError('BaseTransaction: invalid NetworkID')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ export {
|
|||||||
export { CheckCancel } from './checkCancel'
|
export { CheckCancel } from './checkCancel'
|
||||||
export { CheckCash } from './checkCash'
|
export { CheckCash } from './checkCash'
|
||||||
export { CheckCreate } from './checkCreate'
|
export { CheckCreate } from './checkCreate'
|
||||||
|
export { Clawback } from './clawback'
|
||||||
export { DepositPreauth } from './depositPreauth'
|
export { DepositPreauth } from './depositPreauth'
|
||||||
export { EscrowCancel } from './escrowCancel'
|
export { EscrowCancel } from './escrowCancel'
|
||||||
export { EscrowCreate } from './escrowCreate'
|
export { EscrowCreate } from './escrowCreate'
|
||||||
@@ -63,4 +64,15 @@ export { SignerListSet } from './signerListSet'
|
|||||||
export { TicketCreate } from './ticketCreate'
|
export { TicketCreate } from './ticketCreate'
|
||||||
export { TrustSetFlagsInterface, TrustSetFlags, TrustSet } from './trustSet'
|
export { TrustSetFlagsInterface, TrustSetFlags, TrustSet } from './trustSet'
|
||||||
export { UNLModify } from './UNLModify'
|
export { UNLModify } from './UNLModify'
|
||||||
export { Clawback } from './clawback'
|
export { XChainAddAccountCreateAttestation } from './XChainAddAccountCreateAttestation'
|
||||||
|
export { XChainAddClaimAttestation } from './XChainAddClaimAttestation'
|
||||||
|
export { XChainClaim } from './XChainClaim'
|
||||||
|
export { XChainCommit } from './XChainCommit'
|
||||||
|
export { XChainCreateBridge } from './XChainCreateBridge'
|
||||||
|
export { XChainCreateClaimID } from './XChainCreateClaimID'
|
||||||
|
export { XChainAccountCreateCommit } from './XChainAccountCreateCommit'
|
||||||
|
export {
|
||||||
|
XChainModifyBridge,
|
||||||
|
XChainModifyBridgeFlags,
|
||||||
|
XChainModifyBridgeFlagsInterface,
|
||||||
|
} from './XChainModifyBridge'
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable max-lines -- need to work with a lot of transactions in a switch statement */
|
||||||
/* eslint-disable max-lines-per-function -- need to work with a lot of Tx verifications */
|
/* eslint-disable max-lines-per-function -- need to work with a lot of Tx verifications */
|
||||||
|
|
||||||
import { ValidationError } from '../../errors'
|
import { ValidationError } from '../../errors'
|
||||||
@@ -56,6 +57,32 @@ import { SetRegularKey, validateSetRegularKey } from './setRegularKey'
|
|||||||
import { SignerListSet, validateSignerListSet } from './signerListSet'
|
import { SignerListSet, validateSignerListSet } from './signerListSet'
|
||||||
import { TicketCreate, validateTicketCreate } from './ticketCreate'
|
import { TicketCreate, validateTicketCreate } from './ticketCreate'
|
||||||
import { TrustSet, validateTrustSet } from './trustSet'
|
import { TrustSet, validateTrustSet } from './trustSet'
|
||||||
|
import {
|
||||||
|
XChainAccountCreateCommit,
|
||||||
|
validateXChainAccountCreateCommit,
|
||||||
|
} from './XChainAccountCreateCommit'
|
||||||
|
import {
|
||||||
|
XChainAddAccountCreateAttestation,
|
||||||
|
validateXChainAddAccountCreateAttestation,
|
||||||
|
} from './XChainAddAccountCreateAttestation'
|
||||||
|
import {
|
||||||
|
XChainAddClaimAttestation,
|
||||||
|
validateXChainAddClaimAttestation,
|
||||||
|
} from './XChainAddClaimAttestation'
|
||||||
|
import { XChainClaim, validateXChainClaim } from './XChainClaim'
|
||||||
|
import { XChainCommit, validateXChainCommit } from './XChainCommit'
|
||||||
|
import {
|
||||||
|
XChainCreateBridge,
|
||||||
|
validateXChainCreateBridge,
|
||||||
|
} from './XChainCreateBridge'
|
||||||
|
import {
|
||||||
|
XChainCreateClaimID,
|
||||||
|
validateXChainCreateClaimID,
|
||||||
|
} from './XChainCreateClaimID'
|
||||||
|
import {
|
||||||
|
XChainModifyBridge,
|
||||||
|
validateXChainModifyBridge,
|
||||||
|
} from './XChainModifyBridge'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @category Transaction Models
|
* @category Transaction Models
|
||||||
@@ -92,6 +119,14 @@ export type Transaction =
|
|||||||
| SignerListSet
|
| SignerListSet
|
||||||
| TicketCreate
|
| TicketCreate
|
||||||
| TrustSet
|
| TrustSet
|
||||||
|
| XChainAddAccountCreateAttestation
|
||||||
|
| XChainAddClaimAttestation
|
||||||
|
| XChainClaim
|
||||||
|
| XChainCommit
|
||||||
|
| XChainCreateBridge
|
||||||
|
| XChainCreateClaimID
|
||||||
|
| XChainAccountCreateCommit
|
||||||
|
| XChainModifyBridge
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @category Transaction Models
|
* @category Transaction Models
|
||||||
@@ -294,6 +329,38 @@ export function validate(transaction: Record<string, unknown>): void {
|
|||||||
validateTrustSet(tx)
|
validateTrustSet(tx)
|
||||||
break
|
break
|
||||||
|
|
||||||
|
case 'XChainAddAccountCreateAttestation':
|
||||||
|
validateXChainAddAccountCreateAttestation(tx)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'XChainAddClaimAttestation':
|
||||||
|
validateXChainAddClaimAttestation(tx)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'XChainClaim':
|
||||||
|
validateXChainClaim(tx)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'XChainCommit':
|
||||||
|
validateXChainCommit(tx)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'XChainCreateBridge':
|
||||||
|
validateXChainCreateBridge(tx)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'XChainCreateClaimID':
|
||||||
|
validateXChainCreateClaimID(tx)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'XChainAccountCreateCommit':
|
||||||
|
validateXChainAccountCreateCommit(tx)
|
||||||
|
break
|
||||||
|
|
||||||
|
case 'XChainModifyBridge':
|
||||||
|
validateXChainModifyBridge(tx)
|
||||||
|
break
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw new ValidationError(
|
throw new ValidationError(
|
||||||
`Invalid field TransactionType: ${tx.TransactionType}`,
|
`Invalid field TransactionType: ${tx.TransactionType}`,
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { PaymentFlags } from '../transactions/payment'
|
|||||||
import { PaymentChannelClaimFlags } from '../transactions/paymentChannelClaim'
|
import { PaymentChannelClaimFlags } from '../transactions/paymentChannelClaim'
|
||||||
import type { Transaction } from '../transactions/transaction'
|
import type { Transaction } from '../transactions/transaction'
|
||||||
import { TrustSetFlags } from '../transactions/trustSet'
|
import { TrustSetFlags } from '../transactions/trustSet'
|
||||||
|
import { XChainModifyBridgeFlags } from '../transactions/XChainModifyBridge'
|
||||||
|
|
||||||
import { isFlagEnabled } from '.'
|
import { isFlagEnabled } from '.'
|
||||||
|
|
||||||
@@ -78,6 +79,9 @@ export function setTransactionFlagsToNumber(tx: Transaction): void {
|
|||||||
case 'TrustSet':
|
case 'TrustSet':
|
||||||
tx.Flags = convertFlagsToNumber(tx.Flags, TrustSetFlags)
|
tx.Flags = convertFlagsToNumber(tx.Flags, TrustSetFlags)
|
||||||
return
|
return
|
||||||
|
case 'XChainModifyBridge':
|
||||||
|
tx.Flags = convertFlagsToNumber(tx.Flags, XChainModifyBridgeFlags)
|
||||||
|
return
|
||||||
default:
|
default:
|
||||||
tx.Flags = 0
|
tx.Flags = 0
|
||||||
}
|
}
|
||||||
|
|||||||
64
packages/xrpl/src/utils/getXChainClaimID.ts
Normal file
64
packages/xrpl/src/utils/getXChainClaimID.ts
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
import { decode } from 'ripple-binary-codec'
|
||||||
|
|
||||||
|
import {
|
||||||
|
CreatedNode,
|
||||||
|
isCreatedNode,
|
||||||
|
TransactionMetadata,
|
||||||
|
} from '../models/transactions/metadata'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ensures that the metadata is in a deserialized format to parse.
|
||||||
|
*
|
||||||
|
* @param meta - the metadata from a `tx` method call. Can be in json format or binary format.
|
||||||
|
* @returns the metadata in a deserialized format.
|
||||||
|
*/
|
||||||
|
function ensureDecodedMeta(
|
||||||
|
meta: TransactionMetadata | string,
|
||||||
|
): TransactionMetadata {
|
||||||
|
if (typeof meta === 'string') {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- Meta is either metadata or serialized metadata.
|
||||||
|
return decode(meta) as unknown as TransactionMetadata
|
||||||
|
}
|
||||||
|
return meta
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the XChainClaimID value from the metadata of an `XChainCreateClaimID` transaction.
|
||||||
|
*
|
||||||
|
* @param meta - Metadata from the response to submitting and waiting for an XChainCreateClaimID transaction
|
||||||
|
* or from a `tx` method call.
|
||||||
|
* @returns The XChainClaimID for the minted NFT.
|
||||||
|
* @throws if meta is not TransactionMetadata.
|
||||||
|
*/
|
||||||
|
export default function getXChainClaimID(
|
||||||
|
meta: TransactionMetadata | string | undefined,
|
||||||
|
): string | undefined {
|
||||||
|
if (typeof meta !== 'string' && meta?.AffectedNodes === undefined) {
|
||||||
|
throw new TypeError(`Unable to parse the parameter given to getXChainClaimID.
|
||||||
|
'meta' must be the metadata from an XChainCreateClaimID transaction. Received ${JSON.stringify(
|
||||||
|
meta,
|
||||||
|
)} instead.`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const decodedMeta = ensureDecodedMeta(meta)
|
||||||
|
|
||||||
|
if (!decodedMeta.TransactionResult) {
|
||||||
|
throw new TypeError(
|
||||||
|
'Cannot get XChainClaimID from un-validated transaction',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (decodedMeta.TransactionResult !== 'tesSUCCESS') {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
|
||||||
|
const createdNode = decodedMeta.AffectedNodes.find(
|
||||||
|
(node) =>
|
||||||
|
isCreatedNode(node) &&
|
||||||
|
node.CreatedNode.LedgerEntryType === 'XChainOwnedClaimID',
|
||||||
|
)
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions -- necessary here
|
||||||
|
return (createdNode as CreatedNode).CreatedNode.NewFields
|
||||||
|
.XChainClaimID as string
|
||||||
|
}
|
||||||
@@ -25,6 +25,7 @@ import { Transaction } from '../models/transactions/transaction'
|
|||||||
import { deriveKeypair, deriveAddress, deriveXAddress } from './derive'
|
import { deriveKeypair, deriveAddress, deriveXAddress } from './derive'
|
||||||
import getBalanceChanges from './getBalanceChanges'
|
import getBalanceChanges from './getBalanceChanges'
|
||||||
import getNFTokenID from './getNFTokenID'
|
import getNFTokenID from './getNFTokenID'
|
||||||
|
import getXChainClaimID from './getXChainClaimID'
|
||||||
import {
|
import {
|
||||||
hashSignedTx,
|
hashSignedTx,
|
||||||
hashTx,
|
hashTx,
|
||||||
@@ -220,4 +221,5 @@ export {
|
|||||||
encodeForSigningClaim,
|
encodeForSigningClaim,
|
||||||
getNFTokenID,
|
getNFTokenID,
|
||||||
parseNFTokenID,
|
parseNFTokenID,
|
||||||
|
getXChainClaimID,
|
||||||
}
|
}
|
||||||
|
|||||||
8
packages/xrpl/test/fixtures/rippled/index.ts
vendored
8
packages/xrpl/test/fixtures/rippled/index.ts
vendored
@@ -25,8 +25,12 @@ import successSubmit from './submit.json'
|
|||||||
import successSubscribe from './subscribe.json'
|
import successSubscribe from './subscribe.json'
|
||||||
import errorSubscribe from './subscribeError.json'
|
import errorSubscribe from './subscribeError.json'
|
||||||
import transaction_entry from './transactionEntry.json'
|
import transaction_entry from './transactionEntry.json'
|
||||||
|
import NFTokenMint from './tx/NFTokenMint.json'
|
||||||
|
import NFTokenMint2 from './tx/NFTokenMint2.json'
|
||||||
import OfferCreateSell from './tx/offerCreateSell.json'
|
import OfferCreateSell from './tx/offerCreateSell.json'
|
||||||
import Payment from './tx/payment.json'
|
import Payment from './tx/payment.json'
|
||||||
|
import XChainCreateClaimID from './tx/XChainCreateClaimID.json'
|
||||||
|
import XChainCreateClaimID2 from './tx/XChainCreateClaimID2.json'
|
||||||
import unsubscribe from './unsubscribe.json'
|
import unsubscribe from './unsubscribe.json'
|
||||||
|
|
||||||
const submit = {
|
const submit = {
|
||||||
@@ -89,8 +93,12 @@ const server_info = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const tx = {
|
const tx = {
|
||||||
|
NFTokenMint,
|
||||||
|
NFTokenMint2,
|
||||||
Payment,
|
Payment,
|
||||||
OfferCreateSell,
|
OfferCreateSell,
|
||||||
|
XChainCreateClaimID,
|
||||||
|
XChainCreateClaimID2,
|
||||||
}
|
}
|
||||||
|
|
||||||
const rippled = {
|
const rippled = {
|
||||||
|
|||||||
118
packages/xrpl/test/fixtures/rippled/tx/XChainCreateClaimID.json
vendored
Normal file
118
packages/xrpl/test/fixtures/rippled/tx/XChainCreateClaimID.json
vendored
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
{
|
||||||
|
"tx": {
|
||||||
|
"Account": "rLVUz66tawieqTPAHuTyFTN6pLbHcXiTzd",
|
||||||
|
"Fee": "20",
|
||||||
|
"Flags": 2147483648,
|
||||||
|
"NetworkID": 2552,
|
||||||
|
"OtherChainSource": "rL5Zd9m5XEoGPddMwYY5H5C8ARcR47b6oM",
|
||||||
|
"Sequence": 1007784,
|
||||||
|
"SignatureReward": "100",
|
||||||
|
"SigningPubKey": "039E925058C740A5B73E49300FC205D058520DE37F2C63C4EE3A0D1B50C4E44080",
|
||||||
|
"TransactionType": "XChainCreateClaimID",
|
||||||
|
"TxnSignature": "304402201C6F95B9997FB63DCD9854664707C58C46AA3207612FE32366B77DA084786CAF02205752C58821D7FAFAE26F77DC10AC0AFDDCBCCF4FCBED90E6B8C4523A0EB3E008",
|
||||||
|
"XChainBridge": {
|
||||||
|
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"IssuingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
},
|
||||||
|
"LockingChainDoor": "rMAXACCrp3Y8PpswXcg3bKggHX76V3F8M4",
|
||||||
|
"LockingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"date": 1695324353000
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"AffectedNodes": [
|
||||||
|
{
|
||||||
|
"ModifiedNode": {
|
||||||
|
"FinalFields": {
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"Flags": 0,
|
||||||
|
"MinAccountCreateAmount": "10000000",
|
||||||
|
"OwnerNode": "0",
|
||||||
|
"SignatureReward": "100",
|
||||||
|
"XChainAccountClaimCount": "e3",
|
||||||
|
"XChainAccountCreateCount": "0",
|
||||||
|
"XChainBridge": {
|
||||||
|
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"IssuingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
},
|
||||||
|
"LockingChainDoor": "rMAXACCrp3Y8PpswXcg3bKggHX76V3F8M4",
|
||||||
|
"LockingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"XChainClaimID": "b0"
|
||||||
|
},
|
||||||
|
"LedgerEntryType": "Bridge",
|
||||||
|
"LedgerIndex": "114C0DC89656D1B0FB1F4A3426034C3FCE75BCE65D9574B5D96ABC2B24D6C8F1",
|
||||||
|
"PreviousFields": {
|
||||||
|
"XChainClaimID": "af"
|
||||||
|
},
|
||||||
|
"PreviousTxnID": "3F6F3BBE584115D1A575AB24BA32B47184F2323B65DE5C8C8EE144A55115E0B9",
|
||||||
|
"PreviousTxnLgrSeq": 1027822
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ModifiedNode": {
|
||||||
|
"FinalFields": {
|
||||||
|
"Flags": 0,
|
||||||
|
"Owner": "rLVUz66tawieqTPAHuTyFTN6pLbHcXiTzd",
|
||||||
|
"RootIndex": "6C1EA1A93D590E831CCC0EE2CBE26C146A3A6FD36F5854DC5E5AB5CE78FAE49C"
|
||||||
|
},
|
||||||
|
"LedgerEntryType": "DirectoryNode",
|
||||||
|
"LedgerIndex": "6C1EA1A93D590E831CCC0EE2CBE26C146A3A6FD36F5854DC5E5AB5CE78FAE49C"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"CreatedNode": {
|
||||||
|
"LedgerEntryType": "XChainOwnedClaimID",
|
||||||
|
"LedgerIndex": "A00BD77AE864509D796B39041AD48E9DEFEC9AF20E5C09CEF2F5DA41D6CFEB1E",
|
||||||
|
"NewFields": {
|
||||||
|
"Account": "rLVUz66tawieqTPAHuTyFTN6pLbHcXiTzd",
|
||||||
|
"OtherChainSource": "rL5Zd9m5XEoGPddMwYY5H5C8ARcR47b6oM",
|
||||||
|
"SignatureReward": "100",
|
||||||
|
"XChainBridge": {
|
||||||
|
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"IssuingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
},
|
||||||
|
"LockingChainDoor": "rMAXACCrp3Y8PpswXcg3bKggHX76V3F8M4",
|
||||||
|
"LockingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"XChainClaimID": "b0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ModifiedNode": {
|
||||||
|
"FinalFields": {
|
||||||
|
"Account": "rLVUz66tawieqTPAHuTyFTN6pLbHcXiTzd",
|
||||||
|
"Balance": "39999940",
|
||||||
|
"Flags": 0,
|
||||||
|
"OwnerCount": 3,
|
||||||
|
"Sequence": 1007785
|
||||||
|
},
|
||||||
|
"LedgerEntryType": "AccountRoot",
|
||||||
|
"LedgerIndex": "FD919D0BAA90C759DA4C7130AEEF6AE7FA2AF074F5E867D40BCBE1ECD8D8D0EA",
|
||||||
|
"PreviousFields": {
|
||||||
|
"Balance": "39999960",
|
||||||
|
"OwnerCount": 2,
|
||||||
|
"Sequence": 1007784
|
||||||
|
},
|
||||||
|
"PreviousTxnID": "3F6F3BBE584115D1A575AB24BA32B47184F2323B65DE5C8C8EE144A55115E0B9",
|
||||||
|
"PreviousTxnLgrSeq": 1027822
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"TransactionIndex": 0,
|
||||||
|
"TransactionResult": "tesSUCCESS"
|
||||||
|
},
|
||||||
|
"hash": "998E76B9840DA5A6009592A2674D0166A9C4862193193AA46EA6B77A64781FB4",
|
||||||
|
"ledger_index": 1027837,
|
||||||
|
"date": 1695324353000
|
||||||
|
}
|
||||||
118
packages/xrpl/test/fixtures/rippled/tx/XChainCreateClaimID2.json
vendored
Normal file
118
packages/xrpl/test/fixtures/rippled/tx/XChainCreateClaimID2.json
vendored
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
{
|
||||||
|
"tx": {
|
||||||
|
"Account": "rwmUSzi5Xp31AjMTEdbvxgWqLETcVNU6Fv",
|
||||||
|
"Fee": "12",
|
||||||
|
"Flags": 0,
|
||||||
|
"LastLedgerSequence": 1027798,
|
||||||
|
"NetworkID": 2552,
|
||||||
|
"OtherChainSource": "rBXdfZ7NVpdjRfYajPMpviGgq7HLDeuBdR",
|
||||||
|
"Sequence": 1027778,
|
||||||
|
"SignatureReward": "100",
|
||||||
|
"SigningPubKey": "EDDDD69DF802B8DB82D644EF92E2C1F06AC128A275CDFF86F013180D104ED39D3B",
|
||||||
|
"TransactionType": "XChainCreateClaimID",
|
||||||
|
"TxnSignature": "67BE63527EC8A0C872F23E2C4EB97C1F3E7D3FED6D10C8310B9235D3891B6B9343768A080E258F6C3687BFC4B7C5FD429ABB33654C99DE46471FD6F2A7035303",
|
||||||
|
"XChainBridge": {
|
||||||
|
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"IssuingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
},
|
||||||
|
"LockingChainDoor": "rMAXACCrp3Y8PpswXcg3bKggHX76V3F8M4",
|
||||||
|
"LockingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"date": 1695324182000
|
||||||
|
},
|
||||||
|
"meta": {
|
||||||
|
"AffectedNodes": [
|
||||||
|
{
|
||||||
|
"ModifiedNode": {
|
||||||
|
"FinalFields": {
|
||||||
|
"Account": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"Flags": 0,
|
||||||
|
"MinAccountCreateAmount": "10000000",
|
||||||
|
"OwnerNode": "0",
|
||||||
|
"SignatureReward": "100",
|
||||||
|
"XChainAccountClaimCount": "e2",
|
||||||
|
"XChainAccountCreateCount": "0",
|
||||||
|
"XChainBridge": {
|
||||||
|
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"IssuingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
},
|
||||||
|
"LockingChainDoor": "rMAXACCrp3Y8PpswXcg3bKggHX76V3F8M4",
|
||||||
|
"LockingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"XChainClaimID": "ac"
|
||||||
|
},
|
||||||
|
"LedgerEntryType": "Bridge",
|
||||||
|
"LedgerIndex": "114C0DC89656D1B0FB1F4A3426034C3FCE75BCE65D9574B5D96ABC2B24D6C8F1",
|
||||||
|
"PreviousFields": {
|
||||||
|
"XChainClaimID": "ab"
|
||||||
|
},
|
||||||
|
"PreviousTxnID": "80C33D1FB349D698CFDB1A85E8368557C5B7219B74DFCB2B05E0B10E2667F902",
|
||||||
|
"PreviousTxnLgrSeq": 1027779
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"ModifiedNode": {
|
||||||
|
"FinalFields": {
|
||||||
|
"Account": "rwmUSzi5Xp31AjMTEdbvxgWqLETcVNU6Fv",
|
||||||
|
"Balance": "19999988",
|
||||||
|
"Flags": 0,
|
||||||
|
"OwnerCount": 1,
|
||||||
|
"Sequence": 1027779
|
||||||
|
},
|
||||||
|
"LedgerEntryType": "AccountRoot",
|
||||||
|
"LedgerIndex": "33442CE111B258424548888D8999F6D064A0866B1300C44AB72E1C5A09765D9D",
|
||||||
|
"PreviousFields": {
|
||||||
|
"Balance": "20000000",
|
||||||
|
"OwnerCount": 0,
|
||||||
|
"Sequence": 1027778
|
||||||
|
},
|
||||||
|
"PreviousTxnID": "7C9ACA230488547B4F39EBCE332447FB90AE59B64C1B03BBF474B509B43739EC",
|
||||||
|
"PreviousTxnLgrSeq": 1027778
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"CreatedNode": {
|
||||||
|
"LedgerEntryType": "DirectoryNode",
|
||||||
|
"LedgerIndex": "439684B06C22596B5B86D2F50903B6AA6F68BD07BED636FC6325704B09DE5D61",
|
||||||
|
"NewFields": {
|
||||||
|
"Owner": "rwmUSzi5Xp31AjMTEdbvxgWqLETcVNU6Fv",
|
||||||
|
"RootIndex": "439684B06C22596B5B86D2F50903B6AA6F68BD07BED636FC6325704B09DE5D61"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"CreatedNode": {
|
||||||
|
"LedgerEntryType": "XChainOwnedClaimID",
|
||||||
|
"LedgerIndex": "8097863E1200B0174006541763AA8F604782DA10C1BD37190D753C699D69C678",
|
||||||
|
"NewFields": {
|
||||||
|
"Account": "rwmUSzi5Xp31AjMTEdbvxgWqLETcVNU6Fv",
|
||||||
|
"OtherChainSource": "rBXdfZ7NVpdjRfYajPMpviGgq7HLDeuBdR",
|
||||||
|
"SignatureReward": "100",
|
||||||
|
"XChainBridge": {
|
||||||
|
"IssuingChainDoor": "rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh",
|
||||||
|
"IssuingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
},
|
||||||
|
"LockingChainDoor": "rMAXACCrp3Y8PpswXcg3bKggHX76V3F8M4",
|
||||||
|
"LockingChainIssue": {
|
||||||
|
"currency": "XRP"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"XChainClaimID": "ac"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"TransactionIndex": 0,
|
||||||
|
"TransactionResult": "tesSUCCESS"
|
||||||
|
},
|
||||||
|
"hash": "A42C4E7F5BAF8A9BEB56853114EE686D554F15F400B8DA885A344B13C32D07BC",
|
||||||
|
"ledger_index": 1027780,
|
||||||
|
"date": 1695324182000
|
||||||
|
}
|
||||||
161
packages/xrpl/test/models/XChainAccountCreateCommit.test.ts
Normal file
161
packages/xrpl/test/models/XChainAccountCreateCommit.test.ts
Normal file
@@ -0,0 +1,161 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { validate, ValidationError } from '../../src'
|
||||||
|
import { validateXChainAccountCreateCommit } from '../../src/models/transactions/XChainAccountCreateCommit'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XChainAccountCreateCommit Transaction Verification Testing.
|
||||||
|
*
|
||||||
|
* Providing runtime verification testing for each specific transaction type.
|
||||||
|
*/
|
||||||
|
describe('XChainAccountCreateCommit', function () {
|
||||||
|
let tx
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tx = {
|
||||||
|
Account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||||
|
XChainBridge: {
|
||||||
|
LockingChainDoor: 'rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL',
|
||||||
|
LockingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
IssuingChainDoor: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV',
|
||||||
|
IssuingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Amount: '1000000',
|
||||||
|
Fee: '10',
|
||||||
|
Flags: 2147483648,
|
||||||
|
Destination: 'rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL',
|
||||||
|
Sequence: 1,
|
||||||
|
SignatureReward: '10000',
|
||||||
|
TransactionType: 'XChainAccountCreateCommit',
|
||||||
|
} as any
|
||||||
|
})
|
||||||
|
|
||||||
|
it('verifies valid XChainAccountCreateCommit', function () {
|
||||||
|
assert.doesNotThrow(() => validateXChainAccountCreateCommit(tx))
|
||||||
|
assert.doesNotThrow(() => validate(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainBridge', function () {
|
||||||
|
delete tx.XChainBridge
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAccountCreateCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainBridge', function () {
|
||||||
|
tx.XChainBridge = { XChainDoor: 'test' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAccountCreateCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing SignatureReward', function () {
|
||||||
|
delete tx.SignatureReward
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAccountCreateCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: missing field SignatureReward',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: missing field SignatureReward',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid SignatureReward', function () {
|
||||||
|
tx.SignatureReward = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAccountCreateCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Destination', function () {
|
||||||
|
delete tx.Destination
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAccountCreateCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: missing field Destination',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: missing field Destination',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Destination', function () {
|
||||||
|
tx.Destination = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAccountCreateCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: invalid field Destination',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: invalid field Destination',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Amount', function () {
|
||||||
|
delete tx.Amount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAccountCreateCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: missing field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: missing field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Amount', function () {
|
||||||
|
tx.Amount = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAccountCreateCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: invalid field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAccountCreateCommit: invalid field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -0,0 +1,381 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { validate, ValidationError } from '../../src'
|
||||||
|
import { validateXChainAddAccountCreateAttestation } from '../../src/models/transactions/XChainAddAccountCreateAttestation'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XChainAddAccountCreateAttestation Transaction Verification Testing.
|
||||||
|
*
|
||||||
|
* Providing runtime verification testing for each specific transaction type.
|
||||||
|
*/
|
||||||
|
describe('XChainAddAccountCreateAttestation', function () {
|
||||||
|
let tx
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tx = {
|
||||||
|
Account: 'r9cYxdjQsoXAEz3qQJc961SNLaXRkWXCvT',
|
||||||
|
Amount: '10000000',
|
||||||
|
AttestationRewardAccount: 'r9cYxdjQsoXAEz3qQJc961SNLaXRkWXCvT',
|
||||||
|
AttestationSignerAccount: 'r9cYxdjQsoXAEz3qQJc961SNLaXRkWXCvT',
|
||||||
|
Destination: 'rJdTJRJZ6GXCCRaamHJgEqVzB7Zy4557Pi',
|
||||||
|
Fee: '20',
|
||||||
|
LastLedgerSequence: 13,
|
||||||
|
OtherChainSource: 'raFcdz1g8LWJDJWJE2ZKLRGdmUmsTyxaym',
|
||||||
|
PublicKey:
|
||||||
|
'ED1F4A024ACFEBDB6C7AA88DEDE3364E060487EA31B14CC9E0D610D152B31AADC2',
|
||||||
|
Sequence: 5,
|
||||||
|
Signature:
|
||||||
|
'EEFCFA3DC2AB4AB7C4D2EBBC168CB621A11B82BABD86534DFC8EFA72439A496' +
|
||||||
|
'62D744073CD848E7A587A95B35162CDF9A69BB237E72C9537A987F5B8C394F30D',
|
||||||
|
SignatureReward: '100',
|
||||||
|
TransactionType: 'XChainAddAccountCreateAttestation',
|
||||||
|
WasLockingChainSend: 1,
|
||||||
|
XChainAccountCreateCount: '0000000000000006',
|
||||||
|
XChainBridge: {
|
||||||
|
IssuingChainDoor: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||||
|
IssuingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
LockingChainDoor: 'rDJVtEuDKr4rj1B3qtW7R5TVWdXV2DY7Qg',
|
||||||
|
LockingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
} as any
|
||||||
|
})
|
||||||
|
|
||||||
|
it('verifies valid XChainAddAccountCreateAttestation', function () {
|
||||||
|
assert.doesNotThrow(() => validateXChainAddAccountCreateAttestation(tx))
|
||||||
|
assert.doesNotThrow(() => validate(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Amount', function () {
|
||||||
|
delete tx.Amount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Amount', function () {
|
||||||
|
tx.Amount = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing AttestationRewardAccount', function () {
|
||||||
|
delete tx.AttestationRewardAccount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field AttestationRewardAccount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field AttestationRewardAccount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid AttestationRewardAccount', function () {
|
||||||
|
tx.AttestationRewardAccount = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field AttestationRewardAccount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field AttestationRewardAccount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing AttestationSignerAccount', function () {
|
||||||
|
delete tx.AttestationSignerAccount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field AttestationSignerAccount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field AttestationSignerAccount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid AttestationSignerAccount', function () {
|
||||||
|
tx.AttestationSignerAccount = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field AttestationSignerAccount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field AttestationSignerAccount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Destination', function () {
|
||||||
|
delete tx.Destination
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field Destination',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field Destination',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Destination', function () {
|
||||||
|
tx.Destination = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field Destination',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field Destination',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing OtherChainSource', function () {
|
||||||
|
delete tx.OtherChainSource
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field OtherChainSource',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field OtherChainSource',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid OtherChainSource', function () {
|
||||||
|
tx.OtherChainSource = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field OtherChainSource',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field OtherChainSource',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing PublicKey', function () {
|
||||||
|
delete tx.PublicKey
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field PublicKey',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field PublicKey',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid PublicKey', function () {
|
||||||
|
tx.PublicKey = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field PublicKey',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field PublicKey',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Signature', function () {
|
||||||
|
delete tx.Signature
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field Signature',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field Signature',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Signature', function () {
|
||||||
|
tx.Signature = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field Signature',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field Signature',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing SignatureReward', function () {
|
||||||
|
delete tx.SignatureReward
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field SignatureReward',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field SignatureReward',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid SignatureReward', function () {
|
||||||
|
tx.SignatureReward = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing WasLockingChainSend', function () {
|
||||||
|
delete tx.WasLockingChainSend
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field WasLockingChainSend',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field WasLockingChainSend',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid WasLockingChainSend', function () {
|
||||||
|
tx.WasLockingChainSend = 2
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field WasLockingChainSend',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field WasLockingChainSend',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainAccountCreateCount', function () {
|
||||||
|
delete tx.XChainAccountCreateCount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field XChainAccountCreateCount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field XChainAccountCreateCount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainAccountCreateCount', function () {
|
||||||
|
tx.XChainAccountCreateCount = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field XChainAccountCreateCount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field XChainAccountCreateCount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainBridge', function () {
|
||||||
|
delete tx.XChainBridge
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainBridge', function () {
|
||||||
|
tx.XChainBridge = { XChainDoor: 'test' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddAccountCreateAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddAccountCreateAttestation: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
334
packages/xrpl/test/models/XChainAddClaimAttestation.test.ts
Normal file
334
packages/xrpl/test/models/XChainAddClaimAttestation.test.ts
Normal file
@@ -0,0 +1,334 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { validate, ValidationError } from '../../src'
|
||||||
|
import { validateXChainAddClaimAttestation } from '../../src/models/transactions/XChainAddClaimAttestation'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XChainAddClaimAttestation Transaction Verification Testing.
|
||||||
|
*
|
||||||
|
* Providing runtime verification testing for each specific transaction type.
|
||||||
|
*/
|
||||||
|
describe('XChainAddClaimAttestation', function () {
|
||||||
|
let tx
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tx = {
|
||||||
|
Account: 'rsqvD8WFFEBBv4nztpoW9YYXJ7eRzLrtc3',
|
||||||
|
Amount: '10000000',
|
||||||
|
AttestationRewardAccount: 'rsqvD8WFFEBBv4nztpoW9YYXJ7eRzLrtc3',
|
||||||
|
AttestationSignerAccount: 'rsqvD8WFFEBBv4nztpoW9YYXJ7eRzLrtc3',
|
||||||
|
Destination: 'rJdTJRJZ6GXCCRaamHJgEqVzB7Zy4557Pi',
|
||||||
|
Fee: '20',
|
||||||
|
LastLedgerSequence: 19,
|
||||||
|
OtherChainSource: 'raFcdz1g8LWJDJWJE2ZKLRGdmUmsTyxaym',
|
||||||
|
PublicKey:
|
||||||
|
'ED7541DEC700470F54276C90C333A13CDBB5D341FD43C60CEA12170F6D6D4E1136',
|
||||||
|
Sequence: 9,
|
||||||
|
Signature:
|
||||||
|
'7C175050B08000AD35EEB2D87E16CD3F95A0AEEBF2A049474275153D9D4DD44528FE99AA50E71660A15B0B768E1B90E609BBD5DC7AFAFD45D9705D72D40EA10C',
|
||||||
|
TransactionType: 'XChainAddClaimAttestation',
|
||||||
|
WasLockingChainSend: 1,
|
||||||
|
XChainBridge: {
|
||||||
|
IssuingChainDoor: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||||
|
IssuingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
LockingChainDoor: 'rDJVtEuDKr4rj1B3qtW7R5TVWdXV2DY7Qg',
|
||||||
|
LockingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
XChainClaimID: '0000000000000001',
|
||||||
|
} as any
|
||||||
|
})
|
||||||
|
|
||||||
|
it('verifies valid XChainAddClaimAttestation', function () {
|
||||||
|
assert.doesNotThrow(() => validateXChainAddClaimAttestation(tx))
|
||||||
|
assert.doesNotThrow(() => validate(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Amount', function () {
|
||||||
|
delete tx.Amount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Amount', function () {
|
||||||
|
tx.Amount = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing AttestationRewardAccount', function () {
|
||||||
|
delete tx.AttestationRewardAccount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field AttestationRewardAccount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field AttestationRewardAccount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid AttestationRewardAccount', function () {
|
||||||
|
tx.AttestationRewardAccount = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field AttestationRewardAccount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field AttestationRewardAccount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing AttestationSignerAccount', function () {
|
||||||
|
delete tx.AttestationSignerAccount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field AttestationSignerAccount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field AttestationSignerAccount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid AttestationSignerAccount', function () {
|
||||||
|
tx.AttestationSignerAccount = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field AttestationSignerAccount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field AttestationSignerAccount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Destination', function () {
|
||||||
|
tx.Destination = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field Destination',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field Destination',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing OtherChainSource', function () {
|
||||||
|
delete tx.OtherChainSource
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field OtherChainSource',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field OtherChainSource',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid OtherChainSource', function () {
|
||||||
|
tx.OtherChainSource = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field OtherChainSource',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field OtherChainSource',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing PublicKey', function () {
|
||||||
|
delete tx.PublicKey
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field PublicKey',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field PublicKey',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid PublicKey', function () {
|
||||||
|
tx.PublicKey = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field PublicKey',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field PublicKey',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Signature', function () {
|
||||||
|
delete tx.Signature
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field Signature',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field Signature',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Signature', function () {
|
||||||
|
tx.Signature = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field Signature',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field Signature',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing WasLockingChainSend', function () {
|
||||||
|
delete tx.WasLockingChainSend
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field WasLockingChainSend',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field WasLockingChainSend',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid WasLockingChainSend', function () {
|
||||||
|
tx.WasLockingChainSend = 2
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field WasLockingChainSend',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field WasLockingChainSend',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainBridge', function () {
|
||||||
|
delete tx.XChainBridge
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainBridge', function () {
|
||||||
|
tx.XChainBridge = { XChainDoor: 'test' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainClaimID', function () {
|
||||||
|
delete tx.XChainClaimID
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field XChainClaimID',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: missing field XChainClaimID',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainClaimID', function () {
|
||||||
|
tx.XChainClaimID = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainAddClaimAttestation(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field XChainClaimID',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainAddClaimAttestation: invalid field XChainClaimID',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
176
packages/xrpl/test/models/XChainClaim.test.ts
Normal file
176
packages/xrpl/test/models/XChainClaim.test.ts
Normal file
@@ -0,0 +1,176 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { validate, ValidationError } from '../../src'
|
||||||
|
import { validateXChainClaim } from '../../src/models/transactions/XChainClaim'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XChainClaim Transaction Verification Testing.
|
||||||
|
*
|
||||||
|
* Providing runtime verification testing for each specific transaction type.
|
||||||
|
*/
|
||||||
|
describe('XChainClaim', function () {
|
||||||
|
let tx
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tx = {
|
||||||
|
Account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||||
|
Amount: '10000',
|
||||||
|
XChainBridge: {
|
||||||
|
LockingChainDoor: 'rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL',
|
||||||
|
LockingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
IssuingChainDoor: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV',
|
||||||
|
IssuingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Destination: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV',
|
||||||
|
Fee: '10',
|
||||||
|
Flags: 2147483648,
|
||||||
|
Sequence: 1,
|
||||||
|
TransactionType: 'XChainClaim',
|
||||||
|
XChainClaimID: '0000000000000001',
|
||||||
|
} as any
|
||||||
|
})
|
||||||
|
|
||||||
|
it('verifies valid XChainClaim', function () {
|
||||||
|
assert.doesNotThrow(() => validateXChainClaim(tx))
|
||||||
|
assert.doesNotThrow(() => validate(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainBridge', function () {
|
||||||
|
delete tx.XChainBridge
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainClaim(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainBridge', function () {
|
||||||
|
tx.XChainBridge = { XChainDoor: 'test' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainClaim(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainClaimID', function () {
|
||||||
|
delete tx.XChainClaimID
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainClaim(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: missing field XChainClaimID',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: missing field XChainClaimID',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainClaimID', function () {
|
||||||
|
tx.XChainClaimID = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainClaim(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field XChainClaimID',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field XChainClaimID',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Destination', function () {
|
||||||
|
delete tx.Destination
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainClaim(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: missing field Destination',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: missing field Destination',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Destination', function () {
|
||||||
|
tx.Destination = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainClaim(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field Destination',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field Destination',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid DestinationTag', function () {
|
||||||
|
tx.DestinationTag = 'number'
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainClaim(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field DestinationTag',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field DestinationTag',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Amount', function () {
|
||||||
|
delete tx.Amount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainClaim(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: missing field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: missing field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Amount', function () {
|
||||||
|
tx.Amount = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainClaim(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainClaim: invalid field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
145
packages/xrpl/test/models/XChainCommit.test.ts
Normal file
145
packages/xrpl/test/models/XChainCommit.test.ts
Normal file
@@ -0,0 +1,145 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { validate, ValidationError } from '../../src'
|
||||||
|
import { validateXChainCommit } from '../../src/models/transactions/XChainCommit'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XChainCommit Transaction Verification Testing.
|
||||||
|
*
|
||||||
|
* Providing runtime verification testing for each specific transaction type.
|
||||||
|
*/
|
||||||
|
describe('XChainCommit', function () {
|
||||||
|
let tx
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tx = {
|
||||||
|
Account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||||
|
Amount: '10000',
|
||||||
|
XChainBridge: {
|
||||||
|
LockingChainDoor: 'rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL',
|
||||||
|
LockingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
IssuingChainDoor: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV',
|
||||||
|
IssuingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Fee: '10',
|
||||||
|
Flags: 2147483648,
|
||||||
|
Sequence: 1,
|
||||||
|
TransactionType: 'XChainCommit',
|
||||||
|
XChainClaimID: '0000000000000001',
|
||||||
|
} as any
|
||||||
|
})
|
||||||
|
|
||||||
|
it('verifies valid XChainCommit', function () {
|
||||||
|
assert.doesNotThrow(() => validateXChainCommit(tx))
|
||||||
|
assert.doesNotThrow(() => validate(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainBridge', function () {
|
||||||
|
delete tx.XChainBridge
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainBridge', function () {
|
||||||
|
tx.XChainBridge = { XChainDoor: 'test' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainClaimID', function () {
|
||||||
|
delete tx.XChainClaimID
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: missing field XChainClaimID',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: missing field XChainClaimID',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainClaimID', function () {
|
||||||
|
tx.XChainClaimID = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: invalid field XChainClaimID',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: invalid field XChainClaimID',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid OtherChainDestination', function () {
|
||||||
|
tx.OtherChainDestination = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: invalid field OtherChainDestination',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: invalid field OtherChainDestination',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing Amount', function () {
|
||||||
|
delete tx.Amount
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: missing field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: missing field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid Amount', function () {
|
||||||
|
tx.Amount = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCommit(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: invalid field Amount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCommit: invalid field Amount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
115
packages/xrpl/test/models/XChainCreateBridge.test.ts
Normal file
115
packages/xrpl/test/models/XChainCreateBridge.test.ts
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { validate, ValidationError } from '../../src'
|
||||||
|
import { validateXChainCreateBridge } from '../../src/models/transactions/XChainCreateBridge'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XChainCreateBridge Transaction Verification Testing.
|
||||||
|
*
|
||||||
|
* Providing runtime verification testing for each specific transaction type.
|
||||||
|
*/
|
||||||
|
describe('XChainCreateBridge', function () {
|
||||||
|
let tx
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tx = {
|
||||||
|
Account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||||
|
XChainBridge: {
|
||||||
|
LockingChainDoor: 'rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL',
|
||||||
|
LockingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
IssuingChainDoor: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV',
|
||||||
|
IssuingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Fee: '10',
|
||||||
|
Flags: 0,
|
||||||
|
MinAccountCreateAmount: '10000',
|
||||||
|
Sequence: 1,
|
||||||
|
SignatureReward: '1000',
|
||||||
|
TransactionType: 'XChainCreateBridge',
|
||||||
|
} as any
|
||||||
|
})
|
||||||
|
|
||||||
|
it('verifies valid XChainCreateBridge', function () {
|
||||||
|
assert.doesNotThrow(() => validateXChainCreateBridge(tx))
|
||||||
|
assert.doesNotThrow(() => validate(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainBridge', function () {
|
||||||
|
delete tx.XChainBridge
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateBridge(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainBridge', function () {
|
||||||
|
tx.XChainBridge = { XChainDoor: 'test' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateBridge(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing SignatureReward', function () {
|
||||||
|
delete tx.SignatureReward
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateBridge(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: missing field SignatureReward',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: missing field SignatureReward',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid SignatureReward', function () {
|
||||||
|
tx.SignatureReward = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateBridge(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid MinAccountCreateAmount', function () {
|
||||||
|
tx.MinAccountCreateAmount = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateBridge(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: invalid field MinAccountCreateAmount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateBridge: invalid field MinAccountCreateAmount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
130
packages/xrpl/test/models/XChainCreateClaimID.test.ts
Normal file
130
packages/xrpl/test/models/XChainCreateClaimID.test.ts
Normal file
@@ -0,0 +1,130 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { validate, ValidationError } from '../../src'
|
||||||
|
import { validateXChainCreateClaimID } from '../../src/models/transactions/XChainCreateClaimID'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XChainCreateClaimID Transaction Verification Testing.
|
||||||
|
*
|
||||||
|
* Providing runtime verification testing for each specific transaction type.
|
||||||
|
*/
|
||||||
|
describe('XChainCreateClaimID', function () {
|
||||||
|
let tx
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tx = {
|
||||||
|
Account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||||
|
XChainBridge: {
|
||||||
|
LockingChainDoor: 'rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL',
|
||||||
|
LockingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
IssuingChainDoor: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV',
|
||||||
|
IssuingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Fee: '10',
|
||||||
|
Flags: 2147483648,
|
||||||
|
OtherChainSource: 'rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL',
|
||||||
|
Sequence: 1,
|
||||||
|
SignatureReward: '10000',
|
||||||
|
TransactionType: 'XChainCreateClaimID',
|
||||||
|
} as any
|
||||||
|
})
|
||||||
|
|
||||||
|
it('verifies valid XChainCreateClaimID', function () {
|
||||||
|
assert.doesNotThrow(() => validateXChainCreateClaimID(tx))
|
||||||
|
assert.doesNotThrow(() => validate(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainBridge', function () {
|
||||||
|
delete tx.XChainBridge
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateClaimID(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainBridge', function () {
|
||||||
|
tx.XChainBridge = { XChainDoor: 'test' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateClaimID(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing SignatureReward', function () {
|
||||||
|
delete tx.SignatureReward
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateClaimID(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: missing field SignatureReward',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: missing field SignatureReward',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid SignatureReward', function () {
|
||||||
|
tx.SignatureReward = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateClaimID(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing OtherChainSource', function () {
|
||||||
|
delete tx.OtherChainSource
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateClaimID(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: missing field OtherChainSource',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: missing field OtherChainSource',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid OtherChainSource', function () {
|
||||||
|
tx.OtherChainSource = 123
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainCreateClaimID(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: invalid field OtherChainSource',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainCreateClaimID: invalid field OtherChainSource',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
100
packages/xrpl/test/models/XChainModifyBridge.test.ts
Normal file
100
packages/xrpl/test/models/XChainModifyBridge.test.ts
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { validate, ValidationError } from '../../src'
|
||||||
|
import { validateXChainModifyBridge } from '../../src/models/transactions/XChainModifyBridge'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* XChainModifyBridge Transaction Verification Testing.
|
||||||
|
*
|
||||||
|
* Providing runtime verification testing for each specific transaction type.
|
||||||
|
*/
|
||||||
|
describe('XChainModifyBridge', function () {
|
||||||
|
let tx
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tx = {
|
||||||
|
Account: 'rHb9CJAWyB4rj91VRWn96DkukG4bwdtyTh',
|
||||||
|
XChainBridge: {
|
||||||
|
LockingChainDoor: 'rGzx83BVoqTYbGn7tiVAnFw7cbxjin13jL',
|
||||||
|
LockingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
IssuingChainDoor: 'r3kmLJN5D28dHuH8vZNUZpMC43pEHpaocV',
|
||||||
|
IssuingChainIssue: {
|
||||||
|
currency: 'XRP',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Fee: '10',
|
||||||
|
Flags: 0,
|
||||||
|
MinAccountCreateAmount: '10000',
|
||||||
|
Sequence: 1,
|
||||||
|
SignatureReward: '1000',
|
||||||
|
TransactionType: 'XChainModifyBridge',
|
||||||
|
} as any
|
||||||
|
})
|
||||||
|
|
||||||
|
it('verifies valid XChainModifyBridge', function () {
|
||||||
|
assert.doesNotThrow(() => validateXChainModifyBridge(tx))
|
||||||
|
assert.doesNotThrow(() => validate(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ missing XChainBridge', function () {
|
||||||
|
delete tx.XChainBridge
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainModifyBridge(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainModifyBridge: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainModifyBridge: missing field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid XChainBridge', function () {
|
||||||
|
tx.XChainBridge = { XChainDoor: 'test' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainModifyBridge(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainModifyBridge: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainModifyBridge: invalid field XChainBridge',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid SignatureReward', function () {
|
||||||
|
tx.SignatureReward = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainModifyBridge(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainModifyBridge: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainModifyBridge: invalid field SignatureReward',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('throws w/ invalid MinAccountCreateAmount', function () {
|
||||||
|
tx.MinAccountCreateAmount = { currency: 'ETH' }
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validateXChainModifyBridge(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainModifyBridge: invalid field MinAccountCreateAmount',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'XChainModifyBridge: invalid field MinAccountCreateAmount',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
})
|
||||||
@@ -78,7 +78,7 @@ describe('BaseTransaction', function () {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
() => validateBaseTransaction(invalidFee),
|
() => validateBaseTransaction(invalidFee),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
'BaseTransaction: invalid Fee',
|
'Payment: invalid field Fee',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -92,7 +92,7 @@ describe('BaseTransaction', function () {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
() => validateBaseTransaction(invalidSeq),
|
() => validateBaseTransaction(invalidSeq),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
'BaseTransaction: invalid Sequence',
|
'Payment: invalid field Sequence',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ describe('BaseTransaction', function () {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
() => validateBaseTransaction(invalidID),
|
() => validateBaseTransaction(invalidID),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
'BaseTransaction: invalid AccountTxnID',
|
'Payment: invalid field AccountTxnID',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -120,7 +120,7 @@ describe('BaseTransaction', function () {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
() => validateBaseTransaction(invalidLastLedgerSequence),
|
() => validateBaseTransaction(invalidLastLedgerSequence),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
'BaseTransaction: invalid LastLedgerSequence',
|
'Payment: invalid field LastLedgerSequence',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -134,7 +134,7 @@ describe('BaseTransaction', function () {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
() => validateBaseTransaction(invalidSourceTag),
|
() => validateBaseTransaction(invalidSourceTag),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
'BaseTransaction: invalid SourceTag',
|
'Payment: invalid field SourceTag',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -148,7 +148,7 @@ describe('BaseTransaction', function () {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
() => validateBaseTransaction(invalidSigningPubKey),
|
() => validateBaseTransaction(invalidSigningPubKey),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
'BaseTransaction: invalid SigningPubKey',
|
'Payment: invalid field SigningPubKey',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ describe('BaseTransaction', function () {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
() => validateBaseTransaction(invalidTicketSequence),
|
() => validateBaseTransaction(invalidTicketSequence),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
'BaseTransaction: invalid TicketSequence',
|
'Payment: invalid field TicketSequence',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -176,7 +176,7 @@ describe('BaseTransaction', function () {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
() => validateBaseTransaction(invalidTxnSignature),
|
() => validateBaseTransaction(invalidTxnSignature),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
'BaseTransaction: invalid TxnSignature',
|
'Payment: invalid field TxnSignature',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -242,7 +242,7 @@ describe('BaseTransaction', function () {
|
|||||||
assert.throws(
|
assert.throws(
|
||||||
() => validateBaseTransaction(invalidNetworkID),
|
() => validateBaseTransaction(invalidNetworkID),
|
||||||
ValidationError,
|
ValidationError,
|
||||||
'BaseTransaction: invalid NetworkID',
|
'Payment: invalid field NetworkID',
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,19 +1,18 @@
|
|||||||
import { assert } from 'chai'
|
import { assert } from 'chai'
|
||||||
|
|
||||||
import { getNFTokenID } from '../../src'
|
import { getNFTokenID } from '../../src'
|
||||||
import * as NFTokenResponse from '../fixtures/rippled/mintNFTMeta.json'
|
import fixtures from '../fixtures/rippled'
|
||||||
import * as NFTokenResponse2 from '../fixtures/rippled/mintNFTMeta2.json'
|
|
||||||
|
|
||||||
describe('getNFTokenID', function () {
|
describe('getNFTokenID', function () {
|
||||||
it('decode a valid NFTokenID', function () {
|
it('decode a valid NFTokenID', function () {
|
||||||
const result = getNFTokenID(NFTokenResponse.meta)
|
const result = getNFTokenID(fixtures.tx.NFTokenMint.meta)
|
||||||
const expectedNFTokenID =
|
const expectedNFTokenID =
|
||||||
'00081388DC1AB4937C899037B2FDFC3CB20F6F64E73120BB5F8AA66A00000228'
|
'00081388DC1AB4937C899037B2FDFC3CB20F6F64E73120BB5F8AA66A00000228'
|
||||||
assert.equal(result, expectedNFTokenID)
|
assert.equal(result, expectedNFTokenID)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('decode a different valid NFTokenID', function () {
|
it('decode a different valid NFTokenID', function () {
|
||||||
const result = getNFTokenID(NFTokenResponse2.meta)
|
const result = getNFTokenID(fixtures.tx.NFTokenMint2.meta)
|
||||||
const expectedNFTokenID =
|
const expectedNFTokenID =
|
||||||
'0008125CBE4B401B2F62ED35CC67362165AA813CCA06316FFA766254000003EE'
|
'0008125CBE4B401B2F62ED35CC67362165AA813CCA06316FFA766254000003EE'
|
||||||
assert.equal(result, expectedNFTokenID)
|
assert.equal(result, expectedNFTokenID)
|
||||||
@@ -21,8 +20,8 @@ describe('getNFTokenID', function () {
|
|||||||
|
|
||||||
it('fails with nice error when given raw response instead of meta', function () {
|
it('fails with nice error when given raw response instead of meta', function () {
|
||||||
assert.throws(() => {
|
assert.throws(() => {
|
||||||
// @ts-expect-error - Validating error for javascript users
|
// @ts-expect-error -- on purpose, to check the error
|
||||||
const _ = getNFTokenID(NFTokenResponse)
|
const _ = getNFTokenID(fixtures.tx.NFTokenMint)
|
||||||
}, /^Unable to parse the parameter given to getNFTokenID.*/u)
|
}, /^Unable to parse the parameter given to getNFTokenID.*/u)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
25
packages/xrpl/test/utils/getXChainClaimID.test.ts
Normal file
25
packages/xrpl/test/utils/getXChainClaimID.test.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { getXChainClaimID } from '../../src'
|
||||||
|
import fixtures from '../fixtures/rippled'
|
||||||
|
|
||||||
|
describe('getXChainClaimID', function () {
|
||||||
|
it('decode a valid XChainClaimID', function () {
|
||||||
|
const result = getXChainClaimID(fixtures.tx.XChainCreateClaimID.meta)
|
||||||
|
const expectedXChainClaimID = 'b0'
|
||||||
|
assert.equal(result, expectedXChainClaimID)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('decode a different valid XChainClaimID', function () {
|
||||||
|
const result = getXChainClaimID(fixtures.tx.XChainCreateClaimID2.meta)
|
||||||
|
const expectedXChainClaimID = 'ac'
|
||||||
|
assert.equal(result, expectedXChainClaimID)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('fails with nice error when given raw response instead of meta', function () {
|
||||||
|
assert.throws(() => {
|
||||||
|
// @ts-expect-error -- on purpose, to check the error
|
||||||
|
const _ = getXChainClaimID(fixtures.tx.XChainCreateClaimID)
|
||||||
|
}, /^Unable to parse the parameter given to getXChainClaimID.*/u)
|
||||||
|
})
|
||||||
|
})
|
||||||
147
packages/xrpl/tools/createValidate.js
Normal file
147
packages/xrpl/tools/createValidate.js
Normal file
@@ -0,0 +1,147 @@
|
|||||||
|
/* eslint-disable no-continue -- unneeded here */
|
||||||
|
/**
|
||||||
|
* This file writes the `validate` function for a transaction, when provided the model name in the `src/models/transactions`
|
||||||
|
* folder.
|
||||||
|
*/
|
||||||
|
const fs = require('fs')
|
||||||
|
|
||||||
|
const NORMAL_TYPES = ['number', 'string']
|
||||||
|
const NUMBERS = ['0', '1']
|
||||||
|
|
||||||
|
// TODO: rewrite this to use regex
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
if (process.argv.length < 3) {
|
||||||
|
console.log(`Usage: ${process.argv[0]} ${process.argv[1]} TxName`)
|
||||||
|
process.exit(1)
|
||||||
|
}
|
||||||
|
const modelName = process.argv[2]
|
||||||
|
const filename = `./src/models/transactions/${modelName}.ts`
|
||||||
|
const [model, txName] = await getModel(filename)
|
||||||
|
return processModel(model, txName)
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getModel(filename) {
|
||||||
|
let model = ''
|
||||||
|
let started = false
|
||||||
|
let ended = false
|
||||||
|
const data = await fs.promises.readFile(filename, { encoding: 'utf8' })
|
||||||
|
const lines = data.split('\n')
|
||||||
|
for (const line of lines) {
|
||||||
|
if (ended) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!started && !line.startsWith('export')) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!started && line.includes('Flags')) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (!started) {
|
||||||
|
started = true
|
||||||
|
}
|
||||||
|
model += `${line}\n`
|
||||||
|
if (line === '}') {
|
||||||
|
ended = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const name_line = model.split('\n')[0].split(' ')
|
||||||
|
const txName = name_line[2]
|
||||||
|
return [model, txName]
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValidationFunction(paramType) {
|
||||||
|
if (NORMAL_TYPES.includes(paramType)) {
|
||||||
|
const paramTypeCapitalized =
|
||||||
|
paramType.substring(0, 1).toUpperCase() + paramType.substring(1)
|
||||||
|
return `is${paramTypeCapitalized}(inp)`
|
||||||
|
}
|
||||||
|
if (NUMBERS.includes(paramType)) {
|
||||||
|
return `inp === ${paramType}`
|
||||||
|
}
|
||||||
|
return `is${paramType}(inp)`
|
||||||
|
}
|
||||||
|
|
||||||
|
function getValidationLine(validationFns) {
|
||||||
|
if (validationFns.length === 1) {
|
||||||
|
if (!validationFns[0].includes('===')) {
|
||||||
|
// Example: `validateRequiredFields(tx, 'Amount', isAmount)`
|
||||||
|
const validationFn = validationFns[0]
|
||||||
|
// strip the `(inp)` in e.g. `isAmount(inp)`
|
||||||
|
return validationFn.substring(0, validationFn.length - 5)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Example:
|
||||||
|
// `validateRequiredFields(tx, 'XChainAccountCreateCount',
|
||||||
|
// (inp) => isNumber(inp) || isString(inp)))`
|
||||||
|
return `(inp) => ${validationFns.join(' || ')}`
|
||||||
|
}
|
||||||
|
|
||||||
|
function processModel(model, txName) {
|
||||||
|
let output = ''
|
||||||
|
// process the TS model and get the types of each parameter
|
||||||
|
for (let line of model.split('\n')) {
|
||||||
|
if (line === '') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (line.startsWith('export')) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (line === '}') {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
line = line.trim()
|
||||||
|
if (line.startsWith('TransactionType')) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (line.startsWith('Flags')) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (line.startsWith('/**')) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if (line.startsWith('*')) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// process the line with a type
|
||||||
|
const split = line.split(' ')
|
||||||
|
const param = split[0].replace('?:', '').replace(':', '').trim()
|
||||||
|
const paramTypes = split.slice(1)
|
||||||
|
const optional = split[0].endsWith('?:')
|
||||||
|
const functionName = optional
|
||||||
|
? 'validateOptionalField'
|
||||||
|
: 'validateRequiredField'
|
||||||
|
|
||||||
|
// process the types and turn them into a validation function
|
||||||
|
let idx = 0
|
||||||
|
const if_outputs = []
|
||||||
|
while (idx < paramTypes.length) {
|
||||||
|
const paramType = paramTypes[idx]
|
||||||
|
if_outputs.push(getValidationFunction(paramType))
|
||||||
|
idx += 2
|
||||||
|
}
|
||||||
|
|
||||||
|
output += ` ${functionName}(tx, '${param}', ${getValidationLine(
|
||||||
|
if_outputs,
|
||||||
|
)})\n\n`
|
||||||
|
}
|
||||||
|
output = output.substring(0, output.length - 1)
|
||||||
|
output += '}\n'
|
||||||
|
|
||||||
|
// initial output content
|
||||||
|
output = `/**
|
||||||
|
* Verify the form and type of a ${txName} at runtime.
|
||||||
|
*
|
||||||
|
* @param tx - A ${txName} Transaction.
|
||||||
|
* @throws When the ${txName} is malformed.
|
||||||
|
*/
|
||||||
|
export function validate${txName}(tx: Record<string, unknown>): void {
|
||||||
|
validateBaseTransaction(tx)
|
||||||
|
|
||||||
|
${output}`
|
||||||
|
|
||||||
|
return output
|
||||||
|
}
|
||||||
|
|
||||||
|
main().then(console.log)
|
||||||
@@ -6,6 +6,7 @@
|
|||||||
"./test/**/*.json",
|
"./test/**/*.json",
|
||||||
"./src/**/*.json",
|
"./src/**/*.json",
|
||||||
"./snippets/src/**/*.ts",
|
"./snippets/src/**/*.ts",
|
||||||
".eslintrc.js"
|
".eslintrc.js",
|
||||||
],
|
],
|
||||||
|
"exclude": ["./tools/*.js"]
|
||||||
}
|
}
|
||||||
|
|||||||
187
tools/createValidateTests.js
Normal file
187
tools/createValidateTests.js
Normal file
@@ -0,0 +1,187 @@
|
|||||||
|
const fs = require("fs");
|
||||||
|
const fixtures = require("../packages/ripple-binary-codec/test/fixtures/codec-fixtures.json");
|
||||||
|
|
||||||
|
const NORMAL_TYPES = ["number", "string"];
|
||||||
|
const NUMBERS = ["0", "1"];
|
||||||
|
|
||||||
|
function getTx(txName) {
|
||||||
|
transactions = fixtures.transactions;
|
||||||
|
const validTxs = fixtures.transactions
|
||||||
|
.filter((tx) => tx.json.TransactionType === txName)
|
||||||
|
.map((tx) => tx.json);
|
||||||
|
const validTx = validTxs[0];
|
||||||
|
delete validTx.TxnSignature;
|
||||||
|
delete validTx.SigningPubKey;
|
||||||
|
return JSON.stringify(validTx, null, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
function main() {
|
||||||
|
const modelName = process.argv[2];
|
||||||
|
const filename = `./packages/xrpl/src/models/transactions/${modelName}.ts`;
|
||||||
|
const [model, txName] = getModel(filename);
|
||||||
|
return processModel(model, txName);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Extract just the model from the file
|
||||||
|
function getModel(filename) {
|
||||||
|
let model = "";
|
||||||
|
let started = false;
|
||||||
|
let ended = false;
|
||||||
|
const data = fs.readFileSync(filename, "utf8");
|
||||||
|
const lines = data.split("\n");
|
||||||
|
for (let line of lines) {
|
||||||
|
if (ended) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!started && !line.startsWith("export")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!started && line.includes("Flags")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!started) {
|
||||||
|
started = true;
|
||||||
|
}
|
||||||
|
model += line + "\n";
|
||||||
|
if (line === "}") {
|
||||||
|
ended = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const name_line = model.split("\n")[0].split(" ");
|
||||||
|
const txName = name_line[2];
|
||||||
|
return [model, txName];
|
||||||
|
}
|
||||||
|
|
||||||
|
function getInvalidValue(paramTypes) {
|
||||||
|
if (paramTypes.length === 1) {
|
||||||
|
const paramType = paramTypes[0];
|
||||||
|
if (paramType == "number") {
|
||||||
|
return "'number'";
|
||||||
|
} else if (paramType == "string") {
|
||||||
|
return 123;
|
||||||
|
} else if (paramType == "IssuedCurrency") {
|
||||||
|
return JSON.stringify({ test: "test" });
|
||||||
|
} else if (paramType == "Amount") {
|
||||||
|
return JSON.stringify({ currency: "ETH" });
|
||||||
|
} else if (paramType == "XChainBridge") {
|
||||||
|
return JSON.stringify({ XChainDoor: "test" });
|
||||||
|
} else {
|
||||||
|
throw Error(`${paramType} not supported yet`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const simplifiedParamTypes = paramTypes.filter(
|
||||||
|
(_paramType, index) => index % 2 == 0
|
||||||
|
);
|
||||||
|
if (JSON.stringify(simplifiedParamTypes) === '["0","1"]') {
|
||||||
|
return 2;
|
||||||
|
} else if (JSON.stringify(simplifiedParamTypes) === '["number","string"]') {
|
||||||
|
return JSON.stringify({ currency: "ETH" });
|
||||||
|
} else {
|
||||||
|
throw Error(`${simplifiedParamTypes} not supported yet`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Process the model and build the tests
|
||||||
|
|
||||||
|
function processModel(model, txName) {
|
||||||
|
let output = "";
|
||||||
|
for (let line of model.split("\n")) {
|
||||||
|
if (line == "") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.startsWith("export")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line == "}") {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
line = line.trim();
|
||||||
|
if (line.startsWith("TransactionType")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.startsWith("Flags")) {
|
||||||
|
// TODO: support flag checking
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.startsWith("/**")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (line.startsWith("*")) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const split = line.split(" ");
|
||||||
|
const param = split[0].replace("?:", "").replace(":", "").trim();
|
||||||
|
const paramTypes = split.slice(1);
|
||||||
|
const optional = split[0].endsWith("?:");
|
||||||
|
|
||||||
|
if (!optional) {
|
||||||
|
output += ` it("throws w/ missing ${param}", function () {
|
||||||
|
delete tx.${param}
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validate${txName}(tx),
|
||||||
|
ValidationError,
|
||||||
|
'${txName}: missing field ${param}',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'${txName}: missing field ${param}',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fakeValue = getInvalidValue(paramTypes);
|
||||||
|
output += ` it('throws w/ invalid ${param}', function () {
|
||||||
|
tx.${param} = ${fakeValue}
|
||||||
|
|
||||||
|
assert.throws(
|
||||||
|
() => validate${txName}(tx),
|
||||||
|
ValidationError,
|
||||||
|
'${txName}: invalid field ${param}',
|
||||||
|
)
|
||||||
|
assert.throws(
|
||||||
|
() => validate(tx),
|
||||||
|
ValidationError,
|
||||||
|
'${txName}: invalid field ${param}',
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
output = output.substring(0, output.length - 2);
|
||||||
|
output += "\n})\n";
|
||||||
|
output =
|
||||||
|
`import { assert } from 'chai'
|
||||||
|
|
||||||
|
import { validate, ValidationError } from '../../src'
|
||||||
|
import { validate${txName} } from '../../src/models/transactions/${txName}'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ${txName} Transaction Verification Testing.
|
||||||
|
*
|
||||||
|
* Providing runtime verification testing for each specific transaction type.
|
||||||
|
*/
|
||||||
|
describe('${txName}', function () {
|
||||||
|
let tx
|
||||||
|
|
||||||
|
beforeEach(function () {
|
||||||
|
tx = ${getTx(txName)} as any
|
||||||
|
})
|
||||||
|
|
||||||
|
it('verifies valid ${txName}', function () {
|
||||||
|
assert.doesNotThrow(() => validate${txName}(tx))
|
||||||
|
assert.doesNotThrow(() => validate(tx))
|
||||||
|
})
|
||||||
|
|
||||||
|
` + output;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(main());
|
||||||
Reference in New Issue
Block a user