@bsv/sdk
Version:
BSV Blockchain Software Development Kit
959 lines • 94.9 kB
JavaScript
import * as Utils from '../../primitives/utils.js';
import calls from './WalletWireCalls.js';
import Certificate from '../../auth/certificates/Certificate.js';
/**
* Processes incoming wallet calls received over a wallet wire, with a given wallet.
*/
export default class WalletWireProcessor {
wallet;
constructor(wallet) {
this.wallet = wallet;
}
decodeOutpoint(reader) {
const txidBytes = reader.read(32);
const txid = Utils.toHex(txidBytes);
const index = reader.readVarIntNum();
return `${txid}.${index}`;
}
encodeOutpoint(outpoint) {
const writer = new Utils.Writer();
const [txid, index] = outpoint.split('.');
writer.write(Utils.toArray(txid, 'hex'));
writer.writeVarIntNum(Number(index));
return writer.toArray();
}
async transmitToWallet(message) {
const messageReader = new Utils.Reader(message);
try {
// Read call code
const callCode = messageReader.readUInt8();
// Map call code to call name
const callName = calls[callCode]; // calls is enum
if (callName === undefined || callName === '') {
// Invalid call code
throw new Error(`Invalid call code: ${callCode}`);
}
// Read originator length
const originatorLength = messageReader.readUInt8();
const originatorBytes = messageReader.read(originatorLength);
const originator = Utils.toUTF8(originatorBytes);
// Read parameters
const paramsReader = messageReader; // Remaining bytes
switch (callName) {
case 'createAction': {
// Deserialize parameters from paramsReader
const args = {};
// Read description
const descriptionLength = paramsReader.readVarIntNum();
const descriptionBytes = paramsReader.read(descriptionLength);
args.description = Utils.toUTF8(descriptionBytes);
// tx
const inputBeefLength = paramsReader.readVarIntNum();
if (inputBeefLength >= 0) {
args.inputBEEF = paramsReader.read(inputBeefLength); // BEEF (Byte[])
}
else {
args.inputBEEF = undefined;
}
// Read inputs
const inputsLength = paramsReader.readVarIntNum();
if (inputsLength >= 0) {
args.inputs = [];
for (let i = 0; i < inputsLength; i++) {
const input = {};
// outpoint
input.outpoint = this.decodeOutpoint(paramsReader);
// unlockingScript / unlockingScriptLength
const unlockingScriptLength = paramsReader.readVarIntNum();
if (unlockingScriptLength >= 0) {
const unlockingScriptBytes = paramsReader.read(unlockingScriptLength);
input.unlockingScript = Utils.toHex(unlockingScriptBytes);
}
else {
input.unlockingScript = undefined;
const unlockingScriptLengthValue = paramsReader.readVarIntNum();
input.unlockingScriptLength = unlockingScriptLengthValue;
}
// inputDescription
const inputDescriptionLength = paramsReader.readVarIntNum();
const inputDescriptionBytes = paramsReader.read(inputDescriptionLength);
input.inputDescription = Utils.toUTF8(inputDescriptionBytes);
// sequenceNumber
const sequenceNumber = paramsReader.readVarIntNum();
if (sequenceNumber >= 0) {
input.sequenceNumber = sequenceNumber;
}
else {
input.sequenceNumber = undefined;
}
args.inputs.push(input);
}
}
else {
args.inputs = undefined;
}
// Read outputs
const outputsLength = paramsReader.readVarIntNum();
if (outputsLength >= 0) {
args.outputs = [];
for (let i = 0; i < outputsLength; i++) {
const output = {};
// lockingScript
const lockingScriptLength = paramsReader.readVarIntNum();
const lockingScriptBytes = paramsReader.read(lockingScriptLength);
output.lockingScript = Utils.toHex(lockingScriptBytes);
// satoshis
output.satoshis = paramsReader.readVarIntNum();
// outputDescription
const outputDescriptionLength = paramsReader.readVarIntNum();
const outputDescriptionBytes = paramsReader.read(outputDescriptionLength);
output.outputDescription = Utils.toUTF8(outputDescriptionBytes);
// basket
const basketLength = paramsReader.readVarIntNum();
if (basketLength >= 0) {
const basketBytes = paramsReader.read(basketLength);
output.basket = Utils.toUTF8(basketBytes);
}
else {
output.basket = undefined;
}
// customInstructions
const customInstructionsLength = paramsReader.readVarIntNum();
if (customInstructionsLength >= 0) {
const customInstructionsBytes = paramsReader.read(customInstructionsLength);
output.customInstructions = Utils.toUTF8(customInstructionsBytes);
}
else {
output.customInstructions = undefined;
}
// tags
const tagsLength = paramsReader.readVarIntNum();
if (tagsLength >= 0) {
output.tags = [];
for (let j = 0; j < tagsLength; j++) {
const tagLength = paramsReader.readVarIntNum();
const tagBytes = paramsReader.read(tagLength);
const tag = Utils.toUTF8(tagBytes);
output.tags.push(tag);
}
}
else {
output.tags = undefined;
}
args.outputs.push(output);
}
}
else {
args.outputs = undefined;
}
// lockTime
const lockTime = paramsReader.readVarIntNum();
if (lockTime >= 0) {
args.lockTime = lockTime;
}
else {
args.lockTime = undefined;
}
// version
const version = paramsReader.readVarIntNum();
if (version >= 0) {
args.version = version;
}
else {
args.version = undefined;
}
// labels
const labelsLength = paramsReader.readVarIntNum();
if (labelsLength >= 0) {
args.labels = [];
for (let i = 0; i < labelsLength; i++) {
const labelLength = paramsReader.readVarIntNum();
const labelBytes = paramsReader.read(labelLength);
const label = Utils.toUTF8(labelBytes);
args.labels.push(label);
}
}
else {
args.labels = undefined;
}
// options
const optionsPresent = paramsReader.readInt8();
if (optionsPresent === 1) {
args.options = {};
// signAndProcess
const signAndProcessFlag = paramsReader.readInt8();
if (signAndProcessFlag === -1) {
args.options.signAndProcess = undefined;
}
else {
args.options.signAndProcess = signAndProcessFlag === 1;
}
// acceptDelayedBroadcast
const acceptDelayedBroadcastFlag = paramsReader.readInt8();
if (acceptDelayedBroadcastFlag === -1) {
args.options.acceptDelayedBroadcast = undefined;
}
else {
args.options.acceptDelayedBroadcast =
acceptDelayedBroadcastFlag === 1;
}
// trustSelf
const trustSelfFlag = paramsReader.readInt8();
if (trustSelfFlag === -1) {
args.options.trustSelf = undefined;
}
else if (trustSelfFlag === 1) {
args.options.trustSelf = 'known';
}
// knownTxids
const knownTxidsLength = paramsReader.readVarIntNum();
if (knownTxidsLength >= 0) {
args.options.knownTxids = [];
for (let i = 0; i < knownTxidsLength; i++) {
const txidBytes = paramsReader.read(32);
const txid = Utils.toHex(txidBytes);
args.options.knownTxids.push(txid);
}
}
else {
args.options.knownTxids = undefined;
}
// returnTXIDOnly
const returnTXIDOnlyFlag = paramsReader.readInt8();
if (returnTXIDOnlyFlag === -1) {
args.options.returnTXIDOnly = undefined;
}
else {
args.options.returnTXIDOnly = returnTXIDOnlyFlag === 1;
}
// noSend
const noSendFlag = paramsReader.readInt8();
if (noSendFlag === -1) {
args.options.noSend = undefined;
}
else {
args.options.noSend = noSendFlag === 1;
}
// noSendChange
const noSendChangeLength = paramsReader.readVarIntNum();
if (noSendChangeLength >= 0) {
args.options.noSendChange = [];
for (let i = 0; i < noSendChangeLength; i++) {
const outpoint = this.decodeOutpoint(paramsReader);
args.options.noSendChange.push(outpoint);
}
}
else {
args.options.noSendChange = undefined;
}
// sendWith
const sendWithLength = paramsReader.readVarIntNum();
if (sendWithLength >= 0) {
args.options.sendWith = [];
for (let i = 0; i < sendWithLength; i++) {
const txidBytes = paramsReader.read(32);
const txid = Utils.toHex(txidBytes);
args.options.sendWith.push(txid);
}
}
else {
args.options.sendWith = undefined;
}
// randomizeOutputs
const randomizeOutputsFlag = paramsReader.readInt8();
if (randomizeOutputsFlag === -1) {
args.options.randomizeOutputs = undefined;
}
else {
args.options.randomizeOutputs = randomizeOutputsFlag === 1;
}
}
else {
args.options = undefined;
}
// Call the method
const createActionResult = await this.wallet.createAction(args, originator);
// Serialize the result
const resultWriter = new Utils.Writer();
// txid
if (createActionResult.txid != null && createActionResult.txid !== '') {
resultWriter.writeInt8(1);
resultWriter.write(Utils.toArray(createActionResult.txid, 'hex'));
}
else {
resultWriter.writeInt8(0);
}
// tx
if (createActionResult.tx != null) {
resultWriter.writeInt8(1);
resultWriter.writeVarIntNum(createActionResult.tx.length);
resultWriter.write(createActionResult.tx);
}
else {
resultWriter.writeInt8(0);
}
// noSendChange
if (createActionResult.noSendChange != null) {
resultWriter.writeVarIntNum(createActionResult.noSendChange.length);
for (const outpoint of createActionResult.noSendChange) {
resultWriter.write(this.encodeOutpoint(outpoint));
}
}
else {
resultWriter.writeVarIntNum(-1);
}
// sendWithResults
if (createActionResult.sendWithResults != null) {
resultWriter.writeVarIntNum(createActionResult.sendWithResults.length);
for (const result of createActionResult.sendWithResults) {
resultWriter.write(Utils.toArray(result.txid, 'hex'));
let statusCode;
if (result.status === 'unproven')
statusCode = 1;
else if (result.status === 'sending')
statusCode = 2;
else if (result.status === 'failed')
statusCode = 3;
resultWriter.writeInt8(statusCode);
}
}
else {
resultWriter.writeVarIntNum(-1);
}
// signableTransaction
if (createActionResult.signableTransaction != null) {
resultWriter.writeInt8(1);
resultWriter.writeVarIntNum(createActionResult.signableTransaction.tx.length);
resultWriter.write(createActionResult.signableTransaction.tx);
const referenceBytes = Utils.toArray(createActionResult.signableTransaction.reference, 'base64');
resultWriter.writeVarIntNum(referenceBytes.length);
resultWriter.write(referenceBytes);
}
else {
resultWriter.writeInt8(0);
}
// Return success code and result
const responseWriter = new Utils.Writer();
responseWriter.writeUInt8(0); // errorByte = 0
responseWriter.write(resultWriter.toArray());
return responseWriter.toArray();
}
case 'signAction': {
const args = {};
// Deserialize spends
const spendCount = paramsReader.readVarIntNum();
args.spends = {};
for (let i = 0; i < spendCount; i++) {
const inputIndex = paramsReader.readVarIntNum();
const spend = {};
// unlockingScript
const unlockingScriptLength = paramsReader.readVarIntNum();
const unlockingScriptBytes = paramsReader.read(unlockingScriptLength);
spend.unlockingScript = Utils.toHex(unlockingScriptBytes);
// sequenceNumber
const sequenceNumber = paramsReader.readVarIntNum();
if (sequenceNumber >= 0) {
spend.sequenceNumber = sequenceNumber;
}
else {
spend.sequenceNumber = undefined;
}
args.spends[inputIndex] = spend;
}
// Deserialize reference
const referenceLength = paramsReader.readVarIntNum();
const referenceBytes = paramsReader.read(referenceLength);
args.reference = Utils.toBase64(referenceBytes);
// Deserialize options
const optionsPresent = paramsReader.readInt8();
if (optionsPresent === 1) {
args.options = {};
// acceptDelayedBroadcast
const acceptDelayedBroadcastFlag = paramsReader.readInt8();
if (acceptDelayedBroadcastFlag === -1) {
args.options.acceptDelayedBroadcast = undefined;
}
else {
args.options.acceptDelayedBroadcast =
acceptDelayedBroadcastFlag === 1;
}
// returnTXIDOnly
const returnTXIDOnlyFlag = paramsReader.readInt8();
if (returnTXIDOnlyFlag === -1) {
args.options.returnTXIDOnly = undefined;
}
else {
args.options.returnTXIDOnly = returnTXIDOnlyFlag === 1;
}
// noSend
const noSendFlag = paramsReader.readInt8();
if (noSendFlag === -1) {
args.options.noSend = undefined;
}
else {
args.options.noSend = noSendFlag === 1;
}
// sendWith
const sendWithLength = paramsReader.readVarIntNum();
if (sendWithLength >= 0) {
args.options.sendWith = [];
for (let i = 0; i < sendWithLength; i++) {
const txidBytes = paramsReader.read(32);
const txid = Utils.toHex(txidBytes);
args.options.sendWith.push(txid);
}
}
else {
args.options.sendWith = undefined;
}
}
else {
args.options = undefined;
}
// Call the method
const signActionResult = await this.wallet.signAction(args, originator);
// Serialize the result
const resultWriter = new Utils.Writer();
// txid
if (signActionResult.txid != null && signActionResult.txid !== '') {
resultWriter.writeInt8(1);
resultWriter.write(Utils.toArray(signActionResult.txid, 'hex'));
}
else {
resultWriter.writeInt8(0);
}
// tx
if (signActionResult.tx != null) {
resultWriter.writeInt8(1);
resultWriter.writeVarIntNum(signActionResult.tx.length);
resultWriter.write(signActionResult.tx);
}
else {
resultWriter.writeInt8(0);
}
// sendWithResults
if (signActionResult.sendWithResults != null) {
resultWriter.writeVarIntNum(signActionResult.sendWithResults.length);
for (const result of signActionResult.sendWithResults) {
resultWriter.write(Utils.toArray(result.txid, 'hex'));
let statusCode;
if (result.status === 'unproven')
statusCode = 1;
else if (result.status === 'sending')
statusCode = 2;
else if (result.status === 'failed')
statusCode = 3;
resultWriter.writeInt8(statusCode);
}
}
else {
resultWriter.writeVarIntNum(-1);
}
// Return success code and result
const responseWriter = new Utils.Writer();
responseWriter.writeUInt8(0); // errorByte = 0
responseWriter.write(resultWriter.toArray());
return responseWriter.toArray();
}
case 'abortAction': {
// Deserialize reference
const referenceBytes = paramsReader.read();
const reference = Utils.toBase64(referenceBytes);
// Call the method
await this.wallet.abortAction({ reference }, originator);
// Return success code and result
const responseWriter = new Utils.Writer();
responseWriter.writeUInt8(0); // errorByte = 0
return responseWriter.toArray();
}
case 'listActions': {
const args = {};
// Deserialize labels
const labelsLength = paramsReader.readVarIntNum();
args.labels = [];
for (let i = 0; i < labelsLength; i++) {
const labelLength = paramsReader.readVarIntNum();
const labelBytes = paramsReader.read(labelLength);
args.labels.push(Utils.toUTF8(labelBytes));
}
// Deserialize labelQueryMode
const labelQueryModeFlag = paramsReader.readInt8();
if (labelQueryModeFlag === -1) {
args.labelQueryMode = undefined;
}
else if (labelQueryModeFlag === 1) {
args.labelQueryMode = 'any';
}
else if (labelQueryModeFlag === 2) {
args.labelQueryMode = 'all';
}
// Deserialize include options
const includeOptionsNames = [
'includeLabels',
'includeInputs',
'includeInputSourceLockingScripts',
'includeInputUnlockingScripts',
'includeOutputs',
'includeOutputLockingScripts'
];
for (const optionName of includeOptionsNames) {
const optionFlag = paramsReader.readInt8();
if (optionFlag === -1) {
args[optionName] = undefined;
}
else {
args[optionName] = optionFlag === 1;
}
}
// Deserialize limit
const limit = paramsReader.readVarIntNum();
if (limit >= 0) {
args.limit = limit;
}
else {
args.limit = undefined;
}
// Deserialize offset
const offset = paramsReader.readVarIntNum();
if (offset >= 0) {
args.offset = offset;
}
else {
args.offset = undefined;
}
// Deserialize seekPermission
const seekPermission = paramsReader.readInt8();
if (seekPermission >= 0) {
args.seekPermission = seekPermission === 1;
}
else {
args.seekPermission = undefined;
}
// Call the method
const listActionsResult = await this.wallet.listActions(args, originator);
// Serialize the result
const resultWriter = new Utils.Writer();
// totalActions
resultWriter.writeVarIntNum(listActionsResult.totalActions);
// actions
for (const action of listActionsResult.actions) {
// txid
resultWriter.write(Utils.toArray(action.txid, 'hex'));
// satoshis
resultWriter.writeVarIntNum(action.satoshis);
// status
let statusCode;
switch (action.status) {
case 'completed':
statusCode = 1;
break;
case 'unprocessed':
statusCode = 2;
break;
case 'sending':
statusCode = 3;
break;
case 'unproven':
statusCode = 4;
break;
case 'unsigned':
statusCode = 5;
break;
case 'nosend':
statusCode = 6;
break;
case 'nonfinal':
statusCode = 7;
break;
case 'failed':
statusCode = 8;
break;
default:
statusCode = -1;
break;
}
resultWriter.writeInt8(statusCode);
// isOutgoing
resultWriter.writeInt8(action.isOutgoing ? 1 : 0);
// description
const descriptionBytes = Utils.toArray(action.description, 'utf8');
resultWriter.writeVarIntNum(descriptionBytes.length);
resultWriter.write(descriptionBytes);
// labels
if (action.labels !== undefined) {
resultWriter.writeVarIntNum(action.labels.length);
for (const label of action.labels) {
const labelBytes = Utils.toArray(label, 'utf8');
resultWriter.writeVarIntNum(labelBytes.length);
resultWriter.write(labelBytes);
}
}
else {
resultWriter.writeVarIntNum(-1);
}
// version
resultWriter.writeVarIntNum(action.version);
// lockTime
resultWriter.writeVarIntNum(action.lockTime);
// inputs
if (action.inputs !== undefined) {
resultWriter.writeVarIntNum(action.inputs.length);
for (const input of action.inputs) {
// sourceOutpoint
resultWriter.write(this.encodeOutpoint(input.sourceOutpoint));
// sourceSatoshis
resultWriter.writeVarIntNum(input.sourceSatoshis);
// sourceLockingScript
if (input.sourceLockingScript !== undefined) {
const sourceLockingScriptBytes = Utils.toArray(input.sourceLockingScript, 'hex');
resultWriter.writeVarIntNum(sourceLockingScriptBytes.length);
resultWriter.write(sourceLockingScriptBytes);
}
else {
resultWriter.writeVarIntNum(-1);
}
// unlockingScript
if (input.unlockingScript !== undefined) {
const unlockingScriptBytes = Utils.toArray(input.unlockingScript, 'hex');
resultWriter.writeVarIntNum(unlockingScriptBytes.length);
resultWriter.write(unlockingScriptBytes);
}
else {
resultWriter.writeVarIntNum(-1);
}
// inputDescription
const inputDescriptionBytes = Utils.toArray(input.inputDescription, 'utf8');
resultWriter.writeVarIntNum(inputDescriptionBytes.length);
resultWriter.write(inputDescriptionBytes);
// sequenceNumber
resultWriter.writeVarIntNum(input.sequenceNumber);
}
}
else {
resultWriter.writeVarIntNum(-1);
}
// outputs
if (action.outputs !== undefined) {
resultWriter.writeVarIntNum(action.outputs.length);
for (const output of action.outputs) {
// outputIndex
resultWriter.writeVarIntNum(output.outputIndex);
// satoshis
resultWriter.writeVarIntNum(output.satoshis);
// lockingScript
if (output.lockingScript !== undefined) {
const lockingScriptBytes = Utils.toArray(output.lockingScript, 'hex');
resultWriter.writeVarIntNum(lockingScriptBytes.length);
resultWriter.write(lockingScriptBytes);
}
else {
resultWriter.writeVarIntNum(-1);
}
// spendable
resultWriter.writeInt8(output.spendable ? 1 : 0);
// outputDescription
const outputDescriptionBytes = Utils.toArray(output.outputDescription, 'utf8');
resultWriter.writeVarIntNum(outputDescriptionBytes.length);
resultWriter.write(outputDescriptionBytes);
// basket
if (output.basket !== undefined) {
const basketBytes = Utils.toArray(output.basket, 'utf8');
resultWriter.writeVarIntNum(basketBytes.length);
resultWriter.write(basketBytes);
}
else {
resultWriter.writeVarIntNum(-1);
}
// tags
if (output.tags !== undefined) {
resultWriter.writeVarIntNum(output.tags.length);
for (const tag of output.tags) {
const tagBytes = Utils.toArray(tag, 'utf8');
resultWriter.writeVarIntNum(tagBytes.length);
resultWriter.write(tagBytes);
}
}
else {
resultWriter.writeVarIntNum(-1);
}
// customInstructions
if (output.customInstructions !== undefined) {
const customInstructionsBytes = Utils.toArray(output.customInstructions, 'utf8');
resultWriter.writeVarIntNum(customInstructionsBytes.length);
resultWriter.write(customInstructionsBytes);
}
else {
resultWriter.writeVarIntNum(-1);
}
}
}
else {
resultWriter.writeVarIntNum(-1);
}
}
const responseWriter = new Utils.Writer();
responseWriter.writeUInt8(0); // errorByte = 0
responseWriter.write(resultWriter.toArray());
return responseWriter.toArray();
}
case 'internalizeAction': {
const args = {};
// Read tx
const txLength = paramsReader.readVarIntNum();
args.tx = paramsReader.read(txLength);
// Read outputs
const outputsLength = paramsReader.readVarIntNum();
args.outputs = [];
for (let i = 0; i < outputsLength; i++) {
const output = {};
// outputIndex
output.outputIndex = paramsReader.readVarIntNum();
// protocol
const protocolFlag = paramsReader.readUInt8();
if (protocolFlag === 1) {
output.protocol = 'wallet payment';
output.paymentRemittance = {};
// senderIdentityKey
const senderIdentityKeyBytes = paramsReader.read(33);
output.paymentRemittance.senderIdentityKey = Utils.toHex(senderIdentityKeyBytes);
// derivationPrefix
const derivationPrefixLength = paramsReader.readVarIntNum();
const derivationPrefixBytes = paramsReader.read(derivationPrefixLength);
output.paymentRemittance.derivationPrefix = Utils.toBase64(derivationPrefixBytes);
// derivationSuffix
const derivationSuffixLength = paramsReader.readVarIntNum();
const derivationSuffixBytes = paramsReader.read(derivationSuffixLength);
output.paymentRemittance.derivationSuffix = Utils.toBase64(derivationSuffixBytes);
}
else if (protocolFlag === 2) {
output.protocol = 'basket insertion';
output.insertionRemittance = {};
// basket
const basketLength = paramsReader.readVarIntNum();
const basketBytes = paramsReader.read(basketLength);
output.insertionRemittance.basket = Utils.toUTF8(basketBytes);
// customInstructions
const customInstructionsLength = paramsReader.readVarIntNum();
if (customInstructionsLength >= 0) {
const customInstructionsBytes = paramsReader.read(customInstructionsLength);
output.insertionRemittance.customInstructions = Utils.toUTF8(customInstructionsBytes);
}
// tags
const tagsLength = paramsReader.readVarIntNum();
if (tagsLength > 0) {
output.insertionRemittance.tags = [];
for (let j = 0; j < tagsLength; j++) {
const tagLength = paramsReader.readVarIntNum();
const tagBytes = paramsReader.read(tagLength);
output.insertionRemittance.tags.push(Utils.toUTF8(tagBytes));
}
}
else {
output.insertionRemittance.tags = [];
}
}
args.outputs.push(output);
}
const numberOfLabels = paramsReader.readVarIntNum();
if (numberOfLabels >= 0) {
args.labels = [];
for (let i = 0; i < numberOfLabels; i++) {
const labelLength = paramsReader.readVarIntNum();
args.labels.push(Utils.toUTF8(paramsReader.read(labelLength)));
}
}
const descriptionLength = paramsReader.readVarIntNum();
args.description = Utils.toUTF8(paramsReader.read(descriptionLength));
// Deserialize seekPermission
const seekPermission = paramsReader.readInt8();
if (seekPermission >= 0) {
args.seekPermission = seekPermission === 1;
}
else {
args.seekPermission = undefined;
}
// Call the method
await this.wallet.internalizeAction(args, originator);
// Return success code and result
const responseWriter = new Utils.Writer();
responseWriter.writeUInt8(0); // errorByte = 0
return responseWriter.toArray();
}
case 'listOutputs': {
const args = {};
// Deserialize basket
const basketLength = paramsReader.readVarIntNum();
const basketBytes = paramsReader.read(basketLength);
args.basket = Utils.toUTF8(basketBytes);
// Deserialize tags
const tagsLength = paramsReader.readVarIntNum();
if (tagsLength > 0) {
args.tags = [];
for (let i = 0; i < tagsLength; i++) {
const tagLength = paramsReader.readVarIntNum();
const tagBytes = paramsReader.read(tagLength);
args.tags.push(Utils.toUTF8(tagBytes));
}
}
else {
args.tags = undefined;
}
// Deserialize tagQueryMode
const tagQueryModeFlag = paramsReader.readInt8();
if (tagQueryModeFlag === 1) {
args.tagQueryMode = 'all';
}
else if (tagQueryModeFlag === 2) {
args.tagQueryMode = 'any';
}
else {
args.tagQueryMode = undefined;
}
// Deserialize include
const includeFlag = paramsReader.readInt8();
if (includeFlag === 1) {
args.include = 'locking scripts';
}
else if (includeFlag === 2) {
args.include = 'entire transactions';
}
else {
args.include = undefined;
}
// Deserialize includeCustomInstructions
const includeCustomInstructionsFlag = paramsReader.readInt8();
if (includeCustomInstructionsFlag === -1) {
args.includeCustomInstructions = undefined;
}
else {
args.includeCustomInstructions =
includeCustomInstructionsFlag === 1;
}
// Deserialize includeTags
const includeTagsFlag = paramsReader.readInt8();
if (includeTagsFlag === -1) {
args.includeTags = undefined;
}
else {
args.includeTags = includeTagsFlag === 1;
}
// Deserialize includeLabels
const includeLabelsFlag = paramsReader.readInt8();
if (includeLabelsFlag === -1) {
args.includeLabels = undefined;
}
else {
args.includeLabels = includeLabelsFlag === 1;
}
// Deserialize limit
const limit = paramsReader.readVarIntNum();
if (limit >= 0) {
args.limit = limit;
}
else {
args.limit = undefined;
}
// Deserialize offset
const offset = paramsReader.readVarIntNum();
if (offset >= 0) {
args.offset = offset;
}
else {
args.offset = undefined;
}
// Deserialize seekPermission
const seekPermission = paramsReader.readInt8();
if (seekPermission >= 0) {
args.seekPermission = seekPermission === 1;
}
else {
args.seekPermission = undefined;
}
// Call the method
const listOutputsResult = await this.wallet.listOutputs(args, originator);
// Serialize the result
const resultWriter = new Utils.Writer();
// totalOutputs
resultWriter.writeVarIntNum(listOutputsResult.totalOutputs);
// BEEF length and BEEF or -1
if (listOutputsResult.BEEF != null) {
resultWriter.writeVarIntNum(listOutputsResult.BEEF.length);
resultWriter.write(listOutputsResult.BEEF);
}
else {
resultWriter.writeVarIntNum(-1);
}
// outputs
for (const output of listOutputsResult.outputs) {
// outpoint
resultWriter.write(this.encodeOutpoint(output.outpoint));
// satoshis
resultWriter.writeVarIntNum(output.satoshis);
// lockingScript
if (output.lockingScript !== undefined) {
const lockingScriptBytes = Utils.toArray(output.lockingScript, 'hex');
resultWriter.writeVarIntNum(lockingScriptBytes.length);
resultWriter.write(lockingScriptBytes);
}
else {
resultWriter.writeVarIntNum(-1);
}
// customInstructions
if (output.customInstructions !== undefined) {
const customInstructionsBytes = Utils.toArray(output.customInstructions, 'utf8');
resultWriter.writeVarIntNum(customInstructionsBytes.length);
resultWriter.write(customInstructionsBytes);
}
else {
resultWriter.writeVarIntNum(-1);
}
// tags
if (output.tags !== undefined) {
resultWriter.writeVarIntNum(output.tags.length);
for (const tag of output.tags) {
const tagBytes = Utils.toArray(tag, 'utf8');
resultWriter.writeVarIntNum(tagBytes.length);
resultWriter.write(tagBytes);
}
}
else {
resultWriter.writeVarIntNum(-1);
}
// labels
if (output.labels !== undefined) {
resultWriter.writeVarIntNum(output.labels.length);
for (const label of output.labels) {
const labelBytes = Utils.toArray(label, 'utf8');
resultWriter.writeVarIntNum(labelBytes.length);
resultWriter.write(labelBytes);
}
}
else {
resultWriter.writeVarIntNum(-1);
}
}
// Return success code and result
const responseWriter = new Utils.Writer();
responseWriter.writeUInt8(0); // errorByte = 0
responseWriter.write(resultWriter.toArray());
return responseWriter.toArray();
}
case 'relinquishOutput': {
const args = {};
// Deserialize basket
const basketLength = paramsReader.readVarIntNum();
const basketBytes = paramsReader.read(basketLength);
args.basket = Utils.toUTF8(basketBytes);
// Deserialize outpoint
args.output = this.decodeOutpoint(paramsReader);
// Call the method
await this.wallet.relinquishOutput(args, originator);
// Return success code and result
const responseWriter = new Utils.Writer();
responseWriter.writeUInt8(0); // errorByte = 0
return responseWriter.toArray();
}
case 'getPublicKey': {
const args = {};
// Deserialize identityKey flag
const ide