Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions modules/abstract-substrate/src/abstractSubstrateCoin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import {
EDDSAMethods,
EDDSAMethodTypes,
KeyPair,
MethodNotImplementedError,
MPCAlgorithm,
MPCConsolidationRecoveryOptions,
MPCRecoveryOptions,
Expand All @@ -20,7 +19,9 @@ import {
ParseTransactionOptions,
RecoveryTxRequest,
SignedTransaction,
VerifyAddressOptions,
TssVerifyAddressOptions,
UnexpectedAddressError,
verifyEddsaTssWalletAddress,
VerifyTransactionOptions,
} from '@bitgo/sdk-core';
import { CoinFamily, BaseCoin as StaticsBaseCoin } from '@bitgo/statics';
Expand Down Expand Up @@ -110,8 +111,18 @@ export class SubstrateCoin extends BaseCoin {
}

/** @inheritDoc **/
isWalletAddress(params: VerifyAddressOptions): Promise<boolean> {
throw new MethodNotImplementedError();
async isWalletAddress(params: TssVerifyAddressOptions): Promise<boolean> {
const isValid = await verifyEddsaTssWalletAddress(
params,
(addr) => this.isValidAddress(addr),
(pubKey) => this.getAddressFromPublicKey(pubKey)
);

if (!isValid) {
throw new UnexpectedAddressError(`address validation failure: ${params.address} is not a wallet address`);
}

return true;
}

/** @inheritDoc **/
Expand Down
87 changes: 87 additions & 0 deletions modules/sdk-coin-tao/test/unit/tao.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,15 @@ describe('Tao:', function () {
let bitgo: TestBitGoAPI;
let baseCoin;

// Test data from wallet 694042b5efbee757e47ec2771cf58a45
const isWalletAddressTestData = {
commonKeychain:
'6e2235aee215f3909b42bf67c360f5bc6ba7087cbf0ed5ba841dd044ae7c3051722f9be974e8e79fa6c4c93d109dbc618672e36571925df0b5a7c5b015bcd382',
rootAddress: '5GU55E8X2YVSpd4LApeJR5RsXwQ8AnPdjM37Qz1drLTKh7as',
receiveAddress: '5EN6LFnhFRtWiwZfFncqBxaNUabTASKnSxoDt2zQvpVX4qVy',
receiveAddressIndex: 1,
};

before(function () {
bitgo = TestBitGo.decorate(BitGoAPI, { env: 'mock' });
bitgo.safeRegister('tao', Tao.createInstance);
Expand All @@ -19,6 +28,84 @@ describe('Tao:', function () {
baseCoin = bitgo.coin('ttao') as Ttao;
});

describe('isWalletAddress', function () {
it('should verify root address (index 0)', async function () {
const keychains = [
{ commonKeychain: isWalletAddressTestData.commonKeychain },
{ commonKeychain: isWalletAddressTestData.commonKeychain },
{ commonKeychain: isWalletAddressTestData.commonKeychain },
];

const result = await baseCoin.isWalletAddress({
address: isWalletAddressTestData.rootAddress,
keychains,
index: 0,
});

result.should.be.true();
});

it('should verify receive address (index > 0)', async function () {
const keychains = [
{ commonKeychain: isWalletAddressTestData.commonKeychain },
{ commonKeychain: isWalletAddressTestData.commonKeychain },
{ commonKeychain: isWalletAddressTestData.commonKeychain },
];

const result = await baseCoin.isWalletAddress({
address: isWalletAddressTestData.receiveAddress,
keychains,
index: isWalletAddressTestData.receiveAddressIndex,
});

result.should.be.true();
});

it('should throw for address mismatch', async function () {
const keychains = [
{ commonKeychain: isWalletAddressTestData.commonKeychain },
{ commonKeychain: isWalletAddressTestData.commonKeychain },
{ commonKeychain: isWalletAddressTestData.commonKeychain },
];

await baseCoin
.isWalletAddress({
address: isWalletAddressTestData.receiveAddress,
keychains,
index: 0, // Wrong index for this address
})
.should.be.rejectedWith(
`address validation failure: ${isWalletAddressTestData.receiveAddress} is not a wallet address`
);
});

it('should throw for invalid address', async function () {
const keychains = [
{ commonKeychain: isWalletAddressTestData.commonKeychain },
{ commonKeychain: isWalletAddressTestData.commonKeychain },
{ commonKeychain: isWalletAddressTestData.commonKeychain },
];

await baseCoin
.isWalletAddress({
address: 'invalidaddress',
keychains,
index: 0,
})
.should.be.rejectedWith('invalid address: invalidaddress');
});

it('should throw for missing keychains', async function () {
await baseCoin
.isWalletAddress({
address: isWalletAddressTestData.rootAddress,
keychains: [],
index: 0,
})
.should.be.rejectedWith('missing required param keychains');
});
});

describe.skip('Recover Transactions:', function () {
const sandBox = sinon.createSandbox();
const recoveryDestination = '5FJ18ywfrWuRifNyc8aPwQ5ium19Fefwmx18H4XYkDc36F2A';
Expand Down