wallet-storage
Version:
BRC100 conforming wallet, wallet storage and wallet signer components
74 lines • 3.62 kB
JavaScript
;
/* eslint-disable @typescript-eslint/no-unused-vars */
Object.defineProperty(exports, "__esModule", { value: true });
exports.signAction = signAction;
exports.makeAtomicBeef = makeAtomicBeef;
exports.completeSignedTransaction = completeSignedTransaction;
const sdk_1 = require("@bsv/sdk");
const index_client_1 = require("../../index.client");
const createAction_1 = require("./createAction");
async function signAction(wallet, auth, vargs) {
const prior = wallet.pendingSignActions[vargs.reference];
if (!prior)
throw new index_client_1.sdk.WERR_NOT_IMPLEMENTED('recovery of out-of-session signAction reference data is not yet implemented.');
if (!prior.dcr.inputBeef)
throw new index_client_1.sdk.WERR_INTERNAL('prior.dcr.inputBeef must be valid');
prior.tx = await completeSignedTransaction(prior, vargs.spends, wallet);
const sendWithResults = await (0, createAction_1.processAction)(prior, wallet, auth, vargs);
const r = {
txid: prior.tx.id('hex'),
tx: vargs.options.returnTXIDOnly ? undefined : makeAtomicBeef(prior.tx, prior.dcr.inputBeef),
sendWithResults
};
return r;
}
function makeAtomicBeef(tx, beef) {
if (Array.isArray(beef))
beef = sdk_1.Beef.fromBinary(beef);
beef.mergeTransaction(tx);
return beef.toBinaryAtomic(tx.id('hex'));
}
async function completeSignedTransaction(prior, spends, wallet) {
/////////////////////
// Insert the user provided unlocking scripts from "spends" arg
/////////////////////
for (const [key, spend] of Object.entries(spends)) {
const vin = Number(key);
const createInput = prior.args.inputs[vin];
const input = prior.tx.inputs[vin];
if (!createInput || !input || createInput.unlockingScript || !Number.isInteger(createInput.unlockingScriptLength))
throw new index_client_1.sdk.WERR_INVALID_PARAMETER('args', `spend does not correspond to prior input with valid unlockingScriptLength.`);
if (spend.unlockingScript.length / 2 > createInput.unlockingScriptLength)
throw new index_client_1.sdk.WERR_INVALID_PARAMETER('args', `spend unlockingScript length ${spend.unlockingScript.length} exceeds expected length ${createInput.unlockingScriptLength}`);
input.unlockingScript = (0, index_client_1.asBsvSdkScript)(spend.unlockingScript);
if (spend.sequenceNumber !== undefined)
input.sequence = spend.sequenceNumber;
}
const results = {
sdk: {}
};
/////////////////////
// Insert SABPPP unlock templates for wallet signed inputs
/////////////////////
for (const pdi of prior.pdi) {
const sabppp = new index_client_1.ScriptTemplateSABPPP({
derivationPrefix: pdi.derivationPrefix,
derivationSuffix: pdi.derivationSuffix,
keyDeriver: wallet.keyDeriver
});
const keys = wallet.getClientChangeKeyPair();
const lockerPrivKey = keys.privateKey;
const unlockerPubKey = pdi.unlockerPubKey || keys.publicKey;
const sourceSatoshis = pdi.sourceSatoshis;
const lockingScript = (0, index_client_1.asBsvSdkScript)(pdi.lockingScript);
const unlockTemplate = sabppp.unlock(lockerPrivKey, unlockerPubKey, sourceSatoshis, lockingScript);
const input = prior.tx.inputs[pdi.vin];
input.unlockingScriptTemplate = unlockTemplate;
}
/////////////////////
// Sign wallet signed inputs making transaction fully valid.
/////////////////////
await prior.tx.sign();
return prior.tx;
}
//# sourceMappingURL=signAction.js.map