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
51 changes: 51 additions & 0 deletions modules/sdk-coin-near/test/unit/tokenEnablementValidation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -612,6 +612,57 @@ describe('NEAR Token Enablement Validation', function () {
);
});

it('should populate recipients from enableTokens in buildParams for TSS wallets', async function () {
// Regression test: before the fix, buildTokenEnablements on TSS wallets did not populate
// buildParams.recipients — only buildParams.enableTokens was set. This caused verifyTransaction
// to throw "missing token name in transaction parameters" because it reads from
// txParams.recipients[0].tokenName (where txParams = { ...txPrebuild.buildParams, ...params }).
const bgUrl = common.Environments['test'].uri;

nock(bgUrl)
.post(`/api/v2/wallet/${tssWallet.id()}/txrequests`)
.reply(200, {
txRequestId: 'test-request-id',
apiVersion: 'full',
transactions: [
{
state: 'pending',
unsignedTx: {
serializedTxHex: testData.rawTx.selfStorageDeposit.unsigned,
signableHex: testData.rawTx.selfStorageDeposit.unsigned,
derivationPath: 'm/0',
feeInfo: { fee: 1160407, feeString: '1160407' },
},
signatureShares: [],
},
],
});

const buildResult = await tssWallet.buildTokenEnablements({
enableTokens: [{ name: 'tnear:tnep24dp' }],
});

const txPrebuild = buildResult[0] as any;

// Verify buildParams.recipients is populated — this is what flows into txParams
// via { ...txPrebuild.buildParams, ...params } inside prebuildAndSignTransaction
txPrebuild.buildParams.should.have.property('recipients');
txPrebuild.buildParams.recipients.should.have.length(1);
txPrebuild.buildParams.recipients[0].tokenName.should.equal('tnear:tnep24dp');
txPrebuild.buildParams.recipients[0].address.should.equal(testData.accounts.account1.address);

// Simulate the txParams construction that prebuildAndSignTransaction performs,
// then confirm verifyTransaction no longer throws "missing token name"
const txParams = { ...txPrebuild.buildParams };
await basecoin.verifyTransaction({
txParams,
txPrebuild,
wallet: tssWallet as any,
verification: { verifyTokenEnablement: true },
walletType: 'tss',
});
});

it('should validate correct storage deposit in TSS wallet flow', async function () {
const bgUrl = common.Environments['test'].uri;

Expand Down
14 changes: 14 additions & 0 deletions modules/sdk-core/src/bitgo/wallet/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3961,6 +3961,20 @@ export class Wallet implements IWallet {
}
// Check if we build with intent
if (this._wallet.multisigType === 'tss') {
// Populate recipients from enableTokens so verifyTransaction can access tokenName.
// enableTokens is kept (not deleted) since the server needs it to build the transaction.
buildParams.recipients = params.enableTokens.map((token) => {
const address =
token.address || this._wallet.coinSpecific?.baseAddress || this._wallet.coinSpecific?.rootAddress;
if (!address) {
throw new Error('Wallet does not have base address, must specify with token param');
}
return {
tokenName: token.name,
address,
amount: '0',
};
});
return [await this.prebuildTransaction(buildParams)];
} else {
// Rewrite tokens into recipients for buildTransaction
Expand Down
Loading