Skip to content

Commit

Permalink
feat: add tests for receiving funds
Browse files Browse the repository at this point in the history
  • Loading branch information
limpbrains committed Nov 27, 2024
1 parent 026cf75 commit fa0cae8
Show file tree
Hide file tree
Showing 10 changed files with 445 additions and 150 deletions.
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@
"description": "A self-custodial, JS Bitcoin wallet management library.",
"main": "dist/index.js",
"scripts": {
"test": "yarn build && env mocha --exit -r ts-node/register 'tests/**/*.ts'",
"test": "yarn build && env mocha --exit -r ts-node/register 'tests/**/*.test.ts'",
"test:boost": "yarn build && env mocha --exit -r ts-node/register 'tests/boost.test.ts'",
"test:wallet": "yarn build && env mocha --exit -r ts-node/register 'tests/wallet.test.ts'",
"test:receive": "yarn build && env mocha --exit -r ts-node/register 'tests/receive.test.ts'",
"test:storage": "yarn build && env mocha --exit -r ts-node/register 'tests/storage.test.ts'",
"test:electrum": "yarn build && env mocha --exit -r ts-node/register 'tests/electrum.test.ts'",
"test:derivation": "yarn build && env mocha --exit -r ts-node/register 'tests/derivation.test.ts'",
"test:transaction": "yarn build && env mocha --exit -r ts-node/register 'tests/transaction.test.ts'",
"test:storage": "yarn build && env mocha --exit -r ts-node/register 'tests/storage.test.ts'",
"example": "ts-node example",
"lint": "eslint . --ext .js,.jsx,.ts,.tsx",
"lint:check": "eslint . --ext .js,.jsx,.ts,.tsx",
Expand Down
10 changes: 7 additions & 3 deletions src/wallet/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import * as bip39 from 'bip39';
import * as bitcoin from 'bitcoinjs-lib';
import { Network, networks } from 'bitcoinjs-lib';
import BIP32Factory, { BIP32Interface } from 'bip32';
import * as ecc from '@bitcoinerlab/secp256k1';
import cloneDeep from 'lodash.clonedeep';

import {
EAddressType,
EAvailableNetworks,
Expand Down Expand Up @@ -107,9 +110,7 @@ import {
import { Electrum } from '../electrum';
import { Transaction } from '../transaction';
import { GAP_LIMIT, GAP_LIMIT_CHANGE, TRANSACTION_DEFAULTS } from './constants';
import cloneDeep from 'lodash.clonedeep';
import { btcToSats } from '../utils/conversion';
import * as bip39 from 'bip39';

const bip32 = BIP32Factory(ecc);

Expand Down Expand Up @@ -1974,7 +1975,6 @@ export class Wallet {
[key: string]: number[];
} = {};
for (const tx of receivedTxs) {
this.sendMessage('transactionReceived', tx);
// No need to scan an address with a saved UTXO.
if (utxoScriptHashes.has(tx.transaction.scriptHash)) continue;
for (const addressType in addresses) {
Expand Down Expand Up @@ -2011,6 +2011,10 @@ export class Wallet {
}
}

for (const tx of receivedTxs) {
this.sendMessage('transactionReceived', tx);
}

return ok(notificationTxid);
}

Expand Down
106 changes: 55 additions & 51 deletions tests/boost.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,62 +25,66 @@ let waitForElectrum: TWaitForElectrum;
const rpc = new BitcoinJsonRpc(bitcoinURL);
const failure = { canBoost: false, rbf: false, cpfp: false };

beforeEach(async function () {
describe('Boost', async function () {
this.timeout(testTimeout);

let balance = await rpc.getBalance();
const address = await rpc.getNewAddress();
await rpc.generateToAddress(1, address);

while (balance < 10) {
await rpc.generateToAddress(10, address);
balance = await rpc.getBalance();
}

waitForElectrum = await initWaitForElectrumToSync(
{ host: electrumHost, port: electrumPort },
bitcoinURL
);

await waitForElectrum();

const mnemonic = generateMnemonic();

const res = await Wallet.create({
rbf: true,
mnemonic,
// mnemonic: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
network: EAvailableNetworks.regtest,
addressType: EAddressType.p2wpkh,
electrumOptions: {
servers: [
{
host: '127.0.0.1',
ssl: 60002,
tcp: 60001,
protocol: EProtocol.tcp
}
],
net,
tls
},
// reduce gap limit to speed up tests
gapLimitOptions: {
lookAhead: 2,
lookBehind: 2,
lookAheadChange: 2,
lookBehindChange: 2
beforeEach(async function () {
this.timeout(testTimeout);

let balance = await rpc.getBalance();
const address = await rpc.getNewAddress();
await rpc.generateToAddress(1, address);

while (balance < 10) {
await rpc.generateToAddress(10, address);
balance = await rpc.getBalance();
}

waitForElectrum = await initWaitForElectrumToSync(
{ host: electrumHost, port: electrumPort },
bitcoinURL
);

await waitForElectrum();

const mnemonic = generateMnemonic();

const res = await Wallet.create({
rbf: true,
mnemonic,
// mnemonic: 'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
network: EAvailableNetworks.regtest,
addressType: EAddressType.p2wpkh,
electrumOptions: {
servers: [
{
host: '127.0.0.1',
ssl: 60002,
tcp: 60001,
protocol: EProtocol.tcp
}
],
net,
tls
},
// reduce gap limit to speed up tests
gapLimitOptions: {
lookAhead: 2,
lookBehind: 2,
lookAheadChange: 2,
lookBehindChange: 2
}
});
if (res.isErr()) {
throw res.error;
}
wallet = res.value;
await wallet.refreshWallet({});
});
if (res.isErr()) {
throw res.error;
}
wallet = res.value;
await wallet.refreshWallet({});
});

describe('Boost', async function () {
this.timeout(testTimeout);
afterEach(async function () {
await wallet?.electrum?.disconnect();
});

it('Should fail in some cases.', async () => {
// tx not found
Expand Down
4 changes: 1 addition & 3 deletions tests/derivation.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import * as chai from 'chai';
import { expect } from 'chai';
import {
EAddressType,
EAvailableNetworks,
Expand All @@ -8,8 +8,6 @@ import {
getKeyDerivationPathString
} from '../src';

const expect = chai.expect;

describe('Derivation Methods', () => {
it('Should return default derivation path object for p2wpkh', () => {
const pathRes = getKeyDerivationPath({
Expand Down
51 changes: 29 additions & 22 deletions tests/electrum.test.ts
Original file line number Diff line number Diff line change
@@ -1,39 +1,46 @@
import * as chai from 'chai';
import { expect } from 'chai';
import net from 'net';
import tls from 'tls';

import { Wallet } from '../';
import { EAvailableNetworks, EAddressType, IGetUtxosResponse } from '../src';
import { TEST_MNEMONIC } from './constants';
import { Result } from '../src';
import { servers } from '../example/helpers';
import {
EAddressType,
EAvailableNetworks,
IGetUtxosResponse,
Result
} from '../src';
import { TEST_MNEMONIC } from './constants';
import { EXPECTED_SHARED_RESULTS } from './expected-results';

const expect = chai.expect;

const testTimeout = 60000;

let wallet: Wallet;

before(async function () {
describe('Electrum Methods', async function (): Promise<void> {
this.timeout(testTimeout);
const res = await Wallet.create({
mnemonic: TEST_MNEMONIC,
network: EAvailableNetworks.testnet,
addressType: EAddressType.p2wpkh,
electrumOptions: {
servers: servers[EAvailableNetworks.testnet],
net,
tls
}

before(async function () {
this.timeout(testTimeout);
const res = await Wallet.create({
mnemonic: TEST_MNEMONIC,
network: EAvailableNetworks.testnet,
addressType: EAddressType.p2wpkh,
electrumOptions: {
servers: servers[EAvailableNetworks.testnet],
net,
tls
}
});
if (res.isErr()) throw res.error;
wallet = res.value;
await wallet.refreshWallet({});
});

after(async function () {
await wallet?.electrum?.disconnect();
});
if (res.isErr()) throw res.error;
wallet = res.value;
await wallet.refreshWallet({});
});

describe('Electrum Methods', async function (): Promise<void> {
this.timeout(testTimeout);
it('connectToElectrum: Should connect to a random Electrum server', async () => {
const connectResponse = await wallet.connectToElectrum();
if (connectResponse.isErr()) throw connectResponse.error;
Expand Down
Loading

0 comments on commit fa0cae8

Please sign in to comment.