@bsv/wallet-toolbox-mobile
Version:
React Native and mobile-safe BRC-100 wallet, signer, and remote storage components
1,536 lines • 1.2 MB
JavaScript
import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
import { AuthFetch, BEEF_V1, BEEF_V2, Beef, BeefParty, BigNumber, CachedKeyDeriver, Certificate, Curve, Hash, LocalKVStore, LockingScript, LookupResolver, MasterCertificate, MerklePath, P2PKH, PrivateKey, ProtoWallet, PublicKey, PushDrop, RPuzzle, Random, SHIPBroadcaster, Script, ScriptEvaluationError, Signature, Spend, SymmetricKey, Telemetry, Transaction, TransactionSignature, Utils, Validation, Validation as Validation$1, VerifiableCertificate, createNonce, defaultHttpClient, verifyNonce } from "@bsv/sdk";
import { AESGCM, AESGCMDecrypt } from "@bsv/sdk/primitives/AESGCM";
import argon2Api from "hash-wasm/dist/argon2.umd.min.js";
import pbkdf2Api from "hash-wasm/dist/pbkdf2.umd.min.js";
import sha256Api from "hash-wasm/dist/sha256.umd.min.js";
import sha512Api from "hash-wasm/dist/sha512.umd.min.js";
import { openDB } from "idb";
//#region ../src/sdk/WalletError.ts
/**
* Derived class constructors should use the derived class name as the value for `name`,
* and an internationalizable constant string for `message`.
*
* If a derived class intends to wrap another WalletError, the public property should
* be named `walletError` and will be recovered by `fromUnknown`.
*
* Optionaly, the derived class `message` can include template parameters passed in
* to the constructor. See WERR_MISSING_PARAMETER for an example.
*
* To avoid derived class name colisions, packages should include a package specific
* identifier after the 'WERR_' prefix. e.g. 'WERR_FOO_' as the prefix for Foo package error
* classes.
*/
var WalletError = class WalletError extends Error {
details;
isError = true;
constructor(name, message, stack, details) {
super(message);
this.details = details;
this.name = name;
if (stack != null && stack !== "") this.stack = stack;
}
/**
* Error class compatible accessor for `code`.
*/
get code() {
return this.name;
}
set code(v) {
this.name = v;
}
/**
* Error class compatible accessor for `description`.
*/
get description() {
return this.message;
}
set description(v) {
this.message = v;
}
/**
* Recovers all public fields from WalletError derived error classes and relevant Error derived errors.
*
*/
static nonEmptyString(value) {
return typeof value === "string" && value !== "" ? value : void 0;
}
static objectErrorFields(error) {
const stringValue = WalletError.nonEmptyString;
const name = error.name === "Error" || error.name === "FetchError" ? stringValue(error.code) ?? stringValue(error.status) ?? "WERR_UNKNOWN" : stringValue(error.name) ?? stringValue(error.code) ?? stringValue(error.status) ?? "WERR_UNKNOWN";
const message = stringValue(error.message) ?? stringValue(error.description) ?? "";
const stack = typeof error.stack === "string" ? error.stack : void 0;
const details = {};
if (typeof error.sql === "string") details.sql = error.sql;
if (typeof error.sqlMessage === "string") details.sqlMessage = error.sqlMessage;
return {
name,
message,
stack,
details: Object.keys(details).length > 0 ? details : void 0
};
}
static copyPublicErrorFields(target, source) {
const extensibleTarget = target;
const baseFields = /* @__PURE__ */ new Set([
"status",
"name",
"code",
"message",
"description",
"stack",
"sql",
"sqlMessage"
]);
for (const [key, value] of Object.entries(source)) {
const supportedValue = typeof value === "string" || typeof value === "number" || Array.isArray(value);
if (key === "walletError") extensibleTarget[key] = WalletError.fromUnknown(value);
else if (!baseFields.has(key) && supportedValue) extensibleTarget[key] = value;
}
}
static fromUnknown(err) {
if (err instanceof WalletError) return err;
let message = "";
if (typeof err === "string") message = err;
else if (typeof err === "number") message = err.toString();
let fields = {
name: "WERR_UNKNOWN",
message,
stack: void 0,
details: void 0
};
if (err !== null && typeof err === "object") fields = WalletError.objectErrorFields(err);
const e = new WalletError(fields.name, fields.message, fields.stack, fields.details);
if (err !== null && typeof err === "object") WalletError.copyPublicErrorFields(e, err);
return e;
}
/**
* @returns standard HTTP error status object with status property set to 'error'.
*/
asStatus() {
return {
status: "error",
code: this.name,
description: this.message
};
}
/**
* Base class default JSON serialization.
* Captures just the name and message properties.
*
* Override this method to safely (avoid deep, large, circular issues) serialize
* derived class properties.
*
* @returns stringified JSON representation of the WalletError.
*/
toJson() {
const e = new WalletError(this.name, this.message);
return JSON.stringify({
isError: true,
name: e.name,
message: e.message
});
}
/**
* Safely serializes a WalletError derived, WERR_REVIEW_ACTIONS (special case), Error or unknown error to JSON.
*
* Safely means avoiding deep, large, circular issues.
*
* @param error
* @returns stringified JSON representation of the error such that it can be desirialized to a WalletError.
*/
static unknownToJson(error) {
let json;
let e;
const t = typeof error;
const ctorName = t === "object" && error !== null ? error.constructor : void 0;
const ctor = ctorName != null && typeof ctorName.name === "string" ? ctorName.name : void 0;
const name = t === "object" && error !== null && typeof error.name === "string" ? error.name : "";
const message = t === "object" && error !== null && typeof error.message === "string" ? error.message : "";
const hasToJson = t === "object" && typeof error?.toJson === "function";
if (ctor != null && ctor !== "" && ctor.startsWith("WERR_") && hasToJson) json = error.toJson();
else if (name !== "" && message !== "") {
e = new WalletError(name, message);
json = e.toJson();
} else {
e = new WalletError("WERR_UNKNOWN", String(error));
json = e.toJson();
}
return json;
}
};
//#endregion
//#region ../src/sdk/WERR_errors.ts
/**
* Not implemented.
*/
var WERR_NOT_IMPLEMENTED = class extends WalletError {
constructor(message) {
super("WERR_NOT_IMPLEMENTED", message ?? "Not implemented.");
}
};
/**
* An internal error has occurred.
*
* This is an example of an error with an optional custom `message`.
*/
var WERR_INTERNAL = class extends WalletError {
constructor(message) {
super("WERR_INTERNAL", message ?? "An internal error has occurred.");
}
};
/**
* The ${parameter} parameter is invalid.
*
* This is an example of an error object with a custom property `parameter` and templated `message`.
*/
var WERR_INVALID_OPERATION = class extends WalletError {
constructor(message) {
super("WERR_INVALID_OPERATION", message ?? "An invalid operation was requested.");
}
};
/**
* Unable to broadcast transaction at this time.
*/
var WERR_BROADCAST_UNAVAILABLE = class extends WalletError {
constructor(_message) {
super("WERR_BROADCAST_UNAVAILABLE", "Unable to broadcast transaction at this time.");
}
};
/**
* The ${parameter} parameter is invalid.
*
* This is an example of an error object with a custom property `parameter` and templated `message`.
*/
var WERR_INVALID_PARAMETER = class extends WalletError {
parameter;
constructor(parameter, mustBe) {
super("WERR_INVALID_PARAMETER", `The ${parameter} parameter must be ${mustBe ?? "valid."}`);
this.parameter = parameter;
}
toJson() {
const obj = JSON.parse(super.toJson());
obj.code = 6;
obj.parameter = this.parameter;
return JSON.stringify(obj);
}
};
/**
* Invalid merkleRoot ${merkleRoot} for block ${blockHash} at height ${blockHeight}${txid ? ` for txid ${txid}` : ''}.
*
* Typically thrown when a chain tracker fails to validate a merkle root.
*/
var WERR_INVALID_MERKLE_ROOT = class extends WalletError {
blockHash;
blockHeight;
merkleRoot;
txid;
constructor(blockHash, blockHeight, merkleRoot, txid) {
super("WERR_INVALID_MERKLE_ROOT", `Invalid merkleRoot ${merkleRoot} for block ${blockHash} at height ${blockHeight}${txid != null ? " for txid " + txid : ""}.`);
this.blockHash = blockHash;
this.blockHeight = blockHeight;
this.merkleRoot = merkleRoot;
this.txid = txid;
}
toJson() {
const obj = JSON.parse(super.toJson());
obj.code = 8;
obj.blockHash = this.blockHash;
obj.blockHeight = this.blockHeight;
obj.merkleRoot = this.merkleRoot;
obj.txid = this.txid;
return JSON.stringify(obj);
}
};
/**
* The required ${parameter} parameter is missing.
*
* This is an example of an error object with a custom property `parameter`
*/
var WERR_MISSING_PARAMETER = class extends WalletError {
parameter;
constructor(parameter) {
super("WERR_MISSING_PARAMETER", `The required ${parameter} parameter is missing.`);
this.parameter = parameter;
}
toJson() {
const obj = JSON.parse(super.toJson());
obj.parameter = this.parameter;
return JSON.stringify(obj);
}
};
/**
* The request is invalid.
*/
var WERR_BAD_REQUEST = class extends WalletError {
constructor(message) {
super("WERR_BAD_REQUEST", message ?? "The request is invalid.");
}
};
/**
* Configured network chain is invalid or does not match across services.
*/
var WERR_NETWORK_CHAIN = class extends WalletError {
constructor(message) {
super("WERR_NETWORK_CHAIN", message ?? "Configured network chain is invalid or does not match across services.");
}
};
/**
* Access is denied due to an authorization error.
*/
var WERR_UNAUTHORIZED = class extends WalletError {
constructor(message) {
super("WERR_UNAUTHORIZED", message ?? "Access is denied due to an authorization error.");
}
};
/**
* WalletStorageManager is not accessing user's active storage or there are conflicting active stores configured.
*/
var WERR_NOT_ACTIVE = class extends WalletError {
constructor(message) {
super("WERR_NOT_ACTIVE", message ?? "WalletStorageManager is not accessing user's active storage or there are conflicting active stores configured.");
}
};
/**
* Insufficient funds in the available inputs to cover the cost of the required outputs
* and the transaction fee (${moreSatoshisNeeded} more satoshis are needed,
* for a total of ${totalSatoshisNeeded}), plus whatever would be required in order
* to pay the fee to unlock and spend the outputs used to provide the additional satoshis.
*/
var WERR_INSUFFICIENT_FUNDS = class extends WalletError {
totalSatoshisNeeded;
moreSatoshisNeeded;
/**
* @param totalSatoshisNeeded Total satoshis required to fund transactions after net of required inputs and outputs.
* @param moreSatoshisNeeded Shortfall on total satoshis required to fund transactions after net of required inputs and outputs.
*/
constructor(totalSatoshisNeeded, moreSatoshisNeeded) {
super("WERR_INSUFFICIENT_FUNDS", `Insufficient funds in the available inputs to cover the cost of the required outputs and the transaction fee (${moreSatoshisNeeded} more satoshis are needed, for a total of ${totalSatoshisNeeded}), plus whatever would be required in order to pay the fee to unlock and spend the outputs used to provide the additional satoshis.`);
this.totalSatoshisNeeded = totalSatoshisNeeded;
this.moreSatoshisNeeded = moreSatoshisNeeded;
}
toJson() {
const obj = JSON.parse(super.toJson());
obj.code = 7;
obj.totalSatoshisNeeded = this.totalSatoshisNeeded;
obj.moreSatoshisNeeded = this.moreSatoshisNeeded;
return JSON.stringify(obj);
}
};
var WERR_INVALID_PUBLIC_KEY = class extends WalletError {
key;
/**
* @param key The invalid public key that caused the error.
* @param environment Optional environment flag to control whether the key is included in the message.
*/
constructor(key, network = "mainnet") {
const message = network === "mainnet" ? `The provided public key "${key}" is invalid or malformed.` : "The provided public key is invalid or malformed.";
super("WERR_INVALID_PUBLIC_KEY", message);
this.key = key;
}
toJson() {
const obj = JSON.parse(super.toJson());
obj.key = this.key;
return JSON.stringify(obj);
}
};
/**
* When a `createAction` or `signAction` is completed in undelayed mode (`acceptDelayedBroadcast`: false),
* any unsuccessful result will return the results by way of this exception to ensure attention is
* paid to processing errors.
*/
var WERR_REVIEW_ACTIONS = class extends WalletError {
reviewActionResults;
sendWithResults;
txid;
tx;
noSendChange;
/**
* All parameters correspond to their comparable `createAction` or `signAction` results
* with the exception of `reviewActionResults`;
* which contains more details, particularly for double spend results.
*/
constructor(reviewActionResults, sendWithResults, txid, tx, noSendChange) {
super("WERR_REVIEW_ACTIONS", "Undelayed createAction or signAction results require review.");
this.reviewActionResults = reviewActionResults;
this.sendWithResults = sendWithResults;
this.txid = txid;
this.tx = tx;
this.noSendChange = noSendChange;
}
toJson() {
const obj = JSON.parse(super.toJson());
obj.code = 5;
obj.reviewActionResults = this.reviewActionResults;
obj.sendWithResults = this.sendWithResults;
obj.txid = this.txid;
obj.tx = this.tx;
obj.noSendChange = this.noSendChange;
return JSON.stringify(obj);
}
};
/**
* IF YOU ADD NEW ERRORS, ALSO UPDATE THE WalletError.fromJson METHOD IN src/sdk/WalletError.ts
*/
//#endregion
//#region ../src/sdk/WalletErrorFromJson.ts
/**
* Reconstruct the correct derived WalletError from a JSON object created by `WalletError.unknownToJson`.
*
* This function is implemented as a separate function instead of a WalletError class static
* to avoid circular dependencies.
*
* @param json
* @returns a WalletError derived error object, typically for re-throw.
*/
function WalletErrorFromJson(json) {
let e;
const obj = json;
switch (obj.name) {
case "WERR_NOT_IMPLEMENTED":
e = new WERR_NOT_IMPLEMENTED(obj.message);
break;
case "WERR_INTERNAL":
e = new WERR_INTERNAL(obj.message);
break;
case "WERR_INVALID_OPERATION":
e = new WERR_INVALID_OPERATION(obj.message);
break;
case "WERR_BROADCAST_UNAVAILABLE":
e = new WERR_BROADCAST_UNAVAILABLE(obj.message);
break;
case "WERR_INVALID_PARAMETER":
e = new WERR_INVALID_PARAMETER(obj.parameter);
e.message = obj.message;
break;
case "WERR_MISSING_PARAMETER":
e = new WERR_MISSING_PARAMETER(obj.parameter);
e.message = obj.message;
break;
case "WERR_BAD_REQUEST":
e = new WERR_BAD_REQUEST(obj.message);
break;
case "WERR_NETWORK_CHAIN":
e = new WERR_NETWORK_CHAIN(obj.message);
break;
case "WERR_UNAUTHORIZED":
e = new WERR_UNAUTHORIZED(obj.message);
break;
case "WERR_NOT_ACTIVE":
e = new WERR_NOT_ACTIVE(obj.message);
break;
case "WERR_INSUFFICIENT_FUNDS":
e = new WERR_INSUFFICIENT_FUNDS(obj.totalSatoshisNeeded, obj.moreSatoshisNeeded);
break;
case "WERR_INVALID_PUBLIC_KEY":
e = new WERR_INVALID_PUBLIC_KEY(obj.key, "mainnet");
e.message = obj.message;
break;
case "WERR_REVIEW_ACTIONS":
e = new WERR_REVIEW_ACTIONS(obj.reviewActionResults, obj.sendWithResults, obj.txid, obj.tx, obj.noSendChange);
break;
default:
e = new WalletError(typeof obj.name === "string" && obj.name !== "" ? obj.name : "WERR_UNKNOWN", typeof obj.message === "string" ? obj.message : "");
break;
}
return e;
}
//#endregion
//#region ../src/sdk/types.ts
const ProvenTxReqTerminalStatus = [
"completed",
"invalid",
"doubleSpend"
];
const ProvenTxReqNonTerminalStatus = [
"sending",
"unsent",
"nosend",
"unknown",
"nonfinal",
"unprocessed",
"unmined",
"callback",
"unconfirmed"
];
/**
* `listOutputs` special operation basket name value.
*
* Returns wallet's current change balance in the `totalOutputs` result property.
* The `outputs` result property will always be an empty array.
*/
const specOpWalletBalance = "893b7646de0e1c9f741bd6e9169b76a8847ae34adef7bef1e6a285371206d2e8";
/**
* `listOutputs` special operation basket name value.
*
* Lists only spendable wallet-managed BRC-29 change from the `default`
* basket. Raw administrative `listOutputs({ basket: 'default' })` remains
* intentionally unfiltered so legacy incompatible rows stay discoverable
* for recovery instead of being hidden or silently mutated.
*/
const specOpWalletManagedUtxos = "284570a6213a74ba861c38b1cf790e1e400d9cf9324454b76ea98860b6031c1a";
/**
* `listOutputs` special operation basket name value.
*
* Returns currently spendable wallet change outputs that fail to validate as unspent transaction outputs.
*
* Optional tag value 'release'. If present, updates invalid change outputs to not spendable.
*
* Optional tag value 'all'. If present, processes all spendable true outputs, independent of baskets, but basket must be defined.
*/
const specOpInvalidChange = "5a76fd430a311f8bc0553859061710a4475c19fed46e2ff95969aa918e612e57";
/**
* `listOutputs` special operation basket name value.
*
* Updates the wallet's automatic change management parameters.
*
* Tag at index 0 is the new desired number of spendable change outputs to maintain.
*
* Tag at index 1 is the new target for minimum satoshis when creating new change outputs.
*/
const specOpSetWalletChangeParams = "a4979d28ced8581e9c1c92f1001cc7cb3aabf8ea32e10888ad898f0a509a3929";
/**
* @param basket Output basket name value.
* @returns true iff the `basket` name is a reserved `listOutputs` special operation identifier.
*/
function isListOutputsSpecOp(basket) {
return [
specOpWalletBalance,
specOpWalletManagedUtxos,
specOpInvalidChange,
specOpSetWalletChangeParams
].includes(basket);
}
/**
* `listActions` special operation label name value.
*
* Processes only actions currently with status 'nosend'
*
* Optional label value 'abort'. If present, runs abortAction on all the actions returned.
*/
const specOpNoSendActions = "ac6b20a3bb320adafecd637b25c84b792ad828d3aa510d05dc841481f664277d";
/**
* `listActions` special operation label name value.
*
* Processes only actions currently with status 'failed'
*
* Optional label value 'unfail'. If present, sets status to 'unfail', which queues them for attempted recovery by the Monitor.
*/
const specOpFailedActions = "97d4eb1e49215e3374cc2c1939a7c43a55e95c7427bf2d45ed63e3b4e0c88153";
/**
* @param label Action / Transaction label name value.
* @returns true iff the `label` name is a reserved `listActions` special operation identifier.
*/
function isListActionsSpecOp(label) {
return [specOpNoSendActions, specOpFailedActions].includes(label);
}
/**
* `createAction` special operation label name value.
*
* Causes WERR_REVIEW_ACTIONS throw with dummy properties.
*
*/
const specOpThrowReviewActions = "a496e747fc3ad5fabdd4ae8f91184e71f87539bd3d962aa2548942faaaf0047a";
/**
* @param label Action / Transaction label name value.
* @returns true iff the `label` name is a reserved `createAction` special operation identifier.
*/
function isCreateActionSpecOp(label) {
return [specOpThrowReviewActions].includes(label);
}
//#endregion
//#region ../src/sdk/PrivilegedKeyManager.ts
/**
* PrivilegedKeyManager
*
* This class manages a privileged (i.e., very sensitive) private key, obtained from
* an external function (`keyGetter`), which might be backed by HSMs, secure enclaves,
* or other secure storage. The manager retains the key in memory only for a limited
* duration (`retentionPeriod`), uses XOR-based chunk-splitting obfuscation, and
* includes decoy data to raise the difficulty of discovering the real key in memory.
*
* IMPORTANT: While these measures raise the bar for attackers, JavaScript environments
* do not provide perfect in-memory secrecy.
*/
var PrivilegedKeyManager = class {
/**
* Function that will retrieve the PrivateKey from a secure environment,
* e.g., an HSM or secure enclave. The reason for key usage is passed in
* to help with user consent, auditing, and access policy checks.
*/
keyGetter;
/**
* Time (in ms) for which the obfuscated key remains in memory
* before being automatically destroyed.
*/
retentionPeriod;
/**
* A list of dynamically generated property names used to store
* real key chunks (XORed with random pads).
*/
chunkPropNames = [];
/**
* A list of dynamically generated property names used to store
* the random pads that correspond to the real key chunks.
*/
chunkPadPropNames = [];
/**
* A list of decoy property names that will be removed
* when the real key is destroyed.
*/
decoyPropNamesDestroy = [];
/**
* A list of decoy property names that remain in memory
* even after the real key is destroyed (just to cause confusion).
*/
decoyPropNamesRemain = [];
/**
* Handle to the timer that will remove the key from memory
* after the retention period. If the key is refreshed again
* within that period, the timer is cleared and re-set.
*/
destroyTimer;
/**
* Number of chunks to split the 32-byte key into.
* Adjust to increase or decrease obfuscation complexity.
*/
CHUNK_COUNT = 4;
/**
* @param keyGetter - Asynchronous function that retrieves the PrivateKey from a secure environment.
* @param retentionPeriod - Time in milliseconds to retain the obfuscated key in memory before zeroizing.
*/
constructor(keyGetter, retentionPeriod = 12e4) {
this.keyGetter = keyGetter;
this.retentionPeriod = retentionPeriod;
for (let i = 0; i < 2; i++) {
const propName = this.generateRandomPropName();
this[propName] = Uint8Array.from(Random(16));
this.decoyPropNamesRemain.push(propName);
}
}
/**
* Safely destroys the in-memory obfuscated key material by zeroizing
* and deleting related fields. Also destroys some (but not all) decoy
* properties to further confuse an attacker.
*/
destroyKey() {
try {
for (const name of this.chunkPropNames) {
const data = this[name];
if (data != null) data.fill(0);
delete this[name];
}
for (const name of this.chunkPadPropNames) {
const data = this[name];
if (data != null) data.fill(0);
delete this[name];
}
for (const name of this.decoyPropNamesDestroy) {
const data = this[name];
if (data != null) data.fill(0);
delete this[name];
}
this.chunkPropNames = [];
this.chunkPadPropNames = [];
this.decoyPropNamesDestroy = [];
} catch {} finally {
if (this.destroyTimer != null) {
clearTimeout(this.destroyTimer);
this.destroyTimer = void 0;
}
}
}
/**
* Re/sets the destruction timer that removes the key from memory
* after `retentionPeriod` ms. If a timer is already running, it
* is cleared and re-set. This ensures the key remains in memory
* for exactly the desired window after its most recent acquisition.
*/
scheduleKeyDestruction() {
if (this.destroyTimer != null) clearTimeout(this.destroyTimer);
this.destroyTimer = setTimeout(() => {
this.destroyKey();
}, this.retentionPeriod);
}
/**
* XOR-based obfuscation on a per-chunk basis.
* This function takes two equal-length byte arrays
* and returns the XOR combination.
*/
xorBytes(a, b) {
const out = new Uint8Array(a.length);
for (let i = 0; i < a.length; i++) out[i] = a[i] ^ b[i];
return out;
}
/**
* Splits the 32-byte key into `this.CHUNK_COUNT` smaller chunks
* (mostly equal length; the last chunk picks up leftover bytes
* if 32 is not evenly divisible).
*/
splitKeyIntoChunks(keyBytes) {
const chunkSize = Math.floor(keyBytes.length / this.CHUNK_COUNT);
const chunks = [];
let offset = 0;
for (let i = 0; i < this.CHUNK_COUNT; i++) {
const size = i === this.CHUNK_COUNT - 1 ? keyBytes.length - offset : chunkSize;
chunks.push(keyBytes.slice(offset, offset + size));
offset += size;
}
return chunks;
}
/**
* Reassembles the chunks from the dynamic properties, XORs them
* with their corresponding pads, and returns a single 32-byte
* Uint8Array representing the raw key.
*/
reassembleKeyFromChunks() {
try {
const chunkArrays = [];
for (let i = 0; i < this.chunkPropNames.length; i++) {
const chunkEnc = this[this.chunkPropNames[i]];
const chunkPad = this[this.chunkPadPropNames[i]];
if (chunkEnc?.length == null || chunkEnc.length !== chunkPad?.length) return null;
const rawChunk = this.xorBytes(chunkEnc, chunkPad);
chunkArrays.push(rawChunk);
}
const totalLength = chunkArrays.reduce((sum, c) => sum + c.length, 0);
if (totalLength !== 32) return null;
const rawKey = new Uint8Array(totalLength);
let offset = 0;
for (const chunk of chunkArrays) {
rawKey.set(chunk, offset);
offset += chunk.length;
chunk.fill(0);
}
return rawKey;
} catch {
return null;
}
}
/**
* Generates a random property name to store key chunks or decoy data.
*/
generateRandomPropName() {
const randomHex = Utils.toHex(Random(4));
const extraBytes = Random(3);
return `_${randomHex}_${(extraBytes[0] << 16 | extraBytes[1] << 8 | extraBytes[2]) % 1e6}`;
}
/**
* Forces a PrivateKey to be represented as exactly 32 bytes, left-padding
* with zeros if its numeric value has fewer than 32 bytes.
*/
get32ByteRepresentation(privKey) {
const buf = privKey.toArray();
if (buf.length > 32) throw new Error("PrivilegedKeyManager: Expected a 32-byte key, but got more.");
const keyBytes = /* @__PURE__ */ new Uint8Array(32);
keyBytes.set(buf, 32 - buf.length);
return keyBytes;
}
/**
* Returns the privileged key needed to perform cryptographic operations.
* Uses in-memory chunk-based obfuscation if the key was already fetched.
* Otherwise, it calls out to `keyGetter`, splits the 32-byte representation
* of the key, XORs each chunk with a random pad, and stores them under
* dynamic property names. Also populates new decoy properties.
*
* @param reason - The reason for why the key is needed, passed to keyGetter.
* @returns The PrivateKey object needed for cryptographic operations.
*/
async getPrivilegedKey(reason) {
if (this.chunkPropNames.length > 0 && this.chunkPadPropNames.length > 0) {
const rawKeyBytes = this.reassembleKeyFromChunks();
if (rawKeyBytes?.length === 32) {
const hexKey = Utils.toHex([...rawKeyBytes]);
rawKeyBytes.fill(0);
this.scheduleKeyDestruction();
return new PrivateKey(hexKey, "hex");
}
}
const fetchedKey = await this.keyGetter(reason);
const keyBytes = this.get32ByteRepresentation(fetchedKey);
this.destroyKey();
const chunks = this.splitKeyIntoChunks(keyBytes);
for (const chunk of chunks) {
const chunkProp = this.generateRandomPropName();
const padProp = this.generateRandomPropName();
this.chunkPropNames.push(chunkProp);
this.chunkPadPropNames.push(padProp);
const pad = Uint8Array.from(Random(chunk.length));
const obf = this.xorBytes(chunk, pad);
this[chunkProp] = obf;
this[padProp] = pad;
}
for (let i = 0; i < 2; i++) {
const decoyProp = this.generateRandomPropName();
this[decoyProp] = Uint8Array.from(Random(32));
this.decoyPropNamesDestroy.push(decoyProp);
}
keyBytes.fill(0);
this.scheduleKeyDestruction();
return fetchedKey;
}
async getPublicKey(args) {
return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason)).getPublicKey(args);
}
async revealCounterpartyKeyLinkage(args) {
return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason)).revealCounterpartyKeyLinkage(args);
}
async revealSpecificKeyLinkage(args) {
return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason)).revealSpecificKeyLinkage(args);
}
async encrypt(args) {
return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason)).encrypt(args);
}
async decrypt(args) {
return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason)).decrypt(args);
}
async createHmac(args) {
return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason)).createHmac(args);
}
async verifyHmac(args) {
return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason)).verifyHmac(args);
}
async createSignature(args) {
return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason)).createSignature(args);
}
async verifySignature(args) {
return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason)).verifySignature(args);
}
};
//#endregion
//#region ../src/sdk/index.ts
var sdk_exports = /* @__PURE__ */ __exportAll({
PrivilegedKeyManager: () => PrivilegedKeyManager,
ProvenTxReqNonTerminalStatus: () => ProvenTxReqNonTerminalStatus,
ProvenTxReqTerminalStatus: () => ProvenTxReqTerminalStatus,
Validation: () => Validation$1,
WERR_BAD_REQUEST: () => WERR_BAD_REQUEST,
WERR_BROADCAST_UNAVAILABLE: () => WERR_BROADCAST_UNAVAILABLE,
WERR_INSUFFICIENT_FUNDS: () => WERR_INSUFFICIENT_FUNDS,
WERR_INTERNAL: () => WERR_INTERNAL,
WERR_INVALID_MERKLE_ROOT: () => WERR_INVALID_MERKLE_ROOT,
WERR_INVALID_OPERATION: () => WERR_INVALID_OPERATION,
WERR_INVALID_PARAMETER: () => WERR_INVALID_PARAMETER,
WERR_INVALID_PUBLIC_KEY: () => WERR_INVALID_PUBLIC_KEY,
WERR_MISSING_PARAMETER: () => WERR_MISSING_PARAMETER,
WERR_NETWORK_CHAIN: () => WERR_NETWORK_CHAIN,
WERR_NOT_ACTIVE: () => WERR_NOT_ACTIVE,
WERR_NOT_IMPLEMENTED: () => WERR_NOT_IMPLEMENTED,
WERR_REVIEW_ACTIONS: () => WERR_REVIEW_ACTIONS,
WERR_UNAUTHORIZED: () => WERR_UNAUTHORIZED,
WalletError: () => WalletError,
WalletErrorFromJson: () => WalletErrorFromJson,
isCreateActionSpecOp: () => isCreateActionSpecOp,
isListActionsSpecOp: () => isListActionsSpecOp,
isListOutputsSpecOp: () => isListOutputsSpecOp,
specOpFailedActions: () => specOpFailedActions,
specOpInvalidChange: () => specOpInvalidChange,
specOpNoSendActions: () => specOpNoSendActions,
specOpSetWalletChangeParams: () => specOpSetWalletChangeParams,
specOpThrowReviewActions: () => specOpThrowReviewActions,
specOpWalletBalance: () => specOpWalletBalance,
specOpWalletManagedUtxos: () => specOpWalletManagedUtxos
});
//#endregion
//#region ../src/utility/stampLog.ts
/**
* If a log is being kept, add a time stamped line.
* @param log Optional time stamped log to extend, or an object with a log property to update
* @param lineToAdd Content to add to line.
* @returns undefined or log extended by time stamped `lineToAdd` and new line.
*/
function stampLog(log, lineToAdd) {
const add = `${(/* @__PURE__ */ new Date()).toISOString()} ${lineToAdd}\n`;
if (typeof log === "object" && typeof log.log === "string") {
log.log = log.log + add;
return log.log;
}
if (typeof log === "string") return log + add;
}
function parseStampLog(log) {
const data = [];
const newClocks = [];
let last = 0;
for (const line of log.split("\n")) {
const spaceAt = line.indexOf(" ");
if (spaceAt < 0) continue;
const when = new Date(line.substring(0, spaceAt)).getTime();
const rest = line.substring(spaceAt + 1);
const delta = when - (last !== 0 ? last : when);
const newClock = rest.includes("**NETWORK**");
if (newClock) newClocks.push(data.length);
data.push({
when,
rest,
delta,
newClock
});
last = when;
}
return {
data,
newClocks
};
}
function adjustNetworkDeltas(data, newClocks, total) {
if (newClocks.length % 2 !== 0) return;
let network = total;
let lastNewClock = 0;
for (const newClock of newClocks) {
network -= data[newClock - 1].when - data[lastNewClock].when;
lastNewClock = newClock;
}
network -= data.at(-1).when - data[lastNewClock].when;
let networks = newClocks.length;
for (const newClock of newClocks) {
const delta = networks > 1 ? Math.floor(network / networks) : network;
data[newClock].delta = delta;
network -= delta;
networks--;
}
}
function formatStampLog(data, total) {
let formatted = `${new Date(data[0].when).toISOString()} Total = ${total} msecs\n`;
for (const entry of data) {
const delta = entry.delta.toString();
formatted += `${" ".repeat(8 - delta.length)}${delta} ${entry.rest}\n`;
}
return formatted;
}
/**
* Replaces individual timestamps with delta msecs.
* Looks for two network crossings and adjusts clock for clock skew if found.
* Assumes log built by repeated calls to `stampLog`
* @param log Each logged event starts with ISO time stamp, space, rest of line, terminated by `\n`.
* @returns reformated multi-line event log
*/
function stampLogFormat(log) {
if (typeof log !== "string") return "";
const { data, newClocks } = parseStampLog(log);
const total = data.at(-1).when - data[0].when;
adjustNetworkDeltas(data, newClocks, total);
return formatStampLog(data, total);
}
//#endregion
//#region ../src/utility/utilityHelpers.noBuffer.ts
/**
* Convert a value to an encoded string if currently an encoded string or number[] or Uint8Array.
* @param val string or number[] or Uint8Array. If string, encoding must be hex. If number[], each value must be 0..255.
* @param enc optional encoding type if val is string, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.
* @param returnEnc optional encoding type for returned string if different from `enc`, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.
* @returns hex encoded string representation of val.
* @publicbody
*/
function asString(val, enc, returnEnc) {
enc ||= "hex";
returnEnc ||= enc;
if (typeof val === "string") {
if (enc === returnEnc) return val;
val = asUint8Array(val, enc);
}
const v = Array.isArray(val) ? val : Array.from(val);
switch (returnEnc) {
case "utf8": return Utils.toUTF8(v);
case "base64": return Utils.toBase64(v);
}
return Utils.toHex(v);
}
/**
* Convert a value to number[] if currently an encoded string or number[] or Uint8Array.
* @param val string or number[] or Uint8Array. If string, encoding must be hex. If number[], each value must be 0..255.
* @param enc optional encoding type if val is string, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.
* @returns number[] array of byte values representation of val.
* @publicbody
*/
function asArray(val, enc) {
if (Array.isArray(val)) return val;
if (typeof val !== "string") return Array.from(val);
enc ||= "hex";
return Utils.toArray(val, enc);
}
/**
* Convert a value to Uint8Array if currently an encoded string or number[] or Uint8Array.
* @param val string or number[] or Uint8Array. If string, encoding must be hex. If number[], each value must be 0..255.
* @param enc optional encoding type if val is string, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.
* @returns Uint8Array representation of val.
* @publicbody
*/
function asUint8Array(val, enc) {
if (Array.isArray(val)) return Uint8Array.from(val);
if (typeof val !== "string") return val;
enc ||= "hex";
return Utils.toUint8Array(val, enc);
}
//#endregion
//#region ../src/utility/utilityHelpers.ts
async function getIdentityKey(wallet) {
return (await wallet.getPublicKey({ identityKey: true })).publicKey;
}
function toWalletNetwork(chain) {
switch (chain) {
case "main": return "mainnet";
case "test":
case "stn":
case "ttn":
case "tstn":
case "mock": return "testnet";
}
}
/**
* Maps a Chain to a network preset suitable for LookupResolver / SHIPBroadcaster.
* Unlike `toWalletNetwork`, this returns `'local'` for `mock` chain.
*/
function toLookupNetworkPreset(chain) {
switch (chain) {
case "main": return "mainnet";
case "test": return "testnet";
case "stn":
case "ttn":
case "tstn":
case "mock": return "local";
}
}
function makeAtomicBeef(tx, beef) {
if (Array.isArray(beef)) beef = Beef.fromBinary(beef);
beef.mergeTransaction(tx);
return beef.toBinaryAtomic(tx.id("hex"));
}
/**
* Coerce a bsv transaction encoded as a hex string, serialized array, or Transaction to Transaction
* If tx is already a Transaction, just return it.
* @publicbody
*/
function asBsvSdkTx(tx) {
if (Array.isArray(tx)) tx = Transaction.fromBinary(tx);
else if (typeof tx === "string") tx = Transaction.fromHex(tx);
return tx;
}
/**
* Coerce a bsv script encoded as a hex string, serialized array, or Script to Script
* If script is already a Script, just return it.
* @publicbody
*/
function asBsvSdkScript(script) {
if (Array.isArray(script)) script = Script.fromBinary(script);
else if (typeof script === "string") script = Script.fromHex(script);
return script;
}
/**
* @param privKey bitcoin private key in 32 byte hex string form
* @returns @bsv/sdk PrivateKey
*/
function asBsvSdkPrivateKey(privKey) {
return PrivateKey.fromString(privKey, "hex");
}
/**
* @param pubKey bitcoin public key in standard compressed key hex string form
* @returns @bsv/sdk PublicKey
*/
function asBsvSdkPublickKey(pubKey) {
return PublicKey.fromString(pubKey);
}
/**
* Helper function.
*
* Verifies that a possibly optional value has a value.
*/
function verifyTruthy(v, description) {
if (v == null) throw new WERR_INTERNAL(description ?? "A truthy value is required.");
return v;
}
/**
* Helper function.
*
* Verifies that a hex string is trimmed and lower case.
*/
function verifyHexString(v) {
if (typeof v !== "string") throw new WERR_INTERNAL("A string is required.");
v = v.trim().toLowerCase();
return v;
}
/**
* Helper function.
*
* Verifies that an optional or null hex string is undefined or a trimmed lowercase string.
*/
function verifyOptionalHexString(v) {
if (v == null || v === "") return void 0;
return verifyHexString(v);
}
/**
* Helper function.
*
* Verifies that an optional or null number has a numeric value.
*/
function verifyNumber(v) {
if (typeof v !== "number") throw new WERR_INTERNAL("A number is required.");
return v;
}
/**
* Helper function.
*
* Verifies that an optional or null number has a numeric value.
*/
function verifyInteger(v) {
if (typeof v !== "number" || !Number.isInteger(v)) throw new WERR_INTERNAL("An integer is required.");
return v;
}
/**
* Helper function.
*
* Verifies that a database record identifier is an integer greater than zero.
*/
function verifyId(id) {
id = verifyInteger(id);
if (id < 1) throw new WERR_INTERNAL("id must be valid integer greater than zero.");
return id;
}
/**
* Helper function.
*
* @throws WERR_BAD_REQUEST if results has length greater than one.
*
* @returns results[0] or undefined if length is zero.
*/
function verifyOneOrNone(results) {
if (results.length > 1) throw new WERR_BAD_REQUEST("Result must be unique.");
return results[0];
}
/**
* Helper function.
*
* @throws WERR_BAD_REQUEST if results has length other than one.
*
* @returns results[0].
*/
function verifyOne(results, errorDescrition) {
if (results.length !== 1) throw new WERR_BAD_REQUEST(errorDescrition ?? "Result must exist and be unique.");
return results[0];
}
/**
* Returns an await'able Promise that resolves in the given number of msecs.
* @param msecs number of milliseconds to wait before resolving the promise.
* Must be greater than zero and less than 2 minutes (120,000 msecs)
* @publicbody
*/
async function wait(msecs) {
const MIN_WAIT = 0;
const MAX_WAIT = 120 * 1e3;
if (typeof msecs !== "number" || !Number.isFinite(msecs) || Number.isNaN(msecs) || msecs < MIN_WAIT || msecs > MAX_WAIT) throw new WERR_INVALID_PARAMETER("msecs", `a number between ${MIN_WAIT} and ${MAX_WAIT} msecs, not ${msecs}.`);
return await new Promise((resolve) => setTimeout(resolve, msecs));
}
/**
* @returns count cryptographically secure random bytes as array of bytes
*/
function randomBytes(count) {
return Random(count);
}
/**
* @returns count cryptographically secure random bytes as hex encoded string
*/
function randomBytesHex(count) {
return Utils.toHex(Random(count));
}
/**
* @returns count cryptographically secure random bytes as base64 encoded string
*/
function randomBytesBase64(count) {
return Utils.toBase64(Random(count));
}
function validateSecondsSinceEpoch(time) {
const date = /* @__PURE__ */ new Date(time * 1e3);
if (date.getTime() / 1e3 !== time || time < 16e8 || time > 1e11) throw new WERR_INVALID_PARAMETER("time", "valid \"since epoch\" unix time");
return date;
}
/**
* Compares lengths and direct equality of values.
* @param arr1
* @param arr2
* @returns
*/
function arraysEqual(arr1, arr2) {
if (arr1.length !== arr2.length) return false;
for (let i = 0; i < arr1.length; i++) if (arr1[i] !== arr2[i]) return false;
return true;
}
function optionalArraysEqual(arr1, arr2) {
if (arr1 == null && arr2 == null) return true;
if (arr1 == null || arr2 == null) return false;
return arraysEqual(arr1, arr2);
}
function maxDate(d1, d2) {
if (d1 != null && d2 != null) {
if (d1 > d2) return d1;
return d2;
}
if (d1 != null) return d1;
if (d2 != null) return d2;
}
/**
* Calculate the SHA256 hash of an array of bytes
* @returns sha256 hash of buffer contents.
* @publicbody
*/
function sha256Hash(data) {
if (!Array.isArray(data)) data = asArray(data);
return new Hash.SHA256().update(data).digest();
}
/**
* Calculate the SHA256 hash of the SHA256 hash of an array of bytes.
* @param data an array of bytes
* @returns double sha256 hash of data, byte 0 of hash first.
* @publicbody
*/
function doubleSha256LE(data) {
if (!Array.isArray(data)) data = asArray(data);
const first = new Hash.SHA256().update(data).digest();
return new Hash.SHA256().update(first).digest();
}
/**
* Calculate the SHA256 hash of the SHA256 hash of an array of bytes.
* @param data is an array of bytes.
* @returns reversed (big-endian) double sha256 hash of data, byte 31 of hash first.
* @publicbody
*/
function doubleSha256BE(data) {
return doubleSha256LE(data).reverse();
}
/**
* Logging function to handle logging based on running in jest "single test" mode,
*
* @param {string} message - The main message to log.
* @param {...any} optionalParams - Additional parameters to log (optional).
*/
const logger = (message, ...optionalParams) => {
if (process.argv.some((arg) => arg === "--testNamePattern" || arg === "-t")) console.log(message, ...optionalParams);
};
//#endregion
//#region ../src/utility/ScriptTemplateBRC29.ts
const brc29ProtocolID = [2, "3241645161d8"];
/**
* Simple Authenticated BSV P2PKH Payment Protocol
* https://brc.dev/29
*/
var ScriptTemplateBRC29 = class {
params;
p2pkh;
constructor(params) {
this.params = params;
this.p2pkh = new P2PKH();
verifyTruthy(params.derivationPrefix);
verifyTruthy(params.derivationSuffix);
}
getKeyID() {
return `${this.params.derivationPrefix ?? ""} ${this.params.derivationSuffix ?? ""}`;
}
getKeyDeriver(privKey) {
if (this.params.keyDeriver?.rootKey === privKey) return this.params.keyDeriver;
if (typeof privKey === "string") {
if (this.params.keyDeriver?.rootKey.toHex() === privKey) return this.params.keyDeriver;
privKey = PrivateKey.fromHex(privKey);
}
if (this.params.keyDeriver == null || this.params.keyDeriver.rootKey.toHex() !== privKey.toHex()) return new CachedKeyDeriver(privKey);
return this.params.keyDeriver;
}
lock(lockerPrivKey, unlockerPubKey) {
const address = this.getKeyDeriver(lockerPrivKey).derivePublicKey(brc29ProtocolID, this.getKeyID(), unlockerPubKey, false).toAddress();
return this.p2pkh.lock(address);
}
unlock(unlockerPrivKey, lockerPubKey, sourceSatoshis, lockingScript) {
const derivedPrivateKey = this.getKeyDeriver(unlockerPrivKey).derivePrivateKey(brc29ProtocolID, this.getKeyID(), lockerPubKey);
return this.unlockWithDerivedPrivateKey(derivedPrivateKey, sourceSatoshis, lockingScript);
}
unlockWithDerivedPrivateKey(derivedPrivateKey, sourceSatoshis, lockingScript) {
return this.p2pkh.unlock(derivedPrivateKey, "all", false, sourceSatoshis, lockingScript);
}
/**
* P2PKH unlock estimateLength is a constant
*/
unlockLength = 108;
};
//#endregion
//#region ../src/utility/parseTxScriptOffsets.ts
function parseTxScriptOffsets(rawTx) {
const br = Utils.ReaderUint8Array.makeReader(rawTx);
const inputs = [];
const outputs = [];
br.pos += 4;
const inputsLength = br.readVarIntNum();
for (let i = 0; i < inputsLength; i++) {
br.pos += 36;
const scriptLength = br.readVarIntNum();
inputs.push({
vin: i,
offset: br.pos,
length: scriptLength
});
br.pos += scriptLength + 4;
}
const outputsLength = br.readVarIntNum();
for (let i = 0; i < outputsLength; i++) {
br.pos += 8;
const scriptLength = br.readVarIntNum();
outputs.push({
vout: i,
offset: br.pos,
length: scriptLength
});
br.pos += scriptLength;
}
return {
inputs,
outputs
};
}
//#endregion
//#region ../src/utility/tscProofToMerklePath.ts
function convertProofToMerklePath(txid, proof) {
const blockHeight = proof.height;
const treeHeight = proof.nodes.length;
const path = Array.from({ length: treeHeight }).fill(0).map(() => []);
let index = proof.index;
for (let level = 0; level < treeHeight; level++) {
const node = proof.nodes[level];
const isOdd = index % 2 === 1;
const leaf = { offset: isOdd ? index - 1 : index + 1 };
if (node === "*" || level === 0 && node === txid) leaf.duplicate = true;
else leaf.hash = node;
path[level].push(leaf);
if (level === 0) {
const txidLeaf = {
offset: proof.index,
hash: txid,
txid: true
};
if (isOdd) path[0].push(txidLeaf);
else path[0].unshift(txidLeaf);
}
index = index >> 1;
}
return new MerklePath(blockHeight, path);
}
//#endregion
//#region ../src/utility/brc114ActionTimeLabels.ts
const FROM_PREFIX = "action time from ";
const TO_PREFIX = "action time to ";
function parseActionTimeBound(label, prefix, bound) {
const value = label.slice(prefix.length);
const invalid = `valid. Invalid action time ${bound} timestamp value.`;
if (!/^\d+$/.test(value)) throw new WERR_INVALID_PARAMETER("labels", invalid);
const timestamp = Number(value);
if (!Number.isSafeInteger(timestamp) || timestamp < 0) throw new WERR_INVALID_PARAMETER("labels", invalid);
if (Number.isNaN(new Date(timestamp).getTime())) throw new WERR_INVALID_PARAMETER("labels", invalid);
return timestamp;
}
function setActionTimeBound(current, label, prefix, bound) {
if (current !== void 0) throw new WERR_INVALID_PARAMETER("labels", `valid. Duplicate action time ${bound} label.`);
return parseActionTimeBound(label, prefix, bound);
}
function parseBrc114ActionTimeLabels(labels) {
let from;
let to;
const remainingLabels = [];
let timeFilterRequested = false;
for (const label of labels ?? []) {
if (label.startsWith(FROM_PREFIX)) {
timeFilterRequested = true;
from = setActionTimeBound(from, label, FROM_PREFIX, "from");
continue;
}
if (label.startsWith(TO_PREFIX)) {
timeFilterRequested = true;
to = setActionTimeBound(to, label, TO_PREFIX, "to");
continue;
}
remainingLabels.push(label);
}
if (from !== void 0 && to !== void 0 && from >= to) throw new WERR_INVALID_PARAMETER("labels", "valid. action time from must be less than action time to.");
return {
from,
to,
timeFilterRequested,
remainingLabels
};
}
function makeBrc114ActionTimeLabel(unixMillis) {
return `action time ${unixMillis}`;
}
//#endregion
//#region ../src/storage/schema/entities/EntityBase.ts
var EntityBase = class {
api;
constructor(api) {
this.api = api;
}
/**
* An entity may decode properties of the underlying Api object on construction.
*
* The `toApi` method forces an `updateApi` before returning the underlying,
* now updated, Api object.
*
* @returns The underlying Api object with any entity decoded properties updated.
*/
toApi() {
this.updateApi();
return this.api;
}
};
function createSyncMap() {
return {
provenTx: {
entityName: "provenTx",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
outputBasket: {
entityName: "outputBasket",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
transaction: {
entityName: "transaction",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
provenTxReq: {
entityName: "provenTxReq",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
txLabel: {
entityName: "txLabel",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
txLabelMap: {
entityName: "txLabelMap",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
output: {
entityName: "output",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
outputTag: {
entityName: "outputTag",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
outputTagMap: {
entityName: "outputTagMap",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
certificate: {
entityName: "certificate",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
certificateField: {
entityName: "certificateField",
idMap: {},
maxUpdated_at: void 0,
count: 0
},
commission: {
entityName: "commission",
idMap: {},
maxUpdated_at: void 0,
count: 0
}
};
}
//#endregion
//#region ../src/storage/schema/entities/EntityCertificate.ts
var EntityCertificate = class EntityCertificate extends EntityBase {
constructor(api) {
const now = /* @__PURE__ */ new Date();
super(api || {
certificateId: 0,
created_at: now,
updated_at: now,
userId: 0,
type: "",
subject: "",
verifier: void 0,
serialNumber: "",
certifier: "",
revocationOutpoint: "",
signature: "",
isDeleted: false
});
}
updateApi() {}
get certificateId() {
return this.api.certificateId;
}
set certificateId(v) {
this.api.certificateId = v;
}
get created_at() {
return this.api.created_at;
}
set created_at(v) {
this.api.created_at = v;
}
get updated_at() {
return this.api.updated_at;
}
set updated_at(v) {
this.api.updated_at = v;
}
get userId() {
return this.api.userId;
}
set userId(v) {
this.api.userId = v;
}
get type() {
return this.api.type;
}
set type(v) {
this.api.type = v;
}
get subject() {
return this.api.subject;
}
set subject(v) {
this.api.subject = v;
}
get verifier() {
return this.api.verifier;
}
set verifier(v) {
this.api.verifier = v;
}
get serialNumber() {
return this.api.serialNumber;
}
set serialNumber(v) {
this.api.serialNumber = v;
}
get certifier() {
return this.api.certifier;
}
set certifier(v) {
this.api.certifier = v;
}
get revocationOutpoint() {
return this.api.revocationOutpoint;
}
set revocationOutpoint(v) {
this.api.revocationOutpoint = v;
}
get signature() {
return this.api.signa