diff --git a/modules/sdk-coin-apt/src/lib/constants.ts b/modules/sdk-coin-apt/src/lib/constants.ts index 425b90a2da..135f430f22 100644 --- a/modules/sdk-coin-apt/src/lib/constants.ts +++ b/modules/sdk-coin-apt/src/lib/constants.ts @@ -10,5 +10,7 @@ export const APTOS_ACCOUNT_MODULE = 'aptos_account'; export const FUNGIBLE_ASSET_MODULE = 'primary_fungible_store'; export const FUNGIBLE_ASSET_FUNCTION = '0x1::primary_fungible_store::transfer'; +export const APTOS_COIN_FUNCTION = '0x1::aptos_account::transfer_coins'; export const FUNGIBLE_ASSET = '0x1::fungible_asset::Metadata'; +export const APTOS_COIN = '0x1::aptos_coin::AptosCoin'; diff --git a/modules/sdk-coin-apt/src/lib/transaction/transferTransaction.ts b/modules/sdk-coin-apt/src/lib/transaction/transferTransaction.ts index 264cad73fd..4737bcf8f7 100644 --- a/modules/sdk-coin-apt/src/lib/transaction/transferTransaction.ts +++ b/modules/sdk-coin-apt/src/lib/transaction/transferTransaction.ts @@ -10,21 +10,28 @@ import { } from '@aptos-labs/ts-sdk'; import { BaseCoin as CoinConfig, NetworkType } from '@bitgo/statics'; +import { APTOS_COIN, APTOS_COIN_FUNCTION } from '../constants'; export class TransferTransaction extends Transaction { constructor(coinConfig: Readonly) { super(coinConfig); this._type = TransactionType.Send; + this._assetId = APTOS_COIN; } protected parseTransactionPayload(payload: TransactionPayload): void { - if (!(payload instanceof TransactionPayloadEntryFunction)) { + if ( + !(payload instanceof TransactionPayloadEntryFunction) || + !payload.entryFunction.type_args[0] || + payload.entryFunction.type_args[0].toString().length === 0 + ) { throw new InvalidTransactionError('Invalid transaction payload'); } const entryFunction = payload.entryFunction; if (!this._recipient) { this._recipient = {} as TransactionRecipient; } + this._assetId = entryFunction.type_args[0].toString(); this._recipient.address = entryFunction.args[0].toString(); const amountBuffer = Buffer.from(entryFunction.args[1].bcsToBytes()); this._recipient.amount = amountBuffer.readBigUint64LE().toString(); @@ -35,12 +42,11 @@ export class TransferTransaction extends Transaction { const aptos = new Aptos(new AptosConfig({ network })); const senderAddress = AccountAddress.fromString(this._sender); const recipientAddress = AccountAddress.fromString(this._recipient.address); - const typeArgs = this.assetId ? [this.assetId] : ['0x1::aptos_coin::AptosCoin']; const simpleTxn = await aptos.transaction.build.simple({ sender: senderAddress, data: { - function: '0x1::aptos_account::transfer_coins', - typeArguments: typeArgs, + function: APTOS_COIN_FUNCTION, + typeArguments: [this.assetId], functionArguments: [recipientAddress, this.recipient.amount], }, options: { diff --git a/modules/sdk-coin-apt/src/lib/transactionBuilder/transferBuilder.ts b/modules/sdk-coin-apt/src/lib/transactionBuilder/transferBuilder.ts index b0dc090c6c..f95204ed90 100644 --- a/modules/sdk-coin-apt/src/lib/transactionBuilder/transferBuilder.ts +++ b/modules/sdk-coin-apt/src/lib/transactionBuilder/transferBuilder.ts @@ -16,6 +16,11 @@ export class TransferBuilder extends TransactionBuilder { return TransactionType.Send; } + assetId(assetId: string): TransactionBuilder { + this.transaction.assetId = assetId; + return this; + } + /** @inheritdoc */ validateTransaction(transaction?: TransferTransaction): void { if (!transaction) { diff --git a/modules/sdk-coin-apt/test/resources/apt.ts b/modules/sdk-coin-apt/test/resources/apt.ts index aeeb23e1ae..d552708045 100644 --- a/modules/sdk-coin-apt/test/resources/apt.ts +++ b/modules/sdk-coin-apt/test/resources/apt.ts @@ -64,7 +64,7 @@ export const invalidRecipients: Recipient[] = [ export const TRANSFER = '0x1aed808916ab9b1b30b07abb53561afd46847285ce28651221d406173a37244992000000000000000200000000000000000000000000000000000000000000000000000000000000010d6170746f735f6163636f756e74087472616e73666572000220f7405c28a02cf5bab4ea4498240bb3579db45951794eb1c843bef0534c093ad908e803000000000000400d0300000000006400000000000000979390670000000002030020f73836f42257240e43d439552471fc9dbcc3f1af5bd0b4ed83f44b5f6614644240caeb90efd4b7ecd922c97bb3163e6a9de1fbb2ee0fc0d56af484f4af9b0015c5831341550af29b3686713b6657c821d894635fe13c7933f06ee043728f040b090000dbc87a1c816d9bcd06b683c37e80c7162e4d48da7812198b830e4d5d8e0629f200205223396c531f13e031a9f0cb26d459d799a52e51be9a1cb9e871afb4c31f91ff4013e7e8a1325ee5f656c93baa3d0206a1d9bd6da5abdc6f5d9b8bbbb0926ddac68f3e57a915dd217d2d43e776a6cc01af72f895ea712acc836d30349f29a3c606'; -export const CHANGED_FUNCTION_TRANSFER = +export const TRANSACTION_USING_TRANSFER_COINS = '0x1aed808916ab9b1b30b07abb53561afd46847285ce28651221d406173a37244992000000000000000200000000000000000000000000000000000000000000000000000000000000010d6170746f735f6163636f756e740e7472616e736665725f636f696e73010700000000000000000000000000000000000000000000000000000000000000010a6170746f735f636f696e094170746f73436f696e000220f7405c28a02cf5bab4ea4498240bb3579db45951794eb1c843bef0534c093ad908e803000000000000400d0300000000006400000000000000979390670000000002030020f73836f42257240e43d439552471fc9dbcc3f1af5bd0b4ed83f44b5f6614644240caeb90efd4b7ecd922c97bb3163e6a9de1fbb2ee0fc0d56af484f4af9b0015c5831341550af29b3686713b6657c821d894635fe13c7933f06ee043728f040b090000dbc87a1c816d9bcd06b683c37e80c7162e4d48da7812198b830e4d5d8e0629f200205223396c531f13e031a9f0cb26d459d799a52e51be9a1cb9e871afb4c31f91ff4013e7e8a1325ee5f656c93baa3d0206a1d9bd6da5abdc6f5d9b8bbbb0926ddac68f3e57a915dd217d2d43e776a6cc01af72f895ea712acc836d30349f29a3c606'; export const INVALID_TRANSFER = diff --git a/modules/sdk-coin-apt/test/unit/transactionBuilder/transferBuilder.ts b/modules/sdk-coin-apt/test/unit/transactionBuilder/transferBuilder.ts index 466f5ade76..453e0eecd3 100644 --- a/modules/sdk-coin-apt/test/unit/transactionBuilder/transferBuilder.ts +++ b/modules/sdk-coin-apt/test/unit/transactionBuilder/transferBuilder.ts @@ -50,7 +50,7 @@ describe('Apt Transfer Transaction', () => { }); it('should build and send a signed tx', async function () { - const txBuilder = factory.from(testData.CHANGED_FUNCTION_TRANSFER); + const txBuilder = factory.from(testData.TRANSACTION_USING_TRANSFER_COINS); const tx = (await txBuilder.build()) as TransferTransaction; should.equal(tx.type, TransactionType.Send); tx.inputs.length.should.equal(1); @@ -73,7 +73,7 @@ describe('Apt Transfer Transaction', () => { should.equal(tx.type, TransactionType.Send); const rawTx = tx.toBroadcastFormat(); should.equal(txBuilder.isValidRawTransaction(rawTx), true); - should.equal(rawTx, testData.CHANGED_FUNCTION_TRANSFER); + should.equal(rawTx, testData.TRANSACTION_USING_TRANSFER_COINS); }); it('should succeed to validate a valid signablePayload', async function () { @@ -123,7 +123,7 @@ describe('Apt Transfer Transaction', () => { }); it('should build a signed tx and validate its toJson', async function () { - const txBuilder = factory.from(testData.CHANGED_FUNCTION_TRANSFER); + const txBuilder = factory.from(testData.TRANSACTION_USING_TRANSFER_COINS); const tx = (await txBuilder.build()) as TransferTransaction; const toJson = tx.toJson(); should.equal(toJson.id, '0x80a52dd5d4f712a80b77ad7b4a12a8e61b76243a546099b0ab9acfef4e9a4e31');