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
2 changes: 1 addition & 1 deletion modules/abstract-utxo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
"build": "npm run build:cjs && npm run build:esm",
"build:cjs": "yarn tsc --build --incremental --verbose .",
"build:esm": "yarn tsc --project tsconfig.esm.json",
"fmt": "prettier --write .",
"fmt": "prettier --write '{src,test}/**/*.{ts,js,json}'",
"check-fmt": "prettier --check '{src,test}/**/*.{ts,js,json}'",
"clean": "rm -rf ./dist",
"lint": "eslint --quiet .",
Expand Down
18 changes: 9 additions & 9 deletions modules/abstract-utxo/test/integration/impl/bch/bch.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as should from 'should';
import 'should-http';
import assert from 'node:assert/strict';

import { BitGoAPI } from '@bitgo/sdk-api';
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';
import * as nock from 'nock';
Expand Down Expand Up @@ -34,13 +34,13 @@ describe('BCH:', function () {
otp: bitgo.testUserOTP(),
});

should.exist(transaction);
transaction.should.have.property('transfer');
transaction.should.have.property('txid');
transaction.should.have.property('tx');
transaction.status.should.containEql('signed');
transaction.transfer.type.should.containEql('send');
transaction.transfer.wallet.should.containEql(wallet._wallet.id);
assert.ok(transaction != null);
assert.ok('transfer' in transaction);
assert.ok('txid' in transaction);
assert.ok('tx' in transaction);
assert.ok(transaction.status.includes('signed'));
assert.ok(transaction.transfer.type.includes('send'));
assert.ok(transaction.transfer.wallet.includes(wallet._wallet.id));
});
});
});
16 changes: 7 additions & 9 deletions modules/abstract-utxo/test/unit/customSigner.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
import * as utxoLib from '@bitgo/utxo-lib';
import 'should';
import 'should-sinon';
import nock = require('nock');
import * as sinon from 'sinon';
import { CustomSigningFunction, common } from '@bitgo/sdk-core';

import { defaultBitGo, getDefaultWalletKeys, getUtxoCoin, getUtxoWallet } from './util';
import { defaultBitGo, getDefaultWalletKeys, getUtxoCoin, getUtxoWallet, assertHasProperty } from './util';

nock.disableNetConnect();

Expand Down Expand Up @@ -65,8 +63,8 @@ describe('UTXO Custom Signer Function', function () {
const scope = nocks({ txHex: psbt.toHex() });
const result = await wallet.sendMany({ recipients, customSigningFunction });

result.should.have.property('ok', true);
customSigningFunction.should.have.been.calledTwice();
assertHasProperty(result, 'ok', true);
sinon.assert.calledTwice(customSigningFunction as sinon.SinonStub);
scope.done();
});

Expand All @@ -81,8 +79,8 @@ describe('UTXO Custom Signer Function', function () {
const scope = nocks({ txHex: psbt.toHex() });
const result = await wallet.sendMany({ recipients, customSigningFunction });

result.should.have.property('ok', true);
customSigningFunction.should.have.been.calledOnce();
assertHasProperty(result, 'ok', true);
sinon.assert.calledOnce(customSigningFunction as sinon.SinonStub);
scope.done();
});

Expand All @@ -97,8 +95,8 @@ describe('UTXO Custom Signer Function', function () {
const scope = nocks({ txHex: tx.buildIncomplete().toHex() });
const result = await wallet.sendMany({ recipients, customSigningFunction });

result.should.have.property('ok', true);
customSigningFunction.should.have.been.calledOnce();
assertHasProperty(result, 'ok', true);
sinon.assert.calledOnce(customSigningFunction as sinon.SinonStub);
scope.done();
});
});
230 changes: 104 additions & 126 deletions modules/abstract-utxo/test/unit/impl/bch/unit/bch.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import assert from 'node:assert/strict';

import { BitGoAPI } from '@bitgo/sdk-api';
import { TestBitGo, TestBitGoAPI } from '@bitgo/sdk-test';

import { Bch, Tbch } from '../../../../../src/impl/bch';

function eq(actual: string, expected: string) {
assert.strictEqual(actual, expected);
}

