diff --git a/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts b/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts new file mode 100644 index 0000000000..454458fdae --- /dev/null +++ b/packages/xrpl/test/models/XChainAccountCreateCommit.test.ts @@ -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', + ) + }) +}) diff --git a/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts b/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts new file mode 100644 index 0000000000..4fb98fd584 --- /dev/null +++ b/packages/xrpl/test/models/XChainAddAccountCreateAttestation.test.ts @@ -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', + ) + }) +}) diff --git a/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts new file mode 100644 index 0000000000..4e7d1aeb7a --- /dev/null +++ b/packages/xrpl/test/models/XChainAddClaimAttestation.test.ts @@ -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', + ) + }) +}) diff --git a/packages/xrpl/test/models/XChainClaim.test.ts b/packages/xrpl/test/models/XChainClaim.test.ts new file mode 100644 index 0000000000..7b854ea786 --- /dev/null +++ b/packages/xrpl/test/models/XChainClaim.test.ts @@ -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', + ) + }) +}) diff --git a/packages/xrpl/test/models/XChainCommit.test.ts b/packages/xrpl/test/models/XChainCommit.test.ts new file mode 100644 index 0000000000..4963cf1bef --- /dev/null +++ b/packages/xrpl/test/models/XChainCommit.test.ts @@ -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', + ) + }) +}) diff --git a/packages/xrpl/test/models/XChainCreateBridge.test.ts b/packages/xrpl/test/models/XChainCreateBridge.test.ts new file mode 100644 index 0000000000..dfd174058e --- /dev/null +++ b/packages/xrpl/test/models/XChainCreateBridge.test.ts @@ -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', + ) + }) +}) diff --git a/packages/xrpl/test/models/XChainCreateClaimID.test.ts b/packages/xrpl/test/models/XChainCreateClaimID.test.ts new file mode 100644 index 0000000000..503fae0130 --- /dev/null +++ b/packages/xrpl/test/models/XChainCreateClaimID.test.ts @@ -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', + ) + }) +}) diff --git a/packages/xrpl/test/models/XChainModifyBridge.test.ts b/packages/xrpl/test/models/XChainModifyBridge.test.ts new file mode 100644 index 0000000000..57eeb50823 --- /dev/null +++ b/packages/xrpl/test/models/XChainModifyBridge.test.ts @@ -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', + ) + }) +}) diff --git a/tools/createValidateTests.js b/tools/createValidateTests.js new file mode 100644 index 0000000000..570644a619 --- /dev/null +++ b/tools/createValidateTests.js @@ -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());