-
Notifications
You must be signed in to change notification settings - Fork 283
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5440 from BitGo/COIN-2920-apt-nft-transfer
feat(sdk-coin-apt): non fungible assest transfer
- Loading branch information
Showing
10 changed files
with
7,138 additions
and
4,868 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
77 changes: 77 additions & 0 deletions
77
modules/sdk-coin-apt/src/lib/transaction/digitalAssetTransaction.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import { Transaction } from './transaction'; | ||
import { | ||
AccountAddress, | ||
Aptos, | ||
AptosConfig, | ||
EntryFunctionABI, | ||
MoveAbility, | ||
Network, | ||
objectStructTag, | ||
TransactionPayload, | ||
TransactionPayloadEntryFunction, | ||
TypeTagAddress, | ||
TypeTagGeneric, | ||
TypeTagStruct, | ||
} from '@aptos-labs/ts-sdk'; | ||
import { InvalidTransactionError, TransactionRecipient, TransactionType } from '@bitgo/sdk-core'; | ||
import { BaseCoin as CoinConfig, NetworkType } from '@bitgo/statics'; | ||
import { | ||
DIGITAL_ASSET_TYPE_ARGUMENT, | ||
DIGITAL_ASSET_TRANSFER_FUNCTION, | ||
DIGITAL_ASSET_TRANSFER_AMOUNT, | ||
} from '../constants'; | ||
|
||
export class DigitalAssetTransaction extends Transaction { | ||
constructor(coinConfig: Readonly<CoinConfig>) { | ||
super(coinConfig); | ||
this._type = TransactionType.SendNFT; | ||
} | ||
|
||
protected parseTransactionPayload(payload: TransactionPayload): void { | ||
if ( | ||
!(payload instanceof TransactionPayloadEntryFunction) || | ||
payload.entryFunction.args.length !== 2 || | ||
payload.entryFunction.type_args.length !== 1 || | ||
DIGITAL_ASSET_TYPE_ARGUMENT !== payload.entryFunction.type_args[0].toString() | ||
) { | ||
throw new InvalidTransactionError('Invalid transaction payload'); | ||
} | ||
const entryFunction = payload.entryFunction; | ||
if (!this._recipient) { | ||
this._recipient = {} as TransactionRecipient; | ||
} | ||
this._assetId = entryFunction.args[0].toString(); | ||
this._recipient.address = entryFunction.args[1].toString(); | ||
this._recipient.amount = DIGITAL_ASSET_TRANSFER_AMOUNT; | ||
} | ||
|
||
protected async buildRawTransaction(): Promise<void> { | ||
const network: Network = this._coinConfig.network.type === NetworkType.MAINNET ? Network.MAINNET : Network.TESTNET; | ||
const aptos = new Aptos(new AptosConfig({ network })); | ||
const senderAddress = AccountAddress.fromString(this._sender); | ||
const recipientAddress = AccountAddress.fromString(this._recipient.address); | ||
const digitalAssetAddress = AccountAddress.fromString(this._assetId); | ||
|
||
const transferDigitalAssetAbi: EntryFunctionABI = { | ||
typeParameters: [{ constraints: [MoveAbility.KEY] }], | ||
parameters: [new TypeTagStruct(objectStructTag(new TypeTagGeneric(0))), new TypeTagAddress()], | ||
}; | ||
|
||
const simpleTxn = await aptos.transaction.build.simple({ | ||
sender: senderAddress, | ||
data: { | ||
function: DIGITAL_ASSET_TRANSFER_FUNCTION, | ||
typeArguments: [DIGITAL_ASSET_TYPE_ARGUMENT], | ||
functionArguments: [digitalAssetAddress, recipientAddress], | ||
abi: transferDigitalAssetAbi, | ||
}, | ||
options: { | ||
maxGasAmount: this.maxGasAmount, | ||
gasUnitPrice: this.gasUnitPrice, | ||
expireTimestamp: this.expirationTime, | ||
accountSequenceNumber: this.sequenceNumber, | ||
}, | ||
}); | ||
this._rawTransaction = simpleTxn.rawTransaction; | ||
} | ||
} |
54 changes: 54 additions & 0 deletions
54
modules/sdk-coin-apt/src/lib/transactionBuilder/digitalAssestTransactionBuilder.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import { TransactionBuilder } from './transactionBuilder'; | ||
import { BaseCoin as CoinConfig } from '@bitgo/statics'; | ||
import { TransactionType } from '@bitgo/sdk-core'; | ||
import utils from '../utils'; | ||
import { TransactionPayload, TransactionPayloadEntryFunction } from '@aptos-labs/ts-sdk'; | ||
import { DigitalAssetTransaction } from '../transaction/digitalAssetTransaction'; | ||
import { DIGITAL_ASSET_TYPE_ARGUMENT } from '../constants'; | ||
|
||
export class DigitalAssetTransactionBuilder extends TransactionBuilder { | ||
constructor(_coinConfig: Readonly<CoinConfig>) { | ||
super(_coinConfig); | ||
this._transaction = new DigitalAssetTransaction(_coinConfig); | ||
} | ||
|
||
protected get transactionType(): TransactionType { | ||
return TransactionType.SendNFT; | ||
} | ||
|
||
assetId(assetId: string): TransactionBuilder { | ||
this.validateAddress({ address: assetId }); | ||
this.transaction.assetId = assetId; | ||
return this; | ||
} | ||
|
||
/** @inheritdoc */ | ||
validateTransaction(transaction?: DigitalAssetTransaction): void { | ||
if (!transaction) { | ||
throw new Error('transaction not defined'); | ||
} | ||
super.validateTransaction(transaction); | ||
this.validateAddress({ address: transaction.assetId }); | ||
} | ||
|
||
protected isValidTransactionPayload(payload: TransactionPayload) { | ||
try { | ||
if ( | ||
!(payload instanceof TransactionPayloadEntryFunction) || | ||
payload.entryFunction.args.length !== 2 || | ||
payload.entryFunction.type_args.length !== 1 || | ||
DIGITAL_ASSET_TYPE_ARGUMENT !== payload.entryFunction.type_args[0].toString() | ||
) { | ||
console.error('invalid transaction payload'); | ||
return false; | ||
} | ||
const entryFunction = payload.entryFunction; | ||
const digitalAssetAddress = entryFunction.args[0].toString(); | ||
const recipientAddress = entryFunction.args[1].toString(); | ||
return utils.isValidAddress(recipientAddress) && utils.isValidAddress(digitalAssetAddress); | ||
} catch (e) { | ||
console.error('invalid transaction payload', e); | ||
return false; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.