describe('Custom BCH Tests', function () {
const bitgo: TestBitGoAPI = TestBitGo.decorate(BitGoAPI, { env: 'test' });
bitgo.initializeTestVars();
Expand All @@ -15,145 +21,117 @@ describe('Custom BCH Tests', function () {
// we use mainnet bch so we can reuse the mainnet address examples
it('should correctly convert addresses', function () {
// P2PKH cashaddr -> cashaddr
bch
.canonicalAddress('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr')
.should.equal('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a');
bch
.canonicalAddress('qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr')
.should.equal('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a');

eq(
bch.canonicalAddress('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr'),
'bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a'
);
eq(
bch.canonicalAddress('qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr'),
'bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a'
);
// P2PKH base58 -> cashaddr
bch
.canonicalAddress('1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu', 'cashaddr')
.should.equal('bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a');

eq(
bch.canonicalAddress('1BpEi6DfDAUFd7GtittLSdBeYJvcoaVggu', 'cashaddr'),
'bitcoincash:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a'
);
// P2SH cashaddr -> cashaddr
bch
.canonicalAddress('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr')
.should.equal('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq');
bch
.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr')
.should.equal('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq');

eq(
bch.canonicalAddress('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr'),
'bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'
);
eq(
bch.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr'),
'bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'
);
// P2SH base58 -> cashaddr
bch
.canonicalAddress('3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC', 'cashaddr')
.should.equal('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq');

eq(
bch.canonicalAddress('3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC', 'cashaddr'),
'bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'
);
// no 'bitcoincash:' prefix
bch
.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr')
.should.equal('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq');

eq(
bch.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq', 'cashaddr'),
'bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'
);
// P2PKH cashaddr -> base58
bch
.canonicalAddress('bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'base58')
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');
bch
.canonicalAddress('qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'base58')
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');

eq(
bch.canonicalAddress('bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'base58'),
'16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb'
);
eq(
bch.canonicalAddress('qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'base58'),
'16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb'
);
// P2PKH base58 -> base58
bch
.canonicalAddress('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb', 'base58')
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');

eq(bch.canonicalAddress('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb', 'base58'), '16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');
// P2SH cashaddr -> base58
bch
.canonicalAddress('bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58')
.should.equal('3LDsS579y7sruadqu11beEJoTjdFiFCdX4');
bch
.canonicalAddress('pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58')
.should.equal('3LDsS579y7sruadqu11beEJoTjdFiFCdX4');

eq(
bch.canonicalAddress('bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58'),
'3LDsS579y7sruadqu11beEJoTjdFiFCdX4'
);
eq(
bch.canonicalAddress('pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58'),
'3LDsS579y7sruadqu11beEJoTjdFiFCdX4'
);
// P2SH base58 -> base58
bch
.canonicalAddress('3LDsS579y7sruadqu11beEJoTjdFiFCdX4', 'base58')
.should.equal('3LDsS579y7sruadqu11beEJoTjdFiFCdX4');

eq(bch.canonicalAddress('3LDsS579y7sruadqu11beEJoTjdFiFCdX4', 'base58'), '3LDsS579y7sruadqu11beEJoTjdFiFCdX4');
// undefined version defaults to base58
bch
.canonicalAddress('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq')
.should.equal('3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC');
bch
.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq')
.should.equal('3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC');

eq(
bch.canonicalAddress('bitcoincash:ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'),
'3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC'
);
eq(bch.canonicalAddress('ppm2qsznhks23z7629mms6s4cwef74vcwvn0h829pq'), '3CWFddi6m4ndiGyKqzYvsFYagqDLPVMTzC');
// all capitalized
bch
.canonicalAddress('BITCOINCASH:QQQ3728YW0Y47SQN6L2NA30MCW6ZM78DZQRE909M2R', 'base58')
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');
bch
.canonicalAddress('QQQ3728YW0Y47SQN6L2NA30MCW6ZM78DZQRE909M2R', 'base58')
.should.equal('16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb');

eq(
bch.canonicalAddress('BITCOINCASH:QQQ3728YW0Y47SQN6L2NA30MCW6ZM78DZQRE909M2R', 'base58'),
'16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb'
);
eq(
bch.canonicalAddress('QQQ3728YW0Y47SQN6L2NA30MCW6ZM78DZQRE909M2R', 'base58'),
'16w1D5WRVKJuZUsSRzdLp9w3YGcgoxDXb'
);
// testnet addresses
tbch
.canonicalAddress('2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X', 'cashaddr')
.should.equal('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f');
tbch
.canonicalAddress('n3jYBjCzgGNydQwf83Hz6GBzGBhMkKfgL1', 'cashaddr')
.should.equal('bchtest:qremgr9dr9x5swv82k69qdjzrvdxgkaaesftdp5xla');
tbch
.canonicalAddress('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr')
.should.equal('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f');
tbch
.canonicalAddress('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr')
.should.equal('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f');
tbch
.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'base58')
.should.equal('2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X');
tbch
.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'base58')
.should.equal('2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X');
tbch
.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr')
.should.equal('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f');
eq(
tbch.canonicalAddress('2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X', 'cashaddr'),
'bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f'
);
eq(
tbch.canonicalAddress('n3jYBjCzgGNydQwf83Hz6GBzGBhMkKfgL1', 'cashaddr'),
'bchtest:qremgr9dr9x5swv82k69qdjzrvdxgkaaesftdp5xla'
);
eq(
tbch.canonicalAddress('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr'),
'bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f'
);
eq(
tbch.canonicalAddress('bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr'),
'bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f'
);
eq(
tbch.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'base58'),
'2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'
);
eq(
tbch.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'base58'),
'2NCEDmmKNNnqKvnWw7pE3RLzuFe5aHHVy1X'
);
eq(
tbch.canonicalAddress('prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f', 'cashaddr'),
'bchtest:prgrnjengs555k3cff2s3gqxg3xyyr9uzyh9js5m8f'
);
});

it('should reject invalid addresses', function () {
// improperly short data segment
(() => {
bch.canonicalAddress('bitcoincash:sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58');
}).should.throw();

// mismatched data segment (cashaddr)
(() => {
bch.canonicalAddress('bitcoincash:yr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58');
}).should.throw();

// double prefix
(() => {
bch.canonicalAddress('bitcoincash:bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58');
}).should.throw();

// mismatched data segment (base58)
(() => {
bch.canonicalAddress('3DDsS579y7sruadqu11beEJoTjdFiFCdX4', 'base58');
}).should.throw();

// improper prefix
(() => {
bch.canonicalAddress(':qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'base58');
}).should.throw();

(() => {
bch.canonicalAddress('bitcoin:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'base58');
}).should.throw();

// mismatched capitalization
(() => {
bch.canonicalAddress('bitcoincash:QPM2Qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr');
}).should.throw();

// improper version
(() => {
bch.canonicalAddress('bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'blah');
}).should.throw();

// undefined address
(() => {
bch.canonicalAddress(undefined as any, 'blah');
}).should.throw();
assert.throws(() => bch.canonicalAddress('bitcoincash:sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58'));
assert.throws(() => bch.canonicalAddress('bitcoincash:yr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58'));
assert.throws(() =>
bch.canonicalAddress('bitcoincash:bitcoincash:pr95sy3j9xwd2ap32xkykttr4cvcu7as4yc93ky28e', 'base58')
);
assert.throws(() => bch.canonicalAddress('3DDsS579y7sruadqu11beEJoTjdFiFCdX4', 'base58'));
assert.throws(() => bch.canonicalAddress(':qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'base58'));
assert.throws(() => bch.canonicalAddress('bitcoin:qpm2qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'base58'));
assert.throws(() => bch.canonicalAddress('bitcoincash:QPM2Qsznhks23z7629mms6s4cwef74vcwvy22gdx6a', 'cashaddr'));
assert.throws(() => bch.canonicalAddress('bitcoincash:qqq3728yw0y47sqn6l2na30mcw6zm78dzqre909m2r', 'blah'));
assert.throws(() => bch.canonicalAddress(undefined as any, 'blah'));
});
});
Loading
Loading