UNPKG

@bsv/wallet-toolbox

Version:

BRC100 conforming wallet, wallet storage and wallet signer components

283 lines 14 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const sdk_1 = require("@bsv/sdk"); const src_1 = require("../../../src"); const TestUtilsWalletStorage_1 = require("../../utils/TestUtilsWalletStorage"); const sdk_2 = require("../../../src/sdk"); const Format_1 = require("../../../src/utility/Format"); const utilityHelpers_noBuffer_1 = require("../../../src/utility/utilityHelpers.noBuffer"); describe('operations.man tests', () => { jest.setTimeout(99999999); test('0 review and release all production invalid change utxos', async () => { const { env, storage } = await TestUtilsWalletStorage_1._tu.createMainReviewSetup(); const users = await storage.findUsers({ partial: {} }); const withInvalid = {}; const vargs = { basket: sdk_2.specOpInvalidChange, tags: ['release'], tagQueryMode: 'all', includeLockingScripts: false, includeTransactions: false, includeCustomInstructions: false, includeTags: false, includeLabels: false, limit: 0, offset: 0, seekPermission: false, knownTxids: [] }; let log = ''; 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); let l = `userId ${userId}: ${r.totalOutputs} utxos updated, total ${total}, ${user.identityKey}\n`; for (const o of r.outputs) { l += ` ${o.outpoint} ${o.satoshis} now ${o.spendable ? 'spendable' : 'spent'}\n`; } console.log(l); log += l; withInvalid[userId] = { user, outputs: r.outputs, total }; } } console.log(log || 'Found zero invalid change outputs.'); await storage.destroy(); }); test('1 review and unfail false doubleSpends', async () => { const { env, storage, services } = await TestUtilsWalletStorage_1._tu.createMainReviewSetup(); let offset = 0; const limit = 100; let allUnfails = []; let reviewed = 0; for (;;) { let log = ''; const unfails = []; const reqs = await storage.findProvenTxReqs({ partial: { status: 'doubleSpend' }, paged: { limit, offset }, orderDescending: true }); 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); } reviewed++; } console.log(`DoubleSpends OFFSET: ${offset} ${reviewed} ${unfails.length} unfails\n${log}`); allUnfails = allUnfails.concat(unfails); if (reqs.length < limit) break; offset += reqs.length; } for (const id of allUnfails) { await storage.updateProvenTxReq(id, { status: 'unfail' }); } await storage.destroy(); }); test('2 review and unfail false invalids', async () => { const { env, storage, services } = await TestUtilsWalletStorage_1._tu.createMainReviewSetup(); let offset = 0; const limit = 100; let allUnfails = []; let reviewed = 0; for (;;) { let log = ''; const unfails = []; const reqs = await storage.findProvenTxReqs({ partial: { status: 'invalid' }, paged: { limit, offset }, orderDescending: true }); 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); } reviewed++; } console.log(`Failed OFFSET: ${offset} ${reviewed} ${unfails.length} unfails\n${log}`); allUnfails = allUnfails.concat(unfails); if (reqs.length < limit) break; offset += reqs.length; } for (const id of allUnfails) { await storage.updateProvenTxReq(id, { status: 'unfail' }); } await storage.destroy(); }); test.skip('3 review proven_txs', async () => { var _a; const { env, storage, services } = await TestUtilsWalletStorage_1._tu.createMainReviewSetup(); let offset = 0; const limit = 100; let allUnfails = []; //for (const provenTxId of [3064, 3065, 11268, 11269, 11270, 11271] ) { for (let height = 895000; height < 895026; height++) { let log = ''; const unfails = []; const txs = await storage.findProvenTxs({ partial: { height }, paged: { limit, offset } }); for (const tx of txs) { const gmpr = await services.getMerklePath(tx.txid); if (gmpr && gmpr.header && gmpr.merklePath) { const mp = gmpr.merklePath; const h = gmpr.header; const mr = mp.computeRoot(tx.txid); const index = (_a = mp.path[0].find(leaf => leaf.hash === tx.txid)) === null || _a === void 0 ? void 0 : _a.offset; const mp2 = sdk_1.MerklePath.fromBinary(tx.merklePath); const mr2 = mp2.computeRoot(); if (h.height !== mp.blockHeight || h.merkleRoot !== mr) { console.log(`Merkle root mismatch for ${tx.txid} ${h.merkleRoot} != ${mr}`); } else { if (tx.merkleRoot !== mr || tx.height !== mp.blockHeight || tx.blockHash !== h.hash || tx.index !== index || mp2.blockHeight !== tx.height || mr2 !== tx.merkleRoot || (0, utilityHelpers_noBuffer_1.asString)(tx.merklePath) !== (0, utilityHelpers_noBuffer_1.asString)(mp.toBinary())) { debugger; await storage.updateProvenTx(tx.provenTxId, { merklePath: mp.toBinary(), merkleRoot: mr, height: mp.blockHeight, blockHash: h.hash, index }); log += `updated ${tx.provenTxId}\n`; } } } } //console.log(`${offset} ${log}`) //if (txs.length < limit) break //offset += txs.length } await storage.destroy(); }); test.skip('10 re-internalize failed WUI exports', async () => { const { env, storage, services } = await TestUtilsWalletStorage_1._tu.createMainReviewSetup(); // From this user const user0 = (0, src_1.verifyOne)(await storage.findUsers({ partial: { userId: 2 } })); // To these users const users = await storage.findUsers({ partial: { userId: 141 } }); // 111, 141 for (const user of users) { const { userId, identityKey } = user; const [outputs] = await storage.knex.raw(` SELECT f.* FROM outputs as f where f.userId = 2 and not f.customInstructions is null and JSON_EXTRACT(f.customInstructions, '$.payee') = '${identityKey}' and not exists(select * from outputs as r where r.userId = ${userId} and r.txid = f.txid) `); if (outputs.length > 0) console.log(`userId ${userId} ${identityKey} ${outputs.length} outputs`); for (const output of outputs) { const req = (0, src_1.verifyOneOrNone)(await storage.findProvenTxReqs({ partial: { txid: output.txid, status: 'completed' } })); const { type, derivationPrefix, derivationSuffix, payee } = JSON.parse(output.customInstructions); if (req && type === 'BRC29' && derivationPrefix && derivationSuffix) { const beef = await storage.getBeefForTransaction(req.txid, {}); // {"type":"BRC29","derivationPrefix":"LDFooHSsXzw=","derivationSuffix":"4f4ixKv+6SY=","payee":"0352caa755d5b6279e15e47e096db908e7c4a73a31775e7e8720bdd4cf2d44873a"} await storage.internalizeAction({ userId, identityKey: user.identityKey }, { tx: beef.toBinaryAtomic(req.txid), outputs: [ { outputIndex: 0, protocol: 'wallet payment', paymentRemittance: { derivationPrefix: derivationPrefix, derivationSuffix: derivationSuffix, senderIdentityKey: user0.identityKey } } ], description: 'Internalizing export funds tx into foreign wallet' }); console.log('internalize', userId, output.txid); } } } /* */ await storage.destroy(); }); test.skip('11 review recent transaction change use for specific userId', async () => { const userId = 311; const { env, storage, services } = await TestUtilsWalletStorage_1._tu.createMainReviewSetup(); const countTxs = await storage.countTransactions({ partial: { userId }, status: ['completed', 'unproven', 'failed'] }); const txs = await storage.findTransactions({ partial: { userId }, status: ['unproven', 'completed', 'failed'], paged: { limit: 100, offset: Math.max(0, countTxs - 100) } }); for (const tx of txs) { const ls = await Format_1.Format.toLogStringTableTransaction(tx, storage); console.log(ls); } const countReqs = await storage.countProvenTxReqs({ partial: {}, status: ['completed', 'unmined'] }); const reqs = await storage.findProvenTxReqs({ partial: {}, status: ['unmined', 'completed'], paged: { limit: 100, offset: countReqs - 100 } }); await storage.destroy(); }); test.skip('12 check storage merged BEEF', async () => { const userId = 127; const txid = 'efba8b92a22c3308f432b292b5ec7efb3869ecd50c62cb3ddfb83871bc7be194'; const vout = 1; const { env, storage, services } = await TestUtilsWalletStorage_1._tu.createMainReviewSetup(); const ptx = (0, src_1.verifyOne)(await storage.findProvenTxs({ partial: { txid } })); const mp = sdk_1.MerklePath.fromBinary(ptx.merklePath); expect(mp.blockHeight).toBe(ptx.height); const txids = ['24b19a5179c1f146e825643df4c6dc2ba21674828c20fc2948e105cb1ca91eae']; const r = await storage.getReqsAndBeefToShareWithWorld(txids, []); await storage.destroy(); }); test('13 review use of outputs in all following transactions', async () => { const { env, storage, services } = await TestUtilsWalletStorage_1._tu.createMainReviewSetup(); const txids = ['2df7b5059112a42fc40adb54ee36244cee0dd216c35ad6c4b6ef4631c14a0e83']; //, '9fb38fc87c6ff39f5c7321a4c689db535c024498ed20031434485c981dd7a182', '3fb6b02e1d001dded1daee3f59dcd684489b96a35a9dfb5082b4119a31689966', '72ea8d84a4c54dbca292f4a79a5ff08cb9917fc3127c1dcff0628aeba8b40823', '0564a515566bc43c1396becf12bbf2d82d821ae7b6e0ef404eedfa090d4877c2', '3b93e4327a50a7f4a421af9fbdec0206b3b7ba5252bc5a0142d0d64aa34c2e73', 'd4b0c3d820696afad43b43e095f3b8c3df52385bb4aeddff0212e0a472dd8e4e'] const userId = 111; const txs = await storage.findTransactions({ partial: { userId }, status: ['completed', 'unproven', 'failed'], orderDescending: true, paged: { limit: 50 } }); const allTxids = txs.map(tx => tx.txid); debugger; const reqs = await storage.findProvenTxReqs({ partial: {}, txids: allTxids }); const beef = new sdk_1.Beef(); for (const req of reqs) { beef.mergeRawTx(req.rawTx); } for (const txid of txids) { const o = await storage.findOutputs({ partial: { txid, userId } }); const tx = await storage.findTransactions({ partial: { txid, userId } }); if (o && tx) { const ltx = await Format_1.Format.toLogStringTableTransaction(tx[0], storage); (0, TestUtilsWalletStorage_1.logger)(ltx); for (const btx of beef.txs) { const tx = btx.tx; for (const i of tx.inputs) { if (i.sourceTXID === txid && i.sourceOutputIndex === 0) { const sltx = Format_1.Format.toLogStringBeefTxid(beef, btx.txid); (0, TestUtilsWalletStorage_1.logger)(sltx); } } } } } await storage.destroy(); }); }); //# sourceMappingURL=operations.man.test.js.map