diff --git a/packages/xrpl/src/models/transactions/signerListSet.ts b/packages/xrpl/src/models/transactions/signerListSet.ts index 3aaaccbd..3677d522 100644 --- a/packages/xrpl/src/models/transactions/signerListSet.ts +++ b/packages/xrpl/src/models/transactions/signerListSet.ts @@ -28,6 +28,8 @@ export interface SignerListSet extends BaseTransaction { const MAX_SIGNERS = 32 +const HEX_WALLET_LOCATOR_REGEX = /^[0-9A-Fa-f]{64}$/u + /** * Verify the form and type of an SignerListSet at runtime. * @@ -64,4 +66,18 @@ export function validateSignerListSet(tx: Record): void { `SignerListSet: maximum of ${MAX_SIGNERS} members allowed in SignerEntries`, ) } + + if (tx.SignerEntries.length > 0) { + for (const entry of tx.SignerEntries) { + const signerEntry = entry.SignerEntry + if ( + signerEntry.WalletLocator !== undefined && + !HEX_WALLET_LOCATOR_REGEX.test(signerEntry.WalletLocator) + ) { + throw new ValidationError( + `SignerListSet: WalletLocator in SignerEntry must be a 256-bit (32-byte) hexadecimal value`, + ) + } + } + } } diff --git a/packages/xrpl/test/integration/transactions/signerListSet.ts b/packages/xrpl/test/integration/transactions/signerListSet.ts index 97edd91a..2c66c0b0 100644 --- a/packages/xrpl/test/integration/transactions/signerListSet.ts +++ b/packages/xrpl/test/integration/transactions/signerListSet.ts @@ -36,29 +36,4 @@ describe('SignerListSet', function () { } await testTransaction(this.client, tx, this.wallet) }) - - it('sign with WalletLocator', async function () { - const tx: SignerListSet = { - TransactionType: 'SignerListSet', - Account: this.wallet.classicAddress, - SignerEntries: [ - { - SignerEntry: { - Account: 'r5nx8ZkwEbFztnc8Qyi22DE9JYjRzNmvs', - SignerWeight: 1, - WalletLocator: - 'CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE', - }, - }, - { - SignerEntry: { - Account: 'r3RtUvGw9nMoJ5FuHxuoVJvcENhKtuF9ud', - SignerWeight: 1, - }, - }, - ], - SignerQuorum: 2, - } - await testTransaction(this.client, tx, this.wallet) - }) }) diff --git a/packages/xrpl/test/models/signerListSet.ts b/packages/xrpl/test/models/signerListSet.ts index c4dcc739..ccbac3a3 100644 --- a/packages/xrpl/test/models/signerListSet.ts +++ b/packages/xrpl/test/models/signerListSet.ts @@ -150,4 +150,66 @@ describe('SignerListSet', function () { errorMessage, ) }) + + it(`verifies valid WalletLocator in SignerEntries`, function () { + signerListSetTx.SignerQuorum = 3 + signerListSetTx.SignerEntries = [ + { + SignerEntry: { + Account: 'rBFBipte4nAQCTsRxd2czwvSurhCpAf4X6', + SignerWeight: 1, + WalletLocator: + 'CAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFECAFE', + }, + }, + { + SignerEntry: { + Account: 'r3ijUH32iiy9tYNj3rD7hKWYjy1BFUxngm', + SignerWeight: 1, + }, + }, + { + SignerEntry: { + Account: 'rpwq8vi4Mn3L5kDJmb8Mg59CanPFPzMCnj', + SignerWeight: 1, + WalletLocator: + '00000000000000000000000000000000000000000000000000000000DEADBEEF', + }, + }, + ] + + assert.doesNotThrow(() => validateSignerListSet(signerListSetTx)) + assert.doesNotThrow(() => validate(signerListSetTx)) + }) + + it(`throws w/ invalid WalletLocator in SignerEntries`, function () { + signerListSetTx.SignerQuorum = 2 + signerListSetTx.SignerEntries = [ + { + SignerEntry: { + Account: 'rBFBipte4nAQCTsRxd2czwvSurhCpAf4X6', + SignerWeight: 1, + WalletLocator: 'not_valid', + }, + }, + { + SignerEntry: { + Account: 'r3ijUH32iiy9tYNj3rD7hKWYjy1BFUxngm', + SignerWeight: 1, + }, + }, + ] + const errorMessage = + 'SignerListSet: WalletLocator in SignerEntry must be a 256-bit (32-byte) hexadecimal value' + assert.throws( + () => validateSignerListSet(signerListSetTx), + ValidationError, + errorMessage, + ) + assert.throws( + () => validate(signerListSetTx), + ValidationError, + errorMessage, + ) + }) })