Skip to content

Commit

Permalink
✨ feat: custom starting address index js wallet
Browse files Browse the repository at this point in the history
  • Loading branch information
matthewjablack committed Sep 16, 2023
1 parent 64b3ffd commit 82b126e
Show file tree
Hide file tree
Showing 7 changed files with 101 additions and 66 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"test": "yarn run test:unit && yarn run test:integration",
"test:unit": "turbo run test",
"test:integration": "nyc --reporter=text --reporter=lcov cross-env NODE_ENV=test mocha --parallel",
"test:integration:single": "nyc --reporter=text --reporter=lcov cross-env NODE_ENV=test mocha",
"prepublishOnly": "yarn build",
"changeset": "changeset",
"version": "yarn changeset version",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ interface BitcoinJsWalletProviderOptions {
mnemonic: string;
baseDerivationPath: string;
addressType?: bT.AddressType;
addressIndex?: number;
}

export default class BitcoinJsWalletProvider extends BitcoinWalletProvider(
Expand All @@ -53,8 +54,9 @@ export default class BitcoinJsWalletProvider extends BitcoinWalletProvider(
mnemonic,
baseDerivationPath,
addressType = bT.AddressType.BECH32,
addressIndex = 0,
} = options;
super({ network, baseDerivationPath, addressType });
super({ network, baseDerivationPath, addressType, addressIndex });

if (!mnemonic) throw new Error('Mnemonic should not be empty');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ interface BitcoinWalletProviderOptions {
network: BitcoinNetwork;
baseDerivationPath: string;
addressType?: bT.AddressType;
addressIndex?: number;
}

export default <T extends Constructor<Provider>>(superclass: T) => {
Expand All @@ -55,6 +56,7 @@ export default <T extends Constructor<Provider>>(superclass: T) => {
_maxAddressesToDerive: number;
_baseDerivationPath: string;
_addressType: bT.AddressType;
_addressIndex: number;
_derivationCache: DerivationCache;

constructor(...args: any[]) {
Expand All @@ -63,6 +65,7 @@ export default <T extends Constructor<Provider>>(superclass: T) => {
network,
baseDerivationPath,
addressType = bT.AddressType.BECH32,
addressIndex = 0,
} = options;
const addressTypes = Object.values(bT.AddressType);
if (!addressTypes.includes(addressType)) {
Expand All @@ -74,6 +77,7 @@ export default <T extends Constructor<Provider>>(superclass: T) => {
this._baseDerivationPath = baseDerivationPath;
this._network = network;
this._addressType = addressType;
this._addressIndex = addressIndex;
this._derivationCache = {};
this._unusedAddressesBlacklist = {};
this._maxAddressesToDerive = 5000;
Expand Down Expand Up @@ -282,7 +286,7 @@ export default <T extends Constructor<Provider>>(superclass: T) => {
const unusedAddressMap = { change: null, nonChange: null };

let addrList;
let addressIndex = 0;
let addressIndex = this._addressIndex;
let changeAddresses: Address[] = [];
let nonChangeAddresses: Address[] = [];

Expand Down
27 changes: 24 additions & 3 deletions tests/integration/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
/* eslint-env mocha */
import Provider from '@atomicfinance/provider';
import { Transaction } from '@atomicfinance/types/lib';
import BN from 'bignumber.js';
import { generateMnemonic } from 'bip39';
import * as cfdJs from 'cfd-js';
Expand Down Expand Up @@ -123,6 +124,20 @@ bitcoinWithJs4.addProvider(
bitcoinWithJs4.addProvider(new BitcoinCfdProvider(cfdJs));
bitcoinWithJs4.addProvider(new BitcoinDlcProvider(network, cfdDlcJs));

const bitcoinWithJs5 = new Client();
bitcoinWithJs5.addProvider((mockedBitcoinRpcProvider() as unknown) as Provider);
bitcoinWithJs5.addProvider(
new BitcoinJsWalletProvider({
network,
mnemonic: generateMnemonic(256),
baseDerivationPath: `m/84'/${config.bitcoin.network.coinType}'/0'`,
addressType: bitcoin.AddressType.BECH32,
addressIndex: 100, // custom starting addressIndex
}) as any,
);
bitcoinWithJs5.addProvider(new BitcoinCfdProvider(cfdJs));
bitcoinWithJs5.addProvider(new BitcoinDlcProvider(network, cfdDlcJs));

const chains = {
bitcoinWithNode: {
id: 'Bitcoin Node',
Expand Down Expand Up @@ -155,9 +170,15 @@ const chains = {
client: bitcoinWithJs4,
network: network,
},
bitcoinWithJs5: {
id: 'Bitcoin Js',
name: 'bitcoin',
client: bitcoinWithJs5,
network: network,
},
};

async function fundAddress(address: string) {
async function fundAddress(address: string): Promise<Transaction<any>> {
const tx = await chains.bitcoinWithNode.client.chain.sendTransaction({
to: address,
value: new BN(CONSTANTS.BITCOIN_ADDRESS_DEFAULT_BALANCE),
Expand All @@ -166,11 +187,11 @@ async function fundAddress(address: string) {
return tx;
}

async function importAddresses(chain: Chain) {
async function importAddresses(chain: Chain): Promise<void> {
return chain.client.getMethod('importAddresses')();
}

async function mineBlock() {
async function mineBlock(): Promise<void> {
try {
await chains.bitcoinWithNode.client.chain.generateBlock(1);
} catch (e) {
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ export default {
bitcoin: {
rpc: {
host: 'http://localhost:18443',
username: 'bitcoin',
username: 'admin',
password: 'local321',
},
network: BitcoinNetworks.bitcoin_regtest,
Expand Down
9 changes: 8 additions & 1 deletion tests/integration/wallet/wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ import * as fixtures from '../fixtures/wallet.json';

const chain = chains.bitcoinWithJs;
const alice = chain.client;

const bob = chains.bitcoinWithJs2.client;
const frank = chains.bitcoinWithJs5.client; // custom starting addressIndex provided

describe('wallet provider', () => {
describe('getUnusedAddress', () => {
Expand All @@ -37,6 +37,13 @@ describe('wallet provider', () => {
});
});

describe('getAddress with addressIndex', () => {
it('should get address at custom derivation path', async () => {
const unusedAddress = await frank.wallet.getUnusedAddress();
expect(unusedAddress.derivationPath).to.equal("m/84'/1'/0'/0/100");
});
});

describe('createMultisig (m-of-n)', () => {
it('should create 2-of-2 multisig', async () => {
const { address, redeemScript } = await alice.wallet.createMultisig(
Expand Down
Loading

0 comments on commit 82b126e

Please sign in to comment.