Skip to content

Commit 3b8ac25

Browse files
baltiyalbhavidhingra
authored andcommitted
feat(sdk-coin-apt): addition of test case for apt transaction builder
Ticket: COIN-2258
1 parent 4fa814a commit 3b8ac25

File tree

13 files changed

+785
-139
lines changed

13 files changed

+785
-139
lines changed

modules/sdk-coin-apt/src/apt.ts

Lines changed: 86 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import {
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';
1617
import 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

1827
export 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, // TODO: check this
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,43 @@ 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> {
147+
const factory = this.getBuilder();
148+
let rebuiltTransaction: BaseTransaction;
149+
150+
try {
151+
const transactionBuilder = factory.from(params.txHex);
152+
rebuiltTransaction = await transactionBuilder.build();
153+
} catch {
154+
throw new Error('Invalid transaction');
155+
}
156+
157+
return rebuiltTransaction.explainTransaction();
81158
}
82159

83160
generateKeyPair(seed?: Buffer): KeyPair {
@@ -103,4 +180,8 @@ export class Apt extends BaseCoin {
103180
signTransaction(params: SignTransactionOptions): Promise<SignedTransaction> {
104181
throw new Error('Method not implemented.');
105182
}
183+
184+
private getBuilder(): TransactionBuilderFactory {
185+
return new TransactionBuilderFactory(coins.get(this.getChain()));
186+
}
106187
}
Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,23 @@
1-
import { ITransactionExplanation, TransactionFee } from '@bitgo/sdk-core';
1+
import {
2+
TransactionExplanation as BaseTransactionExplanation,
3+
TransactionRecipient,
4+
TransactionType as BitGoTransactionType,
5+
} from '@bitgo/sdk-core';
26

3-
export type TransactionExplanation = ITransactionExplanation<TransactionFee>;
7+
export interface AptTransactionExplanation extends BaseTransactionExplanation {
8+
sender?: string;
9+
type?: BitGoTransactionType;
10+
}
411

512
/**
613
* The transaction data returned from the toJson() function of a transaction
714
*/
8-
export interface TxData {
15+
export interface TransferTxData {
916
id: string;
1017
sender: string;
11-
sequenceNumber: BigInt;
12-
maxGasAmount: BigInt;
13-
gasUnitPrice: BigInt;
14-
expirationTime: BigInt;
15-
payload: AptPayload;
16-
chainId: number;
17-
}
18-
19-
export interface AptPayload {
20-
function: string;
21-
typeArguments: string[];
22-
arguments: string[];
23-
type: string;
18+
recipient: TransactionRecipient;
19+
sequenceNumber: number;
20+
maxGasAmount: number;
21+
gasUnitPrice: number;
22+
expirationTime: number;
2423
}

0 commit comments

Comments
 (0)