-
Notifications
You must be signed in to change notification settings - Fork 302
Expand file tree
/
Copy pathdescriptorAddress.ts
More file actions
90 lines (78 loc) · 3.22 KB
/
descriptorAddress.ts
File metadata and controls
90 lines (78 loc) · 3.22 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import * as assert from 'node:assert';
import * as utxolib from '@bitgo/utxo-lib';
import { address as wasmAddress, CoinName } from '@bitgo/wasm-utxo';
import { IWallet, WalletCoinSpecific } from '@bitgo/sdk-core';
import { descriptor as utxod } from '../../src';
import { getUtxoCoin } from './util';
export function getDescriptorAddress(d: string, index: number, coinName: CoinName): string {
const derivedScript = utxod.Descriptor.fromString(d, 'derivable').atDerivationIndex(index).scriptPubkey();
return wasmAddress.fromOutputScriptWithCoin(derivedScript, coinName);
}
describe('descriptor wallets', function () {
const coin = getUtxoCoin('tbtc');
const xpubs = utxolib.testutil.getKeyTriple('setec astronomy').map((k) => k.neutered().toBase58());
function withChecksum(descriptor: string): string {
return utxod.Descriptor.fromString(descriptor, 'derivable').toString();
}
function getNamedDescriptor2Of2(name: string, a: string, b: string): utxod.NamedDescriptor {
return {
name,
value: withChecksum(`sh(multi(2,${a}/*,${b}/*))`),
signatures: [],
};
}
function getIWalletWithDescriptors(descriptors: utxod.NamedDescriptor[]): IWallet {
return {
coinSpecific() {
return { descriptors } as unknown as WalletCoinSpecific;
},
} as IWallet;
}
const descFoo = getNamedDescriptor2Of2('foo', xpubs[0], xpubs[1]);
const descBar = getNamedDescriptor2Of2('bar', xpubs[1], xpubs[0]);
const addressFoo0 = getDescriptorAddress(descFoo.value, 0, coin.name);
const addressFoo1 = getDescriptorAddress(descFoo.value, 1, coin.name);
const addressBar0 = getDescriptorAddress(descBar.value, 0, coin.name);
it('has expected values', function () {
assert.deepStrictEqual(
[addressFoo0, addressFoo1, addressBar0],
[
'2N9b1trWxMJN16mTzGJypFn6pEWfXtgh689',
'2N1YFzj4ECzcjuruaEvSzGaGGH1topMXMXZ',
'2N9oN5Kc2fLt2MrxEkuQPsy8Fg2KdrFfeKH',
]
);
});
function runTestIsAddress(
address: string,
index: number,
descriptorName: string,
descriptorChecksum: string,
expected: true | Error | RegExp
) {
it(`should return ${expected} for address ${address} with index ${index} and descriptor ${descriptorName} with checksum ${descriptorChecksum}`, async function () {
const wallet = getIWalletWithDescriptors([descFoo, descBar]);
async function f() {
return coin.isWalletAddress(
{
address,
index,
coinSpecific: { descriptorName, descriptorChecksum },
keychains: xpubs.map((pub) => ({ pub })),
},
wallet
);
}
if (expected === true) {
assert.equal(await f(), expected);
} else {
// because isWalletAddress is stupid it actually throws instead of returning false
await assert.rejects(f, expected);
}
});
}
runTestIsAddress(addressFoo0, 0, 'foo', descFoo.value.slice(-8), true);
runTestIsAddress(addressFoo1, 0, 'foo', descFoo.value.slice(-8), /Address mismatch for descriptor/);
runTestIsAddress(addressBar0, 0, 'bar', descFoo.value.slice(-8), /Descriptor checksum mismatch/);
runTestIsAddress(addressFoo0, 0, 'bar', descBar.value.slice(-8), /Address mismatch for descriptor/);
});