Skip to content

Commit 78026ba

Browse files
committed
feat(sdk-coin-dot): implement isWalletAddress for address verfn
TICKET: WP-6460
1 parent e42fb85 commit 78026ba

File tree

2 files changed

+99
-4
lines changed

2 files changed

+99
-4
lines changed

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

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,14 @@ import {
77
Environments,
88
ExplanationResult,
99
KeyPair,
10-
MethodNotImplementedError,
1110
MPCAlgorithm,
1211
ParsedTransaction,
1312
ParseTransactionOptions,
1413
SignedTransaction,
1514
SignTransactionOptions as BaseSignTransactionOptions,
1615
UnsignedTransaction,
17-
VerifyAddressOptions,
1816
VerifyTransactionOptions,
17+
TssVerifyAddressOptions,
1918
EDDSAMethods,
2019
EDDSAMethodTypes,
2120
MPCTx,
@@ -29,6 +28,7 @@ import {
2928
MultisigType,
3029
multisigTypes,
3130
AuditDecryptedKeyParams,
31+
verifyEddsaTssWalletAddress,
3232
} from '@bitgo/sdk-core';
3333
import { BaseCoin as StaticsBaseCoin, coins, PolkadotSpecNameType } from '@bitgo/statics';
3434
import { Interface, KeyPair as DotKeyPair, Transaction, TransactionBuilderFactory, Utils } from './lib';
@@ -642,8 +642,12 @@ export class Dot extends BaseCoin {
642642
return {};
643643
}
644644

645-
async isWalletAddress(params: VerifyAddressOptions): Promise<boolean> {
646-
throw new MethodNotImplementedError();
645+
async isWalletAddress(params: TssVerifyAddressOptions): Promise<boolean> {
646+
return verifyEddsaTssWalletAddress(
647+
params,
648+
(address) => this.isValidAddress(address),
649+
(publicKey) => this.getAddressFromPublicKey(publicKey)
650+
);
647651
}
648652

649653
async verifyTransaction(params: VerifyTransactionOptions): Promise<boolean> {

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

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { BitGoAPI } from '@bitgo/sdk-api';
22
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
33
import { randomBytes } from 'crypto';
44
import should = require('should');
5+
import assert = require('assert');
56
import { Dot, Tdot, KeyPair } from '../../src';
67
import * as testData from '../fixtures';
78
import { chainName, txVersion, genesisHash, specVersion } from '../resources';
@@ -670,4 +671,94 @@ describe('DOT:', function () {
670671
);
671672
});
672673
});
674+
675+
describe('isWalletAddress', () => {
676+
it('should verify valid wallet address with correct keychain and index', async function () {
677+
const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
678+
const commonKeychain =
679+
'6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
680+
const index = '3';
681+
const keychains = [{ commonKeychain }];
682+
683+
const result = await basecoin.isWalletAddress({ keychains, address, index });
684+
result.should.equal(true);
685+
});
686+
687+
it('should return false for address with incorrect keychain', async function () {
688+
const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
689+
const wrongKeychain =
690+
'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
691+
const index = '3';
692+
const keychains = [{ commonKeychain: wrongKeychain }];
693+
694+
const result = await basecoin.isWalletAddress({ keychains, address, index });
695+
result.should.equal(false);
696+
});
697+
698+
it('should return false for address with incorrect index', async function () {
699+
const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
700+
const commonKeychain =
701+
'6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
702+
const wrongIndex = '999';
703+
const keychains = [{ commonKeychain }];
704+
705+
const result = await basecoin.isWalletAddress({ keychains, address, index: wrongIndex });
706+
result.should.equal(false);
707+
});
708+
709+
it('should throw error for invalid address', async function () {
710+
const invalidAddress = 'invalidaddress';
711+
const commonKeychain =
712+
'6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
713+
const index = '3';
714+
const keychains = [{ commonKeychain }];
715+
716+
await assert.rejects(async () => await basecoin.isWalletAddress({ keychains, address: invalidAddress, index }), {
717+
message: `invalid address: ${invalidAddress}`,
718+
});
719+
});
720+
721+
it('should throw error when keychains are missing', async function () {
722+
const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
723+
const index = '3';
724+
725+
await assert.rejects(async () => await basecoin.isWalletAddress({ address, index } as any), {
726+
message: 'missing required param keychains',
727+
});
728+
});
729+
730+
it('should throw error when keychains have different commonKeychains', async function () {
731+
const address = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
732+
const commonKeychain1 =
733+
'6d2d5150f6e435dfd9b4f225f2cc29d95ec3b61b34e8bec98693b1a7ffe44cd764f99ee5058838d785c73360ad4f24d78e0255ab2c368c09060b29a9b27f040e';
734+
const commonKeychain2 =
735+
'0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000';
736+
const index = '3';
737+
const keychains = [{ commonKeychain: commonKeychain1 }, { commonKeychain: commonKeychain2 }];
738+
739+
await assert.rejects(async () => await basecoin.isWalletAddress({ keychains, address, index }), {
740+
message: 'all keychains must have the same commonKeychain for MPC coins',
741+
});
742+
});
743+
});
744+
745+
describe('getAddressFromPublicKey', () => {
746+
it('should convert public key to SS58 address for testnet', function () {
747+
const publicKey = '53845d7b6a6e4a666fa2a0f500b88849b02926da5590993731d2b428b7643690';
748+
const expectedAddress = '5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74';
749+
750+
const address = basecoin.getAddressFromPublicKey(publicKey);
751+
address.should.equal(expectedAddress);
752+
});
753+
754+
it('should convert public key to SS58 address for mainnet', function () {
755+
const publicKey = '53845d7b6a6e4a666fa2a0f500b88849b02926da5590993731d2b428b7643690';
756+
// Mainnet uses different SS58 prefix (0) vs testnet (42)
757+
const address = prodCoin.getAddressFromPublicKey(publicKey);
758+
address.should.be.type('string');
759+
address.length.should.be.greaterThan(0);
760+
// Should be different from testnet address
761+
address.should.not.equal('5DxD9nT16GQLrU6aB5pSS5VtxoZbVju3NHUCcawxZyZCTf74');
762+
});
763+
});
673764
});

0 commit comments

Comments
 (0)