Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions modules/abstract-substrate/src/abstractSubstrateCoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,13 @@ export class SubstrateCoin extends BaseCoin {
if (prebuildMaterial && typeof factory.material === 'function') {
factory.material(prebuildMaterial);
}
// Token enablement (preApproveAsset) transactions have no destination address — they are
// self-transactions signed by the wallet. Skip transfer recipient validation, consistent
// with how XRP and Algo handle enabletoken in their verifyTransaction implementations.
if (txParams.type === 'enabletoken') {
return true;
}

const txBuilder = factory.from(txPrebuild.txHex) as unknown as NativeTransferBuilder;
const txTo: string = txBuilder['_to'];
const txAmount: string = txBuilder['_amount'];
Expand Down
24 changes: 24 additions & 0 deletions modules/sdk-coin-polyx/test/unit/polyx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,30 @@ describe('Polyx:', function () {
});
});

describe('token enablement (preApproveAsset) transaction', function () {
it('should return true for enabletoken type with recipients (wallet root address)', async function () {
// buildTokenEnablements sets recipients[0].address = wallet rootAddress and type = 'enabletoken'.
// verifyTransaction must short-circuit before the _to check since preApproveAsset has no destination.
const walletAddress = '5F8jxKE81GhFrphyfMFr5UjeAz5wS4AaZFmeFPnf8wTetD72';
const result = await baseCoin.verifyTransaction({
txPrebuild: { txHex: rawTx.preApproveAsset.signed },
txParams: {
type: 'enabletoken',
recipients: [{ address: walletAddress, amount: '0', tokenName: 'tpolyx:sometoken' }],
},
});
result.should.be.true();
});

it('should return true for enabletoken type with no recipients', async function () {
const result = await baseCoin.verifyTransaction({
txPrebuild: { txHex: rawTx.preApproveAsset.signed },
txParams: { type: 'enabletoken' },
});
result.should.be.true();
});
});

describe('v8 transfer with coinSpecific.material', function () {
const v8Amount = '1000000';
const v8Receiver = accounts.account2;
Expand Down
Loading