Skip to content

Commit 791c320

Browse files
committed
feat: address verification for vet
TICKET: WP-7050
1 parent 7a6dab5 commit 791c320

File tree

2 files changed

+146
-4
lines changed

2 files changed

+146
-4
lines changed

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

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,17 @@ import {
2020
SignedTransaction,
2121
SignTransactionOptions,
2222
TokenTransferRecipientParams,
23+
TssVerifyAddressOptions,
2324
VerifyAddressOptions,
2425
VerifyTransactionOptions,
26+
isTssVerifyAddressOptions,
2527
TokenType,
2628
Ecdsa,
2729
ECDSAUtils,
2830
Environments,
2931
BaseBroadcastTransactionOptions,
3032
BaseBroadcastTransactionResult,
33+
verifyMPCWalletAddress,
3134
} from '@bitgo/sdk-core';
3235
import * as mpc from '@bitgo/sdk-lib-mpc';
3336
import { BaseCoin as StaticsBaseCoin, coins } from '@bitgo/statics';
@@ -53,6 +56,12 @@ interface FeeEstimateData {
5356
coefDivisor: string;
5457
}
5558

59+
export interface TssVerifyVetAddressOptions extends TssVerifyAddressOptions {
60+
address: string;
61+
baseAddress?: string;
62+
walletVersion?: number;
63+
}
64+
5665
/**
5766
* Full Name: Vechain
5867
* Docs: https://docs.vechain.org/
@@ -153,12 +162,50 @@ export class Vet extends BaseCoin {
153162
return true;
154163
}
155164

156-
async isWalletAddress(params: VerifyAddressOptions): Promise<boolean> {
157-
const { address: newAddress } = params;
165+
/**
166+
* Verify that an address belongs to this wallet.
167+
*
168+
* @param {VerifyAddressOptions | TssVerifyAddressOptions} params - Verification parameters
169+
* @returns {Promise<boolean>} True if address belongs to wallet
170+
* @throws {InvalidAddressError} If address format is invalid
171+
* @throws {Error} If invalid wallet version or missing parameters
172+
*/
173+
async isWalletAddress(params: VerifyAddressOptions | TssVerifyAddressOptions): Promise<boolean> {
174+
const { address, baseAddress, walletVersion } = params as TssVerifyVetAddressOptions;
175+
176+
if (address && !this.isValidAddress(address)) {
177+
throw new InvalidAddressError(`invalid address: ${address}`);
178+
}
179+
180+
if (walletVersion !== 6) {
181+
throw new Error(`VET only supports wallet version 6, but got version ${walletVersion}`);
182+
}
183+
184+
if (!isTssVerifyAddressOptions(params)) {
185+
throw new Error('VET requires TSS verification parameters (keychains with commonKeychain)');
186+
}
158187

159-
if (!this.isValidAddress(newAddress)) {
160-
throw new InvalidAddressError(`invalid address: ${newAddress}`);
188+
const isVerifyingBaseAddress = baseAddress && address.toLowerCase() === baseAddress.toLowerCase();
189+
if (isVerifyingBaseAddress) {
190+
const index = typeof params.index === 'string' ? parseInt(params.index, 10) : params.index;
191+
if (index !== 0) {
192+
throw new Error(`Base address verification requires index 0, but got index ${params.index}.`);
193+
}
161194
}
195+
196+
const result = await verifyMPCWalletAddress(
197+
{ ...params, keyCurve: 'secp256k1' },
198+
this.isValidAddress.bind(this),
199+
(pubKey) => {
200+
const keyPair = new EthKeyPair({ pub: pubKey });
201+
return keyPair.getAddress();
202+
}
203+
);
204+
205+
if (!result) {
206+
throw new InvalidAddressError(`invalid address: ${address}`);
207+
}
208+
162209
return true;
163210
}
164211

modules/sdk-coin-vet/test/unit/vet.ts

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,4 +238,99 @@ describe('Vechain', function () {
238238
basecoin.isValidAddress(address).should.equal(false);
239239
});
240240
});
241+
242+
describe('address verification', () => {
243+
const testData = {
244+
walletVersion: 6,
245+
commonKeychain:
246+
'02fad451e7d1a536897ded5f803a73cc7309a403cf43bb25bda494b9800efe32999b6b71b6159eccf1244492556b733f68733a23c184bf40bc37c52da5ad29e575',
247+
baseAddress: '0x8420429aa50b7f6ab196c4ce0dcf629fdbb821a1',
248+
feeAddress: '0x33f9d3172de8a88e47b399562e51fa9cde0f2511',
249+
depositAddress: '0x26b88c0a103d185792a9597580c2c5170d93f410',
250+
depositIndex: 3,
251+
forwarderVersion: 5,
252+
};
253+
254+
it('should verify a valid TSS base address (wallet version 6)', async function () {
255+
const params = {
256+
address: testData.baseAddress,
257+
baseAddress: testData.baseAddress,
258+
keychains: [
259+
{ commonKeychain: testData.commonKeychain },
260+
{ commonKeychain: testData.commonKeychain },
261+
{ commonKeychain: testData.commonKeychain },
262+
],
263+
index: 0,
264+
walletVersion: testData.walletVersion,
265+
coinSpecific: {
266+
feeAddress: testData.feeAddress,
267+
forwarderVersion: testData.forwarderVersion,
268+
},
269+
};
270+
271+
const result = await basecoin.isWalletAddress(params);
272+
result.should.equal(true);
273+
});
274+
275+
it('should fail to verify a invalid TSS base address (wallet version 6)', async function () {
276+
const params = {
277+
address: '0x8420429aa50b7f6ab196c4ce0dcf629fdbb821a0',
278+
baseAddress: testData.baseAddress,
279+
keychains: [
280+
{ commonKeychain: testData.commonKeychain },
281+
{ commonKeychain: testData.commonKeychain },
282+
{ commonKeychain: testData.commonKeychain },
283+
],
284+
index: 0,
285+
walletVersion: testData.walletVersion,
286+
coinSpecific: {
287+
feeAddress: testData.feeAddress,
288+
forwarderVersion: testData.forwarderVersion,
289+
},
290+
};
291+
292+
await basecoin.isWalletAddress(params).should.be.rejected();
293+
});
294+
295+
it('should verify a valid TSS deposit address (wallet version 6)', async function () {
296+
const params = {
297+
address: testData.depositAddress,
298+
baseAddress: testData.baseAddress,
299+
keychains: [
300+
{ commonKeychain: testData.commonKeychain },
301+
{ commonKeychain: testData.commonKeychain },
302+
{ commonKeychain: testData.commonKeychain },
303+
],
304+
index: testData.depositIndex,
305+
walletVersion: testData.walletVersion,
306+
coinSpecific: {
307+
feeAddress: testData.feeAddress,
308+
forwarderVersion: testData.forwarderVersion,
309+
},
310+
};
311+
312+
const result = await basecoin.isWalletAddress(params);
313+
result.should.equal(true);
314+
});
315+
316+
it('should fail to verify a invalid TSS deposit address (wallet version 6)', async function () {
317+
const params = {
318+
address: '0x26b88c0a103d185792a9597580c2c5170d93f411',
319+
baseAddress: testData.baseAddress,
320+
keychains: [
321+
{ commonKeychain: testData.commonKeychain },
322+
{ commonKeychain: testData.commonKeychain },
323+
{ commonKeychain: testData.commonKeychain },
324+
],
325+
index: testData.depositIndex,
326+
walletVersion: testData.walletVersion,
327+
coinSpecific: {
328+
feeAddress: testData.feeAddress,
329+
forwarderVersion: testData.forwarderVersion,
330+
},
331+
};
332+
333+
await basecoin.isWalletAddress(params).should.be.rejected();
334+
});
335+
});
241336
});

0 commit comments

Comments
 (0)