@bsv/wallet-toolbox
Version:
BRC100 conforming wallet, wallet storage and wallet signer components
284 lines • 12.1 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
const sdk_1 = require("@bsv/sdk");
const src_1 = require("../../../src");
const sdk_2 = require("../../../src/sdk");
const localWalletMethods_1 = require("../../utils/localWalletMethods");
const dotenv = __importStar(require("dotenv"));
dotenv.config();
const chain = 'main';
const options = {
setActiveClient: true,
useMySQLConnectionForClient: true,
useTestIdentityKey: false,
useIdentityKey2: false
};
describe('localWallet2 tests', () => {
jest.setTimeout(99999999);
test('0 monitor runOnce', async () => {
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
const log = await setup.monitor.runTask('UnFail');
if (log)
console.log(log);
await setup.monitor.runOnce();
await setup.wallet.destroy();
});
test('0a abort nosend', async () => {
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
await setup.wallet.listNoSendActions({ labels: [] }, true);
await setup.wallet.destroy();
});
test('1 recover 1 sat outputs', async () => {
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
await (0, localWalletMethods_1.recoverOneSatTestOutputs)(setup, 1);
await setup.wallet.destroy();
});
test('2 create 1 sat delayed', async () => {
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
const car = await (0, localWalletMethods_1.createOneSatTestOutput)(setup, {}, 1);
//await trackReqByTxid(setup, car.txid!)
await setup.wallet.destroy();
});
test('2a create 1 sat immediate', async () => {
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
const car = await (0, localWalletMethods_1.createOneSatTestOutput)(setup, { acceptDelayedBroadcast: false }, 1);
await setup.wallet.destroy();
});
test('2c burn 1 sat output', async () => {
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
await (0, localWalletMethods_1.burnOneSatTestOutput)(setup, {}, 1);
await setup.wallet.destroy();
});
test('2d doubleSpend old change', async () => {
var _a, _b;
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
try {
await (0, localWalletMethods_1.doubleSpendOldChange)(setup, {
acceptDelayedBroadcast: false
});
}
catch (eu) {
const e = src_1.sdk.WalletError.fromUnknown(eu);
expect(e.code).toBe('WERR_REVIEW_ACTIONS');
expect(((_a = e.reviewActionResults) === null || _a === void 0 ? void 0 : _a.length) === 1).toBe(true);
const rar = e.reviewActionResults[0];
expect(rar.status).toBe('doubleSpend');
expect((_b = rar.competingTxs) === null || _b === void 0 ? void 0 : _b.length).toBe(1);
}
await setup.wallet.destroy();
});
test('4 review change utxos', async () => {
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
const lor = await setup.wallet.listOutputs({
basket: sdk_2.specOpInvalidChange,
tags: ['all']
});
if (lor.totalOutputs > 0) {
debugger;
const lor = await setup.wallet.listOutputs({
basket: sdk_2.specOpInvalidChange,
tags: ['all', 'release']
});
}
await setup.wallet.destroy();
});
test('5 review and release all production invalid change utxos', async () => {
const { env, storage } = await (0, localWalletMethods_1.createMainReviewSetup)();
const users = await storage.findUsers({ partial: {} });
const withInvalid = {};
// [76, 48, 166, 94, 110, 111, 81]
const vargs = {
basket: sdk_2.specOpInvalidChange,
tags: [],
tagQueryMode: 'all',
includeLockingScripts: false,
includeTransactions: false,
includeCustomInstructions: false,
includeTags: false,
includeLabels: false,
limit: 0,
offset: 0,
seekPermission: false,
knownTxids: []
};
for (const user of users) {
const { userId } = user;
const auth = { userId, identityKey: '' };
let r = await storage.listOutputs(auth, vargs);
if (r.totalOutputs > 0) {
const total = r.outputs.reduce((s, o) => (s += o.satoshis), 0);
console.log(`userId ${userId}: ${r.totalOutputs} unspendable utxos, total ${total}, ${user.identityKey}`);
withInvalid[userId] = { user, outputs: r.outputs, total };
}
}
if (Object.keys(withInvalid).length > 0) {
debugger;
// Release invalids
for (const { user, outputs } of Object.values(withInvalid)) {
const { userId } = user;
const auth = { userId, identityKey: '' };
await storage.listOutputs(auth, { ...vargs, tags: ['release'] });
}
// Verify
for (const { user, outputs } of Object.values(withInvalid)) {
const { userId } = user;
const auth = { userId, identityKey: '' };
const r = await storage.listOutputs(auth, vargs);
expect(r.totalOutputs).toBe(0);
}
}
await storage.destroy();
});
test('6 review and unfail false doubleSpends', async () => {
const { env, storage, services } = await (0, localWalletMethods_1.createMainReviewSetup)();
let offset = 1100;
const limit = 100;
let allUnfails = [];
for (;;) {
let log = '';
const unfails = [];
const reqs = await storage.findProvenTxReqs({ partial: { status: 'doubleSpend' }, paged: { limit, offset } });
for (const req of reqs) {
const gsr = await services.getStatusForTxids([req.txid]);
if (gsr.results[0].status !== 'unknown') {
log += `unfail ${req.provenTxReqId} ${req.txid}\n`;
unfails.push(req.provenTxReqId);
}
}
console.log(`OFFSET: ${offset} ${unfails.length} unfails\n${log}`);
allUnfails = allUnfails.concat(unfails);
if (reqs.length < limit)
break;
offset += reqs.length;
}
debugger;
for (const id of allUnfails) {
await storage.updateProvenTxReq(id, { status: 'unfail' });
}
await storage.destroy();
});
test('7 review and unfail false invalids', async () => {
const { env, storage, services } = await (0, localWalletMethods_1.createMainReviewSetup)();
let offset = 400;
const limit = 100;
let allUnfails = [];
for (;;) {
let log = '';
const unfails = [];
const reqs = await storage.findProvenTxReqs({ partial: { status: 'invalid' }, paged: { limit, offset } });
for (const req of reqs) {
if (!req.txid || !req.rawTx)
continue;
const gsr = await services.getStatusForTxids([req.txid]);
if (gsr.results[0].status !== 'unknown') {
log += `unfail ${req.provenTxReqId} ${req.txid}\n`;
unfails.push(req.provenTxReqId);
}
}
console.log(`OFFSET: ${offset} ${unfails.length} unfails\n${log}`);
allUnfails = allUnfails.concat(unfails);
if (reqs.length < limit)
break;
offset += reqs.length;
}
debugger;
for (const id of allUnfails) {
await storage.updateProvenTxReq(id, { status: 'unfail' });
}
await storage.destroy();
});
test('8 Beef verifier', async () => {
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
// replace bb with beef to test
const bb = new sdk_1.Beef().toBinary();
const beef = sdk_1.Beef.fromBinary(bb);
console.log(beef.toLogString());
const ok = await beef.verify(await setup.services.getChainTracker());
await setup.wallet.destroy();
});
test.skip('9 received payment from wif and outpoint', async () => {
const setup = await (0, localWalletMethods_1.createSetup)(chain, options);
console.log(`active store ${setup.wallet.storage.getActiveStore()}`);
if (!setup.wallet.storage.isActiveEnabled)
throw new Error('Active storage is not enabled.');
const pk = sdk_1.PrivateKey.fromWif('L4ZRWA...Nw4Brt8rvJLRZegPF2oiBKJaxUgr4e');
const outpoint = { txid: '5e2965a50618425af21bebddb9aa60c3e12f64c8e1eb44b6589273455a9760e9', vout: 0 };
const address = pk.toAddress();
console.log(`address: ${address.toString()}`);
const inputBEEF = await setup.activeStorage.getBeefForTransaction(outpoint.txid, { ignoreStorage: true });
const btx = inputBEEF.findTxid(outpoint.txid);
const satoshis = btx.tx.outputs[0].satoshis;
const unlock = src_1.Setup.getUnlockP2PKH(pk, satoshis);
const label = 'inputBrayden257';
const car = await setup.wallet.createAction({
inputBEEF: inputBEEF.toBinary(),
inputs: [
{
outpoint: `${outpoint.txid}.${outpoint.vout}`,
unlockingScriptLength: 108,
inputDescription: label
}
],
labels: [label],
description: label
});
const st = car.signableTransaction;
const beef = sdk_1.Beef.fromBinary(st.tx);
const tx = beef.findAtomicTransaction(beef.txs.slice(-1)[0].txid);
tx.inputs[0].unlockingScriptTemplate = unlock;
await tx.sign();
const unlockingScript = tx.inputs[0].unlockingScript.toHex();
const signArgs = {
reference: st.reference,
spends: { 0: { unlockingScript } },
options: {
acceptDelayedBroadcast: false
}
};
const sar = await setup.wallet.signAction(signArgs);
{
const beef = sdk_1.Beef.fromBinary(sar.tx);
const txid = sar.txid;
console.log(`
BEEF
${beef.toHex()}
${beef.toLogString()}
`);
}
await setup.wallet.destroy();
});
});
//# sourceMappingURL=localWallet2.man.test.js.map