11import {
22 BaseCoin ,
3+ BaseTransaction ,
34 BitGoBase ,
45 InvalidAddressError ,
56 KeyPair ,
@@ -11,9 +12,17 @@ import {
1112 VerifyAddressOptions ,
1213 VerifyTransactionOptions ,
1314} from '@bitgo/sdk-core' ;
14- import { BaseCoin as StaticsBaseCoin } from '@bitgo/statics' ;
15- import { KeyPair as AptKeyPair } from './lib' ;
15+ import { BaseCoin as StaticsBaseCoin , coins } from '@bitgo/statics' ;
16+ import { KeyPair as AptKeyPair , TransactionBuilderFactory , TransferTransaction } from './lib' ;
1617import utils from './lib/utils' ;
18+ import * as _ from 'lodash' ;
19+ import BigNumber from 'bignumber.js' ;
20+ import { ExplainTransactionOptions } from './lib/types' ;
21+ import { AptTransactionExplanation } from './lib/iface' ;
22+
23+ export interface AptParseTransactionOptions extends ParseTransactionOptions {
24+ txHex : string ;
25+ }
1726
1827export class Apt extends BaseCoin {
1928 protected readonly _staticsCoin : Readonly < StaticsBaseCoin > ;
@@ -64,7 +73,40 @@ export class Apt extends BaseCoin {
6473 }
6574
6675 async verifyTransaction ( params : VerifyTransactionOptions ) : Promise < boolean > {
67- throw new Error ( 'Method not implemented.' ) ;
76+ const coinConfig = coins . get ( this . getChain ( ) ) ;
77+ const { txPrebuild : txPrebuild , txParams : txParams } = params ;
78+ const transaction = new TransferTransaction ( coinConfig ) ;
79+ const rawTx = txPrebuild . txHex ;
80+ if ( ! rawTx ) {
81+ throw new Error ( 'missing required tx prebuild property txHex' ) ;
82+ }
83+ transaction . fromRawTransaction ( rawTx ) ;
84+ const explainedTx = transaction . explainTransaction ( ) ;
85+ if ( txParams . recipients !== undefined ) {
86+ const filteredRecipients = txParams . recipients ?. map ( ( recipient ) => {
87+ return {
88+ address : recipient . address ,
89+ amount : BigInt ( recipient . amount ) ,
90+ } ;
91+ } ) ;
92+ const filteredOutputs = explainedTx . outputs . map ( ( output ) => {
93+ return {
94+ address : output . address ,
95+ amount : BigInt ( output . amount ) ,
96+ } ;
97+ } ) ;
98+ if ( ! _ . isEqual ( filteredOutputs , filteredRecipients ) ) {
99+ throw new Error ( 'Tx outputs does not match with expected txParams recipients' ) ;
100+ }
101+ let totalAmount = new BigNumber ( 0 ) ;
102+ for ( const recipients of txParams . recipients ) {
103+ totalAmount = totalAmount . plus ( recipients . amount ) ;
104+ }
105+ if ( ! totalAmount . isEqualTo ( explainedTx . outputAmount ) ) {
106+ throw new Error ( 'Tx total amount does not match with expected total amount field' ) ;
107+ }
108+ }
109+ return true ;
68110 }
69111
70112 async isWalletAddress ( params : VerifyAddressOptions ) : Promise < boolean > {
@@ -76,8 +118,41 @@ export class Apt extends BaseCoin {
76118 return true ;
77119 }
78120
79- parseTransaction ( params : ParseTransactionOptions ) : Promise < ParsedTransaction > {
80- throw new Error ( 'Method not implemented.' ) ;
121+ async parseTransaction ( params : AptParseTransactionOptions ) : Promise < ParsedTransaction > {
122+ const transactionExplanation = await this . explainTransaction ( { txHex : params . txHex } ) ;
123+ if ( ! transactionExplanation ) {
124+ throw new Error ( 'Invalid transaction' ) ;
125+ }
126+ return {
127+ inputs : [
128+ {
129+ address : transactionExplanation . sender ,
130+ amount : transactionExplanation . outputAmount ,
131+ } ,
132+ ] ,
133+ outputs : [
134+ {
135+ address : transactionExplanation . outputs [ 0 ] . address ,
136+ amount : transactionExplanation . outputs [ 0 ] . amount ,
137+ } ,
138+ ] ,
139+ } ;
140+ }
141+
142+ /**
143+ * Explain a Apt transaction
144+ * @param params
145+ */
146+ async explainTransaction ( params : ExplainTransactionOptions ) : Promise < AptTransactionExplanation | undefined > {
147+ const factory = this . getBuilder ( ) ;
148+ let rebuiltTransaction : BaseTransaction ;
149+ try {
150+ const transactionBuilder = factory . from ( params . txHex ) ;
151+ rebuiltTransaction = await transactionBuilder . build ( ) ;
152+ } catch {
153+ return undefined ;
154+ }
155+ return rebuiltTransaction . explainTransaction ( ) ;
81156 }
82157
83158 generateKeyPair ( seed ?: Buffer ) : KeyPair {
@@ -103,4 +178,8 @@ export class Apt extends BaseCoin {
103178 signTransaction ( params : SignTransactionOptions ) : Promise < SignedTransaction > {
104179 throw new Error ( 'Method not implemented.' ) ;
105180 }
181+
182+ private getBuilder ( ) : TransactionBuilderFactory {
183+ return new TransactionBuilderFactory ( coins . get ( this . getChain ( ) ) ) ;
184+ }
106185}
0 commit comments