Skip to content

Commit 5f99a06

Browse files
committed
feat(sdk-coin-icp): add missing function implementations
Ticket: WIN-5189
1 parent 959fb86 commit 5f99a06

File tree

2 files changed

+47
-4
lines changed

2 files changed

+47
-4
lines changed

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

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import assert from 'assert';
12
import {
23
BaseBroadcastTransactionOptions,
34
BaseBroadcastTransactionResult,
@@ -7,7 +8,6 @@ import {
78
ECDSAUtils,
89
Environments,
910
KeyPair,
10-
MethodNotImplementedError,
1111
MPCAlgorithm,
1212
MultisigType,
1313
multisigTypes,
@@ -18,6 +18,8 @@ import {
1818
SignTransactionOptions,
1919
TssVerifyAddressOptions,
2020
VerifyTransactionOptions,
21+
InvalidAddressError,
22+
UnexpectedAddressError,
2123
} from '@bitgo/sdk-core';
2224
import { coins, BaseCoin as StaticsBaseCoin } from '@bitgo/statics';
2325
import { Principal } from '@dfinity/principal';
@@ -37,9 +39,12 @@ import {
3739
ROOT_PATH,
3840
Signatures,
3941
SigningPayload,
42+
IcpTransactionExplanation,
43+
IcpCoinSpecific,
4044
} from './lib/iface';
4145
import { TransactionBuilderFactory } from './lib/transactionBuilderFactory';
4246
import utils from './lib/utils';
47+
import { Transaction } from './lib';
4348

4449
/**
4550
* Class representing the Internet Computer (ICP) coin.
@@ -84,16 +89,50 @@ export class Icp extends BaseCoin {
8489
return Math.pow(10, this._staticsCoin.decimalPlaces);
8590
}
8691

92+
async explainTransaction(params: { txHex: string }): Promise<IcpTransactionExplanation> {
93+
const transaction = (await (await this.getBuilderFactory().from(params.txHex)).build()) as Transaction;
94+
return transaction.explainTransaction();
95+
}
96+
8797
async verifyTransaction(params: VerifyTransactionOptions): Promise<boolean> {
88-
throw new MethodNotImplementedError();
98+
const { txParams, txPrebuild } = params;
99+
const { txHex } = txPrebuild;
100+
if (!txHex) {
101+
throw new Error('txHex is required');
102+
}
103+
const explainedTx = await this.explainTransaction({ txHex });
104+
105+
if (Array.isArray(txParams.recipients) && txParams.recipients.length > 0) {
106+
if (txParams.recipients.length > 1) {
107+
throw new Error(
108+
`${this.getChain()} doesn't support sending to more than 1 destination address within a single transaction. Try again, using only a single recipient.`
109+
);
110+
}
111+
assert(explainedTx.outputs.length === 1, 'Tx outputs does not match with expected txParams recipients');
112+
113+
const output = explainedTx.outputs[0];
114+
const recipient = txParams.recipients[0];
115+
assert(
116+
output.address === recipient.address && BigNumber(output.amount).eq(BigNumber(recipient.amount)),
117+
'Tx outputs does not match with expected txParams recipients'
118+
);
119+
}
120+
return true;
89121
}
90122

91123
async isWalletAddress(params: TssVerifyAddressOptions): Promise<boolean> {
92-
throw new MethodNotImplementedError();
124+
if (!this.isValidAddress(params.address)) {
125+
throw new InvalidAddressError(`invalid address: ${params.address}`);
126+
}
127+
const rootAddress = (params.coinSpecific as IcpCoinSpecific).rootAddress;
128+
if (params.address.includes(rootAddress)) {
129+
throw new UnexpectedAddressError(`address validation failure: ${params.address} vs ${rootAddress}`);
130+
}
131+
return true;
93132
}
94133

95134
async parseTransaction(params: ParseTransactionOptions): Promise<ParsedTransaction> {
96-
throw new MethodNotImplementedError();
135+
return {};
97136
}
98137

99138
/**

modules/sdk-coin-icp/src/lib/iface.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -194,3 +194,7 @@ export interface RecoveryOptions {
194194
export interface PublicNodeSubmitResponse {
195195
status: string;
196196
}
197+
198+
export interface IcpCoinSpecific {
199+
rootAddress: string;
200+
}

0 commit comments

Comments
 (0)