UNPKG

@bsv/wallet-toolbox

Version:

BRC100 conforming wallet, wallet storage and wallet signer components

142 lines 5.63 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.getListOutputsSpecOp = getListOutputsSpecOp; const types_1 = require("../../sdk/types"); const utilityHelpers_1 = require("../../utility/utilityHelpers"); const WERR_errors_1 = require("../../sdk/WERR_errors"); const INVALID_CHANGE_MAX_CONCURRENCY = 12; async function runWithConcurrency(values, maxConcurrency, worker) { const active = []; for (const value of values) { const task = worker(value).finally(() => { const i = active.indexOf(task); if (i >= 0) active.splice(i, 1); }); active.push(task); if (active.length >= maxConcurrency) { await Promise.race(active); } } await Promise.all(active); } const getBasketToSpecOp = () => { return { [types_1.specOpWalletBalance]: { name: 'totalOutputsIsWalletBalance', useBasket: 'default', ignoreLimit: true, totalOutputsIsSumOfSatoshis: true, resultFromOutputs: async (s, auth, vargs, specOpTags, outputs) => { let totalOutputs = 0; for (const o of outputs) totalOutputs += o.satoshis; return { totalOutputs, outputs: [] }; } }, [types_1.specOpInvalidChange]: { name: 'invalidChangeOutputs', useBasket: 'default', ignoreLimit: true, includeOutputScripts: true, includeSpent: false, tagsToIntercept: ['release', 'all'], filterOutputs: async (s, auth, vargs, specOpTags, outputs) => { const invalidOutputIds = new Set(); const services = s.getServices(); await runWithConcurrency(outputs, INVALID_CHANGE_MAX_CONCURRENCY, async (o) => { if (!o.basketId) return; // only care about outputs assigned to baskets. await s.validateOutputScript(o); let ok = false; if (o.lockingScript && o.lockingScript.length > 0) { ok = await services.isUtxo(o); } else { ok = undefined; } if (ok === false) { invalidOutputIds.add(o.outputId); } }); const filteredOutputs = outputs.filter(o => invalidOutputIds.has(o.outputId)); if (specOpTags.indexOf('release') >= 0) { await runWithConcurrency(filteredOutputs, INVALID_CHANGE_MAX_CONCURRENCY, async (o) => { await s.updateOutput(o.outputId, { spendable: false }); o.spendable = false; }); } return filteredOutputs; } }, [types_1.specOpSetWalletChangeParams]: { name: 'setWalletChangeParams', tagsParamsCount: 2, resultFromTags: async (s, auth, vargs, specOpTags) => { if (specOpTags.length !== 2) throw new WERR_errors_1.WERR_INVALID_PARAMETER('numberOfDesiredUTXOs and minimumDesiredUTXOValue', 'valid'); const numberOfDesiredUTXOs = (0, utilityHelpers_1.verifyInteger)(Number(specOpTags[0])); const minimumDesiredUTXOValue = (0, utilityHelpers_1.verifyInteger)(Number(specOpTags[1])); const basket = (0, utilityHelpers_1.verifyOne)(await s.findOutputBaskets({ partial: { userId: (0, utilityHelpers_1.verifyId)(auth.userId), name: 'default' } })); await s.updateOutputBasket(basket.basketId, { numberOfDesiredUTXOs, minimumDesiredUTXOValue }); return { totalOutputs: 0, outputs: [] }; } } }; }; const getTagToSpecOp = () => { return { [types_1.specOpWalletBalance]: { name: 'totalOutputsIsWalletBalance', useBasket: 'default', ignoreLimit: true, totalOutputsIsSumOfSatoshis: true, resultFromOutputs: async (s, auth, vargs, specOpTags, outputs) => { let totalOutputs = 0; for (const o of outputs) totalOutputs += o.satoshis; return { totalOutputs, outputs: [] }; } } }; }; let _basketSpecOps = undefined; let _tagSpecOps = undefined; /** * Check basket and tags arguments passed to listOutputs to determine if they trigger a special operation execution mode. * @param basket * @param tags * @returns */ function getListOutputsSpecOp(basket, tags) { let specOp; if (basket) { if (_basketSpecOps === undefined) { _basketSpecOps = getBasketToSpecOp(); } specOp = _basketSpecOps[basket]; if (specOp) { return { specOp, basket: specOp.useBasket, tags: tags || [] }; } } if (tags) { if (_tagSpecOps === undefined) { _tagSpecOps = getTagToSpecOp(); } for (const tag of tags) { specOp = _tagSpecOps[tag]; if (specOp) { if (!basket && specOp.useBasket) basket = specOp.useBasket; return { specOp, basket, tags: tags.filter(t => t !== tag) }; } } } return { specOp: undefined, basket, tags }; } //# sourceMappingURL=ListOutputsSpecOp.js.map