{"version":3,"file":"index.mobile.mjs","names":["SdkUtils","sp","wsm","BsvTransaction","sdk.WERR_INVALID_PARAMETER","sdk.WERR_INVALID_OPERATION","sdk.WERR_NOT_ACTIVE","sdk.WERR_UNAUTHORIZED","sdk.WERR_INTERNAL","sdk.WERR_NOT_IMPLEMENTED","makeKnownTxidLookup","processAction","BsvTransaction","sdk.WERR_INTERNAL","createAction","createActionCore","internalizeAction","trimInputBeef","createAction","internalizeAction","writeUInt32BE","readUInt32BE","BsvTransaction","sdk.WERR_INVALID_OPERATION","sdk.WERR_INTERNAL","beginBatch","extendBatch","renewBatch","prepareBatchCommit","putBatchBlob","putBatchPack","commitBatch","commitBatchByDigest","abortBatch","processAction","sdk.WERR_UNAUTHORIZED","TAG","isObject","vbhfs","stripTrailingSlash","defaultDeploymentId","BsvTransaction","createInsertHeaderResult"],"sources":["../../src/sdk/WalletError.ts","../../src/sdk/WERR_errors.ts","../../src/sdk/WalletErrorFromJson.ts","../../src/sdk/types.ts","../../src/sdk/PrivilegedKeyManager.ts","../../src/sdk/index.ts","../../src/utility/stampLog.ts","../../src/utility/utilityHelpers.noBuffer.ts","../../src/utility/utilityHelpers.ts","../../src/utility/ScriptTemplateBRC29.ts","../../src/utility/parseTxScriptOffsets.ts","../../src/utility/tscProofToMerklePath.ts","../../src/utility/brc114ActionTimeLabels.ts","../../src/storage/schema/entities/EntityBase.ts","../../src/storage/schema/entities/EntityCertificate.ts","../../src/storage/schema/entities/EntityCertificateField.ts","../../src/storage/schema/entities/EntityCommission.ts","../../src/storage/schema/entities/EntityOutput.ts","../../src/storage/schema/entities/EntityOutputBasket.ts","../../src/storage/schema/entities/EntityOutputTag.ts","../../src/storage/schema/entities/EntityOutputTagMap.ts","../../src/storage/schema/entities/EntityProvenTx.ts","../../src/storage/schema/entities/EntityProvenTxReq.ts","../../src/storage/schema/entities/EntityTransaction.ts","../../src/storage/schema/entities/EntityTxLabel.ts","../../src/storage/schema/entities/EntityTxLabelMap.ts","../../src/storage/schema/entities/EntityUser.ts","../../src/storage/schema/entities/MergeEntity.ts","../../src/storage/schema/entities/EntitySyncState.ts","../../src/storage/WalletStorageManager.ts","../../src/storage/storageProviderHelpers.ts","../../src/storage/methods/getBeefForTransaction.ts","../../src/utility/aggregateResults.ts","../../src/storage/methods/processAction.ts","../../src/storage/methods/attemptToPostReqsToNetwork.ts","../../src/storage/methods/listCertificates.ts","../../src/storage/methods/utils.ts","../../src/storage/methods/generateChange.ts","../../src/signer/methods/acquireDirectCertificate.ts","../../src/signer/methods/proveCertificate.ts","../../src/signer/methods/buildSignableTransaction.ts","../../src/signer/methods/verifyUnlockScripts.ts","../../src/signer/methods/completeSignedTransaction.ts","../../src/signer/methods/resultBeef.ts","../../src/signer/methods/createAction.ts","../../src/signer/methods/signAction.ts","../../src/signer/methods/internalizeAction.ts","../../src/WalletSettingsManager.ts","../../src/utility/identityUtils.ts","../../src/signer/actionBatch/actionBatchBootstrap.ts","../../src/utility/actionBatchDigest.ts","../../src/utility/beefForTxids.ts","../../src/storage/methods/offsetKey.ts","../../src/storage/methods/actionPlanning.ts","../../src/signer/actionBatch/ActionBatchPlanner.ts","../../src/utility/actionBatchPack.ts","../../src/signer/actionBatch/ActionBatchWorkspace.ts","../../src/Wallet.ts","../../src/storage/methods/managedChange.ts","../../src/storage/methods/createAction.ts","../../src/services/chaintracker/chaintracks/util/dirtyHashes.ts","../../src/services/chaintracker/chaintracks/util/validBulkHeaderFilesByFileHash.ts","../../src/services/chaintracker/chaintracks/util/blockHeaderUtilities.ts","../../src/storage/methods/internalizeAction.ts","../../src/storage/methods/getSyncChunk.ts","../../src/storage/StorageReader.ts","../../src/storage/StorageReaderWriter.ts","../../src/storage/methods/actionBatchBlobs.ts","../../src/storage/methods/actionBatchValidation.ts","../../src/storage/methods/actionBatch.ts","../../src/storage/methods/availableManagedChange.ts","../../src/storage/StorageProvider.ts","../../src/storage/StorageSyncReader.ts","../../src/storage/schema/tables/TableTransaction.ts","../../src/storage/schema/tables/TableOutput.ts","../../src/storage/schema/tables/TableAuthSession.ts","../../src/storage/remoting/entityValidationHelpers.ts","../../src/storage/remoting/StorageClientBase.ts","../../src/storage/remoting/BinaryJson.ts","../../src/storage/remoting/StorageMobile.ts","../../src/utility/hashWasm.ts","../../src/storage/portable/index.ts","../../src/storage/methods/ListActionsSpecOp.ts","../../src/storage/methods/ListOutputsSpecOp.ts","../../src/services/chaintracker/chaintracks/Api/BlockHeaderApi.ts","../../src/services/chaintracker/chaintracks/util/HeightRange.ts","../../src/services/chaintracker/chaintracks/util/SingleWriterMultiReaderLock.ts","../../src/services/chaintracker/chaintracks/Chaintracks.ts","../../src/services/chaintracker/chaintracks/ChaintracksServiceClient.ts","../../src/services/chaintracker/chaintracks/GoChaintracksServiceClient.ts","../../src/services/chaintracker/chaintracks/Ingest/BulkIngestorBase.ts","../../src/services/chaintracker/chaintracks/Ingest/LiveIngestorBase.ts","../../src/services/chaintracker/chaintracks/util/BulkFileDataReader.ts","../../src/services/chaintracker/chaintracks/util/ChaintracksFetch.ts","../../src/services/chaintracker/chaintracks/util/BulkFileDataManager.ts","../../src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDN.ts","../../src/services/chaintracker/chaintracks/Ingest/BulkIngestorCDNBabbage.ts","../../src/services/providers/SdkWhatsOnChain.ts","../../src/services/ServiceCollection.ts","../../src/services/networkConfig.ts","../../src/services/createDefaultWalletServicesOptions.ts","../../src/services/providers/exchangeRates.ts","../../src/services/providers/ARC.ts","../../src/services/providers/Arcade.ts","../../src/services/providers/Bitails.ts","../../src/services/providers/getBeefForTxid.ts","../../src/services/chaintracker/ChaintracksChainTracker.ts","../../src/services/Services.ts","../../src/services/providers/whatsOnChainHelpers.ts","../../src/services/providers/WhatsOnChain.ts","../../src/services/chaintracker/chaintracks/Ingest/WhatsOnChainServices.ts","../../src/services/chaintracker/chaintracks/Ingest/BulkIngestorWhatsOnChainCdn.ts","../../src/services/chaintracker/chaintracks/Ingest/BulkIngestorChaintracks.ts","../../src/services/chaintracker/chaintracks/Ingest/LiveIngestorWhatsOnChainPoll.ts","../../src/services/chaintracker/chaintracks/Ingest/LiveIngestorChaintracksSSE.ts","../../src/services/chaintracker/chaintracks/Storage/BulkStorageBase.ts","../../src/services/chaintracker/chaintracks/util/BulkHeaderFile.ts","../../src/services/chaintracker/chaintracks/util/BulkFilesReader.ts","../../src/services/chaintracker/chaintracks/Storage/ChaintracksStorageBase.ts","../../src/services/chaintracker/chaintracks/Storage/ChaintracksStorageNoDb.ts","../../src/services/chaintracker/chaintracks/Storage/ChaintracksStorageIdb.ts","../../src/services/chaintracker/chaintracks/configureChaintracksIngestors.ts","../../src/services/chaintracker/chaintracks/createDefaultNoDbChaintracksOptions.ts","../../src/services/chaintracker/chaintracks/createNoDbChaintracks.ts","../../src/CWIStyleWalletManager.ts","../../src/monitor/tasks/WalletMonitorTask.ts","../../src/monitor/tasks/TaskPurge.ts","../../src/monitor/tasks/TaskReviewStatus.ts","../../src/monitor/tasks/TaskFailAbandoned.ts","../../src/monitor/tasks/TaskCheckForProofs.ts","../../src/monitor/tasks/TaskClock.ts","../../src/monitor/tasks/TaskNewHeader.ts","../../src/monitor/tasks/TaskMonitorCallHistory.ts","../../src/monitor/tasks/TaskReorg.ts","../../src/services/providers/ArcSSEClient.ts","../../src/monitor/tasks/TaskUnFail.ts","../../src/monitor/tasks/TaskArcSSE.ts","../../src/monitor/tasks/TaskMineBlock.ts","../../src/monitor/tasks/TaskSendWaiting.ts","../../src/monitor/tasks/TaskCheckNoSends.ts","../../src/monitor/tasks/TaskReviewUtxos.ts","../../src/monitor/tasks/TaskReviewDoubleSpends.ts","../../src/monitor/tasks/TaskReviewProvenTxs.ts","../../src/monitor/tasks/TaskCleanupActionBatches.ts","../../src/monitor/Monitor.ts","../../src/signer/WalletSigner.ts","../../src/SimpleWalletManager.ts","../../src/wab-client/WABTransport.ts","../../src/wab-client/auth-method-interactors/AuthMethodInteractor.ts","../../src/wab-client/auth-method-interactors/PersonaIDInteractor.ts","../../src/wab-client/auth-method-interactors/TwilioPhoneInteractor.ts","../../src/wab-client/auth-method-interactors/DevConsoleInteractor.ts","../../src/wab-client/WABClient.ts","../../src/WalletLogger.ts","../../src/WalletAuthenticationManager.ts","../../src/WalletPermissionsManager.ts"],"sourcesContent":["import { ErrorCodeString10To40Bytes, ErrorDescriptionString20To200Bytes, WalletErrorObject } from '@bsv/sdk'\n\n/**\n * Derived class constructors should use the derived class name as the value for `name`,\n * and an internationalizable constant string for `message`.\n *\n * If a derived class intends to wrap another WalletError, the public property should\n * be named `walletError` and will be recovered by `fromUnknown`.\n *\n * Optionaly, the derived class `message` can include template parameters passed in\n * to the constructor. See WERR_MISSING_PARAMETER for an example.\n *\n * To avoid derived class name colisions, packages should include a package specific\n * identifier after the 'WERR_' prefix. e.g. 'WERR_FOO_' as the prefix for Foo package error\n * classes.\n */\nexport class WalletError extends Error implements WalletErrorObject {\n  // Facilitates detection of Error objects from non-error return values.\n  isError = true as const\n\n  constructor(\n    name: string,\n    message: string,\n    stack?: string,\n    public details?: Record<string, string>\n  ) {\n    super(message)\n    this.name = name\n    if (stack != null && stack !== '') this.stack = stack\n  }\n\n  /**\n   * Error class compatible accessor for  `code`.\n   */\n  get code(): ErrorCodeString10To40Bytes {\n    return this.name\n  }\n\n  set code(v: ErrorCodeString10To40Bytes) {\n    this.name = v\n  }\n\n  /**\n   * Error class compatible accessor for `description`.\n   */\n  get description(): ErrorDescriptionString20To200Bytes {\n    return this.message\n  }\n\n  set description(v: ErrorDescriptionString20To200Bytes) {\n    this.message = v\n  }\n\n  /**\n   * Recovers all public fields from WalletError derived error classes and relevant Error derived errors.\n   *\n   */\n  private static nonEmptyString(value: unknown): string | undefined {\n    return typeof value === 'string' && value !== '' ? value : undefined\n  }\n\n  private static objectErrorFields(error: Record<string, unknown>): {\n    name: string\n    message: string\n    stack: string | undefined\n    details: Record<string, string> | undefined\n  } {\n    const stringValue = WalletError.nonEmptyString\n    const genericName = error.name === 'Error' || error.name === 'FetchError'\n    const name = genericName\n      ? (stringValue(error.code) ?? stringValue(error.status) ?? 'WERR_UNKNOWN')\n      : (stringValue(error.name) ?? stringValue(error.code) ?? stringValue(error.status) ?? 'WERR_UNKNOWN')\n    const message = stringValue(error.message) ?? stringValue(error.description) ?? ''\n    const stack = typeof error.stack === 'string' ? error.stack : undefined\n    const details: Record<string, string> = {}\n    if (typeof error.sql === 'string') details.sql = error.sql\n    if (typeof error.sqlMessage === 'string') details.sqlMessage = error.sqlMessage\n    return {\n      name,\n      message,\n      stack,\n      details: Object.keys(details).length > 0 ? details : undefined\n    }\n  }\n\n  private static copyPublicErrorFields(target: WalletError, source: Record<string, unknown>): void {\n    const extensibleTarget = target as WalletError & Record<string, unknown>\n    const baseFields = new Set(['status', 'name', 'code', 'message', 'description', 'stack', 'sql', 'sqlMessage'])\n    for (const [key, value] of Object.entries(source)) {\n      const supportedValue = typeof value === 'string' || typeof value === 'number' || Array.isArray(value)\n      if (key === 'walletError') {\n        extensibleTarget[key] = WalletError.fromUnknown(value)\n      } else if (!baseFields.has(key) && supportedValue) {\n        extensibleTarget[key] = value\n      }\n    }\n  }\n\n  static fromUnknown(err: unknown): WalletError {\n    if (err instanceof WalletError) return err\n    let message = ''\n    if (typeof err === 'string') {\n      message = err\n    } else if (typeof err === 'number') {\n      message = err.toString()\n    }\n    let fields = {\n      name: 'WERR_UNKNOWN',\n      message,\n      stack: undefined as string | undefined,\n      details: undefined as Record<string, string> | undefined\n    }\n    if (err !== null && typeof err === 'object') {\n      fields = WalletError.objectErrorFields(err as Record<string, unknown>)\n    }\n    const e = new WalletError(fields.name, fields.message, fields.stack, fields.details)\n    if (err !== null && typeof err === 'object') {\n      WalletError.copyPublicErrorFields(e, err as Record<string, unknown>)\n    }\n    return e\n  }\n\n  /**\n   * @returns standard HTTP error status object with status property set to 'error'.\n   */\n  asStatus(): { status: string; code: string; description: string } {\n    return {\n      status: 'error',\n      code: this.name,\n      description: this.message\n    }\n  }\n\n  /**\n   * Base class default JSON serialization.\n   * Captures just the name and message properties.\n   *\n   * Override this method to safely (avoid deep, large, circular issues) serialize\n   * derived class properties.\n   *\n   * @returns stringified JSON representation of the WalletError.\n   */\n  protected toJson(): string {\n    const e = new WalletError(this.name, this.message)\n    const json = JSON.stringify({\n      isError: true,\n      name: e.name,\n      message: e.message\n    })\n    return json\n  }\n\n  /**\n   * Safely serializes a WalletError derived, WERR_REVIEW_ACTIONS (special case), Error or unknown error to JSON.\n   *\n   * Safely means avoiding deep, large, circular issues.\n   *\n   * @param error\n   * @returns stringified JSON representation of the error such that it can be desirialized to a WalletError.\n   */\n  static unknownToJson(error: unknown): string {\n    let json: string | undefined\n    let e: WalletError | undefined\n    const t = typeof error\n    const ctorName: unknown =\n      t === 'object' && error !== null ? (error as Record<string, unknown>).constructor : undefined\n    const ctor: string | undefined =\n      ctorName != null && typeof (ctorName as Record<string, unknown>).name === 'string'\n        ? ((ctorName as Record<string, unknown>).name as string)\n        : undefined\n    const name = t === 'object' && error !== null && typeof (error as any).name === 'string' ? (error as any).name : ''\n    const message =\n      t === 'object' && error !== null && typeof (error as any).message === 'string' ? (error as any).message : ''\n    const hasToJson: boolean = t === 'object' && typeof (error as any)?.toJson === 'function'\n    if (ctor != null && ctor !== '' && ctor.startsWith('WERR_') && hasToJson) {\n      json = (error as WalletError).toJson()\n    } else if (name !== '' && message !== '') {\n      e = new WalletError(name, message)\n      json = e.toJson()\n    } else {\n      e = new WalletError('WERR_UNKNOWN', String(error))\n      json = e.toJson()\n    }\n    return json\n  }\n}\n","import { AtomicBEEF, OutpointString, SendWithResult, TXIDHexString, WalletNetwork } from '@bsv/sdk'\nimport { WalletError } from './WalletError'\nimport { ReviewActionResult } from './WalletStorage.interfaces'\n\n/**\n * Not implemented.\n */\nexport class WERR_NOT_IMPLEMENTED extends WalletError {\n  constructor(message?: string) {\n    super('WERR_NOT_IMPLEMENTED', message ?? 'Not implemented.')\n  }\n}\n\n/**\n * An internal error has occurred.\n *\n * This is an example of an error with an optional custom `message`.\n */\nexport class WERR_INTERNAL extends WalletError {\n  constructor(message?: string) {\n    super('WERR_INTERNAL', message ?? 'An internal error has occurred.')\n  }\n}\n\n/**\n * The ${parameter} parameter is invalid.\n *\n * This is an example of an error object with a custom property `parameter` and templated `message`.\n */\nexport class WERR_INVALID_OPERATION extends WalletError {\n  constructor(message?: string) {\n    super('WERR_INVALID_OPERATION', message ?? 'An invalid operation was requested.')\n  }\n}\n\n/**\n * Unable to broadcast transaction at this time.\n */\nexport class WERR_BROADCAST_UNAVAILABLE extends WalletError {\n  constructor(_message?: string) {\n    super('WERR_BROADCAST_UNAVAILABLE', 'Unable to broadcast transaction at this time.')\n  }\n}\n\n/**\n * The ${parameter} parameter is invalid.\n *\n * This is an example of an error object with a custom property `parameter` and templated `message`.\n */\nexport class WERR_INVALID_PARAMETER extends WalletError {\n  constructor(\n    public parameter: string,\n    mustBe?: string\n  ) {\n    super('WERR_INVALID_PARAMETER', `The ${parameter} parameter must be ${mustBe ?? 'valid.'}`)\n  }\n\n  override toJson(): string {\n    const obj = JSON.parse(super.toJson())\n    obj.code = 6 // Must match HTTPWalletJSON.ts code\n    obj.parameter = this.parameter\n    return JSON.stringify(obj)\n  }\n}\n\n/**\n * Invalid merkleRoot ${merkleRoot} for block ${blockHash} at height ${blockHeight}${txid ? ` for txid ${txid}` : ''}.\n *\n * Typically thrown when a chain tracker fails to validate a merkle root.\n */\nexport class WERR_INVALID_MERKLE_ROOT extends WalletError {\n  constructor(\n    public blockHash: string,\n    public blockHeight: number,\n    public merkleRoot: string,\n    public txid?: string\n  ) {\n    super(\n      'WERR_INVALID_MERKLE_ROOT',\n      `Invalid merkleRoot ${merkleRoot} for block ${blockHash} at height ${blockHeight}${txid != null ? ' for txid ' + txid : ''}.`\n    )\n  }\n\n  override toJson(): string {\n    const obj = JSON.parse(super.toJson())\n    obj.code = 8 // Must match HTTPWalletJSON.ts code\n    obj.blockHash = this.blockHash\n    obj.blockHeight = this.blockHeight\n    obj.merkleRoot = this.merkleRoot\n    obj.txid = this.txid\n    return JSON.stringify(obj)\n  }\n}\n\n/**\n * The required ${parameter} parameter is missing.\n *\n * This is an example of an error object with a custom property `parameter`\n */\nexport class WERR_MISSING_PARAMETER extends WalletError {\n  constructor(public parameter: string) {\n    super('WERR_MISSING_PARAMETER', `The required ${parameter} parameter is missing.`)\n  }\n\n  override toJson(): string {\n    const obj = JSON.parse(super.toJson())\n    obj.parameter = this.parameter\n    return JSON.stringify(obj)\n  }\n}\n\n/**\n * The request is invalid.\n */\nexport class WERR_BAD_REQUEST extends WalletError {\n  constructor(message?: string) {\n    super('WERR_BAD_REQUEST', message ?? 'The request is invalid.')\n  }\n}\n\n/**\n * Configured network chain is invalid or does not match across services.\n */\nexport class WERR_NETWORK_CHAIN extends WalletError {\n  constructor(message?: string) {\n    super('WERR_NETWORK_CHAIN', message ?? 'Configured network chain is invalid or does not match across services.')\n  }\n}\n\n/**\n * Access is denied due to an authorization error.\n */\nexport class WERR_UNAUTHORIZED extends WalletError {\n  constructor(message?: string) {\n    super('WERR_UNAUTHORIZED', message ?? 'Access is denied due to an authorization error.')\n  }\n}\n\n/**\n * WalletStorageManager is not accessing user's active storage or there are conflicting active stores configured.\n */\nexport class WERR_NOT_ACTIVE extends WalletError {\n  constructor(message?: string) {\n    super(\n      'WERR_NOT_ACTIVE',\n      message ??\n        \"WalletStorageManager is not accessing user's active storage or there are conflicting active stores configured.\"\n    )\n  }\n}\n\n/**\n * Insufficient funds in the available inputs to cover the cost of the required outputs\n * and the transaction fee (${moreSatoshisNeeded} more satoshis are needed,\n * for a total of ${totalSatoshisNeeded}), plus whatever would be required in order\n * to pay the fee to unlock and spend the outputs used to provide the additional satoshis.\n */\nexport class WERR_INSUFFICIENT_FUNDS extends WalletError {\n  /**\n   * @param totalSatoshisNeeded Total satoshis required to fund transactions after net of required inputs and outputs.\n   * @param moreSatoshisNeeded Shortfall on total satoshis required to fund transactions after net of required inputs and outputs.\n   */\n  constructor(\n    public totalSatoshisNeeded: number,\n    public moreSatoshisNeeded: number\n  ) {\n    super(\n      'WERR_INSUFFICIENT_FUNDS',\n      `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.`\n    )\n  }\n\n  override toJson(): string {\n    const obj = JSON.parse(super.toJson())\n    obj.code = 7 // Must match HTTPWalletJSON.ts code\n    obj.totalSatoshisNeeded = this.totalSatoshisNeeded\n    obj.moreSatoshisNeeded = this.moreSatoshisNeeded\n    return JSON.stringify(obj)\n  }\n}\n\nexport class WERR_INVALID_PUBLIC_KEY extends WalletError {\n  /**\n   * @param key The invalid public key that caused the error.\n   * @param environment Optional environment flag to control whether the key is included in the message.\n   */\n  constructor(\n    public key: string,\n    network: WalletNetwork = 'mainnet'\n  ) {\n    const message =\n      network === 'mainnet'\n        ? `The provided public key \"${key}\" is invalid or malformed.`\n        : 'The provided public key is invalid or malformed.'\n    super('WERR_INVALID_PUBLIC_KEY', message)\n  }\n\n  protected override toJson(): string {\n    const obj = JSON.parse(super.toJson())\n    obj.key = this.key\n    return JSON.stringify(obj)\n  }\n}\n\n/**\n * When a `createAction` or `signAction` is completed in undelayed mode (`acceptDelayedBroadcast`: false),\n * any unsuccessful result will return the results by way of this exception to ensure attention is\n * paid to processing errors.\n */\nexport class WERR_REVIEW_ACTIONS extends WalletError {\n  /**\n   * All parameters correspond to their comparable `createAction` or `signAction` results\n   * with the exception of `reviewActionResults`;\n   * which contains more details, particularly for double spend results.\n   */\n  constructor(\n    public reviewActionResults: ReviewActionResult[],\n    public sendWithResults: SendWithResult[],\n    public txid?: TXIDHexString,\n    public tx?: AtomicBEEF,\n    public noSendChange?: OutpointString[]\n  ) {\n    super('WERR_REVIEW_ACTIONS', 'Undelayed createAction or signAction results require review.')\n  }\n\n  override toJson(): string {\n    const obj = JSON.parse(super.toJson())\n    obj.code = 5 // Must match HTTPWalletJSON.ts code\n    obj.reviewActionResults = this.reviewActionResults\n    obj.sendWithResults = this.sendWithResults\n    obj.txid = this.txid\n    obj.tx = this.tx\n    obj.noSendChange = this.noSendChange\n    return JSON.stringify(obj)\n  }\n}\n\n/**\n * IF YOU ADD NEW ERRORS, ALSO UPDATE THE WalletError.fromJson METHOD IN src/sdk/WalletError.ts\n */\n","import { WalletError } from './WalletError'\nimport {\n  WERR_BAD_REQUEST,\n  WERR_BROADCAST_UNAVAILABLE,\n  WERR_INSUFFICIENT_FUNDS,\n  WERR_INTERNAL,\n  WERR_INVALID_OPERATION,\n  WERR_INVALID_PARAMETER,\n  WERR_INVALID_PUBLIC_KEY,\n  WERR_MISSING_PARAMETER,\n  WERR_NETWORK_CHAIN,\n  WERR_NOT_ACTIVE,\n  WERR_NOT_IMPLEMENTED,\n  WERR_REVIEW_ACTIONS,\n  WERR_UNAUTHORIZED\n} from './WERR_errors'\n\n/**\n * Reconstruct the correct derived WalletError from a JSON object created by `WalletError.unknownToJson`.\n *\n * This function is implemented as a separate function instead of a WalletError class static\n * to avoid circular dependencies.\n *\n * @param json\n * @returns a WalletError derived error object, typically for re-throw.\n */\nexport function WalletErrorFromJson (json: object): WalletError {\n  let e: WalletError\n  const obj = json as any\n  switch (obj.name) {\n    case 'WERR_NOT_IMPLEMENTED':\n      e = new WERR_NOT_IMPLEMENTED(obj.message)\n      break\n    case 'WERR_INTERNAL':\n      e = new WERR_INTERNAL(obj.message)\n      break\n    case 'WERR_INVALID_OPERATION':\n      e = new WERR_INVALID_OPERATION(obj.message)\n      break\n    case 'WERR_BROADCAST_UNAVAILABLE':\n      e = new WERR_BROADCAST_UNAVAILABLE(obj.message)\n      break\n    case 'WERR_INVALID_PARAMETER':\n      e = new WERR_INVALID_PARAMETER(obj.parameter)\n      e.message = obj.message\n      break\n    case 'WERR_MISSING_PARAMETER':\n      e = new WERR_MISSING_PARAMETER(obj.parameter)\n      e.message = obj.message\n      break\n    case 'WERR_BAD_REQUEST':\n      e = new WERR_BAD_REQUEST(obj.message)\n      break\n    case 'WERR_NETWORK_CHAIN':\n      e = new WERR_NETWORK_CHAIN(obj.message)\n      break\n    case 'WERR_UNAUTHORIZED':\n      e = new WERR_UNAUTHORIZED(obj.message)\n      break\n    case 'WERR_NOT_ACTIVE':\n      e = new WERR_NOT_ACTIVE(obj.message)\n      break\n    case 'WERR_INSUFFICIENT_FUNDS':\n      e = new WERR_INSUFFICIENT_FUNDS(obj.totalSatoshisNeeded, obj.moreSatoshisNeeded)\n      break\n    case 'WERR_INVALID_PUBLIC_KEY':\n      e = new WERR_INVALID_PUBLIC_KEY(obj.key, 'mainnet')\n      e.message = obj.message\n      break\n    case 'WERR_REVIEW_ACTIONS':\n      e = new WERR_REVIEW_ACTIONS(obj.reviewActionResults, obj.sendWithResults, obj.txid, obj.tx, obj.noSendChange)\n      break\n    default:\n      e = new WalletError((typeof obj.name === 'string' && obj.name !== '' ? obj.name : 'WERR_UNKNOWN'), (typeof obj.message === 'string' ? obj.message : ''))\n      break\n  }\n  return e\n}\n","import { Transaction, UnlockingScript } from '@bsv/sdk'\n\n/**\n * Identifies a unique transaction output by its `txid` and index `vout`\n */\nexport interface OutPoint {\n  /**\n   * Transaction double sha256 hash as big endian hex string\n   */\n  txid: string\n  /**\n   * zero based output index within the transaction\n   */\n  vout: number\n}\n\nexport type Chain = 'main' | 'test' | 'stn' | 'ttn' | 'tstn' | 'mock'\n\n/**\n * Initial status (attempts === 0):\n *\n * nosend: transaction was marked 'noSend'. It is complete and signed. It may be sent by an external party. Proof should be sought as if 'unmined'. No error if it remains unknown by network.\n *\n * unprocessed: indicates req is about to be posted to network by non-acceptDelayedBroadcast application code, after posting status is normally advanced to 'sending'\n *\n * unsent: rawTx has not yet been sent to the network for processing. req is queued for delayed processing.\n *\n * sending: At least one attempt to send rawTx to transaction processors has occured without confirmation of acceptance.\n *\n * unknown: rawTx status is unknown but is believed to have been previously sent to the network.\n *\n * Attempts > 0 status, processing:\n *\n * unknown: Last status update received did not recognize txid or wasn't understood.\n *\n * nonfinal: rawTx has an un-expired nLockTime and is eligible for continuous updating by new transactions with additional outputs and incrementing sequence numbers.\n *\n * unmined: Last attempt has txid waiting to be mined, possibly just sent without callback\n *\n * callback: Waiting for proof confirmation callback from transaction processor.\n *\n * unconfirmed: Potential proof has not been confirmed by chaintracks\n *\n * Terminal status:\n *\n * doubleSpend: Transaction spends same input as another transaction.\n *\n * invalid: rawTx is structuraly invalid or was rejected by the network. Will never be re-attempted or completed.\n *\n * completed: proven_txs record added, and notifications are complete.\n *\n * unfail: asigned to force review of a currently invalid ProvenTxReq.\n */\nexport type ProvenTxReqStatus =\n  | 'sending'\n  | 'unsent'\n  | 'nosend'\n  | 'unknown'\n  | 'nonfinal'\n  | 'unprocessed'\n  | 'unmined'\n  | 'callback'\n  | 'unconfirmed'\n  | 'completed'\n  | 'invalid'\n  | 'doubleSpend'\n  | 'unfail'\n\nexport const ProvenTxReqTerminalStatus: ProvenTxReqStatus[] = ['completed', 'invalid', 'doubleSpend']\n\nexport const ProvenTxReqNonTerminalStatus: ProvenTxReqStatus[] = [\n  'sending',\n  'unsent',\n  'nosend',\n  'unknown',\n  'nonfinal',\n  'unprocessed',\n  'unmined',\n  'callback',\n  'unconfirmed'\n]\n\nexport type TransactionStatus =\n  'completed' | 'failed' | 'unprocessed' | 'sending' | 'unproven' | 'unsigned' | 'nosend' | 'nonfinal' | 'unfail'\n\nexport interface Paged {\n  limit: number\n  offset?: number\n}\n\nexport interface KeyPair {\n  privateKey: string\n  publicKey: string\n}\n\nexport interface StorageIdentity {\n  /**\n   * The identity key (public key) assigned to this storage\n   */\n  storageIdentityKey: string\n  /**\n   * The human readable name assigned to this storage.\n   */\n  storageName: string\n}\n\nexport interface EntityTimeStamp {\n  created_at: Date\n  updated_at: Date\n}\n\nexport interface ScriptTemplateUnlock {\n  sign: (tx: Transaction, inputIndex: number) => Promise<UnlockingScript>\n  estimateLength: (tx: Transaction, inputIndex: number) => Promise<number>\n}\n\nexport interface WalletBalance {\n  total: number\n  utxos: Array<{ satoshis: number; outpoint: string }>\n}\n\nexport interface ReqHistoryNote {\n  when?: string\n  what: string\n  [key: string]: boolean | string | number | undefined\n}\n\n/**\n * The transaction status that a client will receive when subscribing to transaction updates in the Monitor.\n */\nexport interface ProvenTransactionStatus {\n  txid: string\n  txIndex: number\n  blockHeight: number\n  blockHash: string\n  merklePath: number[]\n  merkleRoot: string\n}\n\n/**\n * `listOutputs` special operation basket name value.\n *\n * Returns wallet's current change balance in the `totalOutputs` result property.\n * The `outputs` result property will always be an empty array.\n */\nexport const specOpWalletBalance = '893b7646de0e1c9f741bd6e9169b76a8847ae34adef7bef1e6a285371206d2e8'\n\n/**\n * `listOutputs` special operation basket name value.\n *\n * Lists only spendable wallet-managed BRC-29 change from the `default`\n * basket. Raw administrative `listOutputs({ basket: 'default' })` remains\n * intentionally unfiltered so legacy incompatible rows stay discoverable\n * for recovery instead of being hidden or silently mutated.\n */\nexport const specOpWalletManagedUtxos = '284570a6213a74ba861c38b1cf790e1e400d9cf9324454b76ea98860b6031c1a'\n\n/**\n * `listOutputs` special operation basket name value.\n *\n * Returns currently spendable wallet change outputs that fail to validate as unspent transaction outputs.\n *\n * Optional tag value 'release'. If present, updates invalid change outputs to not spendable.\n *\n * Optional tag value 'all'. If present, processes all spendable true outputs, independent of baskets, but basket must be defined.\n */\nexport const specOpInvalidChange = '5a76fd430a311f8bc0553859061710a4475c19fed46e2ff95969aa918e612e57'\n\n/**\n * `listOutputs` special operation basket name value.\n *\n * Updates the wallet's automatic change management parameters.\n *\n * Tag at index 0 is the new desired number of spendable change outputs to maintain.\n *\n * Tag at index 1 is the new target for minimum satoshis when creating new change outputs.\n */\nexport const specOpSetWalletChangeParams = 'a4979d28ced8581e9c1c92f1001cc7cb3aabf8ea32e10888ad898f0a509a3929'\n\n/**\n * @param basket Output basket name value.\n * @returns true iff the `basket` name is a reserved `listOutputs` special operation identifier.\n */\nexport function isListOutputsSpecOp(basket: string): boolean {\n  return [specOpWalletBalance, specOpWalletManagedUtxos, specOpInvalidChange, specOpSetWalletChangeParams].includes(\n    basket\n  )\n}\n\n/**\n * `listActions` special operation label name value.\n *\n * Processes only actions currently with status 'nosend'\n *\n * Optional label value 'abort'. If present, runs abortAction on all the actions returned.\n */\nexport const specOpNoSendActions = 'ac6b20a3bb320adafecd637b25c84b792ad828d3aa510d05dc841481f664277d'\n\n/**\n * `listActions` special operation label name value.\n *\n * Processes only actions currently with status 'failed'\n *\n * Optional label value 'unfail'. If present, sets status to 'unfail', which queues them for attempted recovery by the Monitor.\n */\nexport const specOpFailedActions = '97d4eb1e49215e3374cc2c1939a7c43a55e95c7427bf2d45ed63e3b4e0c88153'\n\n/**\n * @param label Action / Transaction label name value.\n * @returns true iff the `label` name is a reserved `listActions` special operation identifier.\n */\nexport function isListActionsSpecOp(label: string): boolean {\n  return [specOpNoSendActions, specOpFailedActions].includes(label)\n}\n\n/**\n * `createAction` special operation label name value.\n *\n * Causes WERR_REVIEW_ACTIONS throw with dummy properties.\n *\n */\nexport const specOpThrowReviewActions = 'a496e747fc3ad5fabdd4ae8f91184e71f87539bd3d962aa2548942faaaf0047a'\n\n/**\n * @param label Action / Transaction label name value.\n * @returns true iff the `label` name is a reserved `createAction` special operation identifier.\n */\nexport function isCreateActionSpecOp(label: string): boolean {\n  return [specOpThrowReviewActions].includes(label)\n}\n","import {\n  Random,\n  Utils,\n  PrivateKey,\n  CreateHmacArgs,\n  CreateHmacResult,\n  CreateSignatureArgs,\n  CreateSignatureResult,\n  GetPublicKeyArgs,\n  ProtoWallet,\n  PubKeyHex,\n  RevealCounterpartyKeyLinkageArgs,\n  RevealCounterpartyKeyLinkageResult,\n  RevealSpecificKeyLinkageArgs,\n  RevealSpecificKeyLinkageResult,\n  VerifyHmacArgs,\n  VerifyHmacResult,\n  VerifySignatureArgs,\n  VerifySignatureResult,\n  WalletDecryptArgs,\n  WalletDecryptResult,\n  WalletEncryptArgs,\n  WalletEncryptResult\n} from '@bsv/sdk'\n\n/**\n * PrivilegedKeyManager\n *\n * This class manages a privileged (i.e., very sensitive) private key, obtained from\n * an external function (`keyGetter`), which might be backed by HSMs, secure enclaves,\n * or other secure storage. The manager retains the key in memory only for a limited\n * duration (`retentionPeriod`), uses XOR-based chunk-splitting obfuscation, and\n * includes decoy data to raise the difficulty of discovering the real key in memory.\n *\n * IMPORTANT: While these measures raise the bar for attackers, JavaScript environments\n * do not provide perfect in-memory secrecy.\n */\nexport class PrivilegedKeyManager implements ProtoWallet {\n  /**\n   * Function that will retrieve the PrivateKey from a secure environment,\n   * e.g., an HSM or secure enclave. The reason for key usage is passed in\n   * to help with user consent, auditing, and access policy checks.\n   */\n  private readonly keyGetter: (reason: string) => Promise<PrivateKey>\n\n  /**\n   * Time (in ms) for which the obfuscated key remains in memory\n   * before being automatically destroyed.\n   */\n  private readonly retentionPeriod: number\n\n  /**\n   * A list of dynamically generated property names used to store\n   * real key chunks (XORed with random pads).\n   */\n  private chunkPropNames: string[] = []\n\n  /**\n   * A list of dynamically generated property names used to store\n   * the random pads that correspond to the real key chunks.\n   */\n  private chunkPadPropNames: string[] = []\n\n  /**\n   * A list of decoy property names that will be removed\n   * when the real key is destroyed.\n   */\n  private decoyPropNamesDestroy: string[] = []\n\n  /**\n   * A list of decoy property names that remain in memory\n   * even after the real key is destroyed (just to cause confusion).\n   */\n  private readonly decoyPropNamesRemain: string[] = []\n\n  /**\n   * Handle to the timer that will remove the key from memory\n   * after the retention period. If the key is refreshed again\n   * within that period, the timer is cleared and re-set.\n   */\n  private destroyTimer: any\n\n  /**\n   * Number of chunks to split the 32-byte key into.\n   * Adjust to increase or decrease obfuscation complexity.\n   */\n  private readonly CHUNK_COUNT = 4\n\n  /**\n   * @param keyGetter - Asynchronous function that retrieves the PrivateKey from a secure environment.\n   * @param retentionPeriod - Time in milliseconds to retain the obfuscated key in memory before zeroizing.\n   */\n  constructor(keyGetter: (reason: string) => Promise<PrivateKey>, retentionPeriod = 120_000) {\n    this.keyGetter = keyGetter\n    this.retentionPeriod = retentionPeriod\n\n    // Initialize some random decoy properties that always remain:\n    for (let i = 0; i < 2; i++) {\n      const propName = this.generateRandomPropName()\n      // Store random garbage to cause confusion\n      ;(this as any)[propName] = Uint8Array.from(Random(16))\n      this.decoyPropNamesRemain.push(propName)\n    }\n  }\n\n  /**\n   * Safely destroys the in-memory obfuscated key material by zeroizing\n   * and deleting related fields. Also destroys some (but not all) decoy\n   * properties to further confuse an attacker.\n   */\n  destroyKey(): void {\n    try {\n      // Zero out real chunk data\n      for (const name of this.chunkPropNames) {\n        const data: Uint8Array | undefined = (this as any)[name]\n        if (data != null) {\n          data.fill(0)\n        }\n        // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n        delete (this as any)[name]\n      }\n      for (const name of this.chunkPadPropNames) {\n        const data: Uint8Array | undefined = (this as any)[name]\n        if (data != null) {\n          data.fill(0)\n        }\n        // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n        delete (this as any)[name]\n      }\n\n      // Destroy some decoys\n      for (const name of this.decoyPropNamesDestroy) {\n        const data: Uint8Array | undefined = (this as any)[name]\n        if (data != null) {\n          data.fill(0)\n        }\n        // eslint-disable-next-line @typescript-eslint/no-dynamic-delete\n        delete (this as any)[name]\n      }\n\n      // Clear arrays of property names\n      this.chunkPropNames = []\n      this.chunkPadPropNames = []\n      this.decoyPropNamesDestroy = []\n    } catch {\n      // Best-effort memory zeroing: if an individual property is already gone or the\n      // fill/delete throws (e.g. frozen object in a test harness), we must still reach\n      // the finally block to clear the destruction timer.  Propagating here would leave\n      // the timer running and risk a second (no-op) destruction attempt.\n    } finally {\n      if (this.destroyTimer != null) {\n        clearTimeout(this.destroyTimer)\n        this.destroyTimer = undefined\n      }\n    }\n  }\n\n  /**\n   * Re/sets the destruction timer that removes the key from memory\n   * after `retentionPeriod` ms. If a timer is already running, it\n   * is cleared and re-set. This ensures the key remains in memory\n   * for exactly the desired window after its most recent acquisition.\n   */\n  private scheduleKeyDestruction(): void {\n    if (this.destroyTimer != null) {\n      clearTimeout(this.destroyTimer)\n    }\n    this.destroyTimer = setTimeout(() => {\n      this.destroyKey()\n    }, this.retentionPeriod)\n  }\n\n  /**\n   * XOR-based obfuscation on a per-chunk basis.\n   * This function takes two equal-length byte arrays\n   * and returns the XOR combination.\n   */\n  private xorBytes(a: Uint8Array, b: Uint8Array): Uint8Array {\n    const out = new Uint8Array(a.length)\n    for (let i = 0; i < a.length; i++) {\n      out[i] = a[i] ^ b[i]\n    }\n    return out\n  }\n\n  /**\n   * Splits the 32-byte key into `this.CHUNK_COUNT` smaller chunks\n   * (mostly equal length; the last chunk picks up leftover bytes\n   * if 32 is not evenly divisible).\n   */\n  private splitKeyIntoChunks(keyBytes: Uint8Array): Uint8Array[] {\n    const chunkSize = Math.floor(keyBytes.length / this.CHUNK_COUNT)\n    const chunks: Uint8Array[] = []\n    let offset = 0\n\n    for (let i = 0; i < this.CHUNK_COUNT; i++) {\n      const size = i === this.CHUNK_COUNT - 1 ? keyBytes.length - offset : chunkSize\n      chunks.push(keyBytes.slice(offset, offset + size))\n      offset += size\n    }\n    return chunks\n  }\n\n  /**\n   * Reassembles the chunks from the dynamic properties, XORs them\n   * with their corresponding pads, and returns a single 32-byte\n   * Uint8Array representing the raw key.\n   */\n  private reassembleKeyFromChunks(): Uint8Array | null {\n    try {\n      const chunkArrays: Uint8Array[] = []\n      for (let i = 0; i < this.chunkPropNames.length; i++) {\n        const chunkEnc = (this as any)[this.chunkPropNames[i]] as Uint8Array\n        const chunkPad = (this as any)[this.chunkPadPropNames[i]] as Uint8Array\n        if (chunkEnc?.length == null || chunkEnc.length !== chunkPad?.length) {\n          return null\n        }\n        const rawChunk = this.xorBytes(chunkEnc, chunkPad)\n        chunkArrays.push(rawChunk)\n      }\n      // Concat them back to a single 32-byte array:\n      const totalLength = chunkArrays.reduce((sum, c) => sum + c.length, 0)\n      if (totalLength !== 32) {\n        // We only handle 32-byte keys\n        return null\n      }\n      const rawKey = new Uint8Array(totalLength)\n      let offset = 0\n      for (const chunk of chunkArrays) {\n        rawKey.set(chunk, offset)\n        offset += chunk.length\n        // Attempt to zero the ephemeral chunk\n        chunk.fill(0)\n      }\n      return rawKey\n    } catch {\n      // Reassembly failed due to a missing property or type mismatch (e.g. the key was\n      // already destroyed or was never stored).  Returning null signals \"no key available\"\n      // to the caller, which will prompt re-authentication — propagating the raw error\n      // would leak internal obfuscation details and bypass that recovery path.\n      return null\n    }\n  }\n\n  /**\n   * Generates a random property name to store key chunks or decoy data.\n   */\n  private generateRandomPropName(): string {\n    // E.g., 8 random hex characters for the property name\n    const randomHex = Utils.toHex(Random(4))\n    const extraBytes = Random(3)\n    const extraNum = ((extraBytes[0] << 16) | (extraBytes[1] << 8) | extraBytes[2]) % 1000000\n    return `_${randomHex}_${extraNum}`\n  }\n\n  /**\n   * Forces a PrivateKey to be represented as exactly 32 bytes, left-padding\n   * with zeros if its numeric value has fewer than 32 bytes.\n   */\n  private get32ByteRepresentation(privKey: PrivateKey): Uint8Array {\n    // The internal \"toArray()\" can be up to 32 bytes, but sometimes fewer\n    // if the numeric value has leading zeros.\n    const buf = privKey.toArray()\n    if (buf.length > 32) {\n      throw new Error('PrivilegedKeyManager: Expected a 32-byte key, but got more.')\n    }\n    // Left-pad with zeros if needed\n    const keyBytes = new Uint8Array(32)\n    keyBytes.set(buf, 32 - buf.length)\n    return keyBytes\n  }\n\n  /**\n   * Returns the privileged key needed to perform cryptographic operations.\n   * Uses in-memory chunk-based obfuscation if the key was already fetched.\n   * Otherwise, it calls out to `keyGetter`, splits the 32-byte representation\n   * of the key, XORs each chunk with a random pad, and stores them under\n   * dynamic property names. Also populates new decoy properties.\n   *\n   * @param reason - The reason for why the key is needed, passed to keyGetter.\n   * @returns The PrivateKey object needed for cryptographic operations.\n   */\n  private async getPrivilegedKey(reason: string): Promise<PrivateKey> {\n    // If we already have chunk properties, try reassemble\n    if (this.chunkPropNames.length > 0 && this.chunkPadPropNames.length > 0) {\n      const rawKeyBytes = this.reassembleKeyFromChunks()\n      if (rawKeyBytes?.length === 32) {\n        // Convert 32 raw bytes back to a PrivateKey\n        // (Leading zeros are preserved, but PrivateKey() will parse it as a big integer.)\n        const hexKey = Utils.toHex([...rawKeyBytes]) // 64 hex chars\n        rawKeyBytes.fill(0) // Zero ephemeral copy\n        this.scheduleKeyDestruction()\n        return new PrivateKey(hexKey, 'hex')\n      }\n    }\n\n    // Otherwise, fetch a fresh key from the secure environment\n    const fetchedKey = await this.keyGetter(reason)\n\n    // Force 32‑byte representation (left-pad if necessary)\n    const keyBytes = this.get32ByteRepresentation(fetchedKey)\n\n    // Clean up any old data first (in case we had something stale)\n    this.destroyKey()\n\n    // Split the key\n    const chunks = this.splitKeyIntoChunks(keyBytes)\n\n    // Store new chunk data under random property names\n    for (const chunk of chunks) {\n      const chunkProp = this.generateRandomPropName()\n      const padProp = this.generateRandomPropName()\n      this.chunkPropNames.push(chunkProp)\n      this.chunkPadPropNames.push(padProp)\n\n      // Generate random pad of the same length as the chunk\n      const pad = Uint8Array.from(Random(chunk.length))\n      // XOR the chunk to obfuscate\n      const obf = this.xorBytes(chunk, pad)\n\n      // Store them in dynamic properties\n      ;(this as any)[chunkProp] = obf\n      ;(this as any)[padProp] = pad\n    }\n\n    // Generate some decoy properties that will be destroyed with the key\n    for (let i = 0; i < 2; i++) {\n      const decoyProp = this.generateRandomPropName()\n      ;(this as any)[decoyProp] = Uint8Array.from(Random(32))\n      this.decoyPropNamesDestroy.push(decoyProp)\n    }\n\n    // Zero out ephemeral original\n    keyBytes.fill(0)\n\n    // Schedule destruction\n    this.scheduleKeyDestruction()\n\n    // Return the newly fetched key as a normal PrivateKey\n    return fetchedKey\n  }\n\n  async getPublicKey(args: GetPublicKeyArgs): Promise<{ publicKey: PubKeyHex }> {\n    return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason as string)).getPublicKey(args)\n  }\n\n  async revealCounterpartyKeyLinkage(\n    args: RevealCounterpartyKeyLinkageArgs\n  ): Promise<RevealCounterpartyKeyLinkageResult> {\n    return await new ProtoWallet(\n      await this.getPrivilegedKey(args.privilegedReason as string)\n    ).revealCounterpartyKeyLinkage(args)\n  }\n\n  async revealSpecificKeyLinkage(args: RevealSpecificKeyLinkageArgs): Promise<RevealSpecificKeyLinkageResult> {\n    return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason as string)).revealSpecificKeyLinkage(\n      args\n    )\n  }\n\n  async encrypt(args: WalletEncryptArgs): Promise<WalletEncryptResult> {\n    return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason as string)).encrypt(args)\n  }\n\n  async decrypt(args: WalletDecryptArgs): Promise<WalletDecryptResult> {\n    return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason as string)).decrypt(args)\n  }\n\n  async createHmac(args: CreateHmacArgs): Promise<CreateHmacResult> {\n    return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason as string)).createHmac(args)\n  }\n\n  async verifyHmac(args: VerifyHmacArgs): Promise<VerifyHmacResult> {\n    return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason as string)).verifyHmac(args)\n  }\n\n  async createSignature(args: CreateSignatureArgs): Promise<CreateSignatureResult> {\n    return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason as string)).createSignature(args)\n  }\n\n  async verifySignature(args: VerifySignatureArgs): Promise<VerifySignatureResult> {\n    return await new ProtoWallet(await this.getPrivilegedKey(args.privilegedReason as string)).verifySignature(args)\n  }\n}\n","export * from './WalletError'\nexport * from './WalletErrorFromJson'\nexport * from './WalletSigner.interfaces'\nexport * from './WalletStorage.interfaces'\nexport * from './ActionBatch.interfaces'\nexport * from './WERR_errors'\nexport { Validation } from '@bsv/sdk'\nexport * from './CertOpsWallet'\nexport * from './types'\nexport * from './WalletServices.interfaces'\nexport * from './PrivilegedKeyManager'\n","/**\n * If a log is being kept, add a time stamped line.\n * @param log  Optional time stamped log to extend, or an object with a log property to update\n * @param lineToAdd Content to add to line.\n * @returns undefined or log extended by time stamped `lineToAdd` and new line.\n */\nexport function stampLog(log: string | undefined | { log?: string }, lineToAdd: string): string | undefined {\n  const add = `${new Date().toISOString()} ${lineToAdd}\\n`\n  if (typeof log === 'object' && typeof log.log === 'string') {\n    log.log = log.log + add\n    return log.log\n  }\n  if (typeof log === 'string') return log + add\n  return undefined\n}\n\ninterface StampLogEntry {\n  when: number\n  rest: string\n  delta: number\n  newClock: boolean\n}\n\nfunction parseStampLog(log: string): { data: StampLogEntry[]; newClocks: number[] } {\n  const data: StampLogEntry[] = []\n  const newClocks: number[] = []\n  let last = 0\n  for (const line of log.split('\\n')) {\n    const spaceAt = line.indexOf(' ')\n    if (spaceAt < 0) continue\n    const when = new Date(line.substring(0, spaceAt)).getTime()\n    const rest = line.substring(spaceAt + 1)\n    const delta = when - (last !== 0 ? last : when)\n    const newClock = rest.includes('**NETWORK**')\n    if (newClock) newClocks.push(data.length)\n    data.push({ when, rest, delta, newClock })\n    last = when\n  }\n  return { data, newClocks }\n}\n\nfunction adjustNetworkDeltas(data: StampLogEntry[], newClocks: number[], total: number): void {\n  if (newClocks.length % 2 !== 0) return\n\n  let network = total\n  let lastNewClock = 0\n  for (const newClock of newClocks) {\n    network -= data[newClock - 1].when - data[lastNewClock].when\n    lastNewClock = newClock\n  }\n  network -= data.at(-1)!.when - data[lastNewClock].when\n\n  let networks = newClocks.length\n  for (const newClock of newClocks) {\n    const delta = networks > 1 ? Math.floor(network / networks) : network\n    data[newClock].delta = delta\n    network -= delta\n    networks--\n  }\n}\n\nfunction formatStampLog(data: StampLogEntry[], total: number): string {\n  let formatted = `${new Date(data[0].when).toISOString()} Total = ${total} msecs\\n`\n  for (const entry of data) {\n    const delta = entry.delta.toString()\n    formatted += `${' '.repeat(8 - delta.length)}${delta} ${entry.rest}\\n`\n  }\n  return formatted\n}\n\n/**\n * Replaces individual timestamps with delta msecs.\n * Looks for two network crossings and adjusts clock for clock skew if found.\n * Assumes log built by repeated calls to `stampLog`\n * @param log Each logged event starts with ISO time stamp, space, rest of line, terminated by `\\n`.\n * @returns reformated multi-line event log\n */\nexport function stampLogFormat(log?: string): string {\n  if (typeof log !== 'string') return ''\n  const { data, newClocks } = parseStampLog(log)\n  const total = data.at(-1)!.when - data[0].when\n  adjustNetworkDeltas(data, newClocks, total)\n  return formatStampLog(data, total)\n}\n","import { Utils } from '@bsv/sdk'\n\n/** Byte array, string, or Uint8Array accepted by buffer-coercion helpers */\nexport type ByteInput = string | number[] | Uint8Array\n\n/** Encoding identifier for buffer-coercion helpers */\nexport type ByteEncoding = 'hex' | 'utf8' | 'base64'\n\n/**\n * Convert a value to an encoded string if currently an encoded string or number[] or Uint8Array.\n * @param val string or number[] or Uint8Array. If string, encoding must be hex. If number[], each value must be 0..255.\n * @param enc optional encoding type if val is string, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.\n * @param returnEnc optional encoding type for returned string if different from `enc`, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.\n * @returns hex encoded string representation of val.\n * @publicbody\n */\nexport function asString (\n  val: ByteInput,\n  enc?: ByteEncoding,\n  returnEnc?: ByteEncoding\n): string {\n  enc ||= 'hex'\n  returnEnc ||= enc\n  if (typeof val === 'string') {\n    if (enc === returnEnc) return val\n    val = asUint8Array(val, enc)\n  }\n  const v = Array.isArray(val) ? val : Array.from(val)\n  switch (returnEnc) {\n    case 'utf8':\n      return Utils.toUTF8(v)\n    case 'base64':\n      return Utils.toBase64(v)\n  }\n  return Utils.toHex(v)\n}\n\n/**\n * Convert a value to number[] if currently an encoded string or number[] or Uint8Array.\n * @param val string or number[] or Uint8Array. If string, encoding must be hex. If number[], each value must be 0..255.\n * @param enc optional encoding type if val is string, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.\n * @returns number[] array of byte values representation of val.\n * @publicbody\n */\nexport function asArray (val: ByteInput, enc?: ByteEncoding): number[] {\n  if (Array.isArray(val)) return val\n  if (typeof val !== 'string') return Array.from(val)\n  enc ||= 'hex'\n  const a: number[] = Utils.toArray(val, enc)\n  return a\n}\n\n/**\n * Convert a value to Uint8Array if currently an encoded string or number[] or Uint8Array.\n * @param val string or number[] or Uint8Array. If string, encoding must be hex. If number[], each value must be 0..255.\n * @param enc optional encoding type if val is string, defaults to 'hex'. Can be 'hex', 'utf8', or 'base64'.\n * @returns Uint8Array representation of val.\n * @publicbody\n */\nexport function asUint8Array (val: ByteInput, enc?: ByteEncoding): Uint8Array {\n  if (Array.isArray(val)) return Uint8Array.from(val)\n  if (typeof val !== 'string') return val\n  enc ||= 'hex'\n  return Utils.toUint8Array(val, enc)\n}\n","import {\n  HexString,\n  PubKeyHex,\n  WalletNetwork,\n  Beef,\n  Hash,\n  PrivateKey,\n  PublicKey,\n  Random,\n  Script,\n  Transaction,\n  Utils\n} from '@bsv/sdk'\nimport { Chain } from '../sdk/types'\nimport { asArray } from './utilityHelpers.noBuffer'\nimport { CertOpsWallet } from '../sdk/CertOpsWallet'\nimport { WERR_BAD_REQUEST, WERR_INTERNAL, WERR_INVALID_PARAMETER } from '../sdk/WERR_errors'\n\nexport async function getIdentityKey(wallet: CertOpsWallet): Promise<PubKeyHex> {\n  return (await wallet.getPublicKey({ identityKey: true })).publicKey\n}\n\nexport function toWalletNetwork(chain: Chain): WalletNetwork {\n  switch (chain) {\n    case 'main':\n      return 'mainnet'\n    case 'test':\n    case 'stn':\n    case 'ttn':\n    case 'tstn':\n    case 'mock':\n      return 'testnet'\n  }\n}\n\n/**\n * Maps a Chain to a network preset suitable for LookupResolver / SHIPBroadcaster.\n * Unlike `toWalletNetwork`, this returns `'local'` for `mock` chain.\n */\nexport function toLookupNetworkPreset(chain: Chain): 'mainnet' | 'testnet' | 'local' {\n  switch (chain) {\n    case 'main':\n      return 'mainnet'\n    case 'test':\n      return 'testnet'\n    case 'stn':\n    case 'ttn':\n    case 'tstn':\n    case 'mock':\n      return 'local'\n  }\n}\n\nexport function makeAtomicBeef(tx: Transaction, beef: number[] | Beef): number[] {\n  if (Array.isArray(beef)) beef = Beef.fromBinary(beef)\n  beef.mergeTransaction(tx)\n  return beef.toBinaryAtomic(tx.id('hex'))\n}\n\n/**\n * Coerce a bsv transaction encoded as a hex string, serialized array, or Transaction to Transaction\n * If tx is already a Transaction, just return it.\n * @publicbody\n */\nexport function asBsvSdkTx(tx: HexString | number[] | Transaction): Transaction {\n  if (Array.isArray(tx)) {\n    tx = Transaction.fromBinary(tx)\n  } else if (typeof tx === 'string') {\n    tx = Transaction.fromHex(tx)\n  }\n  return tx\n}\n\n/**\n * Coerce a bsv script encoded as a hex string, serialized array, or Script to Script\n * If script is already a Script, just return it.\n * @publicbody\n */\nexport function asBsvSdkScript(script: HexString | number[] | Script): Script {\n  if (Array.isArray(script)) {\n    script = Script.fromBinary(script)\n  } else if (typeof script === 'string') {\n    script = Script.fromHex(script)\n  }\n  return script\n}\n\n/**\n * @param privKey bitcoin private key in 32 byte hex string form\n * @returns @bsv/sdk PrivateKey\n */\nexport function asBsvSdkPrivateKey(privKey: string): PrivateKey {\n  return PrivateKey.fromString(privKey, 'hex')\n}\n\n/**\n * @param pubKey bitcoin public key in standard compressed key hex string form\n * @returns @bsv/sdk PublicKey\n */\nexport function asBsvSdkPublickKey(pubKey: string): PublicKey {\n  return PublicKey.fromString(pubKey)\n}\n\n/**\n * Helper function.\n *\n * Verifies that a possibly optional value has a value.\n */\nexport function verifyTruthy<T>(v: T | null | undefined, description?: string): T {\n  if (v == null) throw new WERR_INTERNAL(description ?? 'A truthy value is required.')\n  return v\n}\n\n/**\n * Helper function.\n *\n * Verifies that a hex string is trimmed and lower case.\n */\nexport function verifyHexString(v: string): string {\n  if (typeof v !== 'string') throw new WERR_INTERNAL('A string is required.')\n  v = v.trim().toLowerCase()\n  return v\n}\n\n/**\n * Helper function.\n *\n * Verifies that an optional or null hex string is undefined or a trimmed lowercase string.\n */\nexport function verifyOptionalHexString(v?: string | null): string | undefined {\n  if (v == null || v === '') return undefined\n  return verifyHexString(v)\n}\n\n/**\n * Helper function.\n *\n * Verifies that an optional or null number has a numeric value.\n */\nexport function verifyNumber(v: number | null | undefined): number {\n  if (typeof v !== 'number') throw new WERR_INTERNAL('A number is required.')\n  return v\n}\n\n/**\n * Helper function.\n *\n * Verifies that an optional or null number has a numeric value.\n */\nexport function verifyInteger(v: number | null | undefined): number {\n  if (typeof v !== 'number' || !Number.isInteger(v)) throw new WERR_INTERNAL('An integer is required.')\n  return v\n}\n\n/**\n * Helper function.\n *\n * Verifies that a database record identifier is an integer greater than zero.\n */\nexport function verifyId(id: number | undefined | null): number {\n  id = verifyInteger(id)\n  if (id < 1) throw new WERR_INTERNAL('id must be valid integer greater than zero.')\n  return id\n}\n\n/**\n * Helper function.\n *\n * @throws WERR_BAD_REQUEST if results has length greater than one.\n *\n * @returns results[0] or undefined if length is zero.\n */\nexport function verifyOneOrNone<T>(results: T[]): T | undefined {\n  if (results.length > 1) throw new WERR_BAD_REQUEST('Result must be unique.')\n  return results[0]\n}\n\n/**\n * Helper function.\n *\n * @throws WERR_BAD_REQUEST if results has length other than one.\n *\n * @returns results[0].\n */\nexport function verifyOne<T>(results: T[], errorDescrition?: string): T {\n  if (results.length !== 1) throw new WERR_BAD_REQUEST(errorDescrition ?? 'Result must exist and be unique.')\n  return results[0]\n}\n\n/**\n * Returns an await'able Promise that resolves in the given number of msecs.\n * @param msecs number of milliseconds to wait before resolving the promise.\n * Must be greater than zero and less than 2 minutes (120,000 msecs)\n * @publicbody\n */\nexport async function wait(msecs: number): Promise<void> {\n  const MIN_WAIT = 0\n  const MAX_WAIT = 2 * 60 * 1000 // maximum allowed wait in ms (2 minutes)\n  if (\n    typeof msecs !== 'number' ||\n    !Number.isFinite(msecs) ||\n    Number.isNaN(msecs) ||\n    msecs < MIN_WAIT ||\n    msecs > MAX_WAIT\n  ) {\n    throw new WERR_INVALID_PARAMETER('msecs', `a number between ${MIN_WAIT} and ${MAX_WAIT} msecs, not ${msecs}.`)\n  }\n  return await new Promise(resolve => setTimeout(resolve, msecs))\n}\n\n/**\n * @returns count cryptographically secure random bytes as array of bytes\n */\nexport function randomBytes(count: number): number[] {\n  return Random(count)\n}\n\n/**\n * @returns count cryptographically secure random bytes as hex encoded string\n */\nexport function randomBytesHex(count: number): string {\n  return Utils.toHex(Random(count))\n}\n\n/**\n * @returns count cryptographically secure random bytes as base64 encoded string\n */\nexport function randomBytesBase64(count: number): string {\n  return Utils.toBase64(Random(count))\n}\n\nexport function validateSecondsSinceEpoch(time: number): Date {\n  const date = new Date(time * 1000)\n  if (date.getTime() / 1000 !== time || time < 1600000000 || time > 100000000000) {\n    throw new WERR_INVALID_PARAMETER('time', 'valid \"since epoch\" unix time')\n  }\n  return date\n}\n\n/**\n * Compares lengths and direct equality of values.\n * @param arr1\n * @param arr2\n * @returns\n */\nexport function arraysEqual(arr1: number[], arr2: number[]): boolean {\n  if (arr1.length !== arr2.length) return false\n  for (let i = 0; i < arr1.length; i++) {\n    if (arr1[i] !== arr2[i]) return false\n  }\n  return true\n}\n\nexport function optionalArraysEqual(arr1?: number[], arr2?: number[]): boolean {\n  if (arr1 == null && arr2 == null) return true\n  if (arr1 == null || arr2 == null) return false\n  return arraysEqual(arr1, arr2)\n}\n\nexport function maxDate(d1?: Date, d2?: Date): Date | undefined {\n  if (d1 != null && d2 != null) {\n    if (d1 > d2) return d1\n    return d2\n  }\n  if (d1 != null) return d1\n  if (d2 != null) return d2\n  return undefined\n}\n\n/**\n * Calculate the SHA256 hash of an array of bytes\n * @returns sha256 hash of buffer contents.\n * @publicbody\n */\nexport function sha256Hash(data: number[] | Uint8Array): number[] {\n  if (!Array.isArray(data)) {\n    data = asArray(data)\n  }\n  const first = new Hash.SHA256().update(data).digest()\n  return first\n}\n\n/**\n * Calculate the SHA256 hash of the SHA256 hash of an array of bytes.\n * @param data an array of bytes\n * @returns double sha256 hash of data, byte 0 of hash first.\n * @publicbody\n */\nexport function doubleSha256LE(data: number[] | Uint8Array): number[] {\n  if (!Array.isArray(data)) {\n    data = asArray(data)\n  }\n  const first = new Hash.SHA256().update(data).digest()\n  const second = new Hash.SHA256().update(first).digest()\n  return second\n}\n\n/**\n * Calculate the SHA256 hash of the SHA256 hash of an array of bytes.\n * @param data is an array of bytes.\n * @returns reversed (big-endian) double sha256 hash of data, byte 31 of hash first.\n * @publicbody\n */\nexport function doubleSha256BE(data: number[] | Uint8Array): number[] {\n  return doubleSha256LE(data).reverse()\n}\n\n/**\n * Logging function to handle logging based on running in jest \"single test\" mode,\n *\n * @param {string} message - The main message to log.\n * @param {...any} optionalParams - Additional parameters to log (optional).\n */\nexport const logger = (message: string, ...optionalParams: any[]): void => {\n  const isSingleTest = process.argv.some(arg => arg === '--testNamePattern' || arg === '-t')\n  if (isSingleTest) {\n    console.log(message, ...optionalParams)\n  }\n}\n","import {\n  HexString,\n  KeyDeriverApi,\n  WalletProtocol,\n  ScriptTemplate,\n  ScriptTemplateUnlock,\n  LockingScript,\n  P2PKH,\n  PrivateKey,\n  PublicKey,\n  Script,\n  CachedKeyDeriver\n} from '@bsv/sdk'\nimport { verifyTruthy } from './utilityHelpers'\n\nexport const brc29ProtocolID: WalletProtocol = [2, '3241645161d8']\n\nexport interface ScriptTemplateParamsBRC29 {\n  derivationPrefix?: string\n  derivationSuffix?: string\n  keyDeriver: KeyDeriverApi\n}\n\n/**\n * Simple Authenticated BSV P2PKH Payment Protocol\n * https://brc.dev/29\n */\nexport class ScriptTemplateBRC29 implements ScriptTemplate {\n  p2pkh: P2PKH\n\n  constructor (public params: ScriptTemplateParamsBRC29) {\n    this.p2pkh = new P2PKH()\n\n    verifyTruthy(params.derivationPrefix)\n    verifyTruthy(params.derivationSuffix)\n  }\n\n  getKeyID (): string {\n    return `${this.params.derivationPrefix ?? ''} ${this.params.derivationSuffix ?? ''}`\n  }\n\n  getKeyDeriver (privKey: PrivateKey | HexString): KeyDeriverApi {\n    if (this.params.keyDeriver?.rootKey === privKey) return this.params.keyDeriver\n    if (typeof privKey === 'string') {\n      // The wallet signing path supplies its existing root key on every input.\n      // Avoid parsing the same hex key into a BigNumber for each template.\n      if (this.params.keyDeriver?.rootKey.toHex() === privKey) return this.params.keyDeriver\n      privKey = PrivateKey.fromHex(privKey)\n    }\n    if (this.params.keyDeriver == null || this.params.keyDeriver.rootKey.toHex() !== privKey.toHex()) { return new CachedKeyDeriver(privKey) }\n    return this.params.keyDeriver\n  }\n\n  lock (lockerPrivKey: string, unlockerPubKey: string): LockingScript {\n    const address = this.getKeyDeriver(lockerPrivKey)\n      .derivePublicKey(brc29ProtocolID, this.getKeyID(), unlockerPubKey, false)\n      .toAddress()\n    const r = this.p2pkh.lock(address)\n    return r\n  }\n\n  unlock (\n    unlockerPrivKey: PrivateKey | HexString,\n    lockerPubKey: PublicKey | string,\n    sourceSatoshis?: number,\n    lockingScript?: Script\n  ): ScriptTemplateUnlock {\n    const derivedPrivateKey = this.getKeyDeriver(unlockerPrivKey)\n      .derivePrivateKey(brc29ProtocolID, this.getKeyID(), lockerPubKey)\n    return this.unlockWithDerivedPrivateKey(derivedPrivateKey, sourceSatoshis, lockingScript)\n  }\n\n  unlockWithDerivedPrivateKey (\n    derivedPrivateKey: PrivateKey,\n    sourceSatoshis?: number,\n    lockingScript?: Script\n  ): ScriptTemplateUnlock {\n    return this.p2pkh.unlock(derivedPrivateKey, 'all', false, sourceSatoshis, lockingScript)\n  }\n\n  /**\n   * P2PKH unlock estimateLength is a constant\n   */\n  unlockLength = 108\n}\n","import { Utils as SdkUtils } from '@bsv/sdk'\n\nexport interface TxScriptOffsets {\n  inputs: Array<{ vin: number, offset: number, length: number }>\n  outputs: Array<{ vout: number, offset: number, length: number }>\n}\n\nexport function parseTxScriptOffsets (rawTx: number[] | Uint8Array): TxScriptOffsets {\n  const br = SdkUtils.ReaderUint8Array.makeReader(rawTx)\n  const inputs: Array<{ vin: number, offset: number, length: number }> = []\n  const outputs: Array<{ vout: number, offset: number, length: number }> = []\n\n  br.pos += 4 // version\n  const inputsLength = br.readVarIntNum()\n  for (let i = 0; i < inputsLength; i++) {\n    br.pos += 36 // txid and vout\n    const scriptLength = br.readVarIntNum()\n    inputs.push({ vin: i, offset: br.pos, length: scriptLength })\n    br.pos += scriptLength + 4 // script and sequence\n  }\n  const outputsLength = br.readVarIntNum()\n  for (let i = 0; i < outputsLength; i++) {\n    br.pos += 8 // satoshis\n    const scriptLength = br.readVarIntNum()\n    outputs.push({ vout: i, offset: br.pos, length: scriptLength })\n    br.pos += scriptLength\n  }\n  return { inputs, outputs }\n}\n","import { MerklePath } from '@bsv/sdk'\n\nexport interface TscMerkleProofApi {\n  height: number\n  index: number\n  nodes: string[]\n}\n\nexport function convertProofToMerklePath(txid: string, proof: TscMerkleProofApi): MerklePath {\n  const blockHeight = proof.height\n  const treeHeight = proof.nodes.length\n  interface Leaf {\n    offset: number\n    hash?: string\n    txid?: boolean\n    duplicate?: boolean\n  }\n  const path: Leaf[][] = Array.from({ length: treeHeight })\n    .fill(0)\n    .map(() => [])\n  let index = proof.index\n  for (let level = 0; level < treeHeight; level++) {\n    const node = proof.nodes[level]\n    const isOdd = index % 2 === 1\n    const offset = isOdd ? index - 1 : index + 1\n    const leaf: Leaf = { offset }\n    if (node === '*' || (level === 0 && node === txid)) {\n      leaf.duplicate = true\n    } else {\n      leaf.hash = node\n    }\n    path[level].push(leaf)\n    if (level === 0) {\n      const txidLeaf: Leaf = {\n        offset: proof.index,\n        hash: txid,\n        txid: true\n      }\n      if (isOdd) {\n        path[0].push(txidLeaf)\n      } else {\n        path[0].unshift(txidLeaf)\n      }\n    }\n    index = index >> 1\n  }\n  return new MerklePath(blockHeight, path)\n}\n","import { WERR_INVALID_PARAMETER } from '../sdk/WERR_errors'\n\nexport interface ParsedBrc114ActionTimeLabels {\n  from?: number\n  to?: number\n  timeFilterRequested: boolean\n  remainingLabels: string[]\n}\n\nconst FROM_PREFIX = 'action time from '\nconst TO_PREFIX = 'action time to '\n\nfunction parseActionTimeBound(label: string, prefix: string, bound: 'from' | 'to'): number {\n  const value = label.slice(prefix.length)\n  const invalid = `valid. Invalid action time ${bound} timestamp value.`\n  if (!/^\\d+$/.test(value)) throw new WERR_INVALID_PARAMETER('labels', invalid)\n  const timestamp = Number(value)\n  if (!Number.isSafeInteger(timestamp) || timestamp < 0) {\n    throw new WERR_INVALID_PARAMETER('labels', invalid)\n  }\n  if (Number.isNaN(new Date(timestamp).getTime())) {\n    throw new WERR_INVALID_PARAMETER('labels', invalid)\n  }\n  return timestamp\n}\n\nfunction setActionTimeBound(current: number | undefined, label: string, prefix: string, bound: 'from' | 'to'): number {\n  if (current !== undefined) {\n    throw new WERR_INVALID_PARAMETER('labels', `valid. Duplicate action time ${bound} label.`)\n  }\n  return parseActionTimeBound(label, prefix, bound)\n}\n\nexport function parseBrc114ActionTimeLabels(labels: string[] | undefined): ParsedBrc114ActionTimeLabels {\n  let from: number | undefined\n  let to: number | undefined\n  const remainingLabels: string[] = []\n  let timeFilterRequested = false\n\n  for (const label of labels ?? []) {\n    if (label.startsWith(FROM_PREFIX)) {\n      timeFilterRequested = true\n      from = setActionTimeBound(from, label, FROM_PREFIX, 'from')\n      continue\n    }\n\n    if (label.startsWith(TO_PREFIX)) {\n      timeFilterRequested = true\n      to = setActionTimeBound(to, label, TO_PREFIX, 'to')\n      continue\n    }\n\n    remainingLabels.push(label)\n  }\n\n  if (from !== undefined && to !== undefined && from >= to) {\n    throw new WERR_INVALID_PARAMETER('labels', 'valid. action time from must be less than action time to.')\n  }\n\n  return { from, to, timeFilterRequested, remainingLabels }\n}\n\nexport function makeBrc114ActionTimeLabel(unixMillis: number): string {\n  return `action time ${unixMillis}`\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { StorageProvider } from '../../StorageProvider'\n\nexport type EntityStorage = StorageProvider\n\nexport abstract class EntityBase<T> {\n  api: T\n\n  constructor (api: T) {\n    this.api = api\n  }\n\n  /**\n   * Standard property for entity database Id\n   */\n  abstract get id (): number\n\n  /**\n   * Name of derived entity class\n   */\n  abstract get entityName (): string\n\n  /**\n   * Schema table name of entity\n   */\n  abstract get entityTable (): string\n\n  /**\n   * On construction, an entity may decode properties of the `api` object,\n   * such as JSON stringified objects.\n   *\n   * The `updateApi` method must re-encode the current state of those decoded properties\n   * into the `api` object.\n   *\n   * Used by the `toApi` method to return an updated `api` object.\n   */\n  abstract updateApi (): void\n\n  /**\n   * Tests for equality or 'merge' / 'convergent' equality if syncMap is provided.\n   *\n   * 'convergent' equality must satisfy (A sync B) equals (B sync A)\n   *\n   * @param ei\n   * @param syncMap\n   */\n  abstract equals (ei: T, syncMap?: SyncMap): boolean\n\n  /**\n   * Perform a 'merge' / 'convergent' equality migration of state\n   * to this new local entity which was constructed\n   * as a copy of the external object.\n   *\n   * @param userId local userId\n   * @param syncMap\n   */\n  abstract mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void>\n\n  /**\n   * Perform a 'merge' / 'convergent' equality migration of state\n   * from external `ei` to this existing local EntityUser\n   *\n   * @param ei\n   * @param syncMap\n   * @returns true iff entity state changed and was updated to storage\n   */\n  abstract mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: T,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean>\n\n  /**\n   * An entity may decode properties of the underlying Api object on construction.\n   *\n   * The `toApi` method forces an `updateApi` before returning the underlying,\n   * now updated, Api object.\n   *\n   * @returns The underlying Api object with any entity decoded properties updated.\n   */\n  toApi (): T {\n    this.updateApi()\n    return this.api\n  }\n}\n\nexport interface EntitySyncMap {\n  entityName: string\n\n  /**\n   * Maps foreign ids to local ids\n   * Some entities don't have idMaps (CertificateField, TxLabelMap and OutputTagMap)\n   */\n  idMap: Record<number, number>\n\n  /**\n   * the maximum updated_at value seen for this entity over chunks received\n   * during this udpate cycle.\n   */\n  maxUpdated_at?: Date\n\n  /**\n   * The cummulative count of items of this entity type received over all the `SyncChunk`s\n   * since the `since` was last updated.\n   *\n   * This is the `offset` value to use for the next SyncChunk request.\n   */\n  count: number\n}\n\nexport interface SyncMap {\n  provenTx: EntitySyncMap\n  outputBasket: EntitySyncMap\n  transaction: EntitySyncMap\n  provenTxReq: EntitySyncMap\n  txLabel: EntitySyncMap\n  txLabelMap: EntitySyncMap\n  output: EntitySyncMap\n  outputTag: EntitySyncMap\n  outputTagMap: EntitySyncMap\n  certificate: EntitySyncMap\n  certificateField: EntitySyncMap\n  commission: EntitySyncMap\n}\n\nexport function createSyncMap (): SyncMap {\n  const r: SyncMap = {\n    provenTx: {\n      entityName: 'provenTx',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    outputBasket: {\n      entityName: 'outputBasket',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    transaction: {\n      entityName: 'transaction',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    provenTxReq: {\n      entityName: 'provenTxReq',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    txLabel: {\n      entityName: 'txLabel',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    txLabelMap: {\n      entityName: 'txLabelMap',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    output: {\n      entityName: 'output',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    outputTag: {\n      entityName: 'outputTag',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    outputTagMap: {\n      entityName: 'outputTagMap',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    certificate: {\n      entityName: 'certificate',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    certificateField: {\n      entityName: 'certificateField',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    },\n    commission: {\n      entityName: 'commission',\n      idMap: {},\n      maxUpdated_at: undefined,\n      count: 0\n    }\n  }\n  return r\n}\n\nexport interface SyncError {\n  code: string\n  description: string\n  stack?: string\n}\n","/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { TableCertificate } from '../tables/TableCertificate'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\n\nexport class EntityCertificate extends EntityBase<TableCertificate> {\n  constructor (api?: TableCertificate) {\n    const now = new Date()\n    super(\n      api || {\n        certificateId: 0,\n        created_at: now,\n        updated_at: now,\n        userId: 0,\n        type: '',\n        subject: '',\n        verifier: undefined,\n        serialNumber: '',\n        certifier: '',\n        revocationOutpoint: '',\n        signature: '',\n        isDeleted: false\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get certificateId () {\n    return this.api.certificateId\n  }\n\n  set certificateId (v: number) {\n    this.api.certificateId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get userId () {\n    return this.api.userId\n  }\n\n  set userId (v: number) {\n    this.api.userId = v\n  }\n\n  get type () {\n    return this.api.type\n  }\n\n  set type (v: string) {\n    this.api.type = v\n  }\n\n  get subject () {\n    return this.api.subject\n  }\n\n  set subject (v: string) {\n    this.api.subject = v\n  }\n\n  get verifier () {\n    return this.api.verifier\n  }\n\n  set verifier (v: string | undefined) {\n    this.api.verifier = v\n  }\n\n  get serialNumber () {\n    return this.api.serialNumber\n  }\n\n  set serialNumber (v: string) {\n    this.api.serialNumber = v\n  }\n\n  get certifier () {\n    return this.api.certifier\n  }\n\n  set certifier (v: string) {\n    this.api.certifier = v\n  }\n\n  get revocationOutpoint () {\n    return this.api.revocationOutpoint\n  }\n\n  set revocationOutpoint (v: string) {\n    this.api.revocationOutpoint = v\n  }\n\n  get signature () {\n    return this.api.signature\n  }\n\n  set signature (v: string) {\n    this.api.signature = v\n  }\n\n  get isDeleted () {\n    return this.api.isDeleted\n  }\n\n  set isDeleted (v: boolean) {\n    this.api.isDeleted = v\n  }\n\n  // get fields() { return this.api.fields }\n  // set fields(v: Record<string, string> | undefined) { this.api.fields = v }\n\n  override get id (): number {\n    return this.api.certificateId\n  }\n\n  override set id (v: number) {\n    this.api.certificateId = v\n  }\n\n  override get entityName (): string {\n    return 'certificate'\n  }\n\n  override get entityTable (): string {\n    return 'certificates'\n  }\n\n  override equals (ei: TableCertificate, syncMap?: SyncMap): boolean {\n    if (\n      this.type !== ei.type ||\n      this.subject !== ei.subject ||\n      this.serialNumber !== ei.serialNumber ||\n      this.revocationOutpoint !== ei.revocationOutpoint ||\n      this.signature !== ei.signature ||\n      this.verifier !== ei.verifier ||\n      this.isDeleted !== ei.isDeleted\n    ) { return false }\n\n    return true\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableCertificate,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityCertificate, eiId: number }> {\n    const ef = verifyOneOrNone(\n      await storage.findCertificates({\n        partial: {\n          serialNumber: ei.serialNumber,\n          certifier: ei.certifier,\n          userId\n        },\n        trx\n      })\n    )\n    return {\n      found: ef != null,\n      eo: new EntityCertificate(ef || { ...ei }),\n      eiId: verifyId(ei.certificateId)\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    this.userId = userId\n    this.certificateId = 0\n    this.certificateId = await storage.insertCertificate(this.toApi(), trx)\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableCertificate,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      this.type = ei.type\n      this.subject = ei.subject\n      this.serialNumber = ei.serialNumber\n      this.revocationOutpoint = ei.revocationOutpoint\n      this.signature = ei.signature\n      this.verifier = ei.verifier\n      this.isDeleted = ei.isDeleted\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateCertificate(this.id, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { WERR_INVALID_OPERATION } from '../../../sdk/WERR_errors'\nimport { verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { TableCertificateField } from '../tables/TableCertificateField'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\n\nexport class EntityCertificateField extends EntityBase<TableCertificateField> {\n  constructor (api?: TableCertificateField) {\n    const now = new Date()\n    super(\n      api || {\n        created_at: now,\n        updated_at: now,\n        userId: 0,\n        certificateId: 0,\n        fieldName: '',\n        fieldValue: '',\n        masterKey: ''\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get userId () {\n    return this.api.userId\n  }\n\n  set userId (v: number) {\n    this.api.userId = v\n  }\n\n  get certificateId () {\n    return this.api.certificateId\n  }\n\n  set certificateId (v: number) {\n    this.api.certificateId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get fieldName () {\n    return this.api.fieldName\n  }\n\n  set fieldName (v: string) {\n    this.api.fieldName = v\n  }\n\n  get fieldValue () {\n    return this.api.fieldValue\n  }\n\n  set fieldValue (v: string) {\n    this.api.fieldValue = v\n  }\n\n  get masterKey () {\n    return this.api.masterKey\n  }\n\n  set masterKey (v: string) {\n    this.api.masterKey = v\n  }\n\n  override get id (): number {\n    throw new WERR_INVALID_OPERATION('entity has no \"id\" value')\n  }\n\n  override get entityName (): string {\n    return 'certificateField'\n  }\n\n  override get entityTable (): string {\n    return 'certificate_fields'\n  }\n\n  override equals (ei: TableCertificateField, syncMap?: SyncMap | undefined): boolean {\n    return (\n      this.certificateId === ((syncMap != null) ? syncMap.certificate.idMap[ei.certificateId] : ei.certificateId) &&\n      this.fieldName === ei.fieldName &&\n      this.fieldValue === ei.fieldValue &&\n      this.masterKey === ei.masterKey\n    )\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableCertificateField,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityCertificateField, eiId: number }> {\n    const certificateId = syncMap.certificate.idMap[ei.certificateId]\n    const ef = verifyOneOrNone(\n      await storage.findCertificateFields({\n        partial: { certificateId, userId, fieldName: ei.fieldName },\n        trx\n      })\n    )\n    return {\n      found: ef != null,\n      eo: new EntityCertificateField(ef || { ...ei }),\n      eiId: -1\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    this.certificateId = syncMap.certificate.idMap[this.certificateId]\n    this.userId = userId\n    await storage.insertCertificateField(this.toApi(), trx)\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableCertificateField,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      this.fieldValue = ei.fieldValue\n      this.masterKey = ei.masterKey\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateCertificateField(this.certificateId, this.fieldName, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { arraysEqual, verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { TableCommission } from '../tables/TableCommission'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\n\nexport class EntityCommission extends EntityBase<TableCommission> {\n  constructor (api?: TableCommission) {\n    const now = new Date()\n    super(\n      api || {\n        commissionId: 0,\n        created_at: now,\n        updated_at: now,\n        transactionId: 0,\n        userId: 0,\n        isRedeemed: false,\n        keyOffset: '',\n        lockingScript: [],\n        satoshis: 0\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get commissionId () {\n    return this.api.commissionId\n  }\n\n  set commissionId (v: number) {\n    this.api.commissionId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get transactionId () {\n    return this.api.transactionId\n  }\n\n  set transactionId (v: number) {\n    this.api.transactionId = v\n  }\n\n  get userId () {\n    return this.api.userId\n  }\n\n  set userId (v: number) {\n    this.api.userId = v\n  }\n\n  get isRedeemed () {\n    return this.api.isRedeemed\n  }\n\n  set isRedeemed (v: boolean) {\n    this.api.isRedeemed = v\n  }\n\n  get keyOffset () {\n    return this.api.keyOffset\n  }\n\n  set keyOffset (v: string) {\n    this.api.keyOffset = v\n  }\n\n  get lockingScript () {\n    return this.api.lockingScript\n  }\n\n  set lockingScript (v: number[]) {\n    this.api.lockingScript = v\n  }\n\n  get satoshis () {\n    return this.api.satoshis\n  }\n\n  set satoshis (v: number) {\n    this.api.satoshis = v\n  }\n\n  override get id (): number {\n    return this.api.commissionId\n  }\n\n  override set id (v: number) {\n    this.api.commissionId = v\n  }\n\n  override get entityName (): string {\n    return 'commission'\n  }\n\n  override get entityTable (): string {\n    return 'commissions'\n  }\n\n  override equals (ei: TableCommission, syncMap?: SyncMap | undefined): boolean {\n    return (\n      this.isRedeemed === ei.isRedeemed &&\n      this.transactionId === ((syncMap != null) ? syncMap.transaction.idMap[ei.transactionId] : ei.transactionId) &&\n      this.keyOffset === ei.keyOffset &&\n      arraysEqual(this.lockingScript, ei.lockingScript) &&\n      this.satoshis === ei.satoshis\n    )\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableCommission,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityCommission, eiId: number }> {\n    const transactionId = syncMap.transaction.idMap[ei.transactionId]\n    const ef = verifyOneOrNone(await storage.findCommissions({ partial: { transactionId, userId }, trx }))\n    return {\n      found: ef != null,\n      eo: new EntityCommission(ef || { ...ei }),\n      eiId: verifyId(ei.commissionId)\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    if (this.transactionId) this.transactionId = syncMap.transaction.idMap[this.transactionId]\n    this.userId = userId\n    this.commissionId = 0\n    this.commissionId = await storage.insertCommission(this.toApi(), trx)\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableCommission,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      this.isRedeemed = ei.isRedeemed\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateCommission(this.id, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { StorageProvidedBy, TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { optionalArraysEqual, verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { TableOutput } from '../tables/TableOutput'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\n\nexport class EntityOutput extends EntityBase<TableOutput> {\n  constructor (api?: TableOutput) {\n    const now = new Date()\n    super(\n      api || {\n        outputId: 0,\n        created_at: now,\n        updated_at: now,\n        userId: 0,\n        transactionId: 0,\n        spendable: false,\n        change: false,\n        satoshis: 0,\n        outputDescription: '',\n        vout: 0,\n        type: '',\n        providedBy: 'you',\n        purpose: '',\n\n        txid: undefined,\n        basketId: undefined,\n        spentBy: undefined,\n        derivationPrefix: undefined,\n        derivationSuffix: undefined,\n        senderIdentityKey: undefined,\n        customInstructions: undefined,\n        spendingDescription: undefined,\n        scriptLength: undefined,\n        scriptOffset: undefined,\n        lockingScript: undefined\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get outputId () {\n    return this.api.outputId\n  }\n\n  set outputId (v: number) {\n    this.api.outputId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get userId () {\n    return this.api.userId\n  }\n\n  set userId (v: number) {\n    this.api.userId = v\n  }\n\n  get transactionId () {\n    return this.api.transactionId\n  }\n\n  set transactionId (v: number) {\n    this.api.transactionId = v\n  }\n\n  get basketId () {\n    return this.api.basketId\n  }\n\n  set basketId (v: number | undefined) {\n    this.api.basketId = v\n  }\n\n  get spentBy () {\n    return this.api.spentBy\n  }\n\n  set spentBy (v: number | undefined) {\n    this.api.spentBy = v\n  }\n\n  get vout () {\n    return this.api.vout\n  }\n\n  set vout (v: number) {\n    this.api.vout = v\n  }\n\n  get satoshis () {\n    return this.api.satoshis\n  }\n\n  set satoshis (v: number) {\n    this.api.satoshis = v\n  }\n\n  get outputDescription () {\n    return this.api.outputDescription\n  }\n\n  set outputDescription (v: string) {\n    this.api.outputDescription = v\n  }\n\n  get spendable () {\n    return this.api.spendable\n  }\n\n  set spendable (v: boolean) {\n    this.api.spendable = v\n  }\n\n  get change () {\n    return this.api.change\n  }\n\n  set change (v: boolean) {\n    this.api.change = v\n  }\n\n  get txid () {\n    return this.api.txid\n  }\n\n  set txid (v: string | undefined) {\n    this.api.txid = v\n  }\n\n  get type () {\n    return this.api.type\n  }\n\n  set type (v: string) {\n    this.api.type = v\n  }\n\n  get providedBy () {\n    return this.api.providedBy\n  }\n\n  set providedBy (v: StorageProvidedBy) {\n    this.api.providedBy = v\n  }\n\n  get purpose () {\n    return this.api.purpose\n  }\n\n  set purpose (v: string) {\n    this.api.purpose = v\n  }\n\n  get spendingDescription () {\n    return this.api.spendingDescription\n  }\n\n  set spendingDescription (v: string | undefined) {\n    this.api.spendingDescription = v\n  }\n\n  get derivationPrefix () {\n    return this.api.derivationPrefix\n  }\n\n  set derivationPrefix (v: string | undefined) {\n    this.api.derivationPrefix = v\n  }\n\n  get derivationSuffix () {\n    return this.api.derivationSuffix\n  }\n\n  set derivationSuffix (v: string | undefined) {\n    this.api.derivationSuffix = v\n  }\n\n  get senderIdentityKey () {\n    return this.api.senderIdentityKey\n  }\n\n  set senderIdentityKey (v: string | undefined) {\n    this.api.senderIdentityKey = v\n  }\n\n  get customInstructions () {\n    return this.api.customInstructions\n  }\n\n  set customInstructions (v: string | undefined) {\n    this.api.customInstructions = v\n  }\n\n  get lockingScript () {\n    return this.api.lockingScript\n  }\n\n  set lockingScript (v: number[] | undefined) {\n    this.api.lockingScript = v\n  }\n\n  get scriptLength () {\n    return this.api.scriptLength\n  }\n\n  set scriptLength (v: number | undefined) {\n    this.api.scriptLength = v\n  }\n\n  get scriptOffset () {\n    return this.api.scriptOffset\n  }\n\n  set scriptOffset (v: number | undefined) {\n    this.api.scriptOffset = v\n  }\n\n  override get id (): number {\n    return this.api.outputId\n  }\n\n  override set id (v: number) {\n    this.api.outputId = v\n  }\n\n  override get entityName (): string {\n    return 'output'\n  }\n\n  override get entityTable (): string {\n    return 'outputs'\n  }\n\n  override equals (ei: TableOutput, syncMap?: SyncMap | undefined): boolean {\n    return (\n      this.transactionId === ((syncMap != null) ? syncMap.transaction.idMap[ei.transactionId] : ei.transactionId) &&\n      this.basketId === ((syncMap != null) && ei.basketId ? syncMap.outputBasket.idMap[ei.basketId] : ei.basketId) &&\n      this.spentBy === ((syncMap != null) && ei.spentBy ? syncMap.transaction.idMap[ei.spentBy] : ei.spentBy) &&\n      this.vout === ei.vout &&\n      this.satoshis === ei.satoshis &&\n      this.spendable === ei.spendable &&\n      this.change === ei.change &&\n      this.txid === ei.txid &&\n      this.type === ei.type &&\n      this.providedBy === ei.providedBy &&\n      this.purpose === ei.purpose &&\n      this.outputDescription === ei.outputDescription &&\n      this.spendingDescription === ei.spendingDescription &&\n      this.derivationPrefix === ei.derivationPrefix &&\n      this.derivationSuffix === ei.derivationSuffix &&\n      this.senderIdentityKey === ei.senderIdentityKey &&\n      this.customInstructions === ei.customInstructions &&\n      optionalArraysEqual(this.lockingScript, ei.lockingScript) &&\n      this.scriptLength === ei.scriptLength &&\n      this.scriptOffset === ei.scriptOffset\n    )\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableOutput,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityOutput, eiId: number }> {\n    const transactionId = syncMap.transaction.idMap[ei.transactionId]\n    const ef = verifyOneOrNone(\n      await storage.findOutputs({\n        partial: { userId, transactionId, vout: ei.vout },\n        trx\n      })\n    )\n    return {\n      found: ef != null,\n      eo: new EntityOutput(ef || { ...ei }),\n      eiId: verifyId(ei.outputId)\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    this.userId = userId\n    this.basketId = this.basketId ? syncMap.outputBasket.idMap[this.basketId] : undefined\n    this.transactionId = syncMap.transaction.idMap[this.transactionId]\n    this.spentBy = this.spentBy ? syncMap.transaction.idMap[this.spentBy] : undefined\n    this.outputId = 0\n    this.outputId = await storage.insertOutput(this.toApi(), trx)\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableOutput,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      this.spentBy = ei.spentBy ? syncMap.transaction.idMap[ei.spentBy] : undefined\n      this.spendable = ei.spendable\n      this.change = ei.change\n      this.type = ei.type\n      this.providedBy = ei.providedBy\n      this.purpose = ei.purpose\n      this.outputDescription = ei.outputDescription\n      this.spendingDescription = ei.spendingDescription\n      this.senderIdentityKey = ei.senderIdentityKey\n      this.customInstructions = ei.customInstructions\n      this.scriptLength = ei.scriptLength\n      this.scriptOffset = ei.scriptOffset\n      this.lockingScript = ei.lockingScript\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateOutput(this.id, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { TableOutputBasket } from '../tables/TableOutputBasket'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\n\nexport class EntityOutputBasket extends EntityBase<TableOutputBasket> {\n  constructor (api?: TableOutputBasket) {\n    const now = new Date()\n    super(\n      api || {\n        basketId: 0,\n        created_at: now,\n        updated_at: now,\n        userId: 0,\n        name: '',\n        numberOfDesiredUTXOs: 0,\n        minimumDesiredUTXOValue: 0,\n        isDeleted: false\n      }\n    )\n  }\n\n  get basketId () {\n    return this.api.basketId\n  }\n\n  set basketId (v: number) {\n    this.api.basketId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get userId () {\n    return this.api.userId\n  }\n\n  set userId (v: number) {\n    this.api.userId = v\n  }\n\n  get name () {\n    return this.api.name\n  }\n\n  set name (v: string) {\n    this.api.name = v\n  }\n\n  get numberOfDesiredUTXOs () {\n    return this.api.numberOfDesiredUTXOs\n  }\n\n  set numberOfDesiredUTXOs (v: number) {\n    this.api.numberOfDesiredUTXOs = v\n  }\n\n  get minimumDesiredUTXOValue () {\n    return this.api.minimumDesiredUTXOValue\n  }\n\n  set minimumDesiredUTXOValue (v: number) {\n    this.api.minimumDesiredUTXOValue = v\n  }\n\n  get isDeleted () {\n    return this.api.isDeleted\n  }\n\n  set isDeleted (v: boolean) {\n    this.api.isDeleted = v\n  }\n\n  override get id () {\n    return this.api.basketId\n  }\n\n  override set id (v: number) {\n    this.api.basketId = v\n  }\n\n  override get entityName (): string {\n    return 'outputBasket'\n  }\n\n  override get entityTable (): string {\n    return 'output_baskets'\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  override equals (ei: TableOutputBasket, syncMap?: SyncMap): boolean {\n    const eo = this.api\n    if (\n      eo.name != ei.name ||\n      eo.numberOfDesiredUTXOs != ei.numberOfDesiredUTXOs ||\n      eo.minimumDesiredUTXOValue != ei.minimumDesiredUTXOValue\n    ) { return false }\n    if (syncMap != null) {\n      if (eo.basketId !== syncMap.outputBasket.idMap[verifyId(ei.basketId)]) return false\n    } else if (eo.basketId !== ei.basketId || eo.userId !== ei.userId) {\n      return false\n    }\n    return true\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableOutputBasket,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityOutputBasket, eiId: number }> {\n    const ef = verifyOneOrNone(\n      await storage.findOutputBaskets({\n        partial: { name: ei.name, userId },\n        trx\n      })\n    )\n    return {\n      found: ef != null,\n      eo: new EntityOutputBasket(ef || { ...ei }),\n      eiId: verifyId(ei.basketId)\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    this.userId = userId\n    this.name ||= 'default'\n    this.basketId = 0\n    this.basketId = await storage.insertOutputBasket(this.toApi(), trx)\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableOutputBasket,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      // basket name is its identity, should not change\n      this.minimumDesiredUTXOValue = ei.minimumDesiredUTXOValue\n      this.numberOfDesiredUTXOs = ei.numberOfDesiredUTXOs\n      this.isDeleted = ei.isDeleted\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateOutputBasket(this.id, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { TableOutputTag } from '../tables/TableOutputTag'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\n\nexport class EntityOutputTag extends EntityBase<TableOutputTag> {\n  constructor (api?: TableOutputTag) {\n    const now = new Date()\n    super(\n      api || {\n        outputTagId: 0,\n        created_at: now,\n        updated_at: now,\n        tag: '',\n        userId: 0,\n        isDeleted: false\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get outputTagId () {\n    return this.api.outputTagId\n  }\n\n  set outputTagId (v: number) {\n    this.api.outputTagId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get tag () {\n    return this.api.tag\n  }\n\n  set tag (v: string) {\n    this.api.tag = v\n  }\n\n  get userId () {\n    return this.api.userId\n  }\n\n  set userId (v: number) {\n    this.api.userId = v\n  }\n\n  get isDeleted () {\n    return this.api.isDeleted\n  }\n\n  set isDeleted (v: boolean) {\n    this.api.isDeleted = v\n  }\n\n  override get id (): number {\n    return this.api.outputTagId\n  }\n\n  override set id (v: number) {\n    this.api.outputTagId = v\n  }\n\n  override get entityName (): string {\n    return 'outputTag'\n  }\n\n  override get entityTable (): string {\n    return 'output_tags'\n  }\n\n  override equals (ei: TableOutputTag, syncMap?: SyncMap | undefined): boolean {\n    const eo = this.toApi()\n    if (eo.tag != ei.tag || eo.isDeleted != ei.isDeleted) return false\n    if (syncMap == null) {\n      if (eo.userId !== ei.userId) return false\n    }\n    return true\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableOutputTag,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityOutputTag, eiId: number }> {\n    const ef = verifyOneOrNone(await storage.findOutputTags({ partial: { tag: ei.tag, userId }, trx }))\n    return {\n      found: ef != null,\n      eo: new EntityOutputTag(ef || { ...ei }),\n      eiId: verifyId(ei.outputTagId)\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    this.userId = userId\n    this.outputTagId = 0\n    this.outputTagId = await storage.insertOutputTag(this.toApi(), trx)\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableOutputTag,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      this.isDeleted = ei.isDeleted\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateOutputTag(this.id, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { WERR_INVALID_OPERATION } from '../../../sdk/WERR_errors'\nimport { verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { TableOutputTagMap } from '../tables/TableOutputTagMap'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\n\nexport class EntityOutputTagMap extends EntityBase<TableOutputTagMap> {\n  constructor (api?: TableOutputTagMap) {\n    const now = new Date()\n    super(\n      api || {\n        created_at: now,\n        updated_at: now,\n        outputId: 0,\n        outputTagId: 0,\n        isDeleted: false\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get outputTagId () {\n    return this.api.outputTagId\n  }\n\n  set outputTagId (v: number) {\n    this.api.outputTagId = v\n  }\n\n  get outputId () {\n    return this.api.outputId\n  }\n\n  set outputId (v: number) {\n    this.api.outputId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get isDeleted () {\n    return this.api.isDeleted\n  }\n\n  set isDeleted (v: boolean) {\n    this.api.isDeleted = v\n  }\n\n  override get id (): number {\n    throw new WERR_INVALID_OPERATION('entity has no \"id\" value')\n  }\n\n  override get entityName (): string {\n    return 'outputTagMap'\n  }\n\n  override get entityTable (): string {\n    return 'output_tags_map'\n  }\n\n  override equals (ei: TableOutputTagMap, syncMap?: SyncMap | undefined): boolean {\n    const eo = this.toApi()\n\n    return (\n      eo.outputId === ((syncMap != null) ? syncMap.output.idMap[verifyId(ei.outputId)] : ei.outputId) &&\n      eo.outputTagId === ((syncMap != null) ? syncMap.outputTag.idMap[verifyId(ei.outputTagId)] : ei.outputTagId) &&\n      eo.isDeleted === ei.isDeleted\n    )\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableOutputTagMap,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityOutputTagMap, eiId: number }> {\n    const outputId = syncMap.output.idMap[ei.outputId]\n    const outputTagId = syncMap.outputTag.idMap[ei.outputTagId]\n    const ef = verifyOneOrNone(\n      await storage.findOutputTagMaps({\n        partial: { outputId, outputTagId },\n        trx\n      })\n    )\n    return {\n      found: ef != null,\n      eo: new EntityOutputTagMap(ef || { ...ei }),\n      eiId: -1\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    this.outputId = syncMap.output.idMap[this.outputId]\n    this.outputTagId = syncMap.outputTag.idMap[this.outputTagId]\n    await storage.insertOutputTagMap(this.toApi(), trx)\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableOutputTagMap,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      this.isDeleted = ei.isDeleted\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateOutputTagMap(this.outputId, this.outputTagId, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { GetMerklePathResult, WalletServices } from '../../../sdk/WalletServices.interfaces'\nimport { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { arraysEqual, verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { TableProvenTx } from '../tables/TableProvenTx'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\nimport { MerklePath } from '@bsv/sdk'\nimport { EntityProvenTxReq } from './EntityProvenTxReq'\nimport { WERR_INTERNAL, WERR_MISSING_PARAMETER } from '../../../sdk/WERR_errors'\nimport { WalletError } from '../../../sdk/WalletError'\n\nexport class EntityProvenTx extends EntityBase<TableProvenTx> {\n  /**\n   * Given a txid and optionally its rawTx, create a new ProvenTx object.\n   *\n   * rawTx is fetched if not provided.\n   *\n   * Only succeeds (proven is not undefined) if a proof is confirmed for rawTx,\n   * and hash of rawTx is confirmed to match txid\n   *\n   * The returned ProvenTx and ProvenTxReq objects have not been added to the storage database,\n   * this is optional and can be done by the caller if appropriate.\n   *\n   * @param txid\n   * @param services\n   * @param rawTx\n   * @returns\n   */\n  static async fromTxid(txid: string, services: WalletServices, rawTx?: number[]): Promise<ProvenTxFromTxidResult> {\n    const r: ProvenTxFromTxidResult = { proven: undefined, rawTx }\n\n    if (r.rawTx == null) {\n      const gr = await services.getRawTx(txid)\n      if (gr?.rawTx == null)\n      // Failing to find anything...\n      {\n        return r\n      }\n      r.rawTx = gr.rawTx!\n    }\n\n    const gmpr = await services.getMerklePath(txid)\n\n    if (gmpr.merklePath != null && gmpr.header != null) {\n      const index = gmpr.merklePath.path[0].find(l => l.hash === txid)?.offset\n      if (index !== undefined) {\n        const api: TableProvenTx = {\n          created_at: new Date(),\n          updated_at: new Date(),\n          provenTxId: 0,\n          txid,\n          height: gmpr.header.height,\n          index,\n          merklePath: gmpr.merklePath.toBinary(),\n          rawTx: r.rawTx,\n          blockHash: gmpr.header.hash,\n          merkleRoot: gmpr.header.merkleRoot\n        }\n        r.proven = new EntityProvenTx(api)\n      }\n    }\n\n    return r\n  }\n\n  constructor(api?: TableProvenTx) {\n    const now = new Date()\n    super(\n      api || {\n        provenTxId: 0,\n        created_at: now,\n        updated_at: now,\n        txid: '',\n        height: 0,\n        index: 0,\n        merklePath: [],\n        rawTx: [],\n        blockHash: '',\n        merkleRoot: ''\n      }\n    )\n  }\n\n  override updateApi(): void {\n    /* nothing needed yet... */\n  }\n\n  /**\n   * @returns desirialized `MerklePath` object, value is cached.\n   */\n  getMerklePath(validateRoots: boolean = true): MerklePath {\n    if (validateRoots) {\n      this._mp ??= MerklePath.fromBinary(this.api.merklePath)\n      return this._mp\n    }\n    this._mpUnchecked ??= MerklePath.fromBinary(this.api.merklePath, true, false)\n    return this._mpUnchecked\n  }\n\n  _mp?: MerklePath\n  _mpUnchecked?: MerklePath\n\n  get provenTxId() {\n    return this.api.provenTxId\n  }\n\n  set provenTxId(v: number) {\n    this.api.provenTxId = v\n  }\n\n  get created_at() {\n    return this.api.created_at\n  }\n\n  set created_at(v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at() {\n    return this.api.updated_at\n  }\n\n  set updated_at(v: Date) {\n    this.api.updated_at = v\n  }\n\n  get txid() {\n    return this.api.txid\n  }\n\n  set txid(v: string) {\n    this.api.txid = v\n  }\n\n  get height() {\n    return this.api.height\n  }\n\n  set height(v: number) {\n    this.api.height = v\n  }\n\n  get index() {\n    return this.api.index\n  }\n\n  set index(v: number) {\n    this.api.index = v\n  }\n\n  get merklePath() {\n    return this.api.merklePath\n  }\n\n  set merklePath(v: number[]) {\n    this.api.merklePath = v\n  }\n\n  get rawTx() {\n    return this.api.rawTx\n  }\n\n  set rawTx(v: number[]) {\n    this.api.rawTx = v\n  }\n\n  get blockHash() {\n    return this.api.blockHash\n  }\n\n  set blockHash(v: string) {\n    this.api.blockHash = v\n  }\n\n  get merkleRoot() {\n    return this.api.merkleRoot\n  }\n\n  set merkleRoot(v: string) {\n    this.api.merkleRoot = v\n  }\n\n  override get id() {\n    return this.api.provenTxId\n  }\n\n  override set id(v: number) {\n    this.api.provenTxId = v\n  }\n\n  override get entityName(): string {\n    return 'provenTx'\n  }\n\n  override get entityTable(): string {\n    return 'proven_txs'\n  }\n\n  override equals(ei: TableProvenTx, syncMap?: SyncMap | undefined): boolean {\n    const eo = this.toApi()\n    if (\n      eo.txid != ei.txid ||\n      eo.height != ei.height ||\n      eo.index != ei.index ||\n      !arraysEqual(eo.merklePath, ei.merklePath) ||\n      !arraysEqual(eo.rawTx, ei.rawTx) ||\n      eo.blockHash !== ei.blockHash ||\n      eo.merkleRoot !== ei.merkleRoot\n      // equality does not depend on timestamps.\n      // || eo.created_at !== ei.created_at\n      // || eo.updated_at !== ei.updated_at\n    ) {\n      return false\n    }\n    if (syncMap != null) {\n      if (eo.provenTxId !== syncMap.provenTx.idMap[ei.provenTxId]) return false\n    } else if (eo.provenTxId !== ei.provenTxId) {\n      return false\n    }\n    return true\n  }\n\n  static async mergeFind(\n    storage: EntityStorage,\n    userId: number,\n    ei: TableProvenTx,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean; eo: EntityProvenTx; eiId: number }> {\n    const ef = verifyOneOrNone(await storage.findProvenTxs({ partial: { txid: ei.txid }, trx }))\n    return {\n      found: ef != null,\n      eo: new EntityProvenTx(ef || { ...ei }),\n      eiId: verifyId(ei.provenTxId)\n    }\n  }\n\n  override async mergeNew(storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    this.provenTxId = 0\n    // Since these records are a shared resource, the record should be validated before accepting it\n    this.provenTxId = await storage.insertProvenTx(this.toApi(), trx)\n  }\n\n  override async mergeExisting(\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableProvenTx,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    // ProvenTxs are never updated.\n    return false\n  }\n\n  /**\n   * How high attempts can go before status is forced to invalid\n   */\n  static readonly getProofAttemptsLimit = 8\n\n  /**\n   * How many hours we have to try for a poof\n   */\n  static readonly getProofMinutes = 60\n\n  private static applyProofTimeoutIfExpired(req: EntityProvenTxReq, maxRebroadcastAttempts: number): void {\n    if (req.created_at == null) return\n    const ageInMsecs = Date.now() - req.created_at.getTime()\n    const ageInMinutes = Math.ceil(ageInMsecs < 1 ? 0 : ageInMsecs / (1000 * 60))\n    if (req.attempts <= EntityProvenTx.getProofAttemptsLimit) return\n    if (ageInMinutes <= EntityProvenTx.getProofMinutes) return\n\n    const limit = EntityProvenTx.getProofAttemptsLimit\n    const { attempts } = req\n    req.addHistoryNote({ what: 'getMerklePathGiveUp', attempts, limit, ageInMinutes }, true)\n    req.applyProofTimeout(maxRebroadcastAttempts)\n  }\n\n  private static createFromProof(\n    req: EntityProvenTxReq,\n    gmpResult: GetMerklePathResult,\n    proof: MerklePath\n  ): EntityProvenTx {\n    const leaf = proof.path[0].find(candidate => candidate.txid === true && candidate.hash === req.txid)\n    if (leaf == null) {\n      req.addHistoryNote({ what: 'getMerklePathTxidNotFound' }, true)\n      throw new WERR_INTERNAL('merkle path does not contain leaf for txid')\n    }\n    const now = new Date()\n    return new EntityProvenTx({\n      created_at: now,\n      updated_at: now,\n      provenTxId: 0,\n      txid: req.txid!,\n      height: proof.blockHeight,\n      index: leaf.offset,\n      merklePath: proof.toBinary(),\n      rawTx: req.rawTx!,\n      merkleRoot: gmpResult.header!.merkleRoot,\n      blockHash: gmpResult.header!.hash\n    })\n  }\n\n  private static recordProofError(req: EntityProvenTxReq, error: unknown): void {\n    const { code, description } = WalletError.fromUnknown(error)\n    const { attempts } = req\n    req.addHistoryNote({ what: 'getMerklePathProvenError', attempts, code, description }, true)\n  }\n\n  /**\n   * Try to create a new ProvenTx from a ProvenTxReq and GetMerkleProofResultApi\n   *\n   * Otherwise it returns undefined and updates req.status to either 'unknown', 'invalid', or 'unconfirmed'\n   *\n   * @param req\n   * @param gmpResult\n   * @returns\n   */\n  static async fromReq(\n    req: EntityProvenTxReq,\n    gmpResult: GetMerklePathResult,\n    countsAsAttempt: boolean,\n    maxRebroadcastAttempts = 0\n  ): Promise<EntityProvenTx | undefined> {\n    if (!req.txid) throw new WERR_MISSING_PARAMETER('req.txid')\n    if (!req.rawTx) throw new WERR_MISSING_PARAMETER('req.rawTx')\n\n    if (!req.rawTx) throw new WERR_INTERNAL('rawTx must be valid')\n\n    for (const note of gmpResult.notes || []) {\n      req.addHistoryNote(note, true)\n    }\n\n    if (!gmpResult.name && gmpResult.merklePath == null && gmpResult.error == null) {\n      // Most likely offline or now services configured.\n      // Does not count as a proof attempt.\n      return undefined\n    }\n\n    if (gmpResult.merklePath == null) {\n      EntityProvenTx.applyProofTimeoutIfExpired(req, maxRebroadcastAttempts)\n      return undefined\n    }\n\n    if (countsAsAttempt) req.attempts++\n\n    const merklePaths = Array.isArray(gmpResult.merklePath) ? gmpResult.merklePath : [gmpResult.merklePath]\n\n    for (const proof of merklePaths) {\n      try {\n        return EntityProvenTx.createFromProof(req, gmpResult, proof)\n      } catch (error: unknown) {\n        EntityProvenTx.recordProofError(req, error)\n      }\n    }\n  }\n}\n\nexport interface ProvenTxFromTxidResult {\n  proven?: EntityProvenTx\n  rawTx?: number[]\n}\n","import { ProvenTxReqStatus, ProvenTxReqTerminalStatus, ReqHistoryNote } from '../../../sdk/types'\nimport { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { WERR_INTERNAL, WERR_INVALID_PARAMETER } from '../../../sdk/WERR_errors'\nimport { arraysEqual, verifyId, verifyOne, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { StorageProvider } from '../../StorageProvider'\nimport { WalletStorageManager } from '../../WalletStorageManager'\nimport { TableProvenTxReq, TableProvenTxReqDynamics } from '../tables/TableProvenTxReq'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\n\nexport class EntityProvenTxReq extends EntityBase<TableProvenTxReq> {\n  static readonly wasBroadcastStatuses: ProvenTxReqStatus[] = ['unmined', 'callback', 'unconfirmed', 'completed']\n\n  static async fromStorageTxid(\n    storage: EntityStorage,\n    txid: string,\n    trx?: TrxToken\n  ): Promise<EntityProvenTxReq | undefined> {\n    const reqApi = verifyOneOrNone(await storage.findProvenTxReqs({ partial: { txid }, trx }))\n    if (reqApi == null) return undefined\n    return new EntityProvenTxReq(reqApi)\n  }\n\n  static async fromStorageId(storage: EntityStorage, id: number, trx?: TrxToken): Promise<EntityProvenTxReq> {\n    const reqApi = verifyOneOrNone(await storage.findProvenTxReqs({ partial: { provenTxReqId: id }, trx }))\n    if (reqApi == null) throw new WERR_INTERNAL(`proven_tx_reqs with id ${id} is missing.`)\n    return new EntityProvenTxReq(reqApi)\n  }\n\n  static fromTxid(\n    txid: string,\n    rawTx: number[] | Uint8Array,\n    inputBEEF?: number[] | Uint8Array\n  ): EntityProvenTxReq {\n    const now = new Date()\n    return new EntityProvenTxReq({\n      provenTxReqId: 0,\n      created_at: now,\n      updated_at: now,\n      txid,\n      // Storage adapters accept typed byte arrays without boxing. The public\n      // table shape remains number[] for backwards-compatible sync payloads.\n      inputBEEF: inputBEEF as number[] | undefined,\n      rawTx: rawTx as number[],\n      status: 'unknown',\n      history: '{}',\n      notify: '{}',\n      attempts: 0,\n      notified: false\n    })\n  }\n\n  history: ProvenTxReqHistory\n  notify: ProvenTxReqNotify\n\n  packApiHistory() {\n    this.api.history = JSON.stringify(this.history)\n  }\n\n  packApiNotify() {\n    this.api.notify = JSON.stringify(this.notify)\n  }\n\n  unpackApiHistory() {\n    this.history = JSON.parse(this.api.history)\n  }\n\n  unpackApiNotify() {\n    this.notify = JSON.parse(this.api.notify)\n  }\n\n  get apiHistory(): string {\n    this.packApiHistory()\n    return this.api.history\n  }\n\n  get apiNotify(): string {\n    this.packApiNotify()\n    return this.api.notify\n  }\n\n  set apiHistory(v: string) {\n    this.api.history = v\n    this.unpackApiHistory()\n  }\n\n  set apiNotify(v: string) {\n    this.api.notify = v\n    this.unpackApiNotify()\n  }\n\n  updateApi(): void {\n    this.packApiHistory()\n    this.packApiNotify()\n  }\n\n  unpackApi(): void {\n    this.unpackApiHistory()\n    this.unpackApiNotify()\n    if (this.notify.transactionIds != null) {\n      // Cleanup null values and duplicates.\n      const transactionIds: number[] = []\n      for (const id of this.notify.transactionIds) {\n        if (Number.isInteger(id) && !transactionIds.includes(id)) transactionIds.push(id)\n      }\n      this.notify.transactionIds = transactionIds\n    }\n  }\n\n  async refreshFromStorage(storage: EntityStorage | WalletStorageManager, trx?: TrxToken): Promise<void> {\n    const newApi = verifyOne(await storage.findProvenTxReqs({ partial: { provenTxReqId: this.id }, trx }))\n    this.api = newApi\n    this.unpackApi()\n  }\n\n  constructor(api?: TableProvenTxReq) {\n    const now = new Date()\n    super(\n      api || {\n        provenTxReqId: 0,\n        created_at: now,\n        updated_at: now,\n        txid: '',\n        rawTx: [],\n        history: '',\n        notify: '',\n        attempts: 0,\n        status: 'unknown',\n        notified: false\n      }\n    )\n    this.history = {}\n    this.notify = {}\n    this.unpackApi()\n  }\n\n  /**\n   * Returns history to only what followed since date.\n   */\n  historySince(since: Date): ProvenTxReqHistory {\n    const fh: ProvenTxReqHistory = { notes: [] }\n    const filter = since.toISOString()\n    const notes = this.history.notes\n    if (notes != null && fh.notes != null) {\n      for (const note of notes) if (note.when && note.when > filter) fh.notes.push(note)\n    }\n    return fh\n  }\n\n  historyPretty(since?: Date, _indent = 0): string {\n    const h = since != null ? this.historySince(since) : { ...this.history }\n    if (h.notes == null) return ''\n    const whenLimit = since != null ? since.toISOString() : undefined\n    let log = ''\n    for (const note of h.notes) {\n      if (whenLimit && note.when && note.when < whenLimit) continue\n      log += this.prettyNote(note) + '\\n'\n    }\n    return log\n  }\n\n  prettyNote(note: ReqHistoryNote): string {\n    let log = `${note.when}: ${note.what}`\n    for (const [key, val] of Object.entries(note)) {\n      if (key !== 'when' && key !== 'what') {\n        if (typeof val === 'string') log += ' ' + key + ':`' + val + '`'\n        else log += ' ' + key + ':' + val\n      }\n    }\n    return log\n  }\n\n  getHistorySummary(): ProvenTxReqHistorySummaryApi {\n    const summary: ProvenTxReqHistorySummaryApi = {\n      setToCompleted: false,\n      setToUnmined: false,\n      setToCallback: false,\n      setToDoubleSpend: false,\n      setToSending: false,\n      setToUnconfirmed: false\n    }\n    const h = this.history\n    if (h.notes != null) {\n      for (const note of h.notes) {\n        this.parseHistoryNote(note, summary)\n      }\n    }\n    return summary\n  }\n\n  parseHistoryNote(note: ReqHistoryNote, summary?: ProvenTxReqHistorySummaryApi): string {\n    const c = summary || {\n      setToCompleted: false,\n      setToUnmined: false,\n      setToCallback: false,\n      setToDoubleSpend: false,\n      setToSending: false,\n      setToUnconfirmed: false\n    }\n    const n = this.prettyNote(note)\n    try {\n      if (note.what === 'status') {\n        const status = note.status_now as ProvenTxReqStatus\n        switch (status) {\n          case 'completed':\n            c.setToCompleted = true\n            break\n          case 'unmined':\n            c.setToUnmined = true\n            break\n          case 'callback':\n            c.setToCallback = true\n            break\n          case 'doubleSpend':\n            c.setToDoubleSpend = true\n            break\n          case 'sending':\n            c.setToSending = true\n            break\n          case 'unconfirmed':\n            c.setToUnconfirmed = true\n            break\n          default:\n            break\n        }\n      }\n    } catch {\n      /** */\n    }\n    return n\n  }\n\n  addNotifyTransactionId(id: number) {\n    if (!Number.isInteger(id)) throw new WERR_INVALID_PARAMETER('id', 'integer')\n    const s = new Set(this.notify.transactionIds || [])\n    s.add(id)\n    this.notify.transactionIds = [...s].sort((a, b) => {\n      if (a > b) return 1\n      if (a < b) return -1\n      return 0\n    })\n    this.notified = false\n  }\n\n  /**\n   * Adds a note to history.\n   * Notes with identical property values to an existing note are ignored.\n   * @param note Note to add\n   * @param noDupes if true, only newest note with same `what` value is retained.\n   */\n  addHistoryNote(note: ReqHistoryNote, noDupes?: boolean) {\n    this.history.notes ??= []\n    if (!note.when) note.when = new Date().toISOString()\n    if (noDupes) {\n      // Remove any existing notes with same 'what' value and either no 'when' or an earlier 'when'\n      this.history.notes = this.history.notes.filter(n => n.what !== note.what || (n.when && n.when > note.when!))\n    }\n    let addNote = true\n    for (const n of this.history.notes) {\n      let isEqual = true\n      for (const [k, v] of Object.entries(n)) {\n        if (v !== note[k]) {\n          isEqual = false\n          break\n        }\n      }\n      if (isEqual) addNote = false\n      if (!addNote) break\n    }\n    if (addNote) {\n      this.history.notes.push(note)\n      const k = (n: ReqHistoryNote): string => {\n        return `${n.when} ${n.what}`\n      }\n      this.history.notes.sort((a, b) => {\n        if (k(a) < k(b)) return -1\n        if (k(a) > k(b)) return 1\n        return 0\n      })\n    }\n  }\n\n  /**\n     * Updates database record with current state of this EntityUser\n\n     * @param storage\n     * @param trx\n     */\n  async updateStorage(storage: EntityStorage, trx?: TrxToken) {\n    this.updated_at = new Date()\n    this.updateApi()\n    if (this.id === 0) {\n      await storage.insertProvenTxReq(this.api)\n    }\n    const update: Partial<TableProvenTxReq> = { ...this.api }\n    await storage.updateProvenTxReq(this.id, update, trx)\n  }\n\n  /**\n   * Update storage with changes to non-static properties:\n   *   updated_at\n   *   provenTxId\n   *   status\n   *   history\n   *   notify\n   *   notified\n   *   attempts\n   *   batch\n   *\n   * @param storage\n   * @param trx\n   */\n  async updateStorageDynamicProperties(storage: WalletStorageManager | StorageProvider, trx?: TrxToken) {\n    this.updated_at = new Date()\n    this.updateApi()\n    const update: Partial<TableProvenTxReqDynamics> = {\n      updated_at: this.api.updated_at,\n      provenTxId: this.api.provenTxId,\n      status: this.api.status,\n      history: this.api.history,\n      notify: this.api.notify,\n      notified: this.api.notified,\n      attempts: this.api.attempts,\n      batch: this.api.batch,\n      wasBroadcast: this.wasBroadcast,\n      rebroadcastAttempts: this.rebroadcastAttempts\n    }\n    if (storage.isStorageProvider()) {\n      const sp = storage as StorageProvider\n      await sp.updateProvenTxReqDynamics(this.id, update, trx)\n    } else {\n      const wsm = storage as WalletStorageManager\n      await wsm.runAsStorageProvider(async sp => {\n        await sp.updateProvenTxReqDynamics(this.id, update, trx)\n      })\n    }\n  }\n\n  async insertOrMerge(storage: EntityStorage, trx?: TrxToken): Promise<EntityProvenTxReq> {\n    const req = await storage.transaction<EntityProvenTxReq>(async trx => {\n      const reqApi0 = this.toApi()\n      const { req: reqApi1, isNew } = await storage.findOrInsertProvenTxReq(reqApi0, trx)\n      if (isNew) {\n        return new EntityProvenTxReq(reqApi1)\n      } else {\n        const req = new EntityProvenTxReq(reqApi1)\n        req.mergeNotifyTransactionIds(reqApi0)\n        req.mergeHistory(reqApi0, undefined, true)\n        await req.updateStorage(storage, trx)\n        return req\n      }\n    }, trx)\n    return req\n  }\n\n  /**\n   * See `ProvenTxReqStatusApi`\n   */\n  get status() {\n    return this.api.status\n  }\n\n  set status(v: ProvenTxReqStatus) {\n    if (v !== this.api.status) {\n      this.addHistoryNote({ what: 'status', status_was: this.api.status, status_now: v })\n      this.api.status = v\n    }\n    if (EntityProvenTxReq.wasBroadcastStatuses.includes(v)) this.wasBroadcast = true\n  }\n\n  get provenTxReqId() {\n    return this.api.provenTxReqId\n  }\n\n  set provenTxReqId(v: number) {\n    this.api.provenTxReqId = v\n  }\n\n  get created_at() {\n    return this.api.created_at\n  }\n\n  set created_at(v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at() {\n    return this.api.updated_at\n  }\n\n  set updated_at(v: Date) {\n    this.api.updated_at = v\n  }\n\n  get txid() {\n    return this.api.txid\n  }\n\n  set txid(v: string) {\n    this.api.txid = v\n  }\n\n  get inputBEEF() {\n    return this.api.inputBEEF\n  }\n\n  set inputBEEF(v: number[] | undefined) {\n    this.api.inputBEEF = v\n  }\n\n  get rawTx() {\n    return this.api.rawTx\n  }\n\n  set rawTx(v: number[]) {\n    this.api.rawTx = v\n  }\n\n  get attempts() {\n    return this.api.attempts\n  }\n\n  set attempts(v: number) {\n    this.api.attempts = v\n  }\n\n  get provenTxId() {\n    return this.api.provenTxId\n  }\n\n  set provenTxId(v: number | undefined) {\n    this.api.provenTxId = v\n  }\n\n  get notified() {\n    return this.api.notified\n  }\n\n  set notified(v: boolean) {\n    this.api.notified = v\n  }\n\n  get batch() {\n    return this.api.batch\n  }\n\n  set batch(v: string | undefined) {\n    this.api.batch = v\n  }\n\n  get wasBroadcast(): boolean {\n    const wasBroadcast = this.api.wasBroadcast as boolean | number | undefined\n    if (wasBroadcast === true || wasBroadcast === 1) return true\n    if (EntityProvenTxReq.wasBroadcastStatuses.includes(this.status)) return true\n    const h = this.getHistorySummary()\n    return h.setToUnmined || h.setToCallback || h.setToUnconfirmed || h.setToCompleted\n  }\n\n  set wasBroadcast(v: boolean) {\n    this.api.wasBroadcast = v\n  }\n\n  get rebroadcastAttempts(): number {\n    return this.api.rebroadcastAttempts ?? 0\n  }\n\n  set rebroadcastAttempts(v: number) {\n    this.api.rebroadcastAttempts = v\n  }\n\n  applyProofTimeout(maxRebroadcastAttempts = 0): { action: 'invalid' | 'rebroadcast'; rebroadcastAttempts: number } {\n    this.notified = false\n\n    if (!this.wasBroadcast) {\n      this.status = 'invalid'\n      return { action: 'invalid', rebroadcastAttempts: this.rebroadcastAttempts }\n    }\n\n    if (maxRebroadcastAttempts > 0 && this.rebroadcastAttempts >= maxRebroadcastAttempts) {\n      this.status = 'invalid'\n      return { action: 'invalid', rebroadcastAttempts: this.rebroadcastAttempts }\n    }\n\n    this.rebroadcastAttempts = this.rebroadcastAttempts + 1\n    this.status = 'unsent'\n    this.attempts = 0\n    return { action: 'rebroadcast', rebroadcastAttempts: this.rebroadcastAttempts }\n  }\n\n  override get id() {\n    return this.api.provenTxReqId\n  }\n\n  override set id(v: number) {\n    this.api.provenTxReqId = v\n  }\n\n  override get entityName(): string {\n    return 'provenTxReq'\n  }\n\n  override get entityTable(): string {\n    return 'proven_tx_reqs'\n  }\n\n  /**\n   * 'convergent' equality must satisfy (A sync B) equals (B sync A)\n   */\n  override equals(ei: TableProvenTxReq, syncMap?: SyncMap | undefined): boolean {\n    const eo = this.toApi()\n    if (\n      eo.txid != ei.txid ||\n      !arraysEqual(eo.rawTx, ei.rawTx) ||\n      (eo.inputBEEF == null && ei.inputBEEF != null) ||\n      (eo.inputBEEF != null && ei.inputBEEF == null) ||\n      (eo.inputBEEF != null && ei.inputBEEF != null && !arraysEqual(eo.inputBEEF, ei.inputBEEF)) ||\n      eo.batch != ei.batch\n    ) {\n      return false\n    }\n    if (syncMap != null) {\n      if (\n        // attempts doesn't matter for convergent equality\n        // history doesn't matter for convergent equality\n        // only local transactionIds matter, that cared about this txid in sorted order\n        eo.provenTxReqId !== syncMap.provenTxReq.idMap[verifyId(ei.provenTxReqId)] ||\n        (!eo.provenTxId && ei.provenTxId) ||\n        (eo.provenTxId && !ei.provenTxId) ||\n        (ei.provenTxId && eo.provenTxId !== syncMap.provenTx.idMap[ei.provenTxId])\n        // || eo.created_at !== minDate(ei.created_at, eo.created_at)\n        // || eo.updated_at !== maxDate(ei.updated_at, eo.updated_at)\n      ) {\n        return false\n      }\n    } else if (\n      eo.attempts != ei.attempts ||\n      eo.history != ei.history ||\n      eo.notify != ei.notify ||\n      eo.provenTxReqId !== ei.provenTxReqId ||\n      eo.provenTxId !== ei.provenTxId\n      // || eo.created_at !== ei.created_at\n      // || eo.updated_at !== ei.updated_at\n    ) {\n      return false\n    }\n    return true\n  }\n\n  static async mergeFind(\n    storage: EntityStorage,\n    userId: number,\n    ei: TableProvenTxReq,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean; eo: EntityProvenTxReq; eiId: number }> {\n    const ef = verifyOneOrNone(await storage.findProvenTxReqs({ partial: { txid: ei.txid }, trx }))\n    return {\n      found: ef != null,\n      eo: new EntityProvenTxReq(ef || { ...ei }),\n      eiId: verifyId(ei.provenTxReqId)\n    }\n  }\n\n  mapNotifyTransactionIds(syncMap: SyncMap): void {\n    // Map external notification transaction ids to local ids\n    const externalIds = this.notify.transactionIds || []\n    this.notify.transactionIds = []\n    for (const transactionId of externalIds) {\n      const localTxId: number | undefined = syncMap.transaction.idMap[transactionId]\n      if (localTxId) {\n        this.addNotifyTransactionId(localTxId)\n      }\n    }\n  }\n\n  mergeNotifyTransactionIds(ei: TableProvenTxReq, syncMap?: SyncMap): void {\n    // Map external notification transaction ids to local ids and merge them if they exist.\n    const eie = new EntityProvenTxReq(ei)\n    if (eie.notify.transactionIds != null) {\n      this.notify.transactionIds ||= []\n      for (const transactionId of eie.notify.transactionIds) {\n        const localTxId: number | undefined = syncMap != null ? syncMap.transaction.idMap[transactionId] : transactionId\n        if (localTxId) {\n          this.addNotifyTransactionId(localTxId)\n        }\n      }\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  mergeHistory(ei: TableProvenTxReq, syncMap?: SyncMap, noDupes?: boolean): void {\n    const eie = new EntityProvenTxReq(ei)\n    if (eie.history.notes != null) {\n      for (const note of eie.history.notes) {\n        this.addHistoryNote(note)\n      }\n    }\n  }\n\n  static isTerminalStatus(status: ProvenTxReqStatus): boolean {\n    return ProvenTxReqTerminalStatus.includes(status)\n  }\n\n  override async mergeNew(storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    if (this.provenTxId) this.provenTxId = syncMap.provenTx.idMap[this.provenTxId]\n    this.mapNotifyTransactionIds(syncMap)\n    this.provenTxReqId = 0\n    this.provenTxReqId = await storage.insertProvenTxReq(this.toApi(), trx)\n  }\n\n  /**\n   * When merging `ProvenTxReq`, care is taken to avoid short-cirtuiting notification: `status` must not transition to `completed` without\n   * passing through `notifying`. Thus a full convergent merge passes through these sequence steps:\n   * 1. Remote storage completes before local storage.\n   * 2. The remotely completed req and ProvenTx sync to local storage.\n   * 3. The local storage transitions to `notifying`, after merging the remote attempts and history.\n   * 4. The local storage notifies, transitioning to `completed`.\n   * 5. Having been updated, the local req, but not ProvenTx sync to remote storage, but do not merge because the earlier `completed` wins.\n   * 6. Convergent equality is achieved (completing work - history and attempts are equal)\n   *\n   * On terminal failure: `doubleSpend` trumps `invalid` as it contains more data.\n   */\n  override async mergeExisting(\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableProvenTxReq,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    if (!this.batch && ei.batch) this.batch = ei.batch\n    else if (this.batch && ei.batch && this.batch !== ei.batch) {\n      throw new WERR_INTERNAL('ProvenTxReq merge batch not equal.')\n    }\n\n    this.mergeHistory(ei, syncMap, true)\n    this.mergeNotifyTransactionIds(ei, syncMap)\n\n    this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n    await storage.updateProvenTxReq(this.id, this.toApi(), trx)\n    return false\n  }\n}\n\nexport interface ProvenTxReqHistorySummaryApi {\n  setToCompleted: boolean\n  setToCallback: boolean\n  setToUnmined: boolean\n  setToDoubleSpend: boolean\n  setToSending: boolean\n  setToUnconfirmed: boolean\n}\n\nexport interface ProvenTxReqHistory {\n  /**\n   * Keys are Date().toISOString()\n   * Values are a description of what happened.\n   */\n  notes?: ReqHistoryNote[]\n}\n\nexport interface ProvenTxReqNotify {\n  transactionIds?: number[]\n}\n","import { TransactionStatus } from '../../../sdk/types'\nimport { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { optionalArraysEqual, verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { TableOutput } from '../tables/TableOutput'\nimport { TableTransaction } from '../tables/TableTransaction'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\nimport { EntityProvenTx } from './EntityProvenTx'\nimport { Transaction as BsvTransaction, TransactionInput } from '@bsv/sdk'\n\nexport class EntityTransaction extends EntityBase<TableTransaction> {\n  /**\n   * @returns @bsv/sdk Transaction object from parsed rawTx.\n   * If rawTx is undefined, returns undefined.\n   */\n  getBsvTx (): BsvTransaction | undefined {\n    if (this.rawTx == null) return undefined\n    return BsvTransaction.fromBinary(this.rawTx)\n  }\n\n  /**\n   * @returns array of @bsv/sdk TransactionInput objects from parsed rawTx.\n   * If rawTx is undefined, an empty array is returned.\n   */\n  getBsvTxIns (): TransactionInput[] {\n    const tx = this.getBsvTx()\n    if (tx == null) return []\n    return tx.inputs\n  }\n\n  /**\n   * Returns an array of \"known\" inputs to this transaction which belong to the same userId.\n   * Uses both spentBy and rawTx inputs (if available) to locate inputs from among user's outputs.\n   * Not all transaction inputs correspond to prior storage outputs.\n   */\n  async getInputs (storage: EntityStorage, trx?: TrxToken): Promise<TableOutput[]> {\n    const inputs = await storage.findOutputs({\n      partial: { userId: this.userId, spentBy: this.id },\n      trx\n    })\n    // Merge \"inputs\" by spentBy and userId\n    for (const input of this.getBsvTxIns()) {\n      // console.log(`getInputs of ${this.id}: ${input.txid()} ${input.txOutNum}`)\n      const pso = verifyOneOrNone(\n        await storage.findOutputs({\n          partial: {\n            userId: this.userId,\n            txid: input.sourceTXID,\n            vout: input.sourceOutputIndex\n          },\n          trx\n        })\n      )\n      if ((pso != null) && !inputs.some(i => i.outputId === pso.outputId)) inputs.push(pso)\n    }\n    return inputs\n  }\n\n  constructor (api?: TableTransaction) {\n    const now = new Date()\n    super(\n      api || {\n        transactionId: 0,\n        created_at: now,\n        updated_at: now,\n        userId: 0,\n        txid: '',\n        status: 'unprocessed',\n        reference: '',\n        satoshis: 0,\n        description: '',\n        isOutgoing: false,\n        rawTx: undefined,\n        inputBEEF: undefined\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get transactionId () {\n    return this.api.transactionId\n  }\n\n  set transactionId (v: number) {\n    this.api.transactionId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get version () {\n    return this.api.version\n  }\n\n  set version (v: number | undefined) {\n    this.api.version = v\n  }\n\n  get lockTime () {\n    return this.api.lockTime\n  }\n\n  set lockTime (v: number | undefined) {\n    this.api.lockTime = v\n  }\n\n  get isOutgoing () {\n    return this.api.isOutgoing\n  }\n\n  set isOutgoing (v: boolean) {\n    this.api.isOutgoing = v\n  }\n\n  get status () {\n    return this.api.status\n  }\n\n  set status (v: TransactionStatus) {\n    this.api.status = v\n  }\n\n  get userId () {\n    return this.api.userId\n  }\n\n  set userId (v: number) {\n    this.api.userId = v\n  }\n\n  get provenTxId () {\n    return this.api.provenTxId\n  }\n\n  set provenTxId (v: number | undefined) {\n    this.api.provenTxId = v\n  }\n\n  get satoshis () {\n    return this.api.satoshis\n  }\n\n  set satoshis (v: number) {\n    this.api.satoshis = v\n  }\n\n  get txid () {\n    return this.api.txid\n  }\n\n  set txid (v: string | undefined) {\n    this.api.txid = v\n  }\n\n  get reference () {\n    return this.api.reference\n  }\n\n  set reference (v: string) {\n    this.api.reference = v\n  }\n\n  get inputBEEF () {\n    return this.api.inputBEEF\n  }\n\n  set inputBEEF (v: number[] | undefined) {\n    this.api.inputBEEF = v\n  }\n\n  get description () {\n    return this.api.description\n  }\n\n  set description (v: string) {\n    this.api.description = v\n  }\n\n  get rawTx () {\n    return this.api.rawTx\n  }\n\n  set rawTx (v: number[] | undefined) {\n    this.api.rawTx = v\n  }\n\n  // Extended (computed / dependent entity) Properties\n  // get labels() { return this.api.labels }\n  // set labels(v: string[] | undefined) { this.api.labels = v }\n\n  override get id (): number {\n    return this.api.transactionId\n  }\n\n  override set id (v: number) {\n    this.api.transactionId = v\n  }\n\n  override get entityName (): string {\n    return 'transaction'\n  }\n\n  override get entityTable (): string {\n    return 'transactions'\n  }\n\n  override equals (ei: TableTransaction, syncMap?: SyncMap | undefined): boolean {\n    const eo = this.toApi()\n\n    // Properties that are never updated\n    if (\n      eo.transactionId === ((syncMap != null) ? syncMap.transaction.idMap[verifyId(ei.transactionId)] : ei.transactionId) &&\n      eo.reference === ei.reference &&\n      eo.version === ei.version &&\n      eo.lockTime === ei.lockTime &&\n      eo.isOutgoing === ei.isOutgoing &&\n      eo.status === ei.status &&\n      eo.satoshis === ei.satoshis &&\n      eo.txid === ei.txid &&\n      eo.description === ei.description &&\n      optionalArraysEqual(eo.rawTx, ei.rawTx) &&\n      optionalArraysEqual(eo.inputBEEF, ei.inputBEEF) &&\n      (eo.provenTxId == null) === (ei.provenTxId == null) &&\n      !(ei.provenTxId && eo.provenTxId !== ((syncMap != null) ? syncMap.provenTx.idMap[verifyId(ei.provenTxId)] : ei.provenTxId))\n    ) { return true }\n\n    return false\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableTransaction,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityTransaction, eiId: number }> {\n    // Prefer (userId, txid) when txid is known — txid is a globally stable\n    // identifier, whereas `reference` is locally-assigned by whichever\n    // storage first ingested the row. Two storages that independently\n    // internalized the same txid will hold different references, and\n    // matching by reference would insert a duplicate row instead of\n    // merging. Fall through to reference when the txid lookup misses so\n    // post-broadcast syncs land on an existing pre-broadcast row that\n    // hasn't learned its txid yet.\n    let ef: TableTransaction | undefined\n    if (ei.txid) {\n      ef = verifyOneOrNone(await storage.findTransactions({ partial: { txid: ei.txid, userId }, trx }))\n    }\n    if ((ef == null) && ei.reference) {\n      ef = verifyOneOrNone(await storage.findTransactions({ partial: { reference: ei.reference, userId }, trx }))\n    }\n    return {\n      found: ef != null,\n      eo: new EntityTransaction(ef || { ...ei }),\n      eiId: verifyId(ei.transactionId)\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    if (this.provenTxId) this.provenTxId = syncMap.provenTx.idMap[this.provenTxId]\n    this.userId = userId\n    this.transactionId = 0\n    this.transactionId = await storage.insertTransaction(this.toApi(), trx)\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableTransaction,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      // Properties that are never updated:\n      // transactionId\n      // userId\n      // reference\n\n      // Merged properties\n      this.version = ei.version\n      this.lockTime = ei.lockTime\n      this.isOutgoing = ei.isOutgoing\n      this.status = ei.status\n      this.provenTxId = ei.provenTxId ? syncMap.provenTx.idMap[ei.provenTxId] : undefined\n      this.satoshis = ei.satoshis\n      this.txid = ei.txid\n      this.description = ei.description\n      this.rawTx = ei.rawTx\n      this.inputBEEF = ei.inputBEEF\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateTransaction(this.id, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n\n  async getProvenTx (storage: EntityStorage, trx?: TrxToken): Promise<EntityProvenTx | undefined> {\n    if (!this.provenTxId) return undefined\n    const p = verifyOneOrNone(\n      await storage.findProvenTxs({\n        partial: { provenTxId: this.provenTxId },\n        trx\n      })\n    )\n    if (p == null) return undefined\n    return new EntityProvenTx(p)\n  }\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\nimport { TableTxLabel } from '../tables/TableTxLabel'\n\nexport class EntityTxLabel extends EntityBase<TableTxLabel> {\n  constructor (api?: TableTxLabel) {\n    const now = new Date()\n    super(\n      api || {\n        txLabelId: 0,\n        created_at: now,\n        updated_at: now,\n        label: '',\n        userId: 0,\n        isDeleted: false\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get txLabelId () {\n    return this.api.txLabelId\n  }\n\n  set txLabelId (v: number) {\n    this.api.txLabelId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get label () {\n    return this.api.label\n  }\n\n  set label (v: string) {\n    this.api.label = v\n  }\n\n  get userId () {\n    return this.api.userId\n  }\n\n  set userId (v: number) {\n    this.api.userId = v\n  }\n\n  get isDeleted () {\n    return this.api.isDeleted\n  }\n\n  set isDeleted (v: boolean) {\n    this.api.isDeleted = v\n  }\n\n  override get id (): number {\n    return this.api.txLabelId\n  }\n\n  override set id (v: number) {\n    this.api.txLabelId = v\n  }\n\n  override get entityName (): string {\n    return 'txLabel'\n  }\n\n  override get entityTable (): string {\n    return 'tx_labels'\n  }\n\n  override equals (ei: TableTxLabel, syncMap?: SyncMap): boolean {\n    const eo = this.toApi()\n    if (eo.label != ei.label || eo.isDeleted != ei.isDeleted) return false\n    if (syncMap == null) {\n      if (eo.userId !== ei.userId) return false\n    }\n    return true\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableTxLabel,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityTxLabel, eiId: number }> {\n    const ef = verifyOneOrNone(await storage.findTxLabels({ partial: { label: ei.label, userId }, trx }))\n    return {\n      found: ef != null,\n      eo: new EntityTxLabel(ef || { ...ei }),\n      eiId: verifyId(ei.txLabelId)\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    this.userId = userId\n    this.txLabelId = 0\n    this.txLabelId = await storage.insertTxLabel(this.toApi(), trx)\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableTxLabel,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      this.isDeleted = ei.isDeleted\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateTxLabel(this.id, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\nimport { TableTxLabelMap } from '../tables/TableTxLabelMap'\nimport { WERR_INVALID_OPERATION } from '../../../sdk/WERR_errors'\n\nexport class EntityTxLabelMap extends EntityBase<TableTxLabelMap> {\n  constructor (api?: TableTxLabelMap) {\n    const now = new Date()\n    super(\n      api || {\n        created_at: now,\n        updated_at: now,\n        transactionId: 0,\n        txLabelId: 0,\n        isDeleted: false\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get txLabelId () {\n    return this.api.txLabelId\n  }\n\n  set txLabelId (v: number) {\n    this.api.txLabelId = v\n  }\n\n  get transactionId () {\n    return this.api.transactionId\n  }\n\n  set transactionId (v: number) {\n    this.api.transactionId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get isDeleted () {\n    return this.api.isDeleted\n  }\n\n  set isDeleted (v: boolean) {\n    this.api.isDeleted = v\n  }\n\n  override get id (): number {\n    throw new WERR_INVALID_OPERATION('entity has no \"id\" value')\n  } // entity does not have its own id.\n\n  override get entityName (): string {\n    return 'txLabelMap'\n  }\n\n  override get entityTable (): string {\n    return 'tx_labels_map'\n  }\n\n  override equals (ei: TableTxLabelMap, syncMap?: SyncMap | undefined): boolean {\n    const eo = this.toApi()\n\n    return (\n      eo.transactionId === ((syncMap != null) ? syncMap.transaction.idMap[verifyId(ei.transactionId)] : ei.transactionId) &&\n      eo.txLabelId === ((syncMap != null) ? syncMap.txLabel.idMap[verifyId(ei.txLabelId)] : ei.txLabelId) &&\n      eo.isDeleted === ei.isDeleted\n    )\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableTxLabelMap,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityTxLabelMap, eiId: number }> {\n    const transactionId = syncMap.transaction.idMap[ei.transactionId]\n    const txLabelId = syncMap.txLabel.idMap[ei.txLabelId]\n    const ef = verifyOneOrNone(\n      await storage.findTxLabelMaps({\n        partial: { transactionId, txLabelId },\n        trx\n      })\n    )\n    return {\n      found: ef != null,\n      eo: new EntityTxLabelMap(ef || { ...ei }),\n      eiId: -1\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    this.transactionId = syncMap.transaction.idMap[this.transactionId]\n    this.txLabelId = syncMap.txLabel.idMap[this.txLabelId]\n    await storage.insertTxLabelMap(this.toApi(), trx)\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableTxLabelMap,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    if (ei.updated_at > this.updated_at) {\n      this.isDeleted = ei.isDeleted\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateTxLabelMap(this.transactionId, this.txLabelId, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { verifyId, verifyOneOrNone } from '../../../utility/utilityHelpers'\nimport { EntityBase, EntityStorage, SyncMap } from './EntityBase'\nimport { TableUser } from '../tables/TableUser'\nimport { WERR_INTERNAL } from '../../../sdk/WERR_errors'\n\nexport class EntityUser extends EntityBase<TableUser> {\n  constructor (api?: TableUser) {\n    const now = new Date()\n    super(\n      api || {\n        userId: 0,\n        created_at: now,\n        updated_at: now,\n        identityKey: '',\n        activeStorage: ''\n      }\n    )\n  }\n\n  override updateApi (): void {\n    /* nothing needed yet... */\n  }\n\n  get userId () {\n    return this.api.userId\n  }\n\n  set userId (v: number) {\n    this.api.userId = v\n  }\n\n  get created_at () {\n    return this.api.created_at\n  }\n\n  set created_at (v: Date) {\n    this.api.created_at = v\n  }\n\n  get updated_at () {\n    return this.api.updated_at\n  }\n\n  set updated_at (v: Date) {\n    this.api.updated_at = v\n  }\n\n  get identityKey () {\n    return this.api.identityKey\n  }\n\n  set identityKey (v: string) {\n    this.api.identityKey = v\n  }\n\n  get activeStorage () {\n    return this.api.activeStorage\n  }\n\n  set activeStorage (v: string) {\n    this.api.activeStorage = v\n  }\n\n  override get id (): number {\n    return this.api.userId\n  }\n\n  override set id (v: number) {\n    this.api.userId = v\n  }\n\n  override get entityName (): string {\n    return 'user'\n  }\n\n  override get entityTable (): string {\n    return 'users'\n  }\n\n  override equals (ei: TableUser, syncMap?: SyncMap | undefined): boolean {\n    const eo = this.toApi()\n    if (eo.identityKey != ei.identityKey || eo.activeStorage != ei.activeStorage) return false\n    if (syncMap == null) {\n      /** */\n    }\n    return true\n  }\n\n  static async mergeFind (\n    storage: EntityStorage,\n    userId: number,\n    ei: TableUser,\n    trx?: TrxToken\n  ): Promise<{ found: boolean, eo: EntityUser, eiId: number }> {\n    const ef = verifyOneOrNone(await storage.findUsers({ partial: { identityKey: ei.identityKey }, trx }))\n    if ((ef != null) && ef.userId != userId) throw new WERR_INTERNAL('logic error, userIds don not match.')\n    return {\n      found: ef != null,\n      eo: new EntityUser(ef || { ...ei }),\n      eiId: verifyId(ei.userId)\n    }\n  }\n\n  override async mergeNew (storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    throw new WERR_INTERNAL('a sync chunk merge must never create a new user')\n  }\n\n  override async mergeExisting (\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableUser,\n    syncMap?: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    let wasMerged = false\n    // The condition on activeStorage here is critical as a new user record may have just been created\n    // in a backup store to which a backup is being pushed.\n    if (ei.updated_at > this.updated_at || (this.activeStorage === undefined && ei.activeStorage !== undefined)) {\n      this.activeStorage = ei.activeStorage\n      this.updated_at = new Date(Math.max(ei.updated_at.getTime(), this.updated_at.getTime()))\n      await storage.updateUser(this.id, this.toApi(), trx)\n      wasMerged = true\n    }\n    return wasMerged\n  }\n}\n","import { TrxToken } from '../../../sdk/WalletStorage.interfaces'\nimport { maxDate, verifyId } from '../../../utility/utilityHelpers'\nimport { EntityBase, EntityStorage, EntitySyncMap, SyncMap } from './EntityBase'\nimport { WERR_INTERNAL } from '../../../sdk/WERR_errors'\nimport { EntityTimeStamp } from '../../../sdk/types'\n\n/**\n * @param API one of the storage table interfaces.\n * @param DE the corresponding entity class\n */\nexport class MergeEntity<API extends EntityTimeStamp, DE extends EntityBase<API>> {\n  idMap: Record<number, number>\n\n  constructor(\n    public stateArray: API[] | undefined,\n    public find: (\n      storage: EntityStorage,\n      userId: number,\n      ei: API,\n      syncMap: SyncMap,\n      trx?: TrxToken\n    ) => Promise<{ found: boolean; eo: DE; eiId: number }>,\n    /** id map for primary id of API and DE object. */\n    public esm: EntitySyncMap\n  ) {\n    this.idMap = esm.idMap\n  }\n\n  updateSyncMap(map: Record<number, number>, inId: number, outId: number) {\n    const i = verifyId(inId)\n    const o = verifyId(outId)\n    if (map[i] === undefined) {\n      map[i] = o\n    } else if (map[i] !== o) throw new WERR_INTERNAL(`updateSyncMap map[${inId}] can't override ${map[i]} with ${o}`)\n  }\n\n  /**\n   * @param since date of current sync chunk\n   */\n  async merge(\n    since: Date | undefined,\n    storage: EntityStorage,\n    userId: number,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<{ inserts: number; updates: number }> {\n    let inserts = 0\n    let updates = 0\n    if (this.stateArray == null) return { inserts, updates }\n    for (const ei of this.stateArray) {\n      this.esm.maxUpdated_at = maxDate(this.esm.maxUpdated_at, ei.updated_at)\n      /**\n       * Switch to using syncMap: if the ei id is in the map, it's an existing merge; otherwise it's new.\n       */\n      const { found, eo, eiId } = await this.find(storage, userId, ei, syncMap, trx)\n      if (found) {\n        if (await eo.mergeExisting(storage, since, ei, syncMap, trx)) {\n          updates++\n        }\n      } else {\n        await eo.mergeNew(storage, userId, syncMap, trx)\n        inserts++\n      }\n      if (eiId > -1) this.updateSyncMap(this.idMap, eiId, eo.id)\n    }\n    return { inserts, updates }\n  }\n}\n","import {\n  RequestSyncChunkArgs,\n  SyncChunk,\n  SyncStatus,\n  TrxToken,\n  WalletStorageSync\n} from '../../../sdk/WalletStorage.interfaces'\nimport { WERR_INVALID_PARAMETER } from '../../../sdk/WERR_errors'\nimport { maxDate, verifyId, verifyTruthy } from '../../../utility/utilityHelpers'\nimport { TableSettings } from '../tables/TableSettings'\nimport { TableSyncState } from '../tables/TableSyncState'\nimport { createSyncMap, EntityBase, EntityStorage, SyncError, SyncMap } from './EntityBase'\nimport { EntityCertificate } from './EntityCertificate'\nimport { EntityCertificateField } from './EntityCertificateField'\nimport { EntityCommission } from './EntityCommission'\nimport { EntityOutput } from './EntityOutput'\nimport { EntityOutputBasket } from './EntityOutputBasket'\nimport { EntityOutputTag } from './EntityOutputTag'\nimport { EntityOutputTagMap } from './EntityOutputTagMap'\nimport { EntityProvenTx } from './EntityProvenTx'\nimport { EntityProvenTxReq } from './EntityProvenTxReq'\nimport { EntityTransaction } from './EntityTransaction'\nimport { EntityTxLabel } from './EntityTxLabel'\nimport { EntityTxLabelMap } from './EntityTxLabelMap'\nimport { EntityUser } from './EntityUser'\nimport { MergeEntity } from './MergeEntity'\n\nfunction formatSyncSection<T>(\n  heading: string,\n  rows: readonly T[] | null | undefined,\n  formatRow: (row: T) => string\n): string {\n  if (rows == null) return ''\n  let section = `  ${heading}\\n`\n  for (const row of rows) {\n    section += `    ${formatRow(row)}\\n`\n  }\n  return section\n}\n\nexport class EntitySyncState extends EntityBase<TableSyncState> {\n  constructor(api?: TableSyncState) {\n    const now = new Date()\n    super(\n      api || {\n        syncStateId: 0,\n        created_at: now,\n        updated_at: now,\n        userId: 0,\n        storageIdentityKey: '',\n        storageName: '',\n        init: false,\n        refNum: '',\n        status: 'unknown',\n        when: undefined,\n        errorLocal: undefined,\n        errorOther: undefined,\n        satoshis: undefined,\n        syncMap: JSON.stringify(createSyncMap())\n      }\n    )\n    this.errorLocal = this.api.errorLocal ? (JSON.parse(this.api.errorLocal) as SyncError) : undefined\n    this.errorOther = this.api.errorOther ? (JSON.parse(this.api.errorOther) as SyncError) : undefined\n    this.syncMap = JSON.parse(this.api.syncMap) as SyncMap\n    this.validateSyncMap(this.syncMap)\n  }\n\n  validateSyncMap(sm: SyncMap) {\n    for (const key of Object.keys(sm)) {\n      const value = (sm as SyncMap & Record<string, unknown>)[key]\n      if (\n        typeof value === 'object' &&\n        value !== null &&\n        'maxUpdated_at' in value &&\n        typeof value.maxUpdated_at === 'string'\n      ) {\n        value.maxUpdated_at = new Date(value.maxUpdated_at)\n      }\n    }\n  }\n\n  static async fromStorage(\n    storage: WalletStorageSync,\n    userIdentityKey: string,\n    remoteSettings: TableSettings\n  ): Promise<EntitySyncState> {\n    const { user } = verifyTruthy(await storage.findOrInsertUser(userIdentityKey))\n    const { syncState: api } = verifyTruthy(\n      await storage.findOrInsertSyncStateAuth(\n        { userId: user.userId, identityKey: userIdentityKey },\n        remoteSettings.storageIdentityKey,\n        remoteSettings.storageName\n      )\n    )\n    if (!api.syncMap || api.syncMap === '{}') api.syncMap = JSON.stringify(createSyncMap())\n    const ss = new EntitySyncState(api)\n    return ss\n  }\n\n  /**\n   * Handles both insert and update based on id value: zero indicates insert.\n   * @param storage\n   * @param notSyncMap if not new and true, excludes updating syncMap in storage.\n   * @param trx\n   */\n  async updateStorage(storage: EntityStorage, notSyncMap?: boolean, trx?: TrxToken) {\n    this.updated_at = new Date()\n    this.updateApi(notSyncMap && this.id > 0)\n    if (this.id === 0) {\n      await storage.insertSyncState(this.api)\n    } else {\n      const update: Partial<TableSyncState> = { ...this.api }\n      if (notSyncMap) delete update.syncMap\n      delete update.created_at\n      await storage.updateSyncState(verifyId(this.id), update, trx)\n    }\n  }\n\n  override updateApi(notSyncMap?: boolean): void {\n    this.api.errorLocal = this.apiErrorLocal\n    this.api.errorOther = this.apiErrorOther\n    if (!notSyncMap) this.api.syncMap = this.apiSyncMap\n  }\n\n  // Pass through api properties\n  set created_at(v: Date) {\n    this.api.created_at = v\n  }\n\n  get created_at() {\n    return this.api.created_at\n  }\n\n  set updated_at(v: Date) {\n    this.api.updated_at = v\n  }\n\n  get updated_at() {\n    return this.api.updated_at\n  }\n\n  set userId(v: number) {\n    this.api.userId = v\n  }\n\n  get userId() {\n    return this.api.userId\n  }\n\n  set storageIdentityKey(v: string) {\n    this.api.storageIdentityKey = v\n  }\n\n  get storageIdentityKey() {\n    return this.api.storageIdentityKey\n  }\n\n  set storageName(v: string) {\n    this.api.storageName = v\n  }\n\n  get storageName() {\n    return this.api.storageName\n  }\n\n  set init(v: boolean) {\n    this.api.init = v\n  }\n\n  get init() {\n    return this.api.init\n  }\n\n  set refNum(v: string) {\n    this.api.refNum = v\n  }\n\n  get refNum() {\n    return this.api.refNum\n  }\n\n  set status(v: SyncStatus) {\n    this.api.status = v\n  }\n\n  get status(): SyncStatus {\n    return this.api.status\n  }\n\n  set when(v: Date | undefined) {\n    this.api.when = v\n  }\n\n  get when() {\n    return this.api.when\n  }\n\n  set satoshis(v: number | undefined) {\n    this.api.satoshis = v\n  }\n\n  get satoshis() {\n    return this.api.satoshis\n  }\n\n  get apiErrorLocal() {\n    return this.errorToString(this.errorLocal)\n  }\n\n  get apiErrorOther() {\n    return this.errorToString(this.errorOther)\n  }\n\n  get apiSyncMap() {\n    return JSON.stringify(this.syncMap)\n  }\n\n  override get id(): number {\n    return this.api.syncStateId\n  }\n\n  set id(id: number) {\n    this.api.syncStateId = id\n  }\n\n  override get entityName(): string {\n    return 'syncState'\n  }\n\n  override get entityTable(): string {\n    return 'sync_states'\n  }\n\n  static mergeIdMap(fromMap: Record<number, number>, toMap: Record<number, number>) {\n    for (const [key, value] of Object.entries(fromMap)) {\n      const typedKey = key as unknown as number\n      const fromValue = fromMap[typedKey]\n      const toValue = toMap[typedKey]\n      if (toValue !== undefined && toValue !== fromValue) {\n        throw new WERR_INVALID_PARAMETER(\n          'syncMap',\n          `an unmapped id or the same mapped id. ${key} maps to ${toValue} not equal to ${fromValue}`\n        )\n      }\n      if (toValue === undefined) toMap[typedKey] = value\n    }\n  }\n\n  /**\n   * Merge additions to the syncMap\n   * @param iSyncMap\n   */\n  mergeSyncMap(iSyncMap: SyncMap) {\n    EntitySyncState.mergeIdMap(iSyncMap.provenTx.idMap, this.syncMap.provenTx.idMap)\n    EntitySyncState.mergeIdMap(iSyncMap.outputBasket.idMap, this.syncMap.outputBasket.idMap)\n    EntitySyncState.mergeIdMap(iSyncMap.transaction.idMap, this.syncMap.transaction.idMap)\n    EntitySyncState.mergeIdMap(iSyncMap.provenTxReq.idMap, this.syncMap.provenTxReq.idMap)\n    EntitySyncState.mergeIdMap(iSyncMap.txLabel.idMap, this.syncMap.txLabel.idMap)\n    EntitySyncState.mergeIdMap(iSyncMap.output.idMap, this.syncMap.output.idMap)\n    EntitySyncState.mergeIdMap(iSyncMap.outputTag.idMap, this.syncMap.outputTag.idMap)\n    EntitySyncState.mergeIdMap(iSyncMap.certificate.idMap, this.syncMap.certificate.idMap)\n    EntitySyncState.mergeIdMap(iSyncMap.commission.idMap, this.syncMap.commission.idMap)\n  }\n\n  // stringified api properties\n\n  errorLocal: SyncError | undefined\n  errorOther: SyncError | undefined\n  syncMap: SyncMap\n\n  /**\n   * Eliminate any properties besides code and description\n   */\n  private errorToString(e: SyncError | undefined): string | undefined {\n    if (e == null) return undefined\n    const es: SyncError = {\n      code: e.code,\n      description: e.description,\n      stack: e.stack\n    }\n    return JSON.stringify(es)\n  }\n\n  override equals(ei: TableSyncState, syncMap?: SyncMap | undefined): boolean {\n    return false\n  }\n\n  override async mergeNew(storage: EntityStorage, userId: number, syncMap: SyncMap, trx?: TrxToken): Promise<void> {\n    // SyncState records are never created during a merge; they are managed separately\n  }\n\n  override async mergeExisting(\n    storage: EntityStorage,\n    since: Date | undefined,\n    ei: TableSyncState,\n    syncMap: SyncMap,\n    trx?: TrxToken\n  ): Promise<boolean> {\n    return false\n  }\n\n  makeRequestSyncChunkArgs(\n    forIdentityKey: string,\n    forStorageIdentityKey: string,\n    maxRoughSize?: number,\n    maxItems?: number\n  ): RequestSyncChunkArgs {\n    const a: RequestSyncChunkArgs = {\n      identityKey: forIdentityKey,\n      maxRoughSize: maxRoughSize || 10000000,\n      maxItems: maxItems || 1000,\n      offsets: [],\n      since: this.when,\n      fromStorageIdentityKey: this.storageIdentityKey,\n      toStorageIdentityKey: forStorageIdentityKey\n    }\n    for (const ess of [\n      this.syncMap.provenTx,\n      this.syncMap.outputBasket,\n      this.syncMap.outputTag,\n      this.syncMap.txLabel,\n      this.syncMap.transaction,\n      this.syncMap.output,\n      this.syncMap.txLabelMap,\n      this.syncMap.outputTagMap,\n      this.syncMap.certificate,\n      this.syncMap.certificateField,\n      this.syncMap.commission,\n      this.syncMap.provenTxReq\n    ]) {\n      a.offsets.push({ name: ess.entityName, offset: ess.count })\n    }\n    return a\n  }\n\n  static syncChunkSummary(c: SyncChunk): string {\n    let log = `SYNC CHUNK SUMMARY\n  from storage: ${c.fromStorageIdentityKey}\n  to storage: ${c.toStorageIdentityKey}\n  for user: ${c.userIdentityKey}\n`\n    if (c.user != null) log += `  USER activeStorage ${c.user.activeStorage}\\n`\n    log += formatSyncSection('PROVEN_TXS', c.provenTxs, r => `${r.provenTxId} ${r.txid}`)\n    log += formatSyncSection(\n      'PROVEN_TX_REQS',\n      c.provenTxReqs,\n      r => `${r.provenTxReqId} ${r.txid} ${r.status} ${r.provenTxId || ''}`\n    )\n    log += formatSyncSection(\n      'TRANSACTIONS',\n      c.transactions,\n      r => `${r.transactionId} ${r.txid} ${r.status} ${r.provenTxId || ''} sats:${r.satoshis}`\n    )\n    log += formatSyncSection(\n      'OUTPUTS',\n      c.outputs,\n      r => `${r.outputId} ${r.txid}.${r.vout} ${r.transactionId} ${r.spendable ? 'spendable' : ''} sats:${r.satoshis}`\n    )\n    return log\n  }\n\n  async processSyncChunk(\n    writer: EntityStorage,\n    args: RequestSyncChunkArgs,\n    chunk: SyncChunk\n  ): Promise<{\n    done: boolean\n    maxUpdated_at: Date | undefined\n    updates: number\n    inserts: number\n  }> {\n    const mes = [\n      new MergeEntity(chunk.provenTxs, EntityProvenTx.mergeFind, this.syncMap.provenTx),\n      new MergeEntity(chunk.outputBaskets, EntityOutputBasket.mergeFind, this.syncMap.outputBasket),\n      new MergeEntity(chunk.outputTags, EntityOutputTag.mergeFind, this.syncMap.outputTag),\n      new MergeEntity(chunk.txLabels, EntityTxLabel.mergeFind, this.syncMap.txLabel),\n      new MergeEntity(chunk.transactions, EntityTransaction.mergeFind, this.syncMap.transaction),\n      new MergeEntity(chunk.outputs, EntityOutput.mergeFind, this.syncMap.output),\n      new MergeEntity(chunk.txLabelMaps, EntityTxLabelMap.mergeFind, this.syncMap.txLabelMap),\n      new MergeEntity(chunk.outputTagMaps, EntityOutputTagMap.mergeFind, this.syncMap.outputTagMap),\n      new MergeEntity(chunk.certificates, EntityCertificate.mergeFind, this.syncMap.certificate),\n      new MergeEntity(chunk.certificateFields, EntityCertificateField.mergeFind, this.syncMap.certificateField),\n      new MergeEntity(chunk.commissions, EntityCommission.mergeFind, this.syncMap.commission),\n      new MergeEntity(chunk.provenTxReqs, EntityProvenTxReq.mergeFind, this.syncMap.provenTxReq)\n    ]\n\n    let updates = 0\n    let inserts = 0\n    let maxUpdated_at: Date | undefined\n    let done = true\n\n    // Merge User\n    if (chunk.user != null) {\n      const ei = chunk.user\n      const { found, eo } = await EntityUser.mergeFind(writer, this.userId, ei)\n      if (found) {\n        if (await eo.mergeExisting(writer, args.since, ei)) {\n          maxUpdated_at = maxDate(maxUpdated_at, ei.updated_at)\n          updates++\n        }\n      }\n    }\n\n    // Merge everything else...\n    for (const me of mes) {\n      const r = await me.merge(args.since, writer, this.userId, this.syncMap)\n      // The counts become the offsets for the next chunk.\n      me.esm.count += me.stateArray?.length || 0\n      updates += r.updates\n      inserts += r.inserts\n      maxUpdated_at = maxDate(maxUpdated_at, me.esm.maxUpdated_at)\n      // If any entity type either did not report results or if there were at least one, then we aren't done.\n      if (me.stateArray === undefined || me.stateArray.length > 0) done = false\n    }\n\n    if (done) {\n      // Next batch starts further in the future with offsets of zero.\n      this.when = maxUpdated_at\n      for (const me of mes) me.esm.count = 0\n    }\n\n    await this.updateStorage(writer, false)\n\n    return { done, maxUpdated_at, updates, inserts }\n  }\n}\n","import {\n  AbortActionArgs,\n  AbortActionResult,\n  Beef,\n  ChainTracker,\n  InternalizeActionArgs,\n  ListActionsResult,\n  ListCertificatesResult,\n  ListOutputsResult,\n  MerklePath,\n  RelinquishCertificateArgs,\n  RelinquishOutputArgs,\n  Validation\n} from '@bsv/sdk'\nimport { EntitySyncState } from '../storage/schema/entities'\nimport * as sdk from '../sdk'\nimport {\n  TableCertificate,\n  TableCertificateX,\n  TableOutput,\n  TableOutputBasket,\n  TableProvenTx,\n  TableProvenTxReq,\n  TableSettings,\n  TableUser\n} from '../storage/schema/tables'\nimport { StorageProvider } from './StorageProvider'\nimport { StorageClient } from './remoting/StorageClient'\n\nclass ManagedStorage {\n  isAvailable: boolean\n  isStorageProvider: boolean\n  settings?: TableSettings\n  user?: TableUser\n\n  constructor(public storage: sdk.WalletStorageProvider) {\n    this.isStorageProvider = storage.isStorageProvider()\n    this.isAvailable = false\n  }\n}\n\n/**\n * The `WalletStorageManager` class delivers authentication checking storage access to the wallet.\n *\n * If manages multiple `StorageBase` derived storage services: one actice, the rest as backups.\n *\n * Of the storage services, one is 'active' at any one time.\n * On startup, and whenever triggered by the wallet, `WalletStorageManager` runs a syncrhonization sequence:\n *\n * 1. While synchronizing, all other access to storage is blocked waiting.\n * 2. The active service is confirmed, potentially triggering a resolution process if there is disagreement.\n * 3. Changes are pushed from the active storage service to each inactive, backup service.\n *\n * Some storage services do not support multiple writers. `WalletStorageManager` manages wait-blocking write requests\n * for these services.\n */\nexport class WalletStorageManager implements sdk.WalletStorage {\n  /**\n   * All configured stores including current active, backups, and conflicting actives.\n   */\n  _stores: ManagedStorage[] = []\n  /**\n   * True if makeAvailable has been run and access to managed stores (active) is allowed\n   */\n  _isAvailable: boolean = false\n  /**\n   * The current active store which is only enabled if the store's user record activeStorage property matches its settings record storageIdentityKey property\n   */\n  _active?: ManagedStorage\n  /**\n   * Stores to which state is pushed by updateBackups.\n   */\n  _backups?: ManagedStorage[]\n  /**\n   * Stores whose user record activeStorage property disagrees with the active store's user record activeStorage property.\n   */\n  _conflictingActives?: ManagedStorage[]\n  /**\n   * identityKey is always valid, userId and isActive are valid only if _isAvailable\n   */\n  _authId: sdk.AuthId\n  /**\n   * Configured services if any. If valid, shared with stores (which may ignore it).\n   */\n  _services?: sdk.WalletServices\n\n  /**\n   * Creates a new WalletStorageManager with the given identityKey and optional active and backup storage providers.\n   *\n   * @param identityKey The identity key of the user for whom this wallet is being managed.\n   * @param active An optional active storage provider. If not provided, no active storage will be set.\n   * @param backups An optional array of backup storage providers. If not provided, no backups will be set.\n   */\n  constructor(identityKey: string, active?: sdk.WalletStorageProvider, backups?: sdk.WalletStorageProvider[]) {\n    const stores = [...(backups ?? [])]\n    if (active != null) stores.unshift(active)\n    this._stores = stores.map(s => new ManagedStorage(s))\n    this._authId = { identityKey }\n  }\n\n  isStorageProvider(): boolean {\n    return false\n  }\n\n  isAvailable(): boolean {\n    return this._isAvailable\n  }\n\n  /**\n   * The active storage is \"enabled\" only if its `storageIdentityKey` matches the user's currently selected `activeStorage`,\n   * and only if there are no stores with conflicting `activeStorage` selections.\n   *\n   * A wallet may be created without including the user's currently selected active storage. This allows readonly access to their wallet data.\n   *\n   * In addition, if there are conflicting `activeStorage` selections among backup storage providers then the active remains disabled.\n   */\n  get isActiveEnabled(): boolean {\n    return (\n      this._active !== undefined &&\n      (this._active.settings as TableSettings).storageIdentityKey === (this._active.user as TableUser).activeStorage &&\n      this._conflictingActives?.length === 0\n    )\n  }\n\n  /**\n   * @returns true if at least one WalletStorageProvider has been added.\n   */\n  canMakeAvailable(): boolean {\n    return this._stores.length > 0\n  }\n\n  /**\n   * This async function must be called after construction and before\n   * any other async function can proceed.\n   *\n   * Runs through `_stores` validating all properties and partitioning across `_active`, `_backups`, `_conflictingActives`.\n   *\n   * @throws WERR_INVALID_PARAMETER if canMakeAvailable returns false.\n   *\n   * @returns {TableSettings} from the active storage.\n   */\n  private async ensureStoreAvailable(store: ManagedStorage): Promise<void> {\n    if (store.isAvailable && store.settings != null && store.user != null) return\n    store.settings = await store.storage.makeAvailable()\n    const r = await store.storage.findOrInsertUser(this._authId.identityKey)\n    store.user = r.user\n    store.isAvailable = true\n  }\n\n  private selectActiveFromStore(store: ManagedStorage, backups: ManagedStorage[]): void {\n    if (this._active == null) {\n      // _stores[0] becomes the default active store.\n      this._active = store\n      return\n    }\n    const ua = (store.user as TableUser).activeStorage\n    const si = (store.settings as TableSettings).storageIdentityKey\n    if (ua === si && !this.isActiveEnabled) {\n      // This store's user record selects it as the enabled active storage — swap.\n      backups.push(this._active)\n      this._active = store\n    } else {\n      backups.push(store)\n    }\n  }\n\n  async makeAvailable(): Promise<TableSettings> {\n    if (this._isAvailable) return (this._active as ManagedStorage).settings as TableSettings\n\n    this._active = undefined\n    this._backups = []\n    this._conflictingActives = []\n\n    if (this._stores.length < 1) {\n      throw new sdk.WERR_INVALID_PARAMETER('active', 'valid. Must add active storage provider to wallet.')\n    }\n\n    const backups: ManagedStorage[] = []\n    for (const store of this._stores) {\n      await this.ensureStoreAvailable(store)\n      this.selectActiveFromStore(store, backups)\n    }\n\n    // Partition backups into proper backups vs conflicting actives.\n    const si = (this._active as unknown as ManagedStorage).settings?.storageIdentityKey\n    for (const store of backups) {\n      if ((store.user as TableUser).activeStorage !== si) this._conflictingActives.push(store)\n      else this._backups.push(store)\n    }\n\n    this._isAvailable = true\n    this._authId.userId = (this._active as unknown as ManagedStorage).user?.userId\n    this._authId.isActive = this.isActiveEnabled\n\n    return (this._active as unknown as ManagedStorage).settings as TableSettings\n  }\n\n  private verifyActive(): ManagedStorage {\n    if (this._active == null || !this._isAvailable) {\n      throw new sdk.WERR_INVALID_OPERATION(\n        'An active WalletStorageProvider must be added to this WalletStorageManager and makeAvailable must be called.'\n      )\n    }\n    return this._active\n  }\n\n  async getAuth(mustBeActive?: boolean): Promise<sdk.AuthId> {\n    if (!this.isAvailable()) await this.makeAvailable()\n    if (mustBeActive === true && this._authId.isActive !== true) throw new sdk.WERR_NOT_ACTIVE()\n    return this._authId\n  }\n\n  async getUserId(): Promise<number> {\n    return (await this.getAuth()).userId as number\n  }\n\n  getActive(): sdk.WalletStorageProvider {\n    return this.verifyActive().storage\n  }\n\n  getActiveSettings(): TableSettings {\n    return this.verifyActive().settings as TableSettings\n  }\n\n  getActiveUser(): TableUser {\n    return this.verifyActive().user as TableUser\n  }\n\n  getActiveStore(): string {\n    return (this.verifyActive().settings as TableSettings).storageIdentityKey\n  }\n\n  getActiveStoreName(): string {\n    return (this.verifyActive().settings as TableSettings).storageName\n  }\n\n  getBackupStores(): string[] {\n    this.verifyActive()\n    return (this._backups as ManagedStorage[]).map(b => (b.settings as TableSettings).storageIdentityKey)\n  }\n\n  getConflictingStores(): string[] {\n    this.verifyActive()\n    return (this._conflictingActives as ManagedStorage[]).map(b => (b.settings as TableSettings).storageIdentityKey)\n  }\n\n  getAllStores(): string[] {\n    this.verifyActive()\n    return this._stores.map(b => (b.settings as TableSettings).storageIdentityKey)\n  }\n\n  private readonly readerLocks: Array<(value: void | PromiseLike<void>) => void> = []\n  private readonly writerLocks: Array<(value: void | PromiseLike<void>) => void> = []\n  private readonly syncLocks: Array<(value: void | PromiseLike<void>) => void> = []\n  private readonly spLocks: Array<(value: void | PromiseLike<void>) => void> = []\n\n  private async getActiveLock(lockQueue: Array<(value: void | PromiseLike<void>) => void>): Promise<void> {\n    if (!this.isAvailable()) await this.makeAvailable()\n\n    let resolveNewLock: () => void = () => {}\n    const newLock = new Promise<void>(resolve => {\n      resolveNewLock = resolve\n      lockQueue.push(resolve)\n    })\n    if (lockQueue.length === 1) {\n      resolveNewLock()\n    }\n    await newLock\n  }\n\n  private releaseActiveLock(queue: Array<(value: void | PromiseLike<void>) => void>): void {\n    queue.shift() // Remove the current lock from the queue\n    if (queue.length > 0) {\n      queue[0]()\n    }\n  }\n\n  private async getActiveForReader(): Promise<sdk.WalletStorageReader> {\n    await this.getActiveLock(this.readerLocks)\n    return this.getActive()\n  }\n\n  private releaseActiveForReader(): void {\n    this.releaseActiveLock(this.readerLocks)\n  }\n\n  private async getActiveForWriter(): Promise<sdk.WalletStorageWriter> {\n    await this.getActiveLock(this.readerLocks)\n    await this.getActiveLock(this.writerLocks)\n    return this.getActive()\n  }\n\n  private releaseActiveForWriter(): void {\n    this.releaseActiveLock(this.writerLocks)\n    this.releaseActiveLock(this.readerLocks)\n  }\n\n  private async getActiveForSync(): Promise<sdk.WalletStorageSync> {\n    await this.getActiveLock(this.readerLocks)\n    await this.getActiveLock(this.writerLocks)\n    await this.getActiveLock(this.syncLocks)\n    return this.getActive()\n  }\n\n  private releaseActiveForSync(): void {\n    this.releaseActiveLock(this.syncLocks)\n    this.releaseActiveLock(this.writerLocks)\n    this.releaseActiveLock(this.readerLocks)\n  }\n\n  private async getActiveForStorageProvider(): Promise<StorageProvider> {\n    await this.getActiveLock(this.readerLocks)\n    await this.getActiveLock(this.writerLocks)\n    await this.getActiveLock(this.syncLocks)\n    await this.getActiveLock(this.spLocks)\n\n    const active = this.getActive()\n    // We can finally confirm that active storage is still able to support `StorageProvider`\n    if (!active.isStorageProvider()) {\n      throw new sdk.WERR_INVALID_OPERATION(\n        'Active \"WalletStorageProvider\" does not support \"StorageProvider\" interface.'\n      )\n    }\n    // Allow the sync to proceed on the active store.\n    return active as unknown as StorageProvider\n  }\n\n  private releaseActiveForStorageProvider(): void {\n    this.releaseActiveLock(this.spLocks)\n    this.releaseActiveLock(this.syncLocks)\n    this.releaseActiveLock(this.writerLocks)\n    this.releaseActiveLock(this.readerLocks)\n  }\n\n  async runAsWriter<R>(writer: (active: sdk.WalletStorageWriter) => Promise<R>): Promise<R> {\n    try {\n      const active = await this.getActiveForWriter()\n      const r = await writer(active)\n      return r\n    } finally {\n      this.releaseActiveForWriter()\n    }\n  }\n\n  async runAsReader<R>(reader: (active: sdk.WalletStorageReader) => Promise<R>): Promise<R> {\n    try {\n      const active = await this.getActiveForReader()\n      const r = await reader(active)\n      return r\n    } finally {\n      this.releaseActiveForReader()\n    }\n  }\n\n  /**\n   *\n   * @param sync the function to run with sync access lock\n   * @param activeSync from chained sync functions, active storage already held under sync access lock.\n   * @returns\n   */\n  async runAsSync<R>(\n    sync: (active: sdk.WalletStorageSync) => Promise<R>,\n    activeSync?: sdk.WalletStorageSync\n  ): Promise<R> {\n    try {\n      const active = activeSync ?? (await this.getActiveForSync())\n      const r = await sync(active)\n      return r\n    } finally {\n      if (activeSync == null) this.releaseActiveForSync()\n    }\n  }\n\n  async runAsStorageProvider<R>(sync: (active: StorageProvider) => Promise<R>): Promise<R> {\n    try {\n      const active = await this.getActiveForStorageProvider()\n      const r = await sync(active)\n      return r\n    } finally {\n      this.releaseActiveForStorageProvider()\n    }\n  }\n\n  /**\n   *\n   * @returns true if the active `WalletStorageProvider` also implements `StorageProvider`\n   */\n  isActiveStorageProvider(): boolean {\n    return this.getActive().isStorageProvider()\n  }\n\n  async addWalletStorageProvider(provider: sdk.WalletStorageProvider): Promise<void> {\n    await provider.makeAvailable()\n    if (this._services != null) provider.setServices(this._services)\n    this._stores.push(new ManagedStorage(provider))\n    this._isAvailable = false\n    await this.makeAvailable()\n  }\n\n  setServices(v: sdk.WalletServices): void {\n    this._services = v\n    for (const store of this._stores) store.storage.setServices(v)\n  }\n\n  getServices(): sdk.WalletServices {\n    if (this._services == null) throw new sdk.WERR_INVALID_OPERATION('Must setServices first.')\n    return this._services\n  }\n\n  getSettings(): TableSettings {\n    return this.getActive().getSettings()\n  }\n\n  async migrate(storageName: string, storageIdentityKey: string): Promise<string> {\n    return await this.runAsWriter(async writer => {\n      return await writer.migrate(storageName, storageIdentityKey)\n    })\n  }\n\n  async destroy(): Promise<void> {\n    if (this._stores.length < 1) return\n    return await this.runAsWriter(async _writer => {\n      for (const store of this._stores) await store.storage.destroy()\n    })\n  }\n\n  async findOrInsertUser(identityKey: string): Promise<{ user: TableUser; isNew: boolean }> {\n    const auth = await this.getAuth()\n    if (identityKey !== auth.identityKey) throw new sdk.WERR_UNAUTHORIZED()\n\n    return await this.runAsWriter(async writer => {\n      const r = await writer.findOrInsertUser(identityKey)\n\n      if (auth.userId != null && auth.userId !== 0 && auth.userId !== r.user.userId) {\n        throw new sdk.WERR_INTERNAL('userId may not change for given identityKey')\n      }\n      this._authId.userId = r.user.userId\n      return r\n    })\n  }\n\n  async abortAction(args: AbortActionArgs): Promise<AbortActionResult> {\n    Validation.validateAbortActionArgs(args)\n    return await this.runAsWriter(async writer => {\n      const auth = await this.getAuth(true)\n      return await writer.abortAction(auth, args)\n    })\n  }\n\n  async createAction(vargs: Validation.ValidCreateActionArgs): Promise<sdk.StorageCreateActionResult> {\n    return await this.runAsWriter(async writer => {\n      const auth = await this.getAuth(true)\n      return await writer.createAction(auth, vargs)\n    })\n  }\n\n  async internalizeAction(args: InternalizeActionArgs): Promise<sdk.StorageInternalizeActionResult> {\n    Validation.validateInternalizeActionArgs(args)\n    return await this.runAsWriter(async writer => {\n      const auth = await this.getAuth(true)\n      return await writer.internalizeAction(auth, args)\n    })\n  }\n\n  async relinquishCertificate(args: RelinquishCertificateArgs): Promise<number> {\n    Validation.validateRelinquishCertificateArgs(args)\n    return await this.runAsWriter(async writer => {\n      const auth = await this.getAuth(true)\n      return await writer.relinquishCertificate(auth, args)\n    })\n  }\n\n  async relinquishOutput(args: RelinquishOutputArgs): Promise<number> {\n    Validation.validateRelinquishOutputArgs(args)\n    return await this.runAsWriter(async writer => {\n      const auth = await this.getAuth(true)\n      return await writer.relinquishOutput(auth, args)\n    })\n  }\n\n  async processAction(args: sdk.StorageProcessActionArgs): Promise<sdk.StorageProcessActionResults> {\n    return await this.runAsWriter(async writer => {\n      const auth = await this.getAuth(true)\n      return await writer.processAction(auth, args)\n    })\n  }\n\n  async getCapabilities(): Promise<sdk.StorageCapabilities> {\n    return await this.runAsReader(async () => await this.getActive().getCapabilities())\n  }\n\n  async beginActionBatch(args: sdk.BeginActionBatchArgs): Promise<sdk.BeginActionBatchResult> {\n    return await this.runAsWriter(async writer => await writer.beginActionBatch(await this.getAuth(true), args))\n  }\n\n  async extendActionBatch(args: sdk.ExtendActionBatchArgs): Promise<sdk.ExtendActionBatchResult> {\n    return await this.runAsWriter(async writer => await writer.extendActionBatch(await this.getAuth(true), args))\n  }\n\n  async renewActionBatch(batchId: string): Promise<sdk.RenewActionBatchResult> {\n    return await this.runAsWriter(async writer => await writer.renewActionBatch(await this.getAuth(true), batchId))\n  }\n\n  async prepareActionBatchCommit(manifest: sdk.ActionBatchManifest): Promise<sdk.PrepareActionBatchCommitResult> {\n    return await this.runAsWriter(\n      async writer => await writer.prepareActionBatchCommit(await this.getAuth(true), manifest)\n    )\n  }\n\n  async putActionBatchBlob(args: sdk.PutActionBatchBlobArgs): Promise<void> {\n    return await this.runAsWriter(async writer => await writer.putActionBatchBlob(await this.getAuth(true), args))\n  }\n\n  async putActionBatchPack(args: sdk.PutActionBatchPackArgs): Promise<void> {\n    return await this.runAsWriter(async writer => {\n      if (writer.putActionBatchPack == null) {\n        throw new sdk.WERR_NOT_IMPLEMENTED('packed action batch uploads are not available')\n      }\n      await writer.putActionBatchPack(await this.getAuth(true), args)\n    })\n  }\n\n  async commitActionBatch(manifest: sdk.ActionBatchManifest): Promise<sdk.CommitActionBatchResult> {\n    return await this.runAsWriter(async writer => await writer.commitActionBatch(await this.getAuth(true), manifest))\n  }\n\n  async commitActionBatchByDigest(args: sdk.CommitActionBatchByDigestArgs): Promise<sdk.CommitActionBatchResult> {\n    return await this.runAsWriter(async writer => {\n      if (writer.commitActionBatchByDigest == null) {\n        throw new sdk.WERR_NOT_IMPLEMENTED('digest-only action batch commit is not available')\n      }\n      return await writer.commitActionBatchByDigest(await this.getAuth(true), args)\n    })\n  }\n\n  async abortActionBatch(batchId: string): Promise<sdk.AbortActionBatchResult> {\n    return await this.runAsWriter(async writer => await writer.abortActionBatch(await this.getAuth(true), batchId))\n  }\n\n  async insertCertificate(certificate: TableCertificate): Promise<number> {\n    return await this.runAsWriter(async writer => {\n      const auth = await this.getAuth(true)\n      return await writer.insertCertificateAuth(auth, certificate)\n    })\n  }\n\n  async listActions(vargs: Validation.ValidListActionsArgs): Promise<ListActionsResult> {\n    const auth = await this.getAuth()\n    return await this.runAsReader(async reader => {\n      return await reader.listActions(auth, vargs)\n    })\n  }\n\n  async listCertificates(args: Validation.ValidListCertificatesArgs): Promise<ListCertificatesResult> {\n    const auth = await this.getAuth()\n    return await this.runAsReader(async reader => {\n      return await reader.listCertificates(auth, args)\n    })\n  }\n\n  async listOutputs(vargs: Validation.ValidListOutputsArgs): Promise<ListOutputsResult> {\n    const auth = await this.getAuth()\n    return await this.runAsReader(async reader => {\n      return await reader.listOutputs(auth, vargs)\n    })\n  }\n\n  async findCertificates(args: sdk.FindCertificatesArgs): Promise<TableCertificateX[]> {\n    const auth = await this.getAuth()\n    return await this.runAsReader(async reader => {\n      return await reader.findCertificatesAuth(auth, args)\n    })\n  }\n\n  async findOutputBaskets(args: sdk.FindOutputBasketsArgs): Promise<TableOutputBasket[]> {\n    const auth = await this.getAuth()\n    return await this.runAsReader(async reader => {\n      return await reader.findOutputBasketsAuth(auth, args)\n    })\n  }\n\n  async findOutputs(args: sdk.FindOutputsArgs): Promise<TableOutput[]> {\n    const auth = await this.getAuth()\n    return await this.runAsReader(async reader => {\n      return await reader.findOutputsAuth(auth, args)\n    })\n  }\n\n  async findProvenTxReqs(args: sdk.FindProvenTxReqsArgs): Promise<TableProvenTxReq[]> {\n    return await this.runAsReader(async reader => {\n      return await reader.findProvenTxReqs(args)\n    })\n  }\n\n  /**\n   * For each proven_txs record currently sourcing its transaction merkle proof from the given deactivated header,\n   * attempt to reprove the transaction against the current chain,\n   * updating the proven_txs record if a new valid proof is found.\n   *\n   * @param deactivatedHash An orphaned header than may have served as a proof source for proven_txs records.\n   * @returns\n   */\n  async reproveHeader(deactivatedHash: string): Promise<sdk.ReproveHeaderResult> {\n    const r: sdk.ReproveHeaderResult = { log: '', updated: [], unchanged: [], unavailable: [] }\n\n    // Lookup all the proven_txs records matching the deactivated headers\n    let ptxs: TableProvenTx[] = []\n    await this.runAsStorageProvider(async sp => {\n      ptxs = await sp.findProvenTxs({ partial: { blockHash: deactivatedHash } })\n    })\n\n    r.log += `  block ${deactivatedHash} orphaned with ${ptxs.length} impacted transactions\\n`\n\n    for (const ptx of ptxs) {\n      // Loop over proven_txs records matching the deactivated header\n      const rp = await this.reproveProven(ptx, true)\n\n      r.log += rp.log\n      if (rp.unavailable) r.unavailable.push(ptx)\n      if (rp.unchanged) r.unchanged.push(ptx)\n      if (rp.updated != null) r.updated.push({ was: ptx, update: rp.updated.update, logUpdate: rp.updated.logUpdate })\n    }\n\n    if (r.updated.length > 0) {\n      await this.runAsStorageProvider(async sp => {\n        for (const u of r.updated) {\n          await sp.updateProvenTx(u.was.provenTxId, u.update)\n          r.log += `    txid ${u.was.txid} proof data updated\\n` + u.logUpdate\n        }\n      })\n    }\n\n    return r\n  }\n\n  /**\n   * For all proven_txs records at the given height currently tied to the given stale merkleRoot,\n   * attempt to reprove them against the current chain and update proof data if new valid proofs are found.\n   *\n   * This is intended for backup auditing of recent heights after the primary reorg event path has run.\n   */\n  async reproveHeightMerkleRoot(height: number, staleMerkleRoot: string): Promise<sdk.ReproveHeaderResult> {\n    const r: sdk.ReproveHeaderResult = { log: '', updated: [], unchanged: [], unavailable: [] }\n\n    let ptxs: TableProvenTx[] = []\n    await this.runAsStorageProvider(async sp => {\n      ptxs = await sp.findProvenTxs({ partial: { height, merkleRoot: staleMerkleRoot } })\n    })\n\n    r.log += `  height ${height} stale merkleRoot ${staleMerkleRoot} with ${ptxs.length} impacted transactions\\n`\n\n    for (const ptx of ptxs) {\n      const rp = await this.reproveProven(ptx, true)\n\n      r.log += rp.log\n      if (rp.unavailable) r.unavailable.push(ptx)\n      if (rp.unchanged) r.unchanged.push(ptx)\n      if (rp.updated != null) r.updated.push({ was: ptx, update: rp.updated.update, logUpdate: rp.updated.logUpdate })\n    }\n\n    if (r.updated.length > 0) {\n      await this.runAsStorageProvider(async sp => {\n        for (const u of r.updated) {\n          await sp.updateProvenTx(u.was.provenTxId, u.update)\n          r.log += `    txid ${u.was.txid} proof data updated\\n` + u.logUpdate\n        }\n      })\n    }\n\n    return r\n  }\n\n  /**\n   * Attempt to reprove the transaction against the current chain,\n   * If a new valid proof is found and noUpdate is not true,\n   * update the proven_txs record with new block and merkle proof data.\n   * If noUpdate is true, the update to be applied is available in the returned result.\n   *\n   * @param ptx proven_txs record to reprove\n   * @param noUpdate\n   * @returns\n   */\n  private async evaluateNewMerkleLeaf(\n    ptx: TableProvenTx,\n    mp: MerklePath,\n    leaf: { offset: number },\n    blockHash: string,\n    chaintracker: ChainTracker,\n    r: sdk.ReproveProvenResult,\n    update: Partial<TableProvenTx>\n  ): Promise<void> {\n    if (blockHash === ptx.blockHash) {\n      r.log += `    txid ${ptx.txid} merkle path update still based on deactivated header ${ptx.blockHash}\\n`\n      r.unchanged = true\n      return\n    }\n    const merkleRoot = mp.computeRoot(ptx.txid)\n    const isValid = await chaintracker.isValidRootForHeight(merkleRoot, update.height as number)\n    const heightChange = ptx.height === update.height ? 'unchanged' : `-> ${String(update.height)}`\n    const logUpdate = `      height ${ptx.height} ${heightChange}\\n`\n    r.log += `      blockHash ${ptx.blockHash} -> ${String(update.blockHash)}\\n`\n    r.log += `      merkleRoot ${ptx.merkleRoot} -> ${String(update.merkleRoot)}\\n`\n    r.log += `      index ${ptx.index} -> ${String(update.index)}\\n`\n    if (isValid) {\n      r.updated = { update, logUpdate }\n    } else {\n      r.log += `    txid ${ptx.txid} chaintracker fails to confirm updated merkle path update invalid\\n` + logUpdate\n      r.unavailable = true\n    }\n  }\n\n  async reproveProven(ptx: TableProvenTx, noUpdate?: boolean): Promise<sdk.ReproveProvenResult> {\n    const r: sdk.ReproveProvenResult = { log: '', updated: undefined, unchanged: false, unavailable: false }\n    const services = this.getServices()\n    const chaintracker = await services.getChainTracker()\n\n    const mpr = await services.getMerklePath(ptx.txid)\n    if (mpr.merklePath != null && mpr.header != null) {\n      const mp = mpr.merklePath\n      const h = mpr.header\n      const leaf = mp.path[0].find(leaf => leaf.txid === true && leaf.hash === ptx.txid)\n      if (leaf != null) {\n        const update: Partial<TableProvenTx> = {\n          height: mp.blockHeight,\n          index: leaf.offset,\n          merklePath: mp.toBinary(),\n          merkleRoot: h.merkleRoot,\n          blockHash: h.hash\n        }\n        await this.evaluateNewMerkleLeaf(ptx, mp, leaf, h.hash, chaintracker, r, update)\n      } else {\n        r.log += `    txid ${ptx.txid} merkle path update doesn't include txid\\n`\n        r.unavailable = true\n      }\n    } else {\n      r.log += `    txid ${ptx.txid} merkle path update unavailable\\n`\n      r.unavailable = true\n    }\n\n    if (r.updated != null && noUpdate !== true) {\n      const updatedSnapshot = r.updated\n      await this.runAsStorageProvider(async sp => {\n        await sp.updateProvenTx(ptx.provenTxId, updatedSnapshot.update)\n        r.log += `    txid ${ptx.txid} proof data updated\\n` + updatedSnapshot.logUpdate\n      })\n    }\n\n    return r\n  }\n\n  async syncFromReader(\n    identityKey: string,\n    reader: sdk.WalletStorageSyncReader,\n    activeSync?: sdk.WalletStorageSync,\n    log: string = ''\n  ): Promise<{ inserts: number; updates: number; log: string }> {\n    const auth = await this.getAuth()\n    if (identityKey !== auth.identityKey) throw new sdk.WERR_UNAUTHORIZED()\n\n    const readerSettings = await reader.makeAvailable()\n\n    let inserts = 0\n    let updates = 0\n\n    log = await this.runAsSync(async sync => {\n      const writer = sync\n      const writerSettings = this.getSettings()\n\n      log += `syncFromReader from ${readerSettings.storageName} to ${writerSettings.storageName}\\n`\n\n      let i = -1\n      for (;;) {\n        i++\n        const ss = await EntitySyncState.fromStorage(writer, identityKey, readerSettings)\n        const args = ss.makeRequestSyncChunkArgs(identityKey, writerSettings.storageIdentityKey)\n        const chunk = await reader.getSyncChunk(args)\n        if (chunk.user != null) {\n          // Merging state from a reader cannot update activeStorage\n          chunk.user.activeStorage = ((this._active as ManagedStorage).user as TableUser).activeStorage\n        }\n        const r = await writer.processSyncChunk(args, chunk)\n        inserts += r.inserts\n        updates += r.updates\n        log += `chunk ${i} inserted ${r.inserts} updated ${r.updates} ${String(r.maxUpdated_at)}\\n`\n        if (r.done) break\n      }\n      log += `syncFromReader complete: ${inserts} inserts, ${updates} updates\\n`\n      return log\n    }, activeSync)\n\n    return { inserts, updates, log }\n  }\n\n  async syncToWriter(\n    auth: sdk.AuthId,\n    writer: sdk.WalletStorageProvider,\n    activeSync?: sdk.WalletStorageSync,\n    log: string = '',\n    progLog?: (s: string) => string\n  ): Promise<{ inserts: number; updates: number; log: string }> {\n    progLog ||= s => s\n    const identityKey = auth.identityKey\n\n    const writerSettings = await writer.makeAvailable()\n\n    let inserts = 0\n    let updates = 0\n\n    log = await this.runAsSync(async sync => {\n      const reader = sync\n      const readerSettings = reader.getSettings()\n\n      log += progLog(`syncToWriter from ${readerSettings.storageName} to ${writerSettings.storageName}\\n`)\n\n      let i = -1\n      for (;;) {\n        i++\n        const ss = await EntitySyncState.fromStorage(writer, identityKey, readerSettings)\n        const args = ss.makeRequestSyncChunkArgs(identityKey, writerSettings.storageIdentityKey)\n        const chunk = await reader.getSyncChunk(args)\n        log += EntitySyncState.syncChunkSummary(chunk)\n        const r = await writer.processSyncChunk(args, chunk)\n        inserts += r.inserts\n        updates += r.updates\n        log += progLog(`chunk ${i} inserted ${r.inserts} updated ${r.updates} ${String(r.maxUpdated_at)}\\n`)\n        if (r.done) break\n      }\n      log += progLog(`syncToWriter complete: ${inserts} inserts, ${updates} updates\\n`)\n      return log\n    }, activeSync)\n\n    return { inserts, updates, log }\n  }\n\n  async updateBackups(activeSync?: sdk.WalletStorageSync, progLog?: (s: string) => string): Promise<string> {\n    progLog ||= s => s\n    const auth = await this.getAuth(true)\n    return await this.runAsSync(async sync => {\n      let log = progLog(`BACKUP CURRENT ACTIVE TO ${(this._backups as ManagedStorage[]).length} STORES\\n`)\n      for (const backup of this._backups as ManagedStorage[]) {\n        const stwr = await this.syncToWriter(auth, backup.storage, sync, undefined, progLog)\n        log += stwr.log\n      }\n      return log\n    }, activeSync)\n  }\n\n  /**\n   * Updates backups and switches to new active storage provider from among current backup providers.\n   *\n   * Also resolves conflicting actives.\n   *\n   * @param storageIdentityKey of current backup storage provider that is to become the new active provider.\n   */\n  async setActive(storageIdentityKey: string, progLog?: (s: string) => string): Promise<string> {\n    progLog ||= s => s\n    if (!this.isAvailable()) await this.makeAvailable()\n\n    // Confirm a valid storageIdentityKey: must match one of the _stores.\n    const newActiveIndex = this._stores.findIndex(\n      s => (s.settings as TableSettings).storageIdentityKey === storageIdentityKey\n    )\n    if (newActiveIndex < 0) {\n      throw new sdk.WERR_INVALID_PARAMETER(\n        'storageIdentityKey',\n        `registered with this \"WalletStorageManager\". ${storageIdentityKey} does not match any managed store.`\n      )\n    }\n\n    const identityKey = (await this.getAuth()).identityKey\n    const newActive = this._stores[newActiveIndex]\n\n    let log = progLog(`setActive to ${(newActive.settings as TableSettings).storageName}`)\n\n    if (storageIdentityKey === this.getActiveStore() && this.isActiveEnabled) {\n      /** Setting the current active as the new active is a permitted no-op. */\n      return log + progLog(' unchanged\\n')\n    }\n\n    log += progLog('\\n')\n\n    log += await this.runAsSync(async _sync => {\n      let log = ''\n\n      if ((this._conflictingActives as ManagedStorage[]).length > 0) {\n        // Merge state from conflicting actives into `newActive`.\n\n        // Handle case where new active is current active to resolve conflicts.\n        // And where new active is one of the current conflict actives.\n        ;(this._conflictingActives as ManagedStorage[]).push(this._active as ManagedStorage)\n        // Remove the new active from conflicting actives and\n        // set new active as the conflicting active that matches the target `storageIdentityKey`\n        this._conflictingActives = (this._conflictingActives as ManagedStorage[]).filter(ca => {\n          const isNewActive = (ca.settings as TableSettings).storageIdentityKey === storageIdentityKey\n          return !isNewActive\n        })\n\n        // Merge state from conflicting actives into `newActive`.\n        for (const conflict of this._conflictingActives) {\n          log += progLog('MERGING STATE FROM CONFLICTING ACTIVES:\\n')\n          const sfr = await this.syncToWriter(\n            { identityKey, userId: (newActive.user as TableUser).userId, isActive: false },\n            newActive.storage,\n            conflict.storage,\n            undefined,\n            progLog\n          )\n          log += sfr.log\n        }\n        log += progLog('PROPAGATE MERGED ACTIVE STATE TO NON-ACTIVES\\n')\n      } else {\n        log += progLog('BACKUP CURRENT ACTIVE STATE THEN SET NEW ACTIVE\\n')\n      }\n\n      // If there were conflicting actives,\n      // Push state merged from all merged actives into newActive to all stores other than the now single active.\n      // Otherwise,\n      // Push state from current active to all other stores.\n      const backupSource =\n        (this._conflictingActives as ManagedStorage[]).length > 0 ? newActive : (this._active as ManagedStorage)\n\n      // Update the backupSource's user record with the new activeStorage\n      // which will propagate to all other stores in the following backup loop.\n      await backupSource.storage.setActive(\n        { identityKey, userId: (backupSource.user as TableUser).userId },\n        storageIdentityKey\n      )\n\n      for (const store of this._stores) {\n        // Update cached user.activeStorage of all stores\n        ;(store.user as TableUser).activeStorage = storageIdentityKey\n\n        if (\n          (store.settings as TableSettings).storageIdentityKey !==\n          (backupSource.settings as TableSettings).storageIdentityKey\n        ) {\n          // If this store is not the backupSource store push state from backupSource to this store.\n          const stwr = await this.syncToWriter(\n            { identityKey, userId: (store.user as TableUser).userId, isActive: false },\n            store.storage,\n            backupSource.storage,\n            undefined,\n            progLog\n          )\n          log += stwr.log\n        }\n      }\n\n      this._isAvailable = false\n      await this.makeAvailable()\n\n      return log\n    })\n\n    return log\n  }\n\n  getStoreEndpointURL(store: ManagedStorage): string | undefined {\n    if (store.storage.constructor.name === 'StorageClient') return (store.storage as StorageClient).endpointUrl\n    return undefined\n  }\n\n  getStores(): sdk.WalletStorageInfo[] {\n    const stores: sdk.WalletStorageInfo[] = []\n    if (this._active != null) {\n      stores.push({\n        isActive: true,\n        isEnabled: this.isActiveEnabled,\n        isBackup: false,\n        isConflicting: false,\n        userId: (this._active.user as TableUser).userId,\n        storageIdentityKey: (this._active.settings as TableSettings).storageIdentityKey,\n        storageName: (this._active.settings as TableSettings).storageName,\n        storageClass: this._active.storage.constructor.name,\n        endpointURL: this.getStoreEndpointURL(this._active)\n      })\n    }\n    for (const store of this._conflictingActives ?? []) {\n      stores.push({\n        isActive: true,\n        isEnabled: false,\n        isBackup: false,\n        isConflicting: true,\n        userId: (store.user as TableUser).userId,\n        storageIdentityKey: (store.settings as TableSettings).storageIdentityKey,\n        storageName: (store.settings as TableSettings).storageName,\n        storageClass: store.storage.constructor.name,\n        endpointURL: this.getStoreEndpointURL(store)\n      })\n    }\n    for (const store of this._backups ?? []) {\n      stores.push({\n        isActive: false,\n        isEnabled: false,\n        isBackup: true,\n        isConflicting: false,\n        userId: (store.user as TableUser).userId,\n        storageIdentityKey: (store.settings as TableSettings).storageIdentityKey,\n        storageName: (store.settings as TableSettings).storageName,\n        storageClass: store.storage.constructor.name,\n        endpointURL: this.getStoreEndpointURL(store)\n      })\n    }\n    return stores\n  }\n}\n\nexport interface VerifyAndRepairBeefResult {\n  isStructurallyValid: boolean\n  originalRoots: Record<number, string>\n  invalidRoots: Record<number, { root: string; reproveResults: sdk.ReproveHeaderResult }>\n  verifiedBeef?: Beef\n}\n","import { Beef, Transaction } from '@bsv/sdk'\nimport { TableProvenTxReq } from './schema/tables/TableProvenTxReq'\nimport { TrxToken } from '../sdk/WalletStorage.interfaces'\nimport { WERR_INTERNAL } from '../sdk/WERR_errors'\nimport { WalletError } from '../sdk/WalletError'\nimport { GetReqsAndBeefDetail } from './methods/processAction'\nimport { ReqHistoryNote } from '../sdk/types'\n\n// ---------------------------------------------------------------------------\n// getReqsAndBeefToShareWithWorld helpers\n// ---------------------------------------------------------------------------\n\nconst alreadySentStatuses = new Set(['unmined', 'callback', 'unconfirmed', 'completed'])\nconst readyToSendStatuses = new Set(['sending', 'unsent', 'nosend', 'unprocessed'])\nconst errorStatuses = new Set(['unknown', 'nonfinal', 'invalid', 'doubleSpend'])\n\n/**\n * Classify a ProvenTxReq status into beef-sharing lifecycle status.\n * Mutates `d` in place.\n */\nexport function classifyReqStatus (d: GetReqsAndBeefDetail, req: TableProvenTxReq): void {\n  if (errorStatuses.has(req.status)) {\n    d.status = 'error'\n    d.error = `ERR_INVALID_PARAMETER: ${d.txid} is not ready to send.`\n  } else if (alreadySentStatuses.has(req.status)) {\n    d.status = 'alreadySent'\n  } else if (readyToSendStatuses.has(req.status)) {\n    if ((req.rawTx == null) || req.inputBEEF == null) {\n      d.status = 'error'\n      d.error = `ERR_INTERNAL: ${d.txid} req is missing rawTx or beef.`\n    } else {\n      d.status = 'readyToSend'\n    }\n  } else {\n    d.status = 'error'\n    d.error = `ERR_INTERNAL: ${d.txid} has unexpected req status ${req.status}`\n  }\n}\n\n// ---------------------------------------------------------------------------\n// Beef input-merge helpers (used by mergeReqToBeefToShareExternally and getValidBeefForTxid)\n// ---------------------------------------------------------------------------\n\n/**\n * For each input of `rawTx`, ensure the source txid is represented in `beef`.\n *\n * When `requiredLevels` is undefined/0 and `knownTxids` contains the source txid,\n * a txid-only stub is merged rather than recursing into storage.\n */\nexport async function mergeInputBeefs (\n  rawTx: number[],\n  beef: Beef,\n  trustSelf: 'known' | undefined,\n  knownTxids: string[] | undefined,\n  trx: TrxToken | undefined,\n  requiredLevels: number | undefined,\n  getValidBeef: (\n    txid: string,\n    beef: Beef,\n    trustSelf: 'known' | undefined,\n    knownTxids: string[] | undefined,\n    trx: TrxToken | undefined,\n    requiredLevels: number | undefined\n  ) => Promise<unknown>\n): Promise<void> {\n  const tx = Transaction.fromBinary(rawTx)\n  for (const input of tx.inputs) {\n    const sourceTXID = input.sourceTXID ?? ''\n    if (sourceTXID === '') throw new WERR_INTERNAL('req all transaction inputs must have valid sourceTXID')\n    const existing = beef.findTxid(sourceTXID)\n    const callerKnows = (requiredLevels == null || requiredLevels === 0) &&\n      (knownTxids?.includes(sourceTXID) === true)\n    // Stored input BEEFs can contain txid-only placeholders supplied by a\n    // different client. They are not proof for the current caller unless that\n    // caller also declared the txid known (or explicitly trusts this storage).\n    if (existing != null && (!existing.isTxidOnly || callerKnows || trustSelf === 'known')) continue\n    if (callerKnows) {\n      beef.mergeTxidOnly(sourceTXID)\n    } else {\n      await getValidBeef(sourceTXID, beef, trustSelf, knownTxids, trx, requiredLevels)\n    }\n  }\n}\n\n/**\n * Convenience wrapper for the external-sharing path where `trustSelf` and\n * `requiredLevels` are always absent.\n */\nexport async function mergeInputsIntoBeef (\n  rawTx: number[],\n  beef: Beef,\n  knownTxids: string[],\n  trx: TrxToken | undefined,\n  getValidBeef: (txid: string, beef: Beef, trustSelf: undefined, knownTxids: string[], trx: TrxToken | undefined) => Promise<unknown>\n): Promise<void> {\n  await mergeInputBeefs(\n    rawTx,\n    beef,\n    undefined,\n    knownTxids,\n    trx,\n    undefined,\n    async (txid, beef, _trustSelf, knownTxids, trx) =>\n      await getValidBeef(txid, beef, undefined, knownTxids as string[], trx)\n  )\n}\n\n// ---------------------------------------------------------------------------\n// updateProvenTxReqWithNewProvenTx helpers\n// ---------------------------------------------------------------------------\n\n/**\n * Notify each transaction that a proof has been found.\n * Mutates `req` history notes in place.\n *\n * The `addNote` callback avoids coupling this helper to a specific entity type.\n * Returns false if any transaction update failed so callers can retain the\n * request for later status repair.\n */\nexport async function notifyTransactionsOfProof (\n  ids: number[],\n  provenTxId: number,\n  addNote: (note: ReqHistoryNote) => void,\n  updateTransaction: (id: number, update: { provenTxId: number, status: 'completed' }) => Promise<unknown>\n): Promise<boolean> {\n  let allUpdatesSucceeded = true\n  for (const id of ids) {\n    try {\n      await updateTransaction(id, { provenTxId, status: 'completed' })\n      addNote({ what: 'notifyTxOfProof', transactionId: id })\n    } catch (error_: unknown) {\n      allUpdatesSucceeded = false\n      const { code, description } = WalletError.fromUnknown(error_)\n      addNote({ what: 'notifyTxOfProofError', id, provenTxId, code, description })\n    }\n  }\n  return allUpdatesSucceeded\n}\n","import { Beef } from '@bsv/sdk'\nimport { StorageProvider } from '../StorageProvider'\nimport { ProvenOrRawTx, StorageGetBeefOptions } from '../../sdk/WalletStorage.interfaces'\nimport { EntityProvenTx } from '../schema/entities/EntityProvenTx'\nimport { WERR_INVALID_MERKLE_ROOT, WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\n\ninterface BeefFrontierItem {\n  txid: string\n  depth: number\n}\n\ninterface ProvenBeefEntry {\n  rawTx: number[]\n  merklePath: ReturnType<EntityProvenTx['getMerklePath']>\n  merkleRoot: string\n}\n\n/**\n * Creates a `Beef` to support the validity of a transaction identified by its `txid`.\n *\n * `storage` is used to retrieve proven transactions and their merkle paths,\n * or proven_tx_req record with beef of external inputs (internal inputs meged by recursion).\n * Otherwise external services are used.\n *\n * `options.maxRecursionDepth` can be set to prevent overly deep chained dependencies. Will throw ERR_EXTSVS_ENVELOPE_DEPTH if exceeded.\n *\n * If `trustSelf` is true, a partial `Beef` will be returned where transactions known by `storage` to\n * be valid by verified proof are represented solely by 'txid'.\n *\n * If `knownTxids` is defined, any 'txid' required by the `Beef` that appears in the array is represented solely as a 'known' txid.\n *\n * @param storage the chain on which txid exists.\n * @param txid the transaction hash for which an envelope is requested.\n * @param options\n */\nexport async function getBeefForTransaction(\n  storage: StorageProvider,\n  txid: string,\n  options: StorageGetBeefOptions\n): Promise<Beef> {\n  const beef = mergeTarget(options)\n\n  // Most createAction proof requests resolve a single, already-proven root.\n  // Building a Set for a wallet's entire known-txid history made that common\n  // path O(history) before storage did any useful work. Use array membership\n  // for the first few lookups and promote to a Set only for a broad ancestor\n  // traversal where the construction cost is recovered.\n  const hasKnownTxid = makeKnownTxidLookup(options.knownTxids ?? [])\n  const scheduled = new Set<string>([txid])\n  let frontier: Array<{ txid: string; depth: number }> = [{ txid, depth: 0 }]\n  const concurrency = normalizeConcurrency(options.maxConcurrency)\n\n  while (frontier.length > 0) {\n    const current = frontier.filter(item => needsResolution(beef, item.txid, hasKnownTxid))\n    const resolved = await mapWithConcurrency(\n      current,\n      concurrency,\n      async item => await resolveBeefForTransaction(storage, item.txid, options, hasKnownTxid, item.depth)\n    )\n\n    const next: Array<{ txid: string; depth: number }> = []\n    for (let i = 0; i < resolved.length; i++) {\n      const result = resolved[i]\n      beef.mergeBeef(result.beef)\n      for (const dependency of result.dependencies) {\n        if (!scheduled.has(dependency) && needsResolution(beef, dependency, hasKnownTxid)) {\n          scheduled.add(dependency)\n          next.push({ txid: dependency, depth: current[i].depth + 1 })\n        }\n      }\n    }\n    frontier = next\n  }\n\n  return beef\n}\n\n/**\n * Build one aggregate BEEF for several roots while resolving each storage\n * frontier as a set. This avoids one proof query per funding input on the\n * createAction success path. Complex proof-level and chain-tracker policies\n * retain the established single-root implementation.\n */\nexport async function getBeefForTransactions(\n  storage: StorageProvider,\n  txids: string[],\n  options: StorageGetBeefOptions\n): Promise<Beef> {\n  const beef = mergeTarget(options)\n  const roots = [...new Set(txids)]\n  if (roots.length === 0) return beef\n  if (requiresSingleRootPolicy(options)) return await mergeSingleRootFragments(storage, roots, options, beef)\n\n  const hasKnownTxid = makeKnownTxidLookup(options.knownTxids ?? [])\n  const scheduled = new Set<string>(roots)\n  let frontier: BeefFrontierItem[] = roots.map(txid => ({ txid, depth: 0 }))\n\n  while (frontier.length > 0) {\n    const unresolved = collectUnresolvedFrontier(storage, frontier, beef, hasKnownTxid)\n    if (unresolved.length === 0) break\n\n    const stored = await storage.getProvenOrRawTxs(unresolved.map(item => item.txid))\n    const allProven = options.trustSelf !== 'known' && unresolved.every(item => stored.get(item.txid)?.proven != null)\n    if (allProven) {\n      mergeAllProven(storage, beef, unresolved, stored)\n      break\n    }\n\n    const [next, missing] = mergeStoredFrontier(beef, unresolved, stored, options, scheduled, hasKnownTxid)\n    await mergeMissingFragments(storage, beef, missing, options)\n    frontier = next\n  }\n\n  return beef\n}\n\nfunction mergeTarget(options: StorageGetBeefOptions): Beef {\n  if (options.mergeToBeef instanceof Beef) return options.mergeToBeef\n  if (options.mergeToBeef != null) return Beef.fromBinary(options.mergeToBeef)\n  return new Beef()\n}\n\nfunction requiresSingleRootPolicy(options: StorageGetBeefOptions): boolean {\n  return options.ignoreStorage === true ||\n    options.minProofLevel !== undefined ||\n    options.chainTracker != null ||\n    options.skipInvalidProofs === true\n}\n\nasync function mergeSingleRootFragments(\n  storage: StorageProvider,\n  roots: string[],\n  options: StorageGetBeefOptions,\n  beef: Beef\n): Promise<Beef> {\n  const fragments = await mapWithConcurrency(\n    roots.filter(txid => beef.findTxid(txid) == null),\n    normalizeConcurrency(options.maxConcurrency),\n    async txid => await getBeefForTransaction(storage, txid, { ...options, mergeToBeef: undefined })\n  )\n  for (const fragment of fragments) beef.mergeBeef(fragment)\n  return beef\n}\n\nfunction collectUnresolvedFrontier(\n  storage: StorageProvider,\n  frontier: BeefFrontierItem[],\n  beef: Beef,\n  hasKnownTxid: (txid: string) => boolean\n): BeefFrontierItem[] {\n  const unresolved: BeefFrontierItem[] = []\n  for (const item of frontier) {\n    if (!needsResolution(beef, item.txid, hasKnownTxid)) continue\n    if (storage.maxRecursionDepth && storage.maxRecursionDepth <= item.depth) {\n      throw new WERR_INVALID_OPERATION(`Maximum BEEF depth exceeded. Limit is ${storage.maxRecursionDepth}`)\n    }\n    if (hasKnownTxid(item.txid)) beef.mergeTxidOnly(item.txid)\n    else unresolved.push(item)\n  }\n  return unresolved\n}\n\nfunction decodeProvenEntries(\n  storage: StorageProvider,\n  unresolved: BeefFrontierItem[],\n  stored: Map<string, ProvenOrRawTx>\n): ProvenBeefEntry[] {\n  const span = storage.telemetry.enabled\n    ? storage.telemetry.startSpan('wallet.storage.beef.decode_proven_batch', {\n      component: 'wallet-storage',\n      attributes: { 'beef.proven_tx_count': unresolved.length }\n    })\n    : undefined\n  try {\n    const entries = unresolved.map(item => {\n      const proven = stored.get(item.txid)!.proven!\n      return {\n        rawTx: proven.rawTx,\n        merklePath: new EntityProvenTx(proven).getMerklePath(false),\n        merkleRoot: proven.merkleRoot\n      }\n    })\n    span?.end({ attributes: { 'beef.decoded_proof_count': entries.length } })\n    return entries\n  } catch (error) {\n    span?.end({ status: 'error', error })\n    throw error\n  }\n}\n\nfunction mergeAllProven(\n  storage: StorageProvider,\n  beef: Beef,\n  unresolved: BeefFrontierItem[],\n  stored: Map<string, ProvenOrRawTx>\n): void {\n  const entries = decodeProvenEntries(storage, unresolved, stored)\n  const span = storage.telemetry.enabled\n    ? storage.telemetry.startSpan('wallet.storage.beef.merge_proven_batch', {\n      component: 'wallet-storage',\n      attributes: { 'beef.proven_tx_count': entries.length }\n    })\n    : undefined\n  try {\n    mergeProvenEntries(beef, entries, unresolved, stored)\n    span?.end({\n      attributes: {\n        'beef.merged_tx_count': entries.length,\n        'beef.result_tx_count': beef.txs.length,\n        'beef.result_bump_count': beef.bumps.length\n      }\n    })\n  } catch (error) {\n    span?.end({ status: 'error', error })\n    throw error\n  }\n}\n\nfunction mergeProvenEntries(\n  beef: Beef,\n  entries: ProvenBeefEntry[],\n  unresolved: BeefFrontierItem[],\n  stored: Map<string, ProvenOrRawTx>\n): void {\n  if (typeof beef.mergeProvenTxs === 'function') {\n    beef.mergeProvenTxs(entries)\n    return\n  }\n  // Runtime compatibility for applications that intentionally retain an older\n  // compatible SDK peer. Current peers use the bulk lane; older peers retain\n  // the established validated sequential behavior.\n  for (const item of unresolved) {\n    const proven = stored.get(item.txid)!.proven!\n    beef.mergeRawTx(proven.rawTx)\n    beef.mergeBump(new EntityProvenTx(proven).getMerklePath())\n  }\n}\n\nfunction mergeStoredFrontier(\n  beef: Beef,\n  unresolved: BeefFrontierItem[],\n  stored: Map<string, ProvenOrRawTx>,\n  options: StorageGetBeefOptions,\n  scheduled: Set<string>,\n  hasKnownTxid: (txid: string) => boolean\n): [next: BeefFrontierItem[], missing: BeefFrontierItem[]] {\n  const next: BeefFrontierItem[] = []\n  const missing: BeefFrontierItem[] = []\n  for (const item of unresolved) {\n    const result = stored.get(item.txid)\n    if (result?.proven != null) mergeStoredProven(beef, item, result, options)\n    else if (result?.rawTx != null) mergeStoredRaw(beef, item, result, options, scheduled, next, hasKnownTxid)\n    else missing.push(item)\n  }\n  return [next, missing]\n}\n\nfunction mergeStoredProven(\n  beef: Beef,\n  item: BeefFrontierItem,\n  result: ProvenOrRawTx,\n  options: StorageGetBeefOptions\n): void {\n  if (options.trustSelf === 'known') {\n    beef.mergeTxidOnly(item.txid)\n    return\n  }\n  const proven = result.proven!\n  beef.mergeRawTx(proven.rawTx)\n  beef.mergeBump(new EntityProvenTx(proven).getMerklePath())\n}\n\nfunction mergeStoredRaw(\n  beef: Beef,\n  item: BeefFrontierItem,\n  result: ProvenOrRawTx,\n  options: StorageGetBeefOptions,\n  scheduled: Set<string>,\n  next: BeefFrontierItem[],\n  hasKnownTxid: (txid: string) => boolean\n): void {\n  if (options.trustSelf === 'known') {\n    beef.mergeTxidOnly(item.txid)\n    return\n  }\n  const transaction = beef.mergeRawTx(result.rawTx!)\n  if (result.inputBEEF != null) beef.mergeBeef(result.inputBEEF)\n  appendNewDependencies(transaction.inputTxids, item.depth + 1, beef, scheduled, next, hasKnownTxid)\n}\n\nfunction appendNewDependencies(\n  dependencies: string[],\n  depth: number,\n  beef: Beef,\n  scheduled: Set<string>,\n  next: BeefFrontierItem[],\n  hasKnownTxid: (txid: string) => boolean\n): void {\n  for (const txid of dependencies) {\n    if (scheduled.has(txid) || !needsResolution(beef, txid, hasKnownTxid)) continue\n    scheduled.add(txid)\n    next.push({ txid, depth })\n  }\n}\n\nfunction needsResolution(\n  beef: Beef,\n  txid: string,\n  hasKnownTxid: (txid: string) => boolean\n): boolean {\n  const entry = beef.findTxid(txid)\n  return entry == null || (entry.isTxidOnly && !hasKnownTxid(txid))\n}\n\nasync function mergeMissingFragments(\n  storage: StorageProvider,\n  beef: Beef,\n  missing: BeefFrontierItem[],\n  options: StorageGetBeefOptions\n): Promise<void> {\n  if (missing.length === 0) return\n  if (options.ignoreServices === true) {\n    throw new WERR_INVALID_PARAMETER(`txid ${missing[0].txid}`, `valid transaction on chain ${storage.chain}`)\n  }\n  const fragments = await mapWithConcurrency(\n    missing,\n    normalizeConcurrency(options.maxConcurrency),\n    async item => await getBeefForTransaction(storage, item.txid, {\n      ...options,\n      ignoreStorage: true,\n      mergeToBeef: undefined\n    })\n  )\n  for (const fragment of fragments) beef.mergeBeef(fragment)\n}\n\nfunction makeKnownTxidLookup (knownTxids: string[]): (txid: string) => boolean {\n  let lookups = 0\n  let indexed: Set<string> | undefined\n  return txid => {\n    lookups++\n    if (indexed != null) return indexed.has(txid)\n    if (knownTxids.length > 64 && lookups > 4) {\n      indexed = new Set(knownTxids)\n      return indexed.has(txid)\n    }\n    return knownTxids.includes(txid)\n  }\n}\n\nfunction normalizeConcurrency(value: number | undefined = 8): number {\n  return Number.isFinite(value)\n    ? Math.max(1, Math.min(32, Math.floor(value)))\n    : 8\n}\n\nasync function mapWithConcurrency<T, R>(\n  values: T[],\n  concurrency: number,\n  mapper: (value: T) => Promise<R>\n): Promise<R[]> {\n  const results = Array.from({ length: values.length }, () => undefined as R)\n  let cursor = 0\n  await Promise.all(\n    Array.from({ length: Math.min(concurrency, values.length) }, async () => {\n      while (cursor < values.length) {\n        const index = cursor++\n        results[index] = await mapper(values[index])\n      }\n    })\n  )\n  return results\n}\n\n/**\n * @returns rawTx if txid known to network, if merkle proof available then also proven result is valid.\n */\nasync function getProvenOrRawTxFromServices(\n  storage: StorageProvider,\n  txid: string,\n  options: StorageGetBeefOptions\n): Promise<ProvenOrRawTx> {\n  const por = await EntityProvenTx.fromTxid(txid, storage.getServices())\n  if (por.proven != null && !options.ignoreStorage && !options.ignoreNewProven) {\n    por.proven.provenTxId = await storage.insertProvenTx(por.proven.toApi())\n  }\n  return { proven: por.proven?.toApi(), rawTx: por.rawTx }\n}\n\nasync function getStoredBeef(\n  storage: StorageProvider,\n  txid: string,\n  options: StorageGetBeefOptions,\n  recursionDepth: number\n): Promise<Beef | undefined> {\n  if (options.ignoreStorage) return undefined\n\n  const requiredLevels = options.minProofLevel === undefined ? undefined : options.minProofLevel + recursionDepth\n  return await storage.getValidBeefForTxid(\n    txid,\n    new Beef(),\n    options.trustSelf,\n    options.knownTxids,\n    undefined,\n    requiredLevels,\n    options.chainTracker,\n    options.skipInvalidProofs\n  )\n}\n\nasync function mergeUsableProvenTransaction(\n  beef: Beef,\n  txid: string,\n  result: ProvenOrRawTx,\n  options: StorageGetBeefOptions,\n  recursionDepth: number\n): Promise<Beef | undefined> {\n  const proven = result.proven\n  if (proven == null) return undefined\n  if (options.minProofLevel !== undefined && options.minProofLevel > recursionDepth) return undefined\n\n  const merklePath = new EntityProvenTx(proven).getMerklePath()\n  if (options.chainTracker != null) {\n    const root = merklePath.computeRoot()\n    const isValid = await options.chainTracker.isValidRootForHeight(root, proven.height)\n    if (!isValid) {\n      if (!options.skipInvalidProofs) {\n        throw new WERR_INVALID_MERKLE_ROOT(proven.blockHash, proven.height, root, txid)\n      }\n      return undefined\n    }\n  }\n\n  beef.mergeRawTx(proven.rawTx)\n  beef.mergeBump(merklePath)\n  return beef\n}\n\nasync function resolveBeefForTransaction(\n  storage: StorageProvider,\n  txid: string,\n  options: StorageGetBeefOptions,\n  hasKnownTxid: (txid: string) => boolean,\n  recursionDepth: number\n): Promise<{ beef: Beef; dependencies: string[] }> {\n  const maxDepth = storage.maxRecursionDepth\n  if (maxDepth && maxDepth <= recursionDepth) {\n    throw new WERR_INVALID_OPERATION(`Maximum BEEF depth exceeded. Limit is ${storage.maxRecursionDepth}`)\n  }\n\n  const beef = new Beef()\n\n  if (hasKnownTxid(txid)) {\n    // This txid is one of the txids the caller claims to already know are valid...\n    beef.mergeTxidOnly(txid)\n    return { beef, dependencies: [] }\n  }\n\n  const storedBeef = await getStoredBeef(storage, txid, options, recursionDepth)\n  if (storedBeef != null) return { beef: storedBeef, dependencies: [] }\n\n  if (options.ignoreServices) {\n    throw new WERR_INVALID_PARAMETER(`txid ${txid}`, `valid transaction on chain ${storage.chain}`)\n  }\n\n  // if storage doesn't know about txid, use services\n  // to find it and if it has a proof, remember it.\n  const result = await getProvenOrRawTxFromServices(storage, txid, options)\n  const provenBeef = await mergeUsableProvenTransaction(beef, txid, result, options, recursionDepth)\n  if (provenBeef != null) return { beef: provenBeef, dependencies: [] }\n\n  if (result.rawTx == null)\n    throw new WERR_INVALID_PARAMETER(`txid ${txid}`, `valid transaction on chain ${storage.chain}`)\n\n  // merge the raw transaction and recurse over its inputs.\n  const beefTx = beef.mergeRawTx(result.rawTx)\n  return { beef, dependencies: beefTx.inputTxids }\n}\n","import { Beef, ReviewActionResult, SendWithResult } from '@bsv/sdk'\nimport { PostReqsToNetworkResult } from '../storage/methods/attemptToPostReqsToNetwork'\nimport { StorageGetBeefOptions, WERR_INTERNAL } from '../sdk'\nimport { StorageProvider } from '../storage/StorageProvider'\n\nexport const aggregateActionResults = async (\n  storage: StorageProvider,\n  sendWithResultReqs: SendWithResult[],\n  postToNetworkResult: PostReqsToNetworkResult\n): Promise<{\n  swr: SendWithResult[]\n  rar: ReviewActionResult[]\n}> => {\n  const swr: SendWithResult[] = []\n  const rar: ReviewActionResult[] = []\n\n  for (const ar of sendWithResultReqs) {\n    const txid = ar.txid\n\n    const d = postToNetworkResult.details.find(d => d.txid === txid)\n    if (d == null) throw new WERR_INTERNAL(`missing details for ${txid}`)\n\n    const arNdr: ReviewActionResult = { txid: d.txid, status: 'success', competingTxs: d.competingTxs }\n    switch (d.status) {\n      case 'success':\n        // processing network has accepted this transaction\n        ar.status = 'unproven'\n        break\n      case 'doubleSpend':\n        // confirmed double spend.\n        ar.status = 'failed'\n        arNdr.status = 'doubleSpend'\n        if (d.competingTxs != null) arNdr.competingBeef = await createMergedBeefOfTxids(d.competingTxs, storage)\n        break\n      case 'serviceError':\n        // services might improve\n        ar.status = 'sending'\n        arNdr.status = 'serviceError'\n        break\n      case 'invalidTx':\n        // nothing will fix this transaction\n        ar.status = 'failed'\n        arNdr.status = 'invalidTx'\n        break\n      case 'unknown':\n      case 'invalid':\n      default:\n        throw new WERR_INTERNAL(`processAction with notDelayed status ${d.status} should not occur.`)\n    }\n\n    swr.push({ txid, status: ar.status })\n    rar.push(arNdr)\n  }\n\n  return { swr, rar }\n}\n\nasync function createMergedBeefOfTxids (txids: string[], storage: StorageProvider): Promise<number[]> {\n  const beef = new Beef()\n  const options: StorageGetBeefOptions = {\n    mergeToBeef: beef,\n    ignoreNewProven: true\n  }\n  for (const txid of txids) {\n    await storage.getBeefForTransaction(txid, options)\n  }\n  return beef.toBinary()\n}\n","// eslint-disable-next-line @typescript-eslint/no-unused-vars\nimport {\n  Beef,\n  Transaction as BsvTransaction,\n  SendWithResult,\n  SendWithResultStatus,\n  WalletLoggerInterface,\n  TelemetrySpan\n} from '@bsv/sdk'\nimport { aggregateActionResults } from '../../utility/aggregateResults'\nimport { StorageProvider } from '../StorageProvider'\nimport {\n  AuthId,\n  ReviewActionResult,\n  StorageProcessActionArgs,\n  StorageProcessActionResults\n} from '../../sdk/WalletStorage.interfaces'\nimport { stampLog } from '../../utility/stampLog'\nimport {\n  randomBytesBase64,\n  verifyId,\n  verifyInteger,\n  verifyOne,\n  verifyOneOrNone,\n  verifyTruthy\n} from '../../utility/utilityHelpers'\nimport { EntityProvenTxReq } from '../schema/entities/EntityProvenTxReq'\nimport { WERR_INTERNAL, WERR_INVALID_OPERATION } from '../../sdk/WERR_errors'\nimport { TableProvenTxReq } from '../schema/tables/TableProvenTxReq'\nimport { TableProvenTx } from '../schema/tables/TableProvenTx'\nimport { ProvenTxReqStatus, TransactionStatus } from '../../sdk/types'\nimport { parseTxScriptOffsets, TxScriptOffsets } from '../../utility/parseTxScriptOffsets'\nimport { TableTransaction } from '../schema/tables/TableTransaction'\nimport { TableOutput } from '../schema/tables/TableOutput'\nimport { asArray, asString } from '../../utility/utilityHelpers.noBuffer'\nimport { WalletError } from '../../sdk/WalletError'\nimport { classifyReqStatus } from '../storageProviderHelpers'\n\nexport async function processAction(\n  storage: StorageProvider,\n  auth: AuthId,\n  args: StorageProcessActionArgs\n): Promise<StorageProcessActionResults> {\n  if (!storage.telemetry.enabled) return await processActionCore(storage, auth, args)\n  return await storage.telemetry.withSpan(\n    'wallet.storage.process_action',\n    {\n      component: 'wallet-storage',\n      carrier: args,\n      attributes: {\n        'action.is_new_transaction': args.isNewTx,\n        'action.is_no_send': args.isNoSend,\n        'action.is_delayed': args.isDelayed,\n        'action.send_with_count': args.sendWith.length\n      }\n    },\n    async span => {\n      const result = await processActionCore(storage, auth, args, span)\n      span.end({ attributes: { 'action.send_result_count': result.sendWithResults?.length ?? 0 } })\n      return result\n    }\n  )\n}\n\nasync function processActionCore(\n  storage: StorageProvider,\n  auth: AuthId,\n  args: StorageProcessActionArgs,\n  parent?: TelemetrySpan\n): Promise<StorageProcessActionResults> {\n  const logger = args.logger\n  logger?.group('storage processAction')\n\n  const userId = verifyId(auth.userId)\n  const r: StorageProcessActionResults = {\n    sendWithResults: undefined\n  }\n\n  let req: EntityProvenTxReq | undefined\n  const txidsOfReqsToShareWithWorld: string[] = [...args.sendWith]\n\n  if (args.isNewTx) {\n    const vargs = await traceProcessStep(\n      storage,\n      'wallet.storage.process_action.validate',\n      parent,\n      async () => await validateCommitNewTxToStorageArgs(storage, userId, args)\n    )\n    logger?.log('validated new tx updates to storage')\n    ;({ req } = await traceProcessStep(\n      storage,\n      'wallet.storage.process_action.commit',\n      parent,\n      async () => await commitNewTxToStorage(storage, userId, vargs)\n    ))\n    logger?.log('committed new tx updates to storage ')\n    if (!req) throw new WERR_INTERNAL()\n    // Add the new txid to sendWith unless there are no others to send and the noSend option is set.\n    if (args.isNoSend && !args.isSendWith) {\n      logger?.log(`noSend txid ${req.txid}`)\n    } else {\n      txidsOfReqsToShareWithWorld.push(req.txid)\n      logger?.log(`sending txid ${req.txid}`)\n    }\n  }\n\n  const { swr, ndr } = await traceProcessStep(\n    storage,\n    'wallet.storage.process_action.share',\n    parent,\n    async () => await shareReqsWithWorld(\n      storage,\n      userId,\n      txidsOfReqsToShareWithWorld,\n      args.isDelayed,\n      undefined,\n      logger\n    )\n  )\n\n  r.sendWithResults = swr\n  r.notDelayedResults = ndr\n\n  logger?.groupEnd()\n\n  return r\n}\n\nasync function traceProcessStep<T>(\n  storage: StorageProvider,\n  name: string,\n  parent: TelemetrySpan | undefined,\n  callback: () => Promise<T>\n): Promise<T> {\n  if (parent == null) return await callback()\n  return await storage.telemetry.withSpan(\n    name,\n    { component: 'wallet-storage', parent: parent.context },\n    callback\n  )\n}\n\nexport interface GetReqsAndBeefDetail {\n  txid: string\n  req?: TableProvenTxReq\n  proven?: TableProvenTx\n  status: 'readyToSend' | 'alreadySent' | 'error' | 'unknown'\n  error?: string\n}\n\nexport interface GetReqsAndBeefResult {\n  beef: Beef\n  details: GetReqsAndBeefDetail[]\n  /** Internal fast path: this exact BEEF instance already passed validation. */\n  verified?: boolean\n}\n\nexport interface PostBeefResultForTxidApi {\n  txid: string\n\n  /**\n   * 'success' - The transaction was accepted for processing\n   */\n  status: 'success' | 'error'\n\n  /**\n   * if true, the transaction was already known to this service. Usually treat as a success.\n   *\n   * Potentially stop posting to additional transaction processors.\n   */\n  alreadyKnown?: boolean\n\n  blockHash?: string\n  blockHeight?: number\n  merklePath?: string\n}\n\n/**\n * Verifies that all the txids are known reqs with ready-to-share status.\n * Assigns a batch identifier and updates all the provenTxReqs.\n * If not isDelayed, triggers an initial attempt to broadcast the batch and returns the results.\n *\n * @param storage\n * @param userId\n * @param txids\n * @param isDelayed\n * @param r Optional. Ignores txids and allows ProvenTxReqs and merged beef to be passed in.\n */\nfunction classifyReqDetails(\n  details: GetReqsAndBeefDetail[],\n  swr: SendWithResult[],\n  readyToSendReqs: EntityProvenTxReq[]\n): void {\n  for (const getReq of details) {\n    let status: SendWithResultStatus = 'failed'\n    if (getReq.status === 'alreadySent') {\n      status = 'unproven'\n    } else if (getReq.status === 'readyToSend') {\n      status = 'sending'\n      readyToSendReqs.push(new EntityProvenTxReq(getReq.req))\n    }\n    swr.push({ txid: getReq.txid, status })\n  }\n}\n\nasync function verifyMergedBeef(\n  storage: StorageProvider,\n  r: GetReqsAndBeefResult,\n  readyToSendReqs: EntityProvenTxReq[],\n  logger?: WalletLoggerInterface\n): Promise<void> {\n  if (readyToSendReqs.length === 0 || r.verified === true) return\n  const beefIsValid = await r.beef.verify(await storage.getServices().getChainTracker())\n  if (!beefIsValid) {\n    logger?.error(`VERIFY FALSE BEEF: ${r.beef.toLogString()}`)\n    throw new WERR_INTERNAL('merged Beef failed validation.')\n  }\n  logger?.log('beef is valid')\n}\n\nasync function getReqDetailsForDelayedShare(storage: StorageProvider, txids: string[]): Promise<GetReqsAndBeefResult> {\n  const r: GetReqsAndBeefResult = {\n    beef: new Beef(),\n    details: []\n  }\n\n  for (const txid of txids) {\n    const d: GetReqsAndBeefDetail = {\n      txid,\n      status: 'unknown'\n    }\n    r.details.push(d)\n    try {\n      d.proven = verifyOneOrNone(await storage.findProvenTxs({ partial: { txid } }))\n      if (d.proven != null) {\n        d.status = 'alreadySent'\n        continue\n      }\n\n      d.req = verifyOneOrNone(await storage.findProvenTxReqs({ partial: { txid } }))\n      if (d.req == null) {\n        d.status = 'error'\n        d.error = `ERR_UNKNOWN_TXID: ${txid} was not found.`\n      } else {\n        classifyReqStatus(d, d.req)\n      }\n    } catch (error_: unknown) {\n      const e = WalletError.fromUnknown(error_)\n      d.error = `${e.name}: ${e.message}`\n    }\n  }\n\n  return r\n}\n\nexport async function shareReqsWithWorld(\n  storage: StorageProvider,\n  userId: number,\n  txids: string[],\n  isDelayed: boolean,\n  r?: GetReqsAndBeefResult,\n  logger?: WalletLoggerInterface\n): Promise<{ swr: SendWithResult[]; ndr: ReviewActionResult[] | undefined }> {\n  const swr: SendWithResult[] = []\n  const ndr: ReviewActionResult[] | undefined = undefined\n\n  if (r == null && txids.length < 1) return { swr, ndr }\n\n  r ??= isDelayed\n    ? await getReqDetailsForDelayedShare(storage, txids)\n    : await storage.getReqsAndBeefToShareWithWorld(txids, [])\n\n  const readyToSendReqs: EntityProvenTxReq[] = []\n  classifyReqDetails(r.details, swr, readyToSendReqs)\n\n  const readyToSendReqIds = readyToSendReqs.map(r => r.id)\n  const transactionIds = readyToSendReqs.flatMap(r => r.notify.transactionIds || [])\n\n  const batch = txids.length > 1 ? randomBytesBase64(16) : undefined\n  if (isDelayed) {\n    // Delayed sends rebuild BEEF when the monitor sends the req. Do not fail a committed\n    // transaction here because the current aggregate BEEF is only a scheduling artifact.\n    if (readyToSendReqIds.length > 0) {\n      await storage.transaction(async trx => {\n        await storage.updateProvenTxReq(readyToSendReqIds, { status: 'unsent', batch }, trx)\n        await storage.updateTransaction(transactionIds, { status: 'sending' }, trx)\n      })\n    }\n    return { swr, ndr }\n  }\n\n  if (readyToSendReqIds.length < 1) return { swr, ndr }\n\n  await verifyMergedBeef(storage, r, readyToSendReqs, logger)\n\n  if (batch) {\n    for (const req of readyToSendReqs) req.batch = batch\n    await storage.updateProvenTxReq(readyToSendReqIds, { batch })\n  }\n\n  const prtn = await storage.attemptToPostReqsToNetwork(readyToSendReqs, undefined, logger)\n  const { swr: swrRes, rar } = await aggregateActionResults(storage, swr, prtn)\n  return { swr: swrRes, ndr: rar }\n}\n\ninterface ReqTxStatus {\n  req: ProvenTxReqStatus\n  tx: TransactionStatus\n}\n\nfunction determineReqTxStatus(params: Pick<StorageProcessActionArgs, 'isNoSend' | 'isSendWith' | 'isDelayed'>): {\n  status: ReqTxStatus\n  postStatus: ReqTxStatus | undefined\n} {\n  if (params.isNoSend && !params.isSendWith) return { status: { req: 'nosend', tx: 'nosend' }, postStatus: undefined }\n  if (!params.isNoSend && params.isDelayed)\n    return { status: { req: 'unsent', tx: 'unprocessed' }, postStatus: undefined }\n  if (!params.isNoSend && !params.isDelayed) {\n    return {\n      status: { req: 'unprocessed', tx: 'unprocessed' },\n      postStatus: { req: 'unmined', tx: 'unproven' }\n    }\n  }\n  throw new WERR_INTERNAL('logic error')\n}\n\nfunction buildOutputUpdates(storage: StorageProvider, tx: BsvTransaction, vargs: ValidCommitNewTxToStorageArgs): void {\n  for (const o of vargs.outputOutputs) {\n    const vout = verifyInteger(o.vout)\n    const offset = vargs.txScriptOffsets.outputs[vout]\n    const rawTxScript = asString(vargs.rawTx.slice(offset.offset, offset.offset + offset.length))\n    if (o.lockingScript != null && rawTxScript !== asString(o.lockingScript)) {\n      throw new WERR_INVALID_OPERATION(\n        `rawTx output locking script for vout ${vout} not equal to expected output script.`\n      )\n    }\n    if (tx.outputs[vout].lockingScript.toHex() !== rawTxScript) {\n      throw new WERR_INVALID_OPERATION(\n        `parsed transaction output locking script for vout ${vout} not equal to expected output script.`\n      )\n    }\n    const update: Partial<TableOutput> = {\n      txid: vargs.txid,\n      spendable: true, // spendability is gated by transaction status. Remains true until the output is spent.\n      scriptLength: offset.length,\n      scriptOffset: offset.offset\n    }\n    if (offset.length > storage.getSettings().maxOutputScript)\n    // Remove long lockingScript data from outputs table, will be read from rawTx in proven_tx or proven_tx_reqs tables.\n    {\n      update.lockingScript = undefined\n    }\n    vargs.outputUpdates.push({ id: o.outputId, update })\n  }\n}\n\ninterface ValidCommitNewTxToStorageArgs {\n  // validated input args\n\n  reference: string\n  txid: string\n  rawTx: number[]\n  isNoSend: boolean\n  isDelayed: boolean\n  isSendWith: boolean\n  log?: string\n\n  // validated dependent args\n\n  tx: BsvTransaction\n  txScriptOffsets: TxScriptOffsets\n  transactionId: number\n  transaction: TableTransaction\n  outputOutputs: TableOutput[]\n\n  req: EntityProvenTxReq\n  outputUpdates: Array<{ id: number; update: Partial<TableOutput> }>\n  transactionUpdate: Partial<TableTransaction>\n  postStatus?: ReqTxStatus\n}\n\nasync function validateCommitNewTxToStorageArgs(\n  storage: StorageProvider,\n  userId: number,\n  params: StorageProcessActionArgs\n): Promise<ValidCommitNewTxToStorageArgs> {\n  if (!params.reference || !params.txid || params.rawTx == null) {\n    throw new WERR_INVALID_OPERATION('One or more expected params are undefined.')\n  }\n  const rawTx = asArray(params.rawTx)\n  let tx: BsvTransaction\n  try {\n    tx = BsvTransaction.fromBinary(rawTx)\n  } catch {\n    throw new WERR_INVALID_OPERATION('Parsing serialized transaction failed.')\n  }\n  if (params.txid !== tx.id('hex')) {\n    throw new WERR_INVALID_OPERATION(\"Hash of serialized transaction doesn't match expected txid\")\n  }\n  const services = storage.getServices()\n  if (!(await services.nLockTimeIsFinal(tx))) {\n    throw new WERR_INVALID_OPERATION(`This transaction is not final.\n         Ensure that the transaction meets the rules for being a finalized\n         which can be found at https://wiki.bitcoinsv.io/index.php/NLocktime_and_nSequence`)\n  }\n  const txScriptOffsets = parseTxScriptOffsets(rawTx)\n  const transaction = verifyOne(\n    await storage.findTransactions({\n      partial: { userId, reference: params.reference }\n    })\n  )\n  if (!transaction.isOutgoing) throw new WERR_INVALID_OPERATION('isOutgoing is not true')\n  if (transaction.inputBEEF == null) throw new WERR_INVALID_OPERATION()\n  // Transaction must have unsigned or unprocessed status\n  if (transaction.status !== 'unsigned' && transaction.status !== 'unprocessed') {\n    throw new WERR_INVALID_OPERATION(`invalid transaction status ${transaction.status}`)\n  }\n  const transactionId = verifyId(transaction.transactionId)\n  // These reads are independent once the planned transaction is resolved.\n  // Running them together removes two network-database round trips from every\n  // successful remote-storage commit.\n  const [outputOutputs, commissionRows] = await Promise.all([\n    storage.findOutputs({ partial: { userId, transactionId } }),\n    storage.commissionSatoshis > 0\n      ? storage.findCommissions({ partial: { transactionId, userId } })\n      : Promise.resolve([])\n  ])\n\n  const commission = verifyOneOrNone(commissionRows)\n  if (storage.commissionSatoshis > 0) {\n    // A commission is required...\n    if (commission == null) throw new WERR_INTERNAL()\n    const commissionValid = tx.outputs.some(\n      x => x.satoshis === commission.satoshis && x.lockingScript.toHex() === asString(commission.lockingScript)\n    )\n    if (!commissionValid) {\n      throw new WERR_INVALID_OPERATION('Transaction did not include an output to cover service fee.')\n    }\n  }\n\n  const req = EntityProvenTxReq.fromTxid(params.txid, rawTx, transaction.inputBEEF)\n  req.addNotifyTransactionId(transactionId)\n\n  // \"Processing\" a transaction is the final step of creating a new one.\n  // If it is to be sent to the network directly (prior to return from processAction),\n  // then there is status pre-send and post-send.\n  // Otherwise there is no post-send status.\n  // Note that isSendWith trumps isNoSend, e.g. isNoSend && !isSendWith\n  //\n  // Determine what status the req and transaction should have pre- at the end of processing.\n  //                           Pre-Status (to newReq/newTx)     Post-Status (to all sent reqs/txs)\n  //                           req         tx                   req                 tx\n  // isNoSend                  noSend      noSend\n  // !isNoSend && isDelayed    unsent      unprocessed\n  // !isNoSend && !isDelayed   unprocessed unprocessed          sending/unmined     sending/unproven      This is the only case that sends immediately.\n  const { status, postStatus } = determineReqTxStatus(params)\n\n  req.status = status.req\n  const vargs: ValidCommitNewTxToStorageArgs = {\n    reference: params.reference,\n    txid: params.txid,\n    rawTx,\n    isSendWith: !!params.sendWith && params.sendWith.length > 0,\n    isDelayed: params.isDelayed,\n    isNoSend: params.isNoSend,\n    // Properties with values added during validation.\n    tx,\n    txScriptOffsets,\n    transactionId,\n    transaction,\n    outputOutputs,\n    req,\n    outputUpdates: [],\n    // update txid, status in transactions table and drop rawTransaction value\n    transactionUpdate: {\n      txid: params.txid,\n      rawTx: undefined,\n      inputBEEF: undefined,\n      status: status.tx\n    },\n    postStatus\n  }\n\n  // update outputs with txid, script offsets and lengths, drop long output scripts from outputs table\n  // outputs spendable will be updated for change to true and all others to !!o.tracked when tx has been broadcast\n  // MAX_OUTPUTSCRIPT_LENGTH is limit for scripts left in outputs table\n  buildOutputUpdates(storage, tx, vargs)\n\n  return vargs\n}\n\nexport interface CommitNewTxResults {\n  req: EntityProvenTxReq\n  log?: string\n}\n\nasync function commitNewTxToStorage(\n  storage: StorageProvider,\n  userId: number,\n  vargs: ValidCommitNewTxToStorageArgs\n): Promise<CommitNewTxResults> {\n  let log = vargs.log\n\n  log = stampLog(log, 'start storage commitNewTxToStorage')\n\n  let req: EntityProvenTxReq | undefined\n\n  await storage.transaction(async trx => {\n    log = stampLog(log, '... storage commitNewTxToStorage storage transaction start')\n\n    // Create initial 'nosend' proven_tx_req record to store signed, valid rawTx and input beef\n    req = await vargs.req.insertOrMerge(storage, trx)\n\n    log = stampLog(log, '... storage commitNewTxToStorage req inserted')\n\n    for (const ou of vargs.outputUpdates) {\n      await storage.updateOutput(ou.id, ou.update, trx)\n    }\n\n    log = stampLog(log, '... storage commitNewTxToStorage outputs updated')\n\n    await storage.updateTransaction(vargs.transactionId, vargs.transactionUpdate, trx)\n\n    log = stampLog(log, '... storage commitNewTxToStorage storage transaction end')\n  })\n\n  log = stampLog(log, '... storage commitNewTxToStorage storage transaction await done')\n\n  const r: CommitNewTxResults = {\n    req: verifyTruthy(req),\n    log\n  }\n\n  log = stampLog(log, 'end storage commitNewTxToStorage')\n\n  return r\n}\n","import { Beef, Transaction, WalletLoggerInterface } from '@bsv/sdk'\nimport { StorageProvider } from '../StorageProvider'\nimport { EntityProvenTxReq } from '../schema/entities'\nimport * as sdk from '../../sdk'\nimport { ReqHistoryNote } from '../../sdk'\nimport { wait } from '../../utility/utilityHelpers'\n\n/**\n * Attempt to post one or more `ProvenTxReq` with status 'unsent'\n * to the bitcoin network.\n *\n * @param reqs\n */\nexport async function attemptToPostReqsToNetwork (\n  storage: StorageProvider,\n  reqs: EntityProvenTxReq[],\n  trx?: sdk.TrxToken,\n  logger?: WalletLoggerInterface\n): Promise<PostReqsToNetworkResult> {\n  // initialize results, validate reqs ready to post, txids are of the transactions in the beef that we care about.\n\n  const { r, vreqs, txids } = await validateReqsAndMergeBeefs(storage, reqs, trx)\n  logger?.log('validated request and merged beefs')\n\n  const services = storage.getServices()\n\n  const pbrs = await services.postBeef(r.beef, txids, logger)\n\n  // post beef results (pbrs) is an array by service provider\n  // for each service provider, there's an aggregate result and individual results by txid.\n\n  await transferNotesToReqHistories(txids, vreqs, pbrs, storage, trx)\n\n  const apbrs = aggregatePostBeefResultsByTxid(txids, vreqs, pbrs)\n\n  await updateReqsFromAggregateResults(txids, r, apbrs, storage, services, trx, logger)\n\n  return r\n}\n\nasync function validateReqsAndMergeBeefs (\n  storage: StorageProvider,\n  reqs: EntityProvenTxReq[],\n  trx?: sdk.TrxToken\n): Promise<{ r: PostReqsToNetworkResult, vreqs: PostReqsToNetworkDetails[], txids: string[] }> {\n  const r: PostReqsToNetworkResult = {\n    status: 'success',\n    beef: new Beef(),\n    details: [],\n    log: ''\n  }\n\n  const vreqs: PostReqsToNetworkDetails[] = []\n\n  for (const req of reqs) {\n    try {\n      const noRawTx = !req.rawTx\n      const noTxIds = (req.notify.transactionIds == null) || req.notify.transactionIds.length < 1\n      const noInputBEEF = req.inputBEEF == null\n      if (noRawTx || noTxIds || noInputBEEF) {\n        // This should have happened earlier...\n        req.addHistoryNote({ when: new Date().toISOString(), what: 'validateReqFailed', noRawTx, noTxIds, noInputBEEF })\n        req.status = 'invalid'\n        await req.updateStorageDynamicProperties(storage, trx)\n        r.details.push({ txid: req.txid, req, status: 'invalid' })\n      } else {\n        const vreq: PostReqsToNetworkDetails = { txid: req.txid, req, status: 'unknown' }\n        await storage.mergeReqToBeefToShareExternally(req.api, r.beef, [], trx)\n        vreqs.push(vreq)\n        r.details.push(vreq)\n      }\n    } catch (error_: unknown) {\n      const { code, message } = sdk.WalletError.fromUnknown(error_)\n      req.addHistoryNote({ when: new Date().toISOString(), what: 'validateReqError', txid: req.txid, code, message })\n      req.attempts++\n      if (req.attempts > 6 || message.startsWith('The txid parameter must be known to storage')) {\n        req.status = 'invalid'\n        r.details.push({ txid: req.txid, req, status: 'invalid' })\n      }\n      await req.updateStorageDynamicProperties(storage, trx)\n    }\n  }\n  return { r, vreqs, txids: vreqs.map(r => r.txid) }\n}\n\nasync function transferNotesToReqHistories (\n  txids: string[],\n  vreqs: PostReqsToNetworkDetails[],\n  pbrs: sdk.PostBeefResult[],\n  storage: StorageProvider,\n  trx?: sdk.TrxToken\n): Promise<void> {\n  for (const txid of txids) {\n    const vreq = vreqs.find(r => r.txid === txid)\n    if (vreq == null) throw new sdk.WERR_INTERNAL()\n    const notes: sdk.ReqHistoryNote[] = []\n    for (const pbr of pbrs) {\n      notes.push(...(pbr.notes || []))\n      const r = pbr.txidResults.find(tr => tr.txid === txid)\n      if (r != null) notes.push(...(r.notes || []))\n    }\n    for (const n of notes) {\n      vreq.req.addHistoryNote(n)\n    }\n    await vreq.req.updateStorageDynamicProperties(storage, trx)\n  }\n}\n\nfunction tallyTxidResults (\n  ar: AggregatePostBeefTxResult,\n  pbrs: sdk.PostBeefResult[]\n): void {\n  for (const pbr of pbrs) {\n    const tr = pbr.txidResults.find(tr => tr.txid === ar.txid)\n    if (tr == null) continue\n    ar.txidResults.push(tr)\n    if (tr.status === 'success') {\n      ar.successCount++\n    } else if (tr.doubleSpend) {\n      ar.doubleSpendCount++\n      if (tr.competingTxs != null) ar.competingTxs = [...tr.competingTxs]\n    } else if (tr.serviceError) {\n      ar.serviceErrorCount++\n    } else {\n      ar.statusErrorCount++\n    }\n  }\n  if (ar.competingTxs.length > 1) ar.competingTxs = [...new Set(ar.competingTxs)]\n}\n\n/**\n * For each txid, decide on the aggregate success or failure of attempting to broadcast it to the bitcoin processing network.\n *\n * Possible results:\n * 1. Success: At least one success, no double spends.\n * 2. DoubleSpend: One or more double spends.\n * 3. InvalidTransaction: No success, no double spend, one or more non-exception errors.\n * 4. Service Failure: No results or all results are exception errors.\n *\n * @param txids\n * @param reqs\n * @param pbrs\n * @param storage\n * @returns\n */\nfunction aggregatePostBeefResultsByTxid (\n  txids: string[],\n  vreqs: PostReqsToNetworkDetails[],\n  pbrs: sdk.PostBeefResult[]\n): Record<string, AggregatePostBeefTxResult> {\n  const r: Record<string, AggregatePostBeefTxResult> = {}\n\n  for (const txid of txids) {\n    const vreq = vreqs.find(r => r.txid === txid)!\n    const ar: AggregatePostBeefTxResult = {\n      txid,\n      vreq,\n      txidResults: [],\n      status: 'success',\n      successCount: 0,\n      doubleSpendCount: 0,\n      statusErrorCount: 0,\n      serviceErrorCount: 0,\n      competingTxs: []\n    }\n    r[txid] = ar\n    tallyTxidResults(ar, pbrs)\n\n    if (ar.successCount > 0 && ar.doubleSpendCount === 0) ar.status = 'success'\n    else if (ar.doubleSpendCount > 0) ar.status = 'doubleSpend'\n    else if (ar.statusErrorCount > 0) ar.status = 'invalidTx'\n    else ar.status = 'serviceError'\n  }\n\n  return r\n}\n\n/**\n * For each txid in submitted `txids`:\n *\n *   Based on its aggregate status, and whether broadcast happening in background (isDelayed) or immediately (!isDelayed),\n *   and iff current req.status is not 'unproven' or 'completed':\n *\n *     'success':\n *       req.status => 'unmined', tx.status => 'unproven'\n *     'doubleSpend':\n *       req.status => 'doubleSpend', tx.status => 'failed'\n *     'invalidTx':\n *       req.status => 'invalid', tx.status => 'failed'\n *     'serviceError':\n *       increment req.attempts\n *\n * @param txids\n * @param apbrs\n * @param storage\n * @param services if valid, doubleSpend results will be verified (but only if not within a trx. e.g. trx must be undefined)\n * @param trx\n */\nfunction applyAggregateStatus(\n  req: EntityProvenTxReq,\n  status: AggregateStatus\n): { newReqStatus: sdk.ProvenTxReqStatus; newTxStatus: sdk.TransactionStatus } {\n  switch (status) {\n    case 'success':\n      // Mark as broadcast so proof-timeout resets to rebroadcast rather than invalid.\n      req.wasBroadcast = true\n      return { newReqStatus: 'unmined', newTxStatus: 'unproven' }\n    case 'doubleSpend':\n      return { newReqStatus: 'doubleSpend', newTxStatus: 'failed' }\n    case 'invalidTx':\n      return { newReqStatus: 'invalid', newTxStatus: 'failed' }\n    case 'serviceError':\n      req.attempts++\n      return { newReqStatus: 'sending', newTxStatus: 'sending' }\n    default:\n      throw new sdk.WERR_INTERNAL(`unimplemented AggregateStatus ${status}`)\n  }\n}\n\nasync function recordStaleInputEvidence(\n  ar: AggregatePostBeefTxResult,\n  req: EntityProvenTxReq,\n  storage: StorageProvider,\n  services: sdk.WalletServices | undefined,\n  trx: sdk.TrxToken | undefined,\n  logger: WalletLoggerInterface | undefined\n): Promise<void> {\n  if (services == null || trx != null) return\n\n  const stale = await markStaleInputsAsSpent(ar, storage, services, trx, logger)\n  if (stale.checked === 0) return\n\n  req.addHistoryNote({\n    when: new Date().toISOString(),\n    what: 'markStaleInputsAsSpent',\n    aggStatus: ar.status,\n    checked: stale.checked,\n    confirmed: stale.staleConfirmed,\n    ...(stale.staleOutpoints.length > 0\n      ? { outpoints: stale.staleOutpoints.join(',') }\n      : {})\n  })\n  await req.updateStorageDynamicProperties(storage, trx)\n}\n\nexport async function updateReqsFromAggregateResults (\n  txids: string[],\n  r: PostReqsToNetworkResult,\n  apbrs: Record<string, AggregatePostBeefTxResult>,\n  storage: StorageProvider,\n  services?: sdk.WalletServices,\n  trx?: sdk.TrxToken,\n  logger?: WalletLoggerInterface\n): Promise<void> {\n  logger?.group('update storage from aggregate results')\n  for (const txid of txids) {\n    const ar = apbrs[txid]\n    const req = ar.vreq.req\n    await req.refreshFromStorage(storage, trx)\n\n    const { successCount, doubleSpendCount, statusErrorCount, serviceErrorCount } = ar\n    const note: ReqHistoryNote = {\n      when: new Date().toISOString(),\n      what: 'aggregateResults',\n      reqStatus: req.status,\n      aggStatus: ar.status,\n      attempts: req.attempts,\n      successCount,\n      doubleSpendCount,\n      statusErrorCount,\n      serviceErrorCount\n    }\n\n    if (['completed', 'unmined'].includes(req.status))\n    // However it happened, don't degrade status if it is somehow already beyond broadcast stage\n    { continue }\n\n    if (ar.status === 'doubleSpend' && (services != null) && (trx == null)) await confirmDoubleSpend(ar, r.beef, storage, services, logger)\n\n    const { newReqStatus, newTxStatus } = applyAggregateStatus(req, ar.status)\n\n    note.newReqStatus = newReqStatus\n    note.newTxStatus = newTxStatus\n    note.newAttempts = req.attempts\n\n    req.status = newReqStatus\n\n    req.addHistoryNote(note)\n    await req.updateStorageDynamicProperties(storage, trx)\n\n    const ids = req.notify.transactionIds\n    if (ids != null) {\n      // Also set generated outputs to spendable false and consumed input outputs to spendable true (and clears their spentBy).\n      await storage.updateTransactionsStatus(ids, newTxStatus, trx)\n    }\n\n    // For ANY failed-broadcast result (doubleSpend, invalidTx,\n    // serviceError-resolved-to-failure), override the optimistic\n    // \"restore inputs spendable\" behavior of updateTransactionStatus\n    // for inputs that on-chain state confirms are actually spent.\n    // Without this, the wallet picks the same stale UTXO on the next\n    // createAction — an infinite missing-inputs loop. Apps cannot\n    // self-heal because the default basket is admin-only on\n    // app-isolated wallets (e.g. metanet-desktop).\n    //\n    // Why broaden beyond doubleSpend (Codex review 51331f6e035a7ed0):\n    // different broadcasters classify the same on-chain reality\n    // differently. ARC reports SEEN_IN_ORPHAN_MEMPOOL → doubleSpend.\n    // WoC + Bitails report 'Missing inputs' / 'missing-inputs' →\n    // invalidTx. Both mean the same root cause (referenced UTXO is\n    // gone). The helper is conservatively opt-in on positive\n    // isUtxo===false evidence: malformed/fee/script failures whose\n    // inputs are still UTXOs are LEFT spendable=true, preserving\n    // the existing transient-retry semantics. So broadening is safe.\n    //\n    // Gate: services available + not in a nested transaction (chain\n    // queries are async I/O — same gate as confirmDoubleSpend).\n    if (newTxStatus === 'failed')\n      await recordStaleInputEvidence(ar, req, storage, services, trx, logger)\n\n    // Transfer critical results to details going back to the user\n    const details = r.details.find(d => d.txid === txid)!\n    details.status = ar.status\n    details.competingTxs = ar.competingTxs\n    logger?.log(`updated ${txid}`)\n  }\n  logger?.group('update storage from aggregate results')\n}\n\nasync function gatherCompetingTxids (\n  ar: AggregatePostBeefTxResult,\n  beef: Beef,\n  services: sdk.WalletServices,\n  note: ReqHistoryNote,\n  logger?: WalletLoggerInterface\n): Promise<void> {\n  const req = ar.vreq.req\n  const tx = Transaction.fromBinary(req.rawTx)\n  const competingTxids = new Set(ar.competingTxs)\n  for (const input of tx.inputs) {\n    const sourceTx = beef.findTxid(input.sourceTXID!)?.tx\n    if (sourceTx == null) {\n      let s = note.missingSourceTx || ''\n      s += input.sourceTXID! + ' '\n      note.missingSourceTx = s\n      continue\n    }\n    const lockingScript = sourceTx.outputs[input.sourceOutputIndex].lockingScript.toHex()\n    const hash = services.hashOutputScript(lockingScript)\n    const shhrs = await services.getScriptHashHistory(hash, undefined, logger)\n    if (shhrs.status === 'success') {\n      for (const h of shhrs.history) {\n        // Neither the source of the input nor the current transaction are competition.\n        if (h.txid !== input.sourceTXID && h.txid !== ar.txid) competingTxids.add(h.txid)\n      }\n    }\n  }\n  ar.competingTxs = [...competingTxids].slice(-24) // keep at most 24, if they were sorted by time, keep newest\n  note.competingTxs = ar.competingTxs.join(',')\n}\n\n/**\n * Requires ar.status === 'doubleSpend'\n *\n * Parse the rawTx and review each input as a possible double spend.\n *\n * If all inputs appear to be unspent, update aggregate status to 'success' if successCount > 0, otherwise 'serviceError'.\n *\n * @param ar\n * @param storage\n * @param services\n */\nasync function confirmDoubleSpend (\n  ar: AggregatePostBeefTxResult,\n  beef: Beef,\n  storage: StorageProvider,\n  services: sdk.WalletServices,\n  logger?: WalletLoggerInterface\n): Promise<void> {\n  const req = ar.vreq.req\n  const note: ReqHistoryNote = { when: new Date().toISOString(), what: 'confirmDoubleSpend' }\n\n  let known = false\n\n  for (let retry = 0; retry < 3; retry++) {\n    const gsr = await services.getStatusForTxids([req.txid])\n    const errCode = gsr.error != null ? gsr.error.code : ''\n    note[`getStatus${retry}`] = `${gsr.status}${errCode},${gsr.results[0]?.status}`\n    if (gsr.status !== 'success' || gsr.results[0].status === 'unknown') {\n      await wait(1000)\n    } else {\n      known = true\n      break\n    }\n  }\n\n  if (known) {\n    // doubleSpend -> success\n    ar.status = 'success'\n    note.newStatus = ar.status\n  } else {\n    // Confirmed double spend, get txids of possible competing transactions.\n    await gatherCompetingTxids(ar, beef, services, note, logger)\n  }\n  req.addHistoryNote(note)\n}\n\n/**\n * After any failed broadcast (doubleSpend, invalidTx, etc.), query each\n * consumed-input outpoint of the failed transaction against on-chain\n * UTXO state. For inputs the chain authoritatively confirms are spent\n * (i.e. NOT a UTXO), update the corresponding wallet basket entry to\n * spendable=false.\n *\n * Background: `updateTransactionStatus(failed)` optimistically restores\n * all consumed-input outputs to spendable=true so the user can retry\n * with the same inputs. For some failures (genuine doubleSpend, or any\n * 'missing-inputs' outcome where the input has been spent on chain by\n * a different transaction), restoration is incorrect — the input is\n * gone and restoring it produces an infinite missing-inputs loop on\n * the next createAction → broadcast cycle. Apps cannot evict from the\n * default basket on app-isolated wallets (admin-only policy), so this\n * self-heal must run inside the wallet.\n *\n * Different broadcasters classify the same on-chain reality differently\n * (ARC → doubleSpend, WhatsOnChain/Bitails → invalidTx via\n * 'missing-inputs'); this helper is broadcaster-agnostic because its\n * decision is based on services.isUtxo, not the aggregate failure\n * classification.\n *\n * Pre-broadcast races where concurrent createActions reach the same\n * UTXO across separate app processes are out of scope; see PR\n * description.\n *\n * Conservatively scoped:\n *   - Only inputs found in the failing user's basket are touched.\n *   - Inputs whose on-chain UTXO status cannot be determined (service\n *     error / inconclusive) are left spendable=true. Eviction is opt-in\n *     based on positive evidence of stale state.\n *   - Inputs the chain confirms are still UTXOs (e.g. a competing tx\n *     itself failed, or a malformed/fee failure where inputs are intact)\n *     are left spendable=true — preserving the existing transient-retry\n *     semantics callers depend on.\n *\n * Returns counts for instrumentation and the set of stale outpoints\n * that were actually evicted (added to history note for diagnostics).\n */\nexport async function markStaleInputsAsSpent (\n  ar: AggregatePostBeefTxResult,\n  storage: StorageProvider,\n  services: sdk.WalletServices,\n  trx?: sdk.TrxToken,\n  logger?: WalletLoggerInterface\n): Promise<{ checked: number; staleConfirmed: number; staleOutpoints: string[] }> {\n  const result = { checked: 0, staleConfirmed: 0, staleOutpoints: [] as string[] }\n  const req = ar.vreq.req\n\n  // Resolve the user owning the failing tx so we only touch THIS user's\n  // basket entries. Multiple txids share a userId; first is sufficient.\n  const txIds = req.notify.transactionIds\n  if (txIds == null || txIds.length === 0) return result\n  const txRecord = (await storage.findTransactions({\n    partial: { transactionId: txIds[0] },\n    noRawTx: true,\n    trx\n  }))[0]\n  if (txRecord == null) return result\n  const userId = txRecord.userId\n\n  // Walk the failed tx's inputs to find which user-owned UTXOs were\n  // consumed and need on-chain verification.\n  const tx = Transaction.fromBinary(req.rawTx)\n  const outpoints = tx.inputs\n    .map(i => ({ txid: i.sourceTXID ?? '', vout: i.sourceOutputIndex ?? 0 }))\n    .filter(o => o.txid !== '')\n  if (outpoints.length === 0) return result\n\n  const byOutpoint = await storage.findOutputsByOutpoints(userId, outpoints, trx)\n\n  // Two-phase processing:\n  //   Phase 1 (parallel, read-only): validateOutputScript + services.isUtxo\n  //     run concurrently across all outpoints. Both are network-bound on\n  //     the slow path; serializing them produces O(N) wall-time for no\n  //     correctness benefit. validateOutputScript only lazily fills the\n  //     in-memory lockingScript from a known-valid tx (no shared state\n  //     to race). services.isUtxo is provider HTTP — independent calls.\n  //     Per-provider rate limiters that 429 some calls fall into the\n  //     existing service-error branch and preserve retry semantics for\n  //     those inputs; the surviving inputs still get correct treatment.\n  //   Phase 2 (serial, in-trx writes): drain the per-input classification\n  //     into result.checked / staleConfirmed accumulators and the\n  //     storage.updateOutput writes, in iteration order. Storage writes\n  //     stay serialized inside the trx — no change in transactional\n  //     semantics from the pre-parallel version.\n  type CheckResult =\n    | { kind: 'skipped' }\n    | { kind: 'service-error'; localOutput: typeof byOutpoint[keyof typeof byOutpoint] }\n    | { kind: 'still-utxo'; localOutput: typeof byOutpoint[keyof typeof byOutpoint] }\n    | {\n        kind: 'stale'\n        localOutput: typeof byOutpoint[keyof typeof byOutpoint]\n        outpoint: { txid: string; vout: number }\n      }\n\n  const checks: CheckResult[] = await Promise.all(\n    outpoints.map(async (outpoint): Promise<CheckResult> => {\n      const localOutput = byOutpoint[`${outpoint.txid}.${outpoint.vout}`]\n      if (localOutput == null) return { kind: 'skipped' }\n\n      // services.isUtxo requires the lockingScript; load it lazily.\n      if (localOutput.lockingScript == null) {\n        try {\n          await storage.validateOutputScript(localOutput, trx)\n        } catch {\n          return { kind: 'skipped' }\n        }\n      }\n\n      let isStillUtxo: boolean\n      try {\n        isStillUtxo = await services.isUtxo(localOutput)\n      } catch {\n        // Service error — preserve current behavior (keep spendable=true).\n        // Eviction requires positive evidence of stale state.\n        return { kind: 'service-error', localOutput }\n      }\n\n      return isStillUtxo\n        ? { kind: 'still-utxo', localOutput }\n        : { kind: 'stale', localOutput, outpoint }\n    })\n  )\n\n  for (const c of checks) {\n    if (c.kind === 'skipped') continue\n    result.checked++\n    if (c.kind === 'stale') {\n      // Authoritative on-chain evidence the input is spent. Override\n      // the optimistic restore from updateTransactionStatus(failed).\n      await storage.updateOutput(\n        c.localOutput.outputId!,\n        { spendable: false },\n        trx\n      )\n      result.staleConfirmed++\n      result.staleOutpoints.push(`${c.outpoint.txid}.${c.outpoint.vout}`)\n    }\n  }\n\n  if (result.staleConfirmed > 0) {\n    logger?.log(\n      `markStaleInputsAsSpent: ${result.staleConfirmed} of ${result.checked} input(s) confirmed-spent on chain for txid=${req.txid}`\n    )\n  }\n  return result\n}\n\ntype AggregateStatus = 'success' | 'doubleSpend' | 'invalidTx' | 'serviceError'\n\nexport interface AggregatePostBeefTxResult {\n  txid: string\n  txidResults: sdk.PostTxResultForTxid[]\n  status: AggregateStatus\n  vreq: PostReqsToNetworkDetails\n  successCount: number\n  doubleSpendCount: number\n  statusErrorCount: number\n  serviceErrorCount: number\n  /**\n   * Any competing double spend txids reported for this txid\n   */\n  competingTxs: string[]\n}\n\n/**\n * Indicates status of a new Action following a `createAction` or `signAction` in immediate mode:\n * When `acceptDelayedBroadcast` is falses.\n *\n * 'success': The action has been broadcast and accepted by the bitcoin processing network.\n * 'doubleSpend': The action has been confirmed to double spend one or more inputs, and by the \"first-seen-rule\" is the losing transaction.\n * 'invalidTx': The action was rejected by the processing network as an invalid bitcoin transaction.\n * 'serviceError': The broadcast services are currently unable to reach the bitcoin network. The action is now queued for delayed retries.\n *\n * 'invalid': The action was in an invalid state for processing, this status should never be seen by user code.\n * 'unknown': An internal processing error has occured, this status should never be seen by user code.\n *\n */\nexport type PostReqsToNetworkDetailsStatus =\n  | 'success'\n  | 'doubleSpend'\n  | 'unknown'\n  | 'invalid'\n  | 'serviceError'\n  | 'invalidTx'\n\nexport interface PostReqsToNetworkDetails {\n  txid: string\n  req: EntityProvenTxReq\n  status: PostReqsToNetworkDetailsStatus\n  /**\n   * Any competing double spend txids reported for this txid\n   */\n  competingTxs?: string[]\n}\n\nexport interface PostReqsToNetworkResult {\n  status: 'success' | 'error'\n  beef: Beef\n  details: PostReqsToNetworkDetails[]\n  log: string\n}\n","import { ListCertificatesResult, OriginatorDomainNameStringUnder250Bytes, Validation } from '@bsv/sdk'\nimport { StorageProvider } from '../StorageProvider'\nimport { TableCertificate } from '../schema/tables/TableCertificate'\nimport { AuthId, FindCertificatesArgs } from '../../sdk/WalletStorage.interfaces'\nimport { Paged } from '../../sdk/types'\n\nexport async function listCertificates(\n  storage: StorageProvider,\n  auth: AuthId,\n  vargs: Validation.ValidListCertificatesArgs,\n  _originator?: OriginatorDomainNameStringUnder250Bytes\n): Promise<ListCertificatesResult> {\n  const paged: Paged = { limit: vargs.limit, offset: vargs.offset }\n\n  const partial: Partial<TableCertificate> = {\n    userId: auth.userId,\n    isDeleted: false\n  }\n\n  if (vargs.partial != null) {\n    const vp = vargs.partial\n    if (vp.type) partial.type = vp.type\n    if (vp.subject) partial.subject = vp.subject\n    if (vp.serialNumber) partial.serialNumber = vp.serialNumber\n    if (vp.certifier) partial.certifier = vp.certifier\n    if (vp.revocationOutpoint) partial.revocationOutpoint = vp.revocationOutpoint\n    if (vp.signature) partial.signature = vp.signature\n  }\n\n  const r = await storage.transaction(async trx => {\n    const findCertsArgs: FindCertificatesArgs = {\n      partial,\n      certifiers: vargs.certifiers,\n      types: vargs.types,\n      paged,\n      trx\n    }\n    const certs = await storage.findCertificates(findCertsArgs)\n    const certsWithFields = await Promise.all(\n      certs.map(async cert => {\n        const fields = await storage.findCertificateFields({\n          partial: { certificateId: cert.certificateId, userId: auth.userId },\n          trx\n        })\n        return {\n          ...cert,\n          fields: Object.fromEntries(fields.map(f => [f.fieldName, f.fieldValue])),\n          masterKeyring: Object.fromEntries(fields.map(f => [f.fieldName, f.masterKey]))\n        }\n      })\n    )\n    const r: ListCertificatesResult = {\n      totalCertificates: 0,\n      certificates: certsWithFields.map(cwf => ({\n        type: cwf.type,\n        subject: cwf.subject,\n        serialNumber: cwf.serialNumber,\n        certifier: cwf.certifier,\n        revocationOutpoint: cwf.revocationOutpoint,\n        signature: cwf.signature,\n        fields: cwf.fields,\n        verifier: cwf.verifier,\n        keyring: cwf.masterKeyring\n      }))\n    }\n    if (r.certificates.length < paged.limit) r.totalCertificates = r.certificates.length\n    else {\n      r.totalCertificates = await storage.countCertificates(findCertsArgs)\n    }\n    return r\n  })\n\n  return r\n}\n","import { WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\n\n/**\n * Returns the byte size required to encode number as Bitcoin VarUint\n * @publicbody\n */\nexport function varUintSize (val: number): 1 | 3 | 5 | 9 {\n  if (val < 0) throw new WERR_INVALID_PARAMETER('varUint', 'non-negative')\n  if (val <= 0xfc) return 1\n  if (val <= 0xffff) return 3\n  if (val <= 0xffffffff) return 5\n  return 9\n}\n\n/**\n * @param scriptSize byte length of input script\n * @returns serialized byte length a transaction input\n */\nexport function transactionInputSize (scriptSize: number): number {\n  return (\n    32 + // txid\n    4 + // vout\n    varUintSize(scriptSize) + // script length, this is already in bytes\n    scriptSize + // script\n    4\n  ) // sequence number\n}\n\n/**\n * @param scriptSize byte length of output script\n * @returns serialized byte length a transaction output\n */\n\nexport function transactionOutputSize (scriptSize: number): number {\n  return (\n    varUintSize(scriptSize) + // output script length, from script encoded as hex string\n    scriptSize + // output script\n    8\n  ) // output amount (satoshis)\n}\n\n/**\n * Compute the serialized binary transaction size in bytes\n * given the number of inputs and outputs,\n * and the size of each script.\n * @param inputs array of input script lengths, in bytes\n * @param outputs array of output script lengths, in bytes\n * @returns total transaction size in bytes\n */\nexport function transactionSize (inputs: number[], outputs: number[]): number {\n  return (\n    4 + // Version\n    varUintSize(inputs.length) + // Number of inputs\n    inputs.reduce((a, e) => a + transactionInputSize(e), 0) + // all inputs\n    varUintSize(outputs.length) + // Number of outputs\n    outputs.reduce((a, e) => a + transactionOutputSize(e), 0) + // all outputs\n    4\n  ) // lock time\n}\n","import { Random, Telemetry, TelemetrySpan, Validation, WalletLoggerInterface } from '@bsv/sdk'\nimport { WalletError } from '../../sdk/WalletError'\nimport { StorageFeeModel } from '../../sdk/WalletStorage.interfaces'\nimport { WERR_INSUFFICIENT_FUNDS, WERR_INTERNAL, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { validateStorageFeeModel } from '../StorageProvider'\nimport { transactionInputSize, transactionOutputSize, transactionSize, varUintSize } from './utils'\n/**\n * An output of this satoshis amount will be adjusted to the largest fundable amount.\n */\nexport const maxPossibleSatoshis = 2099999999999999\n\n/**\n * Maximum number of change outputs to create in a single transaction.\n *\n * Limits how aggressively the wallet builds up its UTXO pool in one shot.\n * When a user first imports a large UTXO, without this cap the wallet would\n * attempt to create `numberOfDesiredUTXOs` change outputs in a single\n * transaction.  That produces a very large transaction whose raw bytes are\n * embedded in the BEEF of every subsequent child transaction, bloating those\n * BEEFs and slowing down external processors.\n *\n * With this cap the UTXO pool builds gradually — at most 8 net new change\n * outputs per transaction — so no single transaction becomes unreasonably\n * large.  A pool of 144 desired UTXOs fills over roughly 18 transactions\n * rather than 1.\n */\nexport const maxChangeOutputsPerTransaction = 8\n\nexport interface GenerateChangeSdkResult {\n  allocatedChangeInputs: GenerateChangeSdkChangeInput[]\n  changeOutputs: GenerateChangeSdkChangeOutput[]\n  size: number\n  fee: number\n  satsPerKb: number\n  maxPossibleSatoshisAdjustment?: {\n    fixedOutputIndex: number\n    satoshis: number\n  }\n}\n\n/**\n * Remove change input/output pairs that represent pointless churn —\n * a change input whose satoshis are covered by a single change output.\n * Mutates both arrays in place.\n */\nfunction removeChurnPairs(\n  allocatedChangeInputs: GenerateChangeSdkChangeInput[],\n  changeOutputs: GenerateChangeSdkChangeOutput[]\n): void {\n  const changeInputs = [...allocatedChangeInputs]\n  while (changeInputs.length > 1 && changeOutputs.length > 1) {\n    const lastOutput = changeOutputs.at(-1)!\n    const i = changeInputs.findIndex(ci => ci.satoshis <= lastOutput.satoshis)\n    if (i < 0) break\n    changeOutputs.pop()\n    changeInputs.splice(i, 1)\n  }\n}\n\n/**\n * Distribute excess fee satoshis across the change outputs.\n * Returns the updated feeExcessNow (will be 0 after distribution).\n */\nfunction distributeExcessFees(\n  changeOutputs: GenerateChangeSdkChangeOutput[],\n  changeInitialSatoshis: number,\n  feeExcessNow: number,\n  rand: (min: number, max: number) => number\n): number {\n  while (changeOutputs.length > 0 && feeExcessNow > 0) {\n    if (changeOutputs.length === 1) {\n      changeOutputs[0].satoshis += feeExcessNow\n      feeExcessNow = 0\n    } else if (changeOutputs[0].satoshis < changeInitialSatoshis) {\n      const sats = Math.min(feeExcessNow, changeInitialSatoshis - changeOutputs[0].satoshis)\n      feeExcessNow -= sats\n      changeOutputs[0].satoshis += sats\n    } else {\n      // Distribute a random percentage between 25% and 50% but at least one satoshi\n      const sats = Math.max(1, Math.floor((rand(2500, 5000) / 10000) * feeExcessNow))\n      feeExcessNow -= sats\n      const index = rand(0, changeOutputs.length - 1)\n      changeOutputs[index].satoshis += sats\n    }\n  }\n  return feeExcessNow\n}\n\n/**\n * Remove change outputs below dustFloor, consolidating their satoshis into the largest output.\n * Always keeps at least one output.\n */\nfunction removeDustOutputs(changeOutputs: GenerateChangeSdkChangeOutput[], dustFloor: number): void {\n  for (let i = changeOutputs.length - 1; i >= 0; i--) {\n    if (changeOutputs[i].satoshis < dustFloor && changeOutputs.length > 1) {\n      const [removed] = changeOutputs.splice(i, 1)\n      // Add the removed sats to the largest remaining output so no sats are lost.\n      const largest = changeOutputs.reduce((best, o) => (o.satoshis > best.satoshis ? o : best), changeOutputs[0])\n      largest.satoshis += removed.satoshis\n    }\n  }\n}\n\n/**\n * Simplifications:\n *  - only support one change type with fixed length scripts.\n *  - only support satsPerKb fee model.\n *\n * Confirms for each availbleChange output that it remains available as they are allocated and selects alternate if not.\n *\n * @param params\n * @returns\n */\nexport async function generateChangeSdk(\n  params: GenerateChangeSdkParams,\n  allocateChangeInput: (\n    targetSatoshis: number,\n    exactSatoshis?: number\n  ) => Promise<GenerateChangeSdkChangeInput | undefined>,\n  releaseChangeInput: (outputId: number) => Promise<void>,\n  logger?: WalletLoggerInterface,\n  telemetry?: Telemetry\n): Promise<GenerateChangeSdkResult> {\n  if (telemetry?.enabled !== true) {\n    return await generateChangeSdkCore(params, allocateChangeInput, releaseChangeInput, logger)\n  }\n\n  return await telemetry.withSpan(\n    'wallet.storage.generate_change',\n    {\n      component: 'wallet-storage',\n      carrier: params,\n      attributes: {\n        'change.fixed_input_count': params.fixedInputs.length,\n        'change.fixed_output_count': params.fixedOutputs.length,\n        'change.target_net_count': params.targetNetCount ?? 0\n      }\n    },\n    async span => {\n      const allocate = async (\n        targetSatoshis: number,\n        exactSatoshis?: number\n      ): Promise<GenerateChangeSdkChangeInput | undefined> =>\n        await traceGenerateChangeStep(\n          telemetry,\n          span,\n          'wallet.storage.generate_change.allocate',\n          async () => await allocateChangeInput(targetSatoshis, exactSatoshis)\n        )\n      const release = async (outputId: number): Promise<void> => {\n        await traceGenerateChangeStep(\n          telemetry,\n          span,\n          'wallet.storage.generate_change.release',\n          async () => await releaseChangeInput(outputId)\n        )\n      }\n      const result = await generateChangeSdkCore(params, allocate, release, logger)\n      span.end({\n        attributes: {\n          'change.allocated_input_count': result.allocatedChangeInputs.length,\n          'change.output_count': result.changeOutputs.length,\n          'change.transaction_size_bytes': result.size,\n          'change.fee_satoshis': result.fee\n        }\n      })\n      return result\n    }\n  )\n}\n\nasync function traceGenerateChangeStep<T>(\n  telemetry: Telemetry,\n  parent: TelemetrySpan,\n  name: string,\n  callback: () => Promise<T>\n): Promise<T> {\n  return await telemetry.withSpan(\n    name,\n    {\n      component: 'wallet-storage',\n      parent: parent.context\n    },\n    callback\n  )\n}\n\nasync function generateChangeSdkCore(\n  params: GenerateChangeSdkParams,\n  allocateChangeInput: (\n    targetSatoshis: number,\n    exactSatoshis?: number\n  ) => Promise<GenerateChangeSdkChangeInput | undefined>,\n  releaseChangeInput: (outputId: number) => Promise<void>,\n  logger?: WalletLoggerInterface\n): Promise<GenerateChangeSdkResult> {\n  if (params.noLogging === false) logGenerateChangeSdkParams(params)\n\n  const r: GenerateChangeSdkResult = {\n    allocatedChangeInputs: [],\n    changeOutputs: [],\n    size: 0,\n    fee: 0,\n    satsPerKb: 0\n  }\n\n  // eslint-disable-next-line no-useless-catch\n  try {\n    const vgcpr = validateGenerateChangeSdkParams(params)\n\n    const satsPerKb = params.feeModel.value || 0\n\n    /**\n     * Minimum satoshi value for a change output to be economically viable.\n     *\n     * A change output is worthless if the fee required to spend it in a\n     * future transaction equals or exceeds its value.  We compute the size\n     * of the smallest possible spend transaction (1 change input, 1 change\n     * output) and require each change output to be worth at least 2× that\n     * fee so the output still has meaningful value after it is spent.\n     *\n     * The absolute floor of 1 prevents nonsensical behaviour at fee rate 0.\n     */\n    const minSpendTxSize = transactionSize([params.changeUnlockingScriptLength], [params.changeLockingScriptLength])\n    const dustFloor = Math.max(1, Math.ceil((minSpendTxSize / 1000) * satsPerKb) * 2)\n\n    /**\n     * Effective cap on change outputs created in this transaction.\n     * Applies the per-transaction limit so that the UTXO pool grows\n     * gradually rather than all at once.\n     */\n    const maxChangeOutputs = params.maxChangeOutputs ?? maxChangeOutputsPerTransaction\n\n    const randomVals = [...(params.randomVals || [])]\n    const nextRandomVal = (): number => {\n      let val = 0\n      if (!randomVals || randomVals.length === 0) {\n        const bytes = Random(4)\n        val = (((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]) >>> 0) / 0x100000000\n      } else {\n        val = randomVals.shift() || 0\n        randomVals.push(val)\n      }\n      return val\n    }\n\n    /**\n     * @returns a random integer betweenn min and max, inclussive.\n     */\n    const rand = (min: number, max: number): number => {\n      if (max < min) throw new WERR_INVALID_PARAMETER('max', `less than min (${min}). max is (${max})`)\n      return Math.floor(nextRandomVal() * (max - min + 1) + min)\n    }\n\n    const fixedInputs = params.fixedInputs\n    const fixedOutputs = params.fixedOutputs\n    const fixedFunding = fixedInputs.reduce((sum, input) => sum + input.satoshis, 0)\n    let fixedSpending = fixedOutputs.reduce((sum, output) => sum + output.satoshis, 0)\n    const fixedInputSize = fixedInputs.reduce(\n      (sum, input) => sum + transactionInputSize(input.unlockingScriptLength),\n      0\n    )\n    const fixedOutputSize = fixedOutputs.reduce(\n      (sum, output) => sum + transactionOutputSize(output.lockingScriptLength),\n      0\n    )\n    const changeInputSize = transactionInputSize(params.changeUnlockingScriptLength)\n    const changeOutputSize = transactionOutputSize(params.changeLockingScriptLength)\n    let allocatedFunding = 0\n\n    /**\n     * @returns sum of transaction fixedInputs satoshis and fundingInputs satoshis\n     */\n    const funding = (): number => {\n      return fixedFunding + allocatedFunding\n    }\n\n    /**\n     * @returns sum of transaction fixedOutputs satoshis\n     */\n    const spending = (): number => {\n      return fixedSpending\n    }\n\n    /**\n     * @returns sum of transaction changeOutputs satoshis\n     */\n    const change = (): number => {\n      return r.changeOutputs.reduce((a, e) => a + e.satoshis, 0)\n    }\n\n    const fee = (): number => funding() - spending() - change()\n\n    const size = (addedChangeInputs?: number, addedChangeOutputs?: number): number => {\n      const inputCount = fixedInputs.length + r.allocatedChangeInputs.length + (addedChangeInputs || 0)\n      const outputCount = fixedOutputs.length + r.changeOutputs.length + (addedChangeOutputs || 0)\n      return 4 +\n        varUintSize(inputCount) +\n        fixedInputSize +\n        (r.allocatedChangeInputs.length + (addedChangeInputs || 0)) * changeInputSize +\n        varUintSize(outputCount) +\n        fixedOutputSize +\n        (r.changeOutputs.length + (addedChangeOutputs || 0)) * changeOutputSize +\n        4\n    }\n\n    /**\n     * @returns the target fee required for the transaction as currently configured under feeModel.\n     */\n    const feeTarget = (addedChangeInputs?: number, addedChangeOutputs?: number): number => {\n      const fee = Math.ceil((size(addedChangeInputs, addedChangeOutputs) / 1000) * satsPerKb)\n      return fee\n    }\n\n    /**\n     * @returns the current excess fee for the transaction as currently configured.\n     *\n     * This is funding() - spending() - change() - feeTarget()\n     *\n     * The goal is an excess fee of zero.\n     *\n     * A positive value is okay if the cost of an additional change output is greater.\n     *\n     * A negative value means the transaction is under funded, or over spends, and may be rejected.\n     */\n    const feeExcess = (addedChangeInputs?: number, addedChangeOutputs?: number): number => {\n      const fe = funding() - spending() - change() - feeTarget(addedChangeInputs, addedChangeOutputs)\n      if (!addedChangeInputs && !addedChangeOutputs) feeExcessNow = fe\n      return fe\n    }\n\n    // The most recent feeExcess()\n    let feeExcessNow = 0\n    feeExcess()\n\n    const hasTargetNetCount = params.targetNetCount !== undefined\n    // Cap targetNetCount to maxChangeOutputs so the UTXO pool grows gradually\n    // rather than trying to reach numberOfDesiredUTXOs in a single transaction.\n    const targetNetCount = Math.min(params.targetNetCount || 0, maxChangeOutputs)\n\n    // current net change in count of change outputs\n    const netChangeCount = (): number => {\n      return r.changeOutputs.length - r.allocatedChangeInputs.length\n    }\n\n    const addOutputToBalanceNewInput = (): boolean => {\n      if (!hasTargetNetCount) return false\n      // Also respect the absolute cap on change output count.\n      if (r.changeOutputs.length >= maxChangeOutputs) return false\n      return netChangeCount() - 1 < targetNetCount\n    }\n\n    const releaseAllocatedChangeInputs = async (): Promise<void> => {\n      while (r.allocatedChangeInputs.length > 0) {\n        const i = r.allocatedChangeInputs.pop()\n        if (i != null) {\n          allocatedFunding -= i.satoshis\n          await releaseChangeInput(i.outputId)\n        }\n      }\n      feeExcessNow = feeExcess()\n    }\n\n    const addDesiredChangeOutputs = (): void => {\n      // They may be removed if it turns out we can't fund them. Respect the\n      // per-transaction cap and ensure each output meets the dust floor.\n      while (\n        r.changeOutputs.length < maxChangeOutputs &&\n        ((hasTargetNetCount && targetNetCount > netChangeCount()) || (r.changeOutputs.length === 0 && feeExcess() > 0))\n      ) {\n        const satoshis =\n          r.changeOutputs.length === 0\n            ? Math.max(dustFloor, params.changeFirstSatoshis)\n            : Math.max(dustFloor, params.changeInitialSatoshis)\n        r.changeOutputs.push({\n          satoshis,\n          lockingScriptLength: params.changeLockingScriptLength\n        })\n      }\n    }\n    addDesiredChangeOutputs()\n\n    const fundTransaction = async (): Promise<void> => {\n      let removingOutputs = false\n\n      const maybeAddChangeOutput = (ao: number): void => {\n        if (removingOutputs || feeExcess() <= 0) return\n        const canAdd = (ao === 1 || r.changeOutputs.length === 0) && r.changeOutputs.length < maxChangeOutputs\n        if (!canAdd) return\n        const cap = r.changeOutputs.length === 0 ? params.changeFirstSatoshis : params.changeInitialSatoshis\n        const satoshis = Math.min(feeExcess(), Math.max(dustFloor, cap))\n        if (satoshis >= dustFloor) {\n          r.changeOutputs.push({ satoshis, lockingScriptLength: params.changeLockingScriptLength })\n        }\n      }\n\n      const attemptToFundTransaction = async (): Promise<boolean> => {\n        if (feeExcess() > 0) return true\n\n        let exactSatoshis: number | undefined\n        if (!hasTargetNetCount && r.changeOutputs.length === 0) {\n          exactSatoshis = -feeExcess(1)\n        }\n        const ao = addOutputToBalanceNewInput() ? 1 : 0\n        // When no change output exists yet, include the dust floor in the target\n        // so the allocated input leaves enough excess for a viable change output.\n        const changeBuffer = r.changeOutputs.length === 0 && ao === 0 ? dustFloor + feeTarget(0, 1) - feeTarget() : 0\n        const targetSatoshis = -feeExcess(1, ao) + (ao === 1 ? 2 * params.changeInitialSatoshis : 0) + changeBuffer\n\n        const allocatedChangeInput = await allocateChangeInput(targetSatoshis, exactSatoshis)\n\n        if (allocatedChangeInput == null) {\n          // Unable to add another funding change input\n          return false\n        }\n\n        r.allocatedChangeInputs.push(allocatedChangeInput)\n        allocatedFunding += allocatedChangeInput.satoshis\n        maybeAddChangeOutput(ao)\n        return true\n      }\n\n      for (;;) {\n        // This is the starvation loop, drops change outputs one at a time if unable to fund them...\n        await releaseAllocatedChangeInputs()\n\n        while (feeExcess() < 0) {\n          // This is the funding loop, add one change input at a time...\n          const ok = await attemptToFundTransaction()\n          if (!ok) break\n        }\n\n        // Done if blanced overbalanced or impossible (all funding applied, all change outputs removed).\n        if (feeExcess() >= 0 || r.changeOutputs.length === 0) break\n\n        removingOutputs = true\n        while (r.changeOutputs.length > 0 && feeExcess() < 0) {\n          r.changeOutputs.pop()\n        }\n        if (feeExcess() < 0)\n        // Not enough available funding even if no change outputs\n        {\n          break\n        }\n        // At this point we have a funded transaction, but there may be change outputs that are each costing as change input,\n        // resulting in pointless churn of change outputs.\n        // And remove change inputs that funded only a single change output (along with that output)...\n        removeChurnPairs(r.allocatedChangeInputs, r.changeOutputs)\n        allocatedFunding = r.allocatedChangeInputs.reduce((sum, input) => sum + input.satoshis, 0)\n        // and try again...\n      }\n    }\n\n    /**\n     * Add funding to achieve a non-negative feeExcess value, if necessary.\n     */\n    await fundTransaction()\n\n    if (feeExcess() < 0 && vgcpr.hasMaxPossibleOutput !== undefined) {\n      // Reduce the fixed output with satoshis of maxPossibleSatoshis to what will just fund the transaction...\n      if (fixedOutputs[vgcpr.hasMaxPossibleOutput].satoshis !== maxPossibleSatoshis) throw new WERR_INTERNAL()\n      const adjustment = feeExcess()\n      fixedOutputs[vgcpr.hasMaxPossibleOutput].satoshis += adjustment\n      fixedSpending += adjustment\n      r.maxPossibleSatoshisAdjustment = {\n        fixedOutputIndex: vgcpr.hasMaxPossibleOutput,\n        satoshis: fixedOutputs[vgcpr.hasMaxPossibleOutput].satoshis\n      }\n    }\n\n    /**\n     * Trigger an account funding event if we don't have enough to cover this transaction.\n     */\n    if (feeExcess() < 0) {\n      const werr = new WERR_INSUFFICIENT_FUNDS(spending() + feeTarget(), -feeExcessNow)\n      logger?.error(`throwing WERR_INSUFFICIENT_FUNDS moreSatoshisNeeded ${werr.moreSatoshisNeeded}`)\n      await releaseAllocatedChangeInputs()\n      throw werr\n    }\n\n    /**\n     * If needed, seek funding to avoid overspending on fees without a change output to recapture it.\n     */\n    if (r.changeOutputs.length === 0 && feeExcessNow > 0) {\n      const minimumChange = Math.max(dustFloor, params.changeFirstSatoshis)\n      const totalSatoshisNeeded = spending() + feeTarget(0, 1) + minimumChange\n      const moreSatoshisNeeded = Math.max(1, totalSatoshisNeeded - funding())\n      await releaseAllocatedChangeInputs()\n      throw new WERR_INSUFFICIENT_FUNDS(totalSatoshisNeeded, moreSatoshisNeeded)\n    }\n\n    /**\n     * Distribute the excess fees across the changeOutputs added.\n     */\n    feeExcessNow = distributeExcessFees(r.changeOutputs, params.changeInitialSatoshis, feeExcessNow, rand)\n\n    /**\n     * Remove any change outputs that ended up below the dust floor after distribution.\n     * Consolidates removed satoshis into the largest remaining output.\n     */\n    removeDustOutputs(r.changeOutputs, dustFloor)\n\n    r.size = size()\n    r.fee = fee()\n    r.satsPerKb = satsPerKb\n\n    const { ok, log } = validateGenerateChangeSdkResult(params, r)\n    if (!ok) {\n      throw new WERR_INTERNAL(`generateChangeSdk error: ${log}`)\n    }\n\n    return r\n  } catch (error_: unknown) {\n    const e = WalletError.fromUnknown(error_)\n    if (e.code === 'WERR_INSUFFICIENT_FUNDS') throw error_\n\n    throw error_\n  }\n}\n\nexport function validateGenerateChangeSdkResult(\n  params: GenerateChangeSdkParams,\n  r: GenerateChangeSdkResult\n): { ok: boolean; log: string } {\n  let ok = true\n  let log = ''\n  const sumIn =\n    params.fixedInputs.reduce((a, e) => a + e.satoshis, 0) + r.allocatedChangeInputs.reduce((a, e) => a + e.satoshis, 0)\n  const sumOut =\n    params.fixedOutputs.reduce((a, e) => a + e.satoshis, 0) + r.changeOutputs.reduce((a, e) => a + e.satoshis, 0)\n  if (r.fee && Number.isInteger(r.fee) && r.fee < 0) {\n    log += `basic fee error ${r.fee};`\n    ok = false\n  }\n  const feePaid = sumIn - sumOut\n  if (feePaid !== r.fee) {\n    log += `exact fee error ${feePaid} !== ${r.fee};`\n    ok = false\n  }\n  const feeRequired = Math.ceil(((r.size || 0) / 1000) * (r.satsPerKb || 0))\n  if (feeRequired !== r.fee) {\n    log += `required fee error ${feeRequired} !== ${r.fee};`\n    ok = false\n  }\n\n  return { ok, log }\n}\n\nfunction logGenerateChangeSdkParams(params: GenerateChangeSdkParams) {\n  console.log('generateChangeSdk parameter summary', {\n    fixedInputCount: params.fixedInputs.length,\n    fixedOutputCount: params.fixedOutputs.length,\n    targetNetCount: params.targetNetCount,\n    changeInitialSatoshis: params.changeInitialSatoshis,\n    changeFirstSatoshis: params.changeFirstSatoshis,\n    randomValsCount: params.randomVals?.length ?? 0\n  })\n}\n\nexport interface GenerateChangeSdkParams {\n  fixedInputs: GenerateChangeSdkInput[]\n  fixedOutputs: GenerateChangeSdkOutput[]\n\n  feeModel: StorageFeeModel\n\n  /**\n   * Target for number of new change outputs added minus number of funding change outputs consumed.\n   * If undefined, only a single change output will be added if excess fees must be recaptured.\n   */\n  targetNetCount?: number\n  /**\n   * Satoshi amount to initialize optional new change outputs.\n   */\n  changeInitialSatoshis: number\n  /**\n   * Lowest amount value to assign to a change output.\n   * Drop the output if unable to satisfy.\n   * default 285\n   */\n  changeFirstSatoshis: number\n\n  /**\n   * Fixed change locking script length.\n   *\n   * For P2PKH template, 25 bytes\n   */\n  changeLockingScriptLength: number\n  /**\n   * Fixed change unlocking script length.\n   *\n   * For P2PKH template, 107 bytes\n   */\n  changeUnlockingScriptLength: number\n\n  /**\n   * Maximum number of change outputs to create in this transaction.\n   * Defaults to `maxChangeOutputsPerTransaction` (8).\n   *\n   * Callers may override this to allow more outputs in special cases (e.g.\n   * consolidation transactions) or fewer outputs when a compact transaction\n   * is preferred.\n   */\n  maxChangeOutputs?: number\n\n  randomVals?: number[]\n  noLogging?: boolean\n  log?: string\n}\n\nexport interface GenerateChangeSdkInput {\n  satoshis: number\n  unlockingScriptLength: number\n}\n\nexport interface GenerateChangeSdkOutput {\n  satoshis: number\n  lockingScriptLength: number\n}\n\nexport interface GenerateChangeSdkChangeInput {\n  outputId: number\n  satoshis: number\n}\n\nexport interface GenerateChangeSdkChangeOutput {\n  satoshis: number\n  lockingScriptLength: number\n}\n\nexport interface ValidateGenerateChangeSdkParamsResult {\n  hasMaxPossibleOutput?: number\n}\n\nexport function validateGenerateChangeSdkParams(\n  params: GenerateChangeSdkParams\n): ValidateGenerateChangeSdkParamsResult {\n  if (!Array.isArray(params.fixedInputs)) throw new WERR_INVALID_PARAMETER('fixedInputs', 'an array of objects')\n\n  const r: ValidateGenerateChangeSdkParamsResult = {}\n\n  params.fixedInputs.forEach((x, i) => {\n    Validation.validateSatoshis(x.satoshis, `fixedInputs[${i}].satoshis`)\n    Validation.validateInteger(x.unlockingScriptLength, `fixedInputs[${i}].unlockingScriptLength`, undefined, 0)\n  })\n\n  if (!Array.isArray(params.fixedOutputs)) throw new WERR_INVALID_PARAMETER('fixedOutputs', 'an array of objects')\n  params.fixedOutputs.forEach((x, i) => {\n    Validation.validateSatoshis(x.satoshis, `fixedOutputs[${i}].satoshis`)\n    Validation.validateInteger(x.lockingScriptLength, `fixedOutputs[${i}].lockingScriptLength`, undefined, 0)\n    if (x.satoshis === maxPossibleSatoshis) {\n      if (r.hasMaxPossibleOutput !== undefined) {\n        throw new WERR_INVALID_PARAMETER(\n          `fixedOutputs[${i}].satoshis`,\n          \"valid satoshis amount. Only one 'maxPossibleSatoshis' output allowed.\"\n        )\n      }\n      r.hasMaxPossibleOutput = i\n    }\n  })\n\n  params.feeModel = validateStorageFeeModel(params.feeModel)\n  if (params.feeModel.model !== 'sat/kb') throw new WERR_INVALID_PARAMETER('feeModel.model', \"'sat/kb'\")\n\n  Validation.validateOptionalInteger(params.targetNetCount, 'targetNetCount')\n\n  Validation.validateSatoshis(params.changeFirstSatoshis, 'changeFirstSatoshis', 1)\n  Validation.validateSatoshis(params.changeInitialSatoshis, 'changeInitialSatoshis', 1)\n\n  Validation.validateInteger(params.changeLockingScriptLength, 'changeLockingScriptLength')\n  Validation.validateInteger(params.changeUnlockingScriptLength, 'changeUnlockingScriptLength')\n\n  return r\n}\n\nexport interface GenerateChangeSdkStorageChange extends GenerateChangeSdkChangeInput {\n  spendable: boolean\n}\n\nexport function generateChangeSdkMakeStorage(availableChange: GenerateChangeSdkChangeInput[]): {\n  allocateChangeInput: (\n    targetSatoshis: number,\n    exactSatoshis?: number\n  ) => Promise<GenerateChangeSdkChangeInput | undefined>\n  releaseChangeInput: (outputId: number) => Promise<void>\n  getLog: () => string\n} {\n  const change: GenerateChangeSdkStorageChange[] = availableChange.map(c => ({\n    ...c,\n    spendable: true\n  }))\n  change.sort((a, b) => {\n    if (a.satoshis < b.satoshis) return -1\n    if (a.satoshis > b.satoshis) return 1\n    if (a.outputId < b.outputId) return -1\n    if (a.outputId > b.outputId) return 1\n    return 0\n  })\n\n  let log = ''\n  for (const c of change) log += `change ${c.satoshis} ${c.outputId}\\n`\n\n  const getLog = (): string => log\n\n  const allocate = (c: GenerateChangeSdkStorageChange) => {\n    log += ` -> ${c.satoshis} sats, id ${c.outputId}\\n`\n    c.spendable = false\n    return c\n  }\n\n  const allocateChangeInput = async (\n    targetSatoshis: number,\n    exactSatoshis?: number\n  ): Promise<GenerateChangeSdkChangeInput | undefined> => {\n    log += `allocate target ${targetSatoshis} exact ${exactSatoshis}`\n\n    if (exactSatoshis !== undefined) {\n      const exact = change.find(c => c.spendable && c.satoshis === exactSatoshis)\n      if (exact != null) return allocate(exact)\n    }\n    const over = change.find(c => c.spendable && c.satoshis >= targetSatoshis)\n    if (over != null) return allocate(over)\n    let under: GenerateChangeSdkStorageChange | undefined\n    for (let i = change.length - 1; i >= 0; i--) {\n      if (change[i].spendable) {\n        under = change[i]\n        break\n      }\n    }\n    if (under != null) return allocate(under)\n    log += '\\n'\n    return undefined\n  }\n\n  const releaseChangeInput = async (outputId: number): Promise<void> => {\n    log += `release id ${outputId}\\n`\n    const c = change.find(x => x.outputId === outputId)\n    if (c == null) throw new WERR_INTERNAL(`unknown outputId ${outputId}`)\n    if (c.spendable) throw new WERR_INTERNAL(`release of spendable outputId ${outputId}`)\n    c.spendable = true\n  }\n\n  return { allocateChangeInput, releaseChangeInput, getLog }\n}\n","import { AcquireCertificateResult, Validation } from '@bsv/sdk'\nimport { Wallet } from '../../Wallet'\nimport { AuthId } from '../../sdk/WalletStorage.interfaces'\nimport { TableCertificateX } from '../../storage/schema/tables/TableCertificate'\n\nexport async function acquireDirectCertificate (\n  wallet: Wallet,\n  auth: AuthId,\n  vargs: Validation.ValidAcquireDirectCertificateArgs\n): Promise<AcquireCertificateResult> {\n  const now = new Date()\n  const newCert: TableCertificateX = {\n    certificateId: 0, // replaced by storage insert\n    created_at: now,\n    updated_at: now,\n    userId: auth.userId!,\n    type: vargs.type,\n    subject: vargs.subject,\n    verifier: vargs.keyringRevealer === 'certifier' ? vargs.certifier : vargs.keyringRevealer,\n    serialNumber: vargs.serialNumber,\n    certifier: vargs.certifier,\n    revocationOutpoint: vargs.revocationOutpoint,\n    signature: vargs.signature,\n    fields: [],\n    isDeleted: false\n  }\n  for (const [name, value] of Object.entries(vargs.fields)) {\n    newCert.fields?.push({\n      certificateId: 0, // replaced by storage insert\n      created_at: now,\n      updated_at: now,\n      userId: auth.userId!,\n      fieldName: name,\n      fieldValue: value,\n      masterKey: vargs.keyringForSubject[name] || ''\n    })\n  }\n\n  await wallet.storage.insertCertificate(newCert)\n\n  const r: AcquireCertificateResult = {\n    type: vargs.type,\n    subject: vargs.subject,\n    serialNumber: vargs.serialNumber,\n    certifier: vargs.certifier,\n    revocationOutpoint: vargs.revocationOutpoint,\n    signature: vargs.signature,\n    fields: vargs.fields\n  }\n\n  return r\n}\n","import { MasterCertificate, ProveCertificateResult, Validation } from '@bsv/sdk'\nimport { Wallet } from '../../Wallet'\nimport { WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { AuthId } from '../../sdk/WalletStorage.interfaces'\n\nexport async function proveCertificate (\n  wallet: Wallet,\n  auth: AuthId,\n  vargs: Validation.ValidProveCertificateArgs\n): Promise<ProveCertificateResult> {\n  const lcargs: Validation.ValidListCertificatesArgs = {\n    partial: {\n      type: vargs.type,\n      serialNumber: vargs.serialNumber,\n      certifier: vargs.certifier,\n      subject: vargs.subject,\n      revocationOutpoint: vargs.revocationOutpoint,\n      signature: vargs.signature\n    },\n    certifiers: [],\n    types: [],\n    limit: 2,\n    offset: 0,\n    privileged: false\n  }\n\n  const lcr = await wallet.storage.listCertificates(lcargs)\n  if (lcr.certificates.length != 1) throw new WERR_INVALID_PARAMETER('args', 'a unique certificate match')\n  const storageCert = lcr.certificates[0]\n  const keyringForVerifier = await MasterCertificate.createKeyringForVerifier(\n    wallet,\n    storageCert.certifier,\n    vargs.verifier,\n    storageCert.fields,\n    vargs.fieldsToReveal,\n    storageCert.keyring!,\n    storageCert.serialNumber,\n    vargs.privileged,\n    vargs.privilegedReason\n  )\n\n  return { keyringForVerifier }\n}\n","import { Beef, Script, Transaction, Validation } from '@bsv/sdk'\nimport { Wallet, PendingStorageInput } from '../../Wallet'\nimport {\n  StorageCreateActionResult,\n  StorageCreateTransactionSdkInput,\n  StorageCreateTransactionSdkOutput\n} from '../../sdk/WalletStorage.interfaces'\nimport { WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { asBsvSdkScript, verifyTruthy } from '../../utility/utilityHelpers'\nimport { KeyPair } from '../../sdk/types'\nimport { ScriptTemplateBRC29 } from '../../utility/ScriptTemplateBRC29'\nimport { maxPossibleSatoshis } from '../../storage/methods/generateChange'\n\nexport function buildSignableTransaction(\n  dctr: StorageCreateActionResult,\n  args: Validation.ValidCreateActionArgs,\n  wallet: Wallet\n): {\n  tx: Transaction\n  amount: number\n  pdi: PendingStorageInput[]\n  log: string\n} {\n  const changeKeys = wallet.getClientChangeKeyPair()\n\n  const inputBeef = args.inputBEEF != null ? Beef.fromBinary(args.inputBEEF) : undefined\n\n  const { inputs: storageInputs, outputs: storageOutputs } = dctr\n\n  // SECURITY (GHSA-36f9-7rg5-cpf8): The locking scripts used to build and sign\n  // the transaction are taken from the storage response. When storage is remote\n  // (StorageClient, the default configuration), a malicious or compromised\n  // storage operator could return a different recipient script than the caller\n  // requested; it would be signed and broadcast while the calling app/UI still\n  // shows the originally requested recipient. Verify that every caller-specified\n  // output is echoed back by storage unchanged before anything is signed.\n  verifyRequestedOutputsUnchanged(storageOutputs, args)\n\n  // SECURITY (GHSA-36f9-7rg5-cpf8): verifyRequestedOutputsUnchanged only protects\n  // the caller's own outputs. Storage could instead inject an ADDITIONAL output\n  // paying an attacker (funded by reducing change), which the loop below signs\n  // verbatim. Every output beyond the caller's must be either a change output\n  // (script re-derived client-side, so it can only pay the client) or the single\n  // bounded commission output. Anything else is rejected before signing.\n  verifyUnrequestedOutputsAreChangeOrCommission(storageOutputs, args)\n\n  const tx = new Transaction(args.version, [], [], args.lockTime)\n  addPlannedOutputs(tx, storageOutputs, dctr, args, changeKeys, wallet)\n\n  const pendingStorageInputs: PendingStorageInput[] = []\n  const totalChangeInputs = addPlannedInputs(\n    tx,\n    storageInputs,\n    args,\n    inputBeef,\n    pendingStorageInputs\n  )\n\n  // The amount is the total of non-foreign inputs minus change outputs\n  // Note that the amount can be negative when we are redeeming more inputs than we are spending\n  const totalChangeOutputs = storageOutputs\n    .filter(x => x.purpose === 'change')\n    .reduce((acc, el) => acc + el.satoshis, 0)\n  const amount = totalChangeInputs - totalChangeOutputs\n\n  return {\n    tx,\n    amount,\n    pdi: pendingStorageInputs,\n    log: ''\n  }\n}\n\nfunction outputIndexByVout(storageOutputs: StorageCreateTransactionSdkOutput[]): number[] {\n  return Array.from({ length: storageOutputs.length }, (_, vout) => {\n    const index = storageOutputs.findIndex(output => output.vout === vout)\n    if (index < 0) {\n      throw new WERR_INVALID_PARAMETER('output.vout', `sequential. ${vout} is missing`)\n    }\n    return index\n  })\n}\n\nfunction addPlannedOutputs(\n  tx: Transaction,\n  storageOutputs: StorageCreateTransactionSdkOutput[],\n  dctr: StorageCreateActionResult,\n  args: Validation.ValidCreateActionArgs,\n  changeKeys: KeyPair,\n  wallet: Wallet\n): void {\n  // Storage preserves request/commission/change array order while `vout` may\n  // randomize the final transaction order.\n  for (const [vout, index] of outputIndexByVout(storageOutputs).entries()) {\n    const output = storageOutputs[index]\n    if (vout !== output.vout) {\n      throw new WERR_INVALID_PARAMETER(\n        'output.vout',\n        `equal to array index. ${output.vout} !== ${vout}`\n      )\n    }\n    const change = output.providedBy === 'storage' && output.purpose === 'change'\n    tx.addOutput({\n      satoshis: output.satoshis,\n      lockingScript: change\n        ? makeChangeLock(output, dctr, args, changeKeys, wallet)\n        : asBsvSdkScript(output.lockingScript),\n      change\n    })\n  }\n  if (storageOutputs.length === 0) {\n    tx.addOutput({\n      satoshis: 0,\n      lockingScript: Script.fromASM('OP_FALSE OP_RETURN 42'),\n      change: false\n    })\n  }\n}\n\nfunction addRequestedInput(\n  tx: Transaction,\n  argsInput: Validation.ValidCreateActionInput,\n  args: Validation.ValidCreateActionArgs,\n  inputBeef: Beef | undefined\n): void {\n  const unlockingScript =\n    typeof argsInput.unlockingScript === 'string'\n      ? asBsvSdkScript(argsInput.unlockingScript)\n      : new Script()\n  tx.addInput({\n    sourceTXID: argsInput.outpoint.txid,\n    sourceOutputIndex: argsInput.outpoint.vout,\n    sourceTransaction: args.isSignAction\n      ? inputBeef?.findTxid(argsInput.outpoint.txid)?.tx\n      : undefined,\n    unlockingScript,\n    sequence: argsInput.sequenceNumber\n  })\n}\n\nfunction sourceTransactionForStorageInput(\n  storageInput: StorageCreateTransactionSdkInput\n): Transaction | undefined {\n  if (storageInput.sourceTransaction == null) return undefined\n  return storageInput.sourceTransaction instanceof Uint8Array\n    ? Transaction.fromBinaryView(storageInput.sourceTransaction)\n    : Transaction.fromBinary(storageInput.sourceTransaction)\n}\n\nfunction addStorageInput(\n  tx: Transaction,\n  storageInput: StorageCreateTransactionSdkInput,\n  pendingStorageInputs: PendingStorageInput[]\n): number {\n  if (storageInput.type !== 'P2PKH') {\n    throw new WERR_INVALID_PARAMETER(\n      'type',\n      `vin ${storageInput.vin}, \"${storageInput.type}\" is not a supported unlocking script type.`\n    )\n  }\n  pendingStorageInputs.push({\n    vin: tx.inputs.length,\n    derivationPrefix: verifyTruthy(storageInput.derivationPrefix),\n    derivationSuffix: verifyTruthy(storageInput.derivationSuffix),\n    unlockerPubKey: storageInput.senderIdentityKey,\n    sourceSatoshis: storageInput.sourceSatoshis,\n    lockingScript: storageInput.sourceLockingScript\n  })\n  tx.addInput({\n    sourceTXID: storageInput.sourceTxid,\n    sourceOutputIndex: storageInput.sourceVout,\n    sourceTransaction: sourceTransactionForStorageInput(storageInput),\n    unlockingScript: new Script(),\n    sequence: 0xffffffff\n  })\n  return Validation.validateSatoshis(\n    storageInput.sourceSatoshis,\n    'storageInput.sourceSatoshis'\n  )\n}\n\nfunction addPlannedInputs(\n  tx: Transaction,\n  storageInputs: StorageCreateTransactionSdkInput[],\n  args: Validation.ValidCreateActionArgs,\n  inputBeef: Beef | undefined,\n  pendingStorageInputs: PendingStorageInput[]\n): number {\n  const inputs = storageInputs\n    .map(storageInput => ({\n      storageInput,\n      argsInput:\n        storageInput.vin < args.inputs.length\n          ? args.inputs[storageInput.vin]\n          : undefined\n    }))\n    .sort((left, right) => left.storageInput.vin - right.storageInput.vin)\n\n  let totalChangeInputs = 0\n  for (const { storageInput, argsInput } of inputs) {\n    if (argsInput != null) {\n      addRequestedInput(tx, argsInput, args, inputBeef)\n      continue\n    }\n    totalChangeInputs += addStorageInput(tx, storageInput, pendingStorageInputs)\n  }\n  return totalChangeInputs\n}\n\n/**\n * Verify that the outputs returned by storage for caller-specified outputs match\n * exactly what the caller requested in `args.outputs`.\n *\n * The storage response (`StorageCreateActionResult.outputs`) is ordered, by\n * contract, as: the caller's `args.outputs` in their original order, followed by\n * the optional commission output, followed by storage-provided change outputs.\n * Only the `vout` field is randomized when `randomizeOutputs` is set; the array\n * order is stable. Therefore array index `i` (for `i < args.outputs.length`)\n * corresponds to `args.outputs[i]`.\n *\n * Because the locking script that is ultimately signed is taken from the storage\n * response, an untrusted storage provider must not be allowed to alter the\n * recipient script (or amount) of a caller-specified output. Any mismatch is a\n * hard error. (GHSA-36f9-7rg5-cpf8)\n *\n * @throws WERR_INVALID_PARAMETER if storage omitted, reclassified, or modified\n *   any caller-specified output.\n */\nexport function verifyRequestedOutputsUnchanged(\n  storageOutputs: StorageCreateTransactionSdkOutput[],\n  args: Validation.ValidCreateActionArgs\n): void {\n  for (let i = 0; i < args.outputs.length; i++) {\n    const requested = args.outputs[i]\n    const provided = storageOutputs[i]\n\n    if (provided == null) {\n      throw new WERR_INVALID_PARAMETER(\n        'storage outputs',\n        `present for every requested output. Storage did not return an output for requested output index ${i}.`\n      )\n    }\n\n    // A caller-specified output must never be reclassified by storage as change\n    // or as storage-provided; doing so would route it through makeChangeLock and\n    // bypass the script comparison below.\n    if (provided.purpose === 'change' || provided.providedBy === 'storage') {\n      throw new WERR_INVALID_PARAMETER(\n        'output.providedBy',\n        `consistent with the request. Storage reclassified requested output ${i} as providedBy='${provided.providedBy}' purpose='${provided.purpose ?? ''}'.`\n      )\n    }\n\n    const requestedScript = (requested.lockingScript ?? '').toLowerCase()\n    const providedScript = (typeof provided.lockingScript === 'string' ? provided.lockingScript : '').toLowerCase()\n    if (requestedScript.length === 0 || requestedScript !== providedScript) {\n      throw new WERR_INVALID_PARAMETER(\n        'output.lockingScript',\n        `equal to the caller-requested locking script. Storage returned a different locking script for output index ${i}; the recipient may have been substituted.`\n      )\n    }\n\n    if (requested.satoshis !== maxPossibleSatoshis && provided.satoshis !== requested.satoshis) {\n      throw new WERR_INVALID_PARAMETER(\n        'output.satoshis',\n        `equal to the caller-requested satoshis. Storage returned ${provided.satoshis} for output index ${i}, caller requested ${requested.satoshis}.`\n      )\n    }\n  }\n}\n\n/**\n * Default ceiling for a storage-provided commission (service-charge) output, in\n * satoshis. The commission is the one output whose locking script is taken\n * verbatim from storage and cannot be re-derived or verified client-side, so a\n * malicious storage operator could point it at an attacker address. Capping it\n * bounds the worst-case loss from that single output; honest commissions are far\n * below this. (GHSA-36f9-7rg5-cpf8)\n */\nexport const MAX_STORAGE_COMMISSION_SATOSHIS = 500000\n\n/**\n * Verify that every storage output beyond the caller's requested outputs is\n * either a change output or the (single, bounded) commission output.\n *\n * The storage response is ordered `[caller outputs][commission?][change...]`;\n * `verifyRequestedOutputsUnchanged` already validates the caller region (indices\n * `< args.outputs.length`). This checks the remainder.\n *\n * Change outputs (`providedBy: 'storage', purpose: 'change'`) are safe at any\n * amount: `buildSignableTransaction` ignores the storage-supplied script and\n * re-derives it client-side (`makeChangeLock` / BRC-29 under the client's own\n * change key), so a change output can only ever pay the client. A change output\n * mislabeled by storage is therefore harmless.\n *\n * The commission output's script, by contrast, is taken verbatim from storage\n * and cannot be verified client-side. A malicious storage could inject an extra\n * output — or relabel one as commission — to redirect funds to an attacker while\n * the caller/UI only sees the requested recipients. To bound that, at most one\n * commission output is allowed and its amount must not exceed `maxCommission`.\n * Any other unrecognized output is rejected outright.\n *\n * @throws WERR_INVALID_PARAMETER if storage returned an unrecognized output, more\n *   than one commission output, or a commission exceeding `maxCommission`.\n */\nexport function verifyUnrequestedOutputsAreChangeOrCommission(\n  storageOutputs: StorageCreateTransactionSdkOutput[],\n  args: Validation.ValidCreateActionArgs,\n  maxCommission: number = MAX_STORAGE_COMMISSION_SATOSHIS\n): void {\n  let commissionCount = 0\n  for (let i = args.outputs.length; i < storageOutputs.length; i++) {\n    const out = storageOutputs[i]\n    const isChange = out.providedBy === 'storage' && out.purpose === 'change'\n    if (isChange) continue\n\n    // Honest storage remaps a service-charge to purpose 'storage-commission';\n    // accept the pre-remap label too so the check is robust across versions.\n    const isCommission =\n      out.providedBy === 'storage' && (out.purpose === 'storage-commission' || out.purpose === 'service-charge')\n    if (isCommission) {\n      commissionCount++\n      if (commissionCount > 1) {\n        throw new WERR_INVALID_PARAMETER(\n          'storage outputs',\n          `at most one commission output. Storage returned an extra commission output at index ${i}.`\n        )\n      }\n      if (out.satoshis > maxCommission) {\n        throw new WERR_INVALID_PARAMETER(\n          'output.satoshis',\n          `a commission no greater than ${maxCommission}. Storage returned a commission of ${out.satoshis} at index ${i}; funds could be redirected to an attacker.`\n        )\n      }\n      continue\n    }\n\n    throw new WERR_INVALID_PARAMETER(\n      'storage outputs',\n      'only change or commission beyond the requested outputs. Storage returned an unrecognized output ' +\n        `(providedBy='${out.providedBy}' purpose='${out.purpose ?? ''}') at index ${i}; funds could be redirected to an attacker.`\n    )\n  }\n}\n\n/**\n * Derive a change output locking script\n */\nexport function makeChangeLock(\n  out: StorageCreateTransactionSdkOutput,\n  dctr: StorageCreateActionResult,\n  args: Validation.ValidCreateActionArgs,\n  changeKeys: KeyPair,\n  wallet: Wallet\n): Script {\n  const derivationPrefix = dctr.derivationPrefix\n  const derivationSuffix = verifyTruthy(out.derivationSuffix)\n  const sabppp = new ScriptTemplateBRC29({\n    derivationPrefix,\n    derivationSuffix,\n    keyDeriver: wallet.keyDeriver\n  })\n  const lockingScript = sabppp.lock(changeKeys.privateKey, changeKeys.publicKey)\n  return lockingScript\n}\n","import {\n  Beef,\n  type BdkVerifierInterface,\n  type DigestVerification,\n  Hash,\n  ScriptEvaluationError,\n  Spend,\n  Transaction,\n  TransactionSignature,\n  type SignatureHashCache,\n  type SpendVerificationContext,\n  type SpendVerifierInterface\n} from '@bsv/sdk'\nimport { WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\n\nexport interface UnlockScriptVerificationResult {\n  verifiedInputs: number\n  skippedInputs: number\n}\n\ntype PendingSpendVerification = readonly [\n  inputIndex: number,\n  resultIndex: number,\n  spend: Spend,\n  context: SpendVerificationContext\n]\n\ntype PendingTransactionVerification = readonly [\n  resultIndex: number,\n  params: Parameters<BdkVerifierInterface['verifyScripts']>[0]\n]\n\ntype PendingDigestVerification = readonly [resultIndex: number, items: DigestVerification[]]\n\ninterface DigestBatchVerifier {\n  isReady?: () => boolean\n  supportsCrypto?: (operation: 'verifyDigestBatch') => boolean\n  verifyDigestBatch: (items: readonly DigestVerification[]) => Promise<boolean[]>\n}\n\nconst postChronicleHeightFallback = 943816\nconst canonicalP2PKHScope = TransactionSignature.SIGHASH_ALL + TransactionSignature.SIGHASH_FORKID\n\nconst javaScriptOnlyVerifier: SpendVerifierInterface = {\n  shouldVerifySpend: () => false,\n  verifySpend: async () => {\n    throw new Error('JavaScript-only verifier unexpectedly selected its backend')\n  }\n}\n\nfunction invalidUnlockingScript(inputIndex: number, detail?: string): WERR_INVALID_PARAMETER {\n  const suffix = detail == null ? '' : ` ${detail}`\n  return new WERR_INVALID_PARAMETER(`inputs[${inputIndex}].unlockScript`, `valid.${suffix}`)\n}\n\nasync function verifyOneSpend(pending: PendingSpendVerification, verifier?: SpendVerifierInterface): Promise<void> {\n  const [inputIndex, , spend, context] = pending\n  try {\n    const valid =\n      verifier === undefined\n        ? spend.validate(context)\n        : await spend.validateWith(verifier, context)\n    if (!valid) throw invalidUnlockingScript(inputIndex)\n  } catch (error: unknown) {\n    if (error instanceof ScriptEvaluationError) {\n      throw invalidUnlockingScript(inputIndex, error.message)\n    }\n    throw error\n  }\n}\n\nasync function verifyPendingSpends(\n  pending: PendingSpendVerification[],\n  verifier?: SpendVerifierInterface\n): Promise<void> {\n  if (verifier?.verifySpendsBatch === undefined) {\n    for (const item of pending) await verifyOneSpend(item, verifier)\n    return\n  }\n\n  const batched: PendingSpendVerification[] = []\n  for (const item of pending) {\n    const selected = verifier.shouldVerifySpend?.(item[2], item[3]) !== false\n    if (selected) batched.push(item)\n    else await verifyOneSpend(item, javaScriptOnlyVerifier)\n  }\n  if (batched.length === 0) return\n\n  let verdicts: boolean[]\n  try {\n    verdicts = await verifier.verifySpendsBatch(batched.map(item => ({ spend: item[2], ...item[3] })))\n  } catch (error: unknown) {\n    if (error instanceof ScriptEvaluationError) {\n      throw invalidUnlockingScript(batched[0][0], error.message)\n    }\n    throw error\n  }\n  if (verdicts.length !== batched.length) {\n    throw new Error('Script verifier returned an invalid batch result count')\n  }\n  verdicts.forEach((valid, index) => {\n    if (!valid) throw invalidUnlockingScript(batched[index][0])\n  })\n}\n\nfunction wholeTransactionVerifier(\n  verifier?: SpendVerifierInterface\n): (SpendVerifierInterface & BdkVerifierInterface) | undefined {\n  const candidate = verifier as (SpendVerifierInterface & Partial<BdkVerifierInterface>) | undefined\n  return typeof candidate?.verifyScripts === 'function'\n    ? candidate as SpendVerifierInterface & BdkVerifierInterface\n    : undefined\n}\n\nfunction digestBatchVerifier(\n  verifier?: SpendVerifierInterface\n): DigestBatchVerifier | undefined {\n  const candidate = verifier as (SpendVerifierInterface & Partial<DigestBatchVerifier>) | undefined\n  if (typeof candidate?.verifyDigestBatch !== 'function') return undefined\n  if (candidate.isReady?.() === false) return undefined\n  if (candidate.supportsCrypto?.('verifyDigestBatch') === false) return undefined\n  return candidate as SpendVerifierInterface & DigestBatchVerifier\n}\n\nfunction equalBytes(left: ArrayLike<number>, right: ArrayLike<number>): boolean {\n  if (left.length !== right.length) return false\n  for (let index = 0; index < left.length; index++) {\n    if (left[index] !== right[index]) return false\n  }\n  return true\n}\n\nfunction isCanonicalP2PKHLock(lock: Uint8Array): boolean {\n  return lock.length === 25 &&\n    lock[0] === 0x76 &&\n    lock[1] === 0xa9 &&\n    lock[2] === 0x14 &&\n    lock[23] === 0x88 &&\n    lock[24] === 0xac\n}\n\nfunction parseCanonicalP2PKHUnlock(\n  unlock: Uint8Array,\n  lock: Uint8Array\n): [checksig: number[], publicKey: Uint8Array, signature: TransactionSignature] | undefined {\n  const signatureLength = unlock[0]\n  if (\n    signatureLength == null ||\n    signatureLength < 9 ||\n    signatureLength > 73 ||\n    unlock.length !== 1 + signatureLength + 1 + 33 ||\n    unlock[1 + signatureLength] !== 33\n  ) return undefined\n  const checksig = Array.from(unlock.subarray(1, 1 + signatureLength))\n  const publicKey = unlock.subarray(1 + signatureLength + 1)\n  if (\n    (publicKey[0] !== 0x02 && publicKey[0] !== 0x03) ||\n    !equalBytes(Hash.hash160(publicKey), lock.subarray(3, 23))\n  ) return undefined\n\n  let signature: TransactionSignature\n  try {\n    signature = TransactionSignature.fromChecksigFormat(checksig)\n  } catch {\n    return undefined\n  }\n  if (\n    signature.scope !== canonicalP2PKHScope ||\n    !signature.hasLowS() ||\n    !equalBytes(signature.toChecksigFormat(), checksig)\n  ) return undefined\n  return [checksig, publicKey, signature]\n}\n\n/**\n * Recognizes only the exact canonical P2PKH shape generated by this wallet.\n * Anything else retains the general-purpose script interpreter/backend path.\n */\nfunction standardP2PKHDigests(tx: Transaction): DigestVerification[] | undefined {\n  const cache: SignatureHashCache = { hashOutputsSingle: new Map() }\n  const items: DigestVerification[] = []\n  for (let inputIndex = 0; inputIndex < tx.inputs.length; inputIndex++) {\n    const input = tx.inputs[inputIndex]\n    const sourceTransaction = input.sourceTransaction\n    const sourceTXID = input.sourceTXID\n    const unlockingScript = input.unlockingScript\n    if (sourceTransaction == null || sourceTXID == null || unlockingScript == null) return undefined\n    const sourceOutput = sourceTransaction.outputs[input.sourceOutputIndex]\n    if (sourceOutput == null) return undefined\n    const lock = sourceOutput.lockingScript.toUint8Array()\n    if (!isCanonicalP2PKHLock(lock)) return undefined\n    const parsed = parseCanonicalP2PKHUnlock(unlockingScript.toUint8Array(), lock)\n    if (parsed == null) return undefined\n    const [checksig, publicKey, signature] = parsed\n\n    const preimage = TransactionSignature.formatBytes({\n      sourceTXID,\n      sourceOutputIndex: input.sourceOutputIndex,\n      sourceSatoshis: sourceOutput.satoshis ?? 0,\n      transactionVersion: tx.version,\n      otherInputs: [],\n      allInputs: tx.inputs,\n      outputs: tx.outputs,\n      inputIndex,\n      subscript: sourceOutput.lockingScript,\n      inputSequence: input.sequence ?? 0xffffffff,\n      lockTime: tx.lockTime,\n      scope: signature.scope,\n      cache\n    })\n    items.push({\n      publicKey,\n      digest: Uint8Array.from(Hash.hash256(preimage)),\n      signature: Uint8Array.from(checksig.slice(0, -1))\n    })\n  }\n  return items\n}\n\nasync function verifyStandardP2PKHDigests(\n  pending: PendingDigestVerification[],\n  verifier: DigestBatchVerifier\n): Promise<Set<number>> {\n  if (pending.length === 0) return new Set()\n  const items = pending.flatMap(entry => entry[1])\n  const verdicts = await verifier.verifyDigestBatch(items)\n  if (verdicts.length !== items.length) {\n    throw new Error('Script verifier returned an invalid digest batch result count')\n  }\n  const verified = new Set<number>()\n  let offset = 0\n  for (const entry of pending) {\n    const end = offset + entry[1].length\n    if (verdicts.slice(offset, end).every(Boolean)) verified.add(entry[0])\n    offset = end\n  }\n  return verified\n}\n\nfunction hydrateTransactionSources(\n  txid: string,\n  transactions: ReadonlyMap<string, Transaction | undefined>\n): Transaction | undefined {\n  const tx = transactions.get(txid)\n  if (tx == null) throw new WERR_INVALID_PARAMETER('txid', `contained in beef, txid ${txid}`)\n  for (let inputIndex = 0; inputIndex < tx.inputs.length; inputIndex++) {\n    const input = tx.inputs[inputIndex]\n    if (input.sourceTXID == null) {\n      throw new WERR_INVALID_PARAMETER(`inputs[${inputIndex}].sourceTXID`, 'valid')\n    }\n    if (input.unlockingScript == null) {\n      throw new WERR_INVALID_PARAMETER(`inputs[${inputIndex}].unlockingScript`, 'valid')\n    }\n    input.sourceTransaction = transactions.get(input.sourceTXID)\n    if (input.sourceTransaction == null) return undefined\n    if (input.sourceTransaction.outputs[input.sourceOutputIndex] == null) {\n      throw new WERR_INVALID_PARAMETER(\n        `inputs[${inputIndex}].sourceOutputIndex`,\n        'reference an output in the source transaction'\n      )\n    }\n  }\n  return tx\n}\n\nfunction transactionIndex(\n  txids: readonly string[],\n  beef: Beef\n): Map<string, Transaction | undefined> {\n  // One public lookup synchronizes nested transaction mutations and rebuilds\n  // BEEF's internal indexes if necessary. Repeating that synchronization for\n  // every input turns a large fragmented action into quadratic work.\n  if (txids.length > 0) beef.findTxid(txids[0])\n  return new Map(beef.txs.map(item => [item.txid, item.tx]))\n}\n\nasync function verifyWholeTransactions(\n  pending: PendingTransactionVerification[],\n  verifier: BdkVerifierInterface\n): Promise<Set<number>> {\n  if (pending.length === 0) return new Set()\n  let verdicts: boolean[]\n  try {\n    verdicts = verifier.verifyScriptsBatch === undefined\n      ? await Promise.all(pending.map(async item => await verifier.verifyScripts(item[1])))\n      : await verifier.verifyScriptsBatch(pending.map(item => item[1]))\n  } catch (error: unknown) {\n    // Whole-transaction backends cannot identify the failing input. Preserve\n    // the historical per-input diagnostic lane for consensus script errors;\n    // integration/runtime failures still propagate unchanged.\n    if (error instanceof ScriptEvaluationError) return new Set()\n    throw error\n  }\n  if (verdicts.length !== pending.length) {\n    throw new Error('Script verifier returned an invalid transaction batch result count')\n  }\n  // A false verdict deliberately falls through to the historical per-input\n  // lane so callers retain the exact failing input in their validation error.\n  return new Set(pending.filter((_, index) => verdicts[index]).map(item => item[0]))\n}\n\nfunction collectTransactionSpends(\n  txid: string,\n  resultIndex: number,\n  transactions: ReadonlyMap<string, Transaction | undefined>,\n  result: UnlockScriptVerificationResult,\n  pending: PendingSpendVerification[]\n): void {\n  const tx = transactions.get(txid)\n  if (tx == null) throw new WERR_INVALID_PARAMETER('txid', `contained in beef, txid ${txid}`)\n  const sigHashCache: SignatureHashCache = { hashOutputsSingle: new Map() }\n  for (let inputIndex = 0; inputIndex < tx.inputs.length; inputIndex++) {\n    const input = tx.inputs[inputIndex]\n    if (input.sourceTXID == null) {\n      throw new WERR_INVALID_PARAMETER(`inputs[${inputIndex}].sourceTXID`, 'valid')\n    }\n    if (input.unlockingScript == null) {\n      throw new WERR_INVALID_PARAMETER(`inputs[${inputIndex}].unlockingScript`, 'valid')\n    }\n    input.sourceTransaction = transactions.get(input.sourceTXID)\n    if (input.sourceTransaction == null) {\n      // knownTxids may intentionally omit a source transaction. Only that\n      // input is skipped; every source that is present is still verified.\n      result.skippedInputs++\n      continue\n    }\n    const sourceOutput = input.sourceTransaction.outputs[input.sourceOutputIndex]\n    if (sourceOutput == null) {\n      throw new WERR_INVALID_PARAMETER(\n        `inputs[${inputIndex}].sourceOutputIndex`,\n        'reference an output in the source transaction'\n      )\n    }\n    const utxoHeight = input.sourceTransaction.merklePath?.blockHeight\n    const context: SpendVerificationContext =\n      utxoHeight === undefined ? { consensus: true } : { consensus: true, utxoHeight }\n    pending.push([\n      inputIndex,\n      resultIndex,\n      new Spend({\n        sourceTXID: input.sourceTXID,\n        sourceOutputIndex: input.sourceOutputIndex,\n        lockingScript: sourceOutput.lockingScript,\n        sourceSatoshis: sourceOutput.satoshis ?? 0,\n        transactionVersion: tx.version,\n        otherInputs: [],\n        allInputs: tx.inputs,\n        unlockingScript: input.unlockingScript,\n        inputSequence: input.sequence ?? 0,\n        inputIndex,\n        outputs: tx.outputs,\n        lockTime: tx.lockTime,\n        sigHashCache\n      }),\n      context\n    ])\n  }\n}\n\nfunction collectAcceleratedTransactions(\n  txids: readonly string[],\n  transactions: ReadonlyMap<string, Transaction | undefined>,\n  digestVerifier: DigestBatchVerifier | undefined,\n  enabled: boolean\n): readonly [Map<number, Transaction>, PendingDigestVerification[]] {\n  const hydrated = new Map<number, Transaction>()\n  const digests: PendingDigestVerification[] = []\n  if (!enabled) return [hydrated, digests]\n  for (let resultIndex = 0; resultIndex < txids.length; resultIndex++) {\n    const tx = hydrateTransactionSources(txids[resultIndex], transactions)\n    if (tx == null) continue\n    hydrated.set(resultIndex, tx)\n    if (digestVerifier === undefined) continue\n    const items = standardP2PKHDigests(tx)\n    if (items != null) digests.push([resultIndex, items])\n  }\n  return [hydrated, digests]\n}\n\nfunction collectWholeTransactionVerifications(\n  hydrated: ReadonlyMap<number, Transaction>,\n  digestAttempted: ReadonlySet<number>,\n  verifier: (SpendVerifierInterface & BdkVerifierInterface) | undefined\n): PendingTransactionVerification[] {\n  if (verifier === undefined) return []\n  const pending: PendingTransactionVerification[] = []\n  for (const [resultIndex, tx] of hydrated) {\n    if (digestAttempted.has(resultIndex)) continue\n    const params = { tx, blockHeight: postChronicleHeightFallback, consensus: true }\n    if (verifier.shouldVerifyScripts?.(params) === false) continue\n    pending.push([resultIndex, params])\n  }\n  return pending\n}\n\nfunction collectFallbackSpends(\n  txids: readonly string[],\n  transactions: ReadonlyMap<string, Transaction | undefined>,\n  accelerated: ReadonlySet<number>,\n  results: UnlockScriptVerificationResult[]\n): PendingSpendVerification[] {\n  const pending: PendingSpendVerification[] = []\n  for (let resultIndex = 0; resultIndex < txids.length; resultIndex++) {\n    if (!accelerated.has(resultIndex)) {\n      collectTransactionSpends(txids[resultIndex], resultIndex, transactions, results[resultIndex], pending)\n      continue\n    }\n    const tx = transactions.get(txids[resultIndex])\n    if (tx == null) throw new WERR_INVALID_PARAMETER('txid', `contained in beef, txid ${txids[resultIndex]}`)\n    results[resultIndex].verifiedInputs = tx.inputs.length\n  }\n  return pending\n}\n\n/**\n * Verifies every resolvable input from several transactions in one optional\n * backend batch while preserving per-transaction verification counts.\n */\nexport async function verifyUnlockScriptsBatch(\n  txids: readonly string[],\n  beef: Beef,\n  verifier?: SpendVerifierInterface\n): Promise<UnlockScriptVerificationResult[]> {\n  const results = txids.map(() => ({ verifiedInputs: 0, skippedInputs: 0 }))\n  const transactions = transactionIndex(txids, beef)\n  const digestVerifier = digestBatchVerifier(verifier)\n  const wholeVerifier = wholeTransactionVerifier(verifier)\n  const [hydrated, digestPending] = collectAcceleratedTransactions(\n    txids,\n    transactions,\n    digestVerifier,\n    digestVerifier !== undefined || wholeVerifier !== undefined\n  )\n  const digestAttempted = new Set(digestPending.map(item => item[0]))\n  const digestVerified = digestVerifier === undefined\n    ? new Set<number>()\n    : await verifyStandardP2PKHDigests(digestPending, digestVerifier)\n  const wholePending = collectWholeTransactionVerifications(hydrated, digestAttempted, wholeVerifier)\n  const wholeVerified = wholeVerifier === undefined\n    ? new Set<number>()\n    : await verifyWholeTransactions(wholePending, wholeVerifier)\n  const accelerated = new Set([...digestVerified, ...wholeVerified])\n  const pending = collectFallbackSpends(txids, transactions, accelerated, results)\n  await verifyPendingSpends(pending, verifier)\n  for (const item of pending) results[item[1]].verifiedInputs++\n  return results\n}\n\n/**\n * @param txid The TXID of a transaction in the beef for which all unlocking scripts must be valid.\n * @param beef Must contain transactions for txid and all its inputs.\n * @throws WERR_INVALID_PARAMETER if any unlocking script is invalid, if sourceTXID is invalid, if beef doesn't contain required transactions.\n */\nexport async function verifyUnlockScripts(\n  txid: string,\n  beef: Beef,\n  verifier?: SpendVerifierInterface\n): Promise<UnlockScriptVerificationResult> {\n  return (await verifyUnlockScriptsBatch([txid], beef, verifier))[0]\n}\n","import { PublicKey, SignActionSpend, Transaction } from '@bsv/sdk'\nimport { PendingSignAction, Wallet } from '../../Wallet'\nimport { WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { asBsvSdkScript } from '../../utility/utilityHelpers'\nimport { brc29ProtocolID, ScriptTemplateBRC29 } from '../../utility/ScriptTemplateBRC29'\n\nexport async function completeSignedTransaction(\n  prior: PendingSignAction,\n  spends: Record<number, SignActionSpend>,\n  wallet: Wallet\n): Promise<Transaction> {\n  /// //////////////////\n  // Insert the user provided unlocking scripts from \"spends\" arg\n  /// //////////////////\n  for (const [key, spend] of Object.entries(spends)) {\n    const vin = Number(key)\n    const createInput = prior.args.inputs[vin]\n    const input = prior.tx.inputs[vin]\n    if (!createInput || !input || createInput.unlockingScript || !Number.isInteger(createInput.unlockingScriptLength)) {\n      throw new WERR_INVALID_PARAMETER(\n        'args',\n        'spend does not correspond to prior input with valid unlockingScriptLength.'\n      )\n    }\n    if (spend.unlockingScript.length / 2 > createInput.unlockingScriptLength) {\n      throw new WERR_INVALID_PARAMETER(\n        'args',\n        `spend unlockingScript length ${spend.unlockingScript.length} exceeds expected length ${createInput.unlockingScriptLength}`\n      )\n    }\n    input.unlockingScript = asBsvSdkScript(spend.unlockingScript)\n    if (spend.sequenceNumber !== undefined) input.sequence = spend.sequenceNumber\n  }\n\n  /// //////////////////\n  // Insert SABPPP unlock templates for wallet signed inputs\n  /// //////////////////\n  const prepareUnlockingTemplates = (\n    keys: ReturnType<Wallet['getClientChangeKeyPair']>\n  ): void => {\n    const counterparties = new Map<string, PublicKey>()\n    const counterparty = (publicKey: string): PublicKey => {\n      let parsed = counterparties.get(publicKey)\n      if (parsed == null) {\n        parsed = PublicKey.fromString(publicKey)\n        counterparties.set(publicKey, parsed)\n      }\n      return parsed\n    }\n    const prepared = prior.pdi.map(pdi => {\n      const template = new ScriptTemplateBRC29({\n        derivationPrefix: pdi.derivationPrefix,\n        derivationSuffix: pdi.derivationSuffix,\n        keyDeriver: wallet.keyDeriver\n      })\n      const unlockerPubKey = counterparty(pdi.unlockerPubKey || keys.publicKey)\n      return { pdi, template, unlockerPubKey }\n    })\n    const derivations = prepared.map(({ template, unlockerPubKey }) => ({\n      protocolID: brc29ProtocolID,\n      keyID: template.getKeyID(),\n      counterparty: unlockerPubKey\n    }))\n    const derivedPrivateKeys = wallet.keyDeriver.derivePrivateKeys?.(derivations) ??\n      derivations.map(derivation => wallet.keyDeriver.derivePrivateKey(\n        derivation.protocolID,\n        derivation.keyID,\n        derivation.counterparty\n      ))\n    for (let index = 0; index < prepared.length; index++) {\n      const { pdi, template } = prepared[index]\n      const unlockTemplate = template.unlockWithDerivedPrivateKey(\n        derivedPrivateKeys[index],\n        pdi.sourceSatoshis,\n        asBsvSdkScript(pdi.lockingScript)\n      )\n      const input = prior.tx.inputs[pdi.vin]\n      input.unlockingScriptTemplate = unlockTemplate\n    }\n  }\n\n  if (wallet.telemetry.enabled && prior.pdi.length > 0) {\n    await wallet.telemetry.withSpan(\n      'wallet.crypto.prepare_unlocking_templates',\n      {\n        component: 'wallet-toolbox',\n        carrier: prior.args,\n        attributes: {\n          'crypto.managed_input_count': prior.pdi.length\n        }\n      },\n      async span => {\n        // Computing the root public key requires an elliptic-curve\n        // multiplication. It is invariant for the complete action and must not\n        // be repeated for every managed input in fragmented funding.\n        const keys = await wallet.telemetry.withSpan(\n          'wallet.crypto.client_change_key',\n          { component: 'wallet-toolbox', parent: span.context },\n          () => wallet.getClientChangeKeyPair()\n        )\n        await wallet.telemetry.withSpan(\n          'wallet.crypto.derive_unlocking_templates',\n          {\n            component: 'wallet-toolbox',\n            parent: span.context,\n            attributes: { 'crypto.managed_input_count': prior.pdi.length }\n          },\n          () => prepareUnlockingTemplates(keys)\n        )\n      }\n    )\n  } else if (prior.pdi.length > 0) {\n    prepareUnlockingTemplates(wallet.getClientChangeKeyPair())\n  }\n\n  /// //////////////////\n  // Sign wallet signed inputs making transaction fully valid.\n  /// //////////////////\n  if (wallet.telemetry.enabled) {\n    await wallet.telemetry.withSpan(\n      'wallet.crypto.transaction_sign',\n      {\n        component: 'wallet-toolbox',\n        carrier: prior.args,\n        attributes: {\n          'crypto.input_count': prior.tx.inputs.length\n        }\n      },\n      async () => await prior.tx.sign()\n    )\n  } else {\n    await prior.tx.sign()\n  }\n\n  return prior.tx\n}\n\nexport { verifyUnlockScripts } from './verifyUnlockScripts'\nexport type { UnlockScriptVerificationResult } from './verifyUnlockScripts'\n","import { Beef } from '@bsv/sdk'\n\nconst resultBeefs = new WeakMap<object, Beef>()\n\nexport function setResultBeef (result: object, beef: Beef): void {\n  resultBeefs.set(result, beef)\n}\n\nexport function getResultBeef (result: object): Beef | undefined {\n  return resultBeefs.get(result)\n}\n","import {\n  AtomicBEEF,\n  Beef,\n  CreateActionResult,\n  OutpointString,\n  SendWithResult,\n  SignableTransaction,\n  TelemetrySpan,\n  TXIDHexString,\n  Transaction,\n  Validation\n} from '@bsv/sdk'\nimport { buildSignableTransaction } from './buildSignableTransaction'\nimport {\n  AuthId,\n  ReviewActionResult,\n  StorageProcessActionArgs,\n  StorageProcessActionResults\n} from '../../sdk/WalletStorage.interfaces'\nimport { completeSignedTransaction, verifyUnlockScripts } from './completeSignedTransaction'\nimport { PendingSignAction, Wallet } from '../../Wallet'\nimport { WERR_INTERNAL } from '../../sdk/WERR_errors'\nimport { setResultBeef } from './resultBeef'\n\nexport interface CreateActionResultX extends CreateActionResult {\n  txid?: TXIDHexString\n  tx?: AtomicBEEF\n  noSendChange?: OutpointString[]\n  sendWithResults?: SendWithResult[]\n  signableTransaction?: SignableTransaction\n  notDelayedResults?: ReviewActionResult[]\n}\n\nexport async function createAction(\n  wallet: Wallet,\n  auth: AuthId,\n  vargs: Validation.ValidCreateActionArgs\n): Promise<CreateActionResultX> {\n  if (!wallet.telemetry.enabled) return await createActionCore(wallet, auth, vargs)\n  return await wallet.telemetry.withSpan(\n    'wallet.create_action',\n    {\n      component: 'wallet-toolbox',\n      carrier: vargs,\n      attributes: {\n        'action.input_count': vargs.inputs.length,\n        'action.output_count': vargs.outputs.length,\n        'action.is_new_transaction': vargs.isNewTx,\n        'action.is_sign_action': vargs.isSignAction\n      }\n    },\n    async span => {\n      const result = await createActionCore(wallet, auth, vargs, span)\n      span.end({\n        attributes: {\n          'action.has_transaction': result.tx != null,\n          'action.has_signable_transaction': result.signableTransaction != null,\n          'action.send_result_count': result.sendWithResults?.length ?? 0\n        }\n      })\n      return result\n    }\n  )\n}\n\nasync function createActionCore(\n  wallet: Wallet,\n  auth: AuthId,\n  vargs: Validation.ValidCreateActionArgs,\n  parent?: TelemetrySpan\n): Promise<CreateActionResultX> {\n  const r: CreateActionResultX = {}\n  const logger = vargs.logger\n\n  let prior: PendingSignAction | undefined\n\n  if (vargs.isNewTx || vargs.isTestWerrReviewActions) {\n    prior = await createNewTx(wallet, vargs, parent)\n    logger?.log('created new transaction')\n\n    if (vargs.isSignAction) {\n      const r = makeSignableTransactionResult(prior, wallet, vargs)\n      logger?.log('created signable transaction result')\n      return r\n    }\n\n    prior.tx = await traceActionStep(\n      wallet,\n      'wallet.create_action.complete_signing',\n      parent,\n      async () => await completeSignedTransaction(prior!, {}, wallet)\n    )\n    logger?.log('completed signed transaction')\n\n    r.txid = prior.tx.id('hex')\n    const beef = await traceActionStep(\n      wallet,\n      'wallet.create_action.assemble_result_beef',\n      parent,\n      () => {\n        const result = new Beef()\n        if (prior!.dcr.inputBeef != null) {\n          const inputBeef =\n            prior!.dcr.inputBeef instanceof Uint8Array\n              ? Beef.fromBinaryView(prior!.dcr.inputBeef)\n              : Beef.fromBinary(prior!.dcr.inputBeef)\n          result.mergeBeef(inputBeef)\n        }\n        result.mergeTransaction(prior!.tx)\n        return result\n      }\n    )\n    logger?.log('merged beef')\n\n    await traceActionStep(\n      wallet,\n      'wallet.create_action.verify_unlock_scripts',\n      parent,\n      async () => await verifyUnlockScripts(r.txid!, beef, wallet.scriptVerifier)\n    )\n    logger?.log('verified unlock scripts')\n\n    r.noSendChange = prior.dcr.noSendChangeOutputVouts?.map(vout => `${r.txid}.${vout}`)\n    beef.atomicTxid = r.txid\n    setResultBeef(r, beef)\n    if (!vargs.options.returnTXIDOnly) {\n      r.tx = await traceActionStep(\n        wallet,\n        'wallet.create_action.serialize_result_beef',\n        parent,\n        () => beef.toBinaryAtomic(r.txid!)\n      )\n    }\n  }\n\n  const { sendWithResults, notDelayedResults } = await traceActionStep(\n    wallet,\n    'wallet.create_action.process',\n    parent,\n    async () => await processAction(prior, wallet, auth, vargs)\n  )\n  logger?.log('processed transaction')\n\n  r.sendWithResults = sendWithResults\n  r.notDelayedResults = notDelayedResults\n\n  return r\n}\n\nasync function traceActionStep<T>(\n  wallet: Wallet,\n  name: string,\n  parent: TelemetrySpan | undefined,\n  callback: () => Promise<T> | T\n): Promise<T> {\n  if (parent == null) return await callback()\n  return await wallet.telemetry.withSpan(\n    name,\n    {\n      component: 'wallet-toolbox',\n      parent: parent.context\n    },\n    callback\n  )\n}\n\nasync function createNewTx(\n  wallet: Wallet,\n  vargs: Validation.ValidCreateActionArgs,\n  parent?: TelemetrySpan\n): Promise<PendingSignAction> {\n  const logger = vargs.logger\n  const storageArgs = removeUnlockScripts(vargs)\n  const dcr = await traceActionStep(\n    wallet,\n    'wallet.create_action.storage_plan',\n    parent,\n    async () => (await wallet.actionBatch.plan(storageArgs)) ?? (await wallet.storage.createAction(storageArgs))\n  )\n\n  const reference = dcr.reference\n\n  const { tx, amount, pdi } = await traceActionStep(\n    wallet,\n    'wallet.create_action.build_signable_transaction',\n    parent,\n    () => buildSignableTransaction(dcr, vargs, wallet)\n  )\n  logger?.log('built signable transaction')\n\n  const prior: PendingSignAction = { reference, dcr, args: vargs, amount, tx, pdi }\n\n  return prior\n}\n\nfunction makeSignableTransactionResult(\n  prior: PendingSignAction,\n  wallet: Wallet,\n  args: Validation.ValidCreateActionArgs\n): CreateActionResult {\n  if (prior.dcr.inputBeef == null) throw new WERR_INTERNAL('prior.dcr.inputBeef must be valid')\n\n  const txid = prior.tx.id('hex')\n\n  const r: CreateActionResult = {\n    noSendChange: args.isNoSend ? prior.dcr.noSendChangeOutputVouts?.map(vout => `${txid}.${vout}`) : undefined,\n    signableTransaction: {\n      reference: prior.dcr.reference,\n      tx: makeSignableTransactionBeef(prior.tx)\n    }\n  }\n\n  wallet.pendingSignActions[r.signableTransaction!.reference] = prior\n\n  return r\n}\n\nfunction makeSignableTransactionBeef(tx: Transaction): number[] {\n  // This is a special case beef for transaction signing.\n  // We only need the transaction being signed, and for each input, the raw source transaction.\n  const beef = new Beef()\n  for (const input of tx.inputs) {\n    if (input.sourceTransaction == null) {\n      throw new WERR_INTERNAL('Every signableTransaction input must have a sourceTransaction')\n    }\n    beef.mergeRawTx(input.sourceTransaction.toUint8Array())\n  }\n  beef.mergeRawTx(tx.toUint8Array())\n  // BRC-100 historically returns number[] here. Keep that observable shape;\n  // Wallet Wire converts it to compact bytes only inside negotiated substrates.\n  return beef.toBinaryAtomic(tx.id('hex'))\n}\n\nfunction removeUnlockScripts(args: Validation.ValidCreateActionArgs) {\n  let storageArgs = args\n  if (!storageArgs.inputs.every(i => i.unlockingScript === undefined)) {\n    // Never send unlocking scripts to storage, all it needs is the script length.\n    storageArgs = { ...args, inputs: [] }\n    for (const i of args.inputs) {\n      const di: Validation.ValidCreateActionInput = {\n        ...i,\n        unlockingScriptLength: i.unlockingScript !== undefined ? i.unlockingScript.length : i.unlockingScriptLength\n      }\n      delete di.unlockingScript\n      storageArgs.inputs.push(di)\n    }\n  }\n  return storageArgs\n}\n\nexport async function processAction(\n  prior: PendingSignAction | undefined,\n  wallet: Wallet,\n  auth: AuthId,\n  vargs: Validation.ValidProcessActionArgs\n): Promise<StorageProcessActionResults> {\n  const batchResult = await wallet.actionBatch.process(prior, vargs)\n  if (batchResult != null) return batchResult\n  const args: StorageProcessActionArgs = {\n    isNewTx: vargs.isNewTx,\n    isSendWith: vargs.isSendWith,\n    isNoSend: vargs.isNoSend,\n    isDelayed: vargs.isDelayed,\n    reference: prior != null ? prior.reference : undefined,\n    txid: prior != null ? prior.tx.id('hex') : undefined,\n    rawTx: prior != null ? prior.tx.toUint8Array() : undefined,\n    sendWith: vargs.isSendWith ? vargs.options.sendWith : [],\n    logger: vargs.logger\n  }\n  const r: StorageProcessActionResults = await wallet.storage.processAction(args)\n\n  return r\n}\n","import {\n  AtomicBEEF,\n  Beef,\n  SendWithResult,\n  SignActionArgs,\n  SignActionResult,\n  TelemetrySpan,\n  TXIDHexString,\n  Validation\n} from '@bsv/sdk'\nimport { processAction } from './createAction'\nimport { AuthId, ReviewActionResult } from '../../sdk/WalletStorage.interfaces'\nimport { completeSignedTransaction, verifyUnlockScripts } from './completeSignedTransaction'\nimport { Wallet } from '../../Wallet'\nimport { WERR_INTERNAL, WERR_NOT_IMPLEMENTED } from '../../sdk/WERR_errors'\nimport { setResultBeef } from './resultBeef'\n\nexport interface SignActionResultX extends SignActionResult {\n  txid?: TXIDHexString\n  tx?: AtomicBEEF\n  sendWithResults?: SendWithResult[]\n  notDelayedResults?: ReviewActionResult[]\n}\n\nexport async function signAction(wallet: Wallet, auth: AuthId, args: SignActionArgs): Promise<SignActionResultX> {\n  if (!wallet.telemetry.enabled) return await signActionCore(wallet, auth, args)\n  return await wallet.telemetry.withSpan(\n    'wallet.sign_action',\n    {\n      component: 'wallet-toolbox',\n      carrier: args\n    },\n    async span => {\n      const result = await signActionCore(wallet, auth, args, span)\n      span.end({\n        attributes: {\n          'action.has_transaction': result.tx != null,\n          'action.send_result_count': result.sendWithResults?.length ?? 0\n        }\n      })\n      return result\n    }\n  )\n}\n\nasync function signActionCore(\n  wallet: Wallet,\n  auth: AuthId,\n  args: SignActionArgs,\n  parent?: TelemetrySpan\n): Promise<SignActionResultX> {\n  const prior = wallet.pendingSignActions[args.reference]\n  if (!prior) {\n    throw new WERR_NOT_IMPLEMENTED('recovery of out-of-session signAction reference data is not yet implemented.')\n  }\n  if (prior.dcr.inputBeef == null) throw new WERR_INTERNAL('prior.dcr.inputBeef must be valid')\n\n  const vargs = mergePriorOptions(prior.args, args)\n\n  prior.tx = await traceSignActionStep(\n    wallet,\n    'wallet.sign_action.complete_signing',\n    parent,\n    async () => await completeSignedTransaction(prior, vargs.spends, wallet)\n  )\n\n  const { sendWithResults, notDelayedResults } = await traceSignActionStep(\n    wallet,\n    'wallet.sign_action.process',\n    parent,\n    async () => await processAction(prior, wallet, auth, vargs)\n  )\n\n  const txid = prior.tx.id('hex')\n  const beef =\n    prior.dcr.inputBeef instanceof Uint8Array\n      ? Beef.fromBinaryView(prior.dcr.inputBeef)\n      : Beef.fromBinary(prior.dcr.inputBeef)\n  beef.mergeTransaction(prior.tx)\n\n  await traceSignActionStep(\n    wallet,\n    'wallet.sign_action.verify_unlock_scripts',\n    parent,\n    async () => await verifyUnlockScripts(txid, beef, wallet.scriptVerifier)\n  )\n\n  const r: SignActionResultX = {\n    txid: prior.tx.id('hex'),\n    tx: vargs.options.returnTXIDOnly ? undefined : beef.toBinaryAtomic(txid),\n    sendWithResults,\n    notDelayedResults\n  }\n\n  beef.atomicTxid = txid\n  setResultBeef(r, beef)\n\n  return r\n}\n\nasync function traceSignActionStep<T>(\n  wallet: Wallet,\n  name: string,\n  parent: TelemetrySpan | undefined,\n  callback: () => Promise<T> | T\n): Promise<T> {\n  if (parent == null) return await callback()\n  return await wallet.telemetry.withSpan(\n    name,\n    {\n      component: 'wallet-toolbox',\n      parent: parent.context\n    },\n    callback\n  )\n}\n\nfunction mergePriorOptions(\n  caVargs: Validation.ValidCreateActionArgs,\n  saArgs: SignActionArgs\n): Validation.ValidSignActionArgs {\n  const saOptions = (saArgs.options ||= {})\n  saOptions.acceptDelayedBroadcast ??= caVargs.options.acceptDelayedBroadcast\n  saOptions.returnTXIDOnly ??= caVargs.options.returnTXIDOnly\n  saOptions.noSend ??= caVargs.options.noSend\n  saOptions.sendWith ??= caVargs.options.sendWith\n  return Validation.validateSignActionArgs(saArgs)\n}\n","import { Beef, InternalizeActionArgs, InternalizeOutput, P2PKH, WalletProtocol, Validation } from '@bsv/sdk'\nimport { Wallet } from '../../Wallet'\nimport { AuthId, StorageInternalizeActionResult } from '../../sdk/WalletStorage.interfaces'\nimport { WERR_INTERNAL, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\n\n/**\n * Internalize Action allows a wallet to take ownership of outputs in a pre-existing transaction.\n * The transaction may, or may not already be known to both the storage and user.\n *\n * Two types of outputs are handled: \"wallet payments\" and \"basket insertions\".\n *\n * A \"basket insertion\" output is considered a custom output and has no effect on the wallet's \"balance\".\n *\n * A \"wallet payment\" adds an outputs value to the wallet's change \"balance\". These outputs are assigned to the \"default\" basket.\n *\n * Processing starts with simple validation and then checks for a pre-existing transaction.\n * If the transaction is already known to the user, then the outputs are reviewed against the existing outputs treatment,\n * and merge rules are added to the arguments passed to the storage layer.\n *\n * The existing transaction's `status` determines what the merge path does next:\n *  - `'unproven'`, `'completed'`, or `'sending'`: outputs are merged; status is left as-is.\n *    The `'sending'` case covers a transaction this wallet already signed and handed to broadcast processing, but\n *    whose proven_tx_req has not yet been advanced by the normal monitor/posting flow.\n *  - `'nosend'`: the `internalizeAction` call is treated as explicit authorization to advance the lifecycle.\n *    `transactions.status` is promoted to `'completed'` (BUMP-bearing BEEF) or `'unproven'` (otherwise), and the\n *    `proven_tx_req` is moved out of `'nosend'` so Monitor's proof-fetching flow can finalize it. See storage-layer\n *    `internalizeAction` docs for the full rationale.\n *  - Any other status: an error.\n *\n * When the transaction already exists, the description is updated. The isOutgoing sense is not changed.\n *\n * \"basket insertion\" Merge Rules:\n * 1. The \"default\" basket may not be specified as the insertion basket.\n * 2. Managed change may not be reclassified as a basket insertion.\n * 3. Basket insertions do not affect wallet balance and are typed \"custom\".\n *\n * \"wallet payment\" Merge Rules:\n * 1. Targeting an existing managed output is idempotent.\n * 2. Targeting a custom output converts it to managed BRC-29 change after\n *    the locking script is verified. This is the only supported in-place\n *    recovery path for a misclassified BRC-29 payment.\n *\n */\nexport async function internalizeAction(\n  wallet: Wallet,\n  auth: AuthId,\n  args: InternalizeActionArgs\n): Promise<StorageInternalizeActionResult> {\n  const vargs = Validation.validateInternalizeActionArgs(args)\n\n  const { tx } = await validateAtomicBeef()\n  const brc29ProtocolID: WalletProtocol = [2, '3241645161d8']\n\n  for (const o of vargs.outputs) {\n    if (o.outputIndex < 0 || o.outputIndex >= tx.outputs.length) {\n      throw new WERR_INVALID_PARAMETER('outputIndex', `a valid output index in range 0 to ${tx.outputs.length - 1}`)\n    }\n    switch (o.protocol) {\n      case 'basket insertion':\n        setupBasketInsertionForOutput(o, vargs)\n        break\n      case 'wallet payment':\n        setupWalletPaymentForOutput(o, vargs)\n        break\n      default:\n        throw new WERR_INTERNAL(`unexpected protocol ${o.protocol}`)\n    }\n  }\n\n  const r: StorageInternalizeActionResult = await wallet.storage.internalizeAction(args)\n\n  return r\n\n  function setupWalletPaymentForOutput(o: InternalizeOutput, _dargs: Validation.ValidInternalizeActionArgs) {\n    const p = o.paymentRemittance\n    const output = tx.outputs[o.outputIndex]\n    if (p == null) throw new WERR_INVALID_PARAMETER('paymentRemittance', `valid for protocol ${o.protocol}`)\n\n    const keyID = `${p.derivationPrefix} ${p.derivationSuffix}`\n\n    const privKey = wallet.keyDeriver.derivePrivateKey(brc29ProtocolID, keyID, p.senderIdentityKey)\n    const expectedLockScript = new P2PKH().lock(privKey.toAddress())\n    if (output.lockingScript.toHex() !== expectedLockScript.toHex()) {\n      throw new WERR_INVALID_PARAMETER('paymentRemittance', 'locked by script conforming to BRC-29')\n    }\n  }\n\n  function setupBasketInsertionForOutput(o: InternalizeOutput, _dargs: Validation.ValidInternalizeActionArgs) {\n    const insertion = o.insertionRemittance\n    if (insertion == null) throw new WERR_INVALID_PARAMETER('insertionRemittance', `valid for protocol ${o.protocol}`)\n    if (insertion.basket === 'default') {\n      throw new WERR_INVALID_PARAMETER('insertionRemittance.basket', 'a non-default basket')\n    }\n  }\n\n  /**\n   * Verifies that the `tx` argument passed to internalizeAction is a valid AtomicBEEF,\n   * and the proofs are valid according to the wallet's configured chainTracker.\n   * THIS DOES NOT GUARANTEE:\n   * 1. That the transaction has been broadcast. (Is known to the network).\n   * 2. That the proofs are for the same block as recorded in the wallet's configured storage in the event of a reorg.\n   */\n  async function validateAtomicBeef() {\n    const ab = Beef.fromBinary(vargs.tx)\n\n    // Internalization is a trust boundary, so verify the AtomicBEEF against the\n    // configured chain tracker instead of accepting caller-supplied known txids.\n    const txValid = await ab.verify(await wallet.getServices().getChainTracker(), false)\n    if (!txValid || !ab.atomicTxid) {\n      console.log(`internalizeAction beef is invalid: ${ab.toLogString()}`)\n      throw new WERR_INVALID_PARAMETER('tx', 'valid AtomicBEEF')\n    }\n    const txid = ab.atomicTxid\n    const btx = ab.findTxid(txid)\n    if (btx == null) throw new WERR_INVALID_PARAMETER('tx', `valid AtomicBEEF with newest txid of ${txid}`)\n    const tx = btx.tx!\n\n    return { ab, tx, txid }\n  }\n}\n","import { LocalKVStore, PubKeyHex, WalletInterface } from '@bsv/sdk'\n\nexport interface Certifier {\n  name: string\n  description: string\n  identityKey: PubKeyHex\n  trust: number\n  iconUrl?: string\n  baseURL?: string // ?\n}\nexport interface TrustSettings {\n  trustLevel: number\n  trustedCertifiers: Certifier[]\n}\nexport interface WalletTheme {\n  mode: string\n}\nexport interface WalletSettings {\n  trustSettings: TrustSettings\n  theme?: WalletTheme\n  currency?: string\n  permissionMode?: string // Vendor-specific permission UX mode identifier\n}\nexport interface WalletSettingsManagerConfig {\n  defaultSettings: WalletSettings\n}\n\nconst SETTINGS_BASKET = 'wallet settings'\n\n// Defaults can be overridden as needed\nexport const DEFAULT_SETTINGS = {\n  trustSettings: {\n    trustLevel: 2,\n    trustedCertifiers: [\n      {\n        name: 'Metanet Trust Services',\n        description: 'Registry for protocols, baskets, and certificates types',\n        iconUrl: 'https://bsvblockchain.org/favicon.ico',\n        identityKey: '03daf815fe38f83da0ad83b5bedc520aa488aef5cbc93a93c67a7fe60406cbffe8',\n        trust: 4\n      },\n      {\n        name: 'SocialCert',\n        description: 'Certifies social media handles, phone numbers and emails',\n        iconUrl: 'https://socialcert.net/favicon.ico',\n        trust: 3,\n        identityKey: '02cf6cdf466951d8dfc9e7c9367511d0007ed6fba35ed42d425cc412fd6cfd4a17'\n      }\n    ]\n  },\n  theme: { mode: 'dark' },\n  permissionMode: 'simple'\n} as WalletSettings\n\n// Mapping of certifier names to their testnet identity keys\nconst TESTNET_IDENTITY_KEYS: Record<string, string> = {\n  'Babbage Trust Services': '03d0b36b5c98b000ec9ffed9a2cf005e279244edf6a19cf90545cdebe873162761',\n  IdentiCert: '036dc48522aba1705afbb43df3c04dbd1da373b6154341a875bceaa2a3e7f21528',\n  SocialCert: '02cf6cdf466951d8dfc9e7c9367511d0007ed6fba35ed42d425cc412fd6cfd4a17'\n}\n\n// Define defaults that can be imported for a testnet environment\nexport const TESTNET_DEFAULT_SETTINGS: WalletSettings = {\n  ...DEFAULT_SETTINGS,\n  trustSettings: {\n    ...DEFAULT_SETTINGS.trustSettings,\n    trustedCertifiers: DEFAULT_SETTINGS.trustSettings.trustedCertifiers.map(certifier => ({\n      ...certifier,\n      // Use the testnet key if provided, otherwise fallback to the default\n      identityKey: TESTNET_IDENTITY_KEYS[certifier.name] || certifier.identityKey\n    }))\n  }\n}\n\n/**\n * Manages wallet settings\n */\nexport class WalletSettingsManager {\n  kv: LocalKVStore\n\n  constructor (\n    private readonly wallet: WalletInterface,\n    private readonly config: WalletSettingsManagerConfig = {\n      defaultSettings: DEFAULT_SETTINGS\n    }\n  ) {\n    this.kv = new LocalKVStore(wallet, SETTINGS_BASKET, true)\n  }\n\n  /**\n   * Returns a user's wallet settings\n   *\n   * @returns - Wallet settings object\n   */\n  async get (): Promise<WalletSettings> {\n    return JSON.parse((await this.kv.get('settings', JSON.stringify(this.config.defaultSettings))) as string)\n  }\n\n  /**\n   * Creates (or updates) the user's settings token.\n   *\n   * @param settings - The wallet settings to be stored.\n   */\n  async set (settings: WalletSettings): Promise<void> {\n    await this.kv.set('settings', JSON.stringify(settings))\n  }\n\n  /**\n   * Deletes the user's settings token.\n   */\n  async delete (): Promise<void> {\n    await this.kv.remove('settings')\n  }\n}\n","import {\n  LookupAnswer,\n  Transaction,\n  PushDrop,\n  VerifiableCertificate,\n  Utils,\n  ProtoWallet,\n  LookupResolver,\n  DiscoverCertificatesResult,\n  IdentityCertificate,\n  IdentityCertifier,\n  Base64String\n} from '@bsv/sdk'\nimport { Certifier, TrustSettings } from '../WalletSettingsManager'\n\n// Our extended certificate includes certifierInfo.\nexport interface ExtendedVerifiableCertificate extends IdentityCertificate {\n  certifierInfo: IdentityCertifier\n  publiclyRevealedKeyring: Record<string, Base64String>\n}\n\n// --- Helper Types for Grouping ---\n\ninterface IdentityGroup {\n  totalTrust: number\n  members: ExtendedVerifiableCertificate[]\n}\n\n/**\n * Transforms an array of VerifiableCertificate instances according to the trust settings.\n * Only certificates whose grouped total trust meets the threshold are returned,\n * and each certificate is augmented with a certifierInfo property.\n *\n * @param trustSettings - the user's trust settings including trustLevel and trusted certifiers.\n * @param certificates - an array of VerifiableCertificate objects.\n * @returns a DiscoverCertificatesResult with totalCertificates and ordered certificates.\n */\nexport const transformVerifiableCertificatesWithTrust = (\n  trustSettings: TrustSettings,\n  certificates: VerifiableCertificate[]\n): DiscoverCertificatesResult => {\n  // Group certificates by subject while accumulating trust.\n  const identityGroups: Record<string, IdentityGroup> = {}\n  // Cache certifier lookups.\n  const certifierCache: Record<string, Certifier> = {}\n\n  certificates.forEach(cert => {\n    const { subject, certifier } = cert\n    if (subject === '' || certifier === '') return\n\n    // Lookup and cache certifier details from trustSettings.\n    if (certifierCache[certifier] == null) {\n      const found = trustSettings.trustedCertifiers.find(x => x.identityKey === certifier)\n      if (found == null) return // Skip this certificate if its certifier is not trusted.\n      certifierCache[certifier] = found\n    }\n\n    // Create the IdentityCertifier object that we want to attach.\n    const certifierInfo: IdentityCertifier = {\n      name: certifierCache[certifier].name,\n      iconUrl: certifierCache[certifier].iconUrl ?? '',\n      description: certifierCache[certifier].description,\n      trust: certifierCache[certifier].trust\n    }\n\n    // Create an extended certificate that includes certifierInfo.\n    // Note: We use object spread to copy over all properties from the original certificate.\n    const extendedCert: IdentityCertificate = {\n      ...cert,\n      signature: cert.signature as string, // We know it exists at this point\n      decryptedFields: cert.decryptedFields as Record<string, string>,\n      publiclyRevealedKeyring: cert.keyring,\n      certifierInfo\n    }\n\n    // Group certificates by subject.\n    identityGroups[subject] ??= { totalTrust: 0, members: [] }\n    identityGroups[subject].totalTrust += certifierInfo.trust\n    identityGroups[subject].members.push(extendedCert)\n  })\n\n  // Filter out groups that do not meet the trust threshold and flatten the results.\n  const finalResults: ExtendedVerifiableCertificate[] = []\n  Object.values(identityGroups).forEach(group => {\n    if (group.totalTrust >= trustSettings.trustLevel) {\n      finalResults.push(...group.members)\n    }\n  })\n\n  // Sort the certificates by their certifier trust in descending order.\n  finalResults.sort((a, b) => b.certifierInfo.trust - a.certifierInfo.trust)\n\n  return {\n    totalCertificates: finalResults.length,\n    certificates: finalResults\n  }\n}\n\n/**\n * Performs an identity overlay service lookup query and returns the parsed results.\n *\n * Identity paths benefit from a larger grace window (more hosts contribute outputs before the\n * query resolves) — 300 ms is well under the \"instant\" perception threshold and catches the long\n * tail of healthy-but-slightly-slow hosts.\n */\nexport const queryOverlay = async (query: unknown, resolver: LookupResolver): Promise<VerifiableCertificate[]> => {\n  const results = await resolver.query({\n    service: 'ls_identity',\n    query\n  }, undefined, { graceMs: 300 })\n\n  return await parseResults(results)\n}\n\n/**\n * Cooperative yield helper. On environments where the main thread also drives UI work\n * (React Native, browsers), parsing many certificates synchronously freezes input handling.\n * Interleaving a 0 ms timeout between iterations gives the runtime a chance to flush UI events.\n *\n * On Node we skip the yield to avoid the timer overhead (no UI to unblock).\n */\nconst isUiRuntime = (): boolean => {\n  if (typeof globalThis === 'undefined') return false\n  const g = globalThis as any\n  // React Native exposes __DEV__/navigator.product; browsers expose window/document.\n  if (g.window !== undefined && g.document !== undefined) return true\n  if (typeof g.navigator?.product === 'string' && g.navigator.product === 'ReactNative') return true\n  return false\n}\n\nconst yieldToUi = async (): Promise<void> => {\n  await new Promise<void>((resolve) => setTimeout(resolve, 0))\n}\n\n/**\n * Parse a single overlay output into a verified, decrypted certificate. Returns `null` on any\n * parse / decrypt / verify failure so a malformed entry can never block the others.\n */\nconst parseOne = async (\n  output: { beef: number[], outputIndex: number, context?: number[] }\n): Promise<VerifiableCertificate | null> => {\n  try {\n    const tx = Transaction.fromBEEF(output.beef)\n    const decodedOutput = PushDrop.decode(tx.outputs[output.outputIndex].lockingScript)\n    const certificate: VerifiableCertificate = JSON.parse(Utils.toUTF8(decodedOutput.fields[0]))\n    const verifiableCert = new VerifiableCertificate(\n      certificate.type,\n      certificate.serialNumber,\n      certificate.subject,\n      certificate.certifier,\n      certificate.revocationOutpoint,\n      certificate.fields,\n      certificate.keyring,\n      certificate.signature\n    )\n    const decryptedFields = await verifiableCert.decryptFields(new ProtoWallet('anyone'))\n    await verifiableCert.verify()\n    verifiableCert.decryptedFields = decryptedFields\n    return verifiableCert\n  } catch (error) {\n    console.error(error)\n    return null\n  }\n}\n\n/**\n * Parse the returned UTXOs, decrypting and verifying each certificate.\n *\n * On UI runtimes (browser / React Native), yields between iterations so the JS thread does not\n * own the frame for the full duration. On Node, runs straight through.\n */\nexport const parseResults = async (lookupResult: LookupAnswer): Promise<VerifiableCertificate[]> => {\n  if (lookupResult.type !== 'output-list') return []\n  const parsedResults: VerifiableCertificate[] = []\n  const shouldYield = isUiRuntime()\n  for (const output of lookupResult.outputs) {\n    if (shouldYield) await yieldToUi()\n    const cert = await parseOne(output)\n    if (cert != null) parsedResults.push(cert)\n  }\n  return parsedResults\n}\n\n/**\n * Iterable variant of {@link parseResults}: emits each successfully parsed certificate as soon as\n * it's ready, so callers can render progressively instead of waiting for the full set.\n */\nexport async function * parseResults$ (lookupResult: LookupAnswer): AsyncIterable<VerifiableCertificate> {\n  if (lookupResult.type !== 'output-list') return\n  const shouldYield = isUiRuntime()\n  for (const output of lookupResult.outputs) {\n    if (shouldYield) await yieldToUi()\n    const cert = await parseOne(output)\n    if (cert != null) yield cert\n  }\n}\n","import { Validation } from '@bsv/sdk'\nimport type {\n  BeginActionBatchArgs,\n  StorageCapabilities\n} from '../../sdk/ActionBatch.interfaces'\n\ntype ActionBatchBootstrap = Omit<BeginActionBatchArgs, 'batchId'>\n\n/**\n * Removes large values that are uploaded through the content-addressed commit\n * path later. Older version-1 providers receive the original request unless\n * they explicitly advertise compact bootstrap support.\n */\nexport function actionBatchBootstrap (\n  args: Validation.ValidCreateActionArgs,\n  capabilities: NonNullable<StorageCapabilities['actionBatch']>\n): ActionBatchBootstrap {\n  const firstAction = { ...args, logger: undefined }\n  if (capabilities.compactBegin !== true) return { firstAction }\n\n  const scriptBytes = args.outputs.reduce(\n    (sum, output) => sum + output.lockingScript.length / 2,\n    0\n  ) + args.inputs.reduce(\n    (sum, input) => sum + (input.unlockingScript?.length ?? 0) / 2,\n    0\n  )\n  const totalBytes = scriptBytes + (args.inputBEEF?.length ?? 0)\n  // Format 2 never needs these bytes remotely: the server reserves from exact\n  // lengths and derives scripts from the signed transaction at commit. Omit\n  // them even when small so a near-limit hexadecimal script cannot become a\n  // request roughly twice the advertised binary target.\n  if (capabilities.manifestVersion !== 2 &&\n    totalBytes <= capabilities.maxInlineBytes) return { firstAction }\n\n  return {\n    firstAction: {\n      ...firstAction,\n      inputBEEF: undefined,\n      inputs: firstAction.inputs.map(input => ({\n        ...input,\n        unlockingScript: undefined\n      })),\n      outputs: firstAction.outputs.map(output => ({\n        ...output,\n        lockingScript: ''\n      }))\n    },\n    firstActionOutputScriptLengths: firstAction.outputs.map(\n      output => output.lockingScript.length / 2\n    )\n  }\n}\n","import { Hash, Utils } from '@bsv/sdk'\nimport { ActionBatchManifest } from '../sdk/ActionBatch.interfaces'\n\nexport function actionBatchBlobDigest (bytes: number[] | Uint8Array): string {\n  return Utils.toHex(Hash.sha256(bytes))\n}\n\n/**\n * Digest only the semantic manifest. Inline bytes are represented by their\n * content digest so inline and uploaded forms have the same idempotency key.\n */\nexport function actionBatchManifestDigest (manifest: Omit<ActionBatchManifest, 'digest'>): string {\n  if (manifest.format === 2) return actionBatchManifestDigestV2(manifest)\n  const payload = {\n    batchId: manifest.batchId,\n    actions: manifest.actions.map(action => ({\n      reference: action.reference,\n      txid: action.txid,\n      rawTxDigest: action.rawTxDigest ?? actionBatchBlobDigest(action.rawTx ?? []),\n      lockingScriptDigests: action.lockingScriptDigests ?? action.plan.outputs.map(output =>\n        output.lockingScript.length === 0\n          ? undefined\n          : actionBatchBlobDigest(Utils.toUint8Array(output.lockingScript, 'hex'))\n      ),\n      plan: {\n        inputs: action.plan.inputs,\n        outputs: action.plan.outputs.map(output => ({ ...output, lockingScript: '' })),\n        noSendChangeOutputVouts: action.plan.noSendChangeOutputVouts,\n        derivationPrefix: action.plan.derivationPrefix,\n        version: action.plan.version,\n        lockTime: action.plan.lockTime,\n        reference: action.plan.reference\n      },\n      metadata: {\n        ...action.metadata,\n        outputs: action.metadata.outputs.map(output => ({ ...output, lockingScript: '' }))\n      },\n      commissionKeyOffset: action.commissionKeyOffset\n    })),\n    dependencyBeefDigest: manifest.dependencyBeefDigest ?? actionBatchBlobDigest(manifest.dependencyBeef ?? []),\n    sendWith: manifest.sendWith,\n    isDelayed: manifest.isDelayed\n  }\n  return actionBatchBlobDigest(Utils.toArray(JSON.stringify(payload), 'utf8'))\n}\n\nfunction actionBatchManifestDigestV2 (manifest: Omit<ActionBatchManifest, 'digest'>): string {\n  const payload = {\n    format: 2,\n    batchId: manifest.batchId,\n    actions: manifest.actions.map(action => ({\n      reference: action.reference,\n      txid: action.txid,\n      rawTxDigest: action.rawTxDigest ?? actionBatchBlobDigest(action.rawTx ?? []),\n      lockingScriptDigests: action.lockingScriptDigests,\n      deriveLockingScripts: action.deriveLockingScripts === true,\n      plan: {\n        inputs: action.plan.inputs.map(input => ({\n          ...input,\n          sourceLockingScript: undefined,\n          sourceTransaction: undefined\n        })),\n        outputs: action.plan.outputs.map(output => ({ ...output, lockingScript: '' })),\n        noSendChangeOutputVouts: action.plan.noSendChangeOutputVouts,\n        derivationPrefix: action.plan.derivationPrefix,\n        version: action.plan.version,\n        lockTime: action.plan.lockTime,\n        reference: action.plan.reference\n      },\n      metadata: {\n        ...action.metadata,\n        outputs: action.metadata.outputs.map(output => ({ ...output, lockingScript: '' }))\n      },\n      commissionKeyOffset: action.commissionKeyOffset\n    })),\n    dependencyBeefDigest: manifest.dependencyBeefDigest ?? actionBatchBlobDigest(manifest.dependencyBeef ?? []),\n    sendWith: manifest.sendWith,\n    isDelayed: manifest.isDelayed\n  }\n  return actionBatchBlobDigest(Utils.toArray(JSON.stringify(payload), 'utf8'))\n}\n\nexport function verifyActionBatchManifestDigest (manifest: ActionBatchManifest): boolean {\n  const { digest: _digest, ...withoutDigest } = manifest\n  return manifest.digest === actionBatchManifestDigest(withoutDigest)\n}\n","import { Beef } from '@bsv/sdk'\n\n/**\n * Return the minimal subgraph needed to prove the requested transactions.\n *\n * Parents are added before children so the resulting BEEF preserves dependency\n * order. Shared ancestors and bumps are merged only once.\n */\nexport function beefForTxids (source: Beef, txids: string[]): Beef {\n  const beef = new Beef()\n  const visited = new Set<string>()\n\n  const visit = (txid: string): void => {\n    if (visited.has(txid)) return\n    visited.add(txid)\n    const sourceTx = source.findTxid(txid)\n    if (sourceTx == null) return\n    if (sourceTx.tx != null) {\n      for (const input of sourceTx.tx.inputs) {\n        if (input.sourceTXID != null) visit(input.sourceTXID)\n      }\n    }\n    if (sourceTx.bumpIndex != null) beef.mergeBump(source.bumps[sourceTx.bumpIndex])\n    beef.mergeBeefTx(sourceTx)\n  }\n\n  for (const txid of txids) visit(txid)\n  return beef\n}\n","import { PublicKey, BigNumber, PrivateKey, Curve, P2PKH, PubKeyHex } from '@bsv/sdk'\nimport { TableCommission } from '../schema/tables/TableCommission'\nimport { sha256Hash } from '../../utility/utilityHelpers'\n\nexport function keyOffsetToHashedSecret(\n  pub: PublicKey,\n  keyOffset?: string\n): { hashedSecret: BigNumber; keyOffset: string } {\n  let offset: PrivateKey\n  if (keyOffset !== undefined && typeof keyOffset === 'string') {\n    if (keyOffset.length === 64) offset = PrivateKey.fromString(keyOffset, 'hex')\n    else offset = PrivateKey.fromWif(keyOffset)\n  } else {\n    offset = PrivateKey.fromRandom()\n    keyOffset = offset.toWif()\n  }\n\n  const sharedSecret = pub.mul(offset).encode(true) as number[]\n  const hashedSecret = sha256Hash(sharedSecret)\n\n  return { hashedSecret: new BigNumber(hashedSecret), keyOffset }\n}\n\nexport function offsetPrivKey(privKey: string, keyOffset?: string): { offsetPrivKey: string; keyOffset: string } {\n  const priv = PrivateKey.fromWif(privKey)\n\n  const pub = priv.toPublicKey()\n\n  const r = keyOffsetToHashedSecret(pub, keyOffset)\n\n  const bn = priv.add(r.hashedSecret).mod(new Curve().n)\n\n  const offsetPrivKey = new PrivateKey(bn).toWif()\n\n  return { offsetPrivKey, keyOffset: r.keyOffset }\n}\n\nexport function offsetPubKey(pubKey: string, keyOffset?: string): { offsetPubKey: string; keyOffset: string } {\n  const pub = PublicKey.fromString(pubKey)\n\n  const r = keyOffsetToHashedSecret(pub, keyOffset)\n\n  // The hashed secret is multiplied by the generator point.\n  const point = new Curve().g.mul(r.hashedSecret)\n\n  // The resulting point is added to the recipient public key.\n  const offsetPubKey = new PublicKey(pub.add(point))\n\n  return { offsetPubKey: offsetPubKey.toString(), keyOffset: r.keyOffset }\n}\n\nexport function lockScriptWithKeyOffsetFromPubKey(\n  pubKey: string,\n  keyOffset?: string\n): { script: string; keyOffset: string } {\n  const r = offsetPubKey(pubKey, keyOffset)\n\n  const offsetPub = PublicKey.fromString(r.offsetPubKey)\n\n  const hash = offsetPub.toHash() as number[]\n\n  const script = new P2PKH().lock(hash).toHex()\n\n  return { script, keyOffset: r.keyOffset }\n}\n\nexport function createStorageServiceChargeScript(pubKeyHex: PubKeyHex): {\n  script: string\n  keyOffset: string\n} {\n  return lockScriptWithKeyOffsetFromPubKey(pubKeyHex)\n}\n\nexport function redeemServiceCharges(privateKeyWif: string, charges: TableCommission[]): Array<{}> {\n  const priv = PrivateKey.fromWif(privateKeyWif)\n  const pub = priv.toPublicKey()\n\n  for (const c of charges) {\n    const { hashedSecret } = keyOffsetToHashedSecret(pub, c.keyOffset)\n    priv.add(hashedSecret).mod(new Curve().n)\n    // const unlock = new P2PKH().unlock(new PrivateKey(bn), signOutputs, anyoneCanPay)\n  }\n\n  return []\n}\n","import { Random } from '@bsv/sdk'\n\nexport interface CanonicalFundingCandidate {\n  outputId: number\n  satoshis: number\n}\n\n/** Pure exact / least-over / largest-under change selection policy. */\nexport function selectCanonicalChange<T extends CanonicalFundingCandidate> (\n  outputs: T[],\n  targetSatoshis: number,\n  exactSatoshis?: number\n): T | undefined {\n  if (exactSatoshis !== undefined) {\n    const exact = outputs\n      .filter(output => output.satoshis === exactSatoshis)\n      .sort((a, b) => a.outputId - b.outputId)[0]\n    if (exact != null) return exact\n  }\n  const over = outputs\n    .filter(output => output.satoshis >= targetSatoshis)\n    .sort((a, b) => a.satoshis - b.satoshis || a.outputId - b.outputId)[0]\n  if (over != null) return over\n  return outputs\n    .filter(output => output.satoshis < targetSatoshis)\n    .sort((a, b) => b.satoshis - a.satoshis || b.outputId - a.outputId)[0]\n}\n\n/**\n * Stateful form of the canonical selector for allocating many inputs from one\n * candidate set. It preserves exact / least-over / largest-under ordering but\n * sorts once instead of filtering and sorting the full set per input.\n */\nexport class CanonicalChangeSelector<T extends CanonicalFundingCandidate> {\n  private readonly sorted: T[]\n  private readonly allocated = new Set<number>()\n\n  constructor (outputs: readonly T[]) {\n    this.sorted = [...outputs].sort((a, b) => a.satoshis - b.satoshis || a.outputId - b.outputId)\n  }\n\n  take (targetSatoshis: number, exactSatoshis?: number): T | undefined {\n    if (exactSatoshis !== undefined) {\n      for (let index = this.lowerBound(exactSatoshis); index < this.sorted.length; index++) {\n        const output = this.sorted[index]\n        if (output.satoshis !== exactSatoshis) break\n        if (!this.allocated.has(output.outputId)) return this.allocate(output)\n      }\n    }\n    for (let index = this.lowerBound(targetSatoshis); index < this.sorted.length; index++) {\n      const output = this.sorted[index]\n      if (!this.allocated.has(output.outputId)) return this.allocate(output)\n    }\n    for (let index = this.lowerBound(targetSatoshis) - 1; index >= 0; index--) {\n      const output = this.sorted[index]\n      if (!this.allocated.has(output.outputId)) return this.allocate(output)\n    }\n    return undefined\n  }\n\n  release (outputId: number): void {\n    this.allocated.delete(outputId)\n  }\n\n  private allocate (output: T): T {\n    this.allocated.add(output.outputId)\n    return output\n  }\n\n  private lowerBound (satoshis: number): number {\n    let low = 0\n    let high = this.sorted.length\n    while (low < high) {\n      const middle = (low + high) >>> 1\n      if (this.sorted[middle].satoshis < satoshis) low = middle + 1\n      else high = middle\n    }\n    return low\n  }\n}\n\nexport function repeatableRandom (randomVals?: number[]): () => number {\n  const values = [...(randomVals ?? [])]\n  return () => {\n    if (values.length > 0) {\n      const value = values.shift() ?? 0\n      values.push(value)\n      return value\n    }\n    const bytes = Random(4)\n    return (((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]) >>> 0) / 0x100000000\n  }\n}\n\n/** Pure Fisher-Yates vout assignment shared by legacy and batch planning. */\nexport function randomizeOutputVouts<T extends { vout: number }> (outputs: T[], randomVals?: number[]): void {\n  const nextRandom = repeatableRandom(randomVals)\n  const vouts = Array.from({ length: outputs.length }, (_, index) => index)\n  for (let current = vouts.length; current > 0; current--) {\n    const randomIndex = Math.floor(nextRandom() * current)\n    ;[vouts[current - 1], vouts[randomIndex]] = [vouts[randomIndex], vouts[current - 1]]\n  }\n  for (let index = 0; index < outputs.length; index++) outputs[index].vout = vouts[index]\n}\n","import { Beef, Transaction, Utils, Validation } from '@bsv/sdk'\nimport { ActionBatchFundingOutput, BeginActionBatchResult } from '../../sdk/ActionBatch.interfaces'\nimport {\n  StorageCreateActionResult,\n  StorageCreateTransactionSdkInput,\n  StorageCreateTransactionSdkOutput,\n  StorageProvidedBy\n} from '../../sdk/WalletStorage.interfaces'\nimport { WERR_INTERNAL, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { randomBytesBase64, verifyTruthy } from '../../utility/utilityHelpers'\nimport { asArray, asString } from '../../utility/utilityHelpers.noBuffer'\nimport { beefForTxids } from '../../utility/beefForTxids'\nimport { createStorageServiceChargeScript } from '../../storage/methods/offsetKey'\nimport {\n  generateChangeSdk,\n  GenerateChangeSdkChangeInput,\n  maxPossibleSatoshis\n} from '../../storage/methods/generateChange'\nimport { randomizeOutputVouts, repeatableRandom, selectCanonicalChange } from '../../storage/methods/actionPlanning'\n\nexport interface ActionBatchPlannedAction {\n  dcr: StorageCreateActionResult\n  consumedOutpoints: string[]\n  commissionKeyOffset?: string\n}\n\nexport interface PlannerOutput extends ActionBatchFundingOutput {\n  basketName?: string\n  tags?: string[]\n}\n\nexport interface ActionBatchPlannerState {\n  begin: BeginActionBatchResult\n  sharedBeef: Beef\n  reserved: Map<string, PlannerOutput>\n  explicit: Map<string, PlannerOutput>\n  staged: Map<string, PlannerOutput>\n  discardedStagedTxids: Set<string>\n  consumed: Set<string>\n  estimatedChangeCount: number\n}\n\nfunction outpointOf(output: Pick<ActionBatchFundingOutput, 'txid' | 'vout'>): string {\n  if (output.txid == null) throw new WERR_INTERNAL('batch planner output is missing txid')\n  return `${output.txid}.${output.vout}`\n}\n\nfunction randomDerivation(count: number, random: () => number): string {\n  const bytes: number[] = []\n  for (let i = 0; i < count; i++) bytes.push(Math.floor(random() * 256))\n  return Utils.toBase64(bytes)\n}\n\nfunction outputFromBeef(beef: Beef, outpoint: { txid: string; vout: number }): PlannerOutput | undefined {\n  const transaction = beef.findTxid(outpoint.txid)?.tx\n  if (transaction == null) return undefined\n  const output = transaction?.outputs[outpoint.vout]\n  if (output == null) return undefined\n  const now = new Date()\n  return {\n    outputId: -1,\n    userId: 0,\n    transactionId: 0,\n    spendable: true,\n    change: false,\n    outputDescription: '',\n    vout: outpoint.vout,\n    satoshis: Validation.validateSatoshis(output.satoshis, 'source output satoshis'),\n    providedBy: 'you',\n    purpose: '',\n    type: 'custom',\n    txid: outpoint.txid,\n    lockingScript: undefined,\n    sourceTransaction: undefined,\n    created_at: now,\n    updated_at: now\n  }\n}\n\nfunction requireManagedChange(output: PlannerOutput | undefined, name: string): PlannerOutput {\n  if (\n    output == null ||\n    !output.change ||\n    output.type !== 'P2PKH' ||\n    output.providedBy !== 'storage' ||\n    output.purpose !== 'change' ||\n    output.derivationPrefix == null ||\n    output.derivationSuffix == null\n  ) {\n    throw new WERR_INVALID_PARAMETER(name, 'wallet-managed BRC-29 change')\n  }\n  return output\n}\n\nfunction resolveInputOutput(state: ActionBatchPlannerState, outpoint: { txid: string; vout: number }): PlannerOutput {\n  const key = `${outpoint.txid}.${outpoint.vout}`\n  return (\n    state.staged.get(key) ??\n    state.explicit.get(key) ??\n    state.reserved.get(key) ??\n    (!state.discardedStagedTxids.has(outpoint.txid) ? outputFromBeef(state.sharedBeef, outpoint) : undefined) ??\n    (() => {\n      throw new WERR_INVALID_PARAMETER('inputBEEF', `proof data for ${key}`)\n    })()\n  )\n}\n\nexport function plannerOutputLockingScript(state: ActionBatchPlannerState, output: PlannerOutput): number[] {\n  if (output.lockingScript != null) return asArray(output.lockingScript)\n  if (output.txid == null) throw new WERR_INTERNAL('batch planner output is missing txid')\n  const script = state.sharedBeef.findTxid(output.txid)?.tx?.outputs[output.vout]?.lockingScript\n  if (script == null)\n    throw new WERR_INTERNAL(`batch planner output ${output.txid}.${output.vout} is missing its script`)\n  return script.toBinary()\n}\n\nexport function plannerInputLockingScript(\n  state: ActionBatchPlannerState,\n  input: Pick<StorageCreateTransactionSdkInput, 'sourceTxid' | 'sourceVout'>\n): number[] {\n  return plannerOutputLockingScript(\n    state,\n    resolveInputOutput(state, {\n      txid: input.sourceTxid,\n      vout: input.sourceVout\n    })\n  )\n}\n\nfunction sdkInputFromExplicit(\n  state: ActionBatchPlannerState,\n  input: Validation.ValidCreateActionInput,\n  vin: number,\n  output: PlannerOutput,\n  isSignAction: boolean\n): StorageCreateTransactionSdkInput {\n  let providedBy: StorageProvidedBy = output.providedBy\n  if (output.providedBy === 'storage') providedBy = 'you-and-storage'\n  return {\n    vin,\n    sourceTxid: verifyTruthy(output.txid),\n    sourceVout: output.vout,\n    sourceSatoshis: output.satoshis,\n    sourceLockingScript: asString(plannerOutputLockingScript(state, output)),\n    sourceTransaction: isSignAction ? sourceTransactionFor(state, output) : undefined,\n    unlockingScriptLength: input.unlockingScriptLength,\n    providedBy,\n    type: output.type,\n    spendingDescription: input.inputDescription,\n    derivationPrefix: output.derivationPrefix,\n    derivationSuffix: output.derivationSuffix,\n    senderIdentityKey: output.senderIdentityKey\n  }\n}\n\nfunction sdkInputFromFunding(\n  state: ActionBatchPlannerState,\n  output: PlannerOutput,\n  vin: number,\n  isSignAction: boolean\n): StorageCreateTransactionSdkInput {\n  return {\n    vin,\n    sourceTxid: verifyTruthy(output.txid),\n    sourceVout: output.vout,\n    sourceSatoshis: output.satoshis,\n    sourceLockingScript: asString(plannerOutputLockingScript(state, output)),\n    sourceTransaction: isSignAction ? sourceTransactionFor(state, output) : undefined,\n    unlockingScriptLength: 107,\n    providedBy: 'storage',\n    type: 'P2PKH',\n    spendingDescription: undefined,\n    derivationPrefix: verifyTruthy(output.derivationPrefix),\n    derivationSuffix: verifyTruthy(output.derivationSuffix),\n    senderIdentityKey: output.senderIdentityKey\n  }\n}\n\nfunction sourceTransactionFor(\n  state: ActionBatchPlannerState,\n  output: PlannerOutput\n): number[] | Uint8Array | undefined {\n  if (output.sourceTransaction != null) return output.sourceTransaction\n  if (output.txid == null) return undefined\n  return state.sharedBeef.findTxid(output.txid)?.tx?.toUint8Array()\n}\n\nfunction trimInputBeef(\n  state: ActionBatchPlannerState,\n  args: Validation.ValidCreateActionArgs,\n  inputs: StorageCreateTransactionSdkInput[]\n): Uint8Array | undefined {\n  if (args.options.returnTXIDOnly) return undefined\n  const beef = beefForTxids(\n    state.sharedBeef,\n    inputs.map(input => input.sourceTxid)\n  )\n  if (args.inputBEEF != null) beef.mergeBeef(args.inputBEEF)\n  for (const txid of args.options.knownTxids) if (beef.findTxid(txid) != null) beef.makeTxidOnly(txid)\n  return beef.toUint8Array()\n}\n\nfunction requestedOutputs(args: Validation.ValidCreateActionArgs): StorageCreateTransactionSdkOutput[] {\n  return args.outputs.map((output, vout) => ({\n    ...output,\n    vout,\n    providedBy: 'you'\n  }))\n}\n\ninterface FundingPlan {\n  allocated: PlannerOutput[]\n  changeSatoshis: number[]\n  maxPossibleSatoshisAdjustment?: { fixedOutputIndex: number; satoshis: number }\n}\n\nasync function planFunding(\n  state: ActionBatchPlannerState,\n  args: Validation.ValidCreateActionArgs,\n  explicit: PlannerOutput[],\n  noSendChange: PlannerOutput[]\n): Promise<FundingPlan> {\n  const available = [...state.reserved.values()].filter(output => !state.consumed.has(outpointOf(output)))\n  const allocated = new Map<number, PlannerOutput>()\n  const noSend = [...noSendChange]\n  const changeBasket = state.begin.changeBasket\n  const params = {\n    fixedInputs: explicit.map((output, index) => ({\n      satoshis: output.satoshis,\n      unlockingScriptLength: args.inputs[index].unlockingScriptLength\n    })),\n    fixedOutputs: [\n      ...args.outputs.map(output => ({\n        satoshis: output.satoshis,\n        lockingScriptLength: output.lockingScript.length / 2\n      })),\n      ...(state.begin.commissionSatoshis > 0\n        ? [{ satoshis: state.begin.commissionSatoshis, lockingScriptLength: 25 }]\n        : [])\n    ],\n    feeModel: state.begin.feeModel,\n    changeInitialSatoshis: Math.max(1, changeBasket.minimumDesiredUTXOValue),\n    changeFirstSatoshis: Math.max(1, Math.round(changeBasket.minimumDesiredUTXOValue / 4)),\n    changeLockingScriptLength: 25,\n    changeUnlockingScriptLength: 107,\n    targetNetCount: changeBasket.numberOfDesiredUTXOs - state.estimatedChangeCount,\n    randomVals: args.randomVals\n  }\n  const allocate = async (\n    targetSatoshis: number,\n    exactSatoshis?: number\n  ): Promise<GenerateChangeSdkChangeInput | undefined> => {\n    let output = noSend.pop()\n    output ??= selectCanonicalChange(\n      available.filter(candidate => !allocated.has(candidate.outputId)),\n      targetSatoshis,\n      exactSatoshis\n    )\n    if (output == null) return undefined\n    allocated.set(output.outputId, output)\n    return { outputId: output.outputId, satoshis: output.satoshis }\n  }\n  const release = async (outputId: number): Promise<void> => {\n    const output = allocated.get(outputId)\n    if (output == null) return\n    allocated.delete(outputId)\n    if (noSendChange.includes(output)) noSend.push(output)\n  }\n  const result = await generateChangeSdk(params, allocate, release, args.logger)\n  return {\n    allocated: result.allocatedChangeInputs.map(input => verifyTruthy(allocated.get(input.outputId))),\n    changeSatoshis: result.changeOutputs.map(output => output.satoshis),\n    maxPossibleSatoshisAdjustment: result.maxPossibleSatoshisAdjustment\n  }\n}\n\nfunction makeChangeOutputs(\n  state: ActionBatchPlannerState,\n  fixedOutputCount: number,\n  changeSatoshis: number[],\n  derivationPrefix: string,\n  random: () => number\n): StorageCreateTransactionSdkOutput[] {\n  return changeSatoshis.map((satoshis, index) => ({\n    vout: fixedOutputCount + index,\n    satoshis,\n    lockingScript: '',\n    providedBy: 'storage',\n    purpose: 'change',\n    basket: state.begin.changeBasket.name,\n    tags: [],\n    outputDescription: '',\n    derivationSuffix: randomDerivation(16, random)\n  }))\n}\n\nfunction validateActionOutpoints(state: ActionBatchPlannerState, args: Validation.ValidCreateActionArgs): void {\n  const seen = new Set<string>()\n  const outpoints = [...args.inputs.map(input => input.outpoint), ...args.options.noSendChange]\n  for (const outpoint of outpoints) {\n    const key = `${outpoint.txid}.${outpoint.vout}`\n    if (seen.has(key)) {\n      throw new WERR_INVALID_PARAMETER('inputs', `unique inputs; ${key} is repeated`)\n    }\n    if (state.consumed.has(key)) {\n      throw new WERR_INVALID_PARAMETER('inputs', `unspent inputs; ${key} is already consumed by this action batch`)\n    }\n    seen.add(key)\n  }\n}\n\nfunction resolveExplicitInputs(\n  state: ActionBatchPlannerState,\n  args: Validation.ValidCreateActionArgs\n): PlannerOutput[] {\n  const explicit = args.inputs.map(input => resolveInputOutput(state, input.outpoint))\n  if (explicit.some(output => output.change)) {\n    throw new WERR_INVALID_PARAMETER('inputs', 'unmanaged inputs; use noSendChange for managed change')\n  }\n  return explicit\n}\n\nfunction addStorageCommission(\n  state: ActionBatchPlannerState,\n  outputs: StorageCreateTransactionSdkOutput[]\n): string | undefined {\n  if (state.begin.commissionSatoshis <= 0 || state.begin.commissionPubKeyHex == null) {\n    return undefined\n  }\n  const commission = createStorageServiceChargeScript(state.begin.commissionPubKeyHex)\n  outputs.push({\n    vout: outputs.length,\n    satoshis: state.begin.commissionSatoshis,\n    lockingScript: commission.script,\n    providedBy: 'storage',\n    purpose: 'storage-commission',\n    outputDescription: 'Storage Service Charge',\n    tags: []\n  })\n  return commission.keyOffset\n}\n\nfunction applyFundingAdjustment(\n  outputs: StorageCreateTransactionSdkOutput[],\n  adjustment: { fixedOutputIndex: number; satoshis: number } | undefined\n): void {\n  if (adjustment == null) return\n  if (outputs[adjustment.fixedOutputIndex]?.satoshis !== maxPossibleSatoshis) {\n    throw new WERR_INTERNAL()\n  }\n  outputs[adjustment.fixedOutputIndex].satoshis = adjustment.satoshis\n}\n\nexport async function planAction(\n  state: ActionBatchPlannerState,\n  args: Validation.ValidCreateActionArgs\n): Promise<ActionBatchPlannedAction> {\n  validateActionOutpoints(state, args)\n  const explicit = resolveExplicitInputs(state, args)\n  const noSendChange = args.options.noSendChange.map(outpoint =>\n    requireManagedChange(resolveInputOutput(state, outpoint), `noSendChange ${outpoint.txid}.${outpoint.vout}`)\n  )\n  const funding = await planFunding(state, args, explicit, noSendChange)\n  const derivationRandom = repeatableRandom(args.randomVals)\n  const derivationPrefix = randomDerivation(16, derivationRandom)\n  const outputs = requestedOutputs(args)\n  const commissionKeyOffset = addStorageCommission(state, outputs)\n  applyFundingAdjustment(outputs, funding.maxPossibleSatoshisAdjustment)\n  const fixedOutputCount = outputs.length\n  outputs.push(\n    ...makeChangeOutputs(state, fixedOutputCount, funding.changeSatoshis, derivationPrefix, derivationRandom)\n  )\n  // Legacy output randomization starts a fresh deterministic stream. Keeping\n  // that boundary is required for byte-for-byte parity with createAction.\n  if (args.options.randomizeOutputs) randomizeOutputVouts(outputs, args.randomVals)\n\n  const inputs = [\n    ...explicit.map((output, vin) => sdkInputFromExplicit(state, args.inputs[vin], vin, output, args.isSignAction)),\n    ...funding.allocated.map((output, index) =>\n      sdkInputFromFunding(state, output, explicit.length + index, args.isSignAction)\n    )\n  ]\n  const consumedOutpoints = funding.allocated.map(outpointOf)\n  for (const input of args.inputs) consumedOutpoints.push(`${input.outpoint.txid}.${input.outpoint.vout}`)\n  for (const outpoint of consumedOutpoints) state.consumed.add(outpoint)\n  state.estimatedChangeCount += funding.changeSatoshis.length - funding.allocated.length\n\n  const reference = randomBytesBase64(12)\n  const dcr: StorageCreateActionResult = {\n    reference,\n    version: args.version,\n    lockTime: args.lockTime,\n    inputs,\n    outputs,\n    derivationPrefix,\n    inputBeef: trimInputBeef(state, args, inputs),\n    noSendChangeOutputVouts: args.isNoSend\n      ? outputs.filter(output => output.purpose === 'change').map(output => output.vout)\n      : undefined\n  }\n  return { dcr, consumedOutpoints, commissionKeyOffset }\n}\n\nexport function addPlannerOutputs(\n  target: Map<string, PlannerOutput>,\n  outputs: ActionBatchFundingOutput[],\n  basketName?: string\n): void {\n  for (const output of outputs)\n    target.set(outpointOf(output), {\n      ...output,\n      sourceTransaction: undefined,\n      basketName\n    })\n}\n\nexport function stageTransactionOutputs(\n  state: ActionBatchPlannerState,\n  tx: Transaction,\n  dcr: Pick<StorageCreateActionResult, 'outputs' | 'derivationPrefix'>\n): void {\n  state.discardedStagedTxids.delete(tx.id('hex'))\n  const now = new Date()\n  for (const output of dcr.outputs) {\n    const isChange = output.providedBy === 'storage' && output.purpose === 'change'\n    const staged: PlannerOutput = {\n      outputId: -(state.staged.size + 1),\n      userId: 0,\n      transactionId: 0,\n      basketId: isChange ? state.begin.changeBasket.basketId : undefined,\n      basketName: output.basket,\n      tags: output.tags,\n      spendable: true,\n      change: isChange,\n      outputDescription: output.outputDescription,\n      vout: output.vout,\n      satoshis: output.satoshis,\n      providedBy: output.providedBy,\n      purpose: output.purpose ?? '',\n      type: isChange ? 'P2PKH' : 'custom',\n      txid: tx.id('hex'),\n      derivationPrefix: isChange ? dcr.derivationPrefix : undefined,\n      derivationSuffix: output.derivationSuffix,\n      customInstructions: output.customInstructions,\n      lockingScript: undefined,\n      created_at: now,\n      updated_at: now\n    }\n    state.staged.set(outpointOf(staged), staged)\n  }\n}\n\nexport function mergePlannerBeef(state: ActionBatchPlannerState, tx: Transaction): void {\n  state.sharedBeef.mergeRawTx(tx.toUint8Array())\n}\n","import { Utils } from '@bsv/sdk'\nimport type {\n  ActionBatchPackEncoding,\n  ActionBatchPackItem\n} from '../sdk/ActionBatch.interfaces'\nimport { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../sdk/WERR_errors'\nimport { asUint8Array } from './utilityHelpers.noBuffer'\n\nconst PACK_MAGIC = Uint8Array.of(0x41, 0x42, 0x50, 0x31)\nconst PACK_HEADER_BYTES = 8\nconst ITEM_HEADER_BYTES = 36\nexport const ACTION_BATCH_PACK_ENCODING_HEADER = 'X-BSV-Action-Batch-Encoding'\n\ntype ExtendedCompressionStreamConstructor = new (\n  format: CompressionFormat | 'brotli'\n) => CompressionStream\n\ntype ExtendedDecompressionStreamConstructor = new (\n  format: CompressionFormat | 'brotli'\n) => DecompressionStream\n\nfunction makeCompressionStream (encoding: Exclude<ActionBatchPackEncoding, 'identity'>): CompressionStream {\n  const Constructor = globalThis.CompressionStream as ExtendedCompressionStreamConstructor\n  return new Constructor(encoding)\n}\n\nfunction makeDecompressionStream (encoding: Exclude<ActionBatchPackEncoding, 'identity'>): DecompressionStream {\n  const Constructor = globalThis.DecompressionStream as ExtendedDecompressionStreamConstructor\n  return new Constructor(encoding)\n}\n\nfunction arrayBufferView (bytes: Uint8Array): Uint8Array<ArrayBuffer> {\n  return bytes.buffer instanceof ArrayBuffer\n    ? bytes as Uint8Array<ArrayBuffer>\n    : Uint8Array.from(bytes)\n}\n\nexport function actionBatchPackLength (items: ActionBatchPackItem[]): number {\n  let length = PACK_HEADER_BYTES\n  for (const item of items) {\n    length += ITEM_HEADER_BYTES + item.bytes.length\n    if (!Number.isSafeInteger(length)) {\n      throw new WERR_INVALID_OPERATION('action batch pack exceeds this runtime’s addressable memory')\n    }\n  }\n  return length\n}\n\nfunction validatePackShape (\n  items: ActionBatchPackItem[],\n  maxBytes: number,\n  maxItems: number\n): number {\n  if (items.length === 0 || items.length > maxItems) {\n    throw new WERR_INVALID_PARAMETER('items', `between 1 and ${String(maxItems)} blobs`)\n  }\n  const length = actionBatchPackLength(items)\n  if (length > maxBytes) throw new WERR_INVALID_PARAMETER('items', 'within the provider pack limit')\n  return length\n}\n\nfunction packHeader (itemCount: number): Uint8Array {\n  const bytes = new Uint8Array(PACK_HEADER_BYTES)\n  bytes.set(PACK_MAGIC)\n  new DataView(bytes.buffer).setUint32(4, itemCount, true)\n  return bytes\n}\n\nfunction packItemHeader (item: ActionBatchPackItem): Uint8Array {\n  const digest = Utils.toUint8Array(item.digest, 'hex')\n  if (digest.length !== 32) {\n    throw new WERR_INVALID_PARAMETER('digest', 'a 32-byte hexadecimal SHA-256 digest')\n  }\n  const bytes = new Uint8Array(ITEM_HEADER_BYTES)\n  bytes.set(digest)\n  new DataView(bytes.buffer).setUint32(32, item.bytes.length, true)\n  return bytes\n}\n\n/** Encode independently content-addressed blobs into one transport frame. */\nexport function encodeActionBatchPack (\n  items: ActionBatchPackItem[],\n  maxBytes: number,\n  maxItems: number\n): Uint8Array {\n  const length = validatePackShape(items, maxBytes, maxItems)\n  const bytes = new Uint8Array(length)\n  bytes.set(packHeader(items.length))\n  let offset = PACK_HEADER_BYTES\n  for (const item of items) {\n    const header = packItemHeader(item)\n    const value = asUint8Array(item.bytes)\n    bytes.set(header, offset)\n    offset += header.length\n    bytes.set(value, offset)\n    offset += value.length\n  }\n  return bytes\n}\n\n/** Decode a transport frame without copying its individual blob payloads. */\nexport function decodeActionBatchPack (\n  bytes: Uint8Array,\n  maxBytes: number,\n  maxItems: number\n): ActionBatchPackItem[] {\n  if (bytes.length < PACK_HEADER_BYTES || bytes.length > maxBytes ||\n    !PACK_MAGIC.every((value, index) => bytes[index] === value)) {\n    throw new WERR_INVALID_PARAMETER('pack', 'a bounded action batch pack')\n  }\n  const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength)\n  const itemCount = view.getUint32(4, true)\n  if (itemCount < 1 || itemCount > maxItems) {\n    throw new WERR_INVALID_PARAMETER('pack', `between 1 and ${String(maxItems)} blobs`)\n  }\n  const items: ActionBatchPackItem[] = []\n  let offset = PACK_HEADER_BYTES\n  for (let index = 0; index < itemCount; index++) {\n    if (offset + ITEM_HEADER_BYTES > bytes.length) {\n      throw new WERR_INVALID_PARAMETER('pack', 'complete item headers')\n    }\n    const digest = Utils.toHex(bytes.subarray(offset, offset + 32))\n    offset += 32\n    const length = view.getUint32(offset, true)\n    offset += 4\n    if (offset + length > bytes.length) throw new WERR_INVALID_PARAMETER('pack', 'complete item bytes')\n    items.push({ digest, bytes: bytes.subarray(offset, offset + length) })\n    offset += length\n  }\n  if (offset !== bytes.length) throw new WERR_INVALID_PARAMETER('pack', 'no trailing bytes')\n  return items\n}\n\nfunction supportsTransform (encoding: ActionBatchPackEncoding, decompress: boolean): boolean {\n  if (encoding === 'identity') return true\n  try {\n    if (decompress) {\n      if (typeof globalThis.DecompressionStream !== 'function') return false\n      makeDecompressionStream(encoding)\n    } else {\n      if (typeof globalThis.CompressionStream !== 'function') return false\n      makeCompressionStream(encoding)\n    }\n    return true\n  } catch {\n    return false\n  }\n}\n\nexport function supportedActionBatchPackEncodings (): ActionBatchPackEncoding[] {\n  const encodings: ActionBatchPackEncoding[] = []\n  // CompressionStream does not expose Brotli quality controls. Its runtime\n  // default can favor density at substantially higher latency, so prefer the\n  // broadly available low-latency gzip lane unless a caller orders otherwise.\n  for (const encoding of ['gzip', 'brotli'] as const) {\n    if (supportsTransform(encoding, false) && supportsTransform(encoding, true)) encodings.push(encoding)\n  }\n  encodings.push('identity')\n  return encodings\n}\n\nasync function collectStream (\n  stream: ReadableStream<Uint8Array>,\n  maxBytes?: number\n): Promise<Uint8Array> {\n  const reader = stream.getReader()\n  const chunks: Uint8Array[] = []\n  let length = 0\n  for (;;) {\n    const { done, value } = await reader.read()\n    if (done) break\n    length += value.length\n    if (!Number.isSafeInteger(length) || (maxBytes != null && length > maxBytes)) {\n      await reader.cancel()\n      throw new WERR_INVALID_PARAMETER('pack', 'within the decompressed provider limit')\n    }\n    chunks.push(value)\n  }\n  const bytes = new Uint8Array(length)\n  let offset = 0\n  for (const chunk of chunks) {\n    bytes.set(chunk, offset)\n    offset += chunk.length\n  }\n  return bytes\n}\n\nasync function transform (\n  bytes: Uint8Array,\n  encoding: ActionBatchPackEncoding,\n  decompress: boolean,\n  maxBytes?: number\n): Promise<Uint8Array> {\n  if (encoding === 'identity') {\n    if (maxBytes != null && bytes.length > maxBytes) {\n      throw new WERR_INVALID_PARAMETER('pack', 'within the provider limit')\n    }\n    return bytes\n  }\n  if (!supportsTransform(encoding, decompress)) {\n    throw new WERR_INVALID_OPERATION(`action batch ${encoding} compression is unavailable in this runtime`)\n  }\n  const codec = decompress\n    ? makeDecompressionStream(encoding)\n    : makeCompressionStream(encoding)\n  const output = collectStream(codec.readable, maxBytes)\n  const writer = codec.writable.getWriter()\n  const input = (async () => {\n    await writer.write(arrayBufferView(bytes))\n    await writer.close()\n  })()\n  const [result] = await Promise.all([output, input])\n  return result\n}\n\nexport async function compressActionBatchPack (\n  bytes: Uint8Array,\n  encoding: ActionBatchPackEncoding\n): Promise<Uint8Array> {\n  return await transform(bytes, encoding, false)\n}\n\n/**\n * Compress a pack directly from its item views. Successful compression avoids\n * allocating and copying an additional uncompressed aggregate frame.\n */\nexport async function compressActionBatchPackItems (\n  items: ActionBatchPackItem[],\n  encoding: ActionBatchPackEncoding,\n  maxBytes: number,\n  maxItems: number\n): Promise<Uint8Array> {\n  validatePackShape(items, maxBytes, maxItems)\n  if (encoding === 'identity') return encodeActionBatchPack(items, maxBytes, maxItems)\n  if (!supportsTransform(encoding, false)) {\n    throw new WERR_INVALID_OPERATION(`action batch ${encoding} compression is unavailable in this runtime`)\n  }\n  const codec = makeCompressionStream(encoding)\n  const output = collectStream(codec.readable)\n  const writer = codec.writable.getWriter()\n  const input = (async () => {\n    await writer.write(arrayBufferView(packHeader(items.length)))\n    for (const item of items) {\n      await writer.write(arrayBufferView(packItemHeader(item)))\n      await writer.write(arrayBufferView(asUint8Array(item.bytes)))\n    }\n    await writer.close()\n  })()\n  const [result] = await Promise.all([output, input])\n  return result\n}\n\nexport async function decompressActionBatchPack (\n  bytes: Uint8Array,\n  encoding: ActionBatchPackEncoding,\n  maxBytes: number\n): Promise<Uint8Array> {\n  return await transform(bytes, encoding, true, maxBytes)\n}\n","import {\n  Beef,\n  ListActionsResult,\n  ListOutputsResult,\n  Validation\n} from '@bsv/sdk'\nimport type { PendingSignAction, Wallet } from '../../Wallet'\nimport {\n  ActionBatchCommitAction,\n  ActionBatchCommitPlan,\n  ActionBatchManifest,\n  BeginActionBatchResult,\n  CommitActionBatchResult,\n  StorageCapabilities\n} from '../../sdk/ActionBatch.interfaces'\nimport { actionBatchBootstrap } from './actionBatchBootstrap'\nimport { StorageCreateActionResult, StorageProcessActionResults } from '../../sdk/WalletStorage.interfaces'\nimport { WERR_INSUFFICIENT_FUNDS, WERR_INVALID_OPERATION } from '../../sdk/WERR_errors'\nimport { randomBytesBase64 } from '../../utility/utilityHelpers'\nimport { asString, asUint8Array } from '../../utility/utilityHelpers.noBuffer'\nimport {\n  isListActionsSpecOp,\n  specOpFailedActions,\n  specOpNoSendActions,\n  specOpWalletBalance,\n  specOpWalletManagedUtxos\n} from '../../sdk/types'\nimport {\n  actionBatchBlobDigest,\n  actionBatchManifestDigest\n} from '../../utility/actionBatchDigest'\nimport {\n  ActionBatchPlannedAction,\n  ActionBatchPlannerState,\n  addPlannerOutputs,\n  mergePlannerBeef,\n  planAction,\n  plannerInputLockingScript,\n  plannerOutputLockingScript,\n  stageTransactionOutputs\n} from './ActionBatchPlanner'\nimport { beefForTxids } from '../../utility/beefForTxids'\nimport { actionBatchPackLength } from '../../utility/actionBatchPack'\n\nexport type ActionBatchMode = 'auto' | 'legacy'\n\ninterface PendingBatchPlan {\n  args: Validation.ValidCreateActionArgs\n  planned: ActionBatchPlannedAction\n}\n\ninterface UploadBlob {\n  digest: string\n  bytes: Uint8Array\n}\n\nfunction mergeUnique (values: string[]): string[] {\n  return [...new Set(values)]\n}\n\nfunction nextGeometricTarget (value: number): number {\n  return Math.min(Number.MAX_SAFE_INTEGER, value * 2)\n}\n\nexport function additionalFundingTarget (error: WERR_INSUFFICIENT_FUNDS): number {\n  return error.moreSatoshisNeeded\n}\n\nexport function fundingRunwayExtension (\n  runwayTarget: number,\n  ewmaConfirmedInputs: number,\n  ewmaConfirmedSatoshis: number,\n  availableConfirmed: Array<{ satoshis: number }>\n): { nextRunwayTarget: number, requestedOutputs: number, targetSatoshis: number } | undefined {\n  const availableConfirmedCount = availableConfirmed.length\n  const availableConfirmedSatoshis = availableConfirmed\n    .reduce((sum, output) => sum + output.satoshis, 0)\n  const predictedByInputs = availableConfirmedCount / Math.max(1, ewmaConfirmedInputs)\n  const predictedBySatoshis = ewmaConfirmedSatoshis > 0\n    ? availableConfirmedSatoshis / ewmaConfirmedSatoshis\n    : Number.POSITIVE_INFINITY\n  if (Math.min(predictedByInputs, predictedBySatoshis) >= 2) return undefined\n  const nextRunwayTarget = nextGeometricTarget(runwayTarget)\n  return {\n    nextRunwayTarget,\n    requestedOutputs: Math.max(\n      1,\n      Math.ceil(nextRunwayTarget * ewmaConfirmedInputs) - availableConfirmedCount\n    ),\n    targetSatoshis: Math.max(\n      1,\n      nextRunwayTarget * ewmaConfirmedSatoshis - availableConfirmedSatoshis\n    )\n  }\n}\n\nfunction makePlannerState (\n  begin: BeginActionBatchResult,\n  firstAction: Validation.ValidCreateActionArgs\n): ActionBatchPlannerState {\n  const sharedBeef = new Beef()\n  if (begin.inputBeef != null) sharedBeef.mergeBeef(begin.inputBeef)\n  if (firstAction.inputBEEF != null) sharedBeef.mergeBeef(firstAction.inputBEEF)\n  for (const output of [...begin.reservedOutputs, ...begin.explicitOutputs]) {\n    if (output.sourceTransaction != null) sharedBeef.mergeRawTx(output.sourceTransaction)\n  }\n  const state: ActionBatchPlannerState = {\n    begin,\n    sharedBeef,\n    reserved: new Map(),\n    explicit: new Map(),\n    staged: new Map(),\n    discardedStagedTxids: new Set(),\n    consumed: new Set(),\n    estimatedChangeCount: begin.availableChangeCount\n  }\n  addPlannerOutputs(state.reserved, begin.reservedOutputs, begin.changeBasket.name)\n  addPlannerOutputs(state.explicit, begin.explicitOutputs)\n  return state\n}\n\nclass ActionBatchWorkspace {\n  readonly batchId: string\n  readonly state: ActionBatchPlannerState\n  readonly planned = new Map<string, PendingBatchPlan>()\n  readonly actions: ActionBatchCommitAction[] = []\n  readonly lockingScripts = new Map<string, string>()\n\n  private ewmaConfirmedInputs = 1\n  private ewmaConfirmedSatoshis = 0\n  private hasConfirmedSample = false\n  private runwayTarget = 4\n  private extension?: Promise<void>\n  private renewal?: Promise<void>\n  private expiresAt: number\n  private committed = false\n  private eagerEnabled = false\n  private eagerLogicalBytes = 0\n  private readonly eagerPending = new Map<string, Uint8Array>()\n  private readonly eagerUploadLanes: Array<Promise<void>>\n  private eagerUploadCursor = 0\n\n  constructor (\n    private readonly wallet: Wallet,\n    begin: BeginActionBatchResult,\n    firstAction: Validation.ValidCreateActionArgs,\n    private readonly capabilities: NonNullable<StorageCapabilities['actionBatch']>\n  ) {\n    this.batchId = begin.batchId\n    this.state = makePlannerState(begin, firstAction)\n    this.expiresAt = Date.parse(begin.expiresAt)\n    this.eagerUploadLanes = Array.from(\n      {\n        length: capabilities.packedUploads == null\n          ? 1\n          : Math.max(1, capabilities.maxConcurrentUploads)\n      },\n      async () => {}\n    )\n  }\n\n  private get usesCompactManifest (): boolean {\n    return this.capabilities.manifestVersion === 2\n  }\n\n  private get packedUploads (): NonNullable<typeof this.capabilities.packedUploads> | undefined {\n    return this.capabilities.packedUploads?.version === 1\n      ? this.capabilities.packedUploads\n      : undefined\n  }\n\n  ownsReference (reference: string): boolean {\n    if (this.planned.has(reference)) return true\n    if (this.actions.some(action => action.reference === reference || action.txid === reference)) return true\n    return Object.entries(this.wallet.pendingSignActions)\n      .some(([pendingReference, pending]) =>\n        this.planned.has(pendingReference) && pending.tx.id('hex') === reference\n      )\n  }\n\n  get isEmpty (): boolean {\n    return this.planned.size === 0 && this.actions.length === 0\n  }\n\n  overlayListActions (\n    persisted: ListActionsResult,\n    args: Validation.ValidListActionsArgs\n  ): ListActionsResult {\n    if (args.labels.includes(specOpFailedActions)) return persisted\n    const controlLabels = new Set(args.labels.includes(specOpNoSendActions) ? ['abort'] : [])\n    const ordinaryLabels = args.labels.filter(label => !isListActionsSpecOp(label) && !controlLabels.has(label))\n    const staged = this.actions\n      .filter(action => {\n        if (ordinaryLabels.length === 0) return true\n        const matches = ordinaryLabels.filter(label => action.metadata.labels.includes(label)).length\n        return args.labelQueryMode === 'all' ? matches === ordinaryLabels.length : matches > 0\n      })\n      .map(action => {\n        const tx = this.state.sharedBeef.findTxid(action.txid)?.tx\n        if (tx == null) throw new WERR_INVALID_OPERATION(`missing staged transaction ${action.txid}`)\n        const managedInputSatoshis = action.plan.inputs\n          .filter(input => input.vin >= action.metadata.inputs.length)\n          .reduce((sum, input) => sum + input.sourceSatoshis, 0)\n        const changeOutputSatoshis = action.plan.outputs\n          .filter(output => output.purpose === 'change')\n          .reduce((sum, output) => sum + output.satoshis, 0)\n        return {\n          txid: action.txid,\n          satoshis: changeOutputSatoshis - managedInputSatoshis,\n          status: 'nosend' as const,\n          isOutgoing: true,\n          description: action.metadata.description,\n          labels: args.includeLabels ? action.metadata.labels : undefined,\n          version: tx.version,\n          lockTime: tx.lockTime,\n          inputs: args.includeInputs\n            ? action.plan.inputs.map(input => ({\n                sourceOutpoint: `${input.sourceTxid}.${input.sourceVout}`,\n                sourceSatoshis: input.sourceSatoshis,\n                sourceLockingScript: args.includeInputSourceLockingScripts\n                  ? asString(plannerInputLockingScript(this.state, input))\n                  : undefined,\n                unlockingScript: args.includeInputUnlockingScripts\n                  ? tx.inputs[input.vin]?.unlockingScript?.toHex()\n                  : undefined,\n                inputDescription: input.spendingDescription ?? '',\n                sequenceNumber: tx.inputs[input.vin]?.sequence ?? 0\n              }))\n            : undefined,\n          outputs: args.includeOutputs\n            ? action.plan.outputs.map(output => ({\n                satoshis: output.satoshis,\n                lockingScript: args.includeOutputLockingScripts\n                  ? tx.outputs[output.vout]?.lockingScript.toHex()\n                  : undefined,\n                spendable: output.purpose !== 'storage-commission',\n                customInstructions: undefined,\n                tags: output.tags,\n                outputIndex: output.vout,\n                outputDescription: output.outputDescription,\n                basket: output.basket ?? ''\n              }))\n            : undefined\n        }\n      })\n    const actions = [...persisted.actions, ...staged]\n    return {\n      totalActions: persisted.totalActions + staged.length,\n      actions: actions.slice(args.offset, args.offset + args.limit)\n    }\n  }\n\n  overlayListOutputs (\n    persisted: ListOutputsResult,\n    args: Validation.ValidListOutputsArgs\n  ): ListOutputsResult {\n    const isBalance = args.basket === specOpWalletBalance || args.tags.includes(specOpWalletBalance)\n    const managedOnly = args.basket === specOpWalletManagedUtxos || isBalance\n    const consumed = this.state.consumed\n    const stagedLabels = new Map(this.actions.map(action => [action.txid, action.metadata.labels]))\n    const staged = [...this.state.staged.entries()]\n      .filter(([outpoint, output]) => {\n        if (consumed.has(outpoint)) return false\n        if (managedOnly) return output.change\n        if (output.basketName !== args.basket) return false\n        const tags = output.tags ?? []\n        if (args.tags.length === 0) return true\n        const matches = args.tags.filter(tag => tags.includes(tag)).length\n        return args.tagQueryMode === 'all' ? matches === args.tags.length : matches > 0\n      })\n      .map(([outpoint, output]) => ({\n        satoshis: output.satoshis,\n        lockingScript: args.includeLockingScripts\n          ? asString(plannerOutputLockingScript(this.state, output))\n          : undefined,\n        spendable: true,\n        customInstructions: args.includeCustomInstructions ? output.customInstructions : undefined,\n        tags: args.includeTags ? output.tags ?? [] : undefined,\n        outpoint,\n        labels: args.includeLabels && output.txid != null ? stagedLabels.get(output.txid) ?? [] : undefined\n      }))\n\n    if (isBalance) {\n      const consumedConfirmed = [...this.state.reserved.entries()]\n        .filter(([outpoint]) => consumed.has(outpoint))\n        .reduce((sum, [, output]) => sum + output.satoshis, 0)\n      return {\n        totalOutputs: persisted.totalOutputs - consumedConfirmed + staged.reduce((sum, output) => sum + output.satoshis, 0),\n        outputs: []\n      }\n    }\n\n    const persistedUnconsumed = persisted.outputs.filter(output => !consumed.has(output.outpoint))\n    const outputs = [\n      ...persistedUnconsumed,\n      ...staged\n    ]\n    const ordered = args.offset < 0 ? [...outputs].reverse() : outputs\n    const offset = args.offset < 0 ? Math.max(0, -args.offset - 1) : args.offset\n    const result: ListOutputsResult = {\n      totalOutputs: persisted.totalOutputs - (persisted.outputs.length - persistedUnconsumed.length) + staged.length,\n      outputs: ordered.slice(offset, offset + args.limit)\n    }\n    if (args.includeTransactions) {\n      const beef = new Beef()\n      if (persisted.BEEF != null) beef.mergeBeef(persisted.BEEF)\n      beef.mergeBeef(this.state.sharedBeef)\n      for (const txid of args.knownTxids) if (beef.findTxid(txid) != null) beef.makeTxidOnly(txid)\n      result.BEEF = beef.toUint8Array()\n    }\n    return result\n  }\n\n  private mergeExtension (\n    extension: {\n      reservedOutputs: BeginActionBatchResult['reservedOutputs']\n      explicitOutputs: BeginActionBatchResult['explicitOutputs']\n      inputBeef?: number[] | Uint8Array\n    }\n  ): void {\n    for (const output of [...extension.reservedOutputs, ...extension.explicitOutputs]) {\n      if (output.sourceTransaction != null) {\n        this.state.sharedBeef.mergeRawTx(output.sourceTransaction)\n      }\n    }\n    addPlannerOutputs(this.state.reserved, extension.reservedOutputs, this.state.begin.changeBasket.name)\n    addPlannerOutputs(this.state.explicit, extension.explicitOutputs)\n    if (extension.inputBeef != null) {\n      this.state.sharedBeef.mergeBeef(extension.inputBeef)\n    }\n  }\n\n  private missingExplicitOutpoints (args: Validation.ValidCreateActionArgs): Array<{ txid: string, vout: number }> {\n    return [...args.inputs.map(input => input.outpoint), ...args.options.noSendChange]\n      .filter(outpoint => {\n        const key = `${outpoint.txid}.${outpoint.vout}`\n        return !this.state.staged.has(key) && !this.state.explicit.has(key) &&\n          !this.state.reserved.has(key) && (this.state.discardedStagedTxids.has(outpoint.txid) ||\n            this.state.sharedBeef.findTxid(outpoint.txid)?.tx == null)\n      })\n  }\n\n  private async extend (\n    targetSatoshis: number,\n    requestedOutputs: number,\n    explicitOutpoints: Array<{ txid: string, vout: number }>,\n    includeSourceTransactions: boolean\n  ): Promise<{ outputCount: number, satoshis: number }> {\n    const extension = await this.wallet.storage.extendActionBatch({\n      batchId: this.batchId,\n      targetSatoshis: Math.max(1, Math.ceil(targetSatoshis)),\n      requestedOutputs: Math.max(1, Math.ceil(requestedOutputs)),\n      explicitOutpoints,\n      includeSourceTransactions\n    })\n    this.mergeExtension(extension)\n    this.expiresAt = Date.parse(extension.expiresAt)\n    return {\n      outputCount: extension.reservedOutputs.length,\n      satoshis: extension.reservedOutputs.reduce((sum, output) => sum + output.satoshis, 0)\n    }\n  }\n\n  private async renewIfNeeded (): Promise<void> {\n    if (Date.now() >= this.expiresAt) return\n    const renewAt = this.expiresAt - this.capabilities.leaseMs * 0.2\n    if (Date.now() < renewAt) return\n    this.renewal ??= this.wallet.storage.renewActionBatch(this.batchId)\n      .then(result => { this.expiresAt = Date.parse(result.expiresAt) })\n      .finally(() => { this.renewal = undefined })\n    await this.renewal\n  }\n\n  async plan (args: Validation.ValidCreateActionArgs): Promise<StorageCreateActionResult> {\n    if (this.committed) throw new WERR_INVALID_OPERATION('action batch is already committed')\n    await this.renewIfNeeded()\n    if (this.extension != null) await this.extension\n    if (args.inputBEEF != null) {\n      this.state.sharedBeef.mergeBeef(args.inputBEEF)\n    }\n    const missing = this.missingExplicitOutpoints(args)\n    if (missing.length > 0) await this.extend(1, 1, missing, args.isSignAction)\n\n    let planned: ActionBatchPlannedAction | undefined\n    let requestedOutputs = 8\n    for (;;) {\n      try {\n        planned = await planAction(this.state, args)\n        break\n      } catch (error) {\n        if (!(error instanceof WERR_INSUFFICIENT_FUNDS)) throw error\n        // generateChangeSdk has already credited every unconsumed reservation\n        // supplied by planFunding. Only the reported shortfall is additional;\n        // requesting totalSatoshisNeeded here double-counts the held pool.\n        const target = additionalFundingTarget(error)\n        const added = await this.extend(target, requestedOutputs, [], args.isSignAction)\n        if (added.outputCount === 0 || added.satoshis === 0) throw error\n        requestedOutputs = nextGeometricTarget(requestedOutputs)\n      }\n    }\n    if (planned == null) throw new WERR_INVALID_OPERATION('unable to plan action batch transaction')\n    this.planned.set(planned.dcr.reference, { args, planned })\n    return planned.dcr\n  }\n\n  private updateEwma (plan: PendingBatchPlan): void {\n    const confirmed = plan.planned.consumedOutpoints\n      .map(outpoint => this.state.reserved.get(outpoint))\n      .filter((output): output is NonNullable<typeof output> => output != null)\n    if (confirmed.length === 0) return\n    const satoshis = confirmed.reduce((sum, output) => sum + output.satoshis, 0)\n    if (!this.hasConfirmedSample) {\n      this.ewmaConfirmedInputs = confirmed.length\n      this.ewmaConfirmedSatoshis = satoshis\n      this.hasConfirmedSample = true\n      return\n    }\n    this.ewmaConfirmedInputs = 0.5 * confirmed.length + 0.5 * this.ewmaConfirmedInputs\n    this.ewmaConfirmedSatoshis = 0.5 * satoshis + 0.5 * this.ewmaConfirmedSatoshis\n  }\n\n  stage (prior: PendingSignAction, processArgs: Validation.ValidProcessActionArgs): void {\n    if (this.actions.some(action => action.reference === prior.reference)) return\n    const pending = this.planned.get(prior.reference)\n    if (pending == null) throw new WERR_INVALID_OPERATION('signed action does not belong to active action batch')\n    const txid = prior.tx.id('hex')\n    const rawTx = prior.tx.toUint8Array()\n    const rawTxDigest = actionBatchBlobDigest(rawTx)\n    const lockingScriptDigests = prior.dcr.outputs.map(output => {\n      const lockingScript = prior.tx.outputs[output.vout]?.lockingScript.toHex()\n      if (lockingScript == null) {\n        throw new WERR_INVALID_OPERATION(`missing staged output script for ${txid}.${String(output.vout)}`)\n      }\n      if (lockingScript.length === 0 && !this.usesCompactManifest) return undefined\n      const digest = actionBatchBlobDigest(asUint8Array(lockingScript))\n      if (!this.usesCompactManifest) this.lockingScripts.set(digest, lockingScript)\n      return digest\n    })\n    const compactPlan: ActionBatchCommitPlan = {\n      ...prior.dcr,\n      inputBeef: undefined,\n      inputs: prior.dcr.inputs.map(input => ({\n        ...input,\n        sourceLockingScript: this.usesCompactManifest ? undefined : input.sourceLockingScript,\n        sourceTransaction: undefined\n      })),\n      outputs: prior.dcr.outputs.map(output => ({ ...output, lockingScript: '' }))\n    }\n    const action: ActionBatchCommitAction = {\n      reference: prior.reference,\n      txid,\n      rawTxDigest,\n      lockingScriptDigests,\n      deriveLockingScripts: this.usesCompactManifest || undefined,\n      plan: compactPlan,\n      metadata: {\n        description: pending.args.description,\n        labels: pending.args.labels,\n        isNoSend: processArgs.isNoSend,\n        isDelayed: processArgs.isDelayed,\n        inputs: pending.args.inputs,\n        outputs: pending.args.outputs.map(output => ({ ...output, lockingScript: '' }))\n      },\n      commissionKeyOffset: pending.planned.commissionKeyOffset\n    }\n    this.actions.push(action)\n    this.updateEwma(pending)\n    stageTransactionOutputs(this.state, prior.tx, prior.dcr)\n    mergePlannerBeef(this.state, prior.tx)\n    this.queueEagerLogicalBlob(rawTxDigest, rawTx)\n    this.planned.delete(prior.reference)\n    this.scheduleExtensionIfNeeded()\n  }\n\n  private physicalBlobs (\n    logicalDigest: string,\n    bytes: Uint8Array\n  ): { chunks?: string[], blobs: UploadBlob[] } {\n    const packed = this.packedUploads\n    const maxPhysicalBytes = packed == null\n      ? this.capabilities.maxBlobBytes\n      : Math.min(\n          this.capabilities.maxBlobBytes,\n          Math.max(1, packed.maxPackBytes - actionBatchPackLength([{\n            digest: logicalDigest,\n            bytes: new Uint8Array()\n          }]))\n        )\n    if (bytes.length <= maxPhysicalBytes) {\n      return { blobs: [{ digest: logicalDigest, bytes }] }\n    }\n    const chunks: string[] = []\n    const blobs: UploadBlob[] = []\n    for (let offset = 0; offset < bytes.length; offset += maxPhysicalBytes) {\n      const chunk = bytes.subarray(offset, Math.min(bytes.length, offset + maxPhysicalBytes))\n      const digest = actionBatchBlobDigest(chunk)\n      chunks.push(digest)\n      blobs.push({ digest, bytes: chunk })\n    }\n    return { chunks, blobs }\n  }\n\n  private queueEagerLogicalBlob (digest: string, bytes: Uint8Array): void {\n    const packed = this.packedUploads\n    if (packed?.eager !== true || !this.usesCompactManifest) return\n    const physical = this.physicalBlobs(digest, bytes)\n    for (const blob of physical.blobs) {\n      if (this.eagerPending.has(blob.digest)) continue\n      this.eagerPending.set(blob.digest, blob.bytes)\n      this.eagerLogicalBytes += blob.bytes.length\n    }\n    if (this.eagerLogicalBytes > this.capabilities.maxInlineBytes) {\n      this.eagerEnabled = true\n      this.flushEagerPacks(false)\n    }\n  }\n\n  private takePack (final: boolean): UploadBlob[] {\n    const packed = this.packedUploads\n    if (packed == null || this.eagerPending.size === 0) return []\n    const items: UploadBlob[] = []\n    for (const [digest, bytes] of this.eagerPending) {\n      const candidate = [...items, { digest, bytes }]\n      if (candidate.length > packed.maxItems ||\n        actionBatchPackLength(candidate) > packed.maxPackBytes) break\n      items.push({ digest, bytes })\n    }\n    if (items.length === 0) throw new WERR_INVALID_OPERATION('action batch blob cannot fit provider pack')\n    const length = actionBatchPackLength(items)\n    if (!final && items.length === this.eagerPending.size &&\n      length < Math.floor(packed.maxPackBytes * 0.9)) return []\n    for (const item of items) this.eagerPending.delete(item.digest)\n    return items\n  }\n\n  private schedulePackUpload (items: UploadBlob[]): void {\n    const packed = this.packedUploads\n    if (packed == null || items.length === 0) return\n    const lane = this.eagerUploadCursor++ % this.eagerUploadLanes.length\n    this.eagerUploadLanes[lane] = this.eagerUploadLanes[lane]\n      .then(async () => {\n        await this.wallet.storage.putActionBatchPack({\n          batchId: this.batchId,\n          items,\n          maxPackBytes: packed.maxPackBytes,\n          maxItems: packed.maxItems,\n          preferredEncodings: packed.encodings\n        })\n      })\n      .catch(() => {\n        // Eager upload is speculative. Prepare remains the source of truth:\n        // anything this attempt did not persist is reported missing and\n        // retried through the ordinary final upload path.\n      })\n  }\n\n  private async awaitEagerUploads (): Promise<void> {\n    await Promise.all(this.eagerUploadLanes)\n  }\n\n  private flushEagerPacks (final: boolean): void {\n    if (!this.eagerEnabled) return\n    for (;;) {\n      const items = this.takePack(final)\n      if (items.length === 0) return\n      this.schedulePackUpload(items)\n    }\n  }\n\n  private scheduleExtensionIfNeeded (): void {\n    if (this.extension != null) return\n    const availableConfirmed = [...this.state.reserved.entries()]\n      .filter(([outpoint]) => !this.state.consumed.has(outpoint))\n    const request = fundingRunwayExtension(\n      this.runwayTarget,\n      this.ewmaConfirmedInputs,\n      this.ewmaConfirmedSatoshis,\n      availableConfirmed.map(([, output]) => output)\n    )\n    if (request == null) return\n    this.extension = this.extend(request.targetSatoshis, request.requestedOutputs, [], false)\n      .then(added => {\n        // A failed or partial extension must not geometrically inflate the\n        // next request against a runway that the wallet never acquired.\n        if (\n          added.outputCount >= request.requestedOutputs &&\n          added.satoshis >= request.targetSatoshis\n        ) {\n          this.runwayTarget = request.nextRunwayTarget\n        }\n      })\n      .catch(() => {})\n      .finally(() => { this.extension = undefined })\n  }\n\n  private addLockingScriptBlobs (blobs: Map<string, Uint8Array>): void {\n    if (this.usesCompactManifest) return\n    for (const [digest, script] of this.lockingScripts) {\n      if (!blobs.has(digest)) blobs.set(digest, asUint8Array(script))\n    }\n  }\n\n  private preparePhysicalUploads (\n    blobs: Map<string, Uint8Array>\n  ): { uploadBlobs: Map<string, Uint8Array>; blobChunks: Record<string, string[]> } {\n    const uploadBlobs = new Map<string, Uint8Array>()\n    const blobChunks: Record<string, string[]> = {}\n    for (const [digest, bytes] of blobs) {\n      const physical = this.physicalBlobs(digest, bytes)\n      for (const blob of physical.blobs) {\n        if (!uploadBlobs.has(blob.digest)) uploadBlobs.set(blob.digest, blob.bytes)\n      }\n      if (physical.chunks != null) blobChunks[digest] = physical.chunks\n    }\n    return { uploadBlobs, blobChunks }\n  }\n\n  private buildManifest (sendWith: string[], isDelayed: boolean): { manifest: ActionBatchManifest, uploads: UploadBlob[] } {\n    const stagedTxids = new Set(this.actions.map(action => action.txid))\n    const externalTxids = this.actions.flatMap(action => action.plan.inputs)\n      .map(input => input.sourceTxid)\n      .filter(txid => !stagedTxids.has(txid))\n    const dependencyBytes = beefForTxids(this.state.sharedBeef, externalTxids).toUint8Array()\n    const rawBytes = this.actions.map(action => {\n      const tx = this.state.sharedBeef.findTxid(action.txid)?.tx\n      if (tx == null) throw new WERR_INVALID_OPERATION(`missing staged transaction ${action.txid}`)\n      return tx.toUint8Array()\n    })\n    const blobs = new Map<string, Uint8Array>()\n    const addBlob = (bytes: Uint8Array): string => {\n      const digest = actionBatchBlobDigest(bytes)\n      if (!blobs.has(digest)) blobs.set(digest, bytes)\n      return digest\n    }\n    const actions = this.actions.map((action, index) => ({\n      ...action,\n      rawTx: undefined,\n      rawTxDigest: addBlob(rawBytes[index])\n    }))\n    const dependencyBeefDigest = addBlob(dependencyBytes)\n    this.addLockingScriptBlobs(blobs)\n    const totalBytes = [...blobs.values()].reduce((sum, bytes) => sum + bytes.length, 0)\n    const useUploads = totalBytes > this.capabilities.maxInlineBytes\n    if (useUploads) this.queueEagerLogicalBlob(dependencyBeefDigest, dependencyBytes)\n    const { uploadBlobs, blobChunks } = useUploads\n      ? this.preparePhysicalUploads(blobs)\n      : { uploadBlobs: new Map<string, Uint8Array>(), blobChunks: {} }\n    const withoutDigest: Omit<ActionBatchManifest, 'digest'> = {\n      format: this.usesCompactManifest ? 2 : undefined,\n      batchId: this.batchId,\n      actions,\n      dependencyBeefDigest,\n      inlineBlobs: useUploads\n        ? undefined\n        : Object.fromEntries(blobs),\n      blobChunks: Object.keys(blobChunks).length === 0 ? undefined : blobChunks,\n      sendWith: mergeUnique(sendWith),\n      isDelayed\n    }\n    return {\n      manifest: { ...withoutDigest, digest: actionBatchManifestDigest(withoutDigest) },\n      uploads: [...uploadBlobs].map(([digest, bytes]) => ({ digest, bytes }))\n    }\n  }\n\n  private async uploadMissing (manifest: ActionBatchManifest, uploads: UploadBlob[]): Promise<void> {\n    this.flushEagerPacks(true)\n    await this.awaitEagerUploads()\n    const prepared = await this.wallet.storage.prepareActionBatchCommit(manifest)\n    const missing = new Set(prepared.missingDigests)\n    const pending = uploads.filter(upload => missing.has(upload.digest))\n    const packed = this.packedUploads\n    if (packed != null && manifest.format === 2) {\n      const packs: UploadBlob[][] = []\n      let current: UploadBlob[] = []\n      for (const upload of pending) {\n        const candidate = [...current, upload]\n        if (current.length > 0 && (\n          candidate.length > packed.maxItems ||\n          actionBatchPackLength(candidate) > packed.maxPackBytes\n        )) {\n          packs.push(current)\n          current = []\n        }\n        current.push(upload)\n      }\n      if (current.length > 0) packs.push(current)\n      const concurrency = Math.max(1, Math.min(\n        prepared.maxConcurrentUploads,\n        this.capabilities.maxConcurrentUploads,\n        packs.length\n      ))\n      let packCursor = 0\n      await Promise.all(Array.from({ length: concurrency }, async () => {\n        for (;;) {\n          const pack = packs[packCursor++]\n          if (pack == null) return\n          await this.wallet.storage.putActionBatchPack({\n            batchId: this.batchId,\n            items: pack,\n            maxPackBytes: packed.maxPackBytes,\n            maxItems: packed.maxItems,\n            preferredEncodings: packed.encodings\n          })\n        }\n      }))\n      return\n    }\n    const concurrency = Math.max(1, Math.min(\n      prepared.maxConcurrentUploads,\n      this.capabilities.maxConcurrentUploads,\n      pending.length\n    ))\n    let cursor = 0\n    await Promise.all(Array.from({ length: concurrency }, async () => {\n      for (;;) {\n        const index = cursor++\n        if (index >= pending.length) return\n        const upload = pending[index]\n        if (upload.bytes.length > prepared.maxBlobBytes) {\n          throw new WERR_INVALID_OPERATION(`action batch blob ${upload.digest} exceeds provider limit`)\n        }\n        await this.wallet.storage.putActionBatchBlob({\n          batchId: this.batchId,\n          digest: upload.digest,\n          bytes: upload.bytes\n        })\n      }\n    }))\n  }\n\n  async commit (sendWith: string[], isDelayed: boolean): Promise<CommitActionBatchResult> {\n    if (this.extension != null) await this.extension\n    await this.renewIfNeeded()\n    if (this.planned.size > 0) throw new WERR_INVALID_OPERATION('all two-step actions must be signed before batch commit')\n    const { manifest, uploads } = this.buildManifest(sendWith, isDelayed)\n    if (uploads.length > 0) await this.uploadMissing(manifest, uploads)\n    const result = uploads.length > 0 && manifest.format === 2 && this.capabilities.commitByDigest === true\n      ? await this.wallet.storage.commitActionBatchByDigest({\n          batchId: manifest.batchId,\n          digest: manifest.digest\n        })\n      : await this.wallet.storage.commitActionBatch(manifest)\n    this.committed = true\n    return result\n  }\n\n  abortAction (referenceOrTxid: string): boolean {\n    let pendingReference: string | undefined\n    if (this.planned.has(referenceOrTxid)) {\n      pendingReference = referenceOrTxid\n    } else {\n      pendingReference = Object.entries(this.wallet.pendingSignActions)\n        .find(([reference, pending]) =>\n          this.planned.has(reference) && pending.tx.id('hex') === referenceOrTxid\n        )?.[0]\n    }\n    const actionIndex = this.actions.findIndex(action =>\n      action.reference === referenceOrTxid || action.txid === referenceOrTxid\n    )\n    const action = actionIndex < 0 ? undefined : this.actions[actionIndex]\n    const targetTxid = action?.txid ??\n      (pendingReference == null ? undefined : this.wallet.pendingSignActions[pendingReference]?.tx.id('hex'))\n    if (targetTxid != null && this.hasDependentAction(targetTxid, action?.reference ?? pendingReference)) {\n      throw new WERR_INVALID_OPERATION(\n        `cannot abort action ${referenceOrTxid} while another staged action depends on it`\n      )\n    }\n    if (action != null) {\n      this.actions.splice(actionIndex, 1)\n    } else if (pendingReference != null) {\n      this.planned.delete(pendingReference)\n      Reflect.deleteProperty(this.wallet.pendingSignActions, pendingReference)\n    } else {\n      return false\n    }\n    if (targetTxid != null) this.state.discardedStagedTxids.add(targetTxid)\n    this.rebuildStagedState()\n    return true\n  }\n\n  private hasDependentAction (txid: string, excludedReference: string | undefined): boolean {\n    if (this.actions.some(action =>\n      action.reference !== excludedReference &&\n      action.plan.inputs.some(input => input.sourceTxid === txid)\n    )) return true\n    return [...this.planned.entries()].some(([reference, pending]) =>\n      reference !== excludedReference &&\n      pending.planned.dcr.inputs.some(input => input.sourceTxid === txid)\n    )\n  }\n\n  private rebuildStagedState (): void {\n    this.state.consumed.clear()\n    this.state.staged.clear()\n    this.state.estimatedChangeCount = this.state.begin.availableChangeCount\n    this.lockingScripts.clear()\n\n    for (const action of this.actions) {\n      const tx = this.state.sharedBeef.findTxid(action.txid)?.tx\n      if (tx == null) throw new WERR_INVALID_OPERATION(`missing staged transaction ${action.txid}`)\n      for (const input of action.plan.inputs) {\n        this.state.consumed.add(`${input.sourceTxid}.${input.sourceVout}`)\n      }\n      const managedInputCount = action.plan.inputs.length - action.metadata.inputs.length\n      const changeOutputCount = action.plan.outputs.filter(output => output.purpose === 'change').length\n      this.state.estimatedChangeCount += changeOutputCount - managedInputCount\n      stageTransactionOutputs(this.state, tx, action.plan)\n      const lockingScriptDigests = action.lockingScriptDigests ?? []\n      lockingScriptDigests.forEach((digest, outputIndex) => {\n        if (digest == null) return\n        const vout = action.plan.outputs[outputIndex]?.vout\n        const script = vout == null ? undefined : tx.outputs[vout]?.lockingScript\n        if (script == null) throw new WERR_INVALID_OPERATION(`missing staged output script for ${action.txid}.${vout}`)\n        if (!this.usesCompactManifest) this.lockingScripts.set(digest, script.toHex())\n      })\n    }\n\n    for (const pending of this.planned.values()) {\n      for (const outpoint of pending.planned.consumedOutpoints) this.state.consumed.add(outpoint)\n      const managedInputCount = pending.planned.dcr.inputs.length - pending.args.inputs.length\n      const changeOutputCount = pending.planned.dcr.outputs.filter(output => output.purpose === 'change').length\n      this.state.estimatedChangeCount += changeOutputCount - managedInputCount\n    }\n  }\n\n  async abort (): Promise<void> {\n    if (this.committed) return\n    await this.awaitEagerUploads()\n    await this.wallet.storage.abortActionBatch(this.batchId)\n    for (const reference of this.planned.keys()) delete this.wallet.pendingSignActions[reference]\n  }\n}\n\nexport class ActionBatchController {\n  private workspace?: ActionBatchWorkspace\n  private readonly capabilities = new Map<string, Promise<StorageCapabilities['actionBatch'] | undefined>>()\n  private serial: Promise<void> = Promise.resolve()\n\n  constructor (private readonly wallet: Wallet, readonly mode: ActionBatchMode) {}\n\n  get hasWorkspace (): boolean { return this.workspace != null }\n\n  overlayListActions (persisted: ListActionsResult, args: Validation.ValidListActionsArgs): ListActionsResult {\n    return this.workspace?.overlayListActions(persisted, args) ?? persisted\n  }\n\n  overlayListOutputs (persisted: ListOutputsResult, args: Validation.ValidListOutputsArgs): ListOutputsResult {\n    return this.workspace?.overlayListOutputs(persisted, args) ?? persisted\n  }\n\n  private async runExclusive<T> (operation: () => Promise<T>): Promise<T> {\n    const run = this.serial.then(operation)\n    this.serial = run.then(() => {}, () => {})\n    return await run\n  }\n\n  private async negotiate (): Promise<StorageCapabilities['actionBatch'] | undefined> {\n    if (this.mode === 'legacy') return undefined\n    const activeStore = this.wallet.storage.getActiveStore()\n    let capabilities = this.capabilities.get(activeStore)\n    if (capabilities == null) {\n      capabilities = this.wallet.storage.getCapabilities()\n        .then(result => result.actionBatch?.version === 1 ? result.actionBatch : undefined)\n        .catch(() => undefined)\n      this.capabilities.set(activeStore, capabilities)\n    }\n    return await capabilities\n  }\n\n  private async begin (args: Validation.ValidCreateActionArgs): Promise<ActionBatchWorkspace | undefined> {\n    if (args.inputs.length > 8) return undefined\n    const capabilities = await this.negotiate()\n    if (capabilities == null) return undefined\n    const batchId = randomBytesBase64(24)\n    const bootstrap = actionBatchBootstrap(args, capabilities)\n    const begin = await this.wallet.storage.beginActionBatch({ ...bootstrap, batchId })\n    this.workspace = new ActionBatchWorkspace(this.wallet, begin, args, capabilities)\n    return this.workspace\n  }\n\n  async plan (args: Validation.ValidCreateActionArgs): Promise<StorageCreateActionResult | undefined> {\n    return await this.runExclusive(async () => {\n      if (!args.isNewTx) return undefined\n      let workspace = this.workspace\n      let beganWorkspace = false\n      if (workspace == null) {\n        if (!args.isNoSend) return undefined\n        workspace = await this.begin(args)\n        if (workspace == null) return undefined\n        beganWorkspace = true\n      }\n      try {\n        return await workspace.plan(args)\n      } catch (error) {\n        if (beganWorkspace) {\n          await workspace.abort()\n          this.workspace = undefined\n        }\n        throw error\n      }\n    })\n  }\n\n  async process (\n    prior: PendingSignAction | undefined,\n    args: Validation.ValidProcessActionArgs\n  ): Promise<StorageProcessActionResults | undefined> {\n    return await this.runExclusive(async () => {\n      const workspace = this.workspace\n      if (workspace == null) return undefined\n      if (prior != null && !workspace.ownsReference(prior.reference)) return undefined\n      if (prior != null) workspace.stage(prior, args)\n      const shouldCommit = args.isSendWith || (prior != null && !args.isNoSend)\n      if (!shouldCommit) return { sendWithResults: [] }\n      const sendWith = [...args.options.sendWith]\n      if (prior != null && !args.isNoSend && !sendWith.includes(prior.tx.id('hex'))) sendWith.push(prior.tx.id('hex'))\n      const result = await workspace.commit(sendWith, args.isDelayed)\n      this.workspace = undefined\n      return result\n    })\n  }\n\n  ownsReference (reference: string): boolean {\n    return this.workspace?.ownsReference(reference) ?? false\n  }\n\n  async abort (): Promise<boolean> {\n    return await this.runExclusive(async () => {\n      if (this.workspace == null) return false\n      await this.workspace.abort()\n      this.workspace = undefined\n      return true\n    })\n  }\n\n  async abortAction (referenceOrTxid: string): Promise<boolean> {\n    return await this.runExclusive(async () => {\n      const workspace = this.workspace\n      if (workspace == null) return false\n      const aborted = workspace.abortAction(referenceOrTxid)\n      if (!aborted) return false\n      if (workspace.isEmpty) {\n        await workspace.abort()\n        this.workspace = undefined\n      }\n      return true\n    })\n  }\n}\n","import {\n  AbortActionArgs,\n  AbortActionResult,\n  AcquireCertificateArgs,\n  AcquireCertificateResult,\n  AuthenticatedResult,\n  Beef,\n  BeefParty,\n  CreateActionArgs,\n  CreateActionResult,\n  CreateHmacArgs,\n  CreateHmacResult,\n  CreateSignatureArgs,\n  CreateSignatureResult,\n  DiscoverByAttributesArgs,\n  DiscoverByIdentityKeyArgs,\n  DiscoverCertificatesResult,\n  GetHeaderArgs,\n  GetHeaderResult,\n  GetHeightResult,\n  GetNetworkResult,\n  GetPublicKeyArgs,\n  GetPublicKeyResult,\n  GetVersionResult,\n  InternalizeActionArgs,\n  InternalizeActionResult,\n  ListActionsArgs,\n  ListActionsResult,\n  ListCertificatesArgs,\n  ListCertificatesResult,\n  ListOutputsArgs,\n  ListOutputsResult,\n  OriginatorDomainNameStringUnder250Bytes,\n  ProtoWallet,\n  ProveCertificateArgs,\n  ProveCertificateResult,\n  PubKeyHex,\n  RelinquishCertificateArgs,\n  RelinquishCertificateResult,\n  RelinquishOutputArgs,\n  RelinquishOutputResult,\n  RevealCounterpartyKeyLinkageArgs,\n  RevealCounterpartyKeyLinkageResult,\n  RevealSpecificKeyLinkageArgs,\n  RevealSpecificKeyLinkageResult,\n  SignActionArgs,\n  SignActionResult,\n  Transaction as BsvTransaction,\n  TrustSelf,\n  Utils,\n  VerifyHmacArgs,\n  VerifyHmacResult,\n  VerifySignatureArgs,\n  VerifySignatureResult,\n  WalletDecryptArgs,\n  WalletDecryptResult,\n  WalletEncryptArgs,\n  WalletEncryptResult,\n  WalletInterface,\n  createNonce,\n  AuthFetch,\n  verifyNonce,\n  MasterCertificate,\n  Certificate,\n  LookupResolver,\n  AtomicBEEF,\n  BEEF,\n  KeyDeriverApi,\n  Validation,\n  WalletLoggerInterface,\n  MakeWalletLogger,\n  Telemetry,\n  TelemetryConfig\n} from '@bsv/sdk'\nimport type { SpendVerifierInterface } from '@bsv/sdk'\nimport { acquireDirectCertificate } from './signer/methods/acquireDirectCertificate'\nimport { proveCertificate } from './signer/methods/proveCertificate'\nimport { createAction, CreateActionResultX } from './signer/methods/createAction'\nimport { signAction, SignActionResultX } from './signer/methods/signAction'\nimport { internalizeAction } from './signer/methods/internalizeAction'\nimport { WalletSettingsManager } from './WalletSettingsManager'\nimport { queryOverlay, transformVerifiableCertificatesWithTrust } from './utility/identityUtils'\nimport { maxPossibleSatoshis } from './storage/methods/generateChange'\nimport { WalletStorageManager } from './storage/WalletStorageManager'\nimport { Monitor } from './monitor/Monitor'\nimport { WalletSigner } from './signer/WalletSigner'\nimport { randomBytesBase64, toLookupNetworkPreset, toWalletNetwork } from './utility/utilityHelpers'\nimport { ScriptTemplateBRC29 } from './utility/ScriptTemplateBRC29'\nimport {\n  Chain,\n  KeyPair,\n  specOpFailedActions,\n  specOpInvalidChange,\n  specOpNoSendActions,\n  specOpSetWalletChangeParams,\n  specOpThrowReviewActions,\n  specOpWalletBalance,\n  specOpWalletManagedUtxos,\n  StorageIdentity,\n  WalletBalance\n} from './sdk/types'\nimport { WalletServices } from './sdk/WalletServices.interfaces'\nimport { PrivilegedKeyManager } from './sdk/PrivilegedKeyManager'\nimport { WERR_INTERNAL, WERR_INVALID_PARAMETER, WERR_NOT_IMPLEMENTED, WERR_REVIEW_ACTIONS } from './sdk/WERR_errors'\nimport { AuthId, StorageCreateActionResult, StorageInternalizeActionResult } from './sdk/WalletStorage.interfaces'\nimport { WalletError } from './sdk/WalletError'\nimport { asArray } from './utility/utilityHelpers.noBuffer'\nimport { getResultBeef } from './signer/methods/resultBeef'\nimport type { ValidListOutputsArgs } from '@bsv/sdk/wallet/validationHelpers'\nimport { ActionBatchController, ActionBatchMode } from './signer/actionBatch/ActionBatchWorkspace'\n\nfunction prepareKnownTxidsForCreateAction(wallet: Wallet, args: CreateActionArgs): void {\n  if (!wallet.autoKnownTxids || args.options?.knownTxids != null) return\n  if (!wallet.telemetry.enabled) {\n    args.options!.knownTxids = wallet.getKnownTxids(args.options?.knownTxids)\n    return\n  }\n  args.options!.knownTxids = wallet.telemetry.withSpan(\n    'wallet.create_action.prepare_known_txids',\n    {\n      component: 'wallet-toolbox',\n      carrier: args,\n      attributes: { 'beef.tx_count': wallet.beef.txs.length }\n    },\n    span => {\n      const knownTxids = wallet.getKnownTxids(args.options?.knownTxids)\n      span.end({ attributes: { 'beef.known_txid_count': knownTxids.length } })\n      return knownTxids\n    }\n  )\n}\n\n/**\n * The preferred means of constructing a `Wallet` is with a `WalletArgs` instance.\n */\n/**\n * Minimal interface the wallet uses to short-circuit identity discovery against the user's local\n * contacts before hitting the overlay. The result shape matches what `discoverByIdentityKey` /\n * `discoverByAttributes` return so callers don't have to special-case contact-sourced records.\n *\n * Implementations typically wrap `@bsv/sdk` `ContactsManager` or another on-device source. Reads\n * are expected to be very fast (single-digit ms against local SQLite is typical).\n */\nexport interface ContactSource {\n  /** Look up a contact by identity key. Return `null` (or undefined) if unknown. */\n  findByIdentityKey: (identityKey: PubKeyHex) => Promise<ContactRecord | null | undefined>\n  /** Look up contacts matching a set of attributes. May be a no-op if attribute search is unsupported. */\n  findByAttributes?: (attributes: Record<string, string> | string[]) => Promise<ContactRecord[]>\n}\n\n/**\n * What a {@link ContactSource} returns. Carries enough to synthesize a minimal trusted\n * `DiscoverCertificatesResult` without touching the overlay.\n */\nexport interface ContactRecord {\n  identityKey: PubKeyHex\n  /** Optional certificate type (e.g. xCert / discordCert) so callers can render a badge. */\n  type?: string\n  /** Optional decrypted fields. Whatever the app stored when saving the contact. */\n  decryptedFields?: Record<string, string>\n  /** Optional certifier metadata; missing trust defaults to `Infinity` (contacts override overlay trust). */\n  certifierInfo?: {\n    name?: string\n    iconUrl?: string\n    description?: string\n    trust?: number\n  }\n}\n\n/**\n * Build a {@link DiscoverCertificatesResult} from contact records so {@link Wallet.discoverByIdentityKey}\n * and {@link Wallet.discoverByAttributes} can short-circuit on a local contacts hit. The synthetic\n * certificate has `trust: Infinity` by default so downstream `transformVerifiableCertificatesWithTrust`\n * style filtering treats contacts as authoritative.\n */\nfunction synthesizeContactResult(contacts: ContactRecord[]): DiscoverCertificatesResult {\n  const certificates = contacts.map(c => ({\n    type: c.type ?? 'contact',\n    subject: c.identityKey,\n    serialNumber: '',\n    certifier: c.identityKey,\n    revocationOutpoint: '',\n    signature: '',\n    fields: {},\n    keyring: {},\n    decryptedFields: c.decryptedFields ?? {},\n    publiclyRevealedKeyring: {},\n    certifierInfo: {\n      name: c.certifierInfo?.name ?? 'Contact',\n      iconUrl: c.certifierInfo?.iconUrl ?? '',\n      description: c.certifierInfo?.description ?? 'Locally saved contact',\n      trust: c.certifierInfo?.trust ?? Number.POSITIVE_INFINITY\n    }\n  }))\n  return {\n    totalCertificates: certificates.length,\n    certificates: certificates as unknown as DiscoverCertificatesResult['certificates']\n  }\n}\n\nexport interface WalletArgs {\n  chain: Chain\n  keyDeriver: KeyDeriverApi\n  storage: WalletStorageManager\n  services?: WalletServices\n  monitor?: Monitor\n  privilegedKeyManager?: PrivilegedKeyManager\n  settingsManager?: WalletSettingsManager\n  lookupResolver?: LookupResolver\n  /**\n   * Optional contact source consulted before the overlay in `discoverByIdentityKey` /\n   * `discoverByAttributes`. When a contact matches, the overlay call is skipped entirely.\n   * Pass `forceRefresh: true` on the discover args to bypass both contacts and the overlay\n   * cache.\n   */\n  contactSource?: ContactSource\n  /**\n   * Optional. Provide a function conforming to the `MakeWalletLogger` type to enable wallet request logging.\n   *\n   * For simple requests using `Console` may be adequate, initialize with\n   * `() => Console`\n   *\n   * Aggregate tracing and control over capturing all logged output in one place:\n   * `(log?: string | WalletLoggerInterface) => new WalletLogger(log)`\n   */\n  makeLogger?: MakeWalletLogger\n  /**\n   * Internal Wallet Toolbox optimization policy. `auto` (the default)\n   * negotiates the optional action-batch storage capability; `legacy` always\n   * uses per-action storage. This does not change the BRC-100 wallet interface.\n   */\n  actionBatchMode?: ActionBatchMode\n  /**\n   * Optional high-performance script verifier used by Wallet Toolbox's\n   * internal transaction checks. This is an implementation extension and does\n   * not change the BRC-100 wallet interface.\n   */\n  scriptVerifier?: SpendVerifierInterface\n  /**\n   * Optional provider-neutral tracing shared by wallet, lookup, storage, and\n   * permission layers. Disabled unless an enabled sink is supplied.\n   */\n  telemetry?: TelemetryConfig\n}\n\nfunction isWalletSigner(args: WalletArgs | WalletSigner): args is WalletSigner {\n  return 'isWalletSigner' in args && args.isWalletSigner\n}\n\nexport class Wallet implements WalletInterface, ProtoWallet {\n  chain: Chain\n  keyDeriver: KeyDeriverApi\n  storage: WalletStorageManager\n  settingsManager: WalletSettingsManager\n  lookupResolver: LookupResolver\n\n  services?: WalletServices\n  monitor?: Monitor\n  contactSource?: ContactSource\n\n  identityKey: string\n\n  /**\n   * The wallet creates a `BeefParty` when it is created.\n   * All the Beefs that pass through the wallet are merged into this beef.\n   * Thus what it contains at any time is the union of all transactions and proof data processed.\n   * The class `BeefParty` derives from `Beef`, adding the ability to track the source of merged data.\n   *\n   * This allows it to generate beefs to send to a particular “party” (storage or the user)\n   * that includes “txid only proofs” for transactions they already know about.\n   * Over time, this allows an active wallet to drastically reduce the amount of data transmitted.\n   */\n  beef: BeefParty\n  /**\n   * If true, signableTransactions will include sourceTransaction for each input,\n   * including those that do not require signature and those that were also contained\n   * in the inputBEEF.\n   */\n  includeAllSourceTransactions: boolean = true\n  /**\n   * If true, txids that are known to the wallet's party beef do not need to be returned from storage.\n   */\n  autoKnownTxids: boolean = false\n  /**\n   * If true, beefs returned to the user may contain txidOnly transactions.\n   */\n  returnTxidOnly: boolean = false\n  trustSelf?: TrustSelf\n  userParty: string\n  proto: ProtoWallet\n  privilegedKeyManager?: PrivilegedKeyManager\n  makeLogger?: MakeWalletLogger\n\n  pendingSignActions: Record<string, PendingSignAction>\n  readonly actionBatch: ActionBatchController\n  readonly scriptVerifier?: SpendVerifierInterface\n  readonly telemetry: Telemetry\n\n  /**\n   * For repeatability testing, set to an array of random numbers from [0..1).\n   */\n  randomVals?: number[] = undefined\n\n  constructor(\n    argsOrSigner: WalletArgs | WalletSigner,\n    services?: WalletServices,\n    monitor?: Monitor,\n    privilegedKeyManager?: PrivilegedKeyManager,\n    makeLogger?: MakeWalletLogger\n  ) {\n    const args: WalletArgs = isWalletSigner(argsOrSigner)\n      ? {\n          chain: argsOrSigner.chain,\n          keyDeriver: argsOrSigner.keyDeriver,\n          storage: argsOrSigner.storage,\n          services,\n          monitor,\n          privilegedKeyManager,\n          makeLogger\n        }\n      : argsOrSigner\n\n    if (args.storage._authId.identityKey != args.keyDeriver.identityKey) {\n      throw new WERR_INVALID_PARAMETER(\n        'storage',\n        `authenticated as the same identityKey (${args.storage._authId.identityKey}) as the keyDeriver (${args.keyDeriver.identityKey}).`\n      )\n    }\n\n    this.telemetry = new Telemetry(args.telemetry)\n    this.settingsManager = args.settingsManager || new WalletSettingsManager(this)\n    this.chain = args.chain\n    this.lookupResolver =\n      args.lookupResolver ||\n      new LookupResolver({\n        networkPreset: toLookupNetworkPreset(this.chain),\n        telemetry: args.telemetry\n      })\n    this.keyDeriver = args.keyDeriver\n    this.storage = args.storage\n    this.proto = new ProtoWallet(args.keyDeriver)\n    this.services = args.services\n    this.monitor = args.monitor\n    this.privilegedKeyManager = args.privilegedKeyManager\n    this.makeLogger = args.makeLogger\n    this.contactSource = args.contactSource\n\n    this.identityKey = this.keyDeriver.identityKey\n\n    this.pendingSignActions = {}\n    this.actionBatch = new ActionBatchController(this, args.actionBatchMode ?? 'auto')\n    this.scriptVerifier = args.scriptVerifier\n\n    this.userParty = `user ${this.getClientChangeKeyPair().publicKey}`\n    this.beef = new BeefParty([this.userParty])\n    this.trustSelf = 'known'\n\n    if (this.services != null) {\n      this.storage.setServices(this.services)\n    }\n  }\n\n  async destroy(): Promise<void> {\n    await this.actionBatch.abort()\n    await this.storage.destroy()\n    if (this.privilegedKeyManager != null) this.privilegedKeyManager.destroyKey()\n  }\n\n  getClientChangeKeyPair(): KeyPair {\n    const kp: KeyPair = {\n      privateKey: this.keyDeriver.rootKey.toString(),\n      publicKey: this.keyDeriver.rootKey.toPublicKey().toString()\n    }\n    return kp\n  }\n\n  async getIdentityKey(): Promise<PubKeyHex> {\n    return (await this.getPublicKey({ identityKey: true })).publicKey\n  }\n\n  async getPublicKey(\n    args: GetPublicKeyArgs,\n    _originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<GetPublicKeyResult> {\n    if (args.privileged) {\n      if (this.privilegedKeyManager == null) {\n        throw new Error('Privileged operations require the Wallet to be configured with a privileged key manager.')\n      }\n      return await this.privilegedKeyManager.getPublicKey(args)\n    }\n    return await this.proto.getPublicKey(args)\n  }\n\n  async revealCounterpartyKeyLinkage(\n    args: RevealCounterpartyKeyLinkageArgs,\n    _originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RevealCounterpartyKeyLinkageResult> {\n    if (args.privileged) {\n      if (this.privilegedKeyManager == null) {\n        throw new Error('Privileged operations require the Wallet to be configured with a privileged key manager.')\n      }\n      return await this.privilegedKeyManager.revealCounterpartyKeyLinkage(args)\n    }\n    return await this.proto.revealCounterpartyKeyLinkage(args)\n  }\n\n  async revealSpecificKeyLinkage(\n    args: RevealSpecificKeyLinkageArgs,\n    _originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RevealSpecificKeyLinkageResult> {\n    if (args.privileged) {\n      if (this.privilegedKeyManager == null) {\n        throw new Error('Privileged operations require the Wallet to be configured with a privileged key manager.')\n      }\n      return await this.privilegedKeyManager.revealSpecificKeyLinkage(args)\n    }\n    return await this.proto.revealSpecificKeyLinkage(args)\n  }\n\n  async encrypt(\n    args: WalletEncryptArgs,\n    _originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<WalletEncryptResult> {\n    if (args.privileged) {\n      if (this.privilegedKeyManager == null) {\n        throw new Error('Privileged operations require the Wallet to be configured with a privileged key manager.')\n      }\n      return await this.privilegedKeyManager.encrypt(args)\n    }\n    return await this.proto.encrypt(args)\n  }\n\n  async decrypt(\n    args: WalletDecryptArgs,\n    _originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<WalletDecryptResult> {\n    if (args.privileged) {\n      if (this.privilegedKeyManager == null) {\n        throw new Error('Privileged operations require the Wallet to be configured with a privileged key manager.')\n      }\n      return await this.privilegedKeyManager.decrypt(args)\n    }\n    return await this.proto.decrypt(args)\n  }\n\n  async createHmac(\n    args: CreateHmacArgs,\n    _originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<CreateHmacResult> {\n    if (args.privileged) {\n      if (this.privilegedKeyManager == null) {\n        throw new Error('Privileged operations require the Wallet to be configured with a privileged key manager.')\n      }\n      return await this.privilegedKeyManager.createHmac(args)\n    }\n    return await this.proto.createHmac(args)\n  }\n\n  async verifyHmac(\n    args: VerifyHmacArgs,\n    _originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<VerifyHmacResult> {\n    if (args.privileged) {\n      if (this.privilegedKeyManager == null) {\n        throw new Error('Privileged operations require the Wallet to be configured with a privileged key manager.')\n      }\n      return await this.privilegedKeyManager.verifyHmac(args)\n    }\n    return await this.proto.verifyHmac(args)\n  }\n\n  async createSignature(\n    args: CreateSignatureArgs,\n    _originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<CreateSignatureResult> {\n    if (args.privileged) {\n      if (this.privilegedKeyManager == null) {\n        throw new Error('Privileged operations require the Wallet to be configured with a privileged key manager.')\n      }\n      return await this.privilegedKeyManager.createSignature(args)\n    }\n    return await this.proto.createSignature(args)\n  }\n\n  async verifySignature(\n    args: VerifySignatureArgs,\n    _originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<VerifySignatureResult> {\n    if (args.privileged) {\n      if (this.privilegedKeyManager == null) {\n        throw new Error('Privileged operations require the Wallet to be configured with a privileged key manager.')\n      }\n      return await this.privilegedKeyManager.verifySignature(args)\n    }\n    return await this.proto.verifySignature(args)\n  }\n\n  getServices(): WalletServices {\n    if (this.services == null) {\n      throw new WERR_INVALID_PARAMETER('services', 'valid in constructor arguments to be retreived here.')\n    }\n    return this.services\n  }\n\n  /**\n   * @returns the full list of txids whose validity this wallet claims to know.\n   *\n   * @param newKnownTxids Optional. Additional new txids known to be valid by the caller to be merged.\n   */\n  getKnownTxids(newKnownTxids?: string[]): string[] {\n    if (newKnownTxids != null) {\n      for (const txid of newKnownTxids) this.beef.mergeTxidOnly(txid)\n    }\n    const r = this.beef.sortTxs()\n    const knownTxids = r.valid\n    return knownTxids\n  }\n\n  getStorageIdentity(): StorageIdentity {\n    const s = this.storage.getSettings()\n    return {\n      storageIdentityKey: s.storageIdentityKey,\n      storageName: s.storageName\n    }\n  }\n\n  private validateAuthAndArgs<A, T extends Validation.ValidWalletSignerArgs>(\n    args: A,\n    validate: (args: A, logger?: WalletLoggerInterface) => T,\n    logger?: WalletLoggerInterface\n  ): { vargs: T; auth: AuthId } {\n    if (!this.telemetry.enabled || typeof args !== 'object' || args == null) {\n      const vargs = validate(args, logger)\n      const auth: AuthId = { identityKey: this.identityKey }\n      return { vargs, auth }\n    }\n\n    const span = this.telemetry.startSpan('wallet.validate_args', {\n      component: 'wallet-toolbox',\n      carrier: args\n    })\n    try {\n      const vargs = validate(args, logger)\n      if (typeof vargs === 'object' && vargs != null) {\n        this.telemetry.bindContext(vargs, span.context)\n      }\n      const auth: AuthId = { identityKey: this.identityKey }\n      span.end({ attributes: { 'validation.result': 'ok' } })\n      return { vargs, auth }\n    } catch (error) {\n      span.end({\n        status: 'error',\n        error,\n        attributes: { 'validation.result': 'rejected' }\n      })\n      throw error\n    }\n  }\n\n  /// ///////////////\n  // List Methods\n  /// ///////////////\n\n  async listActions(\n    args: ListActionsArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ListActionsResult> {\n    Validation.validateOriginator(originator)\n    const { vargs } = this.validateAuthAndArgs(args, Validation.validateListActionsArgs)\n    const storageArgs = this.actionBatch.hasWorkspace ? { ...vargs, limit: 10000, offset: 0 } : vargs\n    const r = this.actionBatch.overlayListActions(await this.storage.listActions(storageArgs), vargs)\n    // Implement security policy to block customInstructions from output results.\n    for (const action of r.actions) {\n      if (action.outputs != null) {\n        for (const output of action.outputs) {\n          output.customInstructions = undefined\n        }\n      }\n    }\n    return r\n  }\n\n  get storageParty(): string {\n    return `storage ${this.getStorageIdentity().storageIdentityKey}`\n  }\n\n  async listOutputs(\n    args: ListOutputsArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ListOutputsResult> {\n    Validation.validateOriginator(originator)\n    const { vargs } = this.validateAuthAndArgs(args, validateListOutputsArgs)\n    if (this.autoKnownTxids && !vargs.knownTxids) {\n      vargs.knownTxids = this.getKnownTxids()\n    }\n    const storageArgs =\n      this.actionBatch.hasWorkspace && vargs.basket !== specOpWalletBalance && !vargs.tags.includes(specOpWalletBalance)\n        ? { ...vargs, limit: 10000, offset: 0 }\n        : vargs\n    const r = this.actionBatch.overlayListOutputs(await this.storage.listOutputs(storageArgs), vargs)\n    if (r.BEEF != null) {\n      this.beef.mergeBeefFromParty(this.storageParty, asArray(r.BEEF))\n      r.BEEF = this.verifyReturnedTxidOnlyBEEF(r.BEEF)\n    }\n    return r\n  }\n\n  async listCertificates(\n    args: ListCertificatesArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ListCertificatesResult> {\n    Validation.validateOriginator(originator)\n    const { vargs } = this.validateAuthAndArgs(args, Validation.validateListCertificatesArgs)\n    const r = await this.storage.listCertificates(vargs)\n    return r\n  }\n\n  /// ///////////////\n  // Certificates\n  /// ///////////////\n\n  private async acquireDirectCertificateProtocol(args: AcquireCertificateArgs): Promise<AcquireCertificateResult> {\n    const { auth, vargs } = this.validateAuthAndArgs(args, Validation.validateAcquireDirectCertificateArgs)\n    vargs.subject = (\n      await this.getPublicKey({\n        identityKey: true,\n        privileged: args.privileged,\n        privilegedReason: args.privilegedReason\n      })\n    ).publicKey\n    try {\n      const certificate = new MasterCertificate(\n        vargs.type,\n        vargs.serialNumber,\n        vargs.subject,\n        vargs.certifier,\n        vargs.revocationOutpoint,\n        vargs.fields,\n        vargs.keyringForSubject,\n        vargs.signature\n      )\n      await certificate.verify()\n      await MasterCertificate.decryptFields(\n        this,\n        vargs.keyringForSubject,\n        vargs.fields,\n        vargs.certifier,\n        vargs.privileged,\n        vargs.privilegedReason\n      )\n    } catch (error_: unknown) {\n      const error = WalletError.fromUnknown(error_)\n      throw new WERR_INVALID_PARAMETER(\n        'args',\n        `valid encrypted and signed certificate and keyring from revealer. ${error.name}: ${error.message}`\n      )\n    }\n    return await acquireDirectCertificate(this, auth, vargs)\n  }\n\n  private validateIssuedCertificateFields(certificate: Certificate, expectedFields: Record<string, string>): void {\n    if (Object.keys(certificate.fields).length !== Object.keys(expectedFields).length) {\n      throw new Error('Fields mismatch! Objects have different numbers of keys.')\n    }\n    for (const field of Object.keys(expectedFields)) {\n      if (!(field in certificate.fields)) {\n        throw new Error(`Missing field: ${field} in certificate.fields`)\n      }\n      if (certificate.fields[field] !== expectedFields[field]) {\n        throw new Error(`Invalid field! Expected: ${expectedFields[field]}, Received: ${certificate.fields[field]}`)\n      }\n    }\n  }\n\n  private validateIssuedCertificate(\n    certificate: Certificate,\n    vargs: Validation.ValidAcquireIssuanceCertificateArgs,\n    expectedFields: Record<string, string>\n  ): void {\n    if (certificate.type !== vargs.type) {\n      throw new Error(`Invalid certificate type! Expected: ${vargs.type}, Received: ${certificate.type}`)\n    }\n    if (certificate.subject !== this.identityKey) {\n      throw new Error(`Invalid certificate subject! Expected: ${this.identityKey}, Received: ${certificate.subject}`)\n    }\n    if (certificate.certifier !== vargs.certifier) {\n      throw new Error(`Invalid certifier! Expected: ${vargs.certifier}, Received: ${certificate.certifier}`)\n    }\n    if (!certificate.revocationOutpoint) {\n      throw new Error('Invalid revocationOutpoint!')\n    }\n    this.validateIssuedCertificateFields(certificate, expectedFields)\n  }\n\n  private async acquireIssuedCertificateProtocol(args: AcquireCertificateArgs): Promise<AcquireCertificateResult> {\n    const { auth, vargs } = this.validateAuthAndArgs(args, Validation.validateAcquireIssuanceCertificateArgs)\n    const clientNonce = await createNonce(this, vargs.certifier)\n    const authClient = new AuthFetch(this)\n    const { certificateFields, masterKeyring } = await MasterCertificate.createCertificateFields(\n      this,\n      vargs.certifier,\n      vargs.fields\n    )\n    const response = await authClient.fetch(`${vargs.certifierUrl}/signCertificate`, {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({\n        clientNonce,\n        type: vargs.type,\n        fields: certificateFields,\n        masterKeyring\n      })\n    })\n    const responseIdentity = response.headers.get('x-bsv-auth-identity-key')\n    if (responseIdentity !== vargs.certifier) {\n      throw new Error(`Invalid certifier! Expected: ${vargs.certifier}, Received: ${responseIdentity}`)\n    }\n    const { certificate, serverNonce } = await response.json()\n    if (!certificate) throw new Error('No certificate received from certifier!')\n    if (!serverNonce) throw new Error('No serverNonce received from certifier!')\n\n    const signedCertificate = new Certificate(\n      certificate.type,\n      certificate.serialNumber,\n      certificate.subject,\n      certificate.certifier,\n      certificate.revocationOutpoint,\n      certificate.fields,\n      certificate.signature\n    )\n    await verifyNonce(serverNonce, this, vargs.certifier)\n    const { valid } = await this.verifyHmac({\n      hmac: Utils.toArray(signedCertificate.serialNumber, 'base64'),\n      data: Utils.toArray(clientNonce + serverNonce, 'base64'),\n      protocolID: [2, 'certificate issuance'],\n      keyID: serverNonce + clientNonce,\n      counterparty: vargs.certifier\n    })\n    if (!valid) throw new Error('Invalid serialNumber')\n    this.validateIssuedCertificate(signedCertificate, vargs, certificateFields)\n    await signedCertificate.verify()\n    await MasterCertificate.decryptFields(this, masterKeyring, certificate.fields, vargs.certifier)\n    return await acquireDirectCertificate(this, auth, {\n      ...certificate,\n      keyringRevealer: 'certifier',\n      keyringForSubject: masterKeyring,\n      privileged: vargs.privileged\n    })\n  }\n\n  async acquireCertificate(\n    args: AcquireCertificateArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<AcquireCertificateResult> {\n    Validation.validateOriginator(originator)\n    if (args.acquisitionProtocol === 'direct') {\n      return await this.acquireDirectCertificateProtocol(args)\n    }\n    if (args.acquisitionProtocol === 'issuance') {\n      return await this.acquireIssuedCertificateProtocol(args)\n    }\n\n    throw new WERR_INVALID_PARAMETER('acquisitionProtocol', `valid.${args.acquisitionProtocol} is unrecognized.`)\n  }\n\n  async relinquishCertificate(\n    args: RelinquishCertificateArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RelinquishCertificateResult> {\n    Validation.validateOriginator(originator)\n    this.validateAuthAndArgs(args, Validation.validateRelinquishCertificateArgs)\n    await this.storage.relinquishCertificate(args)\n    return { relinquished: true }\n  }\n\n  async proveCertificate(\n    args: ProveCertificateArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ProveCertificateResult> {\n    Validation.validateOriginator(originator)\n    const { auth, vargs } = this.validateAuthAndArgs(args, Validation.validateProveCertificateArgs)\n    const r = await proveCertificate(this, auth, vargs)\n    return r\n  }\n\n  /** 2-minute cache of trust settings for identity resolution paths */\n  private _trustSettingsCache?: {\n    expiresAt: number\n    trustSettings: Awaited<ReturnType<WalletSettingsManager['get']>>['trustSettings']\n  }\n\n  /** 2-minute cache of queryOverlay() results keyed by normalized query */\n  private readonly _overlayCache: Map<string, { expiresAt: number; value: unknown }> = new Map()\n\n  async discoverByIdentityKey(\n    args: DiscoverByIdentityKeyArgs & { forceRefresh?: boolean },\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<DiscoverCertificatesResult> {\n    Validation.validateOriginator(originator)\n    this.validateAuthAndArgs(args, Validation.validateDiscoverByIdentityKeyArgs)\n\n    const TTL_MS = 2 * 60 * 1000\n    const now = Date.now()\n    const forceRefresh = args.forceRefresh === true\n\n    // --- Contacts short-circuit (sub-10 ms typical, no network) ---\n    if (!forceRefresh && this.contactSource != null) {\n      try {\n        const contact = await this.contactSource.findByIdentityKey(args.identityKey)\n        if (contact != null) {\n          return synthesizeContactResult([contact])\n        }\n      } catch {\n        // Contact source failures must never block the network path.\n      }\n    }\n\n    // --- trustSettings cache (2 minutes) ---\n    let trustSettings =\n      this._trustSettingsCache != null && this._trustSettingsCache.expiresAt > now\n        ? this._trustSettingsCache.trustSettings\n        : undefined\n\n    if (trustSettings == null) {\n      const settings = await this.settingsManager.get()\n      trustSettings = settings.trustSettings\n      this._trustSettingsCache = { trustSettings, expiresAt: now + TTL_MS }\n    }\n\n    const certifiers = trustSettings.trustedCertifiers.map(c => c.identityKey).sort((a, b) => a.localeCompare(b))\n\n    // --- queryOverlay cache (2 minutes, client-side, bounded staleness) ---\n    const cacheKey = JSON.stringify({\n      fn: 'discoverByIdentityKey',\n      identityKey: args.identityKey,\n      certifiers\n    })\n\n    let cached = forceRefresh ? undefined : this._overlayCache.get(cacheKey)\n    if (cached == null || cached.expiresAt <= now) {\n      const value = await queryOverlay({ identityKey: args.identityKey, certifiers }, this.lookupResolver)\n      cached = { value, expiresAt: now + TTL_MS }\n      this._overlayCache.set(cacheKey, cached)\n    }\n\n    if (!cached.value) {\n      return { totalCertificates: 0, certificates: [] }\n    }\n\n    return transformVerifiableCertificatesWithTrust(trustSettings, cached.value as any)\n  }\n\n  async discoverByAttributes(\n    args: DiscoverByAttributesArgs & { forceRefresh?: boolean },\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<DiscoverCertificatesResult> {\n    Validation.validateOriginator(originator)\n    this.validateAuthAndArgs(args, Validation.validateDiscoverByAttributesArgs)\n\n    const TTL_MS = 2 * 60 * 1000\n    const now = Date.now()\n    const forceRefresh = args.forceRefresh === true\n\n    // --- Contacts short-circuit (optional, only when source supports attribute search) ---\n    if (!forceRefresh && this.contactSource?.findByAttributes != null && args.attributes != null) {\n      try {\n        const matches = await this.contactSource.findByAttributes(args.attributes as Record<string, string> | string[])\n        if (Array.isArray(matches) && matches.length > 0) {\n          return synthesizeContactResult(matches)\n        }\n      } catch {\n        // Fall through to network path on contact-source failure.\n      }\n    }\n\n    // --- trustSettings cache (2 minutes) ---\n    let trustSettings =\n      this._trustSettingsCache != null && this._trustSettingsCache.expiresAt > now\n        ? this._trustSettingsCache.trustSettings\n        : undefined\n\n    if (trustSettings == null) {\n      const settings = await this.settingsManager.get()\n      trustSettings = settings.trustSettings\n      this._trustSettingsCache = { trustSettings, expiresAt: now + TTL_MS }\n    }\n\n    const certifiers = trustSettings.trustedCertifiers.map(c => c.identityKey).sort((a, b) => a.localeCompare(b))\n\n    // Normalize attributes for a stable cache key.\n    // If attributes is an object, sort its top-level keys; if it's an array, sort a shallow copy.\n    let attributesKey: unknown = args.attributes\n    if (args.attributes && typeof args.attributes === 'object') {\n      const keys = Object.keys(args.attributes as Record<string, unknown>).sort((a, b) => a.localeCompare(b))\n      attributesKey = JSON.stringify(args.attributes, keys)\n    }\n\n    // --- queryOverlay cache (2 minutes, client-side, bounded staleness) ---\n    const cacheKey = JSON.stringify({\n      fn: 'discoverByAttributes',\n      attributes: attributesKey,\n      certifiers\n    })\n\n    let cached = forceRefresh ? undefined : this._overlayCache.get(cacheKey)\n    if (cached == null || cached.expiresAt <= now) {\n      const value = await queryOverlay({ attributes: args.attributes, certifiers }, this.lookupResolver)\n      cached = { value, expiresAt: now + TTL_MS }\n      this._overlayCache.set(cacheKey, cached)\n    }\n\n    if (!cached.value) {\n      return { totalCertificates: 0, certificates: [] }\n    }\n\n    return transformVerifiableCertificatesWithTrust(trustSettings, cached.value as any)\n  }\n\n  verifyReturnedTxidOnly(beef: Beef, knownTxids?: string[]): Beef {\n    if (this.returnTxidOnly) return beef\n    const onlyTxids = beef.txs.filter(btx => btx.isTxidOnly).map(btx => btx.txid)\n    for (const txid of onlyTxids) {\n      if (knownTxids?.includes(txid)) continue\n      const tx = this.beef.findAtomicTransaction(txid)\n      if (tx == null) throw new WERR_INTERNAL(`unable to merge txid ${txid} into beef`)\n      beef.mergeTransaction(tx)\n    }\n    for (const btx of beef.txs) {\n      if (knownTxids?.includes(btx.txid)) continue\n      if (btx.isTxidOnly) throw new WERR_INTERNAL(`remaining txidOnly ${btx.txid} is not known`)\n    }\n    return beef\n  }\n\n  verifyReturnedTxidOnlyAtomicBEEF(beef: AtomicBEEF, knownTxids?: string[], parsedBeef?: Beef): AtomicBEEF {\n    if (this.returnTxidOnly) return beef\n    const b = parsedBeef ?? Beef.fromBinary(beef)\n    if (!b.atomicTxid) throw new WERR_INTERNAL()\n    const hasUnknownTxidOnly = b.txs.some(btx => btx.isTxidOnly && !knownTxids?.includes(btx.txid))\n    if (!hasUnknownTxidOnly) return beef\n    return this.verifyReturnedTxidOnly(b, knownTxids).toBinaryAtomic(b.atomicTxid)\n  }\n\n  verifyReturnedTxidOnlyBEEF(beef: BEEF): BEEF {\n    if (this.returnTxidOnly) return beef\n    const b = Beef.fromBinary(beef)\n    return this.verifyReturnedTxidOnly(b).toBinary()\n  }\n\n  logMakeLogger(method: string, args: any): WalletLoggerInterface | undefined {\n    const logger = this.makeLogger?.(args.log)\n    this.logMethodStart(method, logger)\n    return logger\n  }\n\n  logMethodStart(method: string, logger?: WalletLoggerInterface): void {\n    logger?.group(`Wallet ${method}`)\n  }\n\n  logResult(r: any, logger?: WalletLoggerInterface): void {\n    if (logger == null) return\n    logger.groupEnd()\n    r.log = logger.flush?.()\n  }\n\n  logWalletError(eu: unknown, logger?: WalletLoggerInterface): void {\n    if (logger == null) return\n    logger.error('WalletError:', WalletError.unknownToJson(eu))\n    logger.flush?.()\n  }\n\n  /// ///////////////\n  // Actions\n  /// ///////////////\n\n  async createAction(\n    args: CreateActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<CreateActionResult> {\n    const logger = this.logMakeLogger('createAction', args)\n    try {\n      Validation.validateOriginator(originator)\n\n      args.options ??= {}\n      args.options.trustSelf ||= this.trustSelf\n      prepareKnownTxidsForCreateAction(this, args)\n\n      const { auth, vargs } = this.validateAuthAndArgs(args, Validation.validateCreateActionArgs, logger)\n      logger?.log('validated args')\n\n      vargs.includeAllSourceTransactions = this.includeAllSourceTransactions\n      if (this.randomVals != null && this.randomVals.length > 1) {\n        vargs.randomVals = [...this.randomVals]\n      }\n\n      const r = await createAction(this, auth, vargs)\n      logger?.log('action created')\n\n      const resultBeef = getResultBeef(r)\n      if (r.tx != null) {\n        const merge = (): void => this.beef.mergeBeefFromParty(this.storageParty, resultBeef ?? r.tx!)\n        if (this.telemetry.enabled) {\n          this.telemetry.withSpan(\n            'wallet.create_action.merge_result_beef',\n            {\n              component: 'wallet-toolbox',\n              carrier: args,\n              attributes: {\n                'beef.retained_tx_count_before': this.beef.txs.length,\n                'beef.result_byte_count': r.tx.length\n              }\n            },\n            merge\n          )\n        } else {\n          merge()\n        }\n      }\n\n      if (r.tx != null) {\n        const verify = (): AtomicBEEF =>\n          this.verifyReturnedTxidOnlyAtomicBEEF(r.tx!, args.options?.knownTxids, resultBeef)\n        r.tx = this.telemetry.enabled\n          ? this.telemetry.withSpan(\n              'wallet.create_action.verify_result_beef',\n              {\n                component: 'wallet-toolbox',\n                carrier: args,\n                attributes: { 'beef.result_byte_count': r.tx.length }\n              },\n              verify\n            )\n          : verify()\n        logger?.log('verify returned AtomicBEEF')\n      }\n\n      if (!vargs.isDelayed) throwIfAnyUnsuccessfulCreateActions(r)\n\n      this.logResult(r, logger)\n      return r\n    } catch (error_: unknown) {\n      this.logWalletError(error_, logger)\n      throw error_\n    }\n  }\n\n  async signAction(\n    args: SignActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<SignActionResult> {\n    Validation.validateOriginator(originator)\n\n    const { auth, vargs } = this.validateAuthAndArgs(args, Validation.validateSignActionArgs)\n    const prior = this.pendingSignActions[args.reference]\n    if (!prior) {\n      throw new WERR_NOT_IMPLEMENTED('recovery of out-of-session signAction reference data is not yet implemented.')\n    }\n    // createAction options are merged with undefined signAction options before validation...\n    const r = await signAction(this, auth, args)\n\n    if (!vargs.isDelayed) throwIfAnyUnsuccessfulSignActions(r)\n\n    if (r.tx != null)\n      r.tx = this.verifyReturnedTxidOnlyAtomicBEEF(r.tx, prior.args.options?.knownTxids, getResultBeef(r))\n    delete this.pendingSignActions[args.reference]\n\n    return r\n  }\n\n  async internalizeAction(\n    args: InternalizeActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<InternalizeActionResult> {\n    Validation.validateOriginator(originator)\n    const { auth, vargs } = this.validateAuthAndArgs(args, Validation.validateInternalizeActionArgs)\n\n    if (vargs.labels.includes(specOpThrowReviewActions)) throwDummyReviewActions()\n\n    const r = await internalizeAction(this, auth, args)\n\n    throwIfUnsuccessfulInternalizeAction(r)\n\n    return r\n  }\n\n  async abortAction(\n    args: AbortActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<AbortActionResult> {\n    Validation.validateOriginator(originator)\n\n    this.validateAuthAndArgs(args, Validation.validateAbortActionArgs)\n    if (this.actionBatch.ownsReference(args.reference)) {\n      return { aborted: await this.actionBatch.abortAction(args.reference) }\n    }\n    const r = await this.storage.abortAction(args)\n    return r\n  }\n\n  async relinquishOutput(\n    args: RelinquishOutputArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RelinquishOutputResult> {\n    Validation.validateOriginator(originator)\n    this.validateAuthAndArgs(args, Validation.validateRelinquishOutputArgs)\n    await this.storage.relinquishOutput(args)\n    return { relinquished: true }\n  }\n\n  async isAuthenticated(args: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<AuthenticatedResult> {\n    Validation.validateOriginator(originator)\n    const r: { authenticated: true } = {\n      authenticated: true\n    }\n    return r\n  }\n\n  async waitForAuthentication(\n    args: {},\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<AuthenticatedResult> {\n    Validation.validateOriginator(originator)\n    return { authenticated: true }\n  }\n\n  async getHeight(args: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetHeightResult> {\n    Validation.validateOriginator(originator)\n    const height = await this.getServices().getHeight()\n    return { height }\n  }\n\n  async getHeaderForHeight(\n    args: GetHeaderArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<GetHeaderResult> {\n    Validation.validateOriginator(originator)\n    const serializedHeader = await this.getServices().getHeaderForHeight(args.height)\n    return { header: Utils.toHex(serializedHeader) }\n  }\n\n  async getNetwork(args: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetNetworkResult> {\n    Validation.validateOriginator(originator)\n    return { network: toWalletNetwork(this.chain) }\n  }\n\n  async getVersion(args: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetVersionResult> {\n    Validation.validateOriginator(originator)\n    return { version: 'wallet-brc100-1.0.0' }\n  }\n\n  /**\n   * Transfer all possible satoshis held by this wallet to `toWallet`.\n   *\n   * @param toWallet wallet which will receive this wallet's satoshis.\n   */\n  async sweepTo(toWallet: Wallet): Promise<void> {\n    const derivationPrefix = randomBytesBase64(8)\n    const derivationSuffix = randomBytesBase64(8)\n    const keyDeriver = this.keyDeriver\n\n    const t = new ScriptTemplateBRC29({\n      derivationPrefix,\n      derivationSuffix,\n      keyDeriver\n    })\n\n    const label = 'sweep'\n\n    const satoshis = maxPossibleSatoshis\n\n    const car = await this.createAction({\n      outputs: [\n        {\n          lockingScript: t.lock(keyDeriver.rootKey.toString(), toWallet.identityKey).toHex(),\n          satoshis,\n          outputDescription: label,\n          tags: ['relinquish'],\n          customInstructions: JSON.stringify({\n            derivationPrefix,\n            derivationSuffix,\n            type: 'BRC29'\n          })\n        }\n      ],\n      options: {\n        randomizeOutputs: false,\n        acceptDelayedBroadcast: false\n      },\n      labels: [label],\n      description: label\n    })\n\n    await toWallet.internalizeAction({\n      tx: car.tx!,\n      outputs: [\n        {\n          outputIndex: 0,\n          protocol: 'wallet payment',\n          paymentRemittance: {\n            derivationPrefix,\n            derivationSuffix,\n            senderIdentityKey: this.identityKey\n          }\n        }\n      ],\n      description: label,\n      labels: [label]\n    })\n  }\n\n  /**\n   * Uses `listOutputs` to iterate over chunks of up to 1000 outputs to\n   * compute the sum of output satoshis.\n   *\n   * For `default`, only wallet-managed BRC-29 change is included. Raw\n   * administrative `listOutputs({ basket: 'default' })` remains available to\n   * discover legacy incompatible rows for recovery.\n   *\n   * @param {string} basket - Optional. Defaults to 'default', the wallet change basket.\n   * @returns {WalletBalance} total sum of output satoshis and utxo details (satoshis and outpoints)\n   */\n  async balanceAndUtxos(basket: string = 'default'): Promise<WalletBalance> {\n    const r: WalletBalance = { total: 0, utxos: [] }\n    const listBasket = basket === 'default' ? specOpWalletManagedUtxos : basket\n    let offset = 0\n    for (;;) {\n      const change = await this.listOutputs({\n        basket: listBasket,\n        limit: 1000,\n        offset\n      })\n      if (change.totalOutputs === 0) break\n      for (const o of change.outputs) {\n        r.total += o.satoshis\n        r.utxos.push({ satoshis: o.satoshis, outpoint: o.outpoint })\n      }\n      offset += change.outputs.length\n    }\n    return r\n  }\n\n  /**\n   * Uses `listOutputs` special operation to compute the total value (of satoshis) for\n   * all spendable outputs in the 'default' basket.\n   *\n   * @returns {number} sum of output satoshis\n   */\n  async balance(args?: ListOutputsArgs): Promise<number> {\n    args ||= { basket: specOpWalletBalance }\n    if (args.basket !== specOpWalletBalance) {\n      args.tags = [...(args.tags || []), specOpWalletBalance]\n    }\n    const r = await this.listOutputs(args)\n    return r.totalOutputs\n  }\n\n  /**\n   * Uses `listOutputs` special operation to review the spendability via `Services` of\n   * outputs currently considered spendable. Returns the outputs that fail to verify.\n   *\n   * Ignores the `limit` and `offset` properties.\n   *\n   * @param all Defaults to false. If false, only change outputs ('default' basket) are reviewed. If true, all spendable outputs are reviewed.\n   * @param release Defaults to false. If true, sets outputs that fail to verify to un-spendable (spendable: false)\n   * @param optionalArgs Optional. Additional tags will constrain the outputs processed.\n   * @returns outputs which are/where considered spendable but currently fail to verify as spendable.\n   */\n  async reviewSpendableOutputs(\n    all = false,\n    release = false,\n    optionalArgs?: Partial<ListOutputsArgs>\n  ): Promise<ListOutputsResult> {\n    const args: ListOutputsArgs = {\n      ...optionalArgs,\n      basket: specOpInvalidChange\n    }\n    args.tags ||= []\n    if (all) args.tags.push('all')\n    if (release) args.tags.push('release')\n    const r = await this.listOutputs(args)\n    return r\n  }\n\n  /**\n   * Uses `listOutputs` special operation to update the 'default' basket's automatic\n   * change generation parameters.\n   *\n   * @param count target number of change UTXOs to maintain.\n   * @param satoshis target value for new change outputs.\n   */\n  async setWalletChangeParams(count: number, satoshis: number): Promise<void> {\n    const args: ListOutputsArgs = {\n      basket: specOpSetWalletChangeParams,\n      tags: [count.toString(), satoshis.toString()]\n    }\n    await this.listOutputs(args)\n  }\n\n  /**\n   * Uses `listActions` special operation to return only actions with status 'nosend'.\n   *\n   * @param abort Defaults to false. If true, runs `abortAction` on each 'nosend' action.\n   * @returns {ListActionsResult} start `listActions` result restricted to 'nosend' (or 'failed' if aborted) actions.\n   */\n  async listNoSendActions(args: ListActionsArgs, abort = false): Promise<ListActionsResult> {\n    const { vargs } = this.validateAuthAndArgs(args, Validation.validateListActionsArgs)\n    vargs.labels.push(specOpNoSendActions)\n    if (abort) {\n      await this.actionBatch.abort()\n      vargs.labels.push('abort')\n    }\n    return await this.listActions(vargs)\n  }\n\n  /**\n   * Uses `listActions` special operation to return only actions with status 'failed'.\n   *\n   * @param unfail Defaults to false. If true, queues the action for attempted recovery.\n   * @returns {ListActionsResult} start `listActions` result restricted to 'failed' status actions.\n   */\n  async listFailedActions(args: ListActionsArgs, unfail = false): Promise<ListActionsResult> {\n    const { vargs } = this.validateAuthAndArgs(args, Validation.validateListActionsArgs)\n    vargs.labels.push(specOpFailedActions)\n    if (unfail) vargs.labels.push('unfail')\n    const r = await this.storage.listActions(vargs)\n    return r\n  }\n}\n\nexport interface PendingStorageInput {\n  vin: number\n  derivationPrefix: string\n  derivationSuffix: string\n  unlockerPubKey?: string\n  sourceSatoshis: number\n  lockingScript: string\n}\n\nexport interface PendingSignAction {\n  reference: string\n  dcr: StorageCreateActionResult\n  args: Validation.ValidCreateActionArgs\n  tx: BsvTransaction\n  amount: number\n  pdi: PendingStorageInput[]\n}\n\nfunction throwIfAnyUnsuccessfulCreateActions(r: CreateActionResultX) {\n  const ndrs = r.notDelayedResults\n  const swrs = r.sendWithResults\n\n  if (ndrs == null || swrs == null || swrs.every(r => r.status === 'unproven')) return\n\n  throw new WERR_REVIEW_ACTIONS(ndrs, swrs, r.txid, r.tx, r.noSendChange)\n}\n\nfunction throwIfAnyUnsuccessfulSignActions(r: SignActionResultX) {\n  const ndrs = r.notDelayedResults\n  const swrs = r.sendWithResults\n\n  if (ndrs == null || swrs == null || swrs.every(r => r.status === 'unproven')) return\n\n  throw new WERR_REVIEW_ACTIONS(ndrs, swrs, r.txid, r.tx)\n}\n\nfunction throwIfUnsuccessfulInternalizeAction(r: StorageInternalizeActionResult) {\n  const ndrs = r.notDelayedResults\n  const swrs = r.sendWithResults\n\n  if (ndrs == null || swrs == null || swrs.every(r => r.status === 'unproven')) return\n\n  throw new WERR_REVIEW_ACTIONS(ndrs, swrs, r.txid)\n}\n\n/**\n * Throws a WERR_REVIEW_ACTIONS with a full set of properties to test data formats and propagation.\n */\nexport function throwDummyReviewActions() {\n  const b58Beef =\n    'gno9MC7VXii1KoCkc2nsVyYJpqzN3dhBzYATETJcys62emMKfpBof4R7GozwYEaSapUtnNvqQ57aaYYjm3U2dv9eUJ1sV46boHkQgppYmAz9YH8FdZduV8aJayPViaKcyPmbDhEw6UW8TM5iFZLXNs7HBnJHUKCeTdNK4FUEL7vAugxAV9WUUZ43BZjJk2SmSeps9TCXjt1Ci9fKWp3d9QSoYvTpxwzyUFHjRKtbUgwq55ZfkBp5bV2Bpz9qSuKywKewW7Hh4S1nCUScwwzpKDozb3zic1V9p2k8rQxoPsRxjUJ8bjhNDdsN8d7KukFuc3n47fXzdWttvnxwsujLJRGnQbgJuknQqx3KLf5kJXHzwjG6TzigZk2t24qeB6d3hbYiaDr2fFkUJBL3tukTHhfNkQYRXuz3kucVDzvejHyqJaF51mXG8BjMN5aQj91ZJXCaPVqkMWCzmvyaqmXMdRiJdSAynhXbQK91xf6RwdNhz1tg5f9B6oJJMhsi9UYSVymmax8VLKD9AKzBCBDcfyD83m3jyS1VgKGZn3SkQmr6bsoWq88L3GsMnnmYUGogvdAYarTqg3pzkjCMxHzmJBMN6ofnUk8c1sRTXQue7BbyUaN5uZu3KW6CmFsEfpuqVvnqFW93TU1jrPP2S8yz8AexAnARPCKE8Yz7RfVaT6RCavwQKL3u5iookwRWEZXW1QWmM37yJWHD87SjVynyg327a1CLwcBxmE2CB48QeNVGyQki4CTQMqw2o8TMhDPJej1g68oniAjBcxBLSCs7KGvK3k7AfrHbCMULX9CTibYhCjdFjbsbBoocqJpxxcvkMo1fEEiAzZuiBVZQDYktDdTVbhKHvYkW25HcYX75NJrpNAhm7AjFeKLzEVxqAQkMfvTufpESNRZF4kQqg2Rg8h2ajcKTd5cpEPwXCrZLHm4EaZEmZVbg3QNfGhn7BJu1bHMtLqPD4y8eJxm2uGrW6saf6qKYmmu64F8A667NbD4yskPRQ1S863VzwGpxxmgLc1Ta3R46jEqsAoRDoZVUaCgBBZG3Yg1CTgi1EVBMXU7qvY4n3h8o2FLCEMWY4KadnV3iD4FbcdCmg4yxBosNAZgbPjhgGjCimjh4YsLd9zymGLmivmz2ZBg5m3xaiXT9NN81X9C1JUujd'\n  const beef = Beef.fromBinary(Utils.fromBase58(b58Beef))\n  const btx = beef.txs.at(-1)!\n  const txid = btx.txid\n\n  console.log('Throwing dummy WERR_REVIEW_ACTIONS')\n\n  throw new WERR_REVIEW_ACTIONS(\n    [\n      {\n        txid, // only care that it is syntactically a txid\n        status: 'doubleSpend',\n        competingTxs: [txid], // a txid in the beef\n        competingBeef: beef.toBinary()\n      }\n    ],\n    [\n      {\n        txid,\n        status: 'failed'\n      }\n    ],\n    txid,\n    beef.toBinaryAtomic(txid),\n    [`${txid}.0`]\n  )\n}\n\n/**\n * Implement BRC-112\n * @param vargs\n * @returns\n */\nfunction validateListOutputsArgs(args: ListOutputsArgs): ValidListOutputsArgs {\n  const vargs = Validation.validateListOutputsArgs(args)\n  const balancePrefix = 'balance '\n  if (vargs.basket.startsWith(balancePrefix)) {\n    vargs.basket = vargs.basket.slice(balancePrefix.length)\n    vargs.tags = [...vargs.tags, specOpWalletBalance]\n  }\n  return vargs\n}\n","import { TableOutput } from '../schema/tables/TableOutput'\n\n/**\n * Fields that identify an output as wallet-managed BRC-29 change.\n *\n * `type: 'P2PKH'` is historical terminology. In this storage model it does\n * not merely describe the locking script. It selects the wallet's BRC-29\n * unlocking path, so the accompanying derivation fields are also required.\n */\nexport const managedChangeOutputFields = {\n  type: 'P2PKH',\n  change: true,\n  providedBy: 'storage',\n  purpose: 'change'\n} as const\n\nfunction isNonEmptyString (value: unknown): value is string {\n  return typeof value === 'string' && value.length > 0\n}\n\n/**\n * True when an output has all metadata required to use the wallet-managed\n * BRC-29 signing path. `senderIdentityKey` is optional: wallet-created change\n * uses the client's change public key when it is absent, while received\n * BRC-29 payments record the sender's identity key.\n */\nexport function isManagedChangeOutput (output: TableOutput | undefined): output is TableOutput {\n  return output?.type === managedChangeOutputFields.type &&\n    output.change === managedChangeOutputFields.change &&\n    output.providedBy === managedChangeOutputFields.providedBy &&\n    output.purpose === managedChangeOutputFields.purpose &&\n    isNonEmptyString(output.derivationPrefix) &&\n    isNonEmptyString(output.derivationSuffix)\n}\n\n/**\n * True when managed change is currently eligible for automatic allocation.\n */\nexport function isAutoSpendableChangeOutput (output: TableOutput | undefined): output is TableOutput {\n  return isManagedChangeOutput(output) && output.spendable && output.spentBy == null\n}\n","import { Beef, OriginatorDomainNameStringUnder250Bytes, Random, Script, TelemetrySpan, Utils, Validation } from '@bsv/sdk'\nimport {\n  generateChangeSdk,\n  GenerateChangeSdkChangeInput,\n  GenerateChangeSdkParams,\n  GenerateChangeSdkResult,\n  maxPossibleSatoshis\n} from './generateChange'\nimport { StorageProvider, validateStorageFeeModel } from '../StorageProvider'\nimport {\n  AuthId,\n  StorageCreateActionResult,\n  StorageCreateTransactionSdkInput,\n  StorageCreateTransactionSdkOutput,\n  StorageFeeModel,\n  StorageGetBeefOptions,\n  StorageProvidedBy,\n  TrxToken\n} from '../../sdk/WalletStorage.interfaces'\nimport {\n  WERR_INTERNAL,\n  WERR_INSUFFICIENT_FUNDS,\n  WERR_INVALID_OPERATION,\n  WERR_INVALID_PARAMETER,\n  WERR_REVIEW_ACTIONS\n} from '../../sdk/WERR_errors'\nimport {\n  randomBytesBase64,\n  verifyId,\n  verifyInteger,\n  verifyNumber,\n  verifyOne,\n  verifyOneOrNone,\n  verifyTruthy\n} from '../../utility/utilityHelpers'\nimport { TableOutputBasket } from '../schema/tables/TableOutputBasket'\nimport { TableOutput } from '../schema/tables/TableOutput'\nimport { asArray, asString } from '../../utility/utilityHelpers.noBuffer'\nimport { TableOutputTag } from '../schema/tables/TableOutputTag'\nimport { TableTransaction } from '../schema/tables/TableTransaction'\nimport { EntityProvenTx } from '../schema/entities/EntityProvenTx'\nimport { throwDummyReviewActions } from '../../Wallet'\nimport { createStorageServiceChargeScript } from './offsetKey'\nimport { WalletError } from '../../sdk'\nimport { isAutoSpendableChangeOutput } from './managedChange'\nimport type { ManagedChangeInputCandidate } from './availableManagedChange'\nimport { CanonicalChangeSelector, randomizeOutputVouts as randomizePlannedOutputVouts } from './actionPlanning'\nimport { TransactionStatus } from '../../sdk/types'\n\nlet disableDoubleSpendCheckForTest = true\nexport function setDisableDoubleSpendCheckForTest(v: boolean) {\n  disableDoubleSpendCheckForTest = v\n}\n\nexport async function createAction(\n  storage: StorageProvider,\n  auth: AuthId,\n  vargs: Validation.ValidCreateActionArgs,\n  _originator?: OriginatorDomainNameStringUnder250Bytes\n): Promise<StorageCreateActionResult> {\n  if (!storage.telemetry.enabled) return await createActionCore(storage, auth, vargs)\n  return await storage.telemetry.withSpan(\n    'wallet.storage.create_action',\n    {\n      component: 'wallet-storage',\n      carrier: vargs,\n      attributes: {\n        'action.fixed_input_count': vargs.inputs.length,\n        'action.fixed_output_count': vargs.outputs.length,\n        'action.known_txid_count': vargs.options.knownTxids?.length ?? 0,\n        'action.is_delayed': vargs.isDelayed,\n        'action.is_no_send': vargs.isNoSend\n      }\n    },\n    async span => {\n      const result = await createActionCore(storage, auth, vargs, span)\n      span.end({\n        attributes: {\n          'action.result_input_count': result.inputs.length,\n          'action.result_output_count': result.outputs.length,\n          'action.input_beef_bytes': result.inputBeef?.length ?? 0\n        }\n      })\n      return result\n    }\n  )\n}\n\nasync function createActionCore(\n  storage: StorageProvider,\n  auth: AuthId,\n  vargs: Validation.ValidCreateActionArgs,\n  parent?: TelemetrySpan\n): Promise<StorageCreateActionResult> {\n  const logger = vargs.logger\n  logger?.group('storage createAction')\n  // stampLog(vargs, `start storage createTransactionSdk`)\n\n  if (vargs.isTestWerrReviewActions) throwDummyReviewActions()\n\n  if (!vargs.isNewTx)\n  // The purpose of this function is to create the initial storage records associated\n  // with a new transaction. It's an error if we have no new inputs or outputs...\n  {\n    throw new WERR_INTERNAL()\n  }\n\n  /**\n   * Steps to create a transaction:\n   * - Verify that all inputs either have proof in vargs.inputBEEF or that options.trustSelf === 'known' and input txid.vout are known valid to storage.\n   * - Create a new transaction record with status 'unsigned' as the anchor for construction work and to new outputs.\n   * - Create all transaction labels.\n   * - Add new commission output\n   * - Attempt to fund the transaction by allocating change outputs:\n   *    - As each change output is selected it is simultaneously locked.\n   * - Create all new output, basket, tag records\n   * - If requested, create result Beef with complete proofs for all inputs used\n   * - Create result inputs with source locking scripts\n   * - Create result outputs with new locking scripts.\n   * - Create and return result.\n  */\n\n  const userId = auth.userId!\n  const validated = await traceStorageStep(\n    storage,\n    'wallet.storage.create_action.validate',\n    parent,\n    {\n      'action.fixed_input_count': vargs.inputs.length,\n      'action.fixed_output_count': vargs.outputs.length\n    },\n    async span => {\n      const requiredInputs = await validateRequiredInputs(storage, userId, vargs)\n      logger?.log('validated required inputs')\n      const xoutputs = validateRequiredOutputs(storage, userId, vargs)\n      logger?.log('validated required outputs')\n\n      const changeBasketName = 'default'\n      const changeBasket = verifyOne(\n        await storage.findOutputBaskets({\n          partial: { userId, name: changeBasketName }\n        }),\n        `Invalid outputGeneration basket \"${changeBasketName}\"`\n      )\n      logger?.log('found change basket')\n\n      const noSendChangeIn = await validateNoSendChange(storage, userId, vargs, changeBasket)\n      logger?.log('validated noSendChange')\n      span?.end({\n        attributes: {\n          'action.validated_input_count': requiredInputs.xinputs.length,\n          'action.validated_output_count': xoutputs.length,\n          'action.no_send_change_input_count': noSendChangeIn.length,\n          'action.validated_beef_tx_count': requiredInputs.beef.txs.length\n        }\n      })\n      return { ...requiredInputs, xoutputs, changeBasket, noSendChangeIn }\n    }\n  )\n  const { storageBeef, beef, xinputs, xoutputs, changeBasket, noSendChangeIn } = validated\n\n  const feeModel = validateStorageFeeModel(storage.feeModel)\n  logger?.log(`validated fee model ${JSON.stringify(feeModel)}`)\n\n  const initialFundingPlan = await prepareFundingPlanWithSendingFallback(\n    storage,\n    [userId, vargs, xinputs, xoutputs, changeBasket, noSendChangeIn, feeModel],\n    parent\n  )\n  logger?.log(`planned funding from ${initialFundingPlan.availableChangeCount} change inputs`)\n\n  // The selected source txids are known before the write transaction begins.\n  // Start their one batched proof read now so PXC/network wait and BEEF\n  // assembly overlap the independent transaction-record/funding/output writes.\n  // A funding-claim retry is handled below by fetching only any residual roots.\n  const allocatedBeefPrefetch = startAllocatedChangeBeefPrefetch(\n    storage,\n    vargs,\n    initialFundingPlan.selected,\n    beef,\n    parent\n  )\n\n  const storageBeefBytes = storageBeef.toBinary()\n  let newTx: TableTransaction | undefined\n  let newTxCommitted = false\n  try {\n    const persisted = await storage.transaction(async trx => {\n      const initialSatoshis = fundingPlanSatoshis(initialFundingPlan)\n      newTx = await traceStorageStep(\n        storage,\n        'wallet.storage.create_action.create_record',\n        parent,\n        {\n          'action.label_count': vargs.labels.length,\n          'action.storage_beef_bytes': storageBeefBytes.length\n        },\n        async span => {\n          const transaction = await createNewTxRecord(\n            storage,\n            userId,\n            vargs,\n            storageBeefBytes,\n            initialSatoshis,\n            trx\n          )\n          span?.end({ attributes: { 'action.transaction_record_created': true } })\n          return transaction\n        }\n      )\n      logger?.log('created new transaction record')\n\n      const ctx: CreateTransactionSdkContext = {\n        xinputs,\n        xoutputs,\n        changeBasket,\n        noSendChangeIn,\n        feeModel,\n        transactionId: newTx.transactionId\n      }\n\n      const funded = await fundNewTransactionSdk(storage, userId, vargs, ctx, initialFundingPlan, parent, trx)\n      logger?.log('funded new transaction')\n\n      if (funded.maxPossibleSatoshisAdjustment != null) {\n        const adjustment = funded.maxPossibleSatoshisAdjustment\n        if (ctx.xoutputs[adjustment.fixedOutputIndex].satoshis !== maxPossibleSatoshis) throw new WERR_INTERNAL()\n        ctx.xoutputs[adjustment.fixedOutputIndex].satoshis = adjustment.satoshis\n        logger?.log('adjusted change outputs to max possible')\n      }\n\n      const satoshis = funded.changeOutputs.reduce((sum, output) => sum + output.satoshis, 0) -\n        funded.allocatedChange.reduce((sum, output) => sum + output.satoshis, 0)\n      if (satoshis !== initialSatoshis) {\n        await storage.updateTransaction(newTx.transactionId, { satoshis }, trx)\n        newTx.satoshis = satoshis\n      }\n      const storedOutputs = await traceStorageStep(\n        storage,\n        'wallet.storage.create_action.persist_outputs',\n        parent,\n        {\n          'action.fixed_output_count': ctx.xoutputs.length,\n          'action.change_output_count': funded.changeOutputs.length\n        },\n        async span => {\n          const result = await createNewOutputs(storage, userId, vargs, ctx, funded.changeOutputs, trx)\n          span?.end({ attributes: { 'action.persisted_output_count': result.outputs.length } })\n          return result\n        }\n      )\n      return { ...funded, ...storedOutputs, ctx }\n    })\n    newTxCommitted = true\n    const committedTx = verifyTruthy(newTx)\n    const { allocatedChange, derivationPrefix, outputs, changeVouts, ctx } = persisted\n    logger?.log('created new output records')\n\n    const inputBeef = await mergeAllocatedChangeBeefs(\n      storage,\n      vargs,\n      allocatedChange,\n      beef,\n      allocatedBeefPrefetch,\n      parent\n    )\n    logger?.log('merged allocated change beefs')\n\n    const inputs = await traceStorageStep(\n      storage,\n      'wallet.storage.create_action.assemble_inputs',\n      parent,\n      {\n        'action.fixed_input_count': ctx.xinputs.length,\n        'action.funding_input_count': allocatedChange.length,\n        'action.include_source_transactions': vargs.includeAllSourceTransactions\n      },\n      async span => {\n        const assembled = await createNewInputs(storage, userId, vargs, ctx, allocatedChange)\n        span?.end({ attributes: { 'action.result_input_count': assembled.length } })\n        return assembled\n      }\n    )\n    logger?.log('created new inputs')\n\n    const r: StorageCreateActionResult = {\n      reference: committedTx.reference,\n      version: committedTx.version!,\n      lockTime: committedTx.lockTime!,\n      inputs,\n      outputs,\n      derivationPrefix,\n      inputBeef,\n      noSendChangeOutputVouts: vargs.isNoSend ? changeVouts : undefined\n    }\n\n    logger?.groupEnd()\n    return r\n  } catch (error) {\n    // Always let an overlapped database read settle before cleanup destroys or\n    // reuses the provider. Its error is surfaced on the success path above;\n    // here the construction error remains authoritative.\n    await allocatedBeefPrefetch\n    if (newTx?.transactionId != null) {\n      try {\n        if (newTxCommitted) {\n          await storage.updateTransactionStatus('failed', newTx.transactionId)\n          logger?.log(`marked failed createAction transaction ${newTx.transactionId} after construction error`)\n        } else {\n          const failed = await createNewTxRecord(storage, userId, vargs, storageBeefBytes, 0, undefined, 'failed')\n          logger?.log(`recorded failed createAction transaction ${failed.transactionId} after rollback`)\n        }\n      } catch (cleanupError) {\n        logger?.log(`failed to clean up createAction transaction ${newTx.transactionId}: ${String(cleanupError)}`)\n      }\n    }\n    logger?.groupEnd()\n    throw error\n  }\n}\n\ninterface CreateTransactionSdkContext {\n  xinputs: XValidCreateActionInput[]\n  xoutputs: XValidCreateActionOutput[]\n  changeBasket: TableOutputBasket\n  noSendChangeIn: TableOutput[]\n  feeModel: StorageFeeModel\n  transactionId: number\n}\n\ninterface XValidCreateActionInput extends Validation.ValidCreateActionInput {\n  vin: number\n  lockingScript: Script\n  satoshis: number\n  output?: TableOutput\n}\n\nexport interface XValidCreateActionOutput extends Validation.ValidCreateActionOutput {\n  vout: number\n  providedBy: StorageProvidedBy\n  purpose?: string\n  derivationSuffix?: string\n  keyOffset?: string\n}\n\nfunction makeDefaultOutput(userId: number, transactionId: number, satoshis: number, vout: number): TableOutput {\n  const now = new Date()\n  const output: TableOutput = {\n    created_at: now,\n    updated_at: now,\n    outputId: 0,\n    userId,\n    transactionId,\n    satoshis,\n    vout,\n\n    basketId: undefined,\n    change: false,\n    customInstructions: undefined,\n    derivationPrefix: undefined,\n    derivationSuffix: undefined,\n    outputDescription: '',\n    lockingScript: undefined,\n    providedBy: 'you',\n    purpose: '',\n    senderIdentityKey: undefined,\n    spendable: true,\n    spendingDescription: undefined,\n    spentBy: undefined,\n    txid: undefined,\n    type: ''\n  }\n  return output\n}\n\n/** Check known outputs for double-spend, mark them spent, return competing txid if found. */\nasync function markKnownInputsSpent(\n  storage: StorageProvider,\n  knownInputRows: Array<{ i: XValidCreateActionInput; o: TableOutput }>,\n  transactionId: number\n): Promise<string | undefined> {\n  let doubleSpendTxid: string | undefined\n  await storage.transaction(async trx => {\n    const outputIds = knownInputRows.map(ni => verifyId(ni.o.outputId))\n    const knownOutputsById = await storage.findOutputsByIds(outputIds, trx)\n    for (const ni of knownInputRows) {\n      const { i, o } = ni\n      const o2 = knownOutputsById[verifyId(o.outputId)]\n      if (!o2) throw new WERR_INTERNAL(`missing outputId ${o.outputId}`)\n      if (o2.spentBy !== undefined && o2.spentBy !== null) {\n        const spendingTx = await storage.findTransactionById(verifyId(o2.spentBy), trx)\n        if (spendingTx?.txid) {\n          doubleSpendTxid = spendingTx.txid\n          return\n        }\n      }\n      if (!o2.spendable) {\n        throw new WERR_INVALID_PARAMETER(\n          `inputs[${i.vin}]`,\n          `spendable output. output ${o.txid}:${o.vout} appears to have been spent (spendable=${o2.spendable}).`\n        )\n      }\n      await storage.updateOutput(\n        verifyId(o.outputId),\n        { spendable: false, spentBy: transactionId, spendingDescription: i.inputDescription },\n        trx\n      )\n      o.spendable = false\n      o.spentBy = transactionId\n      o.spendingDescription = i.inputDescription\n    }\n  })\n  return doubleSpendTxid\n}\n\n/** Build an SDK input record for a new-input row that has a backing output. */\nasync function buildSdkInputFromOutput(\n  storage: StorageProvider,\n  vargs: Validation.ValidCreateActionArgs,\n  vin: number,\n  i: XValidCreateActionInput | undefined,\n  o: TableOutput,\n  unlockLen: number | undefined\n): Promise<StorageCreateTransactionSdkInput> {\n  if (i == null && !unlockLen) throw new WERR_INTERNAL(`vin ${vin} non-fixedInput without unlockLen`)\n  const sourceTransaction =\n    vargs.includeAllSourceTransactions && vargs.isSignAction\n      ? await storage.getRawTxOfKnownValidTransaction(o.txid)\n      : undefined\n  return {\n    vin,\n    sourceTxid: o.txid!,\n    sourceVout: o.vout,\n    sourceSatoshis: o.satoshis,\n    sourceLockingScript: asString(o.lockingScript!),\n    sourceTransaction,\n    unlockingScriptLength: unlockLen || i!.unlockingScriptLength,\n    providedBy: i != null && o.providedBy === 'storage' ? 'you-and-storage' : o.providedBy,\n    type: o.type,\n    spendingDescription: o.spendingDescription || undefined,\n    derivationPrefix: o.derivationPrefix || undefined,\n    derivationSuffix: o.derivationSuffix || undefined,\n    senderIdentityKey: o.senderIdentityKey || undefined\n  }\n}\n\n/** Build an SDK input record for a user-specified input with no corresponding stored output. */\nfunction buildSdkInputFromXInput(vin: number, i: XValidCreateActionInput): StorageCreateTransactionSdkInput {\n  return {\n    vin,\n    sourceTxid: i.outpoint.txid,\n    sourceVout: i.outpoint.vout,\n    sourceSatoshis: i.satoshis,\n    sourceLockingScript: i.lockingScript.toHex(),\n    unlockingScriptLength: i.unlockingScriptLength,\n    providedBy: 'you',\n    type: 'custom',\n    spendingDescription: undefined,\n    derivationPrefix: undefined,\n    derivationSuffix: undefined,\n    senderIdentityKey: undefined\n  }\n}\n\nasync function createNewInputs(\n  storage: StorageProvider,\n  userId: number,\n  vargs: Validation.ValidCreateActionArgs,\n  ctx: CreateTransactionSdkContext,\n  allocatedChange: TableOutput[]\n): Promise<StorageCreateTransactionSdkInput[]> {\n  const r: StorageCreateTransactionSdkInput[] = []\n\n  const newInputs: Array<{ i?: XValidCreateActionInput; o?: TableOutput; unlockLen?: number }> = []\n  for (const i of ctx.xinputs) newInputs.push({ i, o: i.output })\n\n  const knownInputRows = newInputs.filter(\n    (ni): ni is { i: XValidCreateActionInput; o: TableOutput } => ni.i != null && ni.o != null\n  )\n  if (knownInputRows.length > 0) {\n    const doubleSpendTxid = await markKnownInputsSpent(storage, knownInputRows, ctx.transactionId)\n    if (doubleSpendTxid) {\n      const beef = await getCompetingBeefForReview(storage, doubleSpendTxid)\n      throw new WERR_REVIEW_ACTIONS(\n        [{ txid: '', status: 'doubleSpend', competingTxs: [doubleSpendTxid], competingBeef: beef.toBinary() }],\n        []\n      )\n    }\n  }\n\n  for (const o of allocatedChange) newInputs.push({ o, unlockLen: 107 })\n\n  let vin = -1\n  for (const { i, o, unlockLen } of newInputs) {\n    vin++\n    if (o != null) {\n      r.push(await buildSdkInputFromOutput(storage, vargs, vin, i, o, unlockLen))\n    } else {\n      if (i == null) throw new WERR_INTERNAL(`vin ${vin} without output or xinput`)\n      r.push(buildSdkInputFromXInput(vin, i))\n    }\n  }\n  return r\n}\n\nasync function getCompetingBeefForReview(storage: StorageProvider, txid: string): Promise<Beef> {\n  try {\n    return await storage.getBeefForTransaction(txid, {})\n  } catch (e) {\n    const walletError = WalletError.fromUnknown(e)\n    if (walletError instanceof WERR_INVALID_PARAMETER || walletError.code === 'WERR_INVALID_PARAMETER') {\n      const beef = new Beef()\n      beef.mergeTxidOnly(txid)\n      return beef\n    }\n    throw e\n  }\n}\n\n/** Build the SDK descriptor for a persisted output. */\nfunction describeNewOutput(\n  o: TableOutput,\n  tags: string[],\n  txBaskets: Record<string, TableOutputBasket>\n): { changeVout: number | undefined; ro: StorageCreateTransactionSdkOutput } {\n  const changeVout = o.change && o.purpose === 'change' && o.providedBy === 'storage' ? o.vout : undefined\n  const ro: StorageCreateTransactionSdkOutput = {\n    vout: verifyInteger(o.vout),\n    satoshis: Validation.validateSatoshis(o.satoshis, 'o.satoshis'),\n    lockingScript: o.lockingScript == null ? '' : asString(o.lockingScript),\n    providedBy: verifyTruthy(o.providedBy),\n    purpose: o.purpose || undefined,\n    basket: Object.values(txBaskets).find(b => b.basketId === o.basketId)?.name,\n    tags,\n    outputDescription: o.outputDescription,\n    derivationSuffix: o.derivationSuffix,\n    customInstructions: o.customInstructions\n  }\n  return { changeVout, ro }\n}\n\n/** Insert the output and attach its tags; return the SDK output descriptor. */\nasync function persistNewOutput(\n  storage: StorageProvider,\n  o: TableOutput,\n  tags: string[],\n  txTags: Record<string, TableOutputTag>,\n  txBaskets: Record<string, TableOutputBasket>,\n  trx?: TrxToken\n): Promise<{ changeVout: number | undefined; ro: StorageCreateTransactionSdkOutput }> {\n  o.outputId = await storage.insertOutput(o, trx)\n  for (const tagName of new Set(tags)) {\n    const tag = txTags[tagName]\n    await storage.insertOutputTagMap({\n      outputId: verifyId(o.outputId),\n      outputTagId: verifyId(tag.outputTagId),\n      created_at: new Date(),\n      updated_at: new Date(),\n      isDeleted: false\n    }, trx)\n  }\n  return describeNewOutput(o, tags, txBaskets)\n}\n\nasync function createNewOutputs(\n  storage: StorageProvider,\n  userId: number,\n  vargs: Validation.ValidCreateActionArgs,\n  ctx: CreateTransactionSdkContext,\n  changeOutputs: TableOutput[],\n  trx?: TrxToken\n): Promise<{\n  outputs: StorageCreateTransactionSdkOutput[]\n  changeVouts: number[]\n}> {\n  const txBaskets: Record<string, TableOutputBasket> = {}\n  const basketNames = [...new Set(ctx.xoutputs.map(x => x.basket).filter((v): v is string => !!v))]\n  Object.assign(txBaskets, await storage.findOrInsertOutputBasketsBulk(userId, basketNames, trx))\n\n  const txTags: Record<string, TableOutputTag> = {}\n  const tagNames = [...new Set(ctx.xoutputs.flatMap(x => x.tags))]\n  Object.assign(txTags, await storage.findOrInsertOutputTagsBulk(userId, tagNames, trx))\n\n  const newOutputs: Array<{ o: TableOutput; tags: string[] }> = []\n\n  for (const xo of ctx.xoutputs) {\n    const lockingScript = asArray(xo.lockingScript)\n    if (xo.purpose === 'service-charge') {\n      const now = new Date()\n      await storage.insertCommission({\n        userId,\n        transactionId: ctx.transactionId,\n        lockingScript,\n        satoshis: xo.satoshis,\n        isRedeemed: false,\n        keyOffset: verifyTruthy(xo.keyOffset),\n        created_at: now,\n        updated_at: now,\n        commissionId: 0\n      }, trx)\n      const o = makeDefaultOutput(userId, ctx.transactionId, xo.satoshis, xo.vout)\n      o.lockingScript = lockingScript\n      o.providedBy = 'storage'\n      o.purpose = 'storage-commission'\n      o.type = 'custom'\n      o.spendable = false\n      newOutputs.push({ o, tags: [] })\n    } else {\n      const o = makeDefaultOutput(userId, ctx.transactionId, xo.satoshis, xo.vout)\n      o.lockingScript = lockingScript\n      o.basketId = xo.basket ? txBaskets[xo.basket].basketId : undefined\n      o.customInstructions = xo.customInstructions\n      o.outputDescription = xo.outputDescription\n      o.providedBy = xo.providedBy\n      o.purpose = xo.purpose || ''\n      o.type = 'custom'\n      newOutputs.push({ o, tags: xo.tags })\n    }\n  }\n\n  for (const o of changeOutputs) {\n    o.spendable = true\n    newOutputs.push({ o, tags: [] })\n  }\n\n  if (vargs.options.randomizeOutputs)\n    randomizePlannedOutputVouts(\n      newOutputs.map(output => output.o),\n      vargs.randomVals\n    )\n\n  // The overwhelmingly common path has no output tags. Those rows do not\n  // need generated outputIds, so Knex can persist fixed and change outputs in\n  // one multi-row statement. Tagged rows retain the established id-dependent\n  // insertion path below.\n  const untagged = newOutputs.filter(output => output.tags.length === 0)\n  await storage.insertOutputs(untagged.map(output => output.o), trx)\n\n  const outputs: StorageCreateTransactionSdkOutput[] = []\n  const changeVouts: number[] = []\n  for (const { o, tags } of newOutputs) {\n    const { changeVout, ro } = tags.length === 0\n      ? describeNewOutput(o, tags, txBaskets)\n      : await persistNewOutput(storage, o, tags, txTags, txBaskets, trx)\n    if (changeVout !== undefined) changeVouts.push(changeVout)\n    outputs.push(ro)\n  }\n\n  return { outputs, changeVouts }\n}\n\nasync function createNewTxRecord(\n  storage: StorageProvider,\n  userId: number,\n  vargs: Validation.ValidCreateActionArgs,\n  storageBeef: number[],\n  satoshis = 0,\n  trx?: TrxToken,\n  status: TableTransaction['status'] = 'unsigned'\n): Promise<TableTransaction> {\n  const now = new Date()\n  const newTx: TableTransaction = {\n    created_at: now,\n    updated_at: now,\n    transactionId: 0,\n    version: vargs.version,\n    lockTime: vargs.lockTime,\n    status,\n    reference: randomBytesBase64(12),\n    satoshis,\n    userId,\n    isOutgoing: true,\n    inputBEEF: storageBeef,\n    description: vargs.description,\n    txid: undefined,\n    rawTx: undefined\n  }\n  newTx.transactionId = await storage.insertTransaction(newTx, trx)\n\n  const labelNames = [...new Set(vargs.labels)]\n  const labels = await storage.findOrInsertTxLabelsBulk(userId, labelNames, trx)\n  for (const label of labelNames) {\n    const txLabel = labels[label]\n    await storage.findOrInsertTxLabelMap(verifyId(newTx.transactionId), verifyId(txLabel.txLabelId), trx)\n  }\n\n  return newTx\n}\n\n/**\n * Convert vargs.outputs:\n *\n * lockingScript: HexString\n * satoshis: SatoshiValue\n * outputDescription: DescriptionString5to50Bytes\n * basket?: BasketStringUnder300Bytes\n * customInstructions?: string\n * tags: BasketStringUnderBytes[]\n *\n * to XValidCreateActionOutput (which aims for StorageCreateTransactionSdkOutput)\n *\n * adds:\n *   vout: number\n *   providedBy: StorageProvidedBy\n *   purpose?: string\n *   derivationSuffix?: string\n *   keyOffset?: string\n *\n * @param vargs\n * @returns xoutputs\n */\nfunction validateRequiredOutputs(\n  storage: StorageProvider,\n  userId: number,\n  vargs: Validation.ValidCreateActionArgs\n): XValidCreateActionOutput[] {\n  const xoutputs: XValidCreateActionOutput[] = []\n  let vout = -1\n  for (const output of vargs.outputs) {\n    vout++\n    const xo: XValidCreateActionOutput = {\n      ...output,\n      vout,\n      providedBy: 'you',\n      purpose: undefined,\n      derivationSuffix: undefined,\n      keyOffset: undefined\n    }\n    xoutputs.push(xo)\n  }\n\n  if (storage.commissionSatoshis > 0 && storage.commissionPubKeyHex) {\n    vout++\n    const { script, keyOffset } = createStorageServiceChargeScript(storage.commissionPubKeyHex)\n    xoutputs.push({\n      lockingScript: script,\n      satoshis: storage.commissionSatoshis,\n      outputDescription: 'Storage Service Charge',\n      basket: undefined,\n      tags: [],\n\n      vout,\n      providedBy: 'storage',\n      purpose: 'service-charge',\n      keyOffset\n    })\n  }\n\n  return xoutputs\n}\n\n/**\n * Verify that we are in posession of validity proof data for any inputs being proposed for a new transaction.\n *\n * `vargs.inputs` is the source of inputs.\n * `vargs.inputBEEF` may include new user supplied validity data.\n * 'vargs.options.trustSelf === 'known'` indicates whether we can rely on the storage database records.\n *\n * If there are no inputs, returns an empty `Beef`.\n *\n * Always pulls rawTx data into first level of validity chains so that parsed transaction data is available\n * and checks input sourceSatoshis as well as filling in input sourceLockingScript.\n *\n * This data may be pruned again before being returned to the user based on `vargs.options.knownTxids`.\n *\n * @param storage\n * @param userId\n * @param vargs\n * @returns {storageBeef} containing only validity proof data for only unknown required inputs.\n * @returns {beef} containing verified validity proof data for all required inputs.\n * @returns {xinputs} extended validated required inputs.\n */\nasync function validateRequiredInputs(\n  storage: StorageProvider,\n  userId: number,\n  vargs: Validation.ValidCreateActionArgs\n): Promise<{\n  storageBeef: Beef\n  beef: Beef\n  xinputs: XValidCreateActionInput[]\n}> {\n  // stampLog(vargs, `start storage verifyInputBeef`)\n\n  const beef = new Beef()\n\n  if (vargs.inputs.length === 0) return { storageBeef: beef, beef, xinputs: [] }\n\n  if (vargs.inputBEEF != null) beef.mergeBeef(vargs.inputBEEF)\n\n  const xinputs: XValidCreateActionInput[] = vargs.inputs.map((input, vin) => ({\n    ...input,\n    vin,\n    satoshis: -1,\n    lockingScript: new Script(),\n    output: undefined\n  }))\n\n  const trustSelf = vargs.options.trustSelf === 'known'\n\n  const preloadedOutputsByOutpoint = await storage.findOutputsByOutpoints(\n    userId,\n    xinputs.map(i => ({ txid: i.outpoint.txid, vout: i.outpoint.vout }))\n  )\n  const preloadedOutputIds = Object.values(preloadedOutputsByOutpoint).map(output => output.outputId)\n  if ((await storage.findReservedActionBatchOutputIds(preloadedOutputIds)).length > 0) {\n    throw new WERR_INVALID_PARAMETER('inputs', 'outputs not reserved by an active action batch')\n  }\n\n  const inputsByTxid: Record<string, XValidCreateActionInput[]> = {}\n  for (const input of xinputs) {\n    inputsByTxid[input.outpoint.txid] ||= []\n    inputsByTxid[input.outpoint.txid].push(input)\n  }\n\n  const localKnownInputTxids: Record<string, boolean> = {}\n  for (const [txid, txInputs] of Object.entries(inputsByTxid)) {\n    localKnownInputTxids[txid] = txInputs.every(input => {\n      const output = preloadedOutputsByOutpoint[`${input.outpoint.txid}.${input.outpoint.vout}`]\n      return output?.lockingScript !== undefined && Number.isInteger(output?.satoshis)\n    })\n  }\n\n  await validateBeefTxidOnlyEntries(beef, inputsByTxid, trustSelf, storage)\n  await ensureBeefContainsAllInputTxids(beef, inputsByTxid, localKnownInputTxids, trustSelf, storage)\n\n  if (!(await beef.verify(await storage.getServices().getChainTracker(), true))) {\n    console.log(`verifyInputBeef failed, inputBEEF failed to verify.\\n${beef.toLogString()}\\n`)\n    throw new WERR_INVALID_PARAMETER('inputBEEF', 'valid Beef when factoring options.trustSelf')\n  }\n\n  const storageBeef = beef.clone()\n\n  for (const input of xinputs) {\n    await resolveInputScript(storage, userId, vargs, input, beef, preloadedOutputsByOutpoint)\n  }\n\n  return { beef, storageBeef, xinputs }\n}\n\n/** Check all txidOnly entries in beef: require either trustSelf vouch or throw. */\nasync function validateBeefTxidOnlyEntries(\n  beef: Beef,\n  inputsByTxid: Record<string, XValidCreateActionInput[]>,\n  trustSelf: boolean,\n  storage: StorageProvider\n): Promise<void> {\n  for (const btx of beef.txs) {\n    if (!btx.isTxidOnly) continue\n    if (!trustSelf)\n      throw new WERR_INVALID_PARAMETER('inputBEEF', `valid and contain complete proof data for ${btx.txid}`)\n    if (inputsByTxid[btx.txid] == null) {\n      const isKnown = await storage.verifyKnownValidTransaction(btx.txid)\n      if (!isKnown)\n        throw new WERR_INVALID_PARAMETER('inputBEEF', `valid and contain complete proof data for unknown ${btx.txid}`)\n    }\n  }\n}\n\n/** Ensure beef has an entry (or txidOnly) for every input txid. */\nasync function ensureBeefContainsAllInputTxids(\n  beef: Beef,\n  inputsByTxid: Record<string, XValidCreateActionInput[]>,\n  localKnownInputTxids: Record<string, boolean>,\n  trustSelf: boolean,\n  storage: StorageProvider\n): Promise<void> {\n  for (const txid of Object.keys(inputsByTxid)) {\n    let btx = beef.findTxid(txid)\n    if (btx == null && localKnownInputTxids[txid]) continue\n    if (btx == null && trustSelf) {\n      if (await storage.verifyKnownValidTransaction(txid)) btx = beef.mergeTxidOnly(txid)\n    }\n    if (btx == null) {\n      throw new WERR_INVALID_PARAMETER(\n        'inputBEEF',\n        `valid and contain proof data for possibly known ${txid}, beef ${beef.toLogString()}`\n      )\n    }\n  }\n}\n\n/** Resolve satoshis and lockingScript for one xinput from either storage or the beef. */\nfunction applyStoredInputScript(\n  output: TableOutput,\n  input: XValidCreateActionInput,\n  vargs: Validation.ValidCreateActionArgs\n): void {\n  const { txid, vout } = input.outpoint\n  if (output.change) {\n    throw new WERR_INVALID_PARAMETER(\n      `inputs[${input.vin}]`,\n      'an unmanaged input. Change outputs are managed by your wallet.'\n    )\n  }\n  input.output = output\n  if (output.lockingScript === undefined || !Number.isInteger(output.satoshis)) {\n    throw new WERR_INVALID_PARAMETER(`${txid}.${vout}`, 'output with valid lockingScript and satoshis')\n  }\n  if (!disableDoubleSpendCheckForTest && !output.spendable && !vargs.isNoSend) {\n    throw new WERR_INVALID_PARAMETER(`${txid}.${vout}`, 'spendable output unless noSend is true')\n  }\n  input.satoshis = Validation.validateSatoshis(output.satoshis, 'output.satoshis')\n  input.lockingScript = Script.fromBinary(asArray(output.lockingScript))\n}\n\nasync function applyBeefInputScript(\n  storage: StorageProvider,\n  beef: Beef,\n  input: XValidCreateActionInput\n): Promise<void> {\n  const { txid, vout } = input.outpoint\n  let beefTx = beef.findTxid(txid)!\n  if (beefTx.isTxidOnly) {\n    const { rawTx, proven } = await storage.getProvenOrRawTx(txid)\n    if (rawTx == null) {\n      throw new WERR_INVALID_PARAMETER('inputBEEF', `valid and contain proof data for ${txid}`)\n    }\n    beefTx = beef.mergeRawTx(asArray(rawTx))\n    if (proven != null) beef.mergeBump(new EntityProvenTx(proven).getMerklePath())\n  }\n  if (vout >= beefTx.tx!.outputs.length) {\n    throw new WERR_INVALID_PARAMETER(`${txid}.${vout}`, 'valid outpoint')\n  }\n  const sourceOutput = beefTx.tx!.outputs[vout]\n  input.satoshis = Validation.validateSatoshis(sourceOutput.satoshis, 'so.satoshis')\n  input.lockingScript = sourceOutput.lockingScript\n}\n\nasync function resolveInputScript(\n  storage: StorageProvider,\n  userId: number,\n  vargs: Validation.ValidCreateActionArgs,\n  input: XValidCreateActionInput,\n  beef: Beef,\n  preloadedOutputsByOutpoint: Record<string, TableOutput>\n): Promise<void> {\n  const { txid, vout } = input.outpoint\n  let output: TableOutput | undefined = preloadedOutputsByOutpoint[`${txid}.${vout}`]\n  output ??= verifyOneOrNone(await storage.findOutputs({ partial: { userId, txid, vout } }))\n  if (output != null) {\n    applyStoredInputScript(output, input, vargs)\n  } else {\n    await applyBeefInputScript(storage, beef, input)\n  }\n}\n\nasync function validateNoSendChange(\n  storage: StorageProvider,\n  userId: number,\n  vargs: Validation.ValidCreateActionArgs,\n  changeBasket: TableOutputBasket\n): Promise<TableOutput[]> {\n  const r: TableOutput[] = []\n\n  if (!vargs.isNoSend) return []\n\n  const noSendChange = vargs.options.noSendChange\n\n  if (noSendChange && noSendChange.length > 0) {\n    const byOutpoint = await storage.findOutputsByOutpoints(userId, noSendChange)\n    for (const op of noSendChange) {\n      const output = byOutpoint[`${op.txid}.${op.vout}`]\n      // noSendChange is signed through the same BRC-29 path as allocated change.\n      // It must satisfy the full managed-change policy, not merely share the\n      // default basket or have a P2PKH-shaped locking script.\n      if (\n        !isAutoSpendableChangeOutput(output) ||\n        !verifyNumber(output.satoshis) ||\n        output.basketId !== changeBasket.basketId\n      ) {\n        throw new WERR_INVALID_PARAMETER('noSendChange outpoint', 'wallet-managed BRC-29 change')\n      }\n      if (r.some(o => o.outputId === output.outputId))\n      // noSendChange duplicate OutPoints are not allowed.\n      {\n        throw new WERR_INVALID_PARAMETER('noSendChange outpoint', 'unique. Duplicates are not allowed.')\n      }\n      r.push(output)\n    }\n  }\n\n  if ((await storage.findReservedActionBatchOutputIds(r.map(output => output.outputId))).length > 0) {\n    throw new WERR_INVALID_PARAMETER('noSendChange', 'outputs not reserved by an active action batch')\n  }\n\n  return r\n}\n\ninterface PreparedFundingPlan {\n  params: GenerateChangeSdkParams\n  result: GenerateChangeSdkResult\n  selected: ManagedChangeInputCandidate[]\n  availableChangeCount: number\n  excludeSending: boolean\n}\n\ntype FundingClaimRequest = readonly [\n  userId: number,\n  basketId: number,\n  excludeSending: boolean,\n  transactionId: number,\n  noSendChangeIn: TableOutput[],\n  plan: PreparedFundingPlan,\n  trx?: TrxToken\n]\n\nfunction fundingPlanSatoshis (plan: PreparedFundingPlan): number {\n  return plan.result.changeOutputs.reduce((sum, output) => sum + output.satoshis, 0) -\n    plan.selected.reduce((sum, output) => sum + output.satoshis, 0)\n}\n\ntype FundingPlanBaseContext = readonly [\n  userId: number,\n  vargs: Validation.ValidCreateActionArgs,\n  xinputs: XValidCreateActionInput[],\n  xoutputs: XValidCreateActionOutput[],\n  changeBasket: TableOutputBasket,\n  noSendChangeIn: TableOutput[],\n  feeModel: StorageFeeModel\n]\n\ntype FundingPlanContext = readonly [\n  ...FundingPlanBaseContext,\n  excludeSending: boolean,\n  parent?: TelemetrySpan,\n  trx?: TrxToken\n]\n\ntype FundingClaim =\n  | {\n    outputs: TableOutput[]\n    sourceTransactionCount: number\n    hydratedScriptCount: number\n    scriptSourceTransactionCount: number\n    conflict?: undefined\n  }\n  | { outputs?: undefined, conflict: 'candidate' | 'noSendChange' }\n\ntype LockedFundingClaim =\n  | { outputs: TableOutput[], sourceTransactionCount: number, conflict?: undefined }\n  | { outputs?: undefined, sourceTransactionCount?: undefined, conflict: 'candidate' | 'noSendChange' }\n\nclass FundingClaimConflict extends Error {\n  constructor (readonly conflict: 'candidate' | 'noSendChange') {\n    super('createAction funding claim changed concurrently')\n  }\n}\n\nasync function traceStorageStep<T> (\n  storage: StorageProvider,\n  name: string,\n  parent: TelemetrySpan | undefined,\n  attributes: Readonly<Record<string, unknown>>,\n  callback: (span?: TelemetrySpan) => Promise<T>\n): Promise<T> {\n  if (!storage.telemetry.enabled) return await callback()\n  return await storage.telemetry.withSpan(\n    name,\n    { component: 'wallet-storage', parent: parent?.context, attributes },\n    async span => await callback(span)\n  )\n}\n\nfunction makeFundingParams (\n  vargs: Validation.ValidCreateActionArgs,\n  xinputs: XValidCreateActionInput[],\n  xoutputs: XValidCreateActionOutput[],\n  changeBasket: TableOutputBasket,\n  feeModel: StorageFeeModel,\n  availableChangeCount: number\n): GenerateChangeSdkParams {\n  return {\n    fixedInputs: xinputs.map(input => ({\n      satoshis: input.satoshis,\n      unlockingScriptLength: input.unlockingScriptLength\n    })),\n    fixedOutputs: xoutputs.map(output => ({\n      satoshis: output.satoshis,\n      lockingScriptLength: output.lockingScript.length / 2\n    })),\n    feeModel,\n    changeInitialSatoshis: Math.max(1, changeBasket.minimumDesiredUTXOValue),\n    changeFirstSatoshis: Math.max(1, Math.round(changeBasket.minimumDesiredUTXOValue / 4)),\n    changeLockingScriptLength: 25,\n    changeUnlockingScriptLength: 107,\n    targetNetCount: changeBasket.numberOfDesiredUTXOs - availableChangeCount,\n    randomVals: vargs.randomVals\n  }\n}\n\nasync function prepareFundingPlan (\n  storage: StorageProvider,\n  context: FundingPlanContext\n): Promise<PreparedFundingPlan> {\n  const [userId, vargs, xinputs, xoutputs, changeBasket, noSendChangeIn, feeModel, excludeSending, parent, trx] = context\n  const candidates = await traceStorageStep(\n    storage,\n    'wallet.storage.create_action.funding_candidates',\n    parent,\n    { 'funding.exclude_sending': excludeSending },\n    async span => {\n      const outputs = await storage.findAvailableManagedChangeInputCandidates(\n        userId,\n        changeBasket.basketId,\n        excludeSending,\n        trx\n      )\n      span?.end({\n        attributes: {\n          'funding.candidate_count': outputs.length,\n          'funding.candidate_satoshis': outputs.reduce((sum, output) => sum + output.satoshis, 0)\n        }\n      })\n      return outputs\n    }\n  )\n  const noSendIds = new Set(noSendChangeIn.map(output => output.outputId))\n  const available = candidates.filter(output => !noSendIds.has(output.outputId))\n  // Preserve the legacy target-net-count input: noSendChange was included in\n  // countChangeInputs before it was consumed by the allocator.\n  const params = makeFundingParams(vargs, xinputs, xoutputs, changeBasket, feeModel, candidates.length)\n\n  return await traceStorageStep(\n    storage,\n    'wallet.storage.create_action.funding_plan',\n    parent,\n    {\n      'funding.candidate_count': available.length,\n      'funding.no_send_change_count': noSendChangeIn.length\n    },\n    async span => {\n      const allocated = new Map<number, ManagedChangeInputCandidate>()\n      const availableSelector = new CanonicalChangeSelector(available)\n      const noSend = [...noSendChangeIn]\n      const noSendById = new Map(noSendChangeIn.map(output => [output.outputId, output]))\n      const allocate = async (\n        targetSatoshis: number,\n        exactSatoshis?: number\n      ): Promise<GenerateChangeSdkChangeInput | undefined> => {\n        let output: ManagedChangeInputCandidate | undefined = noSend.pop()\n        output ??= availableSelector.take(targetSatoshis, exactSatoshis)\n        if (output == null) return undefined\n        allocated.set(output.outputId, output)\n        return { outputId: output.outputId, satoshis: output.satoshis }\n      }\n      const release = async (outputId: number): Promise<void> => {\n        const output = allocated.get(outputId)\n        if (output == null) return\n        allocated.delete(outputId)\n        availableSelector.release(outputId)\n        const noSendOutput = noSendById.get(outputId)\n        if (noSendOutput != null) noSend.push(noSendOutput)\n      }\n      const result = await generateChangeSdk(params, allocate, release, vargs.logger, storage.telemetry)\n      const selected = result.allocatedChangeInputs.map(input => verifyTruthy(allocated.get(input.outputId)))\n      span?.end({\n        attributes: {\n          'funding.allocated_input_count': selected.length,\n          'funding.change_output_count': result.changeOutputs.length,\n          'funding.fee_satoshis': result.fee,\n          'funding.transaction_size_bytes': result.size\n        }\n      })\n      return {\n        params,\n        result,\n        selected,\n        availableChangeCount: candidates.length,\n        excludeSending\n      }\n    }\n  )\n}\n\nasync function prepareFundingPlanWithSendingFallback (\n  storage: StorageProvider,\n  context: FundingPlanBaseContext,\n  parent?: TelemetrySpan,\n  trx?: TrxToken\n): Promise<PreparedFundingPlan> {\n  const excludeSending = !context[1].isDelayed\n  try {\n    return await prepareFundingPlan(storage, [...context, excludeSending, parent, trx])\n  } catch (error) {\n    if (!excludeSending || !(error instanceof WERR_INSUFFICIENT_FUNDS)) throw error\n    // A transaction waiting for background broadcast already has a complete\n    // raw transaction and input BEEF in storage. Its wallet-managed change is\n    // safe to chain: the immediate broadcast path recursively merges that\n    // ancestor into the child BEEF. Prefer settled change, then admit queued\n    // change only when excluding it would report an underfunded wallet.\n    return await prepareFundingPlan(storage, [...context, false, parent, trx])\n  }\n}\n\nasync function claimFundingPlan (\n  storage: StorageProvider,\n  request: FundingClaimRequest\n): Promise<FundingClaim> {\n  const [userId, basketId, excludeSending, transactionId, noSendChangeIn, plan, trx] = request\n  if (plan.selected.length === 0) {\n    return { outputs: [], sourceTransactionCount: 0, hydratedScriptCount: 0, scriptSourceTransactionCount: 0 }\n  }\n  const noSendIds = new Set(noSendChangeIn.map(output => output.outputId))\n  const statuses: TransactionStatus[] = ['completed', 'unproven']\n  if (!excludeSending) statuses.push('sending')\n\n  const claim: LockedFundingClaim = await storage.transaction<LockedFundingClaim>(async claimTrx => {\n    const currentById = await storage.findFundingOutputsForUpdate(\n      userId,\n      plan.selected.map(output => output.outputId),\n      statuses,\n      claimTrx\n    )\n    const transactionIds = [...new Set(Object.values(currentById).map(output => output.transactionId))]\n    const claimed: TableOutput[] = []\n    for (const planned of plan.selected) {\n      const current = currentById[planned.outputId]\n      if (\n        current?.outputId !== planned.outputId ||\n        current?.satoshis !== planned.satoshis ||\n        current?.basketId !== basketId ||\n        !isAutoSpendableChangeOutput(current) ||\n        current?.txid !== planned.txid ||\n        current?.vout !== planned.vout\n      ) {\n        return { conflict: noSendIds.has(planned.outputId) ? 'noSendChange' : 'candidate' } as const\n      }\n      claimed.push(current)\n    }\n    const updated = await storage.markChangeInputsSpent(claimed.map(output => output.outputId), transactionId, claimTrx)\n    if (updated !== claimed.length) {\n      throw new FundingClaimConflict(\n        claimed.some(output => noSendIds.has(output.outputId)) ? 'noSendChange' : 'candidate'\n      )\n    }\n    for (const output of claimed) {\n      output.spendable = false\n      output.spentBy = transactionId\n    }\n    return { outputs: claimed, sourceTransactionCount: transactionIds.length }\n  }, trx).catch(error => {\n    if (error instanceof FundingClaimConflict) return { conflict: error.conflict } as const\n    throw error\n  })\n  if (claim.outputs == null) return claim\n  const hydration = await hydrateFundingInputScripts(storage, claim.outputs, trx)\n  return {\n    outputs: claim.outputs,\n    sourceTransactionCount: claim.sourceTransactionCount,\n    ...hydration\n  }\n}\n\nasync function hydrateFundingInputScripts (\n  storage: StorageProvider,\n  outputs: TableOutput[],\n  trx?: TrxToken\n): Promise<{ hydratedScriptCount: number, scriptSourceTransactionCount: number }> {\n  const missing = outputs.filter(output =>\n    output.lockingScript?.length !== output.scriptLength &&\n    output.scriptLength != null && output.scriptLength > 0 &&\n    output.scriptOffset != null && output.scriptOffset > 0 &&\n    output.txid != null && output.txid !== ''\n  )\n  if (missing.length === 0) return { hydratedScriptCount: 0, scriptSourceTransactionCount: 0 }\n\n  const byTxid = new Map<string, TableOutput[]>()\n  for (const output of missing) {\n    const txid = verifyTruthy(output.txid)\n    const group = byTxid.get(txid) ?? []\n    group.push(output)\n    byTxid.set(txid, group)\n  }\n  const groups = [...byTxid.entries()]\n  let cursor = 0\n  await Promise.all(\n    Array.from({ length: Math.min(8, groups.length) }, async () => {\n      while (cursor < groups.length) {\n        const [txid, group] = groups[cursor++]\n        if (group.length === 1) {\n          await storage.validateOutputScript(group[0], trx)\n          continue\n        }\n        const rawTx = await storage.getRawTxOfKnownValidTransaction(txid, undefined, undefined, trx)\n        if (rawTx != null) {\n          for (const output of group) {\n            output.lockingScript = rawTx.slice(output.scriptOffset!, output.scriptOffset! + output.scriptLength!)\n          }\n        } else {\n          for (const output of group) await storage.validateOutputScript(output, trx)\n        }\n      }\n    })\n  )\n  return {\n    hydratedScriptCount: missing.filter(output => output.lockingScript?.length === output.scriptLength).length,\n    scriptSourceTransactionCount: groups.length\n  }\n}\n\nasync function fundNewTransactionSdk(\n  storage: StorageProvider,\n  userId: number,\n  vargs: Validation.ValidCreateActionArgs,\n  ctx: CreateTransactionSdkContext,\n  initialPlan: PreparedFundingPlan,\n  parent?: TelemetrySpan,\n  trx?: TrxToken\n): Promise<{\n  allocatedChange: TableOutput[]\n  changeOutputs: TableOutput[]\n  derivationPrefix: string\n  maxPossibleSatoshisAdjustment?: {\n    fixedOutputIndex: number\n    satoshis: number\n  }\n}> {\n  let plan = initialPlan\n  let allocatedChange: TableOutput[] | undefined\n  let retryCount = 0\n  await traceStorageStep(\n    storage,\n    'wallet.storage.create_action.funding_claim',\n    parent,\n    { 'funding.planned_input_count': initialPlan.selected.length },\n    async span => {\n      for (let attempt = 0; attempt < 3; attempt++) {\n        const claim = await claimFundingPlan(storage, [\n          userId,\n          ctx.changeBasket.basketId,\n          plan.excludeSending,\n          ctx.transactionId,\n          ctx.noSendChangeIn,\n          plan,\n          trx\n        ])\n        if (claim.outputs != null) {\n          allocatedChange = claim.outputs\n          span?.end({\n            attributes: {\n              'funding.claim_retry_count': retryCount,\n              'funding.source_transaction_count': claim.sourceTransactionCount,\n              'funding.hydrated_script_count': claim.hydratedScriptCount,\n              'funding.script_source_transaction_count': claim.scriptSourceTransactionCount\n            }\n          })\n          return\n        }\n        if (claim.conflict === 'noSendChange') {\n          throw new WERR_INVALID_PARAMETER('noSendChange', 'outputs that remain spendable during action planning')\n        }\n        retryCount++\n        plan = await prepareFundingPlanWithSendingFallback(\n          storage,\n          [\n            userId,\n            vargs,\n            ctx.xinputs,\n            ctx.xoutputs,\n            ctx.changeBasket,\n            ctx.noSendChangeIn,\n            ctx.feeModel\n          ],\n          parent,\n          trx\n        )\n      }\n      throw new WERR_INVALID_OPERATION('wallet funding changed repeatedly during action planning; retry createAction')\n    }\n  )\n  if (allocatedChange == null) throw new WERR_INTERNAL('funding plan was not claimed')\n  const params = plan.params\n  const gcr = plan.result\n\n  const nextRandomVal = (): number => {\n    let val = 0\n    if (vargs.randomVals == null || vargs.randomVals.length === 0) {\n      const bytes = Random(4)\n      val = (((bytes[0] << 24) | (bytes[1] << 16) | (bytes[2] << 8) | bytes[3]) >>> 0) / 0x100000000\n    } else {\n      val = vargs.randomVals.shift() || 0\n      vargs.randomVals.push(val)\n    }\n    return val\n  }\n\n  /**\n   * @returns a random integer betweenn min and max, inclussive.\n   */\n  const rand = (min: number, max: number): number => {\n    if (max < min) throw new WERR_INVALID_PARAMETER('max', `less than min (${min}). max is (${max})`)\n    return Math.floor(nextRandomVal() * (max - min + 1) + min)\n  }\n\n  const randomDerivation = (count: number): string => {\n    let val: number[] = []\n    if (vargs.randomVals == null || vargs.randomVals.length === 0) {\n      val = Random(count)\n    } else {\n      for (let i = 0; i < count; i++) val.push(rand(0, 255))\n    }\n    return Utils.toBase64(val)\n  }\n\n  // Generate a derivation prefix for the payment\n  const derivationPrefix = randomDerivation(16)\n\n  const r: {\n    allocatedChange: TableOutput[]\n    changeOutputs: TableOutput[]\n    derivationPrefix: string\n    maxPossibleSatoshisAdjustment?: {\n      fixedOutputIndex: number\n      satoshis: number\n    }\n  } = {\n    maxPossibleSatoshisAdjustment: gcr.maxPossibleSatoshisAdjustment,\n    allocatedChange,\n    changeOutputs: gcr.changeOutputs.map((o, i) => ({\n      // what we knnow now and can insert into the database for this new transaction's change output\n      created_at: new Date(),\n      updated_at: new Date(),\n      outputId: 0,\n      userId,\n      transactionId: ctx.transactionId,\n      vout: params.fixedOutputs.length + i,\n      satoshis: o.satoshis,\n      basketId: ctx.changeBasket.basketId,\n      spendable: false,\n      change: true,\n      type: 'P2PKH',\n      derivationPrefix,\n      derivationSuffix: randomDerivation(16),\n      providedBy: 'storage',\n      purpose: 'change',\n      customInstructions: undefined,\n      senderIdentityKey: undefined,\n      outputDescription: '',\n\n      // what will be known when transaction is signed\n      txid: undefined,\n      lockingScript: undefined,\n\n      // when this output gets spent\n      spentBy: undefined,\n      spendingDescription: undefined\n    })),\n    derivationPrefix\n  }\n\n  return r\n}\n\n/**\n * Avoid returning any known raw transaction data by converting any known transaction\n * in the `beef` to txidOnly.\n * @returns undefined if `vargs.options.returnTXIDOnly` or trimmed `Beef`\n */\nfunction trimInputBeef(beef: Beef, vargs: Validation.ValidCreateActionArgs): Uint8Array | undefined {\n  if (vargs.options.returnTXIDOnly) return undefined\n  const knownTxids = vargs.options.knownTxids ?? []\n  const hasKnownTxid = makeKnownTxidLookup(knownTxids)\n  // The returned BEEF normally contains only a handful of transactions. A\n  // direct scan avoids materializing a second full index of a potentially\n  // very large wallet history on every successful action.\n  for (const btx of beef.txs) if (hasKnownTxid(btx.txid)) beef.makeTxidOnly(btx.txid)\n  return beef.toUint8Array()\n}\n\nfunction makeKnownTxidLookup (knownTxids: string[]): (txid: string) => boolean {\n  let lookups = 0\n  let indexed: Set<string> | undefined\n  return txid => {\n    lookups++\n    if (indexed != null) return indexed.has(txid)\n    if (knownTxids.length > 64 && lookups > 4) {\n      indexed = new Set(knownTxids)\n      return indexed.has(txid)\n    }\n    return knownTxids.includes(txid)\n  }\n}\n\ninterface AllocatedChangeBeefPrefetchResult {\n  beef?: Beef\n  error?: unknown\n  sourceCount: number\n  txids: string[]\n}\n\nfunction missingAllocatedChangeTxids (\n  allocatedChange: Array<{ txid?: string }>,\n  beef: Beef,\n  knownTxids: string[]\n): string[] {\n  const hasKnownTxid = makeKnownTxidLookup(knownTxids)\n  return Array.from(\n    new Set(\n      allocatedChange\n        .map(output => verifyTruthy(output.txid))\n        .filter(txid => beef.findTxid(txid) == null && !hasKnownTxid(txid))\n    )\n  )\n}\n\nfunction startAllocatedChangeBeefPrefetch (\n  storage: StorageProvider,\n  vargs: Validation.ValidCreateActionArgs,\n  allocatedChange: ManagedChangeInputCandidate[],\n  beef: Beef,\n  parent?: TelemetrySpan\n): Promise<AllocatedChangeBeefPrefetchResult> {\n  if (vargs.options.returnTXIDOnly) return Promise.resolve({ sourceCount: 0, txids: [] })\n  const knownTxids = vargs.options.knownTxids ?? []\n  const missing = missingAllocatedChangeTxids(allocatedChange, beef, knownTxids)\n  if (missing.length === 0) return Promise.resolve({ sourceCount: 0, txids: [] })\n  const options: StorageGetBeefOptions = {\n    trustSelf: undefined,\n    knownTxids,\n    ignoreStorage: false,\n    ignoreServices: true,\n    ignoreNewProven: false,\n    minProofLevel: undefined\n  }\n  return traceStorageStep(\n    storage,\n    'wallet.storage.create_action.beef_prefetch',\n    parent,\n    {\n      'beef.planned_source_count': allocatedChange.length,\n      'beef.missing_source_count': missing.length,\n      'beef.storage_batch_count': missing.length === 0 ? 0 : 1\n    },\n    async span => {\n      const fetched = await storage.getBeefForTransactions(missing, options)\n      span?.end({\n        attributes: {\n          'beef.fetched_tx_count': fetched.txs.length,\n          'beef.fetched_bump_count': fetched.bumps.length\n        }\n      })\n      return fetched\n    }\n  ).then(\n    prefetched => ({ beef: prefetched, sourceCount: missing.length, txids: missing }),\n    error => ({ error, sourceCount: missing.length, txids: missing })\n  )\n}\n\nfunction sameTxids (left: readonly string[], right: readonly string[]): boolean {\n  if (left.length !== right.length) return false\n  const expected = new Set(left)\n  return right.every(txid => expected.has(txid))\n}\n\nasync function mergeAllocatedChangeBeefs(\n  storage: StorageProvider,\n  vargs: Validation.ValidCreateActionArgs,\n  allocatedChange: TableOutput[],\n  beef: Beef,\n  prefetch: Promise<AllocatedChangeBeefPrefetchResult>,\n  parent?: TelemetrySpan\n): Promise<Uint8Array | undefined> {\n  const options: StorageGetBeefOptions = {\n    trustSelf: undefined,\n    knownTxids: vargs.options.knownTxids,\n    mergeToBeef: beef,\n    ignoreStorage: false,\n    ignoreServices: true,\n    ignoreNewProven: false,\n    minProofLevel: undefined\n  }\n  if (vargs.options.returnTXIDOnly) return undefined\n  const knownTxids = vargs.options.knownTxids ?? []\n  const requiredBeforePrefetch = missingAllocatedChangeTxids(allocatedChange, beef, knownTxids)\n  const prefetched = await traceStorageStep(\n    storage,\n    'wallet.storage.create_action.beef_prefetch_join',\n    parent,\n    { 'beef.prefetch_source_count': 0 },\n    async span => {\n      const result = await prefetch\n      span?.end({ attributes: { 'beef.prefetch_source_count': result.sourceCount } })\n      return result\n    }\n  )\n  // A claim retry may replace only part of the initial funding plan. Never\n  // merge proofs for outputs the final transaction does not spend: apart from\n  // unnecessary bytes, that would disclose unrelated wallet history.\n  const usePrefetch = sameTxids(prefetched.txids, requiredBeforePrefetch)\n  if (usePrefetch && prefetched.error != null) throw prefetched.error\n  if (usePrefetch && prefetched.beef != null) beef.mergeBeef(prefetched.beef)\n\n  // If a concurrent spender forced the funding claim to be replanned, only\n  // the newly selected roots remain. The normal uncontended path is empty.\n  const missing = missingAllocatedChangeTxids(allocatedChange, beef, knownTxids)\n  let fetched: Beef | undefined\n  await traceStorageStep(\n    storage,\n    'wallet.storage.create_action.beef_fetch',\n    parent,\n    {\n      'beef.allocated_change_count': allocatedChange.length,\n      'beef.distinct_source_count': new Set(allocatedChange.map(output => output.txid)).size,\n      'beef.known_txid_count': knownTxids.length,\n      'beef.missing_source_count': missing.length,\n      'beef.fetch_concurrency': 1,\n      'beef.prefetch_reused': usePrefetch\n    },\n    async span => {\n      if (missing.length > 0) {\n        fetched = await storage.getBeefForTransactions(missing, { ...options, mergeToBeef: undefined })\n      }\n      span?.end({\n        attributes: {\n          'beef.fetched_tx_count': fetched?.txs.length ?? 0,\n          'beef.fetched_bump_count': fetched?.bumps.length ?? 0,\n          'beef.storage_batch_count': missing.length === 0 ? 0 : 1\n        }\n      })\n    }\n  )\n  await traceStorageStep(\n    storage,\n    'wallet.storage.create_action.beef_merge',\n    parent,\n    { 'beef.fragment_count': (usePrefetch && prefetched.beef != null ? 1 : 0) + (fetched == null ? 0 : 1) },\n    async span => {\n      if (fetched != null) beef.mergeBeef(fetched)\n      span?.end({\n        attributes: {\n          'beef.merged_tx_count': beef.txs.length,\n          'beef.merged_bump_count': beef.bumps.length\n        }\n      })\n    }\n  )\n  return await traceStorageStep(\n    storage,\n    'wallet.storage.create_action.beef_trim_serialize',\n    parent,\n    {\n      'beef.tx_count': beef.txs.length,\n      'beef.bump_count': beef.bumps.length,\n      'beef.known_txid_count': knownTxids.length\n    },\n    async span => {\n      const result = trimInputBeef(beef, vargs)\n      span?.end({ attributes: { 'beef.result_bytes': result?.length ?? 0 } })\n      return result\n    }\n  )\n}\n","/**\n * These hashes are for blocks that are to known to have violated the Bitcoin\n * protocol. Regardless of the amount of proof-of-work that chains built on top\n * of them may have accumulated, they cannot be considered valid Bitcoin blocks.\n *\n * In the first instance, segregating witness data from transactions is not\n * part of the design of Bitcoin.\n *\n * In the second instance, adding new opcodes to be used when evaluating\n * scripts is also not allowed.\n */\nexport const dirtyHashes = {\n  // Block 478,558 with hash of 0000000000000000011865af4122fe3b144e2cbeea86142e8ff2fb4107352d43 was the last block shared by BSV, BCH and BTC\n  // Block 478,559 with hash of 00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148 was the first block of the BTC Segwit chain.\n  // Block 478,559 with hash of 000000000000000000651ef99cb9fcbe0dadde1d424bd9f15ff20136191a5eec was the valid Bitcoin block shared by BSV and BCH.\n  '00000000000000000019f112ec0a9982926f1258cdcc558dd7c3b7e5dc7fa148':\n    'This is the first header of the invalid SegWit chain.',\n  '0000000000000000004626ff6e3b936941d341c5932ece4357eeccac44e6d56c':\n    'This is the first header of the invalid ABC chain.'\n}\nconst dirtyHashLookup = dirtyHashes as typeof dirtyHashes & Record<string, string | undefined>\n\n/**\n * Throws Error if blockHash is in the dirtyHashes list.\n */\nexport function validateAgainstDirtyHashes(blockHash: string): void {\n  const reason = dirtyHashLookup[blockHash]\n  if (reason) {\n    throw new Error(`Not adding a header with a dirty hash: ${reason}`)\n  }\n}\n","import { BulkHeaderFileInfo } from './BulkHeaderFile'\n\n/**\n * Compares meta data received for a bulk header file `vbf` to known\n * valid bulk header files based on their `fileHash`.\n *\n * Short circuits both the retreival and validation of individual headers,\n * only a single SHA256 hash of the aggregate data needs to be compared.\n *\n * The standard file size for historic block headers is 100,000 per file\n * which results in a many orders of magnitude initialization speedup.\n *\n * The following properties must match:\n * - `firstHeight`\n * - `count`\n * - `prevChainWork`\n * - `prevHash`\n * - `lastChainWork`\n * - `lastHash`\n * - `chain`\n *\n * @param vbf\n * @returns true iff bulk file meta data (excluding its source) matches a known file.\n *\n * @publicbody\n */\nexport function isKnownValidBulkHeaderFile (vbf: BulkHeaderFileInfo): boolean {\n  if (!vbf?.fileHash) return false\n  const bf = validBulkHeaderFilesByFileHash()[vbf.fileHash]\n  if (\n    bf?.firstHeight !== vbf.firstHeight ||\n    bf?.count !== vbf.count ||\n    bf?.prevChainWork !== vbf.prevChainWork ||\n    bf?.prevHash !== vbf.prevHash ||\n    bf?.lastChainWork !== vbf.lastChainWork ||\n    bf?.lastHash !== vbf.lastHash ||\n    bf?.chain !== vbf.chain\n  ) {\n    return false\n  }\n  return true\n}\n\nlet _validBulkHeaderFilesByFileHash: Record<string, BulkHeaderFileInfo> | undefined\n\n/**\n * Hash map of known valid bulk header files by their `fileHash`.\n * @returns object where keys are file hashes of known bulk header files.\n */\nexport function validBulkHeaderFilesByFileHash (): Record<string, BulkHeaderFileInfo> {\n  if (_validBulkHeaderFilesByFileHash == null) {\n    _validBulkHeaderFilesByFileHash = {}\n    for (const vbf of validBulkHeaderFiles) {\n      if (vbf.fileHash) {\n        _validBulkHeaderFilesByFileHash[vbf.fileHash] = vbf\n      }\n    }\n  }\n  return _validBulkHeaderFilesByFileHash\n}\n\n/**\n * Static array of known valid bulk header files.\n * `sourceUrl` is included only as a reference to the original certifying authority.\n */\nexport const validBulkHeaderFiles: BulkHeaderFileInfo[] = [\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_0.headers',\n    firstHeight: 0,\n    prevHash: '0000000000000000000000000000000000000000000000000000000000000000',\n    count: 100000,\n    lastHash: '000000004956cc2edd1a8caa05eacfa3c69f4c490bfc9ace820257834115ab35',\n    fileHash: 'gAJPUfI2DfAabJTOBxT1rwy1cS4/QULaQHaQWa1RWNk=',\n    lastChainWork: '000000000000000000000000000000000000000000000000004143c00b3d47b8',\n    prevChainWork: '0000000000000000000000000000000000000000000000000000000000000000',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_1.headers',\n    firstHeight: 100000,\n    prevHash: '000000004956cc2edd1a8caa05eacfa3c69f4c490bfc9ace820257834115ab35',\n    count: 100000,\n    lastHash: '0000000000c470c4a573272aa4a680c93fc4c2f5df8ce9546441796f73277334',\n    fileHash: 'OIJ010bnIbFobNppJzCNE9jFI1uANz0iNGvqpoG2xq4=',\n    lastChainWork: '00000000000000000000000000000000000000000000000004504f3a4e71aa13',\n    prevChainWork: '000000000000000000000000000000000000000000000000004143c00b3d47b8',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_2.headers',\n    firstHeight: 200000,\n    prevHash: '0000000000c470c4a573272aa4a680c93fc4c2f5df8ce9546441796f73277334',\n    count: 100000,\n    lastHash: '00000000dfe970844d1bf983d0745f709368b5c66224837a17ed633f0dabd300',\n    fileHash: 'hZXE3im7V4tE0oROWM2mGB9xPXEcpVLRIYUPaYT3VV0=',\n    lastChainWork: '00000000000000000000000000000000000000000000000062378b066f9fba96',\n    prevChainWork: '00000000000000000000000000000000000000000000000004504f3a4e71aa13',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_3.headers',\n    firstHeight: 300000,\n    prevHash: '00000000dfe970844d1bf983d0745f709368b5c66224837a17ed633f0dabd300',\n    count: 100000,\n    lastHash: '0000000001127c76ac45f605f9300dfa96a8054533b96413883fdc4378aeb42d',\n    fileHash: 'BGZxsk/Ooa4BOaoBEMOor+B8wL9ghW5A0We2G2fmyLE=',\n    lastChainWork: '0000000000000000000000000000000000000000000000040da9d61d8e129a53',\n    prevChainWork: '00000000000000000000000000000000000000000000000062378b066f9fba96',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_4.headers',\n    firstHeight: 400000,\n    prevHash: '0000000001127c76ac45f605f9300dfa96a8054533b96413883fdc4378aeb42d',\n    count: 100000,\n    lastHash: '0000000001965655a870175b510326e6393114d293896ddb237709eecb381ab8',\n    fileHash: '3DjOpFnatZ0OKrpACATfAtBITX2s8JjfYTAnDHVkGuw=',\n    lastChainWork: '00000000000000000000000000000000000000000000000461063a8389300d36',\n    prevChainWork: '0000000000000000000000000000000000000000000000040da9d61d8e129a53',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_5.headers',\n    firstHeight: 500000,\n    prevHash: '0000000001965655a870175b510326e6393114d293896ddb237709eecb381ab8',\n    count: 100000,\n    lastHash: '000000000000bb1644b4d9a643b165a52b3ffba077f2a12b8bd1f0a6b6cc0fbc',\n    fileHash: 'wF008GqnZzAYsOwnmyFzIOmrJthHE3bq6oUg1FvHG1Y=',\n    lastChainWork: '0000000000000000000000000000000000000000000000067a8291cfec0aa549',\n    prevChainWork: '00000000000000000000000000000000000000000000000461063a8389300d36',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_6.headers',\n    firstHeight: 600000,\n    prevHash: '000000000000bb1644b4d9a643b165a52b3ffba077f2a12b8bd1f0a6b6cc0fbc',\n    count: 100000,\n    lastHash: '0000000000003e784511e93aca014ecaa6d4ba3637cf373f4b84dcac7c70cca0',\n    fileHash: 'uc7IW6NRXXtX3oGWwOYjtetTaZ+1zhvijNEwPbK+rAs=',\n    lastChainWork: '0000000000000000000000000000000000000000000000078286c7f42f7ec693',\n    prevChainWork: '0000000000000000000000000000000000000000000000067a8291cfec0aa549',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_7.headers',\n    firstHeight: 700000,\n    prevHash: '0000000000003e784511e93aca014ecaa6d4ba3637cf373f4b84dcac7c70cca0',\n    count: 100000,\n    lastHash: '0000000000068f8658ff71cbf8f5b31c837cc6df5bf53e40f05459d4267b53e6',\n    fileHash: 'yfomaIGZyoW/m7YdpZYNozeNrUmJBwaF0PpLdSADWJE=',\n    lastChainWork: '00000000000000000000000000000000000000000000000a551ea869597d2a74',\n    prevChainWork: '0000000000000000000000000000000000000000000000078286c7f42f7ec693',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_8.headers',\n    firstHeight: 800000,\n    prevHash: '0000000000068f8658ff71cbf8f5b31c837cc6df5bf53e40f05459d4267b53e6',\n    count: 100000,\n    lastHash: '0000000000214fbb71abe4695d935b8e089d306899c4a90124b1bc6806e6e299',\n    fileHash: '/AIS2PYHdMJBmRF9ECsZmCphoqhDyFWs+aO+3GIpPhg=',\n    lastChainWork: '00000000000000000000000000000000000000000000000eb93c12a85efec237',\n    prevChainWork: '00000000000000000000000000000000000000000000000a551ea869597d2a74',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_9.headers',\n    firstHeight: 900000,\n    prevHash: '0000000000214fbb71abe4695d935b8e089d306899c4a90124b1bc6806e6e299',\n    count: 100000,\n    lastHash: '00000000002208a5fee5b9baa4b5519d2cd8ab405754fca13704dc667448f21a',\n    fileHash: 'lJtRGLYlMnHe6r0xuJJWauJA7DKL4ZYOqkYmUD2iwbM=',\n    lastChainWork: '000000000000000000000000000000000000000000000017e96a5ada9f4a8bfb',\n    prevChainWork: '00000000000000000000000000000000000000000000000eb93c12a85efec237',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_10.headers',\n    firstHeight: 1000000,\n    prevHash: '00000000002208a5fee5b9baa4b5519d2cd8ab405754fca13704dc667448f21a',\n    count: 100000,\n    lastHash: '000000000005bc8878ba47a47129c3e21f32f8c10b9658f9ee6db16a83870162',\n    fileHash: 'tfWVFoIp4A6yXd2c0YietQ7hYlmLf7O884baego+D4E=',\n    lastChainWork: '000000000000000000000000000000000000000000000021bf46518c698a4bc8',\n    prevChainWork: '000000000000000000000000000000000000000000000017e96a5ada9f4a8bfb',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_11.headers',\n    firstHeight: 1100000,\n    prevHash: '000000000005bc8878ba47a47129c3e21f32f8c10b9658f9ee6db16a83870162',\n    count: 100000,\n    lastHash: '00000000f8bf61018ddd77d23c112e874682704a290252f635e7df06c8a317b8',\n    fileHash: 'S0Y9WXGFFJLRsRkQRNvrtImOezjReEQ1eDdB2x5M6Mw=',\n    lastChainWork: '0000000000000000000000000000000000000000000000288b285ca9b1bb8065',\n    prevChainWork: '000000000000000000000000000000000000000000000021bf46518c698a4bc8',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_12.headers',\n    firstHeight: 1200000,\n    prevHash: '00000000f8bf61018ddd77d23c112e874682704a290252f635e7df06c8a317b8',\n    count: 100000,\n    lastHash: '0000000000000165e6678be46ec2b15c587611b86da7147f7069a0e7175d62da',\n    fileHash: 'eFHQB8EaSfs4EKZxVsLhX8UA79kpOI4dR6j/z9P8frI=',\n    lastChainWork: '0000000000000000000000000000000000000000000000542144c6af6e9258ea',\n    prevChainWork: '0000000000000000000000000000000000000000000000288b285ca9b1bb8065',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_13.headers',\n    firstHeight: 1300000,\n    prevHash: '0000000000000165e6678be46ec2b15c587611b86da7147f7069a0e7175d62da',\n    count: 100000,\n    lastHash: '00000000000002ef0a47d0f242ab280bded8f4780bad506c71f2e1d2771becd4',\n    fileHash: '2MFJLBjHOBnuaDAICQFCL3y+6ejj0k92gbcmLWa1/Xc=',\n    lastChainWork: '0000000000000000000000000000000000000000000000dcc85f546d353f7b08',\n    prevChainWork: '0000000000000000000000000000000000000000000000542144c6af6e9258ea',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_14.headers',\n    firstHeight: 1400000,\n    prevHash: '00000000000002ef0a47d0f242ab280bded8f4780bad506c71f2e1d2771becd4',\n    count: 100000,\n    lastHash: '0000000000000168de8736c8a424fd5ebe1dcf0a030ed5fa0699b8c0fafc0b5e',\n    fileHash: 'lWmP/pOR5ciEnu5tjIrf7OTEaiaMcfqFZQQYT7QH6qg=',\n    lastChainWork: '00000000000000000000000000000000000000000000011bed7ab81a56a65cbc',\n    prevChainWork: '0000000000000000000000000000000000000000000000dcc85f546d353f7b08',\n    chain: 'test',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'testNet_15.headers',\n    firstHeight: 1500000,\n    prevHash: '0000000000000168de8736c8a424fd5ebe1dcf0a030ed5fa0699b8c0fafc0b5e',\n    count: 100000,\n    lastHash: '00000000000005504bfd1a3ce4688c30c86740390102b6cd464a2fb5e0e3fed1',\n    fileHash: '1bCf0R0RsoadANX+6H4NH1b3jNuTPyTayoS1SpQXa2Q=',\n    lastChainWork: '000000000000000000000000000000000000000000000156c3b84396da4e60b9',\n    prevChainWork: '00000000000000000000000000000000000000000000011bed7ab81a56a65cbc',\n    chain: 'test',\n    validated: true\n  },\n  {\n    chain: 'test',\n    count: 100000,\n    fileHash: 'qPjPA41mUU0ieEqud/JO95Agqq8XgzbzS5FLnHIRyPA=',\n    fileName: 'testNet_16.headers',\n    firstHeight: 1600000,\n    lastChainWork: '00000000000000000000000000000000000000000000015814b9c82dabd4ea74',\n    lastHash: '000000000001561e0532f48401f822f5c0d8797e364b1d612a317eca6983ca36',\n    prevChainWork: '000000000000000000000000000000000000000000000156c3b84396da4e60b9',\n    prevHash: '00000000000005504bfd1a3ce4688c30c86740390102b6cd464a2fb5e0e3fed1',\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    validated: true\n  },\n  {\n    chain: 'test',\n    count: 28130,\n    fileHash: '2DNTS2vBk4ddDzVz5MbFfRtxuze4FN4wrtKfaxbfC98=',\n    fileName: 'testNet_17.headers',\n    firstHeight: 1700000,\n    lastChainWork: '0000000000000000000000000000000000000000000001581bdf712d6fabd4da',\n    lastHash: '0000000072d02bc85e05ff155357fbbde7fe80057c4f9354fe5535147de00687',\n    prevChainWork: '00000000000000000000000000000000000000000000015814b9c82dabd4ea74',\n    prevHash: '000000000001561e0532f48401f822f5c0d8797e364b1d612a317eca6983ca36',\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders'\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'mainNet_0.headers',\n    firstHeight: 0,\n    prevHash: '0000000000000000000000000000000000000000000000000000000000000000',\n    count: 100000,\n    lastHash: '000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250',\n    fileHash: 'DMXYETHMphmYRh5y0+qsJhj67ML5Ui4LE1eEZDYbnZE=',\n    lastChainWork: '000000000000000000000000000000000000000000000000064492eaf00f2520',\n    prevChainWork: '0000000000000000000000000000000000000000000000000000000000000000',\n    chain: 'main',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'mainNet_1.headers',\n    firstHeight: 100000,\n    prevHash: '000000000002d01c1fccc21636b607dfd930d31d01c3a62104612a1719011250',\n    count: 100000,\n    lastHash: '00000000000003a20def7a05a77361b9657ff954b2f2080e135ea6f5970da215',\n    fileHash: 'IID8O84Uny22i10fWHTQr6f9+9eFZ8dhVyegYPGSg+Q=',\n    lastChainWork: '00000000000000000000000000000000000000000000001ac0479f335782cb80',\n    prevChainWork: '000000000000000000000000000000000000000000000000064492eaf00f2520',\n    chain: 'main',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'mainNet_2.headers',\n    firstHeight: 200000,\n    prevHash: '00000000000003a20def7a05a77361b9657ff954b2f2080e135ea6f5970da215',\n    count: 100000,\n    lastHash: '000000000000000067ecc744b5ae34eebbde14d21ca4db51652e4d67e155f07e',\n    fileHash: 'wbfV/ZuPvLKHtRJN4QlHiKlpNncuqWA1dMJ6O9mhisc=',\n    lastChainWork: '000000000000000000000000000000000000000000005a795f5d6ede10bc6d60',\n    prevChainWork: '00000000000000000000000000000000000000000000001ac0479f335782cb80',\n    chain: 'main',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'mainNet_3.headers',\n    firstHeight: 300000,\n    prevHash: '000000000000000067ecc744b5ae34eebbde14d21ca4db51652e4d67e155f07e',\n    count: 100000,\n    lastHash: '0000000000000000030034b661aed920a9bdf6bbfa6d2e7a021f78481882fa39',\n    fileHash: '5pklz64as2MG6y9lQiiClZaA82f6xoK1xdzkSqOZLsA=',\n    lastChainWork: '0000000000000000000000000000000000000000001229fea679a4cdc26e7460',\n    prevChainWork: '000000000000000000000000000000000000000000005a795f5d6ede10bc6d60',\n    chain: 'main',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'mainNet_4.headers',\n    firstHeight: 400000,\n    prevHash: '0000000000000000030034b661aed920a9bdf6bbfa6d2e7a021f78481882fa39',\n    count: 100000,\n    lastHash: '0000000000000000043831d6ebb013716f0580287ee5e5687e27d0ed72e6e523',\n    fileHash: '2X78/S+Z/h5ELA63aC3xt6/o4G8JMcAOEiZ00ycKHsM=',\n    lastChainWork: '0000000000000000000000000000000000000000007ae4707601d47bc6695487',\n    prevChainWork: '0000000000000000000000000000000000000000001229fea679a4cdc26e7460',\n    chain: 'main',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'mainNet_5.headers',\n    firstHeight: 500000,\n    prevHash: '0000000000000000043831d6ebb013716f0580287ee5e5687e27d0ed72e6e523',\n    count: 100000,\n    lastHash: '0000000000000000078f57b9a986b53b73f007c6b27b6f16409ca4eda83034e8',\n    fileHash: 'Tzm60n66tIuq7wNdP6M1BH77iFzGCPbOMIl6smJ/LRg=',\n    lastChainWork: '000000000000000000000000000000000000000000e8f2ea21f069a214067ed7',\n    prevChainWork: '0000000000000000000000000000000000000000007ae4707601d47bc6695487',\n    chain: 'main',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'mainNet_6.headers',\n    firstHeight: 600000,\n    prevHash: '0000000000000000078f57b9a986b53b73f007c6b27b6f16409ca4eda83034e8',\n    count: 100000,\n    lastHash: '000000000000000013abf3ab026610ed70e023476db8ce96f68637acdcbcf3cb',\n    fileHash: 'O7SoyIDxhejB0Qs4rBO4OkfBK2yVZKhxra6YxZMhiIk=',\n    lastChainWork: '0000000000000000000000000000000000000000012f32fb33b26aa239be0fc3',\n    prevChainWork: '000000000000000000000000000000000000000000e8f2ea21f069a214067ed7',\n    chain: 'main',\n    validated: true\n  },\n  {\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    fileName: 'mainNet_7.headers',\n    firstHeight: 700000,\n    prevHash: '000000000000000013abf3ab026610ed70e023476db8ce96f68637acdcbcf3cb',\n    count: 100000,\n    lastHash: '00000000000000000b6ae23bbe9f549844c20943d8c20b8ceedbae8aa1dde8e0',\n    fileHash: '+0Wu2GrKgCv4o1yZfdWl60aAgvBj6Rt3xlWj8TQprUw=',\n    lastChainWork: '000000000000000000000000000000000000000001483b2995af390c20b58320',\n    prevChainWork: '0000000000000000000000000000000000000000012f32fb33b26aa239be0fc3',\n    chain: 'main',\n    validated: true\n  },\n  {\n    chain: 'main',\n    count: 100000,\n    fileHash: 'xKYCsMzfbWdwq6RtEos4+4w7F3FroFMXb4tk4Z2gn5s=',\n    fileName: 'mainNet_8.headers',\n    firstHeight: 800000,\n    lastChainWork: '000000000000000000000000000000000000000001664db1f2d50327928007e0',\n    lastHash: '00000000000000000e7dcc27c06ee353bd37260b2e7e664314c204f0324a5087',\n    prevChainWork: '000000000000000000000000000000000000000001483b2995af390c20b58320',\n    prevHash: '00000000000000000b6ae23bbe9f549844c20943d8c20b8ceedbae8aa1dde8e0',\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders',\n    validated: true\n  },\n  {\n    chain: 'main',\n    count: 42761,\n    fileHash: 'iWZR7qvenqLKHANygKBBnikqmiW8GCoVCN7zjVXwgwY=',\n    fileName: 'mainNet_9.headers',\n    firstHeight: 900000,\n    lastChainWork: '0000000000000000000000000000000000000000016bf64e6fb83417f3b94c86',\n    lastHash: '0000000000000000108a6b142072acf8a781d5fcdd1c9a637d2194ad6b9c09dc',\n    prevChainWork: '000000000000000000000000000000000000000001664db1f2d50327928007e0',\n    prevHash: '00000000000000000e7dcc27c06ee353bd37260b2e7e664314c204f0324a5087',\n    sourceUrl: 'https://cdn.projectbabbage.com/blockheaders'\n  }\n]\n","import { validateAgainstDirtyHashes } from './dirtyHashes'\nimport { BigNumber, Hash, Utils } from '@bsv/sdk'\nimport { asArray, asString } from '../../../../utility/utilityHelpers.noBuffer'\nimport { doubleSha256BE } from '../../../../utility/utilityHelpers'\nimport { Chain } from '../../../../sdk/types'\nimport { ChaintracksFsApi } from '../Api/ChaintracksFsApi'\nimport { BulkHeaderFileInfo } from './BulkHeaderFile'\nimport { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'\nimport { isKnownValidBulkHeaderFile } from './validBulkHeaderFilesByFileHash'\nimport { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../../../sdk/WERR_errors'\nimport { BaseBlockHeader, BlockHeader } from '../../../../sdk/WalletServices.interfaces'\n\n/**\n * Computes sha256 hash of file contents read as bytes with no encoding.\n * @param filepath Full filepath to file.\n * @param bufferSize Optional read buffer size to use. Defaults to 80,000 bytes. Currently ignored.\n * @returns `{hash, length}` where `hash` is base64 string form of file hash and `length` is file length in bytes.\n */\nexport async function sha256HashOfBinaryFile(\n  fs: ChaintracksFsApi,\n  filepath: string,\n  _bufferSize = 80000\n): Promise<{ hash: string; length: number }> {\n  const sha256 = new Hash.SHA256()\n  const bytes = await fs.readFile(filepath)\n  const length = bytes.length\n  sha256.update(asArray(bytes))\n  return { hash: Utils.toBase64(sha256.digest()), length }\n}\n\n/**\n * Validates the contents of a bulk header file.\n * @param bf BulkHeaderFileInfo containing `data` to validate.\n * @param prevHash Required previous header hash.\n * @param prevChainWork Required previous chain work.\n * @param fetch Optional ChaintracksFetchApi instance for fetching data.\n * @returns Validated BulkHeaderFileInfo with `validated` set to true.\n */\nexport async function validateBulkFileData(\n  bf: BulkHeaderFileInfo,\n  prevHash: string,\n  prevChainWork: string,\n  fetch?: ChaintracksFetchApi\n): Promise<BulkHeaderFileInfo> {\n  const vbf = { ...bf }\n\n  if (vbf.data == null && vbf.sourceUrl && fetch != null) {\n    const url = fetch.pathJoin(vbf.sourceUrl, vbf.fileName)\n    vbf.data = await fetch.download(url)\n  }\n\n  if (vbf.data == null) throw new WERR_INVALID_OPERATION(`bulk file ${vbf.fileName} data is unavailable`)\n\n  if (vbf.count <= 0) {\n    throw new WERR_INVALID_PARAMETER('bf.count', `expected count to be greater than 0, but got ${vbf.count}`)\n  }\n\n  if (vbf.data.length !== vbf.count * 80) {\n    throw new WERR_INVALID_PARAMETER(\n      'bf.data',\n      `bulk file ${vbf.fileName} data length ${vbf.data.length} does not match expected count ${vbf.count}`\n    )\n  }\n\n  vbf.fileHash = asString(Hash.sha256(asArray(vbf.data)), 'base64')\n  if (bf.fileHash && bf.fileHash !== vbf.fileHash) {\n    throw new WERR_INVALID_PARAMETER('bf.fileHash', `expected ${bf.fileHash} but got ${vbf.fileHash}`)\n  }\n\n  if (!isKnownValidBulkHeaderFile(vbf)) {\n    const { lastHeaderHash, lastChainWork } = validateBufferOfHeaders(vbf.data, prevHash, 0, undefined, prevChainWork)\n    vbf.lastHash = lastHeaderHash\n    vbf.lastChainWork = lastChainWork!\n    if (vbf.firstHeight === 0) {\n      validateGenesisHeader(vbf.data, vbf.chain!)\n    }\n  }\n  vbf.validated = true\n\n  return vbf\n}\n\n/**\n * Validate headers contained in an array of bytes. The headers must be consecutive block headers, 80 bytes long,\n *  where the hash of each header equals the previousHash of the following header.\n * @param buffer Buffer of headers to be validated.\n * @param previousHash Expected previousHash of first header.\n * @param offset Optional starting offset within `buffer`.\n * @param count Optional number of headers to validate. Validates to end of buffer if missing.\n * @returns Header hash of last header validated or previousHash if there where none.\n */\nexport function validateBufferOfHeaders(\n  buffer: Uint8Array,\n  previousHash: string,\n  offset = 0,\n  count = -1,\n  previousChainWork?: string\n): { lastHeaderHash: string; lastChainWork: string | undefined } {\n  if (count < 0) count = Math.floor((buffer.length - offset) / 80)\n  count = Math.max(0, count)\n  let lastHeaderHash = previousHash\n  let lastChainWork = previousChainWork\n  for (let i = 0; i < count; i++) {\n    const headerStart = offset + i * 80\n    const headerEnd = headerStart + 80\n    if (headerEnd > buffer.length) {\n      throw new WERR_INVALID_PARAMETER(\n        'buffer',\n        `multiple of 80 bytes long. header ${i} missing bytes for header at offset ${headerStart} in buffer of length ${buffer.length}`\n      )\n    }\n    const header = buffer.slice(headerStart, headerEnd)\n    const h = deserializeBaseBlockHeader(header)\n    const hashPrev = asString(header.slice(4, 36).reverse())\n    if (lastHeaderHash !== hashPrev) {\n      throw new Error(`header ${i} invalid previousHash ${lastHeaderHash} vs ${hashPrev}`)\n    }\n    lastHeaderHash = asString(doubleSha256BE(header))\n    validateAgainstDirtyHashes(lastHeaderHash)\n    if (lastChainWork) {\n      lastChainWork = addWork(lastChainWork, convertBitsToWork(h.bits))\n    }\n  }\n  return { lastHeaderHash, lastChainWork }\n}\n\n/**\n * Verifies that buffer begins with valid genesis block header for the specified chain.\n * @param buffer\n * @param chain\n */\nexport function validateGenesisHeader(buffer: Uint8Array, chain: Chain): void {\n  const header = buffer.slice(0, 80)\n  const h = deserializeBlockHeader(header, 0)\n  const gh = genesisHeader(chain)\n  if (\n    h.bits !== gh.bits ||\n    h.previousHash !== gh.previousHash ||\n    h.merkleRoot !== gh.merkleRoot ||\n    h.time !== gh.time ||\n    h.nonce !== gh.nonce ||\n    h.version !== gh.version ||\n    h.height !== gh.height ||\n    h.hash !== gh.hash\n  ) {\n    throw new WERR_INVALID_PARAMETER('buffer', `genesis header for chain ${chain}`)\n  }\n}\n\n/**\n * @param work chainWork as a BigNumber\n * @returns Converted chainWork value from BN to hex string of 32 bytes.\n */\nexport function workBNtoBuffer(work: BigNumber): string {\n  return work.toString(16).padStart(64, '0')\n}\n\n/**\n * Returns true if work1 is more work (greater than) work2\n */\nexport function isMoreWork(work1: string, work2: string): boolean {\n  return new BigNumber(asArray(work1), 16).gt(new BigNumber(asArray(work2), 16))\n}\n\n/**\n * Add two Buffer encoded chainwork values\n * @returns Sum of work1 + work2 as Buffer encoded chainWork value\n */\nexport function addWork(work1: string, work2: string): string {\n  const sum = new BigNumber(work1, 16).add(new BigNumber(work2, 16))\n  return workBNtoBuffer(sum)\n}\n\n/**\n * Subtract Buffer encoded chainwork values\n * @returns work1 - work2 as Buffer encoded chainWork value\n */\nexport function subWork(work1: string, work2: string): string {\n  const sum = new BigNumber(work1, 16).sub(new BigNumber(work2, 16))\n  return workBNtoBuffer(sum)\n}\n\n/**\n * Computes \"target\" value for 4 byte Bitcoin block header \"bits\" value.\n * @param bits number or converted from Buffer using `readUint32LE`\n * @returns 32 byte Buffer with \"target\" value\n */\nexport function convertBitsToTarget(bits: number | number[]): BigNumber {\n  if (Array.isArray(bits)) bits = readUInt32LE(bits, 0)\n\n  const shift = (bits >> 24) & 0xff\n  const data = bits & 0x007fffff\n\n  const target = new BigNumber(data)\n  if (shift <= 3) {\n    target.iushrn(8 * (3 - shift))\n  } else {\n    target.iushln(8 * (shift - 3))\n  }\n\n  return target\n}\n\n/**\n * Computes \"chainWork\" value for 4 byte Bitcoin block header \"bits\" value.\n * @param bits number or converted from Buffer using `readUint32LE`\n * @returns 32 byte Buffer with \"chainWork\" value\n */\nexport function convertBitsToWork(bits: number | number[]): string {\n  const target = convertBitsToTarget(bits)\n\n  // convert target to work\n  const work = target.notn(256).div(target.addn(1)).addn(1)\n\n  return work.toString(16).padStart(64, '0')\n}\n\nexport function deserializeBaseBlockHeaders(\n  buffer: number[] | Uint8Array,\n  offset = 0,\n  count?: number | undefined\n): BaseBlockHeader[] {\n  const headers: BaseBlockHeader[] = []\n  while ((!count || headers.length < count) && offset + 80 <= buffer.length && offset >= 0) {\n    headers.push(deserializeBaseBlockHeader(buffer, offset))\n    offset += 80\n  }\n  return headers\n}\n\nexport function deserializeBlockHeaders(\n  firstHeight: number,\n  buffer: number[] | Uint8Array,\n  offset = 0,\n  count?: number | undefined\n): BlockHeader[] {\n  const headers: BlockHeader[] = []\n  let nextHeight = firstHeight\n  while ((!count || headers.length < count) && offset + 80 <= buffer.length && offset >= 0) {\n    const baseBuffer = buffer.slice(offset, offset + 80)\n    const base = deserializeBaseBlockHeader(baseBuffer)\n    const header = {\n      ...base,\n      height: nextHeight++,\n      hash: asString(blockHash(baseBuffer))\n    }\n    headers.push(header)\n    offset += 80\n  }\n  return headers\n}\n\n/**\n * Given a block header, ensures that its format is correct. This does not\n * check its difficulty or validity relative to the chain of headers.\n *\n * Throws on format errors.\n *\n * @param The header to validate\n *\n * @returns true if the header is correctly formatted\n */\nfunction validateUnsignedHeaderInteger(value: unknown, field: string, maximum: number, rangeField = field): void {\n  if (typeof value !== 'number') {\n    throw new TypeError(`Header ${field} must be a number.`)\n  }\n  if (!Number.isInteger(value)) {\n    throw new TypeError(`Header ${field} must be an integer.`)\n  }\n  if (value < 0 || value > maximum) {\n    throw new Error(`Header ${rangeField} must be between 0 and ${maximum}.`)\n  }\n}\n\nexport function validateHeaderFormat(header: BlockHeader): void {\n  const ALLOWED_KEYS = {\n    version: true,\n    previousHash: true,\n    merkleRoot: true,\n    time: true,\n    bits: true,\n    nonce: true,\n    height: true,\n    hash: true\n  }\n\n  const UINT_MAX = 0xffffffff\n\n  /**\n   * Root object checks\n   */\n  if (header === undefined) {\n    throw new TypeError('Missing header.')\n  }\n  if (typeof header !== 'object') {\n    throw new TypeError('Header must be an object.')\n  }\n  if (!Object.keys(header).every(key => key in ALLOWED_KEYS)) {\n    throw new Error('Header contains extra properties.')\n  }\n\n  /**\n   * Version\n   */\n  validateUnsignedHeaderInteger(header.version, 'version', UINT_MAX)\n\n  /**\n   * Height\n   */\n  validateUnsignedHeaderInteger(header.height, 'height', UINT_MAX / 2, 'version')\n\n  /**\n   * Previous hash\n   */\n  if (header.previousHash.length !== 64) {\n    throw new Error('Header previousHash must be 32 hex bytes.')\n  }\n\n  /**\n   * Merkle root\n   */\n  if (header.merkleRoot.length !== 64) {\n    throw new Error('Header merkleRoot must be 32 hex bytes.')\n  }\n\n  /**\n   * Time\n   */\n  validateUnsignedHeaderInteger(header.time, 'time', UINT_MAX)\n\n  /**\n   * Bits\n   */\n  validateUnsignedHeaderInteger(header.bits, 'bits', UINT_MAX)\n\n  /**\n   * Nonce\n   */\n  validateUnsignedHeaderInteger(header.nonce, 'nonce', UINT_MAX)\n\n  /**\n   * Hash\n   */\n  if (header.hash.length !== 64) {\n    throw new Error('Header hash must be 32 hex bytes.')\n  }\n  if (header.hash !== asString(blockHash(header))) {\n    throw new Error('Header hash is invalid.')\n  }\n}\n\n/**\n * Ensures that a header has a valid proof-of-work\n * Requires chain is 'main'\n *\n * @param header The header to validate\n *\n * @returns true if the header is valid\n */\nexport function validateHeaderDifficulty(hash: Buffer, bits: number) {\n  const hashBN = new BigNumber(asArray(hash))\n\n  const target = convertBitsToTarget(bits)\n\n  if (hashBN.lte(target)) return true\n\n  throw new Error('Block hash is not less than specified target.')\n}\n\n/**\n * Computes double sha256 hash of bitcoin block header\n * bytes are reversed to bigendian order\n *\n * If header is a Buffer, it is required to 80 bytes long\n * and in standard block header serialized encoding.\n *\n * @returns doule sha256 hash of header bytes reversed\n * @publicbody\n */\nexport function blockHash(header: BaseBlockHeader | number[] | Uint8Array): string {\n  const a = !Array.isArray(header) && !(header instanceof Uint8Array) ? serializeBaseBlockHeader(header) : header\n  if (a.length !== 80) throw new Error('Block header must be 80 bytes long.')\n  return asString(doubleSha256BE(a))\n}\n\n/**\n * Serializes a block header as an 80 byte Buffer.\n * The exact serialized format is defined in the Bitcoin White Paper\n * such that computing a double sha256 hash of the buffer computes\n * the block hash for the header.\n * @returns 80 byte Buffer\n * @publicbody\n */\nexport function serializeBaseBlockHeader(header: BaseBlockHeader, buffer?: number[], offset?: number): number[] {\n  const writer = new Utils.Writer()\n  writer.writeUInt32LE(header.version)\n  writer.write(asArray(header.previousHash).reverse())\n  writer.write(asArray(header.merkleRoot).reverse())\n  writer.writeUInt32LE(header.time)\n  writer.writeUInt32LE(header.bits)\n  writer.writeUInt32LE(header.nonce)\n  const data = writer.toArray()\n  if (buffer != null) {\n    offset ||= 0\n    for (let i = 0; i < data.length; i++) {\n      if (offset + i >= buffer.length) {\n        throw new Error(`Buffer overflow at offset ${offset + i} for data length ${data.length}`)\n      }\n      buffer[offset + i] = data[i]\n    }\n  }\n  return data\n}\n\nexport function serializeBaseBlockHeaders(headers: BlockHeader[]): Uint8Array {\n  const data = new Uint8Array(headers.length * 80)\n  let i = -1\n  for (const header of headers) {\n    i++\n    const d = serializeBaseBlockHeader(header)\n    data.set(d, i * 80)\n  }\n  return data\n}\n\n/**\n * Deserialize a BaseBlockHeader from an 80 byte buffer\n * @publicbody\n */\nexport function deserializeBaseBlockHeader(buffer: number[] | Uint8Array, offset = 0): BaseBlockHeader {\n  const reader = Utils.ReaderUint8Array.makeReader(buffer, offset)\n  const header: BaseBlockHeader = {\n    version: reader.readUInt32LE(),\n    previousHash: asString(reader.read(32).reverse()),\n    merkleRoot: asString(reader.read(32).reverse()),\n    time: reader.readUInt32LE(),\n    bits: reader.readUInt32LE(),\n    nonce: reader.readUInt32LE()\n  }\n  return header\n}\n\nexport function deserializeBlockHeader(buffer: number[] | Uint8Array, height: number, offset = 0): BlockHeader {\n  const base = deserializeBaseBlockHeader(buffer, offset)\n  const header: BlockHeader = {\n    ...base,\n    height,\n    hash: asString(doubleSha256BE(buffer.slice(offset, offset + 80)))\n  }\n  return header\n}\n\n/**\n * Returns the genesis block for the specified chain.\n * @publicbody\n */\nexport function genesisHeader(chain: Chain): BlockHeader {\n  switch (chain) {\n    case 'main':\n      return {\n        version: 1,\n        previousHash: '0000000000000000000000000000000000000000000000000000000000000000',\n        merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',\n        time: 1231006505,\n        bits: 486604799,\n        nonce: 2083236893,\n        height: 0,\n        hash: '000000000019d6689c085ae165831e934ff763ae46a2a6c172b3f1b60a8ce26f'\n      }\n    case 'test':\n      return {\n        version: 1,\n        previousHash: '0000000000000000000000000000000000000000000000000000000000000000',\n        merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',\n        time: 1296688602,\n        bits: 486604799,\n        nonce: 414098458,\n        height: 0,\n        hash: '000000000933ea01ad0ee984209779baaec3ced90fa3f408719526f8d77f4943'\n      }\n    case 'stn':\n      return {\n        version: 1,\n        previousHash: '0000000000000000000000000000000000000000000000000000000000000000',\n        merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',\n        time: 1296688602,\n        bits: 486604799,\n        nonce: 173779992,\n        height: 0,\n        // go-chaincfg v1.6.1 retains a stale StnParams.GenesisHash literal.\n        // This is the hash of the serialized stnGenesisBlock header itself.\n        hash: '6b38bdbcd73a19f7889d23e1fa6166a9de71affceca60ca3bb1b28af8135c594'\n      }\n    case 'ttn':\n      return {\n        version: 1,\n        previousHash: '0000000000000000000000000000000000000000000000000000000000000000',\n        merkleRoot: '4a5e1e4baab89f3a32518a88c31bc87f618f76673e2cc77ab2127b7afdeda33b',\n        time: 1755606836,\n        bits: 486604799,\n        nonce: 1092578460,\n        height: 0,\n        hash: '000000000499eabba0a88f5b3747231c74b9191c1a4a04b2c2ea817976b7776d'\n      }\n    case 'tstn':\n      return {\n        version: 1,\n        previousHash: '0000000000000000000000000000000000000000000000000000000000000000',\n        merkleRoot: '64452e5b25c65e492ad6a4f5ce9f427ca986626c28315d88de920d66e28cc98f',\n        time: 1782864000,\n        bits: 486604799,\n        nonce: 1780488216,\n        height: 0,\n        hash: '000000005d221c0e023cb56b5682cf094f32cd959958b40bc931e5797cae706c'\n      }\n    case 'mock':\n      throw new Error(\"genesisHeader does not support 'mock' chain. Mock chain generates its own genesis block.\")\n  }\n}\n\n/**\n * Returns the genesis block for the specified chain.\n * @publicbody\n */\nexport function genesisBuffer(chain: Chain): number[] {\n  return serializeBaseBlockHeader(genesisHeader(chain))\n}\n\n/**\n * Returns a copy of a Buffer with byte order reversed.\n * @returns new buffer with byte order reversed.\n * @publicbody\n */\nexport function swapByteOrder(buffer: number[]): number[] {\n  return buffer.slice().reverse()\n}\n\n/**\n * @param num a number value in the Uint32 value range\n * @param littleEndian true for little-endian byte order in Buffer\n * @returns four byte buffer with Uint32 number encoded\n * @publicbody\n */\nexport function convertUint32ToBuffer(n: number, littleEndian = true): number[] {\n  const a = [\n    n & 0xff, // lowest byte\n    (n >> 8) & 0xff,\n    (n >> 16) & 0xff,\n    (n >> 24) & 0xff // highest byte\n  ]\n  return littleEndian ? a : a.reverse()\n}\n\nexport function writeUInt32LE(n: number, a: number[] | Uint8Array, offset: number): number {\n  a[offset++] = n & 0xff // lowest byte\n  a[offset++] = (n >> 8) & 0xff\n  a[offset++] = (n >> 16) & 0xff\n  a[offset++] = (n >> 24) & 0xff // highest byte\n  return offset\n}\n\nexport function writeUInt32BE(n: number, a: number[] | Uint8Array, offset: number): number {\n  a[offset++] = (n >> 24) & 0xff // highest byte\n  a[offset++] = (n >> 16) & 0xff\n  a[offset++] = (n >> 8) & 0xff\n  a[offset++] = n & 0xff // lowest byte\n  return offset\n}\n\nexport function readUInt32LE(a: number[] | Uint8Array, offset: number): number {\n  return a[offset++] | (a[offset++] << 8) | (a[offset++] << 16) | (a[offset++] << 24)\n}\n\nexport function readUInt32BE(a: number[] | Uint8Array, offset: number): number {\n  return (a[offset++] << 24) | (a[offset++] << 16) | (a[offset++] << 8) | a[offset++]\n}\n\n/**\n * @param buffer four byte buffer with Uint32 number encoded\n * @param littleEndian true for little-endian byte order in Buffer\n * @returns a number value in the Uint32 value range\n * @publicbody\n */\nexport function convertBufferToUint32(buffer: number[] | Uint8Array, littleEndian = true): number {\n  const a = littleEndian ? buffer : buffer.slice().reverse()\n  const n = a[0] | (a[1] << 8) | (a[2] << 16) | (a[3] << 24)\n  return n\n}\n","import {\n  Transaction as BsvTransaction,\n  WalletPayment,\n  BasketInsertion,\n  InternalizeActionArgs,\n  TransactionOutput,\n  Beef,\n  BeefTx,\n  MerklePath,\n  Validation,\n  Utils\n} from '@bsv/sdk'\nimport { GetReqsAndBeefResult, shareReqsWithWorld } from './processAction'\nimport { StorageProvider } from '../StorageProvider'\nimport { AuthId, StorageInternalizeActionResult, StorageProvenOrReq } from '../../sdk/WalletStorage.interfaces'\nimport { TableOutput } from '../schema/tables/TableOutput'\nimport { TableOutputBasket } from '../schema/tables/TableOutputBasket'\nimport { TableTransaction } from '../schema/tables/TableTransaction'\nimport { WERR_INTERNAL, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { randomBytesBase64, verifyId, verifyOne, verifyOneOrNone } from '../../utility/utilityHelpers'\nimport { TransactionStatus } from '../../sdk/types'\nimport { EntityProvenTxReq } from '../schema/entities/EntityProvenTxReq'\nimport { blockHash } from '../../services/chaintracker/chaintracks/util/blockHeaderUtilities'\nimport { TableProvenTx } from '../schema/tables/TableProvenTx'\nimport { isManagedChangeOutput } from './managedChange'\n\n/**\n * Record of a spent-input transition this internalize call performed.\n * Carries enough state to roll back the exact change via\n * {@link restoreInputsToSpendable}: which row, and whether we touched\n * `spentBy` (only true for rows owned by the internalizing user).\n */\nexport interface SpentInputTransition {\n  outputId: number\n  /** true if the call set spentBy; false if only spendable was flipped. */\n  setSpentBy: boolean\n}\n\n/**\n * Mark every storage row at each consumed-input outpoint as spent — across\n * all users that track that outpoint. An on-chain spend invalidates the UTXO\n * for every wallet that references it, not just the wallet that called\n * `internalizeAction`. Returns the per-row transitions so the caller can\n * roll back via {@link restoreInputsToSpendable} on broadcast failure.\n *\n * Cross-user semantics:\n *   - For rows owned by `userId` (the internalizing user) we also set\n *     `spentBy=transactionId`. They own the corresponding transaction\n *     record; the FK target exists in their scope.\n *   - For rows owned by other users we set `spendable=false` and leave\n *     `spentBy` untouched. `spentBy` references the owning user's\n *     `transactions.transactionId`, and that user has no record of our\n *     transaction yet — they'd need to internalize it themselves to get\n *     one. Leaving `spentBy` undefined keeps the field consistent with\n *     \"this UTXO is spent, but my wallet didn't witness the spend\".\n *\n * Mirrors what `createAction` does for wallet-originated transactions and\n * what `TaskUnFail.unfailReq` does when reviving a previously-failed tx.\n * Without this, an externally-broadcast tx that consumed user UTXOs would\n * leave those UTXOs as phantom spendable rows, picked up by subsequent\n * `createAction` fund selection.\n *\n * Idempotent: rows already `spendable=false` are skipped. Rows already\n * `spentBy` a different transaction are also skipped (a competing spend\n * has been recorded; do not overwrite).\n */\nexport async function markUserInputsSpent (\n  storage: StorageProvider,\n  userId: number,\n  tx: BsvTransaction,\n  transactionId: number\n): Promise<SpentInputTransition[]> {\n  const outpoints = tx.inputs\n    .map(i => ({ txid: i.sourceTXID ?? '', vout: i.sourceOutputIndex ?? 0 }))\n    .filter(o => o.txid !== '')\n  if (outpoints.length === 0) return []\n  const transitioned: SpentInputTransition[] = []\n  await storage.transaction(async trx => {\n    for (const op of outpoints) {\n      const matches = await storage.findOutputs({\n        partial: { txid: op.txid, vout: op.vout },\n        noScript: true,\n        trx\n      })\n      for (const o of matches) {\n        if (!o.spendable) continue\n        if (o.spentBy != null && o.spentBy !== transactionId) continue\n        const setSpentBy = o.userId === userId\n        const update: Partial<TableOutput> = setSpentBy\n          ? { spendable: false, spentBy: transactionId }\n          : { spendable: false }\n        await storage.updateOutput(verifyId(o.outputId), update, trx)\n        transitioned.push({ outputId: verifyId(o.outputId), setSpentBy })\n      }\n    }\n  })\n  return transitioned\n}\n\n/**\n * Revert the spendable=true → false transitions performed by\n * {@link markUserInputsSpent}. Used when an internalize call's downstream\n * broadcast fails non-fatally so the caller can retry with the same UTXOs.\n *\n * Only undoes what was changed: `spendable=true` always; `spentBy=undefined`\n * only when the original transition set it. Avoids clobbering a competing\n * spent-by on cross-user rows.\n *\n * The downstream `attemptToPostReqsToNetwork` path also calls\n * `updateTransactionStatus('failed')` on doubleSpend/invalidTx outcomes,\n * which independently restores same-user inputs (via\n * `EntityTransaction.getInputs` filtered by userId). This explicit rollback\n * covers cross-user rows and any path where the downstream restore did not\n * run, and is a no-op when the downstream restore already happened.\n */\nexport async function restoreInputsToSpendable (\n  storage: StorageProvider,\n  transitions: SpentInputTransition[]\n): Promise<void> {\n  if (transitions.length === 0) return\n  await storage.transaction(async trx => {\n    for (const t of transitions) {\n      const update: Partial<TableOutput> = t.setSpentBy\n        ? { spendable: true, spentBy: undefined }\n        : { spendable: true }\n      await storage.updateOutput(verifyId(t.outputId), update, trx)\n    }\n  })\n}\n\n/**\n * Internalize Action allows a wallet to take ownership of outputs in a pre-existing transaction.\n * The transaction may, or may not already be known to both the storage and user.\n *\n * Two types of outputs are handled: \"wallet payments\" and \"basket insertions\".\n *\n * A \"basket insertion\" output is considered a custom output and has no effect on the wallet's \"balance\".\n *\n * A \"wallet payment\" adds an outputs value to the wallet's change \"balance\". These outputs are assigned to the \"default\" basket.\n *\n * Processing starts with simple validation and then checks for a pre-existing transaction.\n * If the transaction is already known to the user, then the outputs are reviewed against the existing outputs treatment,\n * and merge rules are added to the arguments passed to the storage layer.\n *\n * The existing transaction's `status` determines what the merge path does next:\n *  - `'unproven'`, `'completed'`, or `'sending'`: outputs are merged into the existing record. The transaction status is left as-is.\n *    The `'sending'` case covers a transaction this wallet already signed and handed to broadcast processing, but\n *    whose proven_tx_req has not yet been advanced by the normal monitor/posting flow.\n *  - `'nosend'`: an ambiguous case. The transaction was created with `noSend: true` and may have been externally\n *    broadcast, may be sitting in a sendWith chain, or may be stuck mid-flight. The merge path treats the\n *    `internalizeAction` call as explicit authorization to advance the lifecycle. Specifically: `transactions.status`\n *    is promoted to `'completed'` (when a BUMP is included in the BEEF) or `'unproven'` (otherwise), and the\n *    `proven_tx_req` is moved out of `'nosend'` so Monitor's standard proof-fetching flow can finalize it.\n *    This makes the `internalizeAction` semantics consistent regardless of whether the originator shares the\n *    same storage as the internalizer or not.\n *  - Any other status: an error.\n *\n * When the transaction already exists, the description is updated. The isOutgoing sense is not changed.\n *\n * \"basket insertion\" Merge Rules:\n * 1. The \"default\" basket may not be specified as the insertion basket.\n * 2. Managed change may not be reclassified as a basket insertion.\n * 3. Basket insertions do not affect wallet balance and are typed \"custom\".\n *\n * \"wallet payment\" Merge Rules:\n * 1. Targeting an existing managed output is idempotent.\n * 2. Targeting an existing custom output converts it to managed BRC-29\n *    change and increases wallet balance. This includes verified recovery of\n *    a legacy custom row that was incorrectly placed in the default basket.\n */\nexport async function internalizeAction (\n  storage: StorageProvider,\n  auth: AuthId,\n  args: InternalizeActionArgs\n): Promise<StorageInternalizeActionResult> {\n  const ctx = new InternalizeActionContext(storage, auth, args)\n  await ctx.asyncSetup()\n\n  if (ctx.isMerge) await ctx.mergedInternalize()\n  else await ctx.newInternalize()\n\n  return ctx.r\n}\n\ninterface BasketInsertionX extends BasketInsertion {\n  /** incoming transaction output index */\n  vout: number\n  /** incoming transaction output */\n  txo: TransactionOutput\n  /** if valid, corresponding storage output  */\n  eo?: TableOutput\n}\n\ninterface WalletPaymentX extends WalletPayment {\n  /** incoming transaction output index */\n  vout: number\n  /** incoming transaction output */\n  txo: TransactionOutput\n  /** if valid, corresponding storage output  */\n  eo?: TableOutput\n  /** corresponds to an existing change output */\n  ignore: boolean\n}\n\nclass InternalizeActionContext {\n  /** result to be returned */\n  r: StorageInternalizeActionResult\n  /** the parsed input AtomicBEEF */\n  ab: Beef\n  /** the incoming transaction extracted from AtomicBEEF */\n  tx: BsvTransaction\n  /** the user's change basket */\n  changeBasket: TableOutputBasket\n  /** cached baskets referenced by basket insertions */\n  baskets: Record<string, TableOutputBasket>\n  /** existing storage transaction for this txid and userId */\n  etx?: TableTransaction\n  /** existing outputs */\n  eos: TableOutput[]\n  /** all the basket insertions from incoming outputs array */\n  basketInsertions: BasketInsertionX[]\n  /** all the wallet payments from incoming outputs array */\n  walletPayments: WalletPaymentX[]\n  /** outputs this call transitioned spendable=true → false (for rollback) */\n  spentInputs: SpentInputTransition[]\n  userId: number\n  vargs: Validation.ValidInternalizeActionArgs\n\n  constructor (\n    public storage: StorageProvider,\n    public auth: AuthId,\n    public args: InternalizeActionArgs\n  ) {\n    this.vargs = Validation.validateInternalizeActionArgs(args)\n    this.userId = auth.userId!\n    this.r = {\n      accepted: true,\n      isMerge: false,\n      txid: '',\n      satoshis: 0\n    }\n    this.ab = new Beef()\n    this.tx = new BsvTransaction()\n    this.changeBasket = {} as TableOutputBasket\n    this.baskets = {}\n    this.basketInsertions = []\n    this.walletPayments = []\n    this.eos = []\n    this.spentInputs = []\n  }\n\n  get isMerge (): boolean {\n    return this.r.isMerge\n  }\n\n  set isMerge (v: boolean) {\n    this.r.isMerge = v\n  }\n\n  get txid (): string {\n    return this.r.txid\n  }\n\n  set txid (v: string) {\n    this.r.txid = v\n  }\n\n  get satoshis (): number {\n    return this.r.satoshis\n  }\n\n  set satoshis (v: number) {\n    this.r.satoshis = v\n  }\n\n  async getBasket (basketName: string): Promise<TableOutputBasket> {\n    if (basketName === 'default') {\n      throw new WERR_INVALID_PARAMETER('insertionRemittance.basket', 'a non-default basket')\n    }\n    let b = this.baskets[basketName]\n    if (b) return b\n    b = await this.storage.findOrInsertOutputBasket(this.userId, basketName)\n    this.baskets[basketName] = b\n    return b\n  }\n\n  private classifyRequestedOutput (\n    output: Validation.ValidInternalizeActionArgs['outputs'][number]\n  ): void {\n    if (output.outputIndex < 0 || output.outputIndex >= this.tx.outputs.length) {\n      throw new WERR_INVALID_PARAMETER(\n        'outputIndex',\n        `a valid output index in range 0 to ${this.tx.outputs.length - 1}`\n      )\n    }\n    const txo = this.tx.outputs[output.outputIndex]\n    if (output.protocol === 'basket insertion') {\n      if (output.insertionRemittance == null || output.paymentRemittance != null) {\n        throw new WERR_INVALID_PARAMETER(\n          'basket insertion',\n          'valid insertionRemittance and no paymentRemittance'\n        )\n      }\n      if (output.insertionRemittance.basket === 'default') {\n        throw new WERR_INVALID_PARAMETER(\n          'insertionRemittance.basket',\n          'a non-default basket'\n        )\n      }\n      this.basketInsertions.push({\n        ...output.insertionRemittance,\n        txo,\n        vout: output.outputIndex\n      })\n      return\n    }\n    if (output.protocol !== 'wallet payment') {\n      throw new WERR_INTERNAL(`unexpected protocol ${output.protocol}`)\n    }\n    if (output.insertionRemittance != null || output.paymentRemittance == null) {\n      throw new WERR_INVALID_PARAMETER(\n        'wallet payment',\n        'valid paymentRemittance and no insertionRemittance'\n      )\n    }\n    this.walletPayments.push({\n      ...output.paymentRemittance,\n      txo,\n      vout: output.outputIndex,\n      ignore: false\n    })\n  }\n\n  private async loadExistingTransaction (): Promise<void> {\n    this.etx = verifyOneOrNone(\n      await this.storage.findTransactions({\n        partial: { userId: this.userId, txid: this.txid }\n      })\n    )\n    const allowedStatuses: TransactionStatus[] = [\n      'completed',\n      'unproven',\n      'sending',\n      'nosend'\n    ]\n    if (this.etx != null && !allowedStatuses.includes(this.etx.status)) {\n      throw new WERR_INVALID_PARAMETER(\n        'tx',\n        `target transaction of internalizeAction has invalid status ${this.etx.status}.`\n      )\n    }\n    this.isMerge = this.etx != null\n  }\n\n  private async linkExistingOutputs (): Promise<void> {\n    if (!this.isMerge) return\n    this.eos = await this.storage.findOutputs({\n      partial: { userId: this.userId, txid: this.txid }\n    })\n    for (const existing of this.eos) {\n      const basket = this.basketInsertions.find(candidate => candidate.vout === existing.vout)\n      const payment = this.walletPayments.find(candidate => candidate.vout === existing.vout)\n      if (basket != null && payment != null) {\n        throw new WERR_INVALID_PARAMETER('outputs', 'unique outputIndex values')\n      }\n      if (basket != null) basket.eo = existing\n      if (payment != null) payment.eo = existing\n    }\n  }\n\n  private validateBasketMerges (): void {\n    if (!this.isMerge) return\n    for (const basket of this.basketInsertions) {\n      if (basket.eo != null && isManagedChangeOutput(basket.eo)) {\n        throw new WERR_INVALID_PARAMETER(\n          'outputs',\n          `output ${basket.vout} is wallet-managed change and cannot be reclassified as a basket insertion`\n        )\n      }\n    }\n  }\n\n  private computeWalletPaymentBalance (): void {\n    for (const payment of this.walletPayments) {\n      if (!this.isMerge || payment.eo == null) {\n        this.satoshis += payment.txo.satoshis!\n        continue\n      }\n      if (\n        isManagedChangeOutput(payment.eo) &&\n        payment.eo.basketId === this.changeBasket.basketId\n      ) {\n        payment.ignore = true\n        continue\n      }\n      this.satoshis += payment.txo.satoshis!\n    }\n  }\n\n  async asyncSetup (): Promise<void> {\n    ;({ ab: this.ab, tx: this.tx, txid: this.txid } = await this.validateAtomicBeef(this.args.tx))\n\n    for (const output of this.vargs.outputs) this.classifyRequestedOutput(output)\n\n    this.changeBasket = verifyOne(\n      await this.storage.findOutputBaskets({\n        partial: { userId: this.userId, name: 'default' }\n      })\n    )\n    this.baskets = {}\n    await this.loadExistingTransaction()\n    await this.linkExistingOutputs()\n    this.validateBasketMerges()\n    this.computeWalletPaymentBalance()\n  }\n\n  /**\n   * This is the second time the atomic beef is validated against a chaintracker.\n   * The first validation used the originating wallet's configured chaintracker.\n   * Now the chaintracker configured for this storage is used.\n   * These may be the same, or different.\n   *\n   * THIS DOES NOT GUARANTEE:\n   * 1. That the transaction has been broadcast. (Is known to the network).\n   * 2. That the proof(s) are for the same block as recorded in this storage in the event of a reorg.\n   *\n   * In the event of a reorg, we CAN assume that the proof contained in this beef should replace the proof in storage.\n   *\n   * @param atomicBeef\n   * @returns\n   */\n  async validateAtomicBeef (atomicBeef: number[] | Uint8Array) {\n    const ab = atomicBeef instanceof Uint8Array ? Beef.fromBinaryView(atomicBeef) : Beef.fromBinary(atomicBeef)\n    const txValid = await ab.verify(await this.storage.getServices().getChainTracker(), false)\n    if (!txValid || !ab.atomicTxid) throw new WERR_INVALID_PARAMETER('tx', 'valid AtomicBEEF')\n    const txid = ab.atomicTxid\n    const btx = ab.findTxid(txid)\n    if (btx == null) throw new WERR_INVALID_PARAMETER('tx', `valid AtomicBEEF with newest txid of ${txid}`)\n    const tx = btx.tx!\n\n\n    return { ab, tx, txid }\n  }\n\n  async findOrInsertTargetTransaction (satoshis: number, provenTx?: TableProvenTx): Promise<TableTransaction> {\n    const now = new Date()\n    const provenTxId = provenTx?.provenTxId\n    const status: TransactionStatus = (provenTx != null) ? 'completed' : 'unproven'\n    const newTx: TableTransaction = {\n      created_at: now,\n      updated_at: now,\n      transactionId: 0,\n\n      provenTxId,\n      status,\n\n      satoshis,\n\n      version: this.tx.version,\n      lockTime: this.tx.lockTime,\n      reference: randomBytesBase64(7),\n      userId: this.userId,\n      isOutgoing: false,\n      description: this.args.description,\n\n      inputBEEF: undefined,\n      txid: this.txid,\n      rawTx: undefined\n    }\n    const tr = await this.storage.findOrInsertTransaction(newTx)\n    if (!tr.isNew) {\n      if (!this.isMerge)\n      // For now, only allow transaction record to pre-exist if it was there at the start.\n      { throw new WERR_INVALID_PARAMETER('tx', 'target transaction of internalizeAction is undergoing active changes.') }\n      const update: Partial<TableTransaction> = { satoshis: tr.tx.satoshis + satoshis }\n      if (provenTx != null) {\n        update.provenTxId = provenTxId\n        update.status = status\n      }\n      await this.storage.updateTransaction(tr.tx.transactionId, update)\n    }\n    return tr.tx\n  }\n\n  private async findOrInsertProvenTxFromBump (bump: MerklePath, btx: BeefTx): Promise<TableProvenTx> {\n    const now = new Date()\n    const merkleRoot = bump.computeRoot(this.txid)\n    const indexEntry = bump.path[0].find(p => p.hash === this.txid)\n    if (indexEntry == null) {\n      throw new WERR_INTERNAL(\n        `Could not determine transaction index for txid ${this.txid} in bump path. Expected to find txid in bump.path[0]: ${JSON.stringify(bump.path[0])}`\n      )\n    }\n    const index = indexEntry.offset\n    const header = await this.storage.getServices().getHeaderForHeight(bump.blockHeight)\n    if (!header) {\n      throw new WERR_INTERNAL(`Block header not found for height ${bump.blockHeight}`)\n    }\n    const hash = blockHash(header)\n    const provenTxR = await this.storage.findOrInsertProvenTx({\n      created_at: now,\n      updated_at: now,\n      provenTxId: 0,\n      txid: this.txid,\n      height: bump.blockHeight,\n      index,\n      merklePath: bump.toBinary(),\n      rawTx: btx.rawTx!,\n      blockHash: hash,\n      merkleRoot\n    })\n    return provenTxR.proven\n  }\n\n  private async mergeWalletPayments (transactionId: number): Promise<void> {\n    for (const payment of this.walletPayments) {\n      if (payment.ignore) continue\n      if (payment.eo != null) {\n        await this.mergeWalletPaymentForOutput(transactionId, payment)\n      } else {\n        await this.storeNewWalletPaymentForOutput(transactionId, payment)\n      }\n    }\n  }\n\n  private async mergeBasketInsertions (transactionId: number): Promise<void> {\n    for (const basket of this.basketInsertions) {\n      if (basket.eo != null) {\n        await this.mergeBasketInsertionForOutput(transactionId, basket)\n      } else {\n        await this.storeNewBasketInsertionForOutput(transactionId, basket)\n      }\n    }\n  }\n\n  private async retireNoSendWithProof (\n    transactionId: number,\n    bump: MerklePath\n  ): Promise<void> {\n    const beefTx = this.ab.findTxid(this.txid)\n    if (beefTx == null) {\n      throw new WERR_INTERNAL(`Could not find transaction ${this.txid} in AtomicBEEF`)\n    }\n    const proven = await this.findOrInsertProvenTxFromBump(bump, beefTx)\n    await this.storage.updateTransaction(transactionId, {\n      provenTxId: proven.provenTxId,\n      status: 'completed'\n    })\n    const req = await EntityProvenTxReq.fromStorageTxid(this.storage, this.txid)\n    if (req?.status !== 'nosend') return\n    req.addHistoryNote({ what: 'internalizeAction-bumpRetire', userId: this.userId })\n    req.provenTxId = proven.provenTxId\n    req.status = 'completed'\n    await req.updateStorageDynamicProperties(this.storage)\n  }\n\n  private async retireNoSendWithoutProof (transactionId: number): Promise<void> {\n    await this.storage.updateTransaction(transactionId, { status: 'unproven' })\n    const req = await EntityProvenTxReq.fromStorageTxid(this.storage, this.txid)\n    if (req?.status !== 'nosend') return\n    req.addHistoryNote({ what: 'internalizeAction-nosendRetire', userId: this.userId })\n    req.status = 'unmined'\n    await req.updateStorageDynamicProperties(this.storage)\n  }\n\n  private async retireNoSendTransaction (transactionId: number): Promise<void> {\n    const bump = this.ab.findBump(this.txid)\n    if (bump != null) {\n      await this.retireNoSendWithProof(transactionId, bump)\n    } else {\n      await this.retireNoSendWithoutProof(transactionId)\n    }\n  }\n\n  async mergedInternalize () {\n    const transactionId = this.etx!.transactionId\n    const wasNoSend = this.etx!.status === 'nosend'\n\n    await this.addLabels(transactionId)\n\n    // Externally-broadcast txs internalized into a pre-existing storage\n    // record (typically a nosend created by this wallet) still need their\n    // consumed user UTXOs marked spent. createAction marks them when the\n    // tx is wallet-originated, but a nosend can be merged from a sender\n    // that doesn't share storage. Idempotent for the wallet-originated\n    // case — already-spent outputs are skipped.\n    await this.markInputsSpent(transactionId)\n\n    await this.mergeWalletPayments(transactionId)\n    await this.mergeBasketInsertions(transactionId)\n\n    // Lifecycle advance when merging into a tx that was 'nosend'.\n    //\n    // Background: an internalizeAction call against an existing tx in\n    // 'nosend' status is the caller asserting the tx has now been\n    // externally broadcast (and potentially mined if the BEEF includes\n    // a BUMP). Before this advance, mergedInternalize only updated\n    // labels + per-output ownership records and left transactions.status\n    // and proven_tx_reqs.status unchanged. The nosend state then had no\n    // reliable retirement path: TaskCheckNoSends's default daily cadence\n    // combined with intermittent wallet uptime meant the req could sit\n    // in 'nosend' indefinitely, and a subsequent abortAction call would\n    // unconditionally invalidate the on-chain tx — orphaning every\n    // output the tx produced.\n    //\n    // BUMP-present path: mirror newInternalize's findOrInsertProvenTx\n    // path, then promote the existing transaction record to 'completed'\n    // with the new provenTxId and retire the proven_tx_req to\n    // 'completed' too.\n    //\n    // BUMP-absent path: promote transactions.status to 'unproven' (so\n    // listOutputs filters the tx's outputs into the spendable set\n    // immediately) and transition the proven_tx_req to 'unmined' so\n    // TaskCheckForProofs picks it up on its next nudge cycle. This\n    // hands off to Monitor's standard proof-fetching flow.\n    if (wasNoSend) await this.retireNoSendTransaction(transactionId)\n  }\n\n  /**\n   * internalize output(s) from a transaction with txid unknown to storage.\n   */\n  async newInternalize () {\n    // Check if the transaction has a merkle path proof (BUMP)\n    const btx = this.ab.findTxid(this.txid)\n    if (btx == null) throw new WERR_INTERNAL(`Could not find transaction ${this.txid} in AtomicBEEF`)\n    const bump = this.ab.findBump(this.txid)\n\n    let pr: StorageProvenOrReq = { isNew: false, proven: undefined, req: undefined }\n\n    if (bump != null) {\n      // The presence bump indicates the transaction has already been mined.\n      // Verify a provenTx record exist before creating a new transaction with completed status...\n      // Which normally means creating a new provenTx record.\n      pr.proven = await this.findOrInsertProvenTxFromBump(bump, btx)\n    }\n\n    this.etx = await this.findOrInsertTargetTransaction(this.satoshis, pr.proven)\n\n    const transactionId = this.etx.transactionId\n\n    // Mark any user-owned outputs the incoming tx consumes as spent BEFORE\n    // attempting broadcast. If broadcast fails we restore them below.\n    await this.markInputsSpent(transactionId)\n\n    if (pr.proven == null) {\n      // beef doesn't include proof of mining for the transaction (etx).\n      // the new transaction record has been added to storage, but (baring race conditions)\n      // there should be no provenTx or provenTxReq records for this txid.\n      //\n      // Attempt to create a provenTxReq record for the txid to obtain a proof,\n      // while allowing for possible race conditions...\n      const newReq = EntityProvenTxReq.fromTxid(this.txid, this.tx.toBinary(), Utils.toArray(this.args.tx))\n      newReq.status = 'unsent'\n      // this history and notify will be merged into an existing req if it exists.\n      newReq.addHistoryNote({ what: 'internalizeAction', userId: this.userId })\n      newReq.addNotifyTransactionId(transactionId)\n      pr = await this.storage.getProvenOrReq(this.txid, newReq.toApi())\n    }\n\n    if (pr.isNew) {\n      // This storage didn't know about this txid and the beef didn't include a mining proof.\n      // Assume the transaction has never been broadcast.\n      // Attempt to broadcast it to the network, throwing an error if it fails.\n\n      // Skip looking up txids and building an aggregate beef,\n      // just this one txid and the already validated atomic beef.\n      // The beef may contain additional unbroadcast transactions which\n      // we don't care about.\n      const r: GetReqsAndBeefResult = {\n        beef: this.ab,\n        details: [{ txid: this.txid, status: 'readyToSend', req: pr.req }]\n      }\n      const { swr, ndr } = await shareReqsWithWorld(this.storage, this.userId, [], false, r)\n      if (ndr![0].status !== 'success') {\n        // Roll back the spendable=true → false transitions performed above\n        // so the caller can retry with the same UTXOs. Idempotent w.r.t.\n        // attemptToPostReqsToNetwork's own updateTransactionStatus('failed')\n        // restore on doubleSpend/invalidTx outcomes.\n        await this.restoreSpentInputs()\n        this.r.sendWithResults = swr\n        this.r.notDelayedResults = ndr\n        // abort the internalize action, WERR_REVIEW_ACTIONS exception will be thrown\n        return\n      }\n    }\n\n    await this.addLabels(transactionId)\n\n    for (const payment of this.walletPayments) {\n      await this.storeNewWalletPaymentForOutput(transactionId, payment)\n    }\n\n    for (const basket of this.basketInsertions) {\n      await this.storeNewBasketInsertionForOutput(transactionId, basket)\n    }\n  }\n\n  async addLabels (transactionId: number) {\n    for (const label of this.vargs.labels) {\n      const txLabel = await this.storage.findOrInsertTxLabel(this.userId, label)\n      await this.storage.findOrInsertTxLabelMap(verifyId(transactionId), verifyId(txLabel.txLabelId))\n    }\n  }\n\n  async markInputsSpent (transactionId: number): Promise<void> {\n    const transitioned = await markUserInputsSpent(this.storage, this.userId, this.tx, transactionId)\n    this.spentInputs.push(...transitioned)\n  }\n\n  async restoreSpentInputs (): Promise<void> {\n    await restoreInputsToSpendable(this.storage, this.spentInputs)\n    this.spentInputs = []\n  }\n\n  async addBasketTags (basket: BasketInsertionX, outputId: number) {\n    for (const tag of basket.tags || []) {\n      await this.storage.tagOutput({ outputId, userId: this.userId }, tag)\n    }\n  }\n\n  async storeNewWalletPaymentForOutput (transactionId: number, payment: WalletPaymentX): Promise<void> {\n    const now = new Date()\n    const txOut: TableOutput = {\n      created_at: now,\n      updated_at: now,\n      outputId: 0,\n      transactionId,\n      userId: this.userId,\n      spendable: true,\n      lockingScript: payment.txo.lockingScript.toBinary(),\n      vout: payment.vout,\n      basketId: this.changeBasket.basketId,\n      satoshis: payment.txo.satoshis!,\n      txid: this.txid,\n      senderIdentityKey: payment.senderIdentityKey,\n      type: 'P2PKH',\n      providedBy: 'storage',\n      purpose: 'change',\n      derivationPrefix: payment.derivationPrefix,\n      derivationSuffix: payment.derivationSuffix,\n\n      change: true,\n      spentBy: undefined,\n      customInstructions: undefined,\n      outputDescription: '',\n      spendingDescription: undefined\n    }\n    txOut.outputId = await this.storage.insertOutput(txOut)\n    payment.eo = txOut\n  }\n\n  async mergeWalletPaymentForOutput (transactionId: number, payment: WalletPaymentX) {\n    const outputId = payment.eo!.outputId\n    const update: Partial<TableOutput> = {\n      basketId: this.changeBasket.basketId,\n      type: 'P2PKH',\n      customInstructions: undefined,\n      change: true,\n      providedBy: 'storage',\n      purpose: 'change',\n      senderIdentityKey: payment.senderIdentityKey,\n      derivationPrefix: payment.derivationPrefix,\n      derivationSuffix: payment.derivationSuffix\n    }\n    await this.storage.updateOutput(outputId, update)\n    payment.eo = { ...payment.eo!, ...update }\n  }\n\n  async mergeBasketInsertionForOutput (transactionId: number, basket: BasketInsertionX) {\n    const outputId = basket.eo!.outputId\n    const update: Partial<TableOutput> = {\n      basketId: (await this.getBasket(basket.basket)).basketId,\n      type: 'custom',\n      customInstructions: basket.customInstructions,\n      change: false,\n      providedBy: 'you',\n      purpose: '',\n      senderIdentityKey: undefined,\n      derivationPrefix: undefined,\n      derivationSuffix: undefined\n    }\n    await this.storage.updateOutput(outputId, update)\n    basket.eo = { ...basket.eo!, ...update }\n  }\n\n  async storeNewBasketInsertionForOutput (transactionId: number, basket: BasketInsertionX): Promise<void> {\n    const now = new Date()\n    const txOut: TableOutput = {\n      created_at: now,\n      updated_at: now,\n      outputId: 0,\n      transactionId,\n      userId: this.userId,\n      spendable: true,\n      lockingScript: basket.txo.lockingScript.toBinary(),\n      vout: basket.vout,\n      basketId: (await this.getBasket(basket.basket)).basketId,\n      satoshis: basket.txo.satoshis!,\n      txid: this.txid,\n      type: 'custom',\n      customInstructions: basket.customInstructions,\n\n      change: false,\n      spentBy: undefined,\n      outputDescription: '',\n      spendingDescription: undefined,\n\n      providedBy: 'you',\n      purpose: '',\n\n      senderIdentityKey: undefined,\n      derivationPrefix: undefined,\n      derivationSuffix: undefined\n    }\n    txOut.outputId = await this.storage.insertOutput(txOut)\n\n    await this.addBasketTags(basket, txOut.outputId)\n\n    basket.eo = txOut\n  }\n}\n","import { StorageReader } from '../StorageReader'\nimport { TableProvenTx } from '../schema/tables/TableProvenTx'\nimport { TableProvenTxReq } from '../schema/tables/TableProvenTxReq'\nimport { TableCertificate } from '../schema/tables/TableCertificate'\nimport { TableCertificateField } from '../schema/tables/TableCertificateField'\nimport { TableOutputBasket } from '../schema/tables/TableOutputBasket'\nimport { TableTransaction } from '../schema/tables/TableTransaction'\nimport { TableOutput } from '../schema/tables/TableOutput'\nimport { TableOutputTag } from '../schema/tables/TableOutputTag'\nimport { TableOutputTagMap } from '../schema/tables/TableOutputTagMap'\nimport { TableTxLabel } from '../schema/tables/TableTxLabel'\nimport { TableTxLabelMap } from '../schema/tables/TableTxLabelMap'\nimport { TableCommission } from '../schema/tables/TableCommission'\nimport { FindForUserSincePagedArgs, RequestSyncChunkArgs, SyncChunk } from '../../sdk/WalletStorage.interfaces'\nimport { verifyTruthy } from '../../utility/utilityHelpers'\nimport { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\n\n/**\n * Gets the next sync chunk of updated data from un-remoted storage (could be using a remote DB connection).\n * @param storage\n * @param args\n * @returns\n */\nexport async function getSyncChunk(storage: StorageReader, args: RequestSyncChunkArgs): Promise<SyncChunk> {\n  const r: SyncChunk = {\n    fromStorageIdentityKey: args.fromStorageIdentityKey,\n    toStorageIdentityKey: args.toStorageIdentityKey,\n    userIdentityKey: args.identityKey\n  }\n\n  let itemCount = args.maxItems\n  let roughSize = args.maxRoughSize\n  let i = 0\n  let done = false\n\n  const user = verifyTruthy(await storage.findUserByIdentityKey(args.identityKey))\n  if (args.since == null || user.updated_at > new Date(args.since)) r.user = user\n\n  const chunkers: ChunkerArgs[] = [\n    {\n      name: 'provenTx',\n      maxDivider: 100,\n      preAdd: () => {\n        r.provenTxs = []\n      },\n      addItem: (i: TableProvenTx) => {\n        r.provenTxs!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.getProvenTxsForUser(args)\n      }\n    },\n    {\n      name: 'outputBasket',\n      maxDivider: 1,\n      preAdd: () => {\n        r.outputBaskets = []\n      },\n      addItem: (i: TableOutputBasket) => {\n        r.outputBaskets!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.findOutputBaskets({\n          partial: { userId: args.userId },\n          since: args.since,\n          paged: args.paged\n        })\n      }\n    },\n    {\n      name: 'outputTag',\n      maxDivider: 1,\n      preAdd: () => {\n        r.outputTags = []\n      },\n      addItem: (i: TableOutputTag) => {\n        r.outputTags!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.findOutputTags({\n          partial: { userId: args.userId },\n          since: args.since,\n          paged: args.paged\n        })\n      }\n    },\n    {\n      name: 'txLabel',\n      maxDivider: 1,\n      preAdd: () => {\n        r.txLabels = []\n      },\n      addItem: (i: TableTxLabel) => {\n        r.txLabels!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.findTxLabels({\n          partial: { userId: args.userId },\n          since: args.since,\n          paged: args.paged\n        })\n      }\n    },\n    {\n      name: 'transaction',\n      maxDivider: 25,\n      preAdd: () => {\n        r.transactions = []\n      },\n      addItem: (i: TableTransaction) => {\n        r.transactions!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.findTransactions({\n          partial: { userId: args.userId },\n          since: args.since,\n          paged: args.paged\n        })\n      }\n    },\n    {\n      name: 'output',\n      maxDivider: 25,\n      preAdd: () => {\n        r.outputs = []\n      },\n      addItem: (i: TableOutput) => {\n        r.outputs!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.findOutputs({\n          partial: { userId: args.userId },\n          since: args.since,\n          paged: args.paged\n        })\n      }\n    },\n    {\n      name: 'txLabelMap',\n      maxDivider: 1,\n      preAdd: () => {\n        r.txLabelMaps = []\n      },\n      addItem: (i: TableTxLabelMap) => {\n        r.txLabelMaps!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.getTxLabelMapsForUser(args)\n      }\n    },\n    {\n      name: 'outputTagMap',\n      maxDivider: 1,\n      preAdd: () => {\n        r.outputTagMaps = []\n      },\n      addItem: (i: TableOutputTagMap) => {\n        r.outputTagMaps!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.getOutputTagMapsForUser(args)\n      }\n    },\n    {\n      name: 'certificate',\n      maxDivider: 25,\n      preAdd: () => {\n        r.certificates = []\n      },\n      addItem: (i: TableCertificate) => {\n        r.certificates!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.findCertificates({\n          partial: { userId: args.userId },\n          since: args.since,\n          paged: args.paged\n        })\n      }\n    },\n    {\n      name: 'certificateField',\n      maxDivider: 25,\n      preAdd: () => {\n        r.certificateFields = []\n      },\n      addItem: (i: TableCertificateField) => {\n        r.certificateFields!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.findCertificateFields({\n          partial: { userId: args.userId },\n          since: args.since,\n          paged: args.paged\n        })\n      }\n    },\n    {\n      name: 'commission',\n      maxDivider: 25,\n      preAdd: () => {\n        r.commissions = []\n      },\n      addItem: (i: TableCommission) => {\n        r.commissions!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.findCommissions({\n          partial: { userId: args.userId },\n          since: args.since,\n          paged: args.paged\n        })\n      }\n    },\n    {\n      name: 'provenTxReq',\n      maxDivider: 100,\n      preAdd: () => {\n        r.provenTxReqs = []\n      },\n      addItem: (i: TableProvenTxReq) => {\n        r.provenTxReqs!.push(i)\n      },\n      findItems: async (storage: StorageReader, args: FindForUserSincePagedArgs) => {\n        return await storage.getProvenTxReqsForUser(args)\n      }\n    }\n  ]\n\n  const addItems = async (a: ChunkerArgs) => {\n    if (i >= args.offsets.length) {\n      done = true\n      return\n    }\n    let { offset, name: oname } = args.offsets[i++]\n    if (a.name !== oname) {\n      throw new WERR_INVALID_PARAMETER('offsets', `in dependency order. '${a.name}' expected, found ${oname}.`)\n    }\n    let preAddCalled = false\n    while (!done) {\n      const limit = Math.min(itemCount, Math.max(10, args.maxItems / a.maxDivider))\n      if (limit <= 0) break\n      const items = await a.findItems(storage, {\n        userId: user.userId,\n        since: args.since,\n        paged: { limit, offset }\n      })\n      checkEntityValues(items)\n      if (!preAddCalled) {\n        a.preAdd()\n        preAddCalled = true\n      }\n      if (items.length === 0) break\n      for (const item of items) {\n        offset++\n        a.addItem(item)\n        itemCount--\n        roughSize -= JSON.stringify(item).length\n        if (itemCount <= 0 || roughSize < 0) {\n          done = true\n          break\n        }\n      }\n    }\n  }\n\n  while (!done) {\n    for (const c of chunkers) {\n      await addItems(c)\n    }\n  }\n\n  return r\n}\n\ninterface ChunkerArgs {\n  name: string\n  maxDivider: number\n  preAdd: () => void\n  addItem: (i: any) => void\n  findItems: (storage: StorageReader, args: FindForUserSincePagedArgs) => Promise<any[]>\n}\n\nfunction checkIsDate(v: any) {\n  if (!(v instanceof Date)) throw new WERR_INVALID_OPERATION('bad date')\n}\n\nfunction checkEntityValues(es: object[]) {\n  for (const e of es) {\n    const entity = e as Record<string, unknown>\n    checkIsDate(entity.created_at)\n    checkIsDate(entity.updated_at)\n    for (const key of Object.keys(entity)) {\n      if (entity[key] === null) throw new WERR_INVALID_OPERATION()\n    }\n  }\n}\n","import {\n  TableCertificateField,\n  TableCertificateX,\n  TableCommission,\n  TableMonitorEvent,\n  TableOutput,\n  TableOutputBasket,\n  TableOutputTag,\n  TableOutputTagMap,\n  TableProvenTx,\n  TableProvenTxReq,\n  TableSettings,\n  TableSyncState,\n  TableTransaction,\n  TableTxLabel,\n  TableTxLabelMap,\n  TableUser\n} from './schema/tables'\nimport * as sdk from '../sdk/index'\nimport { validateSecondsSinceEpoch, verifyOneOrNone, verifyTruthy } from '../utility/utilityHelpers'\nimport { getSyncChunk } from './methods/getSyncChunk'\nimport { Telemetry, TelemetryConfig } from '@bsv/sdk'\n\ntype StorageDate = Date | string\ntype DateInput = Date | string | number\ntype OptionalDateInput = DateInput | null | undefined\n\n/**\n * The `StorageReader` abstract class is the base of the concrete wallet storage provider classes.\n *\n * It is the minimal interface required to read all wallet state records and is the base class for sync readers.\n *\n * The next class in the heirarchy is the `StorageReaderWriter` which supports sync readers and writers.\n *\n * The last class in the heirarchy is the `Storage` class which supports all active wallet operations.\n *\n * The ability to construct a properly configured instance of this class implies authentication.\n * As such there are no user specific authenticated access checks implied in the implementation of any of these methods.\n */\nexport abstract class StorageReader implements sdk.WalletStorageSyncReader {\n  chain: sdk.Chain\n  readonly telemetry: Telemetry\n  _settings?: TableSettings\n  whenLastAccess?: Date\n  get dbtype (): DBType | undefined {\n    return this._settings?.dbtype\n  }\n\n  constructor (options: StorageReaderOptions) {\n    this.chain = options.chain\n    this.telemetry = new Telemetry(options.telemetry)\n  }\n\n  isAvailable (): boolean {\n    return this._settings != null\n  }\n\n  async makeAvailable (): Promise<TableSettings> {\n    if (this._settings != null) return this._settings\n    this._settings = await this.readSettings()\n    return this._settings\n  }\n\n  getSettings (): TableSettings {\n    if (this._settings == null) throw new sdk.WERR_INVALID_OPERATION('must call \"makeAvailable\" before accessing \"settings\"')\n    return this._settings\n  }\n\n  isStorageProvider (): boolean {\n    return false\n  }\n\n  abstract destroy (): Promise<void>\n\n  abstract transaction<T>(scope: (trx: sdk.TrxToken) => Promise<T>, trx?: sdk.TrxToken): Promise<T>\n\n  abstract readSettings (trx?: sdk.TrxToken): Promise<TableSettings>\n\n  abstract findCertificateFields (args: sdk.FindCertificateFieldsArgs): Promise<TableCertificateField[]>\n  abstract findCertificates (args: sdk.FindCertificatesArgs): Promise<TableCertificateX[]>\n  abstract findCommissions (args: sdk.FindCommissionsArgs): Promise<TableCommission[]>\n  abstract findMonitorEvents (args: sdk.FindMonitorEventsArgs): Promise<TableMonitorEvent[]>\n  abstract findOutputBaskets (args: sdk.FindOutputBasketsArgs): Promise<TableOutputBasket[]>\n  abstract findOutputs (args: sdk.FindOutputsArgs): Promise<TableOutput[]>\n  abstract findOutputTags (args: sdk.FindOutputTagsArgs): Promise<TableOutputTag[]>\n  abstract findSyncStates (args: sdk.FindSyncStatesArgs): Promise<TableSyncState[]>\n  abstract findTransactions (args: sdk.FindTransactionsArgs): Promise<TableTransaction[]>\n  abstract findTxLabels (args: sdk.FindTxLabelsArgs): Promise<TableTxLabel[]>\n  abstract findUsers (args: sdk.FindUsersArgs): Promise<TableUser[]>\n\n  abstract countCertificateFields (args: sdk.FindCertificateFieldsArgs): Promise<number>\n  abstract countCertificates (args: sdk.FindCertificatesArgs): Promise<number>\n  abstract countCommissions (args: sdk.FindCommissionsArgs): Promise<number>\n  abstract countMonitorEvents (args: sdk.FindMonitorEventsArgs): Promise<number>\n  abstract countOutputBaskets (args: sdk.FindOutputBasketsArgs): Promise<number>\n  abstract countOutputs (args: sdk.FindOutputsArgs): Promise<number>\n  abstract countOutputTags (args: sdk.FindOutputTagsArgs): Promise<number>\n  abstract countSyncStates (args: sdk.FindSyncStatesArgs): Promise<number>\n  abstract countTransactions (args: sdk.FindTransactionsArgs): Promise<number>\n  abstract countTxLabels (args: sdk.FindTxLabelsArgs): Promise<number>\n  abstract countUsers (args: sdk.FindUsersArgs): Promise<number>\n\n  abstract getProvenTxsForUser (args: sdk.FindForUserSincePagedArgs): Promise<TableProvenTx[]>\n  abstract getProvenTxReqsForUser (args: sdk.FindForUserSincePagedArgs): Promise<TableProvenTxReq[]>\n  abstract getTxLabelMapsForUser (args: sdk.FindForUserSincePagedArgs): Promise<TableTxLabelMap[]>\n  abstract getOutputTagMapsForUser (args: sdk.FindForUserSincePagedArgs): Promise<TableOutputTagMap[]>\n\n  async findUserByIdentityKey (key: string): Promise<TableUser | undefined> {\n    return verifyOneOrNone(await this.findUsers({ partial: { identityKey: key } }))\n  }\n\n  async getSyncChunk (args: sdk.RequestSyncChunkArgs): Promise<sdk.SyncChunk> {\n    return await getSyncChunk(this, args)\n  }\n\n  /**\n   * Force dates to strings on SQLite and Date objects on MySQL\n   * @param date\n   * @returns\n   */\n  validateEntityDate (date: DateInput): StorageDate {\n    if (this.dbtype == null) throw new sdk.WERR_INTERNAL('must call verifyReadyForDatabaseAccess first')\n    let r: StorageDate = this.validateDate(date)\n    switch (this.dbtype) {\n      case 'IndexedDB':\n      case 'MySQL':\n        break\n      case 'SQLite':\n        r = r.toISOString()\n        break\n      default:\n        throw new sdk.WERR_INTERNAL(`Invalid dateScheme ${String(this.dbtype)}`)\n    }\n    return r\n  }\n\n  /**\n   *\n   * @param date\n   * @param useNowAsDefault if true and date is null or undefiend, set to current time.\n   * @returns\n   */\n  validateOptionalEntityDate (\n    date: OptionalDateInput,\n    useNowAsDefault?: boolean\n  ): StorageDate | undefined {\n    if (this.dbtype == null) throw new sdk.WERR_INTERNAL('must call verifyReadyForDatabaseAccess first')\n    let r: StorageDate | undefined = this.validateOptionalDate(date)\n    if ((r == null) && (useNowAsDefault === true)) r = new Date()\n    switch (this.dbtype) {\n      case 'IndexedDB':\n      case 'MySQL':\n        break\n      case 'SQLite':\n        if (r != null) r = r.toISOString()\n        break\n      default:\n        throw new sdk.WERR_INTERNAL(`Invalid dateScheme ${String(this.dbtype)}`)\n    }\n    return r\n  }\n\n  validateDate (date: DateInput): Date {\n    let r: Date\n    if (date instanceof Date) r = date\n    else r = new Date(date)\n    return r\n  }\n\n  validateOptionalDate (date: OptionalDateInput): Date | undefined {\n    if (date === null || date === undefined) return undefined\n    return this.validateDate(date)\n  }\n\n  validateDateForWhere (date: DateInput): DateInput {\n    if (this.dbtype == null) throw new sdk.WERR_INTERNAL('must call verifyReadyForDatabaseAccess first')\n    if (typeof date === 'number') date = validateSecondsSinceEpoch(date)\n    const vdate = verifyTruthy(this.validateDate(date))\n    let r: DateInput\n    switch (this.dbtype) {\n      case 'IndexedDB':\n      case 'MySQL':\n        r = vdate\n        break\n      case 'SQLite':\n        r = vdate.toISOString()\n        break\n      default:\n        throw new sdk.WERR_INTERNAL(`Invalid dateScheme ${String(this.dbtype)}`)\n    }\n    return r\n  }\n}\n\nexport interface StorageReaderOptions {\n  chain: sdk.Chain\n  /** Optional provider-neutral storage and database tracing. */\n  telemetry?: TelemetryConfig\n}\n\nexport type DBType = 'SQLite' | 'MySQL' | 'IndexedDB'\n","import { TableCertificate } from './schema/tables/TableCertificate'\nimport { TableCertificateField } from './schema/tables/TableCertificateField'\nimport { TableCommission } from './schema/tables/TableCommission'\nimport { TableMonitorEvent } from './schema/tables/TableMonitorEvent'\nimport { TableOutput } from './schema/tables/TableOutput'\nimport { TableOutputBasket } from './schema/tables/TableOutputBasket'\nimport { TableOutputTag } from './schema/tables/TableOutputTag'\nimport { TableOutputTagMap } from './schema/tables/TableOutputTagMap'\nimport { TableProvenTx } from './schema/tables/TableProvenTx'\nimport { TableProvenTxReq } from './schema/tables/TableProvenTxReq'\nimport { TableSyncState } from './schema/tables/TableSyncState'\nimport { TableTransaction } from './schema/tables/TableTransaction'\nimport { TableTxLabel } from './schema/tables/TableTxLabel'\nimport { TableTxLabelMap } from './schema/tables/TableTxLabelMap'\nimport { TableUser } from './schema/tables/TableUser'\nimport { randomBytesBase64, verifyOneOrNone, verifyId, verifyOne } from '../utility/utilityHelpers'\nimport { StorageReader, StorageReaderOptions } from './StorageReader'\nimport {\n  AuthId,\n  FindOutputTagMapsArgs,\n  FindProvenTxReqsArgs,\n  FindProvenTxsArgs,\n  FindStaleMerkleRootsArgs,\n  FindTxLabelMapsArgs,\n  ProcessSyncChunkResult,\n  RequestSyncChunkArgs,\n  SyncChunk,\n  TrxToken\n} from '../sdk/WalletStorage.interfaces'\nimport { createSyncMap } from './schema/entities/EntityBase'\n\nexport abstract class StorageReaderWriter extends StorageReader {\n  abstract dropAllData (): Promise<void>\n  abstract migrate (storageName: string, storageIdentityKey: string): Promise<string>\n\n  abstract findOutputTagMaps (args: FindOutputTagMapsArgs): Promise<TableOutputTagMap[]>\n  abstract findProvenTxReqs (args: FindProvenTxReqsArgs): Promise<TableProvenTxReq[]>\n  abstract findProvenTxs (args: FindProvenTxsArgs): Promise<TableProvenTx[]>\n  abstract findTxLabelMaps (args: FindTxLabelMapsArgs): Promise<TableTxLabelMap[]>\n\n  abstract findStaleMerkleRoots (args: FindStaleMerkleRootsArgs): Promise<string[]>\n\n  abstract countOutputTagMaps (args: FindOutputTagMapsArgs): Promise<number>\n  abstract countProvenTxReqs (args: FindProvenTxReqsArgs): Promise<number>\n  abstract countProvenTxs (args: FindProvenTxsArgs): Promise<number>\n  abstract countTxLabelMaps (args: FindTxLabelMapsArgs): Promise<number>\n\n  abstract insertCertificate (certificate: TableCertificate, trx?: TrxToken): Promise<number>\n  abstract insertCertificateField (certificateField: TableCertificateField, trx?: TrxToken): Promise<void>\n  abstract insertCommission (commission: TableCommission, trx?: TrxToken): Promise<number>\n  abstract insertMonitorEvent (event: TableMonitorEvent, trx?: TrxToken): Promise<number>\n  abstract insertOutput (output: TableOutput, trx?: TrxToken): Promise<number>\n  abstract insertOutputBasket (basket: TableOutputBasket, trx?: TrxToken): Promise<number>\n  abstract insertOutputTag (tag: TableOutputTag, trx?: TrxToken): Promise<number>\n  abstract insertOutputTagMap (tagMap: TableOutputTagMap, trx?: TrxToken): Promise<void>\n  abstract insertProvenTx (tx: TableProvenTx, trx?: TrxToken): Promise<number>\n  abstract insertProvenTxReq (tx: TableProvenTxReq, trx?: TrxToken): Promise<number>\n  abstract insertSyncState (syncState: TableSyncState, trx?: TrxToken): Promise<number>\n  abstract insertTransaction (tx: TableTransaction, trx?: TrxToken): Promise<number>\n  abstract insertTxLabel (label: TableTxLabel, trx?: TrxToken): Promise<number>\n  abstract insertTxLabelMap (labelMap: TableTxLabelMap, trx?: TrxToken): Promise<void>\n  abstract insertUser (user: TableUser, trx?: TrxToken): Promise<number>\n\n  abstract updateCertificate (id: number, update: Partial<TableCertificate>, trx?: TrxToken): Promise<number>\n  abstract updateCertificateField (\n    certificateId: number,\n    fieldName: string,\n    update: Partial<TableCertificateField>,\n    trx?: TrxToken\n  ): Promise<number>\n  abstract updateCommission (id: number, update: Partial<TableCommission>, trx?: TrxToken): Promise<number>\n  abstract updateMonitorEvent (id: number, update: Partial<TableMonitorEvent>, trx?: TrxToken): Promise<number>\n  abstract updateOutput (id: number, update: Partial<TableOutput>, trx?: TrxToken): Promise<number>\n  abstract updateOutputBasket (id: number, update: Partial<TableOutputBasket>, trx?: TrxToken): Promise<number>\n  abstract updateOutputTag (id: number, update: Partial<TableOutputTag>, trx?: TrxToken): Promise<number>\n  abstract updateOutputTagMap (\n    outputId: number,\n    tagId: number,\n    update: Partial<TableOutputTagMap>,\n    trx?: TrxToken\n  ): Promise<number>\n  abstract updateProvenTx (id: number, update: Partial<TableProvenTx>, trx?: TrxToken): Promise<number>\n  abstract updateProvenTxReq (id: number | number[], update: Partial<TableProvenTxReq>, trx?: TrxToken): Promise<number>\n  abstract updateSyncState (id: number, update: Partial<TableSyncState>, trx?: TrxToken): Promise<number>\n  abstract updateTransaction (id: number | number[], update: Partial<TableTransaction>, trx?: TrxToken): Promise<number>\n  abstract updateTxLabel (id: number, update: Partial<TableTxLabel>, trx?: TrxToken): Promise<number>\n  abstract updateTxLabelMap (\n    transactionId: number,\n    txLabelId: number,\n    update: Partial<TableTxLabelMap>,\n    trx?: TrxToken\n  ): Promise<number>\n  abstract updateUser (id: number, update: Partial<TableUser>, trx?: TrxToken): Promise<number>\n\n  async setActive (auth: AuthId, newActiveStorageIdentityKey: string): Promise<number> {\n    return await this.updateUser(verifyId(auth.userId), {\n      activeStorage: newActiveStorageIdentityKey\n    })\n  }\n\n  async findCertificateById (id: number, trx?: TrxToken): Promise<TableCertificate | undefined> {\n    return verifyOneOrNone(await this.findCertificates({ partial: { certificateId: id }, trx }))\n  }\n\n  async findCommissionById (id: number, trx?: TrxToken): Promise<TableCommission | undefined> {\n    return verifyOneOrNone(await this.findCommissions({ partial: { commissionId: id }, trx }))\n  }\n\n  async findOutputById (id: number, trx?: TrxToken, noScript?: boolean): Promise<TableOutput | undefined> {\n    return verifyOneOrNone(await this.findOutputs({ partial: { outputId: id }, noScript, trx }))\n  }\n\n  async findOutputBasketById (id: number, trx?: TrxToken): Promise<TableOutputBasket | undefined> {\n    return verifyOneOrNone(await this.findOutputBaskets({ partial: { basketId: id }, trx }))\n  }\n\n  async findProvenTxById (id: number, trx?: TrxToken | undefined): Promise<TableProvenTx | undefined> {\n    return verifyOneOrNone(await this.findProvenTxs({ partial: { provenTxId: id }, trx }))\n  }\n\n  async findProvenTxReqById (id: number, trx?: TrxToken | undefined): Promise<TableProvenTxReq | undefined> {\n    return verifyOneOrNone(await this.findProvenTxReqs({ partial: { provenTxReqId: id }, trx }))\n  }\n\n  async findSyncStateById (id: number, trx?: TrxToken): Promise<TableSyncState | undefined> {\n    return verifyOneOrNone(await this.findSyncStates({ partial: { syncStateId: id }, trx }))\n  }\n\n  async findTransactionById (id: number, trx?: TrxToken, noRawTx?: boolean): Promise<TableTransaction | undefined> {\n    return verifyOneOrNone(\n      await this.findTransactions({\n        partial: { transactionId: id },\n        noRawTx,\n        trx\n      })\n    )\n  }\n\n  async findTxLabelById (id: number, trx?: TrxToken): Promise<TableTxLabel | undefined> {\n    return verifyOneOrNone(await this.findTxLabels({ partial: { txLabelId: id }, trx }))\n  }\n\n  async findOutputTagById (id: number, trx?: TrxToken): Promise<TableOutputTag | undefined> {\n    return verifyOneOrNone(await this.findOutputTags({ partial: { outputTagId: id }, trx }))\n  }\n\n  async findUserById (id: number, trx?: TrxToken): Promise<TableUser | undefined> {\n    return verifyOneOrNone(await this.findUsers({ partial: { userId: id }, trx }))\n  }\n\n  async findOrInsertUser (identityKey: string, trx?: TrxToken): Promise<{ user: TableUser, isNew: boolean }> {\n    let user: TableUser | undefined\n    let isNew = false\n    for (let retry = 0; ; retry++) {\n      try {\n        user = verifyOneOrNone(await this.findUsers({ partial: { identityKey }, trx }))\n        // console.log(`findOrInsertUser oneOrNone: ${JSON.stringify(user || 'none').slice(0,512)}`)\n        if (user != null) break\n        const now = new Date()\n        user = {\n          created_at: now,\n          updated_at: new Date('1971-01-01'), // Default constructed user, sync will override with any updated user.\n          userId: 0,\n          identityKey,\n          activeStorage: this.getSettings().storageIdentityKey\n        }\n        user.userId = await this.insertUser(user, trx)\n        isNew = true\n        // Add default change basket for new user.\n        await this.insertOutputBasket({\n          created_at: now,\n          updated_at: new Date('1971-01-01'), // Default constructed basket, sync will override with any updated basket.\n          basketId: 0,\n          userId: user.userId,\n          name: 'default',\n          numberOfDesiredUTXOs: 144,\n          minimumDesiredUTXOValue: 32,\n          isDeleted: false\n        })\n        break\n      } catch (error_: unknown) {\n        console.log(`findOrInsertUser catch: ${JSON.stringify(error_).slice(0, 512)}`)\n        if (retry > 0) throw error_\n      }\n    }\n    return { user, isNew }\n  }\n\n  async findOrInsertTransaction (\n    newTx: TableTransaction,\n    trx?: TrxToken\n  ): Promise<{ tx: TableTransaction, isNew: boolean }> {\n    let tx: TableTransaction | undefined\n    let isNew = false\n    for (let retry = 0; ; retry++) {\n      try {\n        tx = verifyOneOrNone(\n          await this.findTransactions({\n            partial: { userId: newTx.userId, txid: newTx.txid },\n            trx\n          })\n        )\n        if (tx != null) break\n        newTx.transactionId = await this.insertTransaction(newTx, trx)\n        isNew = true\n        tx = newTx\n        break\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n    return { tx, isNew }\n  }\n\n  async findOrInsertOutputBasket (userId: number, name: string, trx?: TrxToken): Promise<TableOutputBasket> {\n    const partial = { name, userId }\n    for (let retry = 0; ; retry++) {\n      try {\n        const now = new Date()\n        let basket = verifyOneOrNone(await this.findOutputBaskets({ partial, trx }))\n        if (basket == null) {\n          basket = {\n            ...partial,\n            minimumDesiredUTXOValue: 0,\n            numberOfDesiredUTXOs: 0,\n            basketId: 0,\n            created_at: now,\n            updated_at: now,\n            isDeleted: false\n          }\n          basket.basketId = await this.insertOutputBasket(basket, trx)\n        }\n        if (basket.isDeleted) {\n          await this.updateOutputBasket(verifyId(basket.basketId), {\n            isDeleted: false\n          })\n        }\n        return basket\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n  }\n\n  async findOrInsertTxLabel (userId: number, label: string, trx?: TrxToken): Promise<TableTxLabel> {\n    const partial = { label, userId }\n    for (let retry = 0; ; retry++) {\n      try {\n        const now = new Date()\n        let txLabel = verifyOneOrNone(await this.findTxLabels({ partial, trx }))\n        if (txLabel == null) {\n          txLabel = {\n            ...partial,\n            txLabelId: 0,\n            created_at: now,\n            updated_at: now,\n            isDeleted: false\n          }\n          txLabel.txLabelId = await this.insertTxLabel(txLabel, trx)\n        }\n        if (txLabel.isDeleted) {\n          await this.updateTxLabel(verifyId(txLabel.txLabelId), {\n            isDeleted: false\n          })\n        }\n        return txLabel\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n  }\n\n  async findOrInsertTxLabelMap (transactionId: number, txLabelId: number, trx?: TrxToken): Promise<TableTxLabelMap> {\n    const partial = { transactionId, txLabelId }\n    for (let retry = 0; ; retry++) {\n      try {\n        const now = new Date()\n        let txLabelMap = verifyOneOrNone(await this.findTxLabelMaps({ partial, trx }))\n        if (txLabelMap == null) {\n          txLabelMap = {\n            ...partial,\n            created_at: now,\n            updated_at: now,\n            isDeleted: false\n          }\n          await this.insertTxLabelMap(txLabelMap, trx)\n        }\n        if (txLabelMap.isDeleted) {\n          await this.updateTxLabelMap(transactionId, txLabelId, {\n            isDeleted: false\n          })\n        }\n        return txLabelMap\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n  }\n\n  async findOrInsertOutputTag (userId: number, tag: string, trx?: TrxToken): Promise<TableOutputTag> {\n    const partial = { tag, userId }\n    for (let retry = 0; ; retry++) {\n      try {\n        const now = new Date()\n        let outputTag = verifyOneOrNone(await this.findOutputTags({ partial, trx }))\n        if (outputTag == null) {\n          outputTag = {\n            ...partial,\n            outputTagId: 0,\n            created_at: now,\n            updated_at: now,\n            isDeleted: false\n          }\n          outputTag.outputTagId = await this.insertOutputTag(outputTag, trx)\n        }\n        if (outputTag.isDeleted) {\n          await this.updateOutputTag(verifyId(outputTag.outputTagId), {\n            isDeleted: false\n          })\n        }\n        return outputTag\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n  }\n\n  async findOrInsertOutputTagMap (outputId: number, outputTagId: number, trx?: TrxToken): Promise<TableOutputTagMap> {\n    const partial = { outputId, outputTagId }\n    for (let retry = 0; ; retry++) {\n      try {\n        const now = new Date()\n        let outputTagMap = verifyOneOrNone(await this.findOutputTagMaps({ partial, trx }))\n        if (outputTagMap == null) {\n          outputTagMap = {\n            ...partial,\n            created_at: now,\n            updated_at: now,\n            isDeleted: false\n          }\n          await this.insertOutputTagMap(outputTagMap, trx)\n        }\n        if (outputTagMap.isDeleted) {\n          await this.updateOutputTagMap(outputId, outputTagId, {\n            isDeleted: false\n          })\n        }\n        return outputTagMap\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n  }\n\n  async findOrInsertSyncStateAuth (\n    auth: AuthId,\n    storageIdentityKey: string,\n    storageName: string\n  ): Promise<{ syncState: TableSyncState, isNew: boolean }> {\n    const partial = { userId: auth.userId as number, storageIdentityKey, storageName }\n    for (let retry = 0; ; retry++) {\n      try {\n        const now = new Date()\n        let syncState = verifyOneOrNone(await this.findSyncStates({ partial }))\n        if (syncState == null) {\n          syncState = {\n            ...partial,\n            created_at: now,\n            updated_at: now,\n            syncStateId: 0,\n            status: 'unknown',\n            init: false,\n            refNum: randomBytesBase64(12),\n            syncMap: JSON.stringify(createSyncMap())\n          }\n          await this.insertSyncState(syncState)\n          return { syncState, isNew: true }\n        }\n        return { syncState, isNew: false }\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n  }\n\n  async findOrInsertProvenTxReq (\n    newReq: TableProvenTxReq,\n    trx?: TrxToken\n  ): Promise<{ req: TableProvenTxReq, isNew: boolean }> {\n    let req: TableProvenTxReq | undefined\n    let isNew = false\n    for (let retry = 0; ; retry++) {\n      try {\n        req = verifyOneOrNone(await this.findProvenTxReqs({ partial: { txid: newReq.txid }, trx }))\n        if (req != null) break\n        newReq.provenTxReqId = await this.insertProvenTxReq(newReq, trx)\n        isNew = true\n        req = newReq\n        break\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n    return { req, isNew }\n  }\n\n  async findOrInsertProvenTx (\n    newProven: TableProvenTx,\n    trx?: TrxToken\n  ): Promise<{ proven: TableProvenTx, isNew: boolean }> {\n    let proven: TableProvenTx | undefined\n    let isNew = false\n    for (let retry = 0; ; retry++) {\n      try {\n        proven = verifyOneOrNone(await this.findProvenTxs({ partial: { txid: newProven.txid }, trx }))\n        if (proven != null) break\n        newProven.provenTxId = await this.insertProvenTx(newProven, trx)\n        isNew = true\n        proven = newProven\n        break\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n    return { proven, isNew }\n  }\n\n  abstract processSyncChunk (args: RequestSyncChunkArgs, chunk: SyncChunk): Promise<ProcessSyncChunkResult>\n\n  async tagOutput (partial: Partial<TableOutput>, tag: string, trx?: TrxToken): Promise<void> {\n    await this.transaction(async trx => {\n      const o = verifyOne(await this.findOutputs({ partial, noScript: true, trx }))\n      const outputTag = await this.findOrInsertOutputTag(o.userId, tag, trx)\n      await this.findOrInsertOutputTagMap(verifyId(o.outputId), verifyId(outputTag.outputTagId), trx)\n    }, trx)\n  }\n}\n\nexport interface StorageReaderWriterOptions extends StorageReaderOptions {\n  /** */\n}\n","import type {\n  ActionBatchManifest,\n  PrepareActionBatchCommitResult,\n  PutActionBatchBlobArgs,\n  PutActionBatchPackArgs\n} from '../../sdk/ActionBatch.interfaces'\nimport type { AuthId } from '../../sdk/WalletStorage.interfaces'\nimport { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { actionBatchBlobDigest, verifyActionBatchManifestDigest } from '../../utility/actionBatchDigest'\nimport { verifyId } from '../../utility/utilityHelpers'\nimport { asUint8Array } from '../../utility/utilityHelpers.noBuffer'\nimport { actionBatchPackLength } from '../../utility/actionBatchPack'\nimport type { StorageProvider } from '../StorageProvider'\nimport type { TableActionBatch } from '../schema/tables/TableActionBatch'\n\nexport const ACTION_BATCH_MAX_BLOB_BYTES = 8 * 1024 * 1024\nexport const ACTION_BATCH_MAX_CONCURRENT_UPLOADS = 4\nexport const ACTION_BATCH_MAX_INLINE_BYTES = 4 * 1024 * 1024\nexport const ACTION_BATCH_MAX_PACK_BYTES = 8 * 1024 * 1024\nexport const ACTION_BATCH_MAX_PACK_ITEMS = 4096\n\nexport function validateActionBatchInlinePayload (manifest: ActionBatchManifest): void {\n  let totalBytes = manifest.dependencyBeef == null ? 0 : manifest.dependencyBeef.length\n  const inlineBlobs = Object.entries(manifest.inlineBlobs ?? {})\n    .map(([digest, value]) => ({ digest, bytes: asUint8Array(value) }))\n  totalBytes += inlineBlobs.reduce((sum, blob) => sum + blob.bytes.length, 0)\n  for (const action of manifest.actions) {\n    if (action.rawTx != null) totalBytes += action.rawTx.length\n    if (action.lockingScriptDigests == null) {\n      totalBytes += action.plan.outputs.reduce((sum, output) => sum + output.lockingScript.length / 2, 0)\n    }\n  }\n  if (totalBytes > ACTION_BATCH_MAX_INLINE_BYTES) {\n    throw new WERR_INVALID_PARAMETER('manifest', 'inline payload within provider limit')\n  }\n  for (const { digest, bytes } of inlineBlobs) {\n    if (actionBatchBlobDigest(bytes) !== digest) {\n      throw new WERR_INVALID_PARAMETER('inlineBlobs', `content matching digest ${digest}`)\n    }\n  }\n}\n\nfunction requireUploadableBatch (batch: TableActionBatch | undefined): TableActionBatch {\n  if (batch == null || batch.status === 'committed' || batch.status === 'aborted') {\n    throw new WERR_INVALID_OPERATION('action batch is not uploadable')\n  }\n  if (batch.hardExpiresAt.getTime() <= Date.now()) {\n    throw new WERR_INVALID_OPERATION('action batch hard lifetime has expired')\n  }\n  return batch\n}\n\nexport function manifestPhysicalDigests (manifest: ActionBatchManifest): string[] {\n  const inline = manifest.inlineBlobs ?? {}\n  const logicalDigests = manifest.actions\n    .filter(action => action.rawTx == null)\n    .map(action => action.rawTxDigest)\n    .filter((digest): digest is string => digest != null)\n  if (manifest.dependencyBeef == null && manifest.dependencyBeefDigest != null &&\n    inline[manifest.dependencyBeefDigest] == null) logicalDigests.push(manifest.dependencyBeefDigest)\n  for (const action of manifest.actions) {\n    if (action.deriveLockingScripts === true) continue\n    for (const digest of action.lockingScriptDigests ?? []) {\n      if (digest != null && inline[digest] == null) logicalDigests.push(digest)\n    }\n  }\n  return [...new Set(logicalDigests.flatMap(digest => {\n    if (inline[digest] != null) return []\n    return manifest.blobChunks?.[digest] ?? [digest]\n  }))]\n}\n\nexport function validateCompactManifest (\n  manifest: ActionBatchManifest,\n  requireUploaded: boolean = false\n): void {\n  if (manifest.format !== 2) return\n  if (requireUploaded && (\n    manifest.inlineBlobs != null ||\n    manifest.dependencyBeef != null ||\n    manifest.actions.some(action => action.rawTx != null)\n  )) {\n    throw new WERR_INVALID_PARAMETER('manifest', 'digest-only bytes in a prepared format-2 manifest')\n  }\n  for (const action of manifest.actions) {\n    if (action.deriveLockingScripts !== true ||\n      action.lockingScriptDigests?.length !== action.plan.outputs.length) {\n      throw new WERR_INVALID_PARAMETER('actions', 'format-2 derived output scripts')\n    }\n    if (action.plan.inputs.some(input =>\n      input.sourceLockingScript != null || input.sourceTransaction != null\n    )) {\n      throw new WERR_INVALID_PARAMETER('actions', 'format-2 derived source scripts')\n    }\n    if (action.plan.outputs.some(output => output.lockingScript !== '') ||\n      action.metadata.outputs.some(output => output.lockingScript !== '')) {\n      throw new WERR_INVALID_PARAMETER('actions', 'format-2 compact output metadata')\n    }\n  }\n}\n\nexport async function prepareActionBatchCommit (\n  storage: StorageProvider,\n  auth: AuthId,\n  manifest: ActionBatchManifest\n): Promise<PrepareActionBatchCommitResult> {\n  validateActionBatchInlinePayload(manifest)\n  if (!verifyActionBatchManifestDigest(manifest)) throw new WERR_INVALID_PARAMETER('manifest.digest', 'valid')\n  validateCompactManifest(manifest, true)\n  const userId = verifyId(auth.userId)\n  return await storage.transaction(async trx => {\n    const batch = requireUploadableBatch(\n      await storage.findActionBatchForUpdate(userId, manifest.batchId, trx)\n    )\n    if (batch.manifestDigest != null && batch.manifestDigest !== manifest.digest) {\n      throw new WERR_INVALID_OPERATION('action batch was already prepared with a different manifest')\n    }\n    const uploadDigests = manifestPhysicalDigests(manifest)\n    const present = new Set(\n      (await storage.findActionBatchBlobRecords(batch.actionBatchId, uploadDigests, trx))\n        .map(blob => blob.digest)\n    )\n    const missingDigests = uploadDigests.filter(digest => !present.has(digest))\n    await storage.updateActionBatch(batch.actionBatchId, {\n      status: batch.status === 'expired' ? 'expired' : 'prepared',\n      manifestDigest: manifest.digest,\n      manifest: manifest.format === 2 ? JSON.stringify(manifest) : undefined,\n      uploadDigests: JSON.stringify(uploadDigests)\n    }, trx)\n    return {\n      missingDigests,\n      maxBlobBytes: ACTION_BATCH_MAX_BLOB_BYTES,\n      maxConcurrentUploads: ACTION_BATCH_MAX_CONCURRENT_UPLOADS\n    }\n  })\n}\n\nexport async function putActionBatchPack (\n  storage: StorageProvider,\n  auth: AuthId,\n  args: PutActionBatchPackArgs\n): Promise<void> {\n  const userId = verifyId(auth.userId)\n  if (args.items.length === 0 || args.items.length > ACTION_BATCH_MAX_PACK_ITEMS ||\n    actionBatchPackLength(args.items) > ACTION_BATCH_MAX_PACK_BYTES) {\n    throw new WERR_INVALID_PARAMETER('items', 'within the provider pack limits')\n  }\n  const items = args.items.map(item => ({\n    digest: item.digest,\n    bytes: asUint8Array(item.bytes)\n  }))\n  for (const item of items) {\n    if (actionBatchBlobDigest(item.bytes) !== item.digest) {\n      throw new WERR_INVALID_PARAMETER('digest', 'match bytes')\n    }\n  }\n  await storage.transaction(async trx => {\n    const batch = requireUploadableBatch(\n      await storage.findActionBatchForUpdate(userId, args.batchId, trx)\n    )\n    const uploadDigests = batch.uploadDigests == null\n      ? []\n      : JSON.parse(batch.uploadDigests) as string[]\n    const allowedDigests = new Set(uploadDigests)\n    if (batch.manifestDigest == null || items.some(item => !allowedDigests.has(item.digest))) {\n      throw new WERR_INVALID_PARAMETER('digest', 'requested by the prepared action batch manifest')\n    }\n    const now = new Date()\n    await storage.putActionBatchBlobRecords(items.map(item => ({\n      actionBatchBlobId: 0,\n      actionBatchId: batch.actionBatchId,\n      digest: item.digest,\n      bytes: item.bytes,\n      created_at: now,\n      updated_at: now\n    })), trx)\n  })\n}\n\nexport async function putActionBatchBlob (\n  storage: StorageProvider,\n  auth: AuthId,\n  args: PutActionBatchBlobArgs\n): Promise<void> {\n  const userId = verifyId(auth.userId)\n  const bytes = asUint8Array(args.bytes)\n  if (bytes.length > ACTION_BATCH_MAX_BLOB_BYTES) throw new WERR_INVALID_PARAMETER('bytes', 'within provider blob limit')\n  if (actionBatchBlobDigest(bytes) !== args.digest) throw new WERR_INVALID_PARAMETER('digest', 'match bytes')\n  await storage.transaction(async trx => {\n    const batch = requireUploadableBatch(\n      await storage.findActionBatchForUpdate(userId, args.batchId, trx)\n    )\n    const uploadDigests = batch.uploadDigests == null\n      ? []\n      : JSON.parse(batch.uploadDigests) as string[]\n    if (batch.manifestDigest == null || !uploadDigests.includes(args.digest)) {\n      throw new WERR_INVALID_PARAMETER('digest', 'requested by the prepared action batch manifest')\n    }\n    const now = new Date()\n    await storage.putActionBatchBlobRecord({\n      actionBatchBlobId: 0,\n      actionBatchId: batch.actionBatchId,\n      digest: args.digest,\n      bytes,\n      created_at: now,\n      updated_at: now\n    }, trx)\n  })\n}\n","import { Beef, Hash, Script, Transaction, Utils, Validation } from '@bsv/sdk'\nimport type { ActionBatchCommitAction, ActionBatchManifest } from '../../sdk/ActionBatch.interfaces'\nimport { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { verifyUnlockScriptsBatch } from '../../signer/methods/verifyUnlockScripts'\nimport { actionBatchBlobDigest } from '../../utility/actionBatchDigest'\nimport { beefForTxids } from '../../utility/beefForTxids'\nimport { asString, asUint8Array } from '../../utility/utilityHelpers.noBuffer'\nimport type { StorageProvider } from '../StorageProvider'\nimport { validateStorageFeeModel } from '../StorageProvider'\nimport type { TableActionBatch, TableActionBatchBlob } from '../schema/tables/TableActionBatch'\nimport { maxPossibleSatoshis } from './generateChange'\nimport { lockScriptWithKeyOffsetFromPubKey } from './offsetKey'\nimport { manifestPhysicalDigests } from './actionBatchBlobs'\n\nexport interface ValidatedBatchAction {\n  action: ActionBatchCommitAction\n  tx: Transaction\n  rawTx: Uint8Array\n  /** Proof frontier for inputs outside this atomic batch. */\n  externalInputBeef: Uint8Array\n}\n\nasync function resolveManifestBytes(\n  blobs: ReadonlyMap<string, TableActionBatchBlob>,\n  inline: number[] | Uint8Array | undefined,\n  digest: string | undefined,\n  name: string,\n  chunkDigests?: string[]\n): Promise<Uint8Array> {\n  if (inline != null) {\n    const bytes = asUint8Array(inline)\n    if (digest != null && actionBatchBlobDigest(bytes) !== digest) {\n      throw new WERR_INVALID_PARAMETER(name, 'match digest')\n    }\n    return bytes\n  }\n  if (digest == null) throw new WERR_INVALID_PARAMETER(name, 'inline bytes or digest')\n  if (chunkDigests != null) {\n    return resolveChunkedManifestBytes(blobs, chunkDigests, digest, name)\n  }\n  const blob = blobs.get(digest)\n  if (blob == null) throw new WERR_INVALID_OPERATION(`missing action batch blob ${digest}`)\n  if (actionBatchBlobDigest(blob.bytes) !== digest) {\n    throw new WERR_INVALID_OPERATION(`corrupt action batch blob ${digest}`)\n  }\n  return blob.bytes instanceof Uint8Array ? blob.bytes : Uint8Array.from(blob.bytes)\n}\n\nfunction allocateManifestBytes(totalBytes: number, name: string): Uint8Array {\n  try {\n    return new Uint8Array(totalBytes)\n  } catch (error: unknown) {\n    if (error instanceof RangeError) {\n      throw new WERR_INVALID_OPERATION(\n        `action batch ${name} cannot be assembled in this runtime`\n      )\n    }\n    throw error\n  }\n}\n\nfunction assembleManifestChunks(\n  chunks: Array<number[] | Uint8Array>,\n  totalBytes: number,\n  name: string\n): Uint8Array {\n  const bytes = allocateManifestBytes(totalBytes, name)\n  let offset = 0\n  for (const chunk of chunks) {\n    bytes.set(chunk, offset)\n    offset += chunk.length\n  }\n  return bytes\n}\n\nfunction resolveChunkedManifestBytes(\n  blobs: ReadonlyMap<string, TableActionBatchBlob>,\n  chunkDigests: string[],\n  digest: string,\n  name: string\n): Uint8Array {\n  if (chunkDigests.length === 0) {\n    throw new WERR_INVALID_PARAMETER(name, 'one or more blob chunks')\n  }\n  const chunks: Array<number[] | Uint8Array> = []\n  const logicalHash = new Hash.SHA256()\n  let totalBytes = 0\n  for (const chunkDigest of chunkDigests) {\n    const chunk = blobs.get(chunkDigest)\n    if (chunk == null) {\n      throw new WERR_INVALID_OPERATION(`missing action batch blob ${chunkDigest}`)\n    }\n    if (actionBatchBlobDigest(chunk.bytes) !== chunkDigest) {\n      throw new WERR_INVALID_OPERATION(`corrupt action batch blob ${chunkDigest}`)\n    }\n    totalBytes += chunk.bytes.length\n    if (!Number.isSafeInteger(totalBytes)) {\n      throw new WERR_INVALID_OPERATION(\n        `action batch ${name} exceeds this runtime's addressable memory`\n      )\n    }\n    chunks.push(chunk.bytes)\n    logicalHash.update(chunk.bytes)\n  }\n  if (Utils.toHex(logicalHash.digest()) !== digest) {\n    throw new WERR_INVALID_PARAMETER(name, 'chunks matching digest')\n  }\n  return assembleManifestChunks(chunks, totalBytes, name)\n}\n\nfunction sameValues<T>(left: T[] | undefined, right: T[] | undefined): boolean {\n  const a = left ?? []\n  const b = right ?? []\n  return a.length === b.length && a.every((value, index) => value === b[index])\n}\n\nconst sameStrings: (left: string[] | undefined, right: string[] | undefined) => boolean = sameValues\nconst sameNumbers: (left: number[] | undefined, right: number[] | undefined) => boolean = sameValues\n\nfunction validateActionInputs(action: ActionBatchCommitAction): void {\n  if (action.metadata.inputs.length > action.plan.inputs.length) {\n    throw new WERR_INVALID_PARAMETER('metadata.inputs', 'align with planned inputs')\n  }\n  for (let index = 0; index < action.metadata.inputs.length; index++) {\n    const requested = action.metadata.inputs[index]\n    const planned = action.plan.inputs[index]\n    if (\n      planned == null ||\n      planned.providedBy === 'storage' ||\n      requested.outpoint.txid !== planned.sourceTxid ||\n      requested.outpoint.vout !== planned.sourceVout ||\n      requested.unlockingScriptLength !== planned.unlockingScriptLength ||\n      requested.inputDescription !== planned.spendingDescription\n    ) {\n      throw new WERR_INVALID_PARAMETER('metadata.inputs', 'match planned explicit inputs')\n    }\n  }\n  if (action.plan.inputs.slice(action.metadata.inputs.length).some(input => input.providedBy !== 'storage')) {\n    throw new WERR_INVALID_PARAMETER('metadata.inputs', 'represent every caller-provided input')\n  }\n}\n\nfunction requestedOutputMatches(\n  requested: ActionBatchCommitAction['metadata']['outputs'][number],\n  planned: ActionBatchCommitAction['plan']['outputs'][number]\n): boolean {\n  const satoshisMatch = requested.satoshis === maxPossibleSatoshis || requested.satoshis === planned.satoshis\n  return (\n    planned.providedBy === 'you' &&\n    satoshisMatch &&\n    requested.lockingScript === planned.lockingScript &&\n    requested.outputDescription === planned.outputDescription &&\n    requested.basket === planned.basket &&\n    requested.customInstructions === planned.customInstructions &&\n    sameStrings(requested.tags, planned.tags)\n  )\n}\n\nfunction validateAdditionalPlannedOutput(\n  action: ActionBatchCommitAction,\n  planned: ActionBatchCommitAction['plan']['outputs'][number]\n): void {\n  const isChange = planned.providedBy === 'storage' && planned.purpose === 'change'\n  const isCommission =\n    planned.providedBy === 'storage' &&\n    (planned.purpose === 'storage-commission' || planned.purpose === 'service-charge')\n  if (!isChange && !isCommission) {\n    throw new WERR_INVALID_PARAMETER('plan.outputs', 'only requested, change, or commission outputs')\n  }\n  if (\n    isChange &&\n    (planned.basket !== 'default' ||\n      planned.tags.length !== 0 ||\n      planned.outputDescription !== '' ||\n      planned.customInstructions != null ||\n      planned.lockingScript !== '' ||\n      planned.derivationSuffix == null ||\n      action.plan.derivationPrefix.length === 0)\n  ) {\n    throw new WERR_INVALID_PARAMETER('plan.outputs', 'canonical wallet-managed change metadata')\n  }\n  if (isCommission && (planned.basket != null || planned.tags.length !== 0 || planned.customInstructions != null)) {\n    throw new WERR_INVALID_PARAMETER('plan.outputs', 'canonical storage commission metadata')\n  }\n}\n\nfunction validateActionOutputs(action: ActionBatchCommitAction): void {\n  if (action.metadata.outputs.length > action.plan.outputs.length) {\n    throw new WERR_INVALID_PARAMETER('metadata.outputs', 'align with planned outputs')\n  }\n  for (let index = 0; index < action.metadata.outputs.length; index++) {\n    const requested = action.metadata.outputs[index]\n    const planned = action.plan.outputs[index]\n    if (planned == null) {\n      throw new WERR_INVALID_PARAMETER('metadata.outputs', 'match planned requested outputs')\n    }\n    if (!requestedOutputMatches(requested, planned)) {\n      throw new WERR_INVALID_PARAMETER('metadata.outputs', 'match planned requested outputs')\n    }\n  }\n  for (const planned of action.plan.outputs.slice(action.metadata.outputs.length)) {\n    validateAdditionalPlannedOutput(action, planned)\n  }\n}\n\nfunction validateActionMetadata(action: ActionBatchCommitAction): void {\n  Validation.validateCreateActionArgs({\n    inputs: action.metadata.inputs.map(input => ({\n      ...input,\n      outpoint: `${input.outpoint.txid}.${input.outpoint.vout}`\n    })),\n    outputs: action.metadata.outputs,\n    labels: action.metadata.labels,\n    description: action.metadata.description,\n    version: action.plan.version,\n    lockTime: action.plan.lockTime,\n    options: {\n      noSend: action.metadata.isNoSend,\n      acceptDelayedBroadcast: action.metadata.isDelayed,\n      randomizeOutputs: false\n    }\n  })\n  validateActionInputs(action)\n  validateActionOutputs(action)\n}\n\nfunction validateActionCommission(storage: StorageProvider, action: ActionBatchCommitAction): void {\n  const commissions = action.plan.outputs.filter(\n    output => output.purpose === 'storage-commission' || output.purpose === 'service-charge'\n  )\n  if (storage.commissionSatoshis === 0) {\n    if (commissions.length > 0 || action.commissionKeyOffset != null) {\n      throw new WERR_INVALID_PARAMETER('commission', 'absent when storage commissions are disabled')\n    }\n    return\n  }\n  if (storage.commissionPubKeyHex == null || action.commissionKeyOffset == null || commissions.length !== 1) {\n    throw new WERR_INVALID_PARAMETER('commission', 'one output matching the active storage commission')\n  }\n  const commission = commissions[0]\n  const expected = lockScriptWithKeyOffsetFromPubKey(storage.commissionPubKeyHex, action.commissionKeyOffset)\n  if (\n    commission.providedBy !== 'storage' ||\n    commission.satoshis !== storage.commissionSatoshis ||\n    commission.lockingScript !== expected.script ||\n    expected.keyOffset !== action.commissionKeyOffset\n  ) {\n    throw new WERR_INVALID_PARAMETER('commission', 'match the active storage commission')\n  }\n}\n\nasync function requireSourceOutput(\n  storage: StorageProvider,\n  beef: Beef,\n  txid: string,\n  vout: number\n): Promise<{ satoshis: number; lockingScript: Script }> {\n  let source = beef.findTxid(txid)?.tx\n  if (source == null) {\n    try {\n      beef.mergeBeef(await storage.getBeefForTransaction(txid, { ignoreServices: true }))\n      source = beef.findTxid(txid)?.tx\n    } catch {\n      // The normalized invalid-parameter error below keeps the remote API\n      // independent of provider-specific lookup failures.\n    }\n  }\n  const output = source?.outputs[vout]\n  if (output == null) throw new WERR_INVALID_PARAMETER('manifest', `source output ${txid}.${vout}`)\n  return {\n    satoshis: Validation.validateSatoshis(output.satoshis, 'source output satoshis'),\n    lockingScript: output.lockingScript\n  }\n}\n\nasync function materializeActionScripts(\n  blobs: ReadonlyMap<string, TableActionBatchBlob>,\n  manifest: ActionBatchManifest,\n  action: ActionBatchCommitAction,\n  tx: Transaction\n): Promise<ActionBatchCommitAction> {\n  if (action.lockingScriptDigests == null) return action\n  if (action.lockingScriptDigests.length !== action.plan.outputs.length) {\n    throw new WERR_INVALID_PARAMETER('lockingScriptDigests', 'align with planned outputs')\n  }\n  const scripts: string[] = []\n  for (let index = 0; index < action.plan.outputs.length; index++) {\n    const digest = action.lockingScriptDigests[index]\n    if (action.deriveLockingScripts === true) {\n      const output = tx.outputs[action.plan.outputs[index].vout]\n      if (output == null) {\n        throw new WERR_INVALID_PARAMETER('lockingScriptDigests', 'align with transaction outputs')\n      }\n      const bytes = output.lockingScript.toUint8Array()\n      if (digest == null || actionBatchBlobDigest(bytes) !== digest) {\n        throw new WERR_INVALID_PARAMETER('lockingScriptDigests', 'match transaction output scripts')\n      }\n      scripts.push(output.lockingScript.toHex())\n    } else {\n      scripts.push(\n        digest == null\n          ? action.plan.outputs[index].lockingScript\n          : asString(\n              await resolveManifestBytes(\n                blobs,\n                manifest.inlineBlobs?.[digest],\n                digest,\n                `locking script ${index}`,\n                manifest.blobChunks?.[digest]\n              )\n            )\n      )\n    }\n  }\n  return {\n    ...action,\n    plan: {\n      ...action.plan,\n      outputs: action.plan.outputs.map((output, index) => ({\n        ...output,\n        // Wallet-managed change is intentionally represented by derivation\n        // metadata in the canonical plan, even though its transaction output\n        // script participates in the compact-manifest digest check above.\n        lockingScript: output.purpose === 'change' ? '' : scripts[index]\n      }))\n    },\n    metadata: {\n      ...action.metadata,\n      outputs: action.metadata.outputs.map((output, index) => ({ ...output, lockingScript: scripts[index] }))\n    }\n  }\n}\n\ninterface ManifestActionValidationState {\n  storage: StorageProvider\n  blobs: ReadonlyMap<string, TableActionBatchBlob>\n  manifest: ActionBatchManifest\n  beef: Beef\n  batchTxids: Set<string>\n  seenTxids: Set<string>\n  seenReferences: Set<string>\n  spentOutpoints: Set<string>\n}\n\nfunction validateActionIdentity(\n  action: ActionBatchCommitAction,\n  state: ManifestActionValidationState\n): void {\n  if (state.seenTxids.has(action.txid)) {\n    throw new WERR_INVALID_PARAMETER('actions', 'unique txids')\n  }\n  if (state.seenReferences.has(action.reference)) {\n    throw new WERR_INVALID_PARAMETER('actions', 'unique references')\n  }\n  if (action.reference !== action.plan.reference) {\n    throw new WERR_INVALID_PARAMETER('reference', 'match plan')\n  }\n  validateActionMetadata(action)\n  validateActionCommission(state.storage, action)\n}\n\nasync function validateActionTransactionShape(\n  storage: StorageProvider,\n  action: ActionBatchCommitAction,\n  tx: Transaction\n): Promise<void> {\n  if (tx.id('hex') !== action.txid) {\n    throw new WERR_INVALID_PARAMETER('txid', 'match raw transaction')\n  }\n  if (!(await storage.getServices().nLockTimeIsFinal(tx))) {\n    throw new WERR_INVALID_PARAMETER(\n      'transaction',\n      'final nLockTime and sequence values'\n    )\n  }\n  if (tx.version !== action.plan.version || tx.lockTime !== action.plan.lockTime) {\n    throw new WERR_INVALID_PARAMETER(\n      'transaction',\n      'match planned version and lockTime'\n    )\n  }\n  if (\n    tx.inputs.length !== action.plan.inputs.length ||\n    tx.outputs.length !== action.plan.outputs.length\n  ) {\n    throw new WERR_INVALID_PARAMETER(\n      'transaction',\n      'match planned input and output counts'\n    )\n  }\n  if (!action.plan.inputs.every((input, index) => input.vin === index)) {\n    throw new WERR_INVALID_PARAMETER('inputs', 'complete sequential vin mappings')\n  }\n  const outputVouts = action.plan.outputs\n    .map(output => output.vout)\n    .sort((left, right) => left - right)\n  if (!outputVouts.every((vout, index) => vout === index)) {\n    throw new WERR_INVALID_PARAMETER('outputs', 'complete sequential vout mappings')\n  }\n  const expectedNoSendChange = action.metadata.isNoSend\n    ? action.plan.outputs\n        .filter(output => output.purpose === 'change')\n        .map(output => output.vout)\n    : undefined\n  if (!sameNumbers(action.plan.noSendChangeOutputVouts, expectedNoSendChange)) {\n    throw new WERR_INVALID_PARAMETER(\n      'noSendChangeOutputVouts',\n      'match planned change outputs'\n    )\n  }\n}\n\nasync function validateActionInputSources(\n  storage: StorageProvider,\n  beef: Beef,\n  action: ActionBatchCommitAction,\n  tx: Transaction\n): Promise<void> {\n  for (const planned of action.plan.inputs) {\n    const input = tx.inputs[planned.vin]\n    if (\n      input?.sourceTXID !== planned.sourceTxid ||\n      input.sourceOutputIndex !== planned.sourceVout\n    ) {\n      throw new WERR_INVALID_PARAMETER(\n        'inputs',\n        'match planned transaction outpoints'\n      )\n    }\n    const source = await requireSourceOutput(\n      storage,\n      beef,\n      planned.sourceTxid,\n      planned.sourceVout\n    )\n    if (\n      source.satoshis !== planned.sourceSatoshis ||\n      (planned.sourceLockingScript != null &&\n        source.lockingScript.toHex() !== planned.sourceLockingScript)\n    ) {\n      throw new WERR_INVALID_PARAMETER('inputs', 'match proven source outputs')\n    }\n  }\n}\n\nfunction registerActionOutpoints(\n  tx: Transaction,\n  state: ManifestActionValidationState\n): void {\n  for (const input of tx.inputs) {\n    const sourceTxid = input.sourceTXID\n    if (sourceTxid == null) {\n      throw new WERR_INVALID_PARAMETER('input.sourceTXID', 'valid')\n    }\n    const outpoint = `${sourceTxid}.${input.sourceOutputIndex}`\n    if (state.spentOutpoints.has(outpoint)) {\n      throw new WERR_INVALID_PARAMETER(\n        'actions',\n        `not double spend ${outpoint}`\n      )\n    }\n    state.spentOutpoints.add(outpoint)\n    if (state.batchTxids.has(sourceTxid) && !state.seenTxids.has(sourceTxid)) {\n      throw new WERR_INVALID_PARAMETER('actions', 'topologically ordered')\n    }\n  }\n}\n\nfunction validateActionFee(\n  storage: StorageProvider,\n  action: ActionBatchCommitAction,\n  tx: Transaction,\n  rawTx: Uint8Array\n): void {\n  const inputSatoshis = action.plan.inputs.reduce(\n    (sum, input) => sum + input.sourceSatoshis,\n    0\n  )\n  const outputSatoshis = tx.outputs.reduce(\n    (sum, output) =>\n      sum +\n      Validation.validateSatoshis(\n        output.satoshis,\n        'transaction output satoshis'\n      ),\n    0\n  )\n  const feeRate = validateStorageFeeModel(storage.feeModel).value ?? 0\n  if (inputSatoshis - outputSatoshis < Math.ceil((rawTx.length * feeRate) / 1000)) {\n    throw new WERR_INVALID_PARAMETER(\n      'transaction fee',\n      'meet the active storage fee model'\n    )\n  }\n}\n\nfunction validateActionTransactionOutputs(\n  action: ActionBatchCommitAction,\n  tx: Transaction\n): void {\n  for (const planned of action.plan.outputs) {\n    const transactionOutput = tx.outputs[planned.vout]\n    const scriptMatches =\n      planned.lockingScript === ''\n        ? planned.providedBy === 'storage' && planned.purpose === 'change'\n        : transactionOutput?.lockingScript.toHex() === planned.lockingScript\n    if (\n      transactionOutput == null ||\n      transactionOutput.satoshis !== planned.satoshis ||\n      !scriptMatches\n    ) {\n      throw new WERR_INVALID_PARAMETER(\n        'outputs',\n        'match planned transaction outputs'\n      )\n    }\n  }\n}\n\nasync function validateManifestAction(\n  compactAction: ActionBatchCommitAction,\n  state: ManifestActionValidationState\n): Promise<ValidatedBatchAction> {\n  const rawTx = await resolveManifestBytes(\n    state.blobs,\n    compactAction.rawTx ??\n      (compactAction.rawTxDigest == null\n        ? undefined\n        : state.manifest.inlineBlobs?.[compactAction.rawTxDigest]),\n    compactAction.rawTxDigest,\n    `rawTx ${compactAction.txid}`,\n    compactAction.rawTxDigest == null\n      ? undefined\n      : state.manifest.blobChunks?.[compactAction.rawTxDigest]\n  )\n  const tx = Transaction.fromBinary(rawTx)\n  const action = await materializeActionScripts(\n    state.blobs,\n    state.manifest,\n    compactAction,\n    tx\n  )\n  validateActionIdentity(action, state)\n  await validateActionTransactionShape(state.storage, action, tx)\n  await validateActionInputSources(state.storage, state.beef, action, tx)\n  registerActionOutpoints(tx, state)\n  validateActionFee(state.storage, action, tx, rawTx)\n  validateActionTransactionOutputs(action, tx)\n  const externalInputBeef = beefForTxids(\n    state.beef,\n    action.plan.inputs\n      .map(input => input.sourceTxid)\n      .filter(txid => !state.batchTxids.has(txid))\n  ).toUint8Array()\n  state.beef.mergeRawTx(rawTx)\n  state.seenTxids.add(action.txid)\n  state.seenReferences.add(action.reference)\n  return { action, tx, rawTx, externalInputBeef }\n}\n\nexport async function validateManifestActions(\n  storage: StorageProvider,\n  batch: TableActionBatch,\n  manifest: ActionBatchManifest\n): Promise<{ actions: ValidatedBatchAction[]; dependencyBeef: Uint8Array; beef: Beef }> {\n  const blobRecords = await storage.findActionBatchBlobRecords(\n    batch.actionBatchId,\n    manifestPhysicalDigests(manifest)\n  )\n  const blobs = new Map(blobRecords.map(blob => [blob.digest, blob]))\n  const dependencyBeef = await resolveManifestBytes(\n    blobs,\n    manifest.dependencyBeef ??\n      (manifest.dependencyBeefDigest == null ? undefined : manifest.inlineBlobs?.[manifest.dependencyBeefDigest]),\n    manifest.dependencyBeefDigest,\n    'dependencyBeef',\n    manifest.dependencyBeefDigest == null ? undefined : manifest.blobChunks?.[manifest.dependencyBeefDigest]\n  )\n  if (manifest.actions.length === 0) {\n    throw new WERR_INVALID_PARAMETER('actions', 'contain at least one signed action')\n  }\n  const beef = dependencyBeef.length === 0 ? new Beef() : Beef.fromBinary(dependencyBeef)\n  const batchTxids = new Set(manifest.actions.map(action => action.txid))\n  const seenTxids = new Set<string>()\n  const seenReferences = new Set<string>()\n  const spentOutpoints = new Set<string>()\n  const actions: ValidatedBatchAction[] = []\n  const state: ManifestActionValidationState = {\n    storage,\n    blobs,\n    manifest,\n    beef,\n    batchTxids,\n    seenTxids,\n    seenReferences,\n    spentOutpoints\n  }\n  for (const compactAction of manifest.actions) {\n    actions.push(await validateManifestAction(compactAction, state))\n  }\n  await verifyUnlockScriptsBatch(\n    actions.map(({ action }) => action.txid),\n    beef,\n    storage.scriptVerifier\n  )\n  if (!(await beef.verify(await storage.getServices().getChainTracker(), true))) {\n    throw new WERR_INVALID_PARAMETER('manifest', 'valid dependency graph')\n  }\n  return { actions, dependencyBeef, beef }\n}\n","import {\n  Beef,\n  Script,\n  Validation\n} from '@bsv/sdk'\nimport {\n  AbortActionBatchResult,\n  ActionBatchCommitAction,\n  ActionBatchFundingOutput,\n  ActionBatchManifest,\n  BeginActionBatchArgs,\n  BeginActionBatchResult,\n  CommitActionBatchByDigestArgs,\n  CommitActionBatchResult,\n  ExtendActionBatchArgs,\n  ExtendActionBatchResult,\n  RenewActionBatchResult,\n  StorageCapabilities\n} from '../../sdk/ActionBatch.interfaces'\nimport { AuthId, TrxToken } from '../../sdk/WalletStorage.interfaces'\nimport { ProvenTxReqStatus, TransactionStatus } from '../../sdk/types'\nimport { WERR_INTERNAL, WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { verifyId, verifyOne } from '../../utility/utilityHelpers'\nimport { verifyActionBatchManifestDigest } from '../../utility/actionBatchDigest'\nimport { supportedActionBatchPackEncodings } from '../../utility/actionBatchPack'\nimport { validateStorageFeeModel } from '../StorageProvider'\nimport type { StorageProvider } from '../StorageProvider'\nimport { EntityProvenTxReq } from '../schema/entities/EntityProvenTxReq'\nimport { TableActionBatch } from '../schema/tables/TableActionBatch'\nimport { TableCommission } from '../schema/tables/TableCommission'\nimport { TableOutput } from '../schema/tables/TableOutput'\nimport { TableOutputBasket } from '../schema/tables/TableOutputBasket'\nimport { TableOutputTag } from '../schema/tables/TableOutputTag'\nimport { TableTransaction } from '../schema/tables/TableTransaction'\nimport { TableTxLabel } from '../schema/tables/TableTxLabel'\nimport { isAutoSpendableChangeOutput } from './managedChange'\nimport { parseTxScriptOffsets } from '../../utility/parseTxScriptOffsets'\nimport { shareReqsWithWorld } from './processAction'\nimport type { GetReqsAndBeefResult } from './processAction'\nimport { classifyReqStatus } from '../storageProviderHelpers'\nimport { transactionSize } from './utils'\nimport { selectCanonicalChange } from './actionPlanning'\nimport {\n  ACTION_BATCH_MAX_BLOB_BYTES,\n  ACTION_BATCH_MAX_CONCURRENT_UPLOADS,\n  ACTION_BATCH_MAX_INLINE_BYTES,\n  ACTION_BATCH_MAX_PACK_BYTES,\n  ACTION_BATCH_MAX_PACK_ITEMS,\n  validateActionBatchInlinePayload,\n  validateCompactManifest\n} from './actionBatchBlobs'\nimport { validateManifestActions } from './actionBatchValidation'\nimport type { ValidatedBatchAction } from './actionBatchValidation'\n\nexport const ACTION_BATCH_LEASE_MS = 15 * 60 * 1000\nexport const ACTION_BATCH_HARD_LIFETIME_MS = 60 * 60 * 1000\nconst INITIAL_RESERVATION_LIMIT = 8\nconst INITIAL_EXTRA_OUTPUTS = 3\nexport const ACTION_BATCH_MAX_RESERVATION_EXTENSION_OUTPUTS = 64\n\nexport function getActionBatchCapabilities (): StorageCapabilities {\n  return {\n    actionBatch: {\n      version: 1,\n      maxInlineBytes: ACTION_BATCH_MAX_INLINE_BYTES,\n      maxBlobBytes: ACTION_BATCH_MAX_BLOB_BYTES,\n      maxConcurrentUploads: ACTION_BATCH_MAX_CONCURRENT_UPLOADS,\n      leaseMs: ACTION_BATCH_LEASE_MS,\n      hardLifetimeMs: ACTION_BATCH_HARD_LIFETIME_MS,\n      compactBegin: true,\n      manifestVersion: 2,\n      commitByDigest: true,\n      packedUploads: {\n        version: 1,\n        maxPackBytes: ACTION_BATCH_MAX_PACK_BYTES,\n        maxItems: ACTION_BATCH_MAX_PACK_ITEMS,\n        encodings: supportedActionBatchPackEncodings(),\n        // Require a prepared manifest to authorize every persisted digest.\n        // Clients still support eager uploads for providers that can enforce\n        // an equivalent bounded authorization policy.\n        eager: false\n      }\n    }\n  }\n}\n\nfunction activeExpiry (batch: TableActionBatch, now = new Date()): boolean {\n  return batch.status !== 'active' && batch.status !== 'prepared' ||\n    batch.expiresAt.getTime() <= now.getTime() ||\n    batch.hardExpiresAt.getTime() <= now.getTime()\n}\n\nfunction canExpire (batch: TableActionBatch, now = new Date()): boolean {\n  return (batch.status === 'active' || batch.status === 'prepared') &&\n    (batch.expiresAt.getTime() <= now.getTime() || batch.hardExpiresAt.getTime() <= now.getTime())\n}\n\nasync function releaseBatchState (\n  storage: StorageProvider,\n  batch: TableActionBatch,\n  status: 'aborted' | 'committed' | 'expired',\n  trx?: TrxToken\n): Promise<void> {\n  await storage.deleteActionBatchOutputReservations(batch.actionBatchId, trx)\n  await storage.deleteActionBatchBlobRecords(batch.actionBatchId, trx)\n  await storage.updateActionBatch(batch.actionBatchId, {\n    status,\n    manifest: undefined,\n    uploadDigests: undefined\n  }, trx)\n}\n\nexport async function cleanupExpiredActionBatches (storage: StorageProvider): Promise<number> {\n  const now = new Date()\n  const expired = await storage.findExpiredActionBatches(now)\n  let released = 0\n  for (const batch of expired) {\n    await storage.transaction(async trx => {\n      const current = await storage.findActionBatchForUpdate(batch.userId, batch.batchId, trx)\n      if (current == null || !canExpire(current, now)) return\n      await releaseBatchState(storage, current, 'expired', trx)\n      released++\n    })\n  }\n  return released\n}\n\nfunction sourceOutputFromBeef (\n  beef: Beef,\n  outpoint: { txid: string, vout: number }\n): { satoshis: number, lockingScript: Script } | undefined {\n  const tx = beef.findTxid(outpoint.txid)?.tx\n  const output = tx?.outputs[outpoint.vout]\n  if (output == null) return undefined\n  return { satoshis: Validation.validateSatoshis(output.satoshis, 'source output satoshis'), lockingScript: output.lockingScript }\n}\n\nasync function resolveExplicitOutputs (\n  storage: StorageProvider,\n  userId: number,\n  args: Validation.ValidCreateActionArgs,\n  allowDeferredProofs: boolean\n): Promise<{ outputs: TableOutput[], inputSatoshis: number }> {\n  const byOutpoint = await storage.findOutputsByOutpoints(userId, args.inputs.map(input => input.outpoint))\n  const beef = args.inputBEEF == null ? new Beef() : Beef.fromBinary(args.inputBEEF)\n  const outputs: TableOutput[] = []\n  let inputSatoshis = 0\n  for (const input of args.inputs) {\n    const output = byOutpoint[`${input.outpoint.txid}.${input.outpoint.vout}`]\n    if (output != null) {\n      await storage.validateOutputScript(output)\n      outputs.push(output)\n      inputSatoshis += output.satoshis\n      continue\n    }\n    const source = sourceOutputFromBeef(beef, input.outpoint)\n    if (source == null) {\n      if (allowDeferredProofs) continue\n      throw new WERR_INVALID_PARAMETER('inputBEEF', `proof data for ${input.outpoint.txid}.${input.outpoint.vout}`)\n    }\n    inputSatoshis += source.satoshis\n  }\n  return { outputs, inputSatoshis }\n}\n\nasync function resolveNoSendChangeOutputs (\n  storage: StorageProvider,\n  userId: number,\n  args: Validation.ValidCreateActionArgs\n): Promise<{ outputs: TableOutput[], inputSatoshis: number }> {\n  const outpoints = args.options.noSendChange\n  const byOutpoint = await storage.findOutputsByOutpoints(userId, outpoints)\n  const outputs: TableOutput[] = []\n  let inputSatoshis = 0\n  for (const outpoint of outpoints) {\n    const key = `${outpoint.txid}.${outpoint.vout}`\n    const output = byOutpoint[key]\n    if (output == null || !output.spendable || output.spentBy != null || !isAutoSpendableChangeOutput(output)) {\n      throw new WERR_INVALID_PARAMETER('noSendChange', `spendable wallet-managed output ${key}`)\n    }\n    await storage.validateOutputScript(output)\n    outputs.push(output)\n    inputSatoshis += output.satoshis\n  }\n  return { outputs, inputSatoshis }\n}\n\nfunction estimateFirstActionTarget (\n  storage: StorageProvider,\n  args: Validation.ValidCreateActionArgs,\n  inputSatoshis: number,\n  outputScriptLengths?: number[]\n): number {\n  const outputSatoshis = args.outputs.reduce((sum, output) => sum + output.satoshis, 0) + storage.commissionSatoshis\n  const inputLengths = args.inputs.map(input => input.unlockingScriptLength)\n  const outputLengths = outputScriptLengths ?? args.outputs.map(output => output.lockingScript.length / 2)\n  if (storage.commissionSatoshis > 0) outputLengths.push(25)\n  outputLengths.push(25)\n  const fee = validateStorageFeeModel(storage.feeModel).value ?? 0\n  const minFee = Math.ceil(transactionSize([...inputLengths, 107], outputLengths) * fee / 1000)\n  return Math.max(1, outputSatoshis + minFee - inputSatoshis)\n}\n\nfunction chooseReservationPool (\n  candidates: TableOutput[],\n  targetSatoshis: number,\n  limit: number,\n  extras: number,\n  fillLimit: boolean,\n  planningCosts: {\n    firstChangeCost: number\n    marginalInputFee: number\n  }\n): TableOutput[] {\n  const remaining = candidates\n    .filter(output => output.satoshis > planningCosts.marginalInputFee)\n  const chosen: TableOutput[] = []\n  // A reservation is useful to generateChangeSdk only after it also covers\n  // the marginal funding-input fee and leaves an economically viable first\n  // change output. Without this buffer, a tiny target repeatedly selects dust\n  // that satisfies the nominal deficit but can never close the real plan.\n  let deficit = targetSatoshis + planningCosts.firstChangeCost\n  while (deficit > 0 && chosen.length < limit) {\n    const output = selectCanonicalChange(\n      remaining,\n      deficit + planningCosts.marginalInputFee\n    )\n    if (output == null) break\n    chosen.push(output)\n    remaining.splice(remaining.indexOf(output), 1)\n    deficit -= output.satoshis - planningCosts.marginalInputFee\n  }\n  const desiredCount = fillLimit ? limit : Math.min(limit, chosen.length + extras)\n  while (remaining.length > 0 && chosen.length < desiredCount) {\n    const output = selectCanonicalChange(remaining, targetSatoshis)\n    if (output == null) break\n    chosen.push(output)\n    remaining.splice(remaining.indexOf(output), 1)\n  }\n  return chosen\n}\n\nfunction reservationPlanningCosts (\n  storage: StorageProvider,\n  basket: TableOutputBasket\n): { firstChangeCost: number, marginalInputFee: number } {\n  const satsPerKb = validateStorageFeeModel(storage.feeModel).value ?? 0\n  const minimumSpendSize = transactionSize([107], [25])\n  const minimumSpendFee = Math.ceil(minimumSpendSize * satsPerKb / 1000)\n  const dustFloor = Math.max(1, minimumSpendFee * 2)\n  const marginalInputSize = transactionSize([107], []) - transactionSize([], [])\n  const marginalOutputSize = transactionSize([], [25]) - transactionSize([], [])\n  const desiredFirstChange = Math.max(\n    dustFloor,\n    Math.max(1, Math.round(basket.minimumDesiredUTXOValue / 4))\n  )\n  return {\n    firstChangeCost: desiredFirstChange + Math.ceil(marginalOutputSize * satsPerKb / 1000),\n    marginalInputFee: Math.ceil(marginalInputSize * satsPerKb / 1000)\n  }\n}\n\nasync function reserveOutputs (\n  storage: StorageProvider,\n  batch: TableActionBatch,\n  outputs: TableOutput[],\n  trx?: TrxToken\n): Promise<void> {\n  const now = new Date()\n  const unique = [...new Map(outputs.map(output => [output.outputId, output])).values()]\n  const reserve = async (transaction: TrxToken): Promise<void> => {\n    const outpoints = unique.map(output => {\n      if (output.txid == null) throw new WERR_INVALID_OPERATION('action batch output is missing its txid')\n      return { txid: output.txid, vout: output.vout }\n    })\n    const current = await storage.findOutputsByOutpointsForUpdate(\n      batch.userId,\n      outpoints,\n      transaction\n    )\n    for (const output of unique) {\n      const stored = output.txid == null ? undefined : current[`${output.txid}.${output.vout}`]\n      if (stored == null || !stored.spendable || stored.spentBy != null) {\n        throw new WERR_INVALID_OPERATION('one or more action batch outputs are no longer spendable')\n      }\n    }\n    const conflicts = await storage.findReservedActionBatchOutputIds(unique.map(output => output.outputId), transaction)\n    if (conflicts.length > 0) throw new WERR_INVALID_OPERATION('one or more action batch outputs were concurrently reserved')\n    await storage.reserveActionBatchOutputs(unique.map(output => ({\n      actionBatchId: batch.actionBatchId,\n      outputId: output.outputId,\n      created_at: now,\n      updated_at: now\n    })), transaction)\n  }\n  if (trx != null) await reserve(trx)\n  else await storage.transaction(reserve)\n}\n\nasync function makeFundingResult (\n  storage: StorageProvider,\n  args: Validation.ValidCreateActionArgs,\n  outputs: TableOutput[]\n): Promise<{ outputs: ActionBatchFundingOutput[], beef?: Uint8Array }> {\n  const beef = new Beef()\n  const result: ActionBatchFundingOutput[] = []\n  for (const output of outputs) {\n    await storage.validateOutputScript(output)\n    const copy: ActionBatchFundingOutput = { ...output }\n    if (args.isSignAction && args.includeAllSourceTransactions) {\n      copy.sourceTransaction = await storage.getRawTxOfKnownValidTransaction(output.txid)\n    }\n    if (output.txid != null && beef.findTxid(output.txid) == null) {\n      beef.mergeBeef(await storage.getBeefForTransaction(output.txid, {\n        knownTxids: args.options.knownTxids,\n        ignoreServices: true\n      }))\n    }\n    result.push(copy)\n  }\n  return { outputs: result, beef: beef.toUint8Array() }\n}\n\nfunction newBatch (userId: number, batchId: string): TableActionBatch {\n  const now = new Date()\n  return {\n    actionBatchId: 0,\n    userId,\n    batchId,\n    status: 'active',\n    expiresAt: new Date(now.getTime() + ACTION_BATCH_LEASE_MS),\n    hardExpiresAt: new Date(now.getTime() + ACTION_BATCH_HARD_LIFETIME_MS),\n    created_at: now,\n    updated_at: now\n  }\n}\n\nexport async function beginActionBatch (\n  storage: StorageProvider,\n  auth: AuthId,\n  args: BeginActionBatchArgs\n): Promise<BeginActionBatchResult> {\n  const userId = verifyId(auth.userId)\n  await cleanupExpiredActionBatches(storage)\n  if (await storage.findActionBatch(userId, args.batchId) != null) {\n    throw new WERR_INVALID_PARAMETER('batchId', 'unique')\n  }\n  const outputScriptLengths = args.firstActionOutputScriptLengths\n  if (outputScriptLengths != null && (\n    outputScriptLengths.length !== args.firstAction.outputs.length ||\n    outputScriptLengths.some(length => !Number.isSafeInteger(length) || length < 0) ||\n    args.firstAction.outputs.some((output, index) =>\n      output.lockingScript.length > 0 &&\n      output.lockingScript.length / 2 !== outputScriptLengths[index]\n    )\n  )) {\n    throw new WERR_INVALID_PARAMETER(\n      'firstActionOutputScriptLengths',\n      'valid byte lengths aligned with firstAction outputs'\n    )\n  }\n  const changeBasket = verifyOne(await storage.findOutputBaskets({ partial: { userId, name: 'default' } }))\n  const explicit = await resolveExplicitOutputs(\n    storage,\n    userId,\n    args.firstAction,\n    outputScriptLengths != null\n  )\n  const noSendChange = await resolveNoSendChangeOutputs(storage, userId, args.firstAction)\n  const fixedOutputIds = new Set([...explicit.outputs, ...noSendChange.outputs].map(output => output.outputId))\n  const available = (await storage.findAvailableManagedChangeInputs(\n    userId, changeBasket.basketId, !args.firstAction.isDelayed\n  )).filter(output => !fixedOutputIds.has(output.outputId))\n  const target = estimateFirstActionTarget(\n    storage,\n    args.firstAction,\n    explicit.inputSatoshis + noSendChange.inputSatoshis,\n    outputScriptLengths\n  )\n  const fixedOutputs = [...explicit.outputs, ...noSendChange.outputs]\n  const requiredCapacity = Math.max(0, INITIAL_RESERVATION_LIMIT - fixedOutputs.length)\n  const funding = chooseReservationPool(\n    available,\n    target,\n    requiredCapacity,\n    INITIAL_EXTRA_OUTPUTS,\n    false,\n    reservationPlanningCosts(storage, changeBasket)\n  )\n  const batch = newBatch(userId, args.batchId)\n  await storage.transaction(async trx => {\n    await storage.insertActionBatch(batch, trx)\n    await reserveOutputs(storage, batch, [...fixedOutputs, ...funding], trx)\n  })\n  let fundingResult: Awaited<ReturnType<typeof makeFundingResult>>\n  try {\n    fundingResult = await makeFundingResult(storage, args.firstAction, [...funding, ...fixedOutputs])\n  } catch (error) {\n    await storage.transaction(async trx => await releaseBatchState(storage, batch, 'aborted', trx))\n    throw error\n  }\n  const explicitIds = new Set(fixedOutputs.map(output => output.outputId))\n  return {\n    batchId: batch.batchId,\n    expiresAt: batch.expiresAt.toISOString(),\n    hardExpiresAt: batch.hardExpiresAt.toISOString(),\n    changeBasket,\n    feeModel: validateStorageFeeModel(storage.feeModel),\n    commissionSatoshis: storage.commissionSatoshis,\n    commissionPubKeyHex: storage.commissionPubKeyHex,\n    availableChangeCount: available.length,\n    reservedOutputs: fundingResult.outputs.filter(output => funding.some(candidate => candidate.outputId === output.outputId)),\n    explicitOutputs: fundingResult.outputs.filter(output => explicitIds.has(output.outputId)),\n    inputBeef: fundingResult.beef\n  }\n}\n\nfunction requireLiveBatch (batch: TableActionBatch | undefined): TableActionBatch {\n  if (batch == null || activeExpiry(batch)) throw new WERR_INVALID_OPERATION('action batch is not active')\n  return batch\n}\n\nexport async function extendActionBatch (\n  storage: StorageProvider,\n  auth: AuthId,\n  args: ExtendActionBatchArgs\n): Promise<ExtendActionBatchResult> {\n  const userId = verifyId(auth.userId)\n  await cleanupExpiredActionBatches(storage)\n  const batch = requireLiveBatch(await storage.findActionBatch(userId, args.batchId))\n  const basket = verifyOne(await storage.findOutputBaskets({ partial: { userId, name: 'default' } }))\n  const alreadyReserved = await storage.findActionBatchOutputIds(batch.actionBatchId)\n  const available = await storage.findAvailableManagedChangeInputs(userId, basket.basketId, false)\n  if (!Number.isSafeInteger(args.requestedOutputs) || args.requestedOutputs < 0) {\n    throw new WERR_INVALID_PARAMETER('requestedOutputs', 'non-negative safe integer')\n  }\n  const requestedCount = Math.min(\n    args.requestedOutputs,\n    ACTION_BATCH_MAX_RESERVATION_EXTENSION_OUTPUTS\n  )\n  const funding = chooseReservationPool(\n    available,\n    Math.max(1, args.targetSatoshis),\n    requestedCount,\n    0,\n    true,\n    reservationPlanningCosts(storage, basket)\n  )\n  const explicitByOutpoint = await storage.findOutputsByOutpoints(userId, args.explicitOutpoints)\n  const explicit = Object.values(explicitByOutpoint)\n    .filter(output => !alreadyReserved.includes(output.outputId))\n  const fundingShape = argsToFundingShape(args.includeSourceTransactions)\n  const fundingResult = await makeFundingResult(storage, fundingShape, [...funding, ...explicit])\n  const expiresAt = new Date(Math.min(\n    batch.hardExpiresAt.getTime(),\n    Date.now() + ACTION_BATCH_LEASE_MS\n  ))\n  await storage.transaction(async trx => {\n    const current = requireLiveBatch(await storage.findActionBatchForUpdate(userId, args.batchId, trx))\n    await reserveOutputs(storage, current, [...funding, ...explicit], trx)\n    await storage.updateActionBatch(current.actionBatchId, { expiresAt }, trx)\n  })\n  return {\n    expiresAt: expiresAt.toISOString(),\n    reservedOutputs: fundingResult.outputs.filter(output => funding.some(candidate => candidate.outputId === output.outputId)),\n    explicitOutputs: fundingResult.outputs.filter(output => explicit.some(candidate => candidate.outputId === output.outputId)),\n    inputBeef: fundingResult.beef\n  }\n}\n\nfunction argsToFundingShape (includeSourceTransactions: boolean): Validation.ValidCreateActionArgs {\n  return {\n    inputs: [], outputs: [], labels: [], description: 'action batch extension', version: 1, lockTime: 0,\n    options: {\n      acceptDelayedBroadcast: true, returnTXIDOnly: false, noSend: true, sendWith: [], signAndProcess: true,\n      knownTxids: [], noSendChange: [], randomizeOutputs: true\n    },\n    isSendWith: false, isNewTx: true, isRemixChange: false, isNoSend: true, isDelayed: true,\n    isTestWerrReviewActions: false,\n    isSignAction: includeSourceTransactions,\n    includeAllSourceTransactions: includeSourceTransactions\n  }\n}\n\nexport async function renewActionBatch (\n  storage: StorageProvider,\n  auth: AuthId,\n  batchId: string\n): Promise<RenewActionBatchResult> {\n  const userId = verifyId(auth.userId)\n  return await storage.transaction(async trx => {\n    const batch = requireLiveBatch(await storage.findActionBatchForUpdate(userId, batchId, trx))\n    const expiresAt = new Date(Math.min(batch.hardExpiresAt.getTime(), Date.now() + ACTION_BATCH_LEASE_MS))\n    await storage.updateActionBatch(batch.actionBatchId, { expiresAt }, trx)\n    return { expiresAt: expiresAt.toISOString() }\n  })\n}\n\nasync function reacquireManifestInputs (\n  storage: StorageProvider,\n  userId: number,\n  batch: TableActionBatch,\n  validated: { actions: ValidatedBatchAction[] },\n  trx: TrxToken\n): Promise<void> {\n  if (batch.hardExpiresAt.getTime() <= Date.now()) {\n    throw new WERR_INVALID_OPERATION('action batch hard lifetime has expired')\n  }\n  const stagedTxids = new Set(validated.actions.map(({ action }) => action.txid))\n  const outpoints = [...new Map(validated.actions.flatMap(({ action }) => action.plan.inputs)\n    .filter(input => !stagedTxids.has(input.sourceTxid))\n    .map(input => [`${input.sourceTxid}.${input.sourceVout}`, {\n      txid: input.sourceTxid,\n      vout: input.sourceVout,\n      providedBy: input.providedBy\n    }])).values()]\n\n  const stored = await storage.findOutputsByOutpointsForUpdate(userId, outpoints, trx)\n  await storage.deleteActionBatchOutputReservations(batch.actionBatchId, trx)\n  const outputs: TableOutput[] = []\n  for (const outpoint of outpoints) {\n    const key = `${outpoint.txid}.${outpoint.vout}`\n    const output = stored[key]\n    if (output == null) {\n      if (outpoint.providedBy === 'storage' || outpoint.providedBy === 'you-and-storage') {\n        throw new WERR_INVALID_OPERATION(`reserved input ${key} is no longer available`)\n      }\n      continue\n    }\n    if (!output.spendable || output.spentBy != null) {\n      throw new WERR_INVALID_OPERATION(`input ${key} is no longer spendable`)\n    }\n    outputs.push(output)\n  }\n  const conflicts = await storage.findReservedActionBatchOutputIds(outputs.map(output => output.outputId), trx)\n  if (conflicts.length > 0) {\n    throw new WERR_INVALID_OPERATION('one or more expired action batch inputs were reserved elsewhere')\n  }\n  const now = new Date()\n  await storage.reserveActionBatchOutputs(outputs.map(output => ({\n    actionBatchId: batch.actionBatchId,\n    outputId: output.outputId,\n    created_at: now,\n    updated_at: now\n  })), trx)\n  await storage.updateActionBatch(batch.actionBatchId, {\n    status: 'active',\n    expiresAt: new Date(Math.min(batch.hardExpiresAt.getTime(), now.getTime() + ACTION_BATCH_LEASE_MS))\n  }, trx)\n}\n\nfunction transactionStatuses (action: ActionBatchCommitAction): { tx: TransactionStatus, req: ProvenTxReqStatus } {\n  if (action.metadata.isNoSend) return { tx: 'nosend', req: 'nosend' }\n  if (action.metadata.isDelayed) return { tx: 'unprocessed', req: 'unsent' }\n  return { tx: 'unprocessed', req: 'unprocessed' }\n}\n\nasync function persistLabels (\n  storage: StorageProvider,\n  transactionId: number,\n  labels: string[],\n  labelsByName: ReadonlyMap<string, TableTxLabel>,\n  trx: TrxToken\n): Promise<void> {\n  for (const label of new Set(labels)) {\n    const row = labelsByName.get(label)\n    if (row == null) throw new WERR_INTERNAL(`missing preloaded transaction label ${label}`)\n    await storage.findOrInsertTxLabelMap(transactionId, verifyId(row.txLabelId), trx)\n  }\n}\n\nfunction outputBasketId (\n  isChange: boolean,\n  basket: string | undefined,\n  baskets: Record<string, TableOutputBasket>\n): number | undefined {\n  if (isChange) return baskets.default?.basketId\n  return basket == null ? undefined : baskets[basket].basketId\n}\n\nasync function persistOutputTags (\n  storage: StorageProvider,\n  outputId: number,\n  tagNames: string[],\n  tags: Record<string, TableOutputTag>,\n  trx: TrxToken\n): Promise<void> {\n  for (const tagName of new Set(tagNames)) {\n    const tag = tags[tagName]\n    await storage.findOrInsertOutputTagMap(outputId, verifyId(tag.outputTagId), trx)\n  }\n}\n\nasync function persistOutputCommission (\n  storage: StorageProvider,\n  row: TableOutput,\n  action: ActionBatchCommitAction,\n  transactionId: number,\n  trx: TrxToken\n): Promise<void> {\n  if (row.lockingScript == null) {\n    throw new WERR_INTERNAL('commission locking script must be retained')\n  }\n  const commission: TableCommission = {\n    commissionId: 0,\n    userId: row.userId,\n    transactionId,\n    satoshis: row.satoshis,\n    keyOffset: action.commissionKeyOffset ?? '',\n    isRedeemed: false,\n    lockingScript: row.lockingScript,\n    created_at: row.created_at,\n    updated_at: row.updated_at\n  }\n  await storage.insertCommission(commission, trx)\n}\n\nasync function persistOutputs (\n  storage: StorageProvider,\n  userId: number,\n  transactionId: number,\n  validated: ValidatedBatchAction,\n  baskets: Record<string, TableOutputBasket>,\n  tags: Record<string, TableOutputTag>,\n  trx: TrxToken\n): Promise<TableOutput[]> {\n  const { action, tx, rawTx } = validated\n  const offsets = parseTxScriptOffsets(rawTx)\n  const rows: TableOutput[] = []\n  for (const planned of action.plan.outputs) {\n    const output = tx.outputs[planned.vout]\n    const isChange = planned.providedBy === 'storage' && planned.purpose === 'change'\n    const isCommission = planned.providedBy === 'storage' &&\n      (planned.purpose === 'storage-commission' || planned.purpose === 'service-charge')\n    const offset = offsets.outputs[planned.vout]\n    const lockingScript = offset.length <= storage.getSettings().maxOutputScript || isCommission\n      ? output.lockingScript.toBinary()\n      : undefined\n    const now = new Date()\n    const row: TableOutput = {\n      outputId: 0,\n      userId,\n      transactionId,\n      basketId: outputBasketId(isChange, planned.basket, baskets),\n      spendable: !isCommission,\n      change: isChange,\n      outputDescription: planned.outputDescription,\n      vout: planned.vout,\n      satoshis: planned.satoshis,\n      providedBy: planned.providedBy,\n      purpose: isCommission ? 'storage-commission' : (planned.purpose ?? ''),\n      type: isChange ? 'P2PKH' : 'custom',\n      txid: action.txid,\n      derivationPrefix: isChange ? action.plan.derivationPrefix : undefined,\n      derivationSuffix: isChange ? planned.derivationSuffix : undefined,\n      customInstructions: planned.customInstructions,\n      scriptLength: offset.length,\n      scriptOffset: offset.offset,\n      lockingScript,\n      created_at: now,\n      updated_at: now\n    }\n    row.outputId = await storage.insertOutput(row, trx)\n    await persistOutputTags(storage, row.outputId, planned.tags, tags, trx)\n    if (isCommission) await persistOutputCommission(storage, row, action, transactionId, trx)\n    rows.push(row)\n  }\n  return rows\n}\n\nasync function persistAction (\n  ...[\n    storage,\n    userId,\n    validated,\n    reservedOutputIds,\n    storedByOutpoint,\n    stagedByOutpoint,\n    labelsByName,\n    baskets,\n    tags,\n    trx\n  ]: [\n    storage: StorageProvider,\n    userId: number,\n    validated: ValidatedBatchAction,\n    reservedOutputIds: Set<number>,\n    storedByOutpoint: Readonly<Record<string, TableOutput>>,\n    stagedByOutpoint: Map<string, TableOutput>,\n    labelsByName: ReadonlyMap<string, TableTxLabel>,\n    baskets: Record<string, TableOutputBasket>,\n    tags: Record<string, TableOutputTag>,\n    trx: TrxToken\n  ]\n): Promise<EntityProvenTxReq> {\n  const { action, tx, rawTx } = validated\n  const statuses = transactionStatuses(action)\n  const managedInputSatoshis = action.plan.inputs\n    .filter(input => input.vin >= action.metadata.inputs.length)\n    .reduce((sum, input) => sum + input.sourceSatoshis, 0)\n  const changeOutputSatoshis = action.plan.outputs\n    .filter(output => output.purpose === 'change')\n    .reduce((sum, output) => sum + output.satoshis, 0)\n  const now = new Date()\n  const transaction: TableTransaction = {\n    transactionId: 0,\n    userId,\n    status: statuses.tx,\n    reference: action.reference,\n    isOutgoing: true,\n    satoshis: changeOutputSatoshis - managedInputSatoshis,\n    description: action.metadata.description,\n    version: tx.version,\n    lockTime: tx.lockTime,\n    txid: action.txid,\n    created_at: now,\n    updated_at: now\n  }\n  transaction.transactionId = await storage.insertTransaction(transaction, trx)\n  await persistLabels(storage, transaction.transactionId, action.metadata.labels, labelsByName, trx)\n\n  for (const input of action.plan.inputs) {\n    const outpoint = `${input.sourceTxid}.${input.sourceVout}`\n    let output = stagedByOutpoint.get(outpoint)\n    output ??= storedByOutpoint[outpoint]\n    if (output == null) continue\n    if (output.spentBy != null || !output.spendable) throw new WERR_INVALID_OPERATION(`input ${outpoint} is no longer spendable`)\n    if (!stagedByOutpoint.has(outpoint) && !reservedOutputIds.has(output.outputId)) {\n      throw new WERR_INVALID_OPERATION(`input ${outpoint} was not reserved by this action batch`)\n    }\n    await storage.updateOutput(output.outputId, {\n      spendable: false,\n      spentBy: transaction.transactionId,\n      spendingDescription: action.metadata.inputs[input.vin]?.inputDescription\n    }, trx)\n    output.spendable = false\n    output.spentBy = transaction.transactionId\n  }\n\n  const outputRows = await persistOutputs(\n    storage,\n    userId,\n    transaction.transactionId,\n    validated,\n    baskets,\n    tags,\n    trx\n  )\n  for (const output of outputRows) stagedByOutpoint.set(`${action.txid}.${output.vout}`, output)\n\n  const req = EntityProvenTxReq.fromTxid(\n    action.txid,\n    rawTx,\n    validated.externalInputBeef\n  )\n  req.status = statuses.req\n  req.addNotifyTransactionId(transaction.transactionId)\n  return await req.insertOrMerge(storage, trx)\n}\n\nasync function persistManifestAtomically (\n  storage: StorageProvider,\n  userId: number,\n  batch: TableActionBatch,\n  manifest: ActionBatchManifest,\n  validated: { actions: ValidatedBatchAction[], dependencyBeef: Uint8Array, beef: Beef }\n): Promise<{\n    batch: TableActionBatch\n    alreadyCommitted: boolean\n    share?: GetReqsAndBeefResult\n  }> {\n  return await storage.transaction(async trx => {\n    const current = await storage.findActionBatchForUpdate(userId, batch.batchId, trx)\n    if (current == null) throw new WERR_INVALID_OPERATION('action batch was not found')\n    if (current.status === 'committed') {\n      if (current.manifestDigest !== manifest.digest) {\n        throw new WERR_INVALID_OPERATION('batch committed with another manifest')\n      }\n      return { batch: current, alreadyCommitted: true }\n    }\n    if (current.status === 'aborted') throw new WERR_INVALID_OPERATION('aborted action batch cannot be committed')\n    if (current.manifestDigest != null && current.manifestDigest !== manifest.digest) {\n      throw new WERR_INVALID_OPERATION('batch prepared with another manifest')\n    }\n    const needsReacquire = current.status === 'expired' || activeExpiry(current)\n    if (needsReacquire) {\n      if (current.hardExpiresAt.getTime() <= Date.now()) {\n        throw new WERR_INVALID_OPERATION('action batch hard lifetime has expired')\n      }\n      await reacquireManifestInputs(storage, userId, current, validated, trx)\n    } else {\n      requireLiveBatch(current)\n    }\n    const reservedOutputIds = new Set(await storage.findActionBatchOutputIds(current.actionBatchId, trx))\n    const stagedTxids = new Set(validated.actions.map(({ action }) => action.txid))\n    const inputOutpoints = [...new Map(validated.actions.flatMap(({ action }) => action.plan.inputs)\n      .filter(input => !stagedTxids.has(input.sourceTxid))\n      .map(input => [`${input.sourceTxid}.${input.sourceVout}`, {\n        txid: input.sourceTxid,\n        vout: input.sourceVout\n      }])).values()]\n    const storedByOutpoint = await storage.findOutputsByOutpointsForUpdate(\n      userId,\n      inputOutpoints,\n      trx\n    )\n    const allBasketNames = validated.actions.flatMap(({ action }) =>\n      action.plan.outputs.flatMap(output => output.basket == null ? [] : [output.basket])\n    )\n    if (validated.actions.some(({ action }) =>\n      action.plan.outputs.some(output => output.purpose === 'change')\n    )) allBasketNames.push('default')\n    const baskets = await storage.findOrInsertOutputBasketsBulk(\n      userId,\n      [...new Set(allBasketNames)],\n      trx\n    )\n    const tags = await storage.findOrInsertOutputTagsBulk(\n      userId,\n      [...new Set(validated.actions.flatMap(({ action }) =>\n        action.plan.outputs.flatMap(output => output.tags)\n      ))],\n      trx\n    )\n    const labelNames = [...new Set(validated.actions.flatMap(({ action }) => action.metadata.labels))]\n    const labelsByName = new Map(Object.entries(\n      await storage.findOrInsertTxLabelsBulk(userId, labelNames, trx)\n    ))\n    const stagedByOutpoint = new Map<string, TableOutput>()\n    const reqsByTxid = new Map<string, EntityProvenTxReq>()\n    for (const action of validated.actions) {\n      const req = await persistAction(\n        storage,\n        userId,\n        action,\n        reservedOutputIds,\n        storedByOutpoint,\n        stagedByOutpoint,\n        labelsByName,\n        baskets,\n        tags,\n        trx\n      )\n      reqsByTxid.set(action.action.txid, req)\n    }\n    await storage.deleteActionBatchOutputReservations(current.actionBatchId, trx)\n    await storage.deleteActionBatchBlobRecords(current.actionBatchId, trx)\n    await storage.updateActionBatch(current.actionBatchId, {\n      status: 'committed',\n      manifestDigest: manifest.digest\n    }, trx)\n    current.status = 'committed'\n    current.manifestDigest = manifest.digest\n    const details = manifest.sendWith.map(txid => {\n      const req = reqsByTxid.get(txid)\n      if (req == null) return undefined\n      const reqApi = req.toApi()\n      const detail: GetReqsAndBeefResult['details'][number] = {\n        txid,\n        req: reqApi,\n        status: 'unknown'\n      }\n      classifyReqStatus(detail, reqApi)\n      return detail\n    })\n    return {\n      batch: current,\n      alreadyCommitted: false,\n      share: details.every(detail => detail != null)\n        ? {\n            beef: validated.beef,\n            details: details.filter((detail): detail is NonNullable<typeof detail> => detail != null),\n            verified: true\n          }\n        : undefined\n    }\n  })\n}\n\nasync function completeCommittedBatch (\n  storage: StorageProvider,\n  userId: number,\n  batch: TableActionBatch,\n  manifest: ActionBatchManifest,\n  alreadyCommitted: boolean,\n  share?: GetReqsAndBeefResult\n): Promise<CommitActionBatchResult> {\n  if (batch.result != null) {\n    const saved = JSON.parse(batch.result) as CommitActionBatchResult\n    return {\n      batchId: saved.batchId,\n      manifestDigest: saved.manifestDigest,\n      committedTxids: saved.committedTxids,\n      alreadyCommitted: true,\n      sendWithResults: saved.sendWithResults,\n      notDelayedResults: saved.notDelayedResults,\n      log: saved.log\n    }\n  }\n  const { swr, ndr } = await shareReqsWithWorld(\n    storage,\n    userId,\n    manifest.sendWith,\n    manifest.isDelayed,\n    share\n  )\n  const result: CommitActionBatchResult = {\n    batchId: manifest.batchId,\n    manifestDigest: manifest.digest,\n    committedTxids: manifest.actions.map(action => action.txid),\n    alreadyCommitted,\n    sendWithResults: swr,\n    notDelayedResults: ndr\n  }\n  await storage.updateActionBatch(batch.actionBatchId, { result: JSON.stringify(result) })\n  return result\n}\n\nasync function commitActionBatchOnce (\n  storage: StorageProvider,\n  userId: number,\n  manifest: ActionBatchManifest\n): Promise<CommitActionBatchResult> {\n  const batch = await storage.findActionBatch(userId, manifest.batchId)\n  if (batch == null) throw new WERR_INVALID_OPERATION('action batch was not found')\n  if (batch.status === 'committed') {\n    if (batch.manifestDigest !== manifest.digest) throw new WERR_INVALID_OPERATION('batch committed with another manifest')\n    return await completeCommittedBatch(storage, userId, batch, manifest, true)\n  }\n  if (batch.status === 'aborted') throw new WERR_INVALID_OPERATION('aborted action batch cannot be committed')\n  const needsReacquire = batch.status === 'expired' || activeExpiry(batch)\n  if (!needsReacquire) requireLiveBatch(batch)\n  else if (batch.hardExpiresAt.getTime() <= Date.now()) {\n    throw new WERR_INVALID_OPERATION('action batch hard lifetime has expired')\n  }\n  if (batch.manifestDigest != null && batch.manifestDigest !== manifest.digest) {\n    throw new WERR_INVALID_OPERATION('batch prepared with another manifest')\n  }\n  const validated = await validateManifestActions(storage, batch, manifest)\n  const persisted = await persistManifestAtomically(storage, userId, batch, manifest, validated)\n  return await completeCommittedBatch(\n    storage,\n    userId,\n    persisted.batch,\n    manifest,\n    persisted.alreadyCommitted,\n    persisted.share\n  )\n}\n\ninterface ActiveBatchCommit {\n  digest: string\n  promise: Promise<CommitActionBatchResult>\n}\n\nconst activeBatchCommits = new WeakMap<StorageProvider, Map<string, ActiveBatchCommit>>()\n\nexport async function commitActionBatch (\n  storage: StorageProvider,\n  auth: AuthId,\n  manifest: ActionBatchManifest\n): Promise<CommitActionBatchResult> {\n  validateActionBatchInlinePayload(manifest)\n  if (!verifyActionBatchManifestDigest(manifest)) throw new WERR_INVALID_PARAMETER('manifest.digest', 'valid')\n  validateCompactManifest(manifest)\n  const userId = verifyId(auth.userId)\n  let commits = activeBatchCommits.get(storage)\n  if (commits == null) {\n    commits = new Map()\n    activeBatchCommits.set(storage, commits)\n  }\n  const key = `${userId}:${manifest.batchId}`\n  const active = commits.get(key)\n  if (active != null) {\n    if (active.digest !== manifest.digest) {\n      throw new WERR_INVALID_OPERATION('action batch commit is active with another manifest')\n    }\n    return await active.promise\n  }\n  const promise = commitActionBatchOnce(storage, userId, manifest)\n    .finally(() => { commits?.delete(key) })\n  commits.set(key, { digest: manifest.digest, promise })\n  return await promise\n}\n\nexport async function commitActionBatchByDigest (\n  storage: StorageProvider,\n  auth: AuthId,\n  args: CommitActionBatchByDigestArgs\n): Promise<CommitActionBatchResult> {\n  const userId = verifyId(auth.userId)\n  const batch = await storage.findActionBatch(userId, args.batchId)\n  if (batch?.manifestDigest !== args.digest || batch?.manifest == null) {\n    throw new WERR_INVALID_OPERATION('prepared action batch manifest was not found')\n  }\n  const manifest = JSON.parse(batch.manifest) as ActionBatchManifest\n  if (manifest.format !== 2 || manifest.batchId !== args.batchId || manifest.digest !== args.digest ||\n    !verifyActionBatchManifestDigest(manifest)) {\n    throw new WERR_INVALID_OPERATION('prepared action batch manifest is invalid')\n  }\n  return await commitActionBatch(storage, auth, manifest)\n}\n\nexport async function abortActionBatch (\n  storage: StorageProvider,\n  auth: AuthId,\n  batchId: string\n): Promise<AbortActionBatchResult> {\n  const userId = verifyId(auth.userId)\n  return await storage.transaction(async trx => {\n    const batch = await storage.findActionBatchForUpdate(userId, batchId, trx)\n    if (batch == null || batch.status === 'aborted') return { aborted: true }\n    if (batch.status === 'committed') return { aborted: false }\n    await releaseBatchState(storage, batch, 'aborted', trx)\n    return { aborted: true }\n  })\n}\n","import type { TransactionStatus } from '../../sdk/types'\nimport type { TrxToken } from '../../sdk/WalletStorage.interfaces'\nimport type { StorageProvider } from '../StorageProvider'\nimport type { TableOutput } from '../schema/tables/TableOutput'\nimport { isAutoSpendableChangeOutput, managedChangeOutputFields } from './managedChange'\n\nexport type ManagedChangeInputCandidate = Pick<\n  TableOutput,\n  'outputId' | 'transactionId' | 'satoshis' | 'txid' | 'vout'\n>\n\n/**\n * Return the exact set of wallet-managed outputs currently eligible for\n * automatic funding. Keeping this predicate shared prevents the planner,\n * allocator, action-batch reservations, and availability count from drifting.\n */\nexport async function availableManagedChange (\n  storage: StorageProvider,\n  userId: number,\n  basketId: number,\n  excludeSending: boolean,\n  trx?: TrxToken\n): Promise<TableOutput[]> {\n  const statuses: TransactionStatus[] = ['completed', 'unproven']\n  if (!excludeSending) statuses.push('sending')\n  const outputs = (await storage.findOutputs({\n    partial: { userId, basketId, spendable: true, ...managedChangeOutputFields },\n    txStatus: statuses,\n    noScript: true,\n    trx\n  })).filter(isAutoSpendableChangeOutput)\n  if (outputs.length === 0) return outputs\n  const reserved = new Set(await storage.findReservedActionBatchOutputIds(outputs.map(output => output.outputId), trx))\n  return outputs.filter(output => !reserved.has(output.outputId))\n}\n","import {\n  AbortActionResult,\n  Beef,\n  InternalizeActionArgs,\n  ListActionsResult,\n  ListOutputsResult,\n  PubKeyHex,\n  ListCertificatesResult,\n  TrustSelf,\n  RelinquishCertificateArgs,\n  RelinquishOutputArgs,\n  AbortActionArgs,\n  Validation,\n  WalletLoggerInterface,\n  ChainTracker,\n  Transaction\n} from '@bsv/sdk'\nimport type { SpendVerifierInterface } from '@bsv/sdk'\nimport {\n  classifyReqStatus,\n  mergeInputsIntoBeef,\n  mergeInputBeefs,\n  notifyTransactionsOfProof\n} from './storageProviderHelpers'\nimport { getBeefForTransaction, getBeefForTransactions } from './methods/getBeefForTransaction'\nimport { GetReqsAndBeefDetail, GetReqsAndBeefResult, processAction } from './methods/processAction'\nimport { attemptToPostReqsToNetwork, PostReqsToNetworkResult } from './methods/attemptToPostReqsToNetwork'\nimport { listCertificates } from './methods/listCertificates'\nimport { createAction } from './methods/createAction'\nimport { internalizeAction } from './methods/internalizeAction'\nimport { StorageReaderWriter, StorageReaderWriterOptions } from './StorageReaderWriter'\nimport { EntityProvenTx, EntityProvenTxReq, EntitySyncState, EntityTransaction } from './schema/entities'\nimport { ServicesCallHistory, WalletServices } from '../sdk/WalletServices.interfaces'\nimport {\n  AuthId,\n  FindCertificatesArgs,\n  FindOutputBasketsArgs,\n  FindOutputsArgs,\n  FindStaleMerkleRootsArgs,\n  ProcessSyncChunkResult,\n  ProvenOrRawTx,\n  PurgeParams,\n  PurgeResults,\n  RequestSyncChunkArgs,\n  StorageCreateActionResult,\n  StorageFeeModel,\n  StorageGetBeefOptions,\n  StorageInternalizeActionResult,\n  StorageProcessActionArgs,\n  StorageProcessActionResults,\n  StorageProvenOrReq,\n  SyncChunk,\n  TrxToken,\n  UpdateProvenTxReqWithNewProvenTxArgs,\n  UpdateProvenTxReqWithNewProvenTxResult,\n  WalletStorageProvider\n} from '../sdk/WalletStorage.interfaces'\nimport { Chain, TransactionStatus } from '../sdk/types'\nimport { TableProvenTxReq, TableProvenTxReqDynamics } from '../../src/storage/schema/tables/TableProvenTxReq'\nimport { TableOutputBasket } from '../../src/storage/schema/tables/TableOutputBasket'\nimport { TableTransaction } from '../../src/storage/schema/tables/TableTransaction'\nimport { TableOutput, TableOutputX } from '../../src/storage/schema/tables/TableOutput'\nimport { TableOutputTag } from '../../src/storage/schema/tables/TableOutputTag'\nimport { TableTxLabel } from '../../src/storage/schema/tables/TableTxLabel'\nimport { TableMonitorEvent } from '../../src/storage/schema/tables/TableMonitorEvent'\nimport { TableUser } from '../../src/storage/schema/tables/TableUser'\nimport { TableCertificateX } from './schema/tables/TableCertificate'\nimport {\n  WERR_INTERNAL,\n  WERR_INVALID_MERKLE_ROOT,\n  WERR_INVALID_OPERATION,\n  WERR_INVALID_PARAMETER,\n  WERR_MISSING_PARAMETER,\n  WERR_NOT_IMPLEMENTED,\n  WERR_UNAUTHORIZED\n} from '../sdk/WERR_errors'\nimport { verifyId, verifyOne, verifyOneOrNone, verifyTruthy } from '../utility/utilityHelpers'\nimport { WalletError } from '../sdk/WalletError'\nimport { asArray, asString } from '../utility/utilityHelpers.noBuffer'\nimport { TableActionBatch, TableActionBatchBlob, TableActionBatchOutput } from './schema/tables/TableActionBatch'\nimport {\n  AbortActionBatchResult,\n  ActionBatchManifest,\n  BeginActionBatchArgs,\n  BeginActionBatchResult,\n  CommitActionBatchByDigestArgs,\n  CommitActionBatchResult,\n  ExtendActionBatchArgs,\n  ExtendActionBatchResult,\n  PrepareActionBatchCommitResult,\n  PutActionBatchBlobArgs,\n  PutActionBatchPackArgs,\n  RenewActionBatchResult,\n  StorageCapabilities\n} from '../sdk/ActionBatch.interfaces'\nimport {\n  abortActionBatch as abortBatch,\n  beginActionBatch as beginBatch,\n  cleanupExpiredActionBatches,\n  commitActionBatch as commitBatch,\n  commitActionBatchByDigest as commitBatchByDigest,\n  extendActionBatch as extendBatch,\n  getActionBatchCapabilities,\n  renewActionBatch as renewBatch\n} from './methods/actionBatch'\nimport {\n  prepareActionBatchCommit as prepareBatchCommit,\n  putActionBatchBlob as putBatchBlob,\n  putActionBatchPack as putBatchPack\n} from './methods/actionBatchBlobs'\nimport { availableManagedChange, ManagedChangeInputCandidate } from './methods/availableManagedChange'\n\nexport abstract class StorageProvider extends StorageReaderWriter implements WalletStorageProvider {\n  isDirty = false\n  _services?: WalletServices\n  feeModel: StorageFeeModel\n  commissionSatoshis: number\n  commissionPubKeyHex?: PubKeyHex\n  maxRecursionDepth?: number\n  readonly scriptVerifier?: SpendVerifierInterface\n\n  static defaultOptions(): { feeModel: StorageFeeModel; commissionSatoshis: number; commissionPubKeyHex: undefined } {\n    const opts: { feeModel: StorageFeeModel; commissionSatoshis: number; commissionPubKeyHex: undefined } = {\n      feeModel: { model: 'sat/kb', value: 100 },\n      commissionSatoshis: 0,\n      commissionPubKeyHex: undefined\n    }\n    return opts\n  }\n\n  static createStorageBaseOptions(chain: Chain): StorageProviderOptions {\n    const options: StorageProviderOptions = {\n      ...StorageProvider.defaultOptions(),\n      chain\n    }\n    return options\n  }\n\n  constructor(options: StorageProviderOptions) {\n    super(options)\n    this.feeModel = options.feeModel\n    this.commissionPubKeyHex = options.commissionPubKeyHex\n    this.commissionSatoshis = options.commissionSatoshis\n    this.maxRecursionDepth = 12\n    this.scriptVerifier = options.scriptVerifier\n  }\n\n  abstract reviewStatus(args: { agedLimit: Date; trx?: TrxToken }): Promise<{ log: string }>\n\n  abstract purgeData(params: PurgeParams, trx?: TrxToken): Promise<PurgeResults>\n\n  abstract allocateChangeInput(\n    userId: number,\n    basketId: number,\n    targetSatoshis: number,\n    exactSatoshis: number | undefined,\n    excludeSending: boolean,\n    transactionId: number\n  ): Promise<TableOutput | undefined>\n\n  /** Mark a planned set of change inputs spent within the caller's transaction. */\n  async markChangeInputsSpent(outputIds: number[], transactionId: number, trx: TrxToken): Promise<number> {\n    let updated = 0\n    const current = await this.findOutputsByIds(outputIds, trx)\n    for (const outputId of outputIds) {\n      const output = current[outputId]\n      if (output == null || !output.spendable || output.spentBy != null) continue\n      updated += await this.updateOutput(outputId, { spendable: false, spentBy: transactionId }, trx)\n    }\n    return updated\n  }\n\n  /**\n   * Insert outputs that do not need their generated ids returned to the\n   * caller. Engines with a multi-row insert override this common-path helper;\n   * the fallback preserves existing storage implementations unchanged.\n   */\n  async insertOutputs(outputs: TableOutput[], trx?: TrxToken): Promise<void> {\n    for (const output of outputs) await this.insertOutput(output, trx)\n  }\n\n  /** Return unreserved wallet-managed outputs eligible for automatic funding. */\n  async findAvailableManagedChangeInputs(\n    userId: number,\n    basketId: number,\n    excludeSending: boolean,\n    trx?: TrxToken\n  ): Promise<TableOutput[]> {\n    return await availableManagedChange(this, userId, basketId, excludeSending, trx)\n  }\n\n  /** Read only the fields needed by the in-memory funding planner. */\n  async findAvailableManagedChangeInputCandidates(\n    userId: number,\n    basketId: number,\n    excludeSending: boolean,\n    trx?: TrxToken\n  ): Promise<ManagedChangeInputCandidate[]> {\n    return (await this.findAvailableManagedChangeInputs(userId, basketId, excludeSending, trx))\n      .map(({ outputId, transactionId, satoshis, txid, vout }) => ({\n        outputId,\n        transactionId,\n        satoshis,\n        txid,\n        vout\n      }))\n  }\n\n  /** Read the current status of a set of source transactions without loading raw transaction bytes. */\n  async findTransactionStatusesByIds(\n    userId: number,\n    transactionIds: number[],\n    trx?: TrxToken\n  ): Promise<Map<number, TransactionStatus>> {\n    const statuses = new Map<number, TransactionStatus>()\n    for (const transactionId of new Set(transactionIds)) {\n      const transaction = await this.findTransactionById(transactionId, trx, true)\n      if (transaction?.userId === userId) statuses.set(transactionId, transaction.status)\n    }\n    return statuses\n  }\n\n  /**\n   * Lock and return the selected funding rows whose source transaction and\n   * action-batch reservation state still permit allocation.\n   */\n  async findFundingOutputsForUpdate(\n    userId: number,\n    outputIds: number[],\n    statuses: TransactionStatus[],\n    trx: TrxToken\n  ): Promise<Record<number, TableOutput>> {\n    const rows = await this.findOutputsByIds(outputIds, trx)\n    const reserved = new Set(await this.findReservedActionBatchOutputIds(outputIds, trx))\n    const transactionIds = [...new Set(Object.values(rows).map(output => output.transactionId))]\n    const transactionStatuses = await this.findTransactionStatusesByIds(userId, transactionIds, trx)\n    const eligible: Record<number, TableOutput> = {}\n    for (const output of Object.values(rows)) {\n      if (\n        output.userId === userId &&\n        !reserved.has(output.outputId) &&\n        statuses.includes(transactionStatuses.get(output.transactionId) as TransactionStatus)\n      ) eligible[output.outputId] = output\n    }\n    return eligible\n  }\n\n  abstract getProvenOrRawTx(txid: string, trx?: TrxToken): Promise<ProvenOrRawTx>\n\n  /**\n   * Resolve several transaction proofs in one storage operation when the\n   * backend supports it. The default preserves compatibility for custom\n   * providers; SQL and IndexedDB providers override this hot path.\n   */\n  async getProvenOrRawTxs(txids: string[], trx?: TrxToken): Promise<Map<string, ProvenOrRawTx>> {\n    const results = new Map<string, ProvenOrRawTx>()\n    const unique = [...new Set(txids)]\n    let cursor = 0\n    await Promise.all(\n      Array.from({ length: Math.min(8, unique.length) }, async () => {\n        while (cursor < unique.length) {\n          const txid = unique[cursor++]\n          results.set(txid, await this.getProvenOrRawTx(txid, trx))\n        }\n      })\n    )\n    return results\n  }\n  abstract getRawTxOfKnownValidTransaction(\n    txid?: string,\n    offset?: number,\n    length?: number,\n    trx?: TrxToken\n  ): Promise<number[] | undefined>\n\n  abstract getLabelsForTransactionId(transactionId?: number, trx?: TrxToken): Promise<TableTxLabel[]>\n  abstract getTagsForOutputId(outputId: number, trx?: TrxToken): Promise<TableOutputTag[]>\n\n  abstract listActions(auth: AuthId, args: Validation.ValidListActionsArgs): Promise<ListActionsResult>\n  abstract listOutputs(auth: AuthId, args: Validation.ValidListOutputsArgs): Promise<ListOutputsResult>\n\n  abstract countChangeInputs(userId: number, basketId: number, excludeSending: boolean): Promise<number>\n\n  async insertActionBatch(_batch: TableActionBatch, _trx?: TrxToken): Promise<number> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n  async findActionBatch(_userId: number, _batchId: string, _trx?: TrxToken): Promise<TableActionBatch | undefined> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n  async findActionBatchForUpdate(\n    userId: number,\n    batchId: string,\n    trx: TrxToken\n  ): Promise<TableActionBatch | undefined> {\n    return await this.findActionBatch(userId, batchId, trx)\n  }\n\n  async findExpiredActionBatches(_now: Date, _trx?: TrxToken): Promise<TableActionBatch[]> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n  async updateActionBatch(\n    _actionBatchId: number,\n    _update: Partial<TableActionBatch>,\n    _trx?: TrxToken\n  ): Promise<number> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n  async deleteActionBatch(_actionBatchId: number, _trx?: TrxToken): Promise<void> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n  async reserveActionBatchOutputs(_reservations: TableActionBatchOutput[], _trx?: TrxToken): Promise<void> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n\n  async findActionBatchOutputIds(_actionBatchId: number, _trx?: TrxToken): Promise<number[]> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n  async findReservedActionBatchOutputIds(_outputIds: number[], _trx?: TrxToken): Promise<number[]> {\n    return []\n  }\n  async deleteActionBatchOutputReservations(_actionBatchId: number, _trx?: TrxToken): Promise<void> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n  async putActionBatchBlobRecord(_blob: TableActionBatchBlob, _trx?: TrxToken): Promise<void> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n  async findActionBatchBlobRecord(\n    _actionBatchId: number,\n    _digest: string,\n    _trx?: TrxToken\n  ): Promise<TableActionBatchBlob | undefined> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n  async findActionBatchBlobRecords(\n    actionBatchId: number,\n    digests: string[],\n    trx?: TrxToken\n  ): Promise<TableActionBatchBlob[]> {\n    return (await Promise.all(\n      digests.map(async digest => await this.findActionBatchBlobRecord(actionBatchId, digest, trx))\n    )).filter((blob): blob is TableActionBatchBlob => blob != null)\n  }\n  async putActionBatchBlobRecords(blobs: TableActionBatchBlob[], trx?: TrxToken): Promise<void> {\n    for (const blob of blobs) await this.putActionBatchBlobRecord(blob, trx)\n  }\n\n  async deleteActionBatchBlobRecords(_actionBatchId: number, _trx?: TrxToken): Promise<void> {\n    throw new WERR_NOT_IMPLEMENTED()\n  }\n\n  async getCapabilities(): Promise<StorageCapabilities> {\n    return this.supportsActionBatchPersistence() ? getActionBatchCapabilities() : {}\n  }\n\n  protected supportsActionBatchPersistence(): boolean {\n    return false\n  }\n\n  /** Custom providers may require physical expiry cleanup before reservations are queried. */\n  protected requiresActionBatchCleanupBeforeCreateAction(): boolean {\n    return true\n  }\n\n  async beginActionBatch(auth: AuthId, args: BeginActionBatchArgs): Promise<BeginActionBatchResult> {\n    if (!this.supportsActionBatchPersistence())\n      throw new WERR_NOT_IMPLEMENTED('actionBatch capability is not available')\n    return await beginBatch(this, auth, args)\n  }\n\n  async extendActionBatch(auth: AuthId, args: ExtendActionBatchArgs): Promise<ExtendActionBatchResult> {\n    return await extendBatch(this, auth, args)\n  }\n\n  async renewActionBatch(auth: AuthId, batchId: string): Promise<RenewActionBatchResult> {\n    return await renewBatch(this, auth, batchId)\n  }\n\n  async prepareActionBatchCommit(auth: AuthId, manifest: ActionBatchManifest): Promise<PrepareActionBatchCommitResult> {\n    return await prepareBatchCommit(this, auth, manifest)\n  }\n\n  async putActionBatchBlob(auth: AuthId, args: PutActionBatchBlobArgs): Promise<void> {\n    return await putBatchBlob(this, auth, args)\n  }\n\n  async putActionBatchPack(auth: AuthId, args: PutActionBatchPackArgs): Promise<void> {\n    return await putBatchPack(this, auth, args)\n  }\n\n  async commitActionBatch(auth: AuthId, manifest: ActionBatchManifest): Promise<CommitActionBatchResult> {\n    return await commitBatch(this, auth, manifest)\n  }\n\n  async commitActionBatchByDigest(\n    auth: AuthId,\n    args: CommitActionBatchByDigestArgs\n  ): Promise<CommitActionBatchResult> {\n    return await commitBatchByDigest(this, auth, args)\n  }\n\n  async abortActionBatch(auth: AuthId, batchId: string): Promise<AbortActionBatchResult> {\n    return await abortBatch(this, auth, batchId)\n  }\n\n  async findOutputsByIds(outputIds: number[], trx?: TrxToken): Promise<Record<number, TableOutput>> {\n    const byId: Record<number, TableOutput> = {}\n    for (const outputId of outputIds) {\n      const o = verifyOneOrNone(await this.findOutputs({ partial: { outputId }, trx }))\n      if (o?.outputId !== undefined) byId[o.outputId] = o\n    }\n    return byId\n  }\n\n  async findStaleMerkleRoots(args: FindStaleMerkleRootsArgs): Promise<string[]> {\n    let provenTxs = await this.findProvenTxs({ partial: { height: args.height } })\n    provenTxs = provenTxs.filter(ptx => ptx.merkleRoot !== args.merkleRoot)\n    const roots = Array.from(new Set(provenTxs.map(ptx => ptx.merkleRoot)))\n    return roots\n  }\n\n  async findOutputsByOutpoints(\n    userId: number,\n    outpoints: Array<{ txid: string; vout: number }>,\n    trx?: TrxToken\n  ): Promise<Record<string, TableOutput>> {\n    const byOutpoint: Record<string, TableOutput> = {}\n    for (const { txid, vout } of outpoints) {\n      const o = verifyOneOrNone(await this.findOutputs({ partial: { userId, txid, vout }, trx }))\n      if (o?.txid !== undefined && o.vout !== undefined) byOutpoint[`${o.txid}.${o.vout}`] = o\n    }\n    return byOutpoint\n  }\n\n  async findOutputsByOutpointsForUpdate(\n    userId: number,\n    outpoints: Array<{ txid: string; vout: number }>,\n    trx: TrxToken,\n    _noScript = false\n  ): Promise<Record<string, TableOutput>> {\n    // Backends that cannot skip hydration remain correct; optimized backends may\n    // use _noScript to keep raw-transaction I/O outside the write lock.\n    return await this.findOutputsByOutpoints(userId, outpoints, trx)\n  }\n\n  async findOrInsertOutputBasketsBulk(\n    userId: number,\n    names: string[],\n    trx?: TrxToken\n  ): Promise<Record<string, TableOutputBasket>> {\n    const byName: Record<string, TableOutputBasket> = {}\n    for (const name of names) byName[name] = await this.findOrInsertOutputBasket(userId, name, trx)\n    return byName\n  }\n\n  async findOrInsertOutputTagsBulk(\n    userId: number,\n    tags: string[],\n    trx?: TrxToken\n  ): Promise<Record<string, TableOutputTag>> {\n    const byTag: Record<string, TableOutputTag> = {}\n    for (const tag of tags) byTag[tag] = await this.findOrInsertOutputTag(userId, tag, trx)\n    return byTag\n  }\n\n  async findOrInsertTxLabelsBulk(\n    userId: number,\n    labels: string[],\n    trx?: TrxToken\n  ): Promise<Record<string, TableTxLabel>> {\n    const byLabel: Record<string, TableTxLabel> = {}\n    for (const label of labels) byLabel[label] ??= await this.findOrInsertTxLabel(userId, label, trx)\n    return byLabel\n  }\n\n  async sumSpendableSatoshisInBasket(\n    userId: number,\n    basketId: number,\n    excludeSending: boolean,\n    trx?: TrxToken\n  ): Promise<number> {\n    const status: TransactionStatus[] = ['completed', 'unproven']\n    if (!excludeSending) status.push('sending')\n    const rows = await this.findOutputs({\n      partial: { userId, spendable: true, basketId },\n      txStatus: status,\n      noScript: true,\n      trx\n    })\n    return rows.filter(r => r.spentBy == null).reduce((a, r) => a + (r.satoshis ?? 0), 0)\n  }\n\n  abstract findCertificatesAuth(auth: AuthId, args: FindCertificatesArgs): Promise<TableCertificateX[]>\n  abstract findOutputBasketsAuth(auth: AuthId, args: FindOutputBasketsArgs): Promise<TableOutputBasket[]>\n  abstract findOutputsAuth(auth: AuthId, args: FindOutputsArgs): Promise<TableOutput[]>\n  abstract insertCertificateAuth(auth: AuthId, certificate: TableCertificateX): Promise<number>\n\n  abstract adminStats(adminIdentityKey: string): Promise<AdminStatsResult>\n\n  async recentlyActiveUsers(limit = 50, trx?: TrxToken): Promise<TableUser[]> {\n    const outputs = await this.findOutputs({\n      partial: {},\n      noScript: true,\n      trx\n    })\n\n    const latestByUserId = new Map<number, Date>()\n    for (const output of outputs) {\n      if (output.userId === undefined) continue\n      const createdAt = this.validateDate(output.created_at)\n      const prior = latestByUserId.get(output.userId)\n      if (prior == null || createdAt > prior) {\n        latestByUserId.set(output.userId, createdAt)\n      }\n    }\n\n    const sortedUserIds = Array.from(latestByUserId.entries())\n      .sort((a, b) => b[1].getTime() - a[1].getTime())\n      .slice(0, limit)\n      .map(([userId]) => userId)\n\n    const users = await Promise.all(sortedUserIds.map(async userId => await this.findUserById(userId, trx)))\n    return users.filter((user): user is TableUser => user != null)\n  }\n\n  override isStorageProvider(): boolean {\n    return true\n  }\n\n  setServices(v: WalletServices): void {\n    this._services = v\n  }\n\n  getServices(): WalletServices {\n    if (this._services == null) throw new WERR_INVALID_OPERATION('Must setServices first.')\n    return this._services\n  }\n\n  private async findAbortableTransaction(\n    userId: number,\n    args: AbortActionArgs,\n    trx: TrxToken\n  ): Promise<{ tx: TableTransaction; reference: string | undefined }> {\n    let reference: string | undefined = args.reference\n    let tx = verifyOneOrNone(\n      await this.findTransactions({\n        partial: { reference, userId },\n        noRawTx: true,\n        trx\n      })\n    )\n    if (tx == null && args.reference.length === 64) {\n      reference = undefined\n      tx = verifyOneOrNone(\n        await this.findTransactions({\n          partial: { txid: args.reference, userId },\n          noRawTx: true,\n          trx\n        })\n      )\n    }\n    const unAbortableStatus: TransactionStatus[] = ['completed', 'failed', 'sending', 'unproven']\n    if (tx == null || !tx.isOutgoing || unAbortableStatus.includes(tx.status)) {\n      throw new WERR_INVALID_PARAMETER(\n        'reference',\n        'an inprocess, outgoing action that has not been signed and shared to the network.'\n      )\n    }\n    return { tx, reference }\n  }\n\n  private async checkAbortChainProtection(\n    tx: TableTransaction,\n    args: AbortActionArgs,\n    trx: TrxToken\n  ): Promise<{ skipped: boolean; serviceUnreachable: boolean }> {\n    if (tx.txid == null || tx.txid === '' || tx.status !== 'nosend') {\n      return { skipped: false, serviceUnreachable: false }\n    }\n\n    let serviceUnreachable = false\n    let chainStatus: 'mined' | 'known' | 'unknown' | undefined\n    try {\n      const result = await this.getServices().getStatusForTxids([tx.txid])\n      if (result.status !== 'success') {\n        serviceUnreachable = true\n      } else {\n        chainStatus = result.results.find(item => item.txid === tx.txid)?.status\n      }\n    } catch {\n      serviceUnreachable = true\n    }\n    if (chainStatus !== 'mined' && chainStatus !== 'known') {\n      return { skipped: false, serviceUnreachable }\n    }\n\n    const req = await EntityProvenTxReq.fromStorageTxid(this, tx.txid, trx)\n    if (req != null) {\n      req.addHistoryNote({\n        what: 'abortAction-skipped-onchain',\n        reference: args.reference,\n        chainStatus\n      })\n      await req.updateStorageDynamicProperties(this, trx)\n    }\n    return { skipped: true, serviceUnreachable }\n  }\n\n  private async invalidateAbortedTransaction(\n    tx: TableTransaction,\n    userId: number,\n    reference: string | undefined,\n    originalReference: string,\n    serviceUnreachable: boolean,\n    trx: TrxToken\n  ): Promise<AbortActionResult> {\n    await this.updateTransactionStatus('failed', tx.transactionId, userId, reference, trx)\n    if (tx.txid != null && tx.txid !== '') {\n      const req = await EntityProvenTxReq.fromStorageTxid(this, tx.txid, trx)\n      if (req != null) {\n        req.addHistoryNote(\n          serviceUnreachable\n            ? { what: 'abortAction-offline-fallback', reference: originalReference }\n            : { what: 'abortAction', reference: originalReference }\n        )\n        req.status = 'invalid'\n        await req.updateStorageDynamicProperties(this, trx)\n      }\n    }\n    return { aborted: true }\n  }\n\n  async abortAction(auth: AuthId, args: AbortActionArgs): Promise<AbortActionResult> {\n    if (auth.userId == null) throw new WERR_INVALID_PARAMETER('auth.userId', 'valid')\n\n    const userId = auth.userId\n    const r = await this.transaction(async trx => {\n      const { tx, reference } = await this.findAbortableTransaction(userId, args, trx)\n      // Chain-status protection for signed nosend txs.\n      //\n      // Background: a nosend tx (created via createAction({noSend:true}))\n      // can be externally broadcast by the caller and reach 'mined' or\n      // mempool-'known' status before any internalizeAction or Monitor\n      // cycle has retired its 'nosend' status in storage. If abortAction\n      // is invoked on it in that window, the destructive transitions\n      // below (transactions.status='failed' + proven_tx_reqs.status='invalid')\n      // orphan every output the tx produced — including auto-fund change\n      // outputs the wallet itself emitted — because listOutputs filters\n      // them out of the spendable set on parent-tx 'failed' status.\n      //\n      // Protection: if the tx has a txid AND status is 'nosend', ask\n      // the network whether it already knows about the tx before\n      // invalidating. getStatusForTxids returns 'mined' | 'known' |\n      // 'unknown' per StatusForTxidResult (WalletServices.interfaces.ts).\n      // Refuse the abort for 'mined' OR 'known' — a tx that's broadcast\n      // and propagating in mempool returns 'known' (depth===0) and\n      // protecting it avoids orphaning during the propagation window.\n      //\n      // Service-unreachable handling: proceed with abort. Refusal is\n      // reserved for positive on-chain confirmation. When the network\n      // confirmation pathway is itself unavailable (services throw or\n      // gracefully return r.status !== 'success'), confirmation is not\n      // possible — and per the BRC-100 contract callers retain the\n      // ability to abort offline. The fallback writes a forensic\n      // history note ('abortAction-offline-fallback') so an operator\n      // can grep for aborts that proceeded under uncertainty. This\n      // hole can never be 100% closed against externally-broadcast\n      // chain-confirmed txs while offline; the audit trail makes it\n      // recoverable.\n      const protection = await this.checkAbortChainProtection(tx, args, trx)\n      if (protection.skipped) {\n        // Commit the audit note before translating this sentinel to aborted:false.\n        return { __abortAction: 'skipped-onchain' as const }\n      }\n      return await this.invalidateAbortedTransaction(\n        tx,\n        userId,\n        reference,\n        args.reference,\n        protection.serviceUnreachable,\n        trx\n      )\n    })\n    if ('__abortAction' in r) {\n      // Tone Engel review feedback (PR #122 comment 4444566147 item 3):\n      // do not throw on chain-confirmed refusal — surface it via the\n      // return value so callers can branch on it. Refusal is positive\n      // chain confirmation only; service-unreachable proceeds with\n      // abort and returns aborted:true with an audit-trail note.\n      return { aborted: false }\n    }\n    return r\n  }\n\n  async internalizeAction(auth: AuthId, args: InternalizeActionArgs): Promise<StorageInternalizeActionResult> {\n    return await internalizeAction(this, auth, args)\n  }\n\n  /**\n   * Given an array of transaction txids with current ProvenTxReq ready-to-share status,\n   * lookup their ProvenTxReqApi req records.\n   * For the txids with reqs and status still ready to send construct a single merged beef.\n   *\n   * @param txids\n   * @param knownTxids\n   * @param trx\n   */\n  async getReqsAndBeefToShareWithWorld(\n    txids: string[],\n    knownTxids: string[],\n    trx?: TrxToken\n  ): Promise<GetReqsAndBeefResult> {\n    const r: GetReqsAndBeefResult = {\n      beef: new Beef(),\n      details: []\n    }\n\n    for (const txid of txids) {\n      const d: GetReqsAndBeefDetail = {\n        txid,\n        // status: 'readyToSend' | 'alreadySent' | 'error' | 'unknown'\n        status: 'unknown'\n        // req?: TableProvenTxReq\n        // proven?: TableProvenTx\n        // error?: string\n      }\n      r.details.push(d)\n      try {\n        d.proven = verifyOneOrNone(await this.findProvenTxs({ partial: { txid }, trx }))\n        if (d.proven != null) {\n          d.status = 'alreadySent'\n          continue\n        }\n\n        d.req = verifyOneOrNone(await this.findProvenTxReqs({ partial: { txid }, trx }))\n        if (d.req == null) {\n          d.status = 'error'\n          d.error = `ERR_UNKNOWN_TXID: ${txid} was not found.`\n        } else {\n          classifyReqStatus(d, d.req)\n        }\n\n        if (d.status === 'readyToSend') {\n          await this.mergeReqToBeefToShareExternally(d.req as TableProvenTxReq, r.beef, knownTxids, trx)\n        }\n      } catch (error_: unknown) {\n        const e = WalletError.fromUnknown(error_)\n        d.error = `${e.name}: ${e.message}`\n      }\n    }\n    return r\n  }\n\n  async mergeReqToBeefToShareExternally(\n    req: TableProvenTxReq,\n    mergeToBeef: Beef,\n    knownTxids: string[],\n    trx?: TrxToken\n  ): Promise<void> {\n    const { rawTx, inputBEEF: beef } = req\n    if (rawTx == null || beef == null) throw new WERR_INTERNAL('req rawTx and beef must be valid.')\n    mergeToBeef.mergeRawTx(asArray(rawTx))\n    mergeToBeef.mergeBeef(asArray(beef))\n    await mergeInputsIntoBeef(\n      asArray(rawTx),\n      mergeToBeef,\n      knownTxids,\n      trx,\n      async (txid, beef, _trust, knownTxids, trx) => {\n        await this.getValidBeefForKnownTxid(txid, beef, undefined, knownTxids, trx)\n      }\n    )\n  }\n\n  /**\n   * Checks if txid is a known valid ProvenTx and returns it if found.\n   * Next checks if txid is a current ProvenTxReq and returns that if found.\n   * If `newReq` is provided and an existing ProvenTxReq isn't found,\n   * use `newReq` to create a new ProvenTxReq.\n   *\n   * This is safe \"findOrInsert\" operation using retry if unique index constraint\n   * is violated by a race condition insert.\n   *\n   * @param txid\n   * @param newReq\n   * @param trx\n   * @returns\n   */\n  private async upsertProvenTxReq(\n    txid: string,\n    newReq: TableProvenTxReq | undefined,\n    trx: TrxToken | undefined\n  ): Promise<TableProvenTxReq | undefined> {\n    const existing = verifyOneOrNone(await this.findProvenTxReqs({ partial: { txid }, trx }))\n    if (existing == null && newReq == null) return undefined\n    if (existing == null) {\n      await this.insertProvenTxReq(newReq as TableProvenTxReq, trx)\n      return newReq\n    }\n    if (newReq != null) {\n      const req1 = new EntityProvenTxReq(existing)\n      req1.mergeHistory(newReq, undefined, true)\n      req1.mergeNotifyTransactionIds(newReq)\n      await req1.updateStorageDynamicProperties(this, trx)\n    }\n    return existing\n  }\n\n  async getProvenOrReq(txid: string, newReq?: TableProvenTxReq, trx?: TrxToken): Promise<StorageProvenOrReq> {\n    if (newReq != null && txid !== newReq.txid) throw new WERR_INVALID_PARAMETER('newReq', 'same txid')\n\n    const r: StorageProvenOrReq = { proven: undefined, req: undefined }\n\n    r.proven = verifyOneOrNone(await this.findProvenTxs({ partial: { txid }, trx }))\n    if (r.proven != null) return r\n\n    for (let retry = 0; ; retry++) {\n      try {\n        r.req = await this.upsertProvenTxReq(txid, newReq, trx)\n        break\n      } catch (error_: unknown) {\n        if (retry > 0) throw error_\n      }\n    }\n\n    return r\n  }\n\n  async updateTransactionsStatus(transactionIds: number[], status: TransactionStatus, trx?: TrxToken): Promise<void> {\n    await this.transaction(async trx => {\n      for (const id of transactionIds) {\n        await this.updateTransactionStatus(status, id, undefined, undefined, trx)\n      }\n    }, trx)\n  }\n\n  private async releaseInputsAllocatedToFailedTransaction(tx: TableTransaction, trx?: TrxToken): Promise<void> {\n    const t = new EntityTransaction(tx)\n    const inputs = await t.getInputs(this, trx)\n    for (const input of inputs) {\n      // input is a prior output belonging to userId that references this transaction either by `spentBy`\n      // or by txid and vout.\n      await this.updateOutput(verifyId(input.outputId), { spendable: true, spentBy: undefined }, trx)\n    }\n  }\n\n  private async markFailedTransactionOutputsNotSpendable(tx: TableTransaction, trx?: TrxToken): Promise<void> {\n    const outputs = await this.findOutputs({\n      partial: { transactionId: verifyId(tx.transactionId) },\n      trx\n    })\n    for (const output of outputs) {\n      if (!output.spendable && output.spentBy == null) continue\n      await this.updateOutput(verifyId(output.outputId), { spendable: false, spentBy: undefined }, trx)\n    }\n  }\n\n  /**\n   * For all `status` values besides 'failed', just updates the transaction records status property.\n   *\n   * For 'status' of 'failed', attempts to make outputs previously allocated as inputs to this transaction usable again\n   * and makes outputs generated by this transaction non-spendable.\n   *\n   * @param status\n   * @param transactionId\n   * @param userId\n   * @param reference\n   * @param trx\n   */\n  async updateTransactionStatus(\n    status: TransactionStatus,\n    transactionId?: number,\n    userId?: number,\n    reference?: string,\n    trx?: TrxToken\n  ): Promise<void> {\n    if (transactionId == null && !(userId != null && reference != null && reference !== '')) {\n      throw new WERR_MISSING_PARAMETER('either transactionId or userId and reference')\n    }\n\n    await this.transaction(async trx => {\n      const where: Partial<TableTransaction> = {}\n      if (transactionId != null) where.transactionId = transactionId\n      if (userId != null) where.userId = userId\n      if (reference != null && reference !== '') where.reference = reference\n\n      const tx = verifyOne(await this.findTransactions({ partial: where, noRawTx: true, trx }))\n\n      // if (tx.status === status)\n      // no change required. Assume inputs and outputs spendable and spentBy are valid for status.\n      // return\n\n      // Once completed, this method cannot be used to \"uncomplete\" transaction.\n      if ((status !== 'completed' && tx.status === 'completed') || tx.provenTxId != null) {\n        throw new WERR_INVALID_OPERATION('The status of a \"completed\" transaction cannot be changed.')\n      }\n      // It is not possible to un-fail a transaction. Information is lost and not recoverable.\n      if (status !== 'failed' && tx.status === 'failed') {\n        throw new WERR_INVALID_OPERATION('A \"failed\" transaction may not be un-failed by this method.')\n      }\n\n      switch (status) {\n        case 'failed':\n          await this.releaseInputsAllocatedToFailedTransaction(tx, trx)\n          await this.markFailedTransactionOutputsNotSpendable(tx, trx)\n          break\n        case 'nosend':\n        case 'unsigned':\n        case 'unprocessed':\n        case 'sending':\n        case 'unproven':\n        case 'completed':\n          break\n        default:\n          throw new WERR_INVALID_PARAMETER('status', `not be ${status}`)\n      }\n\n      await this.updateTransaction(tx.transactionId, { status }, trx)\n    }, trx)\n  }\n\n  async createAction(auth: AuthId, args: Validation.ValidCreateActionArgs): Promise<StorageCreateActionResult> {\n    if (auth.userId == null) throw new WERR_UNAUTHORIZED()\n    if (this.supportsActionBatchPersistence() && this.requiresActionBatchCleanupBeforeCreateAction()) {\n      await cleanupExpiredActionBatches(this)\n    }\n    return await createAction(this, auth, args)\n  }\n\n  async processAction(auth: AuthId, args: StorageProcessActionArgs): Promise<StorageProcessActionResults> {\n    if (auth.userId == null) throw new WERR_UNAUTHORIZED()\n    return await processAction(this, auth, args)\n  }\n\n  async attemptToPostReqsToNetwork(\n    reqs: EntityProvenTxReq[],\n    trx?: TrxToken,\n    logger?: WalletLoggerInterface\n  ): Promise<PostReqsToNetworkResult> {\n    return await attemptToPostReqsToNetwork(this, reqs, trx, logger)\n  }\n\n  async listCertificates(auth: AuthId, args: Validation.ValidListCertificatesArgs): Promise<ListCertificatesResult> {\n    return await listCertificates(this, auth, args)\n  }\n\n  async verifyKnownValidTransaction(txid: string, trx?: TrxToken): Promise<boolean> {\n    const { proven, rawTx } = await this.getProvenOrRawTx(txid, trx)\n    return proven !== undefined || rawTx !== undefined\n  }\n\n  /**\n   * Pulls data from storage to build a valid beef for a txid.\n   *\n   * Optionally merges the data into an existing beef.\n   * Optionally requires a minimum number of proof levels.\n   *\n   * @param txid\n   * @param mergeToBeef\n   * @param trustSelf\n   * @param knownTxids\n   * @param trx\n   * @param requiredLevels\n   * @returns\n   */\n  async getValidBeefForKnownTxid(\n    txid: string,\n    mergeToBeef?: Beef,\n    trustSelf?: TrustSelf,\n    knownTxids?: string[],\n    trx?: TrxToken,\n    requiredLevels?: number\n  ): Promise<Beef> {\n    const beef = await this.getValidBeefForTxid(txid, mergeToBeef, trustSelf, knownTxids, trx, requiredLevels)\n    if (beef == null) throw new WERR_INVALID_PARAMETER('txid', `known to storage. ${txid} is not known.`)\n    return beef\n  }\n\n  /**\n   * Handles the proven-tx branch of getValidBeefForTxid.\n   *\n   * Returns the beef if the proof was merged and we can stop, or `undefined` to\n   * signal that the caller should fall through to the rawTx path.  May also\n   * populate `r.rawTx` so the rawTx path can proceed without re-fetching.\n   */\n  private async handleProvenTxBranch(\n    txid: string,\n    r: ProvenOrRawTx,\n    beef: Beef,\n    trustSelf: TrustSelf | undefined,\n    requiredLevels: number | undefined,\n    chainTracker: ChainTracker | undefined,\n    skipInvalidProofs: boolean | undefined\n  ): Promise<Beef | undefined> {\n    const proven = r.proven\n    if (proven == null) return undefined\n    if ((requiredLevels ?? 0) > 0) {\n      // Need more levels — caller should proceed via rawTx path\n      r.rawTx = proven.rawTx\n      return undefined\n    }\n    if (trustSelf === 'known') {\n      beef.mergeTxidOnly(txid)\n      return beef\n    }\n    const mp = new EntityProvenTx(proven).getMerklePath()\n    if (chainTracker != null) {\n      const root = mp.computeRoot()\n      const isValid = await chainTracker.isValidRootForHeight(root, proven.height)\n      if (!isValid) {\n        if (skipInvalidProofs !== true) throw new WERR_INVALID_MERKLE_ROOT(proven.blockHash, proven.height, root, txid)\n        // Proof is currently invalid — recurse deeper via rawTx path\n        r.rawTx = proven.rawTx\n        r.proven = undefined\n        return undefined\n      }\n    }\n    // Proof is good — merge and return\n    beef.mergeRawTx(proven.rawTx)\n    beef.mergeBump(mp)\n    return beef\n  }\n\n  async getValidBeefForTxid(\n    ...[\n      txid,\n      mergeToBeef,\n      trustSelf,\n      knownTxids,\n      trx,\n      requiredLevels,\n      chainTracker,\n      skipInvalidProofs\n    ]: [\n      txid: string,\n      mergeToBeef?: Beef,\n      trustSelf?: TrustSelf,\n      knownTxids?: string[],\n      trx?: TrxToken,\n      requiredLevels?: number,\n      chainTracker?: ChainTracker,\n      skipInvalidProofs?: boolean\n    ]\n  ): Promise<Beef | undefined> {\n    const beef = mergeToBeef ?? new Beef()\n    const r = await this.getProvenOrRawTx(txid, trx)\n\n    // --- proven-tx path ---\n    if (r.proven != null) {\n      const result = await this.handleProvenTxBranch(\n        txid,\n        r,\n        beef,\n        trustSelf,\n        requiredLevels,\n        chainTracker,\n        skipInvalidProofs\n      )\n      if (result != null || r.rawTx == null) return result\n    }\n\n    // --- rawTx path ---\n    if (r.rawTx == null) return undefined\n\n    if (trustSelf === 'known') {\n      beef.mergeTxidOnly(txid)\n    } else {\n      beef.mergeRawTx(r.rawTx)\n      if (r.inputBEEF != null) beef.mergeBeef(r.inputBEEF)\n      if ((requiredLevels ?? 0) > 0) requiredLevels = (requiredLevels as number) - 1\n      await mergeInputBeefs(\n        r.rawTx,\n        beef,\n        trustSelf,\n        knownTxids,\n        trx,\n        requiredLevels,\n        async (sourceTXID, beef, trustSelf, knownTxids, trx, requiredLevels) => {\n          await this.getValidBeefForKnownTxid(sourceTXID, beef, trustSelf, knownTxids, trx, requiredLevels)\n        }\n      )\n    }\n    return beef\n  }\n\n  async getBeefForTransaction(txid: string, options: StorageGetBeefOptions): Promise<Beef> {\n    const beef = await getBeefForTransaction(this, txid, options)\n    return beef\n  }\n\n  async getBeefForTransactions(txids: string[], options: StorageGetBeefOptions): Promise<Beef> {\n    return await getBeefForTransactions(this, txids, options)\n  }\n\n  async findMonitorEventById(id: number, trx?: TrxToken): Promise<TableMonitorEvent | undefined> {\n    return verifyOneOrNone(await this.findMonitorEvents({ partial: { id }, trx }))\n  }\n\n  async relinquishCertificate(auth: AuthId, args: RelinquishCertificateArgs): Promise<number> {\n    const vargs = Validation.validateRelinquishCertificateArgs(args)\n    const cert = verifyOne(\n      await this.findCertificates({\n        partial: {\n          certifier: vargs.certifier,\n          serialNumber: vargs.serialNumber,\n          type: vargs.type\n        }\n      })\n    )\n    return await this.updateCertificate(cert.certificateId, {\n      isDeleted: true\n    })\n  }\n\n  async relinquishOutput(auth: AuthId, args: RelinquishOutputArgs): Promise<number> {\n    const vargs = Validation.validateRelinquishOutputArgs(args)\n    const { txid, vout } = Validation.parseWalletOutpoint(vargs.output)\n    const output = verifyOne(await this.findOutputs({ partial: { userId: auth.userId, txid, vout } }))\n    return await this.updateOutput(output.outputId, { basketId: undefined })\n  }\n\n  async processSyncChunk(args: RequestSyncChunkArgs, chunk: SyncChunk): Promise<ProcessSyncChunkResult> {\n    const user = verifyTruthy(await this.findUserByIdentityKey(args.identityKey))\n    const ss = new EntitySyncState(\n      verifyOne(\n        await this.findSyncStates({\n          partial: {\n            storageIdentityKey: args.fromStorageIdentityKey,\n            userId: user.userId\n          }\n        })\n      )\n    )\n    const r = await ss.processSyncChunk(this, args, chunk)\n    return r\n  }\n\n  /**\n   * Handles storage changes when a valid MerklePath and mined block header are found for a ProvenTxReq txid.\n   *\n   * Performs the following storage updates (typically):\n   * 1. Lookup the exising `ProvenTxReq` record for its rawTx\n   * 2. Insert a new ProvenTx record using properties from `args` and rawTx, yielding a new provenTxId\n   * 3. Update ProvenTxReq record with status 'completed' and new provenTxId value (and history of status changed)\n   * 4. Unpack notify transactionIds from req and update each transaction's status to 'completed', provenTxId value.\n   * 5. Update ProvenTxReq history again to record that transactions have been notified.\n   * 6. Return results...\n   *\n   * Alterations of \"typically\" to handle:\n   */\n  async updateProvenTxReqWithNewProvenTx(\n    args: UpdateProvenTxReqWithNewProvenTxArgs\n  ): Promise<UpdateProvenTxReqWithNewProvenTxResult> {\n    const req = await EntityProvenTxReq.fromStorageId(this, args.provenTxReqId)\n    let proven: EntityProvenTx\n    if (req.provenTxId != null && req.provenTxId > 0) {\n      // Someone beat us to it, grab what we need for results...\n      proven = new EntityProvenTx(verifyOne(await this.findProvenTxs({ partial: { txid: args.txid } })))\n      if (req.status !== 'completed' || req.provenTxId !== proven.provenTxId) {\n        req.status = 'completed'\n        req.provenTxId = proven.provenTxId\n        await req.updateStorageDynamicProperties(this)\n      }\n    } else {\n      proven = await this.transaction(async trx => {\n        const { proven: api } = await this.findOrInsertProvenTx(\n          {\n            created_at: new Date(),\n            updated_at: new Date(),\n            provenTxId: 0,\n            txid: args.txid,\n            height: args.height,\n            index: args.index,\n            merklePath: args.merklePath,\n            rawTx: req.rawTx,\n            blockHash: args.blockHash,\n            merkleRoot: args.merkleRoot\n          },\n          trx\n        )\n        const found = new EntityProvenTx(api)\n        if (req.status !== 'completed' || req.provenTxId !== found.provenTxId) {\n          req.status = 'completed'\n          req.provenTxId = found.provenTxId\n          await req.updateStorageDynamicProperties(this, trx)\n        }\n        return found\n      })\n    }\n\n    await this.reconcileProvenTxReqTransactions(req, proven)\n\n    const r: UpdateProvenTxReqWithNewProvenTxResult = {\n      status: req.status,\n      history: req.apiHistory,\n      provenTxId: proven.provenTxId,\n      notified: req.notified,\n      notify: req.apiNotify\n    }\n    return r\n  }\n\n  /**\n   * Reconcile completed proof requests whose transaction fan-out previously\n   * failed or whose durable notification state drifted.\n   *\n   * This is called by TaskReviewStatus so a completed request with\n   * `notified = false` is retried and can become eligible for normal purge.\n   */\n  async reconcileCompletedProvenTxReqs(): Promise<{ log: string }> {\n    let log = ''\n    const reqs = await this.findProvenTxReqs({\n      partial: { status: 'completed', notified: false }\n    })\n\n    for (const reqApi of reqs) {\n      const req = new EntityProvenTxReq(reqApi)\n      if (req.provenTxId == null || req.provenTxId <= 0) {\n        log += `completed req ${req.id} cannot reconcile without provenTxId\\n`\n        continue\n      }\n\n      const provenApi = verifyOneOrNone(\n        await this.findProvenTxs({\n          partial: { provenTxId: req.provenTxId }\n        })\n      )\n      if (provenApi == null) {\n        log += `completed req ${req.id} cannot reconcile missing provenTx ${req.provenTxId}\\n`\n        continue\n      }\n\n      await this.reconcileProvenTxReqTransactions(req, new EntityProvenTx(provenApi))\n      if (req.notified) log += `completed req ${req.id} transaction notifications reconciled\\n`\n    }\n\n    return { log }\n  }\n\n  private async prepareProofRecoveryOutputVerdicts(\n    transactions: TableTransaction[]\n  ): Promise<Map<number, boolean | undefined>> {\n    const verdicts = new Map<number, boolean | undefined>()\n    if (transactions.length === 0) return verdicts\n    const services = this.getServices()\n    for (const transaction of transactions) {\n      const outputs = await this.findOutputs({\n        partial: {\n          userId: transaction.userId,\n          transactionId: transaction.transactionId\n        }\n      })\n      for (const output of outputs) {\n        const outputId = verifyId(output.outputId)\n        await this.validateOutputScript(output)\n        verdicts.set(\n          outputId,\n          output.lockingScript == null ? undefined : await services.isUtxo(output)\n        )\n      }\n    }\n    return verdicts\n  }\n\n  private async restoreProofRecoveryInputs(\n    tx: TableTransaction,\n    bsvtx: Transaction,\n    indent: number,\n    trx: TrxToken\n  ): Promise<string> {\n    let log = ''\n    for (const [vin, input] of bsvtx.inputs.entries()) {\n      const sourceTXID = input.sourceTXID\n      if (sourceTXID == null) {\n        log += ' '.repeat(indent + 2) + `input ${vin} has no source transaction id\\n`\n        continue\n      }\n      const outputs = await this.findOutputs({\n        partial: {\n          userId: tx.userId,\n          txid: sourceTXID,\n          vout: input.sourceOutputIndex\n        },\n        trx\n      })\n      if (outputs.length !== 1) {\n        log += ' '.repeat(indent + 2) + `input ${vin} not matched to user's outputs\\n`\n        continue\n      }\n      const output = outputs[0]\n      log +=\n        ' '.repeat(indent + 2) +\n        `input ${vin} matched to output ${output.outputId} updated spentBy ${tx.transactionId}\\n`\n      await this.updateOutput(\n        verifyId(output.outputId),\n        { spendable: false, spentBy: tx.transactionId },\n        trx\n      )\n    }\n    return log\n  }\n\n  private async restoreProofRecoveryOutputs(\n    tx: TableTransaction,\n    outputVerdicts: Map<number, boolean | undefined>,\n    indent: number,\n    trx: TrxToken\n  ): Promise<string> {\n    let log = ''\n    const outputs = await this.findOutputs({\n      partial: { userId: tx.userId, transactionId: tx.transactionId },\n      trx\n    })\n    for (const output of outputs) {\n      const outputId = verifyId(output.outputId)\n      if (!outputVerdicts.has(outputId)) {\n        throw new WERR_INTERNAL(\n          `Output ${outputId} changed while preparing proof recovery.`\n        )\n      }\n      const isUtxo = outputVerdicts.get(outputId)\n      if (isUtxo == null) {\n        log +=\n          ' '.repeat(indent + 2) +\n          `output ${output.outputId} does not have a valid locking script\\n`\n        continue\n      }\n      if (isUtxo === output.spendable) {\n        log += ' '.repeat(indent + 2) + `output ${output.outputId} unchanged\\n`\n        continue\n      }\n      log +=\n        ' '.repeat(indent + 2) +\n        `output ${output.outputId} set to ${isUtxo ? 'spendable' : 'spent'}\\n`\n      await this.updateOutput(outputId, { spendable: isUtxo }, trx)\n    }\n    return log\n  }\n\n  private async restoreTransactionForProof(\n    tx: TableTransaction,\n    bsvtx: Transaction | undefined,\n    preparedTransactionIds: Set<number>,\n    outputVerdicts: Map<number, boolean | undefined>,\n    indent: number,\n    trx: TrxToken\n  ): Promise<string> {\n    if (bsvtx == null || !preparedTransactionIds.has(tx.transactionId)) {\n      throw new WERR_INTERNAL(\n        `Transaction ${tx.transactionId} changed while preparing proof recovery.`\n      )\n    }\n    await this.updateTransaction(tx.transactionId, { status: 'unproven' }, trx)\n    let log =\n      ' '.repeat(indent) +\n      `transaction ${tx.transactionId} status is now 'unproven'\\n`\n    log += await this.restoreProofRecoveryInputs(tx, bsvtx, indent, trx)\n    log += await this.restoreProofRecoveryOutputs(tx, outputVerdicts, indent, trx)\n    return log\n  }\n\n  /**\n   * Restore every failed local copy of a transaction before proof completion.\n   * Also heals the request's notification set from the authoritative txid\n   * lookup so TaskUnFail cannot omit a local copy after notification drift.\n   */\n  async unfailTransactionsForProof(\n    req: EntityProvenTxReq,\n    indent = 0,\n    requestUpdate?: Pick<TableProvenTxReqDynamics, 'status' | 'attempts'>\n  ): Promise<string> {\n    const transactions = await this.findTransactions({\n      partial: { txid: req.txid },\n      noRawTx: true\n    })\n    const transactionsToRepair = transactions.filter(\n      transaction => requestUpdate != null || transaction.status === 'failed'\n    )\n    // Proof completion is the hot path. If no failed transaction needs repair,\n    // notification reconciliation below will perform the required atomic work;\n    // avoid an otherwise empty refresh/write transaction here.\n    if (transactionsToRepair.length === 0 && requestUpdate == null) return ''\n\n    // Refresh only after deciding recovery is required, while the caller has\n    // not yet applied an intended request transition. TaskUnFail passes that\n    // transition separately so it is persisted atomically with bookkeeping.\n    await req.refreshFromStorage(this)\n    const preparedTransactionIds = new Set(transactionsToRepair.map(transaction => transaction.transactionId))\n    const bsvtx = transactionsToRepair.length > 0 ? Transaction.fromBinary(req.rawTx) : undefined\n\n    // UTXO checks can call external services. Complete every check before\n    // opening the write transaction so network latency never holds DB locks.\n    const outputVerdicts =\n      await this.prepareProofRecoveryOutputVerdicts(transactionsToRepair)\n\n    return await this.transaction(async trx => {\n      let log = ''\n      await req.refreshFromStorage(this, trx)\n      const currentTransactions = await this.findTransactions({\n        partial: { txid: req.txid },\n        noRawTx: true,\n        trx\n      })\n      const knownNotificationIds = new Set(req.notify.transactionIds ?? [])\n\n      if (requestUpdate != null) {\n        req.status = requestUpdate.status\n        req.attempts = requestUpdate.attempts\n      }\n\n      for (const tx of currentTransactions) {\n        if (!knownNotificationIds.has(tx.transactionId)) {\n          req.addNotifyTransactionId(tx.transactionId)\n          knownNotificationIds.add(tx.transactionId)\n        }\n        const shouldRepair = requestUpdate != null || tx.status === 'failed'\n        if (!shouldRepair) continue\n        log += await this.restoreTransactionForProof(\n          tx,\n          bsvtx,\n          preparedTransactionIds,\n          outputVerdicts,\n          indent,\n          trx\n        )\n      }\n\n      await req.updateStorageDynamicProperties(this, trx)\n      return log\n    })\n  }\n\n  private async reconcileProvenTxReqTransactions(req: EntityProvenTxReq, proven: EntityProvenTx): Promise<void> {\n    // A transaction can be internalized concurrently by several users. Their\n    // transaction rows share a txid but race while merging the JSON notify\n    // list, so a last-writer-wins update can omit one local copy. A valid proof\n    // is authoritative for every local transaction with this txid: discover\n    // them from the indexed transaction table and atomically heal both the\n    // durable notify set and any row that missed the original completion.\n    // Keep the clean proof-completion path identical to the normal notification\n    // transaction. Only leave it when failed rows require external UTXO checks,\n    // which must run without an open transaction.\n    let repairAttempts = 0\n    for (;;) {\n      const needsRepair = await this.transaction(async trx => {\n        await req.refreshFromStorage(this, trx)\n        const transactions = await this.findTransactions({ partial: { txid: req.txid }, trx })\n        if (transactions.some(transaction => transaction.status === 'failed')) return true\n\n        const knownNotificationIds = new Set(req.notify.transactionIds ?? [])\n        for (const transaction of transactions) {\n          if (!knownNotificationIds.has(transaction.transactionId)) {\n            req.addNotifyTransactionId(transaction.transactionId)\n            knownNotificationIds.add(transaction.transactionId)\n          }\n        }\n        const transactionIdsNeedingProof = transactions\n          .filter(transaction => transaction.status !== 'completed' || transaction.provenTxId !== proven.provenTxId)\n          .map(transaction => transaction.transactionId)\n        const updatesSucceeded = await notifyTransactionsOfProof(\n          transactionIdsNeedingProof,\n          proven.provenTxId,\n          note => req.addHistoryNote(note),\n          async (id, update) => {\n            await this.updateTransaction(id, update, trx)\n          }\n        )\n        const completedTransactions = await this.findTransactions({ partial: { txid: req.txid }, trx })\n        req.notified =\n          updatesSucceeded &&\n          completedTransactions.every(\n            transaction => transaction.status === 'completed' && transaction.provenTxId === proven.provenTxId\n          )\n        await req.updateStorageDynamicProperties(this, trx)\n        return false\n      })\n\n      if (!needsRepair) return\n      if (repairAttempts >= 2) {\n        throw new WERR_INTERNAL(`Transactions for ${req.txid} repeatedly changed to failed during proof recovery.`)\n      }\n      repairAttempts++\n      await this.unfailTransactionsForProof(req)\n    }\n  }\n\n  /**\n   * For each spendable output in the 'default' basket of the authenticated user,\n   * verify that the output script, satoshis, vout and txid match that of an output\n   * still in the mempool of at least one service provider.\n   *\n   * @returns object with invalidSpendableOutputs array. A good result is an empty array.\n   */\n  async confirmSpendableOutputs(): Promise<{\n    invalidSpendableOutputs: TableOutput[]\n  }> {\n    const invalidSpendableOutputs: TableOutput[] = []\n    const users = await this.findUsers({ partial: {} })\n    const services = this.getServices()\n\n    for (const { userId } of users) {\n      const defaultBasket = verifyOne(await this.findOutputBaskets({ partial: { userId, name: 'default' } }))\n      const outputs = await this.findOutputs({\n        partial: { userId, basketId: defaultBasket.basketId, spendable: true }\n      })\n\n      for (const o of outputs) {\n        if (!o.spendable) continue\n        const isUtxo = await this.checkOutputIsUtxo(o, services)\n        if (!isUtxo) invalidSpendableOutputs.push(o)\n      }\n    }\n    return { invalidSpendableOutputs }\n  }\n\n  private async checkOutputIsUtxo(\n    o: TableOutput,\n    services: {\n      hashOutputScript: (s: string) => string\n      getUtxoStatus: (hash: string, fmt: undefined, outpoint: string) => Promise<{ isUtxo?: boolean }>\n    }\n  ): Promise<boolean> {\n    if (o.lockingScript == null || o.lockingScript.length === 0) return false\n    const hash = services.hashOutputScript(asString(o.lockingScript))\n    const r = await services.getUtxoStatus(hash, undefined, `${o.txid ?? ''}.${o.vout ?? ''}`)\n    return r.isUtxo === true\n  }\n\n  async updateProvenTxReqDynamics(\n    id: number,\n    update: Partial<TableProvenTxReqDynamics>,\n    trx?: TrxToken\n  ): Promise<number> {\n    const partial: Partial<TableProvenTxReq> = {}\n    if (update.updated_at != null) partial.updated_at = update.updated_at\n    if (update.provenTxId != null && update.provenTxId > 0) partial.provenTxId = update.provenTxId\n    if (update.status != null) partial.status = update.status\n    if (Number.isInteger(update.attempts)) partial.attempts = update.attempts\n    if (update.notified !== undefined) partial.notified = update.notified\n    if (update.batch != null && update.batch !== '') partial.batch = update.batch\n    if (update.history != null && update.history !== '') partial.history = update.history\n    if (update.notify != null && update.notify !== '') partial.notify = update.notify\n    if (update.wasBroadcast !== undefined) partial.wasBroadcast = update.wasBroadcast ?? false\n    if (Number.isInteger(update.rebroadcastAttempts)) partial.rebroadcastAttempts = update.rebroadcastAttempts ?? 0\n\n    return await this.updateProvenTxReq(id, partial, trx)\n  }\n\n  async extendOutput(\n    o: TableOutput,\n    includeBasket = false,\n    includeTags = false,\n    trx?: TrxToken\n  ): Promise<TableOutputX> {\n    const ox = o as TableOutputX\n    if (includeBasket && ox.basketId != null && ox.basketId > 0)\n      ox.basket = await this.findOutputBasketById(o.basketId as number, trx)\n    if (includeTags) {\n      ox.tags = await this.getTagsForOutputId(o.outputId)\n    }\n    return o\n  }\n\n  async validateOutputScript(o: TableOutput, trx?: TrxToken): Promise<void> {\n    // without offset and length values return what we have (make no changes)\n    if (\n      o.scriptLength == null ||\n      o.scriptLength === 0 ||\n      o.scriptOffset == null ||\n      o.scriptOffset === 0 ||\n      o.txid == null ||\n      o.txid === ''\n    )\n      return\n    // if there is an outputScript and its length is the expected length return what we have.\n    if (o.lockingScript?.length === o.scriptLength) return\n\n    // outputScript is missing or has incorrect length...\n\n    const script = await this.getRawTxOfKnownValidTransaction(o.txid, o.scriptOffset, o.scriptLength, trx)\n    if (script == null) return\n    o.lockingScript = script\n  }\n}\n\nexport interface StorageProviderOptions extends StorageReaderWriterOptions {\n  chain: Chain\n  feeModel: StorageFeeModel\n  /**\n   * Transactions created by this Storage can charge a fee per transaction.\n   * A value of zero disables commission fees.\n   */\n  commissionSatoshis: number\n  /**\n   * If commissionSatoshis is greater than zero, must be a valid public key hex string.\n   * The actual locking script for each commission will use a public key derived\n   * from this key by information stored in the commissions table.\n   */\n  commissionPubKeyHex?: PubKeyHex\n  /**\n   * Optional verifier for server-side action-batch script checks. This Wallet\n   * Toolbox extension leaves the BRC-100 wallet interface unchanged.\n   */\n  scriptVerifier?: SpendVerifierInterface\n}\n\nexport function validateStorageFeeModel(v?: StorageFeeModel): StorageFeeModel {\n  const r: StorageFeeModel = {\n    model: 'sat/kb',\n    value: 100\n  }\n  if (typeof v === 'object') {\n    if (v.model !== 'sat/kb') throw new WERR_INVALID_PARAMETER('StorageFeeModel.model', '\"sat/kb\"')\n    if (typeof v.value === 'number') {\n      r.value = v.value\n    }\n  }\n  return r\n}\n\nexport interface StorageAdminStats {\n  requestedBy: string\n  when: string\n  usersDay: number\n  usersWeek: number\n  usersMonth: number\n  usersTotal: number\n  transactionsDay: number\n  transactionsWeek: number\n  transactionsMonth: number\n  transactionsTotal: number\n  txCompletedDay: number\n  txCompletedWeek: number\n  txCompletedMonth: number\n  txCompletedTotal: number\n  txFailedDay: number\n  txFailedWeek: number\n  txFailedMonth: number\n  txFailedTotal: number\n  txAbandonedDay: number\n  txAbandonedWeek: number\n  txAbandonedMonth: number\n  txAbandonedTotal: number\n  txUnprocessedDay: number\n  txUnprocessedWeek: number\n  txUnprocessedMonth: number\n  txUnprocessedTotal: number\n  txSendingDay: number\n  txSendingWeek: number\n  txSendingMonth: number\n  txSendingTotal: number\n  txUnprovenDay: number\n  txUnprovenWeek: number\n  txUnprovenMonth: number\n  txUnprovenTotal: number\n  txUnsignedDay: number\n  txUnsignedWeek: number\n  txUnsignedMonth: number\n  txUnsignedTotal: number\n  txNosendDay: number\n  txNosendWeek: number\n  txNosendMonth: number\n  txNosendTotal: number\n  txNonfinalDay: number\n  txNonfinalWeek: number\n  txNonfinalMonth: number\n  txNonfinalTotal: number\n  txUnfailDay: number\n  txUnfailWeek: number\n  txUnfailMonth: number\n  txUnfailTotal: number\n  satoshisDefaultDay: number\n  satoshisDefaultWeek: number\n  satoshisDefaultMonth: number\n  satoshisDefaultTotal: number\n  satoshisOtherDay: number\n  satoshisOtherWeek: number\n  satoshisOtherMonth: number\n  satoshisOtherTotal: number\n  basketsDay: number\n  basketsWeek: number\n  basketsMonth: number\n  basketsTotal: number\n  labelsDay: number\n  labelsWeek: number\n  labelsMonth: number\n  labelsTotal: number\n  tagsDay: number\n  tagsWeek: number\n  tagsMonth: number\n  tagsTotal: number\n}\n\nexport interface AdminStatsResult extends StorageAdminStats {\n  servicesStats?: ServicesCallHistory\n  monitorStats?: ServicesCallHistory\n}\n","import * as sdk from '../sdk/index'\nimport { TableSettings } from '../storage/schema/tables/TableSettings'\nimport { StorageReader } from './StorageReader'\n\n/**\n * The `StorageSyncReader` non-abstract class must be used when authentication checking access to the methods of a `StorageBaseReader` is required.\n *\n * Constructed from an `auth` object that must minimally include the authenticated user's identityKey,\n * and the `StorageBaseReader` to be protected.\n */\nexport class StorageSyncReader implements sdk.WalletStorageSyncReader {\n  constructor (\n    public auth: sdk.AuthId,\n    public storage: StorageReader\n  ) {}\n\n  async makeAvailable (): Promise<TableSettings> {\n    await this.storage.makeAvailable()\n    if (this.auth.userId === undefined) {\n      const user = await this.storage.findUserByIdentityKey(this.auth.identityKey)\n      if (user == null) throw new sdk.WERR_UNAUTHORIZED()\n      this.auth.userId = user.userId\n    }\n    return this.storage.getSettings()\n  }\n\n  async destroy (): Promise<void> {\n    return await this.storage.destroy()\n  }\n\n  async getSyncChunk (args: sdk.RequestSyncChunkArgs): Promise<sdk.SyncChunk> {\n    if (this.auth.userId == null) await this.makeAvailable()\n    if (args.identityKey !== this.auth.identityKey) throw new sdk.WERR_UNAUTHORIZED()\n    return await this.storage.getSyncChunk(args)\n  }\n}\n","import { Base64String } from '@bsv/sdk'\nimport * as sdk from '../../../sdk'\n\nexport interface TableTransaction extends sdk.EntityTimeStamp {\n  created_at: Date\n  updated_at: Date\n  transactionId: number\n  userId: number\n  provenTxId?: number\n  status: sdk.TransactionStatus\n  /**\n   * max length of 64, hex encoded\n   */\n  reference: Base64String\n  /**\n   * true if transaction originated in this wallet, change returns to it.\n   * false for a transaction created externally and handed in to this wallet.\n   */\n  isOutgoing: boolean\n  satoshis: number\n  description: string\n  /**\n   * If not undefined, must match value in associated rawTransaction.\n   */\n  version?: number\n  /**\n   * Optional. Default is zero.\n   * When the transaction can be processed into a block:\n   * >= 500,000,000 values are interpreted as minimum required unix time stamps in seconds\n   * < 500,000,000 values are interpreted as minimum required block height\n   */\n  lockTime?: number\n  txid?: string\n  inputBEEF?: number[]\n  rawTx?: number[]\n}\n\nexport const transactionColumnsWithoutRawTx = [\n  'created_at',\n  'updated_at',\n  'transactionId',\n  'userId',\n  'provenTxId',\n  'status',\n  'reference',\n  'isOutgoing',\n  'satoshis',\n  'version',\n  'lockTime',\n  'description',\n  'txid'\n  //   'inputBEEF',\n  //   'rawTx',\n]\n","import { Base64String, DescriptionString5to50Bytes, PubKeyHex } from '@bsv/sdk'\nimport { TableOutputBasket } from './TableOutputBasket'\nimport { TableOutputTag } from './TableOutputTag'\nimport * as sdk from '../../../sdk'\n\nexport interface TableOutput extends sdk.EntityTimeStamp {\n  created_at: Date\n  updated_at: Date\n  outputId: number\n  userId: number\n  transactionId: number\n  basketId?: number\n  spendable: boolean\n  change: boolean\n  outputDescription: DescriptionString5to50Bytes\n  vout: number\n  satoshis: number\n  providedBy: sdk.StorageProvidedBy\n  purpose: string\n  type: string\n  txid?: string\n  senderIdentityKey?: PubKeyHex\n  derivationPrefix?: Base64String\n  derivationSuffix?: Base64String\n  customInstructions?: string\n  spentBy?: number\n  sequenceNumber?: number\n  spendingDescription?: string\n  scriptLength?: number\n  scriptOffset?: number\n  lockingScript?: number[]\n}\n\nexport interface TableOutputX extends TableOutput {\n  basket?: TableOutputBasket\n  tags?: TableOutputTag[]\n}\n\nexport const outputColumnsWithoutLockingScript = [\n  'created_at',\n  'updated_at',\n  'outputId',\n  'userId',\n  'transactionId',\n  'basketId',\n  'spendable',\n  'change',\n  'vout',\n  'satoshis',\n  'providedBy',\n  'purpose',\n  'type',\n  'outputDescription',\n  'txid',\n  'senderIdentityKey',\n  'derivationPrefix',\n  'derivationSuffix',\n  'customInstructions',\n  'spentBy',\n  'sequenceNumber',\n  'spendingDescription',\n  'scriptLength',\n  'scriptOffset'\n  // 'lockingScript',\n]\n","import { PeerSession } from '@bsv/sdk'\n\n/**\n * Durable representation of a BRC-103 peer session.\n *\n * The session nonce is the authoritative key. `lastUpdate` also acts as the\n * optimistic-write version so a delayed request from one replica cannot\n * overwrite newer authentication state written by another replica.\n */\nexport interface TableAuthSession {\n  sessionNonce: string\n  peerNonce?: string | null\n  peerIdentityKey?: string | null\n  isAuthenticated: boolean | number\n  lastUpdate: number | string\n  certificatesRequired?: boolean | number | null\n  certificatesValidated?: boolean | number | null\n  expiresAt: number | string\n}\n\nexport function tableAuthSessionToPeerSession (row: TableAuthSession): PeerSession {\n  return {\n    sessionNonce: row.sessionNonce,\n    peerNonce: row.peerNonce ?? undefined,\n    peerIdentityKey: row.peerIdentityKey ?? undefined,\n    isAuthenticated: Boolean(row.isAuthenticated),\n    lastUpdate: Number(row.lastUpdate),\n    certificatesRequired: row.certificatesRequired == null ? undefined : Boolean(row.certificatesRequired),\n    certificatesValidated: row.certificatesValidated == null ? undefined : Boolean(row.certificatesValidated)\n  }\n}\n","import { SyncChunk } from '../../sdk/WalletStorage.interfaces'\nimport { EntityTimeStamp } from '../../sdk/types'\n\n/**\n * Shared entity-validation helpers used by both client-side storage remoting\n * (StorageClientBase / StorageMobile) and the server-side StorageServer.\n *\n * These helpers normalise records returned from remote calls or database queries:\n *   - Coerce date strings / timestamps to `Date` objects.\n *   - Replace `null` values with `undefined`.\n *   - Replace `Uint8Array` / `Buffer` values with plain `number[]` arrays.\n */\n\nexport function validateDate(date: Date | string | number): Date {\n  if (date instanceof Date) return date\n  return new Date(date)\n}\n\nfunction defineOwnValues(target: object, values: ReadonlyMap<string, unknown>): void {\n  Object.defineProperties(\n    target,\n    Object.fromEntries(\n      Array.from(values, ([key, value]) => [\n        key,\n        {\n          value,\n          writable: true,\n          enumerable: true,\n          configurable: true\n        }\n      ])\n    )\n  )\n}\n\n/**\n * Force uniform behaviour across database engines.\n * Use to process all individual records with timestamps retrieved from database.\n */\nexport function validateEntity<T extends EntityTimeStamp>(entity: T, dateFields?: string[]): T {\n  const indexedEntity = entity as T & Record<string, unknown>\n  entity.created_at = validateDate(entity.created_at)\n  entity.updated_at = validateDate(entity.updated_at)\n  const replacements = new Map<string, unknown>()\n  if (dateFields != null) {\n    for (const df of dateFields) {\n      const value = indexedEntity[df]\n      if (Object.hasOwn(entity, df) && value) {\n        replacements.set(df, validateDate(value as Date | string | number))\n      }\n    }\n  }\n  for (const key of Object.keys(entity)) {\n    const val = replacements.has(key) ? replacements.get(key) : indexedEntity[key]\n    if (val === null) {\n      replacements.set(key, undefined)\n    } else if (val instanceof Uint8Array) {\n      replacements.set(key, Array.from(val))\n    }\n  }\n  if (replacements.size > 0) defineOwnValues(entity, replacements)\n  return entity\n}\n\n/**\n * Force uniform behaviour across database engines.\n * Use to process all arrays of records with timestamps retrieved from database.\n * @returns input `entities` array with contained values validated.\n */\nexport function validateEntities<T extends EntityTimeStamp>(entities: T[], dateFields?: string[]): T[] {\n  if (!Array.isArray(entities)) return entities\n  for (let i = 0; i < entities.length; i++) {\n    entities[i] = validateEntity(entities[i], dateFields)\n  }\n  return entities\n}\n\n/**\n * Validate all entity arrays within a `SyncChunk` received from a remote storage call.\n * Normalises timestamps, nulls, and binary fields in-place.\n */\nexport function validateSyncChunkEntities(r: SyncChunk): SyncChunk {\n  if (r.certificateFields != null) r.certificateFields = validateEntities(r.certificateFields)\n  if (r.certificates != null) r.certificates = validateEntities(r.certificates)\n  if (r.commissions != null) r.commissions = validateEntities(r.commissions)\n  if (r.outputBaskets != null) r.outputBaskets = validateEntities(r.outputBaskets)\n  if (r.outputTagMaps != null) r.outputTagMaps = validateEntities(r.outputTagMaps)\n  if (r.outputTags != null) r.outputTags = validateEntities(r.outputTags)\n  if (r.outputs != null) r.outputs = validateEntities(r.outputs)\n  if (r.provenTxReqs != null) r.provenTxReqs = validateEntities(r.provenTxReqs)\n  if (r.provenTxs != null) r.provenTxs = validateEntities(r.provenTxs)\n  if (r.transactions != null) r.transactions = validateEntities(r.transactions)\n  if (r.txLabelMaps != null) r.txLabelMaps = validateEntities(r.txLabelMaps)\n  if (r.txLabels != null) r.txLabels = validateEntities(r.txLabels)\n  if (r.user != null) r.user = validateEntity(r.user)\n  return r\n}\n","import {\n  AbortActionArgs,\n  AbortActionResult,\n  InternalizeActionArgs,\n  ListActionsResult,\n  ListCertificatesResult,\n  ListOutputsResult,\n  RelinquishCertificateArgs,\n  RelinquishOutputArgs,\n  WalletInterface,\n  AuthFetch,\n  Validation,\n  Telemetry,\n  TelemetryConfig,\n  TelemetrySpan\n} from '@bsv/sdk'\nimport {\n  AuthId,\n  FindCertificatesArgs,\n  FindOutputBasketsArgs,\n  FindOutputsArgs,\n  FindProvenTxReqsArgs,\n  ProcessSyncChunkResult,\n  RequestSyncChunkArgs,\n  StorageCreateActionResult,\n  StorageInternalizeActionResult,\n  StorageProcessActionArgs,\n  StorageProcessActionResults,\n  SyncChunk,\n  UpdateProvenTxReqWithNewProvenTxArgs,\n  UpdateProvenTxReqWithNewProvenTxResult,\n  WalletStorageProvider\n} from '../../sdk/WalletStorage.interfaces'\nimport {\n  AbortActionBatchResult,\n  ActionBatchManifest,\n  BeginActionBatchArgs,\n  BeginActionBatchResult,\n  CommitActionBatchByDigestArgs,\n  CommitActionBatchResult,\n  ExtendActionBatchArgs,\n  ExtendActionBatchResult,\n  PrepareActionBatchCommitResult,\n  PutActionBatchBlobArgs,\n  PutActionBatchPackArgs,\n  RenewActionBatchResult,\n  StorageCapabilities\n} from '../../sdk/ActionBatch.interfaces'\nimport { TableSettings } from '../schema/tables/TableSettings'\nimport { WERR_INVALID_OPERATION } from '../../sdk/WERR_errors'\nimport { WalletServices } from '../../sdk/WalletServices.interfaces'\nimport { TableUser } from '../schema/tables/TableUser'\nimport { TableSyncState } from '../schema/tables/TableSyncState'\nimport { TableCertificateX } from '../schema/tables/TableCertificate'\nimport { TableOutputBasket } from '../schema/tables/TableOutputBasket'\nimport { TableOutput } from '../schema/tables/TableOutput'\nimport { TableProvenTxReq } from '../schema/tables/TableProvenTxReq'\nimport { EntityTimeStamp } from '../../sdk/types'\nimport { validateDate, validateEntity, validateEntities, validateSyncChunkEntities } from './entityValidationHelpers'\nimport {\n  ACTION_BATCH_PACK_ENCODING_HEADER,\n  actionBatchPackLength,\n  compressActionBatchPackItems,\n  encodeActionBatchPack,\n  supportedActionBatchPackEncodings\n} from '../../utility/actionBatchPack'\n\nexport interface StorageClientOptions {\n  /**\n   * Send compact tagged binary request values after the server advertises\n   * support. Leave disabled during rolling deployments where an endpoint may\n   * still route requests to legacy server instances.\n   */\n  binaryRequests?: boolean\n  /**\n   * Optional vendor-neutral tracing. Disabled unless an enabled sink is\n   * supplied. Request parameters and response payloads are never emitted.\n   */\n  telemetry?: TelemetryConfig\n}\n\n/**\n * Abstract base class shared by `StorageClient` and `StorageMobile`.\n *\n * Contains all `WalletStorageProvider` method implementations and entity-validation\n * helpers. Subclasses only need to provide `rpcCall`, which differs between\n * the full (logger-aware) and mobile (lightweight) variants.\n */\nexport abstract class StorageClientBase implements WalletStorageProvider {\n  readonly endpointUrl: string\n  protected readonly authClient: AuthFetch\n  protected nextId = 1\n  protected serverSupportsBinary = false\n  protected readonly binaryRequests: boolean\n  protected readonly telemetry: Telemetry\n\n  // Track ephemeral (in-memory) \"settings\" if you wish to align with isAvailable() checks\n  public settings?: TableSettings\n\n  constructor(wallet: WalletInterface, endpointUrl: string, options: StorageClientOptions = {}) {\n    this.authClient = new AuthFetch(wallet)\n    this.endpointUrl = endpointUrl\n    this.binaryRequests = options.binaryRequests === true\n    this.telemetry = new Telemetry(options.telemetry)\n  }\n\n  protected async traceRpcCall<T>(\n    method: string,\n    params: unknown[],\n    callback: (span?: TelemetrySpan) => Promise<T>\n  ): Promise<T> {\n    if (!this.telemetry.enabled) return await callback()\n    const carrier = params.find(param => typeof param === 'object' && param != null) as object | undefined\n    return await this.telemetry.withSpan(\n      'wallet.storage.rpc',\n      {\n        component: 'wallet-storage-client',\n        kind: 'client',\n        carrier,\n        attributes: {\n          'rpc.method': method,\n          'rpc.system': 'wallet-storage',\n          'network.protocol': 'http'\n        }\n      },\n      callback\n    )\n  }\n\n  protected async traceRpcStep<T>(\n    name: string,\n    parent: TelemetrySpan | undefined,\n    callback: (span?: TelemetrySpan) => Promise<T> | T,\n    attributes?: Readonly<Record<string, unknown>>\n  ): Promise<T> {\n    if (parent == null) return await callback()\n    return await this.telemetry.withSpan(\n      name,\n      {\n        component: 'wallet-storage-client',\n        kind: 'client',\n        parent: parent.context,\n        attributes\n      },\n      callback\n    )\n  }\n\n  /**\n   * The `StorageClient` implements the `WalletStorageProvider` interface.\n   * It does not implement the lower level `StorageProvider` interface.\n   *\n   * @returns false\n   */\n  isStorageProvider(): boolean {\n    return false\n  }\n\n  /**\n   * Make a JSON-RPC call to the remote server.\n   * Implemented differently by each subclass (with or without logger support).\n   * @param method The WalletStorage method name to call.\n   * @param params The array of parameters to pass to the method in order.\n   */\n  protected abstract rpcCall<T>(method: string, params: unknown[]): Promise<T>\n\n  /**\n   * @returns true once storage `TableSettings` have been retreived from remote storage.\n   */\n  isAvailable(): boolean {\n    // We'll just say \"yes\" if we have settings\n    return this.settings != null\n  }\n\n  /**\n   * @returns remote storage `TableSettings` if they have been retreived by `makeAvailable`.\n   * @throws WERR_INVALID_OPERATION if `makeAvailable` has not yet been called.\n   */\n  getSettings(): TableSettings {\n    if (this.settings == null) {\n      throw new WERR_INVALID_OPERATION('call makeAvailable at least once before getSettings')\n    }\n    return this.settings\n  }\n\n  /**\n   * Must be called prior to making use of storage.\n   * Retreives `TableSettings` from remote storage provider.\n   * @returns remote storage `TableSettings`\n   */\n  async makeAvailable(): Promise<TableSettings> {\n    this.settings ??= await this.rpcCall<TableSettings>('makeAvailable', [])\n    return this.settings\n  }\n\n  /// ///////////////////////////////////////////////////////////////////////////\n  //\n  // Implementation of all WalletStorage interface methods\n  // They are simple pass-thrus to rpcCall\n  //\n  // IMPORTANT: The parameter ordering must match exactly as in your interface.\n  /// ///////////////////////////////////////////////////////////////////////////\n\n  /**\n   * Called to cleanup resources when no further use of this object will occur.\n   */\n  async destroy(): Promise<void> {\n    return await this.rpcCall<void>('destroy', [])\n  }\n\n  /**\n   * Requests schema migration to latest.\n   * Typically remote storage will ignore this request.\n   * @param storageName Unique human readable name for remote storage if it does not yet exist.\n   * @param storageIdentityKey Unique identity key for remote storage if it does not yet exist.\n   * @returns current schema migration identifier\n   */\n  async migrate(storageName: string, _storageIdentityKey: string): Promise<string> {\n    return await this.rpcCall<string>('migrate', [storageName])\n  }\n\n  /**\n   * Remote storage does not offer `Services` to remote clients.\n   * @throws WERR_INVALID_OPERATION\n   */\n  getServices(): WalletServices {\n    // Typically, the client would not store or retrieve \"Services\" from a remote server.\n    // The \"services\" in local in-memory usage is a no-op or your own approach:\n    throw new WERR_INVALID_OPERATION(\n      'getServices() not implemented in remote client. This method typically is not used remotely.'\n    )\n  }\n\n  /**\n   * Ignored. Remote storage cannot share `Services` with remote clients.\n   */\n  setServices(_v: WalletServices): void {\n    // Typically no-op for remote client\n    // Because \"services\" are usually local definitions to the Storage.\n  }\n\n  /**\n   * Storage level processing for wallet `internalizeAction`.\n   * Updates internalized outputs in remote storage.\n   * Triggers proof validation of containing transaction.\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args Original wallet `internalizeAction` arguments.\n   * @returns `internalizeAction` results\n   */\n  async internalizeAction(auth: AuthId, args: InternalizeActionArgs): Promise<StorageInternalizeActionResult> {\n    return await this.rpcCall<StorageInternalizeActionResult>('internalizeAction', [auth, args])\n  }\n\n  /**\n   * Storage level processing for wallet `createAction`.\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args Validated extension of original wallet `createAction` arguments.\n   * @returns `StorageCreateActionResults` supporting additional wallet processing to yield `createAction` results.\n   */\n  async createAction(auth: AuthId, args: Validation.ValidCreateActionArgs): Promise<StorageCreateActionResult> {\n    return await this.rpcCall<StorageCreateActionResult>('createAction', [auth, args])\n  }\n\n  /**\n   * Storage level processing for wallet `createAction` and `signAction`.\n   *\n   * Handles remaining storage tasks once a fully signed transaction has been completed. This is common to both `createAction` and `signAction`.\n   *\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args `StorageProcessActionArgs` convey completed signed transaction to storage.\n   * @returns `StorageProcessActionResults` supporting final wallet processing to yield `createAction` or `signAction` results.\n   */\n  async processAction(auth: AuthId, args: StorageProcessActionArgs): Promise<StorageProcessActionResults> {\n    return await this.rpcCall<StorageProcessActionResults>('processAction', [auth, args])\n  }\n\n  async getCapabilities(): Promise<StorageCapabilities> {\n    return await this.rpcCall<StorageCapabilities>('getCapabilities', [])\n  }\n\n  async beginActionBatch(auth: AuthId, args: BeginActionBatchArgs): Promise<BeginActionBatchResult> {\n    return await this.rpcCall<BeginActionBatchResult>('beginActionBatch', [auth, args])\n  }\n\n  async extendActionBatch(auth: AuthId, args: ExtendActionBatchArgs): Promise<ExtendActionBatchResult> {\n    return await this.rpcCall<ExtendActionBatchResult>('extendActionBatch', [auth, args])\n  }\n\n  async renewActionBatch(auth: AuthId, batchId: string): Promise<RenewActionBatchResult> {\n    return await this.rpcCall<RenewActionBatchResult>('renewActionBatch', [auth, batchId])\n  }\n\n  async prepareActionBatchCommit(auth: AuthId, manifest: ActionBatchManifest): Promise<PrepareActionBatchCommitResult> {\n    return await this.rpcCall<PrepareActionBatchCommitResult>('prepareActionBatchCommit', [auth, manifest])\n  }\n\n  async putActionBatchBlob(auth: AuthId, args: PutActionBatchBlobArgs): Promise<void> {\n    const baseUrl = this.endpointUrl.endsWith('/') ? this.endpointUrl.slice(0, -1) : this.endpointUrl\n    const url = `${baseUrl}/action-batch/${encodeURIComponent(args.batchId)}/blob/${encodeURIComponent(args.digest)}`\n    const bytes = args.bytes instanceof Uint8Array ? args.bytes : Uint8Array.from(args.bytes)\n    const response = await this.authClient.fetch(url, {\n      method: 'PUT',\n      headers: { 'Content-Type': 'application/octet-stream' },\n      body: bytes\n    })\n    if (!response.ok) {\n      const details = (await response.text()).slice(0, 512)\n      throw new Error(\n        `WalletStorageClient putActionBatchBlob: network error ${response.status} ${response.statusText}: ${details}`\n      )\n    }\n  }\n\n  async putActionBatchPack(_auth: AuthId, args: PutActionBatchPackArgs): Promise<void> {\n    const available = new Set(supportedActionBatchPackEncodings())\n    const encoding = (args.preferredEncodings ?? ['identity']).find(candidate => available.has(candidate)) ?? 'identity'\n    const frameLength = actionBatchPackLength(args.items)\n    let body = await compressActionBatchPackItems(args.items, encoding, args.maxPackBytes, args.maxItems)\n    let transmittedEncoding = encoding\n    if (encoding !== 'identity' && body.length >= frameLength) {\n      body = encodeActionBatchPack(args.items, args.maxPackBytes, args.maxItems)\n      transmittedEncoding = 'identity'\n    }\n    const baseUrl = this.endpointUrl.endsWith('/') ? this.endpointUrl.slice(0, -1) : this.endpointUrl\n    const url = `${baseUrl}/action-batch/${encodeURIComponent(args.batchId)}/pack`\n    const response = await this.authClient.fetch(url, {\n      method: 'PUT',\n      headers: {\n        'Content-Type': 'application/octet-stream',\n        [ACTION_BATCH_PACK_ENCODING_HEADER]: transmittedEncoding\n      },\n      body\n    })\n    if (!response.ok) {\n      const details = (await response.text()).slice(0, 512)\n      throw new Error(\n        `WalletStorageClient putActionBatchPack: network error ${response.status} ${response.statusText}: ${details}`\n      )\n    }\n  }\n\n  async commitActionBatch(auth: AuthId, manifest: ActionBatchManifest): Promise<CommitActionBatchResult> {\n    return await this.rpcCall<CommitActionBatchResult>('commitActionBatch', [auth, manifest])\n  }\n\n  async commitActionBatchByDigest(auth: AuthId, args: CommitActionBatchByDigestArgs): Promise<CommitActionBatchResult> {\n    return await this.rpcCall<CommitActionBatchResult>('commitActionBatchByDigest', [auth, args])\n  }\n\n  async abortActionBatch(auth: AuthId, batchId: string): Promise<AbortActionBatchResult> {\n    return await this.rpcCall<AbortActionBatchResult>('abortActionBatch', [auth, batchId])\n  }\n\n  /**\n   * Aborts an action by `reference` string.\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args original wallet `abortAction` args.\n   * @returns `abortAction` result.\n   */\n  async abortAction(auth: AuthId, args: AbortActionArgs): Promise<AbortActionResult> {\n    return await this.rpcCall<AbortActionResult>('abortAction', [auth, args])\n  }\n\n  /**\n   * Used to both find and initialize a new user by identity key.\n   * It is up to the remote storage whether to allow creation of new users by this method.\n   * @param identityKey of the user.\n   * @returns `TableUser` for the user and whether a new user was created.\n   */\n  async findOrInsertUser(identityKey: string): Promise<{ user: TableUser; isNew: boolean }> {\n    return await this.rpcCall<{ user: TableUser; isNew: boolean }>('findOrInsertUser', [identityKey])\n  }\n\n  /**\n   * Used to both find and insert a `TableSyncState` record for the user to track wallet data replication across storage providers.\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param storageName the name of the remote storage being sync'd\n   * @param storageIdentityKey the identity key of the remote storage being sync'd\n   * @returns `TableSyncState` and whether a new record was created.\n   */\n  async findOrInsertSyncStateAuth(\n    auth: AuthId,\n    storageIdentityKey: string,\n    storageName: string\n  ): Promise<{ syncState: TableSyncState; isNew: boolean }> {\n    const r = await this.rpcCall<{ syncState: TableSyncState; isNew: boolean }>('findOrInsertSyncStateAuth', [\n      auth,\n      storageIdentityKey,\n      storageName\n    ])\n    r.syncState = validateEntity(r.syncState, ['when'])\n    return r\n  }\n\n  /**\n   * Inserts a new certificate with fields and keyring into remote storage.\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param certificate the certificate to insert.\n   * @returns record Id of the inserted `TableCertificate` record.\n   */\n  async insertCertificateAuth(auth: AuthId, certificate: TableCertificateX): Promise<number> {\n    const r = await this.rpcCall<number>('insertCertificateAuth', [auth, certificate])\n    return r\n  }\n\n  /**\n   * Storage level processing for wallet `listActions`.\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args Validated extension of original wallet `listActions` arguments.\n   * @returns `listActions` results.\n   */\n  async listActions(auth: AuthId, vargs: Validation.ValidListActionsArgs): Promise<ListActionsResult> {\n    const r = await this.rpcCall<ListActionsResult>('listActions', [auth, vargs])\n    return r\n  }\n\n  /**\n   * Storage level processing for wallet `listOutputs`.\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args Validated extension of original wallet `listOutputs` arguments.\n   * @returns `listOutputs` results.\n   */\n  async listOutputs(auth: AuthId, vargs: Validation.ValidListOutputsArgs): Promise<ListOutputsResult> {\n    const r = await this.rpcCall<ListOutputsResult>('listOutputs', [auth, vargs])\n    return r\n  }\n\n  /**\n   * Storage level processing for wallet `listCertificates`.\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args Validated extension of original wallet `listCertificates` arguments.\n   * @returns `listCertificates` results.\n   */\n  async listCertificates(auth: AuthId, vargs: Validation.ValidListCertificatesArgs): Promise<ListCertificatesResult> {\n    const r = await this.rpcCall<ListCertificatesResult>('listCertificates', [auth, vargs])\n    return r\n  }\n\n  /**\n   * Find user certificates, optionally with fields.\n   *\n   * This certificate retrieval method supports internal wallet operations.\n   * Field values are stored and retrieved encrypted.\n   *\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args `FindCertificatesArgs` determines which certificates to retrieve and whether to include fields.\n   * @returns array of certificates matching args.\n   */\n  async findCertificatesAuth(auth: AuthId, args: FindCertificatesArgs): Promise<TableCertificateX[]> {\n    const r = await this.rpcCall<TableCertificateX[]>('findCertificatesAuth', [auth, args])\n    validateEntities(r)\n    if (args.includeFields) {\n      for (const c of r) {\n        if (c.fields != null) validateEntities(c.fields)\n      }\n    }\n    return r\n  }\n\n  /**\n   * Find output baskets.\n   *\n   * This retrieval method supports internal wallet operations.\n   *\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args `FindOutputBasketsArgs` determines which baskets to retrieve.\n   * @returns array of output baskets matching args.\n   */\n  async findOutputBasketsAuth(auth: AuthId, args: FindOutputBasketsArgs): Promise<TableOutputBasket[]> {\n    const r = await this.rpcCall<TableOutputBasket[]>('findOutputBasketsAuth', [auth, args])\n    validateEntities(r)\n    return r\n  }\n\n  /**\n   * Find outputs.\n   *\n   * This retrieval method supports internal wallet operations.\n   *\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args `FindOutputsArgs` determines which outputs to retrieve.\n   * @returns array of outputs matching args.\n   */\n  async findOutputsAuth(auth: AuthId, args: FindOutputsArgs): Promise<TableOutput[]> {\n    const r = await this.rpcCall<TableOutput[]>('findOutputsAuth', [auth, args])\n    validateEntities(r)\n    return r\n  }\n\n  /**\n   * Find requests for transaction proofs.\n   *\n   * This retrieval method supports internal wallet operations.\n   *\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args `FindProvenTxReqsArgs` determines which proof requests to retrieve.\n   * @returns array of proof requests matching args.\n   */\n  async findProvenTxReqs(args: FindProvenTxReqsArgs): Promise<TableProvenTxReq[]> {\n    const r = await this.rpcCall<TableProvenTxReq[]>('findProvenTxReqs', [args])\n    validateEntities(r)\n    return r\n  }\n\n  /**\n   * Relinquish a certificate.\n   *\n   * For storage supporting replication records must be kept of deletions. Therefore certificates are marked as deleted\n   * when relinquished, and no longer returned by `listCertificates`, but are still retained by storage.\n   *\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args original wallet `relinquishCertificate` args.\n   */\n  async relinquishCertificate(auth: AuthId, args: RelinquishCertificateArgs): Promise<number> {\n    return await this.rpcCall<number>('relinquishCertificate', [auth, args])\n  }\n\n  /**\n   * Relinquish an output.\n   *\n   * Relinquishing an output removes the output from whatever basket was tracking it.\n   *\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param args original wallet `relinquishOutput` args.\n   */\n  async relinquishOutput(auth: AuthId, args: RelinquishOutputArgs): Promise<number> {\n    return await this.rpcCall<number>('relinquishOutput', [auth, args])\n  }\n\n  /**\n   * Process a \"chunk\" of replication data for the user.\n   *\n   * The normal data flow is for the active storage to push backups as a sequence of data chunks to backup storage providers.\n   *\n   * @param args a copy of the replication request args that initiated the sequence of data chunks.\n   * @param chunk the current data chunk to process.\n   * @returns whether processing is done, counts of inserts and udpates, and related progress tracking properties.\n   */\n  async processSyncChunk(args: RequestSyncChunkArgs, chunk: SyncChunk): Promise<ProcessSyncChunkResult> {\n    const r = await this.rpcCall<ProcessSyncChunkResult>('processSyncChunk', [args, chunk])\n    return r\n  }\n\n  /**\n   * Request a \"chunk\" of replication data for a specific user and storage provider.\n   *\n   * The normal data flow is for the active storage to push backups as a sequence of data chunks to backup storage providers.\n   * Also supports recovery where non-active storage can attempt to merge available data prior to becoming active.\n   *\n   * @param args that identify the non-active storage which will receive replication data and constrains the replication process.\n   * @returns the next \"chunk\" of replication data\n   */\n  async getSyncChunk(args: RequestSyncChunkArgs): Promise<SyncChunk> {\n    const r = await this.rpcCall<SyncChunk>('getSyncChunk', [args])\n    return validateSyncChunkEntities(r)\n  }\n\n  /**\n   * Handles the data received when a new transaction proof is found in response to an outstanding request for proof data:\n   *\n   *   - Creates a new `TableProvenTx` record.\n   *   - Notifies all user transaction records of the new status.\n   *   - Updates the proof request record to 'completed' status which enables delayed deletion.\n   *\n   * @param args proof request and new transaction proof data\n   * @returns results of updates\n   */\n  async updateProvenTxReqWithNewProvenTx(\n    args: UpdateProvenTxReqWithNewProvenTxArgs\n  ): Promise<UpdateProvenTxReqWithNewProvenTxResult> {\n    const r = await this.rpcCall<UpdateProvenTxReqWithNewProvenTxResult>('updateProvenTxReqWithNewProvenTx', [args])\n    return r\n  }\n\n  /**\n   * Ensures up-to-date wallet data replication to all configured backup storage providers,\n   * then promotes one of the configured backups to active,\n   * demoting the current active to new backup.\n   *\n   * @param auth Identifies client by identity key and the storage identity key of their currently active storage.\n   * This must match the `AuthFetch` identity securing the remote conneciton.\n   * @param newActiveStorageIdentityKey which must be a currently configured backup storage provider.\n   */\n  async setActive(auth: AuthId, newActiveStorageIdentityKey: string): Promise<number> {\n    return await this.rpcCall<number>('setActive', [auth, newActiveStorageIdentityKey])\n  }\n\n  /** @see {@link validateDate} */\n  validateDate(date: Date | string | number): Date {\n    return validateDate(date)\n  }\n\n  /**\n   * Helper to force uniform behavior across database engines.\n   * Use to process all individual records with time stamps retreived from database.\n   * @see {@link validateEntity}\n   */\n  validateEntity<T extends EntityTimeStamp>(entity: T, dateFields?: string[]): T {\n    return validateEntity(entity, dateFields)\n  }\n\n  /**\n   * Helper to force uniform behavior across database engines.\n   * Use to process all arrays of records with time stamps retreived from database.\n   * @returns input `entities` array with contained values validated.\n   * @see {@link validateEntities}\n   */\n  validateEntities<T extends EntityTimeStamp>(entities: T[], dateFields?: string[]): T[] {\n    return validateEntities(entities, dateFields)\n  }\n}\n","export const BINARY_ENCODING_HEADER = 'X-BSV-Binary-Encoding'\nexport const BINARY_REQUEST_ENCODING_HEADER = 'X-BSV-Binary-Request-Encoding'\nexport const BINARY_ENCODING = 'base64'\n\nconst TAG = '$bsvBinary'\nconst ESCAPED = 'escaped'\nconst BASE64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'\n\nfunction getBufferCtor(): any {\n  return typeof globalThis === 'undefined' ? undefined : (globalThis as any).Buffer\n}\n\nfunction toBase64(bytes: Uint8Array): string {\n  const BufferCtor = getBufferCtor()\n  if (BufferCtor != null) return BufferCtor.from(bytes.buffer, bytes.byteOffset, bytes.byteLength).toString('base64')\n  if (typeof globalThis.btoa === 'function') {\n    let binary = ''\n    const chunkSize = 0x8000\n    for (let offset = 0; offset < bytes.length; offset += chunkSize) {\n      binary += String.fromCodePoint(...bytes.subarray(offset, Math.min(offset + chunkSize, bytes.length)))\n    }\n    return globalThis.btoa(binary)\n  }\n  let encoded = ''\n  for (let i = 0; i < bytes.length; i += 3) {\n    const first = bytes[i]\n    const second = bytes[i + 1] ?? 0\n    const third = bytes[i + 2] ?? 0\n    encoded += BASE64[first >>> 2]\n    encoded += BASE64[((first & 3) << 4) | (second >>> 4)]\n    encoded += i + 1 < bytes.length ? BASE64[((second & 15) << 2) | (third >>> 6)] : '='\n    encoded += i + 2 < bytes.length ? BASE64[third & 63] : '='\n  }\n  return encoded\n}\n\nfunction validateBase64(base64: string): number {\n  if (base64.length % 4 !== 0) throw new TypeError('Invalid base64 binary JSON value')\n  let padding = 0\n  if (base64.endsWith('==')) {\n    padding = 2\n  } else if (base64.endsWith('=')) {\n    padding = 1\n  }\n  const contentLength = base64.length - padding\n  for (let i = 0; i < contentLength; i++) {\n    if (!BASE64.includes(base64[i])) throw new TypeError('Invalid base64 binary JSON value')\n  }\n  for (let i = contentLength; i < base64.length; i++) {\n    if (base64[i] !== '=') throw new TypeError('Invalid base64 binary JSON value')\n  }\n  if (\n    (padding === 1 && (BASE64.indexOf(base64[contentLength - 1]) & 3) !== 0) ||\n    (padding === 2 && (BASE64.indexOf(base64[contentLength - 1]) & 15) !== 0)\n  )\n    throw new TypeError('Invalid base64 binary JSON value')\n  return padding\n}\n\nfunction decodeBase64WithoutPlatformSupport(base64: string, padding: number): Uint8Array {\n  const bytes = new Uint8Array(Math.floor((base64.length * 3) / 4) - padding)\n  let offset = 0\n  for (let i = 0; i < base64.length; i += 4) {\n    const first = BASE64.indexOf(base64[i])\n    const second = BASE64.indexOf(base64[i + 1])\n    const third = base64[i + 2] === '=' ? 0 : BASE64.indexOf(base64[i + 2])\n    const fourth = base64[i + 3] === '=' ? 0 : BASE64.indexOf(base64[i + 3])\n    const value = (first << 18) | (second << 12) | (third << 6) | fourth\n    if (offset < bytes.length) bytes[offset++] = value >>> 16\n    if (offset < bytes.length) bytes[offset++] = value >>> 8\n    if (offset < bytes.length) bytes[offset++] = value\n  }\n  return bytes\n}\n\nfunction fromBase64(base64: string): Uint8Array {\n  const padding = validateBase64(base64)\n  const BufferCtor = getBufferCtor()\n  if (BufferCtor != null) {\n    const buffer = BufferCtor.from(base64, 'base64')\n    return new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength)\n  }\n  if (typeof globalThis.atob === 'function') {\n    const binary = globalThis.atob(base64)\n    // Uint8Array.from performs the conversion in the native collection\n    // primitive and avoids an attacker-controlled JavaScript loop bound.\n    return Uint8Array.from(binary, character => character.codePointAt(0)!)\n  }\n  return decodeBase64WithoutPlatformSupport(base64, padding)\n}\n\nfunction isTaggedBinary(value: unknown): value is { [TAG]: typeof BINARY_ENCODING; data: string } {\n  return (\n    value != null &&\n    typeof value === 'object' &&\n    (value as any)[TAG] === BINARY_ENCODING &&\n    typeof (value as any).data === 'string' &&\n    Object.keys(value).length === 2\n  )\n}\n\nfunction isBufferJson(value: unknown): value is { type: 'Buffer'; data: number[] } {\n  return (\n    value != null &&\n    typeof value === 'object' &&\n    (value as any).type === 'Buffer' &&\n    Array.isArray((value as any).data) &&\n    Object.keys(value).length === 2\n  )\n}\n\nfunction isEscapedJson(value: unknown): value is { [TAG]: typeof ESCAPED; entries: Array<[string, unknown]> } {\n  return (\n    value != null &&\n    typeof value === 'object' &&\n    (value as any)[TAG] === ESCAPED &&\n    Array.isArray((value as any).entries) &&\n    Object.keys(value).length === 2 &&\n    (value as any).entries.every(\n      (entry: unknown) => Array.isArray(entry) && entry.length === 2 && typeof entry[0] === 'string'\n    )\n  )\n}\n\nfunction escapeJsonObject(value: object): unknown {\n  return { [TAG]: ESCAPED, entries: Object.entries(value) }\n}\n\nfunction defineOwnValues(target: object, values: Array<readonly [string, unknown]>): void {\n  // Build the descriptors through Object.fromEntries so reserved keys such as\n  // __proto__ remain ordinary own data properties. Defining the batch avoids\n  // both prototype setters and individual writes through remote property names.\n  Object.defineProperties(\n    target,\n    Object.fromEntries(\n      values.map(([key, value]) => [\n        key,\n        {\n          value,\n          writable: true,\n          enumerable: true,\n          configurable: true\n        }\n      ])\n    )\n  )\n}\n\nfunction collectDecodedChild(\n  key: string,\n  child: unknown,\n  replacements: Array<readonly [string, unknown]>,\n  stack: object[]\n): void {\n  if (isTaggedBinary(child)) {\n    replacements.push([key, fromBase64(child.data)])\n  } else if (isEscapedJson(child)) {\n    const restored = Object.fromEntries(child.entries)\n    replacements.push([key, restored])\n    stack.push(restored)\n  } else if (child != null && typeof child === 'object') {\n    stack.push(child)\n  }\n}\n\nexport function binaryJsonReplacer(this: Record<string, unknown>, key: string, value: unknown): unknown {\n  if (value instanceof Uint8Array) return { [TAG]: BINARY_ENCODING, data: toBase64(value) }\n  if (value == null || typeof value !== 'object') return value\n  // Buffer.toJSON runs before a JSON replacer, but the holder still contains\n  // the original Buffer. Literal Buffer-JSON objects must remain ordinary data.\n  if (isBufferJson(value)) {\n    const original = this[key]\n    if (original instanceof Uint8Array) return { [TAG]: BINARY_ENCODING, data: toBase64(original) }\n    return escapeJsonObject(value)\n  }\n  if (isTaggedBinary(value) || isEscapedJson(value)) return escapeJsonObject(value)\n  return value\n}\n\nexport function legacyBinaryJsonReplacer(_key: string, value: unknown): unknown {\n  if (value instanceof Uint8Array) return Array.from(value)\n  return value\n}\n\nexport function binaryJsonReviver(_key: string, value: unknown): unknown {\n  if (isTaggedBinary(value)) return fromBase64(value.data)\n  if (isEscapedJson(value)) return Object.fromEntries(value.entries)\n  return value\n}\n\nexport function decodeBinaryJsonValue(value: unknown): unknown {\n  if (isTaggedBinary(value)) return fromBase64(value.data)\n  if (value == null || typeof value !== 'object') return value\n\n  // JSON can be nested far more deeply than the JavaScript call stack. Walk it\n  // iteratively so an authenticated peer cannot turn binary decoding into a\n  // recursion overflow.\n  const decoded = isEscapedJson(value) ? Object.fromEntries(value.entries) : value\n  const stack: object[] = [decoded]\n  while (stack.length > 0) {\n    const current = stack.pop()\n    if (current == null) continue\n    const replacements: Array<readonly [string, unknown]> = []\n    for (const [key, child] of Object.entries(current)) {\n      collectDecodedChild(key, child, replacements, stack)\n    }\n    if (replacements.length > 0) defineOwnValues(current, replacements)\n  }\n  return decoded\n}\n\nconst JSON_RPC_REPLACERS = new Map<boolean, typeof binaryJsonReplacer | typeof legacyBinaryJsonReplacer>([\n  [true, binaryJsonReplacer],\n  [false, legacyBinaryJsonReplacer]\n])\n\nexport function stringifyJsonRpc(value: unknown, binary: boolean): string {\n  return JSON.stringify(value, JSON_RPC_REPLACERS.get(binary))\n}\n\nconst JSON_RPC_REVIVERS = new Map<boolean, typeof binaryJsonReviver | undefined>([\n  [true, binaryJsonReviver],\n  [false, undefined]\n])\n\nexport function parseJsonRpc(text: string, binary: boolean = false): any {\n  return JSON.parse(text, JSON_RPC_REVIVERS.get(binary))\n}\n","import { WalletInterface } from '@bsv/sdk'\nimport { StorageClientBase, type StorageClientOptions } from './StorageClientBase'\nimport {\n  BINARY_ENCODING,\n  BINARY_ENCODING_HEADER,\n  BINARY_REQUEST_ENCODING_HEADER,\n  parseJsonRpc,\n  stringifyJsonRpc\n} from './BinaryJson'\n\n/**\n * `StorageClient` (mobile variant) implements the `WalletStorageProvider` interface which allows it to\n * serve as a BRC-100 wallet's active storage.\n *\n * Internally, it uses JSON-RPC over HTTPS to make requests of a remote server.\n * Typically this server uses the `StorageServer` class to implement the service.\n *\n * This mobile variant omits the full logger support present in `StorageClient` to keep\n * the bundle lean for mobile / browser environments.\n *\n * For details of the API implemented, follow the \"See also\" link for the `WalletStorageProvider` interface.\n */\nexport class StorageClient extends StorageClientBase {\n  constructor(wallet: WalletInterface, endpointUrl: string, options: StorageClientOptions = {}) {\n    super(wallet, endpointUrl, options)\n  }\n\n  /// ///////////////////////////////////////////////////////////////////////////\n  // JSON-RPC helper\n  /// ///////////////////////////////////////////////////////////////////////////\n\n  /**\n   * Make a JSON-RPC call to the remote server.\n   * @param method The WalletStorage method name to call.\n   * @param params The array of parameters to pass to the method in order.\n   */\n  protected async rpcCall<T>(method: string, params: unknown[]): Promise<T> {\n    return await this.traceRpcCall(method, params, async rpcSpan => {\n      const id = this.nextId++\n      const body = {\n        jsonrpc: '2.0',\n        method,\n        params,\n        id\n      }\n\n      const requestUsesBinary = this.binaryRequests && this.serverSupportsBinary\n      const requestBody = await this.traceRpcStep(\n        'wallet.storage.request.serialize',\n        rpcSpan,\n        () => stringifyJsonRpc(body, requestUsesBinary),\n        { 'rpc.encoding': requestUsesBinary ? 'binary-json' : 'json' }\n      )\n      const response = await this.traceRpcStep(\n        'wallet.storage.http',\n        rpcSpan,\n        async () =>\n          await this.authClient.fetch(this.endpointUrl, {\n            method: 'POST',\n            headers: {\n              'Content-Type': 'application/json',\n              [BINARY_ENCODING_HEADER]: BINARY_ENCODING,\n              ...(requestUsesBinary ? { [BINARY_REQUEST_ENCODING_HEADER]: BINARY_ENCODING } : {})\n            },\n            body: requestBody\n          }),\n        {\n          'http.request.method': 'POST',\n          'rpc.encoding': requestUsesBinary ? 'binary-json' : 'json'\n        }\n      )\n\n      if (!response.ok) {\n        throw new Error(`WalletStorageClient rpcCall: network error ${response.status} ${response.statusText}`)\n      }\n\n      const responseUsesBinary = response.headers.get(BINARY_ENCODING_HEADER) === BINARY_ENCODING\n      if (responseUsesBinary) this.serverSupportsBinary = true\n      const responseText = await this.traceRpcStep(\n        'wallet.storage.response.read',\n        rpcSpan,\n        async () => await response.text(),\n        {\n          'http.response.status_code': response.status,\n          'rpc.encoding': responseUsesBinary ? 'binary-json' : 'json'\n        }\n      )\n      const json = await this.traceRpcStep(\n        'wallet.storage.response.parse',\n        rpcSpan,\n        () => parseJsonRpc(responseText, responseUsesBinary),\n        {\n          'rpc.encoding': responseUsesBinary ? 'binary-json' : 'json',\n          'response.size_bytes': responseText.length\n        }\n      )\n      if (json.error) {\n        const { code, message, data } = json.error\n        const err = new Error(`RPC Error: ${message}`)\n        // You could attach more info here if you like:\n        ;(err as any).code = code\n        ;(err as any).data = data\n        throw err\n      }\n\n      rpcSpan?.end({\n        attributes: {\n          'http.response.status_code': response.status,\n          'rpc.encoding': responseUsesBinary ? 'binary-json' : 'json'\n        }\n      })\n      return json.result\n    })\n  }\n}\n","import argon2Api from 'hash-wasm/dist/argon2.umd.min.js'\nimport pbkdf2Api from 'hash-wasm/dist/pbkdf2.umd.min.js'\nimport sha256Api from 'hash-wasm/dist/sha256.umd.min.js'\nimport sha512Api from 'hash-wasm/dist/sha512.umd.min.js'\n\nexport const argon2id = argon2Api.argon2id\nexport const pbkdf2 = pbkdf2Api.pbkdf2\nexport const createSHA256 = sha256Api.createSHA256\nexport const createSHA512 = sha512Api.createSHA512\n","/* eslint-disable @typescript-eslint/triple-slash-reference */\n/// <reference path=\"../../types/bsv-sdk-aesgcm.d.ts\" />\n/* eslint-enable @typescript-eslint/triple-slash-reference */\n\nimport { Random, Utils } from '@bsv/sdk'\nimport { AESGCM, AESGCMDecrypt } from '@bsv/sdk/primitives/AESGCM'\nimport { argon2id } from '../../utility/hashWasm'\nimport { StorageProvider } from '../StorageProvider'\nimport {\n  TableCertificate,\n  TableCertificateField,\n  TableCommission,\n  TableOutput,\n  TableOutputBasket,\n  TableOutputTag,\n  TableOutputTagMap,\n  TableProvenTx,\n  TableProvenTxReq,\n  TableSettings,\n  TableSyncState,\n  TableTransaction,\n  TableTxLabel,\n  TableTxLabelMap,\n  TableUser\n} from '../schema/tables'\nimport { createSyncMap, SyncMap } from '../schema/entities/EntityBase'\nimport * as sdk from '../../sdk'\nimport { verifyOne, verifyOneOrNone, verifyTruthy } from '../../utility/utilityHelpers'\n\ntype JsonPrimitive = string | number | boolean\ntype JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue }\ntype PortableRow = Record<string, JsonValue>\n\nexport interface BRC38Tables {\n  provenTxs: PortableRow[]\n  provenTxReqs: PortableRow[]\n  outputBaskets: PortableRow[]\n  transactions: PortableRow[]\n  commissions: PortableRow[]\n  outputs: PortableRow[]\n  outputTags: PortableRow[]\n  outputTagMaps: PortableRow[]\n  txLabels: PortableRow[]\n  txLabelMaps: PortableRow[]\n  certificates: PortableRow[]\n  certificateFields: PortableRow[]\n  syncStates: PortableRow[]\n}\n\nexport interface BRC38WalletData {\n  brc: 38\n  title: 'User Wallet Data Format'\n  formatVersion: 1\n  exportedAt: string\n  sourceStorage: PortableRow\n  user: PortableRow\n  tables: BRC38Tables\n}\n\nexport interface BRC38ImportOptions {\n  mode: 'merge' | 'restore'\n}\n\nexport interface BRC38ImportResult {\n  mode: 'merge' | 'restore'\n  identityKey: string\n  userId: number\n  inserts: number\n  updates: number\n}\n\nexport interface BRC39Options {\n  iterations?: number\n  memoryKiB?: number\n  parallelism?: number\n}\n\ninterface DecodedBRC38 {\n  sourceStorage: TableSettings\n  user: TableUser\n  provenTxs: TableProvenTx[]\n  provenTxReqs: TableProvenTxReq[]\n  outputBaskets: TableOutputBasket[]\n  transactions: TableTransaction[]\n  commissions: TableCommission[]\n  outputs: TableOutput[]\n  outputTags: TableOutputTag[]\n  outputTagMaps: TableOutputTagMap[]\n  txLabels: TableTxLabel[]\n  txLabelMaps: TableTxLabelMap[]\n  certificates: TableCertificate[]\n  certificateFields: TableCertificateField[]\n  syncStates: TableSyncState[]\n}\n\nconst BRC38_TITLE = 'User Wallet Data Format'\nconst BRC39_MAGIC = [0x57, 0x44, 0x41, 0x54] // WDAT\nconst BRC39_HEADER_LENGTH = 33\nconst BRC39_TAG_LENGTH = 16\nconst BRC39_DEFAULT_ITERATIONS = 7\nconst BRC39_DEFAULT_MEMORY_KIB = 131072\nconst BRC39_DEFAULT_PARALLELISM = 1\nconst BRC39_HASH_LENGTH = 32\nconst BRC39_SALT_LENGTH = 32\nconst BRC39_NONCE_LENGTH = 32\n\nconst tableNames: Array<keyof BRC38Tables> = [\n  'provenTxs',\n  'provenTxReqs',\n  'outputBaskets',\n  'transactions',\n  'commissions',\n  'outputs',\n  'outputTags',\n  'outputTagMaps',\n  'txLabels',\n  'txLabelMaps',\n  'certificates',\n  'certificateFields',\n  'syncStates'\n]\n\nconst SYNC_CHUNK_ENTITY_ORDER = [\n  'provenTx',\n  'outputBasket',\n  'outputTag',\n  'txLabel',\n  'transaction',\n  'output',\n  'txLabelMap',\n  'outputTagMap',\n  'certificate',\n  'certificateField',\n  'commission',\n  'provenTxReq'\n]\n\nconst binaryFieldsByKind: Partial<Record<string, string[]>> = {\n  commission: ['lockingScript'],\n  output: ['lockingScript'],\n  provenTx: ['merklePath', 'rawTx'],\n  provenTxReq: ['rawTx', 'inputBEEF'],\n  transaction: ['inputBEEF', 'rawTx']\n}\n\nconst jsonFieldsByKind: Partial<Record<string, string[]>> = {\n  provenTxReq: ['history', 'notify'],\n  syncState: ['syncMap', 'errorLocal', 'errorOther']\n}\n\nconst dateFieldsByKind: Partial<Record<string, string[]>> = {\n  settings: ['created_at', 'updated_at'],\n  user: ['created_at', 'updated_at'],\n  provenTx: ['created_at', 'updated_at'],\n  provenTxReq: ['created_at', 'updated_at'],\n  outputBasket: ['created_at', 'updated_at'],\n  transaction: ['created_at', 'updated_at'],\n  commission: ['created_at', 'updated_at'],\n  output: ['created_at', 'updated_at'],\n  outputTag: ['created_at', 'updated_at'],\n  outputTagMap: ['created_at', 'updated_at'],\n  txLabel: ['created_at', 'updated_at'],\n  txLabelMap: ['created_at', 'updated_at'],\n  certificate: ['created_at', 'updated_at'],\n  certificateField: ['created_at', 'updated_at'],\n  syncState: ['created_at', 'updated_at', 'when']\n}\n\nexport async function exportBRC38 (storage: StorageProvider, identityKey: string): Promise<BRC38WalletData> {\n  const sourceStorage = await storage.makeAvailable()\n  const user = verifyTruthy(await storage.findUserByIdentityKey(identityKey))\n  const userId = user.userId\n\n  const transactions = await storage.findTransactions({ partial: { userId } })\n  const transactionIds = new Set(transactions.map(t => t.transactionId))\n  const transactionTxids = new Set(transactions.map(t => t.txid).filter((txid): txid is string => txid != null))\n\n  const provenTxReqs = (await storage.getProvenTxReqsForUser({ userId })).filter(r => transactionTxids.has(r.txid))\n  const provenTxIds = new Set<number>()\n  for (const tx of transactions) if (tx.provenTxId != null) provenTxIds.add(tx.provenTxId)\n  for (const req of provenTxReqs) if (req.provenTxId != null) provenTxIds.add(req.provenTxId)\n\n  const provenTxs: TableProvenTx[] = []\n  for (const provenTxId of Array.from(provenTxIds).sort(compareNumber)) {\n    const proven = verifyOneOrNone(await storage.findProvenTxs({ partial: { provenTxId } }))\n    if (proven != null) provenTxs.push(proven)\n  }\n\n  const outputBaskets = await storage.findOutputBaskets({ partial: { userId } })\n  const commissions = await storage.findCommissions({ partial: { userId } })\n  const outputs = await storage.findOutputs({ partial: { userId } })\n  const outputTags = await storage.findOutputTags({ partial: { userId } })\n  const outputTagMaps = (await storage.getOutputTagMapsForUser({ userId }))\n    .filter(m => outputs.some(o => o.outputId === m.outputId))\n  const txLabels = await storage.findTxLabels({ partial: { userId } })\n  const txLabelMaps = (await storage.getTxLabelMapsForUser({ userId }))\n    .filter(m => transactionIds.has(m.transactionId))\n  const certificates = await storage.findCertificates({ partial: { userId } })\n  const certificateFields = await storage.findCertificateFields({ partial: { userId } })\n  const syncStates = await storage.findSyncStates({ partial: { userId } })\n\n  const data: BRC38WalletData = {\n    brc: 38,\n    title: BRC38_TITLE,\n    formatVersion: 1,\n    exportedAt: isoDate(new Date()),\n    sourceStorage: portableRow('settings', sourceStorage),\n    user: portableRow('user', user),\n    tables: {\n      provenTxs: provenTxs.map(r => portableRow('provenTx', r)),\n      provenTxReqs: provenTxReqs.map(r => portableRow('provenTxReq', r)),\n      outputBaskets: outputBaskets.map(r => portableRow('outputBasket', r)),\n      transactions: transactions.map(r => portableRow('transaction', r)),\n      commissions: commissions.map(r => portableRow('commission', r)),\n      outputs: outputs.map(r => portableRow('output', r)),\n      outputTags: outputTags.map(r => portableRow('outputTag', r)),\n      outputTagMaps: outputTagMaps.map(r => portableRow('outputTagMap', r)),\n      txLabels: txLabels.map(r => portableRow('txLabel', r)),\n      txLabelMaps: txLabelMaps.map(r => portableRow('txLabelMap', r)),\n      certificates: certificates.map(r => {\n        const row = portableRow('certificate', r)\n        delete row.fields\n        return row\n      }),\n      certificateFields: certificateFields.map(r => portableRow('certificateField', r)),\n      syncStates: syncStates.map(r => portableRow('syncState', r))\n    }\n  }\n\n  sortBRC38Tables(data.tables)\n  validateBRC38(data)\n  return data\n}\n\nexport async function exportBRC38Json (storage: StorageProvider, identityKey: string): Promise<string> {\n  return canonicalize(await exportBRC38(storage, identityKey))\n}\n\nexport function parseBRC38Json (json: string): BRC38WalletData {\n  let data: unknown\n  try {\n    data = JSON.parse(json)\n  } catch (e) {\n    throw new Error(`Invalid BRC-38 JSON: ${(e as Error).message}`)\n  }\n  return validateBRC38(data)\n}\n\nexport async function importBRC38 (\n  storage: StorageProvider,\n  documentOrJson: BRC38WalletData | string,\n  options: BRC38ImportOptions\n): Promise<BRC38ImportResult> {\n  const data = typeof documentOrJson === 'string' ? parseBRC38Json(documentOrJson) : validateBRC38(documentOrJson)\n  const targetSettings = await storage.makeAvailable()\n  const decoded = decodeBRC38(data)\n  if (decoded.sourceStorage.chain !== targetSettings.chain) {\n    throw new Error(`BRC-38 chain mismatch: payload is ${decoded.sourceStorage.chain}, target is ${targetSettings.chain}`)\n  }\n  if (options.mode === 'restore') return await restoreBRC38(storage, decoded)\n  if (options.mode === 'merge') return await mergeBRC38(storage, decoded, targetSettings)\n  throw new Error(`Unsupported BRC-38 import mode: ${String((options as { mode?: unknown }).mode)}`)\n}\n\nexport async function exportBRC39 (\n  storage: StorageProvider,\n  identityKey: string,\n  password: string,\n  options?: BRC39Options\n): Promise<number[]> {\n  return await encryptBRC39(await exportBRC38(storage, identityKey), password, options)\n}\n\nexport async function importBRC39 (\n  storage: StorageProvider,\n  bytes: number[] | Uint8Array,\n  password: string,\n  options: BRC38ImportOptions\n): Promise<BRC38ImportResult> {\n  return await importBRC38(storage, await decryptBRC39(bytes, password), options)\n}\n\nexport async function encryptBRC39 (\n  documentOrJson: BRC38WalletData | string,\n  password: string,\n  options?: BRC39Options\n): Promise<number[]> {\n  const data = typeof documentOrJson === 'string' ? parseBRC38Json(documentOrJson) : validateBRC38(documentOrJson)\n  const plaintext = new Uint8Array(Utils.toArray(canonicalize(data), 'utf8'))\n  const salt = new Uint8Array(Random(BRC39_SALT_LENGTH))\n  const nonce = new Uint8Array(Random(BRC39_NONCE_LENGTH))\n  const iterations = options?.iterations ?? BRC39_DEFAULT_ITERATIONS\n  const memoryKiB = options?.memoryKiB ?? BRC39_DEFAULT_MEMORY_KIB\n  const parallelism = options?.parallelism ?? BRC39_DEFAULT_PARALLELISM\n  validateKdfParams(iterations, memoryKiB, parallelism, BRC39_HASH_LENGTH)\n  validateExportKdfParams(iterations, memoryKiB)\n  const key = await deriveBRC39Key(password, salt, iterations, memoryKiB, parallelism)\n  const { result, authenticationTag } = AESGCM(plaintext, nonce, key)\n  const header = new Uint8Array(BRC39_HEADER_LENGTH + salt.length + nonce.length)\n  header.set(BRC39_MAGIC, 0)\n  header[4] = 1\n  header[5] = 1\n  header[6] = 38\n  header[7] = 1\n  header[8] = 0\n  header[9] = salt.length\n  header[10] = nonce.length\n  writeUInt32BE(header, 11, iterations)\n  writeUInt32BE(header, 15, memoryKiB)\n  header[19] = parallelism\n  header[20] = BRC39_HASH_LENGTH\n  header.set(salt, BRC39_HEADER_LENGTH)\n  header.set(nonce, BRC39_HEADER_LENGTH + salt.length)\n  return Array.from(concatBytes(header, result, authenticationTag))\n}\n\ninterface BRC39Header {\n  saltLength: number\n  nonceLength: number\n  iterations: number\n  memoryKiB: number\n  parallelism: number\n  hashLength: number\n}\n\nfunction parseBRC39Header (file: Uint8Array): BRC39Header {\n  if (file.length < BRC39_HEADER_LENGTH + BRC39_TAG_LENGTH + 2) throw new Error('Invalid BRC-39 file: too short')\n  for (let i = 0; i < BRC39_MAGIC.length; i++) {\n    if (file[i] !== BRC39_MAGIC[i]) throw new Error('Invalid BRC-39 file: bad magic')\n  }\n  assertHeaderConstants(file)\n  for (let i = 21; i < BRC39_HEADER_LENGTH; i++) {\n    if (file[i] !== 0) throw new Error('Invalid BRC-39 reserved bytes')\n  }\n  const saltLength = file[9]\n  const nonceLength = file[10]\n  if (saltLength === 0) throw new Error('Invalid BRC-39 salt length')\n  if (nonceLength === 0) throw new Error('Invalid BRC-39 nonce length')\n  const iterations = readUInt32BE(file, 11)\n  const memoryKiB = readUInt32BE(file, 15)\n  const parallelism = file[19]\n  const hashLength = file[20]\n  validateKdfParams(iterations, memoryKiB, parallelism, hashLength)\n  return { saltLength, nonceLength, iterations, memoryKiB, parallelism, hashLength }\n}\n\nfunction assertHeaderConstants (file: Uint8Array): void {\n  if (file[4] !== 1) throw new Error('Unsupported BRC-39 format version')\n  if (file[5] !== 1) throw new Error('Unsupported BRC-39 protector type')\n  if (file[6] !== 38) throw new Error('Unsupported BRC-39 inner format')\n  if (file[7] !== 1) throw new Error('Unsupported BRC-39 KDF type')\n  if (file[8] !== 0) throw new Error('Invalid BRC-39 flags')\n}\n\nexport async function decryptBRC39 (bytes: number[] | Uint8Array, password: string): Promise<BRC38WalletData> {\n  const file = new Uint8Array(bytes)\n  const header = parseBRC39Header(file)\n  const payloadStart = BRC39_HEADER_LENGTH + header.saltLength + header.nonceLength\n  if (file.length <= payloadStart + BRC39_TAG_LENGTH) throw new Error('Invalid BRC-39 ciphertext')\n  const salt = file.slice(BRC39_HEADER_LENGTH, BRC39_HEADER_LENGTH + header.saltLength)\n  const nonce = file.slice(BRC39_HEADER_LENGTH + header.saltLength, payloadStart)\n  const ciphertext = file.slice(payloadStart, file.length - BRC39_TAG_LENGTH)\n  const tag = file.slice(file.length - BRC39_TAG_LENGTH)\n  const key = await deriveBRC39Key(password, salt, header.iterations, header.memoryKiB, header.parallelism)\n  const plaintext = AESGCMDecrypt(ciphertext, nonce, tag, key)\n  if (plaintext == null) throw new Error('BRC-39 authentication failed')\n  return parseBRC38Json(Utils.toUTF8(Array.from(plaintext)))\n}\n\nfunction validateBRC38 (value: unknown): BRC38WalletData {\n  rejectNulls(value, 'document')\n  if (!isObject(value)) throw new Error('BRC-38 document must be an object')\n  const data = value as unknown as BRC38WalletData\n  if (data.brc !== 38) throw new Error('BRC-38 document brc must equal 38')\n  if (data.title !== BRC38_TITLE) throw new Error('BRC-38 title must equal User Wallet Data Format')\n  if (data.formatVersion !== 1) throw new Error('BRC-38 formatVersion must equal 1')\n  assertIsoDate(data.exportedAt, 'exportedAt')\n  if (!isObject(data.sourceStorage)) throw new Error('BRC-38 sourceStorage must be an object')\n  if (!isObject(data.user)) throw new Error('BRC-38 user must be an object')\n  if (!isObject(data.tables)) throw new Error('BRC-38 tables must be an object')\n  for (const name of tableNames) {\n    if (!Array.isArray(data.tables[name])) throw new Error(`BRC-38 tables.${name} must be an array`)\n  }\n  validatePortableRows('settings', [data.sourceStorage], 'sourceStorage')\n  validatePortableRows('user', [data.user], 'user')\n  validatePortableRows('provenTx', data.tables.provenTxs, 'provenTxs')\n  validatePortableRows('provenTxReq', data.tables.provenTxReqs, 'provenTxReqs')\n  validatePortableRows('outputBasket', data.tables.outputBaskets, 'outputBaskets')\n  validatePortableRows('transaction', data.tables.transactions, 'transactions')\n  validatePortableRows('commission', data.tables.commissions, 'commissions')\n  validatePortableRows('output', data.tables.outputs, 'outputs')\n  validatePortableRows('outputTag', data.tables.outputTags, 'outputTags')\n  validatePortableRows('outputTagMap', data.tables.outputTagMaps, 'outputTagMaps')\n  validatePortableRows('txLabel', data.tables.txLabels, 'txLabels')\n  validatePortableRows('txLabelMap', data.tables.txLabelMaps, 'txLabelMaps')\n  validatePortableRows('certificate', data.tables.certificates, 'certificates')\n  validatePortableRows('certificateField', data.tables.certificateFields, 'certificateFields')\n  validatePortableRows('syncState', data.tables.syncStates, 'syncStates')\n  validateRelationships(data)\n  return data\n}\n\nfunction decodeBRC38 (data: BRC38WalletData): DecodedBRC38 {\n  return {\n    sourceStorage: fromPortableRow<TableSettings>('settings', data.sourceStorage),\n    user: fromPortableRow<TableUser>('user', data.user),\n    provenTxs: data.tables.provenTxs.map(r => fromPortableRow<TableProvenTx>('provenTx', r)),\n    provenTxReqs: data.tables.provenTxReqs.map(r => fromPortableRow<TableProvenTxReq>('provenTxReq', r)),\n    outputBaskets: data.tables.outputBaskets.map(r => fromPortableRow<TableOutputBasket>('outputBasket', r)),\n    transactions: data.tables.transactions.map(r => fromPortableRow<TableTransaction>('transaction', r)),\n    commissions: data.tables.commissions.map(r => fromPortableRow<TableCommission>('commission', r)),\n    outputs: data.tables.outputs.map(r => fromPortableRow<TableOutput>('output', r)),\n    outputTags: data.tables.outputTags.map(r => fromPortableRow<TableOutputTag>('outputTag', r)),\n    outputTagMaps: data.tables.outputTagMaps.map(r => fromPortableRow<TableOutputTagMap>('outputTagMap', r)),\n    txLabels: data.tables.txLabels.map(r => fromPortableRow<TableTxLabel>('txLabel', r)),\n    txLabelMaps: data.tables.txLabelMaps.map(r => fromPortableRow<TableTxLabelMap>('txLabelMap', r)),\n    certificates: data.tables.certificates.map(r => fromPortableRow<TableCertificate>('certificate', r)),\n    certificateFields: data.tables.certificateFields.map(r => fromPortableRow<TableCertificateField>('certificateField', r)),\n    syncStates: data.tables.syncStates.map(r => fromPortableRow<TableSyncState>('syncState', r))\n  }\n}\n\nasync function restoreBRC38 (storage: StorageProvider, data: DecodedBRC38): Promise<BRC38ImportResult> {\n  await assertRestoreTargetEmpty(storage)\n  await storage.transaction(async trx => {\n    await storage.insertUser({ ...data.user }, trx)\n    for (const row of data.provenTxs) await storage.insertProvenTx({ ...row }, trx)\n    for (const row of data.outputBaskets) await storage.insertOutputBasket({ ...row }, trx)\n    for (const row of data.outputTags) await storage.insertOutputTag({ ...row }, trx)\n    for (const row of data.txLabels) await storage.insertTxLabel({ ...row }, trx)\n    for (const row of data.transactions) await storage.insertTransaction({ ...row }, trx)\n    for (const row of data.outputs) await storage.insertOutput({ ...row }, trx)\n    for (const row of data.txLabelMaps) await storage.insertTxLabelMap({ ...row }, trx)\n    for (const row of data.outputTagMaps) await storage.insertOutputTagMap({ ...row }, trx)\n    for (const row of data.certificates) await storage.insertCertificate({ ...row }, trx)\n    for (const row of data.certificateFields) await storage.insertCertificateField({ ...row }, trx)\n    for (const row of data.commissions) await storage.insertCommission({ ...row }, trx)\n    for (const row of data.provenTxReqs) await storage.insertProvenTxReq({ ...row }, trx)\n    for (const row of data.syncStates) await storage.insertSyncState({ ...row }, trx)\n  })\n  return {\n    mode: 'restore',\n    identityKey: data.user.identityKey,\n    userId: data.user.userId,\n    inserts: 1 + countDecodedRows(data),\n    updates: 0\n  }\n}\n\nasync function mergeBRC38 (\n  storage: StorageProvider,\n  data: DecodedBRC38,\n  targetSettings: TableSettings\n): Promise<BRC38ImportResult> {\n  const { user: targetUser } = await storage.findOrInsertUser(data.user.identityKey)\n  await storage.findOrInsertSyncStateAuth(\n    { identityKey: data.user.identityKey, userId: targetUser.userId },\n    data.sourceStorage.storageIdentityKey,\n    data.sourceStorage.storageName\n  )\n  const chunk: sdk.SyncChunk = {\n    fromStorageIdentityKey: data.sourceStorage.storageIdentityKey,\n    toStorageIdentityKey: targetSettings.storageIdentityKey,\n    userIdentityKey: data.user.identityKey,\n    user: { ...data.user, activeStorage: targetUser.activeStorage },\n    provenTxs: data.provenTxs.map(r => ({ ...r })),\n    outputBaskets: data.outputBaskets.map(r => ({ ...r })),\n    outputTags: data.outputTags.map(r => ({ ...r })),\n    txLabels: data.txLabels.map(r => ({ ...r })),\n    transactions: data.transactions.map(r => ({ ...r })),\n    outputs: data.outputs.map(r => ({ ...r })),\n    txLabelMaps: data.txLabelMaps.map(r => ({ ...r })),\n    outputTagMaps: data.outputTagMaps.map(r => ({ ...r })),\n    certificates: data.certificates.map(r => ({ ...r })),\n    certificateFields: data.certificateFields.map(r => ({ ...r })),\n    commissions: data.commissions.map(r => ({ ...r })),\n    provenTxReqs: data.provenTxReqs.map(r => ({ ...r }))\n  }\n  const args = {\n    fromStorageIdentityKey: chunk.fromStorageIdentityKey,\n    toStorageIdentityKey: chunk.toStorageIdentityKey,\n    identityKey: data.user.identityKey,\n    maxRoughSize: Number.MAX_SAFE_INTEGER,\n    maxItems: Number.MAX_SAFE_INTEGER,\n    offsets: SYNC_CHUNK_ENTITY_ORDER.map(name => ({ name, offset: 0 }))\n  }\n  const first = await storage.processSyncChunk(args, chunk)\n  const done = await storage.processSyncChunk(args, {\n    fromStorageIdentityKey: chunk.fromStorageIdentityKey,\n    toStorageIdentityKey: chunk.toStorageIdentityKey,\n    userIdentityKey: data.user.identityKey,\n    provenTxs: [],\n    outputBaskets: [],\n    outputTags: [],\n    txLabels: [],\n    transactions: [],\n    outputs: [],\n    txLabelMaps: [],\n    outputTagMaps: [],\n    certificates: [],\n    certificateFields: [],\n    commissions: [],\n    provenTxReqs: []\n  })\n  const currentSyncState = verifyOne(\n    await storage.findSyncStates({\n      partial: {\n        userId: targetUser.userId,\n        storageIdentityKey: data.sourceStorage.storageIdentityKey,\n        storageName: data.sourceStorage.storageName\n      }\n    })\n  )\n  const importMap = normalizeSyncMap(JSON.parse(currentSyncState.syncMap))\n  const syncStateResult = await mergeImportedSyncStates(\n    storage,\n    data.syncStates,\n    targetUser.userId,\n    importMap,\n    data.sourceStorage\n  )\n  return {\n    mode: 'merge',\n    identityKey: data.user.identityKey,\n    userId: targetUser.userId,\n    inserts: first.inserts + done.inserts + syncStateResult.inserts,\n    updates: first.updates + done.updates + syncStateResult.updates\n  }\n}\n\nasync function mergeImportedSyncStates (\n  storage: StorageProvider,\n  syncStates: TableSyncState[],\n  userId: number,\n  importMap: SyncMap,\n  sourceStorage: TableSettings\n): Promise<{ inserts: number, updates: number }> {\n  let inserts = 0\n  let updates = 0\n  for (const source of syncStates) {\n    const row: TableSyncState = {\n      ...source,\n      userId,\n      syncMap: JSON.stringify(remapSyncMap(JSON.parse(source.syncMap), importMap))\n    }\n    const existing = verifyOneOrNone(\n      await storage.findSyncStates({\n        partial: {\n          userId,\n          storageIdentityKey: row.storageIdentityKey,\n          storageName: row.storageName\n        }\n      })\n    )\n    if (existing == null) {\n      row.syncStateId = 0\n      await storage.insertSyncState(row)\n      inserts++\n    } else {\n      row.syncStateId = existing.syncStateId\n      if (\n        row.storageIdentityKey === sourceStorage.storageIdentityKey &&\n        row.storageName === sourceStorage.storageName\n      ) {\n        row.syncMap = existing.syncMap\n      }\n      await storage.updateSyncState(existing.syncStateId, row)\n      updates++\n    }\n  }\n  return { inserts, updates }\n}\n\nfunction remapSyncMap (source: unknown, importMap: SyncMap): SyncMap {\n  const copy = normalizeSyncMap(source)\n  remapEntityIdMap(copy.provenTx.idMap, importMap.provenTx.idMap)\n  remapEntityIdMap(copy.outputBasket.idMap, importMap.outputBasket.idMap)\n  remapEntityIdMap(copy.transaction.idMap, importMap.transaction.idMap)\n  remapEntityIdMap(copy.provenTxReq.idMap, importMap.provenTxReq.idMap)\n  remapEntityIdMap(copy.txLabel.idMap, importMap.txLabel.idMap)\n  remapEntityIdMap(copy.output.idMap, importMap.output.idMap)\n  remapEntityIdMap(copy.outputTag.idMap, importMap.outputTag.idMap)\n  remapEntityIdMap(copy.certificate.idMap, importMap.certificate.idMap)\n  remapEntityIdMap(copy.commission.idMap, importMap.commission.idMap)\n  return copy\n}\n\nfunction normalizeSyncMap (source: unknown): SyncMap {\n  const normalized = createSyncMap()\n  if (!isObject(source)) return normalized\n  for (const key of Object.keys(normalized) as Array<keyof SyncMap>) {\n    const incoming = source[key]\n    if (isObject(incoming)) mergeSyncMapEntry(normalized[key], incoming)\n  }\n  return normalized\n}\n\nfunction mergeSyncMapEntry (target: SyncMap[keyof SyncMap], incoming: Record<string, unknown>): void {\n  if (typeof incoming.entityName === 'string') target.entityName = incoming.entityName\n  if (Number.isInteger(incoming.count)) target.count = incoming.count as number\n  if (isObject(incoming.idMap)) target.idMap = parseIdMap(incoming.idMap)\n  applyMaxUpdatedAt(target, incoming.maxUpdated_at)\n}\n\nfunction parseIdMap (incoming: Record<string, unknown>): Record<number, number> {\n  const idMap: Record<number, number> = {}\n  for (const [remoteId, localId] of Object.entries(incoming)) {\n    const parsedRemoteId = Number(remoteId)\n    if (Number.isInteger(parsedRemoteId) && Number.isInteger(localId)) {\n      idMap[parsedRemoteId] = localId as number\n    }\n  }\n  return idMap\n}\n\nfunction applyMaxUpdatedAt (target: SyncMap[keyof SyncMap], value: unknown): void {\n  if (typeof value === 'string') {\n    const maxUpdatedAt = new Date(value)\n    if (!Number.isNaN(maxUpdatedAt.getTime())) target.maxUpdated_at = maxUpdatedAt\n  } else if (value instanceof Date) {\n    target.maxUpdated_at = value\n  }\n}\n\nfunction remapEntityIdMap (idMap: Record<number, number>, importIdMap: Record<number, number>): void {\n  for (const key of Object.keys(idMap)) {\n    const targetId = importIdMap[idMap[Number(key)]]\n    if (targetId != null) idMap[Number(key)] = targetId\n  }\n}\n\nasync function assertRestoreTargetEmpty (storage: StorageProvider): Promise<void> {\n  const counts = await Promise.all([\n    storage.countUsers({ partial: {} }),\n    storage.countProvenTxs({ partial: {} }),\n    storage.countProvenTxReqs({ partial: {} }),\n    storage.countOutputBaskets({ partial: {} }),\n    storage.countTransactions({ partial: {} }),\n    storage.countCommissions({ partial: {} }),\n    storage.countOutputs({ partial: {} }),\n    storage.countOutputTags({ partial: {} }),\n    storage.countOutputTagMaps({ partial: {} }),\n    storage.countTxLabels({ partial: {} }),\n    storage.countTxLabelMaps({ partial: {} }),\n    storage.countCertificates({ partial: {} }),\n    storage.countCertificateFields({ partial: {} }),\n    storage.countSyncStates({ partial: {} }),\n    storage.countMonitorEvents({ partial: {} })\n  ])\n  if (counts.some(c => c > 0)) throw new Error('BRC-38 restore requires an empty target storage except settings')\n}\n\nfunction countDecodedRows (data: DecodedBRC38): number {\n  return data.provenTxs.length + data.provenTxReqs.length + data.outputBaskets.length + data.transactions.length +\n    data.commissions.length + data.outputs.length + data.outputTags.length + data.outputTagMaps.length +\n    data.txLabels.length + data.txLabelMaps.length + data.certificates.length + data.certificateFields.length +\n    data.syncStates.length\n}\n\ninterface RelationshipIndex {\n  userId: number\n  txIds: Set<number>\n  txidValues: Set<string>\n  provenTxIds: Set<number>\n  basketIds: Set<number>\n  outputIds: Set<number>\n  outputTagIds: Set<number>\n  txLabelIds: Set<number>\n  certificateIds: Set<number>\n}\n\nfunction buildRelationshipIndex (data: BRC38WalletData): RelationshipIndex {\n  return {\n    userId: requireNumber(data.user.userId, 'user.userId'),\n    txIds: ids(data.tables.transactions, 'transactionId', 'transactions'),\n    txidValues: new Set(data.tables.transactions.map(t => t.txid).filter((v): v is string => typeof v === 'string')),\n    provenTxIds: ids(data.tables.provenTxs, 'provenTxId', 'provenTxs'),\n    basketIds: ids(data.tables.outputBaskets, 'basketId', 'outputBaskets'),\n    outputIds: ids(data.tables.outputs, 'outputId', 'outputs'),\n    outputTagIds: ids(data.tables.outputTags, 'outputTagId', 'outputTags'),\n    txLabelIds: ids(data.tables.txLabels, 'txLabelId', 'txLabels'),\n    certificateIds: ids(data.tables.certificates, 'certificateId', 'certificates')\n  }\n}\n\nfunction requireRef (set: Set<number>, value: unknown, path: string, message: string): void {\n  if (!set.has(requireNumber(value, path))) throw new Error(message)\n}\n\nfunction validateTransactions (data: BRC38WalletData, idx: RelationshipIndex): void {\n  for (const row of data.tables.transactions) {\n    requireUserId(row, idx.userId, 'transactions')\n    if (row.provenTxId != null) {\n      requireRef(idx.provenTxIds, row.provenTxId, 'transaction.provenTxId',\n        'BRC-38 transaction.provenTxId does not reference an exported provenTx')\n    }\n  }\n}\n\nfunction validateOutputs (data: BRC38WalletData, idx: RelationshipIndex): void {\n  for (const row of data.tables.outputs) {\n    requireUserId(row, idx.userId, 'outputs')\n    requireRef(idx.txIds, row.transactionId, 'output.transactionId',\n      'BRC-38 output.transactionId does not reference an exported transaction')\n    if (row.basketId != null) {\n      requireRef(idx.basketIds, row.basketId, 'output.basketId',\n        'BRC-38 output.basketId does not reference an exported output basket')\n    }\n    if (row.spentBy != null) {\n      requireRef(idx.txIds, row.spentBy, 'output.spentBy',\n        'BRC-38 output.spentBy does not reference an exported transaction')\n    }\n  }\n}\n\nfunction validateCommissions (data: BRC38WalletData, idx: RelationshipIndex): void {\n  for (const row of data.tables.commissions) {\n    requireUserId(row, idx.userId, 'commissions')\n    requireRef(idx.txIds, row.transactionId, 'commission.transactionId',\n      'BRC-38 commission.transactionId does not reference an exported transaction')\n  }\n}\n\nfunction validateTxLabelMaps (data: BRC38WalletData, idx: RelationshipIndex): void {\n  for (const row of data.tables.txLabelMaps) {\n    requireRef(idx.txIds, row.transactionId, 'txLabelMap.transactionId',\n      'BRC-38 txLabelMap.transactionId does not reference an exported transaction')\n    requireRef(idx.txLabelIds, row.txLabelId, 'txLabelMap.txLabelId',\n      'BRC-38 txLabelMap.txLabelId does not reference an exported transaction label')\n  }\n}\n\nfunction validateOutputTagMaps (data: BRC38WalletData, idx: RelationshipIndex): void {\n  for (const row of data.tables.outputTagMaps) {\n    requireRef(idx.outputIds, row.outputId, 'outputTagMap.outputId',\n      'BRC-38 outputTagMap.outputId does not reference an exported output')\n    requireRef(idx.outputTagIds, row.outputTagId, 'outputTagMap.outputTagId',\n      'BRC-38 outputTagMap.outputTagId does not reference an exported output tag')\n  }\n}\n\nfunction validateCertificateFields (data: BRC38WalletData, idx: RelationshipIndex): void {\n  for (const row of data.tables.certificateFields) {\n    requireUserId(row, idx.userId, 'certificateFields')\n    requireRef(idx.certificateIds, row.certificateId, 'certificateField.certificateId',\n      'BRC-38 certificateField.certificateId does not reference an exported certificate')\n  }\n}\n\nfunction validateProvenTxReqs (data: BRC38WalletData, idx: RelationshipIndex): void {\n  for (const row of data.tables.provenTxReqs) {\n    if (!idx.txidValues.has(requireString(row.txid, 'provenTxReq.txid'))) {\n      throw new Error('BRC-38 provenTxReq.txid does not match an exported transaction')\n    }\n    if (row.provenTxId != null) {\n      requireRef(idx.provenTxIds, row.provenTxId, 'provenTxReq.provenTxId',\n        'BRC-38 provenTxReq.provenTxId does not reference an exported provenTx')\n    }\n  }\n}\n\nfunction validateRelationships (data: BRC38WalletData): void {\n  const idx = buildRelationshipIndex(data)\n  validateTransactions(data, idx)\n  for (const row of data.tables.outputBaskets) requireUserId(row, idx.userId, 'outputBaskets')\n  for (const row of data.tables.outputTags) requireUserId(row, idx.userId, 'outputTags')\n  for (const row of data.tables.txLabels) requireUserId(row, idx.userId, 'txLabels')\n  for (const row of data.tables.certificates) requireUserId(row, idx.userId, 'certificates')\n  for (const row of data.tables.syncStates) requireUserId(row, idx.userId, 'syncStates')\n  validateOutputs(data, idx)\n  validateCommissions(data, idx)\n  validateTxLabelMaps(data, idx)\n  validateOutputTagMaps(data, idx)\n  validateCertificateFields(data, idx)\n  validateProvenTxReqs(data, idx)\n}\n\nfunction validatePortableRows (kind: string, rows: PortableRow[], path: string): void {\n  const dateFields = new Set(dateFieldsByKind[kind] ?? [])\n  const binaryFields = new Set(binaryFieldsByKind[kind] ?? [])\n  const jsonFields = new Set(jsonFieldsByKind[kind] ?? [])\n  for (const [index, row] of rows.entries()) {\n    validatePortableRow(row, `${path}[${index}]`, dateFields, binaryFields, jsonFields)\n  }\n}\n\nfunction validatePortableRow (\n  row: PortableRow,\n  rowPath: string,\n  dateFields: Set<string>,\n  binaryFields: Set<string>,\n  jsonFields: Set<string>\n): void {\n  if (!isObject(row)) throw new Error(`BRC-38 ${rowPath} must be an object`)\n  for (const field of dateFields) {\n    if (field in row) assertIsoDate(row[field], `${rowPath}.${field}`)\n  }\n  for (const field of binaryFields) {\n    if (field in row) assertBase64(row[field], `${rowPath}.${field}`)\n  }\n  for (const field of jsonFields) {\n    if (field in row && !isObject(row[field])) throw new Error(`BRC-38 ${rowPath}.${field} must be an object`)\n  }\n}\n\nfunction portableRow (kind: string, row: object): PortableRow {\n  const out: PortableRow = {}\n  const binaryFields = new Set(binaryFieldsByKind[kind] ?? [])\n  const jsonFields = new Set(jsonFieldsByKind[kind] ?? [])\n  for (const [key, value] of Object.entries(row)) {\n    if (value == null) continue\n    if (key === 'logger') continue\n    if (binaryFields.has(key)) {\n      out[key] = Utils.toBase64(value as number[])\n    } else if (jsonFields.has(key)) {\n      out[key] = typeof value === 'string' ? JSON.parse(value) as JsonValue : value as JsonValue\n    } else if (value instanceof Date) {\n      out[key] = isoDate(value)\n    } else {\n      out[key] = value as JsonValue\n    }\n  }\n  return out\n}\n\nfunction fromPortableRow<T> (kind: string, row: PortableRow): T {\n  const out: Record<string, unknown> = {}\n  const dateFields = new Set(dateFieldsByKind[kind] ?? [])\n  const binaryFields = new Set(binaryFieldsByKind[kind] ?? [])\n  const jsonFields = new Set(jsonFieldsByKind[kind] ?? [])\n  for (const [key, value] of Object.entries(row)) {\n    if (dateFields.has(key)) out[key] = new Date(value as string)\n    else if (binaryFields.has(key)) out[key] = Utils.toArray(value, 'base64')\n    else if (jsonFields.has(key)) out[key] = JSON.stringify(value)\n    else out[key] = value\n  }\n  return out as T\n}\n\nfunction sortBRC38Tables (tables: BRC38Tables): void {\n  tables.provenTxs.sort(byNumber('provenTxId'))\n  tables.provenTxReqs.sort(byNumber('provenTxReqId'))\n  tables.outputBaskets.sort(byNumber('basketId'))\n  tables.transactions.sort(byNumber('transactionId'))\n  tables.commissions.sort(byNumber('commissionId'))\n  tables.outputs.sort(byNumber('outputId'))\n  tables.outputTags.sort(byNumber('outputTagId'))\n  tables.outputTagMaps.sort(byNumber('outputId', 'outputTagId'))\n  tables.txLabels.sort(byNumber('txLabelId'))\n  tables.txLabelMaps.sort(byNumber('transactionId', 'txLabelId'))\n  tables.certificates.sort(byNumber('certificateId'))\n  tables.certificateFields.sort((a, b) => {\n    const certificateIdOrder =\n      requireNumber(a.certificateId, 'certificateId') - requireNumber(b.certificateId, 'certificateId')\n    if (certificateIdOrder !== 0) return certificateIdOrder\n    return requireString(a.fieldName, 'fieldName').localeCompare(requireString(b.fieldName, 'fieldName'))\n  })\n  tables.syncStates.sort(byNumber('syncStateId'))\n}\n\nfunction byNumber (field: string, secondField?: string): (a: PortableRow, b: PortableRow) => number {\n  return (a, b) => {\n    const first = requireNumber(a[field], field) - requireNumber(b[field], field)\n    if (first !== 0 || secondField == null) return first\n    return requireNumber(a[secondField], secondField) - requireNumber(b[secondField], secondField)\n  }\n}\n\nfunction ids (rows: PortableRow[], field: string, label: string): Set<number> {\n  const set = new Set<number>()\n  for (const row of rows) {\n    const id = requireNumber(row[field], `${label}.${field}`)\n    if (set.has(id)) throw new Error(`BRC-38 duplicate ${label}.${field}: ${id}`)\n    set.add(id)\n  }\n  return set\n}\n\nfunction requireUserId (row: PortableRow, userId: number, label: string): void {\n  if (requireNumber(row.userId, `${label}.userId`) !== userId) throw new Error(`BRC-38 ${label}.userId does not match user.userId`)\n}\n\nfunction requireNumber (value: unknown, path: string): number {\n  if (!Number.isInteger(value)) throw new Error(`BRC-38 ${path} must be an integer`)\n  return value as number\n}\n\nfunction requireString (value: unknown, path: string): string {\n  if (typeof value !== 'string') throw new Error(`BRC-38 ${path} must be a string`)\n  return value\n}\n\nfunction assertIsoDate (value: unknown, path: string): void {\n  if (typeof value !== 'string' || !/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$/.test(value)) {\n    throw new Error(`BRC-38 ${path} must be a UTC ISO timestamp`)\n  }\n  const date = new Date(value)\n  if (Number.isNaN(date.getTime()) || date.toISOString() !== value) throw new Error(`BRC-38 ${path} is invalid`)\n}\n\nfunction assertBase64 (value: unknown, path: string): void {\n  if (typeof value !== 'string' || value.length % 4 !== 0 || !/^[A-Za-z0-9+/]*={0,2}$/.test(value)) {\n    throw new Error(`BRC-38 ${path} must be padded base64`)\n  }\n}\n\nfunction rejectNulls (value: unknown, path: string): void {\n  if (value === null) throw new Error(`BRC-38 ${path} must omit null values`)\n  if (Array.isArray(value)) {\n    for (let i = 0; i < value.length; i++) rejectNulls(value[i], `${path}[${i}]`)\n  } else if (isObject(value)) {\n    for (const [key, child] of Object.entries(value)) rejectNulls(child, `${path}.${key}`)\n  }\n}\n\nfunction canonicalize (value: unknown): string {\n  if (value === null || value === undefined) throw new Error('Cannot canonicalize null or undefined')\n  if (typeof value === 'string') return JSON.stringify(value)\n  if (typeof value === 'number') {\n    if (!Number.isFinite(value)) throw new Error('Cannot canonicalize non-finite number')\n    return JSON.stringify(value)\n  }\n  if (typeof value === 'boolean') return value ? 'true' : 'false'\n  if (Array.isArray(value)) return `[${value.map(canonicalize).join(',')}]`\n  if (isObject(value)) {\n    const entries = Object.keys(value)\n      .sort(compareCodepoints)\n      .map(key => canonicalizeEntry(key, value[key]))\n    return `{${entries.join(',')}}`\n  }\n  throw new Error(`Unsupported JSON value type: ${typeof value}`)\n}\n\nfunction canonicalizeEntry (key: string, value: unknown): string {\n  return `${JSON.stringify(key)}:${canonicalize(value)}`\n}\n\nfunction compareCodepoints (a: string, b: string): number {\n  if (a < b) return -1\n  if (a > b) return 1\n  return 0\n}\n\nfunction isoDate (date: Date): string {\n  return date.toISOString()\n}\n\nfunction isObject (value: unknown): value is Record<string, unknown> {\n  return typeof value === 'object' && value !== null && !Array.isArray(value)\n}\n\nfunction compareNumber (a: number, b: number): number {\n  return a - b\n}\n\nfunction concatBytes (...arrays: Uint8Array[]): Uint8Array {\n  const total = arrays.reduce((sum, a) => sum + a.length, 0)\n  const out = new Uint8Array(total)\n  let offset = 0\n  for (const array of arrays) {\n    out.set(array, offset)\n    offset += array.length\n  }\n  return out\n}\n\nasync function deriveBRC39Key (\n  password: string,\n  salt: Uint8Array,\n  iterations: number,\n  memoryKiB: number,\n  parallelism: number\n): Promise<Uint8Array> {\n  const normalized = password.normalize('NFC')\n  const hash = await argon2id({\n    password: new Uint8Array(Utils.toArray(normalized, 'utf8')),\n    salt,\n    iterations,\n    memorySize: memoryKiB,\n    parallelism,\n    hashLength: BRC39_HASH_LENGTH,\n    outputType: 'binary'\n  })\n  return new Uint8Array(hash)\n}\n\nfunction validateKdfParams (iterations: number, memoryKiB: number, parallelism: number, hashLength: number): void {\n  if (!Number.isInteger(iterations) || iterations <= 0) throw new Error('Invalid BRC-39 Argon2id iterations')\n  if (!Number.isInteger(memoryKiB) || memoryKiB <= 0) throw new Error('Invalid BRC-39 Argon2id memoryKiB')\n  if (!Number.isInteger(parallelism) || parallelism <= 0 || parallelism > 255) throw new Error('Invalid BRC-39 Argon2id parallelism')\n  if (hashLength !== BRC39_HASH_LENGTH) throw new Error('Invalid BRC-39 Argon2id hashLength')\n}\n\nfunction validateExportKdfParams (iterations: number, memoryKiB: number): void {\n  if (iterations < BRC39_DEFAULT_ITERATIONS) {\n    throw new Error('BRC-39 export iterations must not be weaker than the canonical default')\n  }\n  if (memoryKiB < BRC39_DEFAULT_MEMORY_KIB) {\n    throw new Error('BRC-39 export memoryKiB must not be weaker than the canonical default')\n  }\n}\n\nfunction writeUInt32BE (target: Uint8Array, offset: number, value: number): void {\n  if (!Number.isInteger(value) || value < 0 || value > 0xffffffff) throw new Error('BRC-39 integer out of range')\n  target[offset] = (value >>> 24) & 0xff\n  target[offset + 1] = (value >>> 16) & 0xff\n  target[offset + 2] = (value >>> 8) & 0xff\n  target[offset + 3] = value & 0xff\n}\n\nfunction readUInt32BE (source: Uint8Array, offset: number): number {\n  return ((source[offset] << 24) >>> 0) + (source[offset + 1] << 16) + (source[offset + 2] << 8) + source[offset + 3]\n}\n","import { Validation } from '@bsv/sdk'\nimport { specOpFailedActions, specOpNoSendActions, TransactionStatus, isListActionsSpecOp } from '../../sdk/types'\nimport { AuthId } from '../../sdk/WalletStorage.interfaces'\nimport { TableTransaction } from '../schema/tables/TableTransaction'\nimport { StorageProvider } from '../StorageProvider'\n\nexport interface ListActionsSpecOp {\n  name: string\n  /**\n   * undefined to intercept no labels from vargs,\n   * empty array to intercept all labels,\n   * or an explicit array of labels to intercept.\n   */\n  labelsToIntercept?: string[]\n  setStatusFilter?: () => TransactionStatus[]\n  postProcess?: (\n    s: StorageProvider,\n    auth: AuthId,\n    vargs: Validation.ValidListActionsArgs,\n    specOpLabels: string[],\n    txs: Array<Partial<TableTransaction>>\n  ) => Promise<void>\n}\n\nexport function partitionActionLabels(ordinaryLabels: string[]): {\n  specOp: ListActionsSpecOp | undefined\n  specOpLabels: string[]\n  labels: string[]\n} {\n  let specOp: ListActionsSpecOp | undefined\n  let specOpLabels: string[] = []\n  let labels: string[] = []\n  for (const label of ordinaryLabels) {\n    if (isListActionsSpecOp(label)) specOp = getLabelToSpecOp()[label]\n    else labels.push(label)\n  }\n  if (specOp?.labelsToIntercept !== undefined) {\n    const intercept = specOp.labelsToIntercept\n    const labels2 = labels\n    labels = []\n    if (intercept.length === 0) specOpLabels = labels2\n    for (const label of labels2) {\n      if (intercept.includes(label)) specOpLabels.push(label)\n      else labels.push(label)\n    }\n  }\n  return { specOp, specOpLabels, labels }\n}\n\nasync function findProtectedNoSendTxids(\n  storage: StorageProvider,\n  transactions: Array<Partial<TableTransaction>>\n): Promise<Set<string>> {\n  // One batched chain-status lookup avoids N network calls. Positive mined or\n  // mempool knowledge protects a row; an unavailable service does not make\n  // abort impossible and falls through to the per-row policy.\n  const candidateTxids = transactions\n    .filter(transaction => transaction.status === 'nosend' && !!transaction.txid)\n    .map(transaction => transaction.txid as string)\n  const protectedTxids = new Set<string>()\n  if (candidateTxids.length === 0) return protectedTxids\n\n  try {\n    const result = await storage.getServices().getStatusForTxids(candidateTxids)\n    if (result.status !== 'success') return protectedTxids\n    for (const transaction of result.results) {\n      if (transaction.status === 'mined' || transaction.status === 'known') {\n        protectedTxids.add(transaction.txid)\n      }\n    }\n  } catch {\n    // Service-unreachable handling intentionally falls through to per-row\n    // abortAction checks, which apply the same offline-fallback policy.\n  }\n  return protectedTxids\n}\n\nasync function abortOffChainNoSendActions(\n  storage: StorageProvider,\n  auth: AuthId,\n  transactions: Array<Partial<TableTransaction>>,\n  protectedTxids: Set<string>\n): Promise<void> {\n  for (const transaction of transactions) {\n    if (transaction.status !== 'nosend') continue\n    // Protected rows remain \"nosend\" so callers can distinguish them from\n    // successfully aborted rows.\n    if (transaction.txid != null && protectedTxids.has(transaction.txid)) continue\n    const result = await storage.abortAction(auth, { reference: transaction.reference! })\n    // A false result closes the status-check/abort race without incorrectly\n    // reporting the action as aborted.\n    if (result.aborted) transaction.status = 'failed'\n  }\n}\n\nasync function postProcessNoSendActions(\n  storage: StorageProvider,\n  auth: AuthId,\n  specOpLabels: string[],\n  transactions: Array<Partial<TableTransaction>>\n): Promise<void> {\n  if (!specOpLabels.includes('abort')) return\n  const protectedTxids = await findProtectedNoSendTxids(storage, transactions)\n  await abortOffChainNoSendActions(storage, auth, transactions, protectedTxids)\n}\n\nexport const getLabelToSpecOp: () => Record<string, ListActionsSpecOp> = () => {\n  return {\n    [specOpNoSendActions]: {\n      name: 'noSendActions',\n      labelsToIntercept: ['abort'],\n      setStatusFilter: () => ['nosend'],\n      postProcess: async (\n        s: StorageProvider,\n        auth: AuthId,\n        vargs: Validation.ValidListActionsArgs,\n        specOpLabels: string[],\n        txs: Array<Partial<TableTransaction>>\n      ): Promise<void> => {\n        await postProcessNoSendActions(s, auth, specOpLabels, txs)\n      }\n    },\n    [specOpFailedActions]: {\n      name: 'failedActions',\n      labelsToIntercept: ['unfail'],\n      setStatusFilter: () => ['failed'],\n      postProcess: async (\n        s: StorageProvider,\n        auth: AuthId,\n        vargs: Validation.ValidListActionsArgs,\n        specOpLabels: string[],\n        txs: Array<Partial<TableTransaction>>\n      ): Promise<void> => {\n        if (specOpLabels.includes('unfail')) {\n          for (const tx of txs) {\n            if (tx.status === 'failed') {\n              await s.updateTransaction(tx.transactionId!, { status: 'unfail' })\n              // wallet wire does not support 'unfail' status, return as 'failed'.\n            }\n          }\n        }\n      }\n    }\n  }\n}\n","import { ListOutputsResult, Validation } from '@bsv/sdk'\nimport { StorageProvider } from '../StorageProvider'\nimport { AuthId } from '../../sdk/WalletStorage.interfaces'\nimport { TableOutput } from '../schema/tables/TableOutput'\nimport {\n  specOpInvalidChange,\n  specOpSetWalletChangeParams,\n  specOpWalletBalance,\n  specOpWalletManagedUtxos\n} from '../../sdk/types'\nimport { verifyId, verifyInteger, verifyOne } from '../../utility/utilityHelpers'\nimport { WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\n\nexport interface ListOutputsSpecOp {\n  name: string\n  useBasket?: string\n  ignoreLimit?: boolean\n  includeOutputScripts?: boolean\n  includeSpent?: boolean\n  /**\n   * If true, and supported by storage, maximum performance optimization, computing balance done in the query itself.\n   */\n  totalOutputsIsSumOfSatoshis?: boolean\n  /** Restrict the operation to wallet-managed, BRC-29-signable change. */\n  managedChangeOnly?: boolean\n  resultFromTags?: (\n    s: StorageProvider,\n    auth: AuthId,\n    vargs: Validation.ValidListOutputsArgs,\n    specOpTags: string[]\n  ) => Promise<ListOutputsResult>\n  resultFromOutputs?: (\n    s: StorageProvider,\n    auth: AuthId,\n    vargs: Validation.ValidListOutputsArgs,\n    specOpTags: string[],\n    outputs: TableOutput[]\n  ) => Promise<ListOutputsResult>\n  filterOutputs?: (\n    s: StorageProvider,\n    auth: AuthId,\n    vargs: Validation.ValidListOutputsArgs,\n    specOpTags: string[],\n    outputs: TableOutput[]\n  ) => Promise<TableOutput[]>\n  /**\n   * undefined to intercept no tags from vargs,\n   * empty array to intercept all tags,\n   * or an explicit array of tags to intercept.\n   */\n  tagsToIntercept?: string[]\n  /**\n   * How many positional tags to intercept.\n   */\n  tagsParamsCount?: number\n}\n\nconst INVALID_CHANGE_MAX_CONCURRENCY = 12\n\nasync function runWithConcurrency<T>(\n  values: T[],\n  maxConcurrency: number,\n  worker: (value: T) => Promise<void>\n): Promise<void> {\n  const active: Array<Promise<void>> = []\n  for (const value of values) {\n    const task = worker(value).finally(() => {\n      const i = active.indexOf(task)\n      if (i >= 0) active.splice(i, 1)\n    })\n    active.push(task)\n    if (active.length >= maxConcurrency) {\n      await Promise.race(active)\n    }\n  }\n  await Promise.all(active)\n}\n\nconst getBasketToSpecOp: () => Record<string, ListOutputsSpecOp> = () => {\n  return {\n    [specOpWalletBalance]: {\n      name: 'totalOutputsIsWalletBalance',\n      useBasket: 'default',\n      ignoreLimit: true,\n      totalOutputsIsSumOfSatoshis: true,\n      managedChangeOnly: true,\n      resultFromOutputs: async (\n        s: StorageProvider,\n        auth: AuthId,\n        vargs: Validation.ValidListOutputsArgs,\n        specOpTags: string[],\n        outputs: TableOutput[]\n      ): Promise<ListOutputsResult> => {\n        let totalOutputs = 0\n        for (const o of outputs) totalOutputs += o.satoshis\n        return { totalOutputs, outputs: [] }\n      }\n    },\n    [specOpWalletManagedUtxos]: {\n      name: 'walletManagedUtxos',\n      useBasket: 'default',\n      managedChangeOnly: true\n    },\n    [specOpInvalidChange]: {\n      name: 'invalidChangeOutputs',\n      useBasket: 'default',\n      ignoreLimit: true,\n      includeOutputScripts: true,\n      includeSpent: false,\n      tagsToIntercept: ['release', 'all'],\n      filterOutputs: async (\n        s: StorageProvider,\n        auth: AuthId,\n        vargs: Validation.ValidListOutputsArgs,\n        specOpTags: string[],\n        outputs: TableOutput[]\n      ): Promise<TableOutput[]> => {\n        if (specOpTags.includes('release')) {\n          await s.reviewStatus({ agedLimit: new Date(0) })\n        }\n        const invalidOutputIds = new Set<number>()\n        const services = s.getServices()\n        await runWithConcurrency(outputs, INVALID_CHANGE_MAX_CONCURRENCY, async o => {\n          if (!o.basketId) return // only care about outputs assigned to baskets.\n          await s.validateOutputScript(o)\n          let ok: boolean | undefined = false\n          if (o.lockingScript != null && o.lockingScript.length > 0) {\n            ok = await services.isUtxo(o)\n          } else {\n            ok = undefined\n          }\n          if (ok === false) {\n            invalidOutputIds.add(o.outputId)\n          }\n        })\n        const filteredOutputs = outputs.filter(o => invalidOutputIds.has(o.outputId))\n        if (specOpTags.includes('release')) {\n          await runWithConcurrency(filteredOutputs, INVALID_CHANGE_MAX_CONCURRENCY, async o => {\n            await s.updateOutput(o.outputId, { spendable: false })\n            o.spendable = false\n          })\n        }\n        return filteredOutputs\n      }\n    },\n    [specOpSetWalletChangeParams]: {\n      name: 'setWalletChangeParams',\n      tagsParamsCount: 2,\n      resultFromTags: async (\n        s: StorageProvider,\n        auth: AuthId,\n        vargs: Validation.ValidListOutputsArgs,\n        specOpTags: string[]\n      ): Promise<ListOutputsResult> => {\n        if (specOpTags.length !== 2) {\n          throw new WERR_INVALID_PARAMETER('numberOfDesiredUTXOs and minimumDesiredUTXOValue', 'valid')\n        }\n        const numberOfDesiredUTXOs: number = verifyInteger(Number(specOpTags[0]))\n        const minimumDesiredUTXOValue: number = verifyInteger(Number(specOpTags[1]))\n        const basket = verifyOne(\n          await s.findOutputBaskets({\n            partial: { userId: verifyId(auth.userId), name: 'default' }\n          })\n        )\n        await s.updateOutputBasket(basket.basketId, {\n          numberOfDesiredUTXOs,\n          minimumDesiredUTXOValue\n        })\n        return { totalOutputs: 0, outputs: [] }\n      }\n    }\n  }\n}\n\nconst getTagToSpecOp: () => Record<string, ListOutputsSpecOp> = () => {\n  return {\n    [specOpWalletBalance]: {\n      name: 'totalOutputsIsWalletBalance',\n      useBasket: 'default',\n      ignoreLimit: true,\n      totalOutputsIsSumOfSatoshis: true,\n      resultFromOutputs: async (\n        s: StorageProvider,\n        auth: AuthId,\n        vargs: Validation.ValidListOutputsArgs,\n        specOpTags: string[],\n        outputs: TableOutput[]\n      ): Promise<ListOutputsResult> => {\n        let totalOutputs = 0\n        for (const o of outputs) totalOutputs += o.satoshis\n        return { totalOutputs, outputs: [] }\n      }\n    }\n  }\n}\n\nlet _basketSpecOps: Record<string, ListOutputsSpecOp> | undefined\nlet _tagSpecOps: Record<string, ListOutputsSpecOp> | undefined\n\nfunction resolveBasketSpecOp(\n  basket: string,\n  tags: string[]\n): { specOp: ListOutputsSpecOp; basket?: string; tags: string[] } | undefined {\n  if (!basket) return undefined\n  _basketSpecOps ??= getBasketToSpecOp()\n  const specOp = _basketSpecOps[basket]\n  return specOp === undefined ? undefined : { specOp, basket: specOp.useBasket, tags: tags || [] }\n}\n\nfunction resolveTagSpecOp(\n  basket: string,\n  tags: string[]\n): { specOp: ListOutputsSpecOp; basket?: string; tags: string[] } | undefined {\n  if (!tags) return undefined\n  _tagSpecOps ??= getTagToSpecOp()\n  for (const tag of tags) {\n    const specOp = _tagSpecOps[tag]\n    if (specOp === undefined) continue\n    if (!basket && specOp.useBasket) basket = specOp.useBasket\n    // The balance tag is also used to sum application baskets. Preserve\n    // that behavior, while treating the default basket as wallet balance\n    // and therefore restricting it to managed BRC-29 change.\n    const resolvedSpecOp =\n      specOp === _tagSpecOps[specOpWalletBalance] && basket === 'default'\n        ? { ...specOp, managedChangeOnly: true }\n        : specOp\n    return { specOp: resolvedSpecOp, basket, tags: tags.filter(candidate => candidate !== tag) }\n  }\n  return undefined\n}\n\n/**\n * Check basket and tags arguments passed to listOutputs to determine if they trigger a special operation execution mode.\n * @param basket\n * @param tags\n * @returns\n */\nexport function getListOutputsSpecOp(\n  basket: string,\n  tags: string[]\n): { specOp: ListOutputsSpecOp | undefined; basket?: string; tags: string[] } {\n  return resolveBasketSpecOp(basket, tags) ?? resolveTagSpecOp(basket, tags) ?? { specOp: undefined, basket, tags }\n}\n","import type { BaseBlockHeader, BlockHeader } from '../../../../sdk/WalletServices.interfaces'\n\nexport type { BaseBlockHeader, BlockHeader } from '../../../../sdk/WalletServices.interfaces'\n\n/**\n * The \"live\" portion of the block chain is recent history that can conceivably be subject to reorganizations.\n * The additional fields support tracking orphan blocks, chain forks, and chain reorgs.\n */\nexport interface LiveBlockHeader extends BlockHeader {\n  /**\n   * The cumulative chainwork achieved by the addition of this block to the chain.\n   * Chainwork only matters in selecting the active chain.\n   */\n  chainWork: string\n  /**\n   * True only if this header is currently a chain tip. e.g. There is no header that follows it by previousHash or previousHeaderId.\n   */\n  isChainTip: boolean\n  /**\n   * True only if this header is currently on the active chain.\n   */\n  isActive: boolean\n  /**\n   * As there may be more than one header with identical height values due to orphan tracking,\n   * headers are assigned a unique headerId while part of the \"live\" portion of the block chain.\n   */\n  headerId: number\n  /**\n   * Every header in the \"live\" portion of the block chain is linked to an ancestor header through\n   * both its previousHash and previousHeaderId properties.\n   *\n   * Due to forks, there may be multiple headers with identical `previousHash` and `previousHeaderId` values.\n   * Of these, only one (the header on the active chain) will have `isActive` === true.\n   */\n  previousHeaderId: number | null\n}\n\n//\n// TYPE GUARDS\n//\n\n/**\n * Type guard function.\n * @publicbody\n */\nexport function isLive(header: BlockHeader | LiveBlockHeader): header is LiveBlockHeader {\n  return (header as LiveBlockHeader).headerId !== undefined\n}\n\n/** Union of all block header variants */\nexport type AnyBlockHeader = BaseBlockHeader | BlockHeader | LiveBlockHeader\n\n/**\n * Type guard function.\n * @publicbody\n */\nexport function isBaseBlockHeader(header: AnyBlockHeader): header is BaseBlockHeader {\n  return typeof header.previousHash === 'string'\n}\n\n/**\n * Type guard function.\n * @publicbody\n */\nexport function isBlockHeader(header: AnyBlockHeader): header is BlockHeader {\n  return 'height' in header && typeof header.previousHash === 'string'\n}\n\n/**\n * Type guard function.\n * @publicbody\n */\nexport function isLiveBlockHeader(header: AnyBlockHeader): header is LiveBlockHeader {\n  return 'chainWork' in header && typeof header.previousHash === 'string'\n}\n","import { BlockHeader } from '../../../../sdk/WalletServices.interfaces'\n\nexport interface HeightRangeApi {\n  minHeight: number\n  maxHeight: number\n}\n\nexport interface HeightRanges {\n  bulk: HeightRange\n  live: HeightRange\n}\n\n/**\n * Represents a range of block heights.\n *\n * Operations support integrating contiguous batches of headers,\n */\nexport class HeightRange implements HeightRangeApi {\n  constructor (\n    public minHeight: number,\n    public maxHeight: number\n  ) {}\n\n  /**\n   * All ranges where maxHeight is less than minHeight are considered empty.\n   * The canonical empty range is (0, -1).\n   */\n  static readonly empty = new HeightRange(0, -1)\n\n  /**\n   * @returns true iff minHeight is greater than maxHeight.\n   */\n  get isEmpty () {\n    return this.minHeight > this.maxHeight\n  }\n\n  /**\n   * @param headers an array of objects with a non-negative integer `height` property.\n   * @returns range of height values from the given headers, or the empty range if there are no headers.\n   */\n  static from (headers: BlockHeader[]): HeightRange {\n    if (headers.length === 0) return HeightRange.empty\n    const minHeight = headers.reduce((min, h) => Math.min(min, h.height), headers[0].height)\n    const maxHeight = headers.reduce((max, h) => Math.max(max, h.height), headers[0].height)\n    return new HeightRange(minHeight, maxHeight)\n  }\n\n  /**\n   * @returns the number of heights in the range, or 0 if the range is empty.\n   */\n  get length () {\n    return Math.max(0, this.maxHeight - this.minHeight + 1)\n  }\n\n  /**\n   * @returns an easy to read string representation of the height range.\n   */\n  toString (): string {\n    return this.isEmpty ? '<empty>' : `${this.minHeight}-${this.maxHeight}`\n  }\n\n  /**\n   * @param range HeightRange or single height value.\n   * @returns true if `range` is entirely within this range.\n   */\n  contains (range: HeightRange | number) {\n    if (typeof range === 'number') {\n      return this.minHeight <= range && this.maxHeight >= range\n    }\n    return this.minHeight <= range.minHeight && this.maxHeight >= range.maxHeight\n  }\n\n  /**\n   * Return the intersection with another height range.\n   *\n   * Intersection with an empty range is always empty.\n   *\n   * The result is always a single, possibly empty, range.\n   * @param range\n   * @returns\n   */\n  intersect (range: HeightRange) {\n    const r = new HeightRange(Math.max(this.minHeight, range.minHeight), Math.min(this.maxHeight, range.maxHeight))\n    return r\n  }\n\n  /**\n   * Return the union with another height range.\n   *\n   * Only valid if the two ranges overlap or touch, or one is empty.\n   *\n   * Throws an error if the union would create two disjoint ranges.\n   *\n   * @param range\n   * @returns\n   */\n  union (range: HeightRange) {\n    if (this.isEmpty) return range.copy()\n    if (range.isEmpty) return this.copy()\n    if (this.maxHeight + 1 < range.minHeight || range.maxHeight + 1 < this.minHeight) { throw new Error('Union of ranges with a gap between them is not supported.') }\n    return new HeightRange(Math.min(this.minHeight, range.minHeight), Math.max(this.maxHeight, range.maxHeight))\n  }\n\n  /**\n   * Returns `range` subtracted from this range.\n   *\n   * Throws an error if the subtraction would create two disjoint ranges.\n   *\n   * @param range\n   * @returns\n   */\n  subtract (range: HeightRange) {\n    if (this.isEmpty || range.isEmpty) return this.copy()\n    if (this.minHeight < range.minHeight && this.maxHeight > range.maxHeight) { throw new Error('Subtraction of range that creates two disjoint ranges is not supported.') }\n    if (range.maxHeight < this.minHeight || range.minHeight > this.maxHeight)\n    // Leave untouched. Subtracted is either all lower or all higher.\n    { return this.copy() }\n    if (range.minHeight <= this.minHeight && range.maxHeight < this.maxHeight)\n    // Remove a chunk on the low side.\n    { return new HeightRange(range.maxHeight + 1, this.maxHeight) }\n    if (range.minHeight <= this.minHeight && range.maxHeight >= this.maxHeight)\n    // Remove the whole thing\n    { return new HeightRange(this.minHeight, this.minHeight - 1) } // empty\n    if (range.minHeight <= this.maxHeight && range.maxHeight >= this.maxHeight)\n    // Remove a chunk on the high side.\n    { return new HeightRange(this.minHeight, range.minHeight - 1) }\n    throw new Error('All cases should have been handled :-) .')\n  }\n\n  /**\n   * If `range` is not empty and this is not empty, returns a new range minHeight\n   * replaced by to range.maxHeight + 1.\n   *\n   * Otherwise returns a copy of this range.\n   *\n   * This returns the portion of this range that is strictly above `range`.\n   */\n  above (range: HeightRange) {\n    if (range.isEmpty || this.isEmpty) return this.copy()\n    return new HeightRange(range.maxHeight + 1, this.maxHeight)\n  }\n\n  /**\n   * Return a copy of this range.\n   */\n  copy (): HeightRange {\n    return new HeightRange(this.minHeight, this.maxHeight)\n  }\n}\n","/**\n * A reader-writer lock to manage concurrent access.\n * Allows multiple readers or one writer at a time.\n */\nexport class SingleWriterMultiReaderLock {\n  private readers: number = 0\n  private writerActive: boolean = false\n  private readonly readerQueue: Array<() => void> = []\n  private readonly writerQueue: Array<() => void> = []\n\n  private checkQueues (): void {\n    if (this.writerActive || this.readers > 0) return\n    if (this.writerQueue.length > 0) {\n      // If there are waiting writers and no active readers or writers, start the next writer\n      const resolve = this.writerQueue.shift()!\n      resolve()\n    } else if (this.readerQueue.length > 0) {\n      // If there are waiting readers and no waiting writers, start all readers\n      const readers = this.readerQueue.splice(0)\n      for (const resolve of readers) {\n        resolve()\n      }\n    }\n  }\n\n  async withReadLock<T>(fn: () => Promise<T>): Promise<T> {\n    if (!this.writerActive && this.writerQueue.length === 0) {\n      // Fast path: no active writer or waiting writers, proceed immediately\n      this.readers++\n      try {\n        return await fn()\n      } finally {\n        this.readers--\n        this.checkQueues()\n      }\n    } else {\n      // Queue the reader until writers are done\n      const promise = new Promise<void>(resolve => {\n        this.readerQueue.push(resolve)\n      })\n      await promise\n      this.readers++\n      try {\n        return await fn()\n      } finally {\n        this.readers--\n        this.checkQueues()\n      }\n    }\n  }\n\n  async withWriteLock<T>(fn: () => Promise<T>): Promise<T> {\n    if (!this.writerActive && this.readers === 0) {\n      // Fast path: no active writer or readers, proceed immediately\n      this.writerActive = true\n      try {\n        return await fn()\n      } finally {\n        this.writerActive = false\n        this.checkQueues()\n      }\n    } else {\n      const promise = new Promise<void>(resolve => {\n        this.writerQueue.push(resolve)\n      })\n      await promise\n      this.writerActive = true\n      try {\n        return await fn()\n      } finally {\n        this.writerActive = false\n        this.checkQueues()\n      }\n    }\n  }\n}\n","import { ChaintracksStorageApi, InsertHeaderResult } from './Api/ChaintracksStorageApi'\nimport { BulkIngestorApi } from './Api/BulkIngestorApi'\nimport { LiveIngestorApi } from './Api/LiveIngestorApi'\n\nimport { validateAgainstDirtyHashes } from './util/dirtyHashes'\n\nimport { ChaintracksOptions, ChaintracksManagementApi } from './Api/ChaintracksApi'\nimport { blockHash, validateHeaderFormat } from './util/blockHeaderUtilities'\nimport { Chain } from '../../../sdk/types'\nimport {\n  ChaintracksInfoApi,\n  ChaintracksSourceStatusApi,\n  HeaderListener,\n  ReorgListener\n} from './Api/ChaintracksClientApi'\nimport { BaseBlockHeader, BlockHeader, LiveBlockHeader } from './Api/BlockHeaderApi'\nimport { asString } from '../../../utility/utilityHelpers.noBuffer'\nimport { HeightRange, HeightRanges } from './util/HeightRange'\nimport { SingleWriterMultiReaderLock } from './util/SingleWriterMultiReaderLock'\nimport { ChaintracksFsApi } from './Api/ChaintracksFsApi'\nimport { randomBytesBase64, wait } from '../../../utility/utilityHelpers'\nimport { WalletError } from '../../../sdk/WalletError'\nexport class Chaintracks implements ChaintracksManagementApi {\n  static createOptions(chain: Chain): ChaintracksOptions {\n    return {\n      chain,\n      storage: undefined,\n      bulkIngestors: [],\n      liveIngestors: [],\n      addLiveRecursionLimit: 36,\n      logging: (...args) => console.log(new Date().toISOString(), ...args),\n      readonly: false\n    }\n  }\n\n  // eslint-disable-next-line @typescript-eslint/no-explicit-any\n  log: (...args: any[]) => void = () => {}\n\n  readonly chain: Chain\n  readonly readonly: boolean\n\n  // Collection of all long running \"threads\": main thread (liveHeaders consumer / monitor) and each live header ingestor.\n  private readonly promises: Array<Promise<void>> = []\n\n  private readonly callbacks: {\n    header: Record<string, HeaderListener | null>\n    reorg: Record<string, ReorgListener | null>\n  } = { header: {}, reorg: {} }\n  private readonly storage: ChaintracksStorageApi\n  private readonly bulkIngestors: BulkIngestorApi[]\n  private readonly liveIngestors: LiveIngestorApi[]\n\n  private readonly baseHeaders: BaseBlockHeader[] = []\n  private readonly liveHeaders: BlockHeader[] = []\n  private readonly addLiveRecursionLimit: number = 11\n\n  private available = false\n  private startupError: WalletError | null = null\n\n  private subscriberCallbacksEnabled = false\n  private stopMainThread = true\n\n  private lastPresentHeight = -1\n  private lastPresentHeightMsecs = 0\n  private readonly lastPresentHeightMaxAge = 60 * 1000 // 1 minute, in milliseconds\n\n  private readonly lock = new SingleWriterMultiReaderLock()\n  private readonly sourceStatus = new Map<string, ChaintracksSourceStatusApi>()\n\n  constructor(public options: ChaintracksOptions) {\n    if (options.storage == null) throw new Error('storage is required.')\n    if (!options.bulkIngestors || options.bulkIngestors.length < 1) {\n      throw new Error('At least one bulk ingestor is required.')\n    }\n    if (!options.liveIngestors || options.liveIngestors.length < 1) {\n      throw new Error('At least one live ingestor is required.')\n    }\n    this.chain = options.chain\n    this.readonly = options.readonly\n    this.storage = options.storage\n    this.bulkIngestors = options.bulkIngestors\n    this.liveIngestors = options.liveIngestors\n    for (const [index, source] of this.bulkIngestors.entries()) {\n      const name = this.sourceName('bulk', index, source)\n      this.sourceStatus.set(name, { name, role: 'bulk', state: 'unknown' })\n    }\n    for (const [index, source] of this.liveIngestors.entries()) {\n      const name = this.sourceName('live', index, source)\n      this.sourceStatus.set(name, { name, role: 'live', state: 'unknown' })\n    }\n\n    this.addLiveRecursionLimit = options.addLiveRecursionLimit\n\n    if (options.logging != null) this.log = options.logging\n    this.storage.log = this.log\n\n    this.log(`New ChaintracksBase Instance Constructed ${options.chain}Net`)\n  }\n\n  async getChain(): Promise<Chain> {\n    return this.chain\n  }\n\n  /**\n   * Caches and returns most recently sourced value if less than one minute old.\n   * @returns the current externally available chain height (via bulk ingestors).\n   */\n  async getPresentHeight(): Promise<number> {\n    const now = Date.now()\n    if (this.lastPresentHeight >= 0 && now - this.lastPresentHeightMsecs < this.lastPresentHeightMaxAge) {\n      return this.lastPresentHeight\n    }\n    for (const [index, bulk] of this.bulkIngestors.entries()) {\n      const source = this.sourceName('bulk', index, bulk)\n      try {\n        const presentHeight = await bulk.getPresentHeight()\n        if (presentHeight != null && Number.isInteger(presentHeight) && presentHeight >= 0) {\n          this.markSourceSuccess(source, 'bulk')\n          this.lastPresentHeight = presentHeight\n          this.lastPresentHeightMsecs = now\n          return presentHeight\n        }\n      } catch (uerr: unknown) {\n        const error = WalletError.fromUnknown(uerr)\n        this.markSourceFailure(source, 'bulk', error)\n        this.log(`Present-height source ${source} failed: ${error.message}`)\n      }\n    }\n\n    // A provider outage must not make an already synchronized tracker unusable.\n    if (this.lastPresentHeight >= 0) return this.lastPresentHeight\n    try {\n      const ranges = await this.storage.getAvailableHeightRanges()\n      const localHeight = Math.max(ranges.bulk.maxHeight, ranges.live.maxHeight)\n      if (localHeight >= 0) {\n        this.lastPresentHeight = localHeight\n        this.lastPresentHeightMsecs = now\n        return localHeight\n      }\n    } catch (error: unknown) {\n      this.log(`Unable to read the locally validated ChainTracks height: ${WalletError.fromUnknown(error).message}`)\n    }\n    throw new Error('No present-height source or locally validated headers are available.')\n  }\n\n  async currentHeight(): Promise<number> {\n    return await this.getPresentHeight()\n  }\n\n  async subscribeHeaders(listener: HeaderListener): Promise<string> {\n    const ID = randomBytesBase64(8)\n    this.callbacks.header[ID] = listener\n    return ID\n  }\n\n  async subscribeReorgs(listener: ReorgListener): Promise<string> {\n    const ID = randomBytesBase64(8)\n    this.callbacks.reorg[ID] = listener\n    return ID\n  }\n\n  async unsubscribe(subscriptionId: string): Promise<boolean> {\n    let success = true\n    if (this.callbacks.header[subscriptionId]) this.callbacks.header[subscriptionId] = null\n    else if (this.callbacks.reorg[subscriptionId]) this.callbacks.reorg[subscriptionId] = null\n    else success = false\n    return success\n  }\n\n  /**\n   * Queues a potentially new, unknown header for consideration as an addition to the chain.\n   * When the header is considered, if the prior header is unknown, recursive calls to the\n   * bulk ingestors will be attempted to resolve the linkage up to a depth of `addLiveRecursionLimit`.\n   *\n   * Headers are considered in the order they were added.\n   *\n   * @param header\n   */\n  async addHeader(header: BaseBlockHeader): Promise<void> {\n    this.baseHeaders.push(header)\n  }\n\n  /**\n   * If not already available, takes a writer lock to queue calls until available.\n   * Becoming available starts by initializing ingestors and main thread,\n   * and ends when main thread sets `available`.\n   * Note that the main thread continues running and takes additional write locks\n   * itself when already available.\n   *\n   * @returns when available for client requests\n   */\n  async makeAvailable(): Promise<void> {\n    if (this.available) return\n    await this.lock.withWriteLock(async () => {\n      // Only the first call proceeds to initialize...\n      if (this.available) return\n      // Make sure database schema exists and is updated...\n      await this.storage.migrateLatest()\n      for (const bulkIn of this.bulkIngestors) await bulkIn.setStorage(this.storage, this.log)\n      for (const liveIn of this.liveIngestors) await liveIn.setStorage(this.storage, this.log)\n\n      // Start all live ingestors to push new headers onto liveHeaders... each long running.\n      this.stopMainThread = false\n      for (const [index, liveIngestor] of this.liveIngestors.entries()) {\n        this.promises.push(this.runLiveIngestor(liveIngestor, index))\n      }\n\n      // Start mai loop to shift out liveHeaders...once sync'd, will set `available` true.\n      this.promises.push(this.mainThreadShiftLiveHeaders())\n\n      // Wait for the main thread to finish initial sync.\n      while (!this.available && this.startupError == null) {\n        await wait(100)\n      }\n\n      if (this.startupError != null) throw this.startupError\n    })\n  }\n\n  async startPromises(): Promise<void> {\n    if (this.promises.length > 0 || !this.stopMainThread) return\n  }\n\n  async destroy(): Promise<void> {\n    if (!this.available) return\n    await this.lock.withWriteLock(async () => {\n      if (!this.available || this.stopMainThread) return\n      this.log('Shutting Down')\n      this.stopMainThread = true\n      for (const liveIn of this.liveIngestors) await liveIn.shutdown()\n      for (const bulkIn of this.bulkIngestors) await bulkIn.shutdown()\n      await Promise.all(this.promises)\n      await this.storage.destroy()\n      this.available = false\n      this.stopMainThread = false\n      this.log('Shutdown')\n    })\n  }\n\n  async listening(): Promise<void> {\n    return await this.makeAvailable()\n  }\n\n  private async runLiveIngestor(liveIngestor: LiveIngestorApi, index: number): Promise<void> {\n    let restartCount = 0\n    const name = liveIngestor.constructor.name\n    const source = this.sourceName('live', index, liveIngestor)\n\n    while (!this.stopMainThread) {\n      try {\n        this.markSourceSuccess(source, 'live')\n        await liveIngestor.startListening(this.liveHeaders)\n        if (this.stopMainThread) return\n        restartCount++\n        const waitMsecs = this.liveIngestorRestartWaitMsecs(restartCount)\n        this.log(`Live ingestor ${name} stopped unexpectedly restart=${restartCount} retryMsecs=${waitMsecs}`)\n        await wait(waitMsecs)\n      } catch (error_: unknown) {\n        if (this.stopMainThread) return\n        restartCount++\n        const e = WalletError.fromUnknown(error_)\n        this.markSourceFailure(source, 'live', e)\n        const waitMsecs = this.liveIngestorRestartWaitMsecs(restartCount)\n        this.log(\n          `Live ingestor ${name} failed restart=${restartCount} retryMsecs=${waitMsecs}: ${e.stack ?? e.message}`\n        )\n        await wait(waitMsecs)\n      }\n    }\n  }\n\n  private liveIngestorRestartWaitMsecs(restartCount: number): number {\n    return Math.min(1000 * Math.min(2 ** Math.max(restartCount - 1, 0), 60), 60000)\n  }\n\n  async isListening(): Promise<boolean> {\n    return this.available\n  }\n\n  async isSynchronized(): Promise<boolean> {\n    await this.makeAvailable()\n    return true\n  }\n\n  async findHeaderForHeight(height: number): Promise<BlockHeader | undefined> {\n    await this.makeAvailable()\n    return await this.lock.withReadLock(async () => await this.findHeaderForHeightNoLock(height))\n  }\n\n  private async findHeaderForHeightNoLock(height: number): Promise<BlockHeader | undefined> {\n    return await this.storage.findHeaderForHeightOrUndefined(height)\n  }\n\n  async findHeaderForBlockHash(hash: string): Promise<BlockHeader | undefined> {\n    await this.makeAvailable()\n    return await this.lock.withReadLock(async () => await this.findHeaderForBlockHashNoLock(hash))\n  }\n\n  private async findHeaderForBlockHashNoLock(hash: string): Promise<BlockHeader | undefined> {\n    return (await this.storage.findLiveHeaderForBlockHash(hash)) || undefined\n  }\n\n  async isValidRootForHeight(root: string, height: number): Promise<boolean> {\n    const r = await this.findHeaderForHeight(height)\n    if (r == null) return false\n    const isValid = root === r.merkleRoot\n    return isValid\n  }\n\n  async getInfo(): Promise<ChaintracksInfoApi> {\n    await this.makeAvailable()\n    return await this.lock.withReadLock(async () => await this.getInfoNoLock())\n  }\n\n  private async getInfoNoLock(): Promise<ChaintracksInfoApi> {\n    const liveRange = await this.storage.findLiveHeightRange()\n    const info: ChaintracksInfoApi = {\n      chain: this.chain,\n      heightBulk: liveRange.minHeight - 1,\n      heightLive: liveRange.maxHeight,\n      storage: this.storage.constructor.name,\n      bulkIngestors: this.bulkIngestors.map(bulkIngestor => bulkIngestor.constructor.name),\n      liveIngestors: this.liveIngestors.map(liveIngestor => liveIngestor.constructor.name),\n      packages: [],\n      sources: Array.from(this.sourceStatus.values()).map(status => ({ ...status }))\n    }\n    return info\n  }\n\n  async getHeaders(height: number, count: number): Promise<string> {\n    await this.makeAvailable()\n    return await this.lock.withReadLock(async () => asString(await this.storage.getHeadersUint8Array(height, count)))\n  }\n\n  async findChainTipHeader(): Promise<BlockHeader> {\n    await this.makeAvailable()\n    return await this.lock.withReadLock(async () => await this.storage.findChainTipHeader())\n  }\n\n  async findChainTipHash(): Promise<string> {\n    await this.makeAvailable()\n    return await this.lock.withReadLock(async () => await this.storage.findChainTipHash())\n  }\n\n  async findLiveHeaderForBlockHash(hash: string): Promise<LiveBlockHeader | undefined> {\n    await this.makeAvailable()\n    const header = await this.lock.withReadLock(async () => await this.storage.findLiveHeaderForBlockHash(hash))\n    return header || undefined\n  }\n\n  async findChainWorkForBlockHash(hash: string): Promise<string | undefined> {\n    const header = await this.findLiveHeaderForBlockHash(hash)\n    return header?.chainWork\n  }\n\n  /**\n   * @returns true iff all headers from height zero through current chainTipHeader height can be retreived and form a valid chain.\n   */\n  async validate(): Promise<boolean> {\n    let h = await this.findChainTipHeader()\n    while (h.height > 0) {\n      const hp = await this.findHeaderForHeight(h.height - 1)\n      if (hp?.hash !== h.previousHash) throw new Error(`validation fails at height ${h.height}`)\n      h = hp\n      if (10000 * Math.floor(h.height / 10000) === h.height) this.log(`height ${h.height}`)\n    }\n    this.log('validated')\n    return true\n  }\n\n  async exportBulkHeaders(\n    toFolder: string,\n    toFs: ChaintracksFsApi,\n    sourceUrl?: string,\n    toHeadersPerFile?: number,\n    maxHeight?: number\n  ): Promise<void> {\n    toHeadersPerFile ||= 100000\n    const bulk = this.storage.bulkManager\n    await bulk.exportHeadersToFs(toFs, toHeadersPerFile, toFolder, sourceUrl, maxHeight)\n  }\n\n  async startListening(): Promise<void> {\n    this.makeAvailable()\n  }\n\n  private async syncBulkStorage(presentHeight: number, initialRanges: HeightRanges): Promise<void> {\n    await this.lock.withWriteLock(async () => await this.syncBulkStorageNoLock(presentHeight, initialRanges))\n  }\n\n  private async syncBulkStorageNoLock(presentHeight: number, initialRanges: HeightRanges): Promise<void> {\n    let newLiveHeaders: BlockHeader[] = []\n    let before = initialRanges\n    let after = before\n    let added = HeightRange.empty\n    const maxSyncRounds = Math.max(1, this.bulkIngestors.length * 2)\n\n    for (let round = 1; round <= maxSyncRounds; round++) {\n      const result = await this.runBulkSyncRound(before, presentHeight, newLiveHeaders)\n      after = result.after\n      newLiveHeaders = result.newLiveHeaders\n      added = after.bulk.above(before.bulk)\n      before = after\n\n      if (this.startupError != null) break\n      if (result.done) break\n      if (!result.madeProgress) {\n        this.log(\n          `Bulk sync stalled after round ${round}. Deferring further bulk sync attempts to continue live header processing.`\n        )\n        break\n      }\n      if (round === maxSyncRounds) {\n        this.log(\n          `Bulk sync paused after ${maxSyncRounds} rounds to avoid runaway retries. Will retry in a later sync cycle.`\n        )\n      }\n    }\n\n    if (this.startupError == null) {\n      this.liveHeaders.unshift(...newLiveHeaders)\n      added = after.bulk.above(initialRanges.bulk)\n      this.log(`syncBulkStorage done\n  Before sync: bulk ${initialRanges.bulk}, live ${initialRanges.live}\n   After sync: bulk ${after.bulk}, live ${after.live}\n  ${added.length} headers added to bulk storage\n  ${this.liveHeaders.length} headers forwarded to live header storage\n`)\n    }\n  }\n\n  private async runBulkSyncRound(\n    before: HeightRanges,\n    presentHeight: number,\n    newLiveHeaders: BlockHeader[]\n  ): Promise<{ after: HeightRanges; newLiveHeaders: BlockHeader[]; done: boolean; madeProgress: boolean }> {\n    let after = before\n    let bulkSyncError: WalletError | undefined\n    let madeProgress = false\n    let hadSuccess = false\n    let done = false\n\n    for (const [index, bulk] of this.bulkIngestors.entries()) {\n      const source = this.sourceName('bulk', index, bulk)\n      try {\n        const beforeBulkMax = before.bulk.maxHeight\n        const beforeLiveRange = HeightRange.from(newLiveHeaders)\n        const r = await bulk.synchronize(presentHeight, before, newLiveHeaders)\n        hadSuccess = true\n        this.markSourceSuccess(source, 'bulk')\n\n        newLiveHeaders = r.liveHeaders\n        after = await this.storage.getAvailableHeightRanges()\n        const added = after.bulk.above(before.bulk)\n        const afterLiveRange = HeightRange.from(newLiveHeaders)\n        if (after.bulk.maxHeight > beforeBulkMax || afterLiveRange.maxHeight > beforeLiveRange.maxHeight)\n          madeProgress = true\n        before = after\n        this.log(\n          `Bulk Ingestor: ${added.length} added with ${newLiveHeaders.length} live headers from ${bulk.constructor.name}`\n        )\n        if (r.done) {\n          done = true\n          break\n        }\n      } catch (error_: unknown) {\n        const e = (bulkSyncError = WalletError.fromUnknown(error_))\n        this.markSourceFailure(source, 'bulk', e)\n        this.log(`bulk sync error: ${e.message}`)\n      }\n    }\n\n    if (!this.available && bulkSyncError != null && !hadSuccess) this.startupError = bulkSyncError\n    return { after, newLiveHeaders, done, madeProgress }\n  }\n\n  private sourceName(role: 'bulk' | 'live', index: number, source: object): string {\n    return `${role}[${index}]:${source.constructor.name}`\n  }\n\n  private markSourceSuccess(name: string, role: 'bulk' | 'live'): void {\n    this.sourceStatus.set(name, {\n      ...this.sourceStatus.get(name),\n      name,\n      role,\n      state: 'healthy',\n      lastSuccess: new Date().toISOString(),\n      error: undefined\n    })\n  }\n\n  private markSourceFailure(name: string, role: 'bulk' | 'live', error: Error): void {\n    this.sourceStatus.set(name, {\n      ...this.sourceStatus.get(name),\n      name,\n      role,\n      state: 'degraded',\n      lastFailure: new Date().toISOString(),\n      error: error.message\n    })\n  }\n\n  private async getMissingBlockHeader(hash: string): Promise<BlockHeader | undefined> {\n    for (const [index, live] of this.liveIngestors.entries()) {\n      const source = this.sourceName('live', index, live)\n      try {\n        const header = await live.getHeaderByHash(hash)\n        this.markSourceSuccess(source, 'live')\n        if (header != null) return header\n      } catch (error: unknown) {\n        const resolved = WalletError.fromUnknown(error)\n        this.markSourceFailure(source, 'live', resolved)\n        this.log(`Header lookup source ${source} failed: ${resolved.message}`)\n      }\n    }\n    return undefined\n  }\n\n  private invalidInsertHeaderResult(ihr: InsertHeaderResult): boolean {\n    return ihr.noActiveAncestor || ihr.noTip || ihr.badPrev\n  }\n\n  private async addLiveHeader(header: BlockHeader): Promise<InsertHeaderResult> {\n    validateHeaderFormat(header)\n    validateAgainstDirtyHashes(header.hash)\n\n    const ihr = this.available\n      ? await this.lock.withWriteLock(async () => await this.storage.insertHeader(header))\n      : await this.storage.insertHeader(header)\n\n    if (this.invalidInsertHeaderResult(ihr)) return ihr\n\n    if (this.subscriberCallbacksEnabled && ihr.added && ihr.isActiveTip) {\n      this.notifyHeaderListeners(header)\n      if (ihr.reorgDepth > 0 && ihr.priorTip != null) {\n        this.notifyReorgListeners(ihr, header)\n      }\n    }\n\n    return ihr\n  }\n\n  private notifyHeaderListeners(header: BlockHeader): void {\n    for (const id in this.callbacks.header) {\n      const listener = this.callbacks.header[id]\n      if (listener != null) {\n        try {\n          listener(header)\n        } catch {\n          /* ignore all errors thrown */\n        }\n      }\n    }\n  }\n\n  private notifyReorgListeners(ihr: InsertHeaderResult, header: BlockHeader): void {\n    const priorTip: BlockHeader = { ...ihr.priorTip! }\n    const deactivated: BlockHeader[] = ihr.deactivatedHeaders.map(lbh => ({ ...lbh }))\n    for (const id in this.callbacks.reorg) {\n      const listener = this.callbacks.reorg[id]\n      if (listener != null) {\n        try {\n          listener(ihr.reorgDepth, priorTip, header, deactivated)\n        } catch {\n          /* ignore all errors thrown */\n        }\n      }\n    }\n  }\n\n  /**\n   * Long running method terminated by setting `stopMainThread` false.\n   *\n   * The promise returned by this method is held in the `promises` array.\n   *\n   * When synchronized (bulk and live storage is valid up to most recent presentHeight),\n   * this method will process headers from `baseHeaders` and `liveHeaders` arrays to extend the chain of headers.\n   *\n   * If a significant gap is detected between bulk+live and presentHeight, `syncBulkStorage` is called to re-establish sync.\n   *\n   * Periodically CDN bulk ingestor is invoked to check if incremental headers can be migrated to CDN backed files.\n   */\n  private async mainThreadShiftLiveHeaders(): Promise<void> {\n    this.stopMainThread = false\n    let lastSyncCheck = 0\n    let lastBulkSync = Date.now()\n    const cdnSyncRepeatMsecs = 24 * 60 * 60 * 1000 // 24 hours\n    const syncCheckRepeatMsecs = 30 * 60 * 1000 // 30 minutes\n\n    while (!this.stopMainThread) {\n      try {\n        const now = Date.now()\n        lastSyncCheck = now\n        lastBulkSync = await this.runBulkSyncIfNeeded(now, lastBulkSync, cdnSyncRepeatMsecs)\n        await this.processLiveHeaderQueue(lastSyncCheck, syncCheckRepeatMsecs)\n      } catch (error_: unknown) {\n        const e = WalletError.fromUnknown(error_)\n        if (this.available) {\n          this.log(`Error occurred during chaintracks main thread processing: ${e.stack || e.message}`)\n        } else {\n          this.startupError = e\n          this.stopMainThread = true\n        }\n      }\n    }\n  }\n\n  /** Returns (potentially updated) lastBulkSync timestamp. */\n  private async runBulkSyncIfNeeded(now: number, lastBulkSync: number, cdnSyncRepeatMsecs: number): Promise<number> {\n    const presentHeight = await this.getPresentHeight()\n    const before = await this.storage.getAvailableHeightRanges()\n\n    let skipBulkSync = !before.live.isEmpty && before.live.maxHeight >= presentHeight - this.addLiveRecursionLimit / 2\n    // If we haven't re-synced in a long time, do it just to check for a CDN update.\n    if (skipBulkSync && now - lastBulkSync > cdnSyncRepeatMsecs) skipBulkSync = false\n\n    this.log(`Chaintracks Update Services: Bulk Header Sync Review\n  presentHeight=${presentHeight}   addLiveRecursionLimit=${this.addLiveRecursionLimit}\n  Before synchronize: bulk ${before.bulk}, live ${before.live}\n  ${skipBulkSync ? 'Skipping' : 'Starting'} syncBulkStorage.\n`)\n\n    if (!skipBulkSync) {\n      // Once available, the initial write lock is released; take a new one to update bulk storage.\n      // While not yet available, the makeAvailable write lock is still held.\n      if (this.available) await this.syncBulkStorage(presentHeight, before)\n      else await this.syncBulkStorageNoLock(presentHeight, before)\n      if (this.startupError != null) throw this.startupError\n      return now\n    }\n    return lastBulkSync\n  }\n\n  private async processNextQueuedHeader(stats: { count: number; liveHeaderDupes: number }): Promise<boolean | null> {\n    const liveHeader = this.liveHeaders.shift()\n    if (liveHeader != null) {\n      const result = await this.processOneLiveHeader(liveHeader)\n      if (result.needSyncCheck) return true\n      if (result.dupe) stats.liveHeaderDupes++\n      if (result.added) stats.count++\n      return false\n    }\n    const baseHeader = this.baseHeaders.shift()\n    if (baseHeader == null) return null\n    if (await this.processOneBaseHeader(baseHeader)) stats.count++\n    return false\n  }\n\n  private async flushLiveHeaderProgress(stats: { count: number; liveHeaderDupes: number }): Promise<void> {\n    if (stats.count === 0) return\n    if (stats.liveHeaderDupes > 0) {\n      this.log(`${stats.liveHeaderDupes} duplicate headers ignored.`)\n      stats.liveHeaderDupes = 0\n    }\n    const updated = await this.storage.getAvailableHeightRanges()\n    this.log(`After adding ${stats.count} live headers\\n   After live: bulk ${updated.bulk}, live ${updated.live}\\n`)\n    stats.count = 0\n  }\n\n  private async waitForQueuedHeaders(\n    stats: { count: number; liveHeaderDupes: number },\n    lastSyncCheck: number,\n    syncCheckRepeatMsecs: number\n  ): Promise<boolean> {\n    await this.flushLiveHeaderProgress(stats)\n    await this.checkAndEnableSubscribers()\n    if (!this.available) this.available = true\n    const needSyncCheck = Date.now() - lastSyncCheck > syncCheckRepeatMsecs\n    if (!needSyncCheck) await wait(1000)\n    return needSyncCheck\n  }\n\n  private async processLiveHeaderQueue(lastSyncCheck: number, syncCheckRepeatMsecs: number): Promise<void> {\n    const stats = { count: 0, liveHeaderDupes: 0 }\n    let needSyncCheck = false\n    while (!needSyncCheck && !this.stopMainThread) {\n      const queuedResult = await this.processNextQueuedHeader(stats)\n      needSyncCheck = queuedResult ?? (await this.waitForQueuedHeaders(stats, lastSyncCheck, syncCheckRepeatMsecs))\n    }\n  }\n\n  private formatIhrLog(prefix: string, header: BlockHeader, ihr: InsertHeaderResult): string {\n    return `${prefix} ${header.height}${ihr.added ? ' added' : ''}${ihr.dupe ? ' dupe' : ''}${ihr.isActiveTip ? ' isActiveTip' : ''}${ihr.reorgDepth ? ' reorg depth ' + ihr.reorgDepth : ''}${ihr.noPrev ? ' noPrev' : ''}${ihr.noActiveAncestor || ihr.noTip || ihr.badPrev ? ' error' : ''}`\n  }\n\n  private async processOneLiveHeader(\n    startHeader: BlockHeader\n  ): Promise<{ needSyncCheck: boolean; dupe: boolean; added: boolean }> {\n    let header = startHeader\n    let recursions = this.addLiveRecursionLimit\n\n    while (!this.stopMainThread) {\n      const ihr = await this.addLiveHeader(header)\n      if (this.invalidInsertHeaderResult(ihr)) {\n        this.log(`Ignoring liveHeader ${header.height} ${header.hash} due to invalid insert result.`)\n        return { needSyncCheck: true, dupe: false, added: false }\n      }\n      if (ihr.noPrev) {\n        // Previous header is unknown; request it by hash from the network and try adding it first.\n        if (recursions-- <= 0) {\n          this.log(\n            `Ignoring liveHeader ${header.height} ${header.hash} addLiveRecursionLimit=${this.addLiveRecursionLimit} exceeded.`\n          )\n          return { needSyncCheck: true, dupe: false, added: false }\n        }\n        const prevHeader = await this.getMissingBlockHeader(header.previousHash)\n        if (prevHeader == null) {\n          this.log(\n            `Ignoring liveHeader ${header.height} ${header.hash} failed to find previous header by hash ${asString(header.previousHash)}`\n          )\n          return { needSyncCheck: true, dupe: false, added: false }\n        }\n        // Retry adding prevHeader first; then re-queue current header.\n        this.liveHeaders.unshift(header)\n        header = prevHeader\n      } else {\n        if (this.subscriberCallbacksEnabled) this.log(this.formatIhrLog('addLiveHeader', header, ihr))\n        return { needSyncCheck: false, dupe: ihr.dupe, added: ihr.added }\n      }\n    }\n    return { needSyncCheck: false, dupe: false, added: false }\n  }\n\n  private async processOneBaseHeader(bheader: BaseBlockHeader): Promise<boolean> {\n    const prev = await this.storage.findLiveHeaderForBlockHash(bheader.previousHash)\n    if (prev == null) {\n      // Unknown previous hash — ignore without triggering a re-sync.\n      this.log(`Ignoring header with unknown previousHash ${bheader.previousHash} in live storage.`)\n      return false\n    }\n    const header: BlockHeader = { ...bheader, height: prev.height + 1, hash: blockHash(bheader) }\n    const ihr = await this.addLiveHeader(header)\n    if (this.invalidInsertHeaderResult(ihr)) {\n      this.log(`Ignoring invalid baseHeader ${header.height} ${header.hash}.`)\n      return false\n    }\n    if (this.subscriberCallbacksEnabled) this.log(this.formatIhrLog('addBaseHeader', header, ihr))\n    return ihr.added\n  }\n\n  private async checkAndEnableSubscribers(): Promise<void> {\n    if (this.subscriberCallbacksEnabled) return\n    const live = await this.storage.findLiveHeightRange()\n    if (!live.isEmpty) {\n      this.subscriberCallbacksEnabled = true\n      this.log(`listening at height of ${live.maxHeight}`)\n    }\n  }\n}\n","import { Chain } from '../../../sdk/types'\nimport { asString } from '../../../utility/utilityHelpers.noBuffer'\nimport { BaseBlockHeader, BlockHeader } from './Api/BlockHeaderApi'\nimport { ChaintracksClientApi, ChaintracksInfoApi, HeaderListener, ReorgListener } from './Api/ChaintracksClientApi'\n\ninterface FetchStatus<T> {\n  status: 'success' | 'error'\n  code?: string\n  description?: string\n  value?: T\n}\n\nexport interface ChaintracksServiceClientOptions {}\n\n/**\n * Connects to a ChaintracksService to implement 'ChaintracksClientApi'\n *\n */\nexport class ChaintracksServiceClient implements ChaintracksClientApi {\n  static createChaintracksServiceClientOptions(): ChaintracksServiceClientOptions {\n    const options: ChaintracksServiceClientOptions = {\n      useAuthrite: false\n    }\n    return options\n  }\n\n  options: ChaintracksServiceClientOptions\n\n  constructor(\n    public chain: Chain,\n    public serviceUrl: string,\n    options?: ChaintracksServiceClientOptions\n  ) {\n    this.options = options || ChaintracksServiceClient.createChaintracksServiceClientOptions()\n  }\n\n  async subscribeHeaders(_listener: HeaderListener): Promise<string> {\n    throw new Error('Method not implemented.')\n  }\n\n  async subscribeReorgs(_listener: ReorgListener): Promise<string> {\n    throw new Error('Method not implemented.')\n  }\n\n  async unsubscribe(_subscriptionId: string): Promise<boolean> {\n    throw new Error('Method not implemented.')\n  }\n\n  async currentHeight(): Promise<number> {\n    return await this.getPresentHeight()\n  }\n\n  async isValidRootForHeight(root: string, height: number): Promise<boolean> {\n    const r = await this.findHeaderForHeight(height)\n    if (r == null) return false\n    const isValid = root === asString(r.merkleRoot)\n    return isValid\n  }\n\n  async getJsonOrUndefined<T>(path: string): Promise<T | undefined> {\n    let e: Error | undefined\n    for (let retry = 0; retry < 3; retry++) {\n      try {\n        const r = await fetch(`${this.serviceUrl}${path}`)\n        const v = (await r.json()) as FetchStatus<T>\n        if (v.status === 'success') return v.value\n        // Some deployed chaintracks services report a missing resource as an\n        // error payload instead of a success with an undefined value. That is\n        // this method's \"or undefined\" case, not an exception: callers such as\n        // findHeaderForBlockHash are typed to return undefined on a miss, and\n        // Services.hashToHeader relies on that to reach its WhatsOnChain\n        // fallback. Genuine service errors still throw below.\n        else if (v.code === 'ERR_NOT_FOUND') return undefined\n        else e = new Error(JSON.stringify(v))\n      } catch (error_: unknown) {\n        e = error_ as Error\n      }\n      if (e && e.name !== 'ECONNRESET') break\n    }\n    if (e != null) throw e\n  }\n\n  async getJson<T>(path: string): Promise<T> {\n    const r = await this.getJsonOrUndefined<T>(path)\n    if (r === undefined) throw new Error('Value was undefined. Requested object may not exist.')\n    return r\n  }\n\n  async postJsonVoid<T>(path: string, params: T): Promise<void> {\n    const headers = { 'Content-Type': 'application/json' }\n    const r = await fetch(`${this.serviceUrl}${path}`, {\n      body: JSON.stringify(params),\n      method: 'POST',\n      headers\n      // cache: 'no-cache',\n    })\n    try {\n      const s = (await r.json()) as FetchStatus<void>\n      if (s.status === 'success') return\n      throw new Error(JSON.stringify(s))\n    } catch (e) {\n      console.log(`Exception: ${JSON.stringify(e)}`)\n      throw new Error(JSON.stringify(e))\n    }\n  }\n\n  //\n  // HTTP API FUNCTIONS\n  //\n\n  async addHeader(header: BaseBlockHeader): Promise<void> {\n    const r = await this.postJsonVoid('/addHeaderHex', header)\n    if (typeof r === 'string') throw new Error(r)\n  }\n\n  async startListening(): Promise<void> {\n    await this.getPresentHeight()\n  }\n\n  async listening(): Promise<void> {\n    await this.getPresentHeight()\n  }\n\n  async getChain(): Promise<Chain> {\n    return this.chain\n  }\n\n  async isListening(): Promise<boolean> {\n    try {\n      await this.getPresentHeight()\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  async isSynchronized(): Promise<boolean> {\n    return await this.isListening()\n  }\n\n  async getPresentHeight(): Promise<number> {\n    return await this.getJson('/getPresentHeight')\n  }\n\n  async getInfo(): Promise<ChaintracksInfoApi> {\n    return await this.getJson('/getInfo')\n  }\n\n  async findChainTipHeader(): Promise<BlockHeader> {\n    return await this.getJson('/findChainTipHeaderHex')\n  }\n\n  async findChainTipHash(): Promise<string> {\n    return await this.getJson('/findChainTipHashHex')\n  }\n\n  async getHeaders(height: number, count: number): Promise<string> {\n    return await this.getJson<string>(`/getHeaders?height=${height}&count=${count}`)\n  }\n\n  async findHeaderForHeight(height: number): Promise<BlockHeader | undefined> {\n    return await this.getJsonOrUndefined(`/findHeaderHexForHeight?height=${height}`)\n  }\n\n  async findHeaderForBlockHash(hash: string): Promise<BlockHeader | undefined> {\n    return await this.getJsonOrUndefined(`/findHeaderHexForBlockHash?hash=${hash}`)\n  }\n}\n","import { Chain } from '../../../sdk/types'\nimport { asString } from '../../../utility/utilityHelpers.noBuffer'\nimport { BaseBlockHeader, BlockHeader } from './Api/BlockHeaderApi'\nimport { ChaintracksClientApi, ChaintracksInfoApi, HeaderListener, ReorgListener } from './Api/ChaintracksClientApi'\n\nexport interface GoChaintracksServiceClientOptions {\n  /**\n   * Path prefix for the go-chaintracks HTTP API.\n   * Arcade exposes this at `/chaintracks/v2`.\n   */\n  apiPrefix?: string\n  fetch?: typeof fetch\n  /** Timeout for HTTP requests and the initial SSE handshake. */\n  requestTimeoutMsecs?: number\n  /** Initial delay before reconnecting a closed or failed SSE stream. */\n  reconnectWaitMsecs?: number\n  /** Maximum SSE reconnect delay. */\n  reconnectWaitMaxMsecs?: number\n}\n\ninterface GoChaintracksHeightResponse {\n  height: number\n}\n\ninterface GoChaintracksNetworkResponse {\n  network: string\n}\n\ninterface SseSubscription {\n  id: string\n  type: 'header' | 'reorg'\n  abort: AbortController\n  done: Promise<void>\n}\n\n/**\n * Client for go-chaintracks compatible HTTP services, including Arcade's\n * `/chaintracks/v2` surface. Unlike the legacy ChaintracksServiceClient, this\n * can subscribe to tip/reorg SSE streams and therefore drive Monitor block\n * processing without a local WhatsOnChain polling ingestor.\n */\nexport class GoChaintracksServiceClient implements ChaintracksClientApi {\n  private readonly baseUrl: string\n  private readonly fetcher: typeof fetch\n  private readonly requestTimeoutMsecs: number\n  private readonly reconnectWaitMsecs: number\n  private readonly reconnectWaitMaxMsecs: number\n  private readonly subscriptions = new Map<string, SseSubscription>()\n  private nextSubscriptionId = 1\n\n  constructor(\n    public chain: Chain,\n    serviceUrl: string,\n    options: GoChaintracksServiceClientOptions = {}\n  ) {\n    let base = serviceUrl\n    while (base.endsWith('/')) base = base.slice(0, -1)\n    let prefix = options.apiPrefix ?? ''\n    if (prefix !== '') {\n      if (!prefix.startsWith('/')) prefix = `/${prefix}`\n      while (prefix.endsWith('/')) prefix = prefix.slice(0, -1)\n    }\n    this.baseUrl = `${base}${prefix}`\n    this.fetcher = options.fetch ?? fetch\n    this.requestTimeoutMsecs = options.requestTimeoutMsecs ?? 30000\n    this.reconnectWaitMsecs = options.reconnectWaitMsecs ?? 1000\n    this.reconnectWaitMaxMsecs = options.reconnectWaitMaxMsecs ?? 60000\n    for (const [name, value] of [\n      ['requestTimeoutMsecs', this.requestTimeoutMsecs],\n      ['reconnectWaitMsecs', this.reconnectWaitMsecs],\n      ['reconnectWaitMaxMsecs', this.reconnectWaitMaxMsecs]\n    ] as const) {\n      if (!Number.isSafeInteger(value) || value < 1) {\n        throw new Error(`${name} must be a positive integer.`)\n      }\n    }\n    if (this.reconnectWaitMaxMsecs < this.reconnectWaitMsecs) {\n      throw new Error('reconnectWaitMaxMsecs must be greater than or equal to reconnectWaitMsecs.')\n    }\n  }\n\n  async currentHeight(): Promise<number> {\n    return await this.getPresentHeight()\n  }\n\n  async isValidRootForHeight(root: string, height: number): Promise<boolean> {\n    const h = await this.findHeaderForHeight(height)\n    return h != null && root === asString(h.merkleRoot)\n  }\n\n  async getChain(): Promise<Chain> {\n    const r = await this.getJson<GoChaintracksNetworkResponse | string>('/network')\n    return this.normalizeChain(typeof r === 'string' ? r : r.network)\n  }\n\n  async getInfo(): Promise<ChaintracksInfoApi> {\n    const tip = await this.findChainTipHeader()\n    return {\n      chain: await this.getChain(),\n      heightBulk: tip.height,\n      heightLive: tip.height,\n      storage: 'go-chaintracks',\n      bulkIngestors: [],\n      liveIngestors: ['GoChaintracksServiceClient'],\n      packages: []\n    }\n  }\n\n  async getPresentHeight(): Promise<number> {\n    const result = await this.getJson<GoChaintracksHeightResponse | number>('/height')\n    return typeof result === 'number' ? result : result.height\n  }\n\n  async getHeaders(height: number, count: number): Promise<string> {\n    const bytes = await this.getBinary(`/headers.bin?height=${height}&count=${count}`)\n    return asString(bytes)\n  }\n\n  async findChainTipHeader(): Promise<BlockHeader> {\n    return await this.getJson<BlockHeader>('/tip')\n  }\n\n  async findChainTipHash(): Promise<string> {\n    return (await this.findChainTipHeader()).hash\n  }\n\n  async findHeaderForHeight(height: number): Promise<BlockHeader | undefined> {\n    return await this.getJsonOrUndefined<BlockHeader>(`/header/height/${height}`)\n  }\n\n  async findHeaderForBlockHash(hash: string): Promise<BlockHeader | undefined> {\n    return await this.getJsonOrUndefined<BlockHeader>(`/header/hash/${hash}`)\n  }\n\n  async addHeader(_header: BaseBlockHeader): Promise<void> {\n    throw new Error('GoChaintracksServiceClient.addHeader is not supported by the remote v2 API.')\n  }\n\n  async startListening(): Promise<void> {\n    await this.getPresentHeight()\n  }\n\n  async listening(): Promise<void> {\n    await this.getPresentHeight()\n  }\n\n  async isListening(): Promise<boolean> {\n    try {\n      await this.getPresentHeight()\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  async isSynchronized(): Promise<boolean> {\n    return await this.isListening()\n  }\n\n  async subscribeHeaders(listener: HeaderListener): Promise<string> {\n    return this.subscribe('header', '/tip/stream', payload => {\n      listener(payload as BlockHeader)\n    })\n  }\n\n  async subscribeReorgs(listener: ReorgListener): Promise<string> {\n    return this.subscribe('reorg', '/reorg/stream', payload => {\n      const event = payload as {\n        depth?: number\n        oldTip?: BlockHeader\n        newTip?: BlockHeader\n        deactivatedHeaders?: BlockHeader[]\n      }\n      if (event.oldTip != null && event.newTip != null) {\n        listener(event.depth ?? 0, event.oldTip, event.newTip, event.deactivatedHeaders)\n      }\n    })\n  }\n\n  async unsubscribe(subscriptionId: string): Promise<boolean> {\n    const sub = this.subscriptions.get(subscriptionId)\n    if (sub == null) return false\n    this.subscriptions.delete(subscriptionId)\n    sub.abort.abort()\n    await sub.done.catch(() => {})\n    return true\n  }\n\n  private async subscribe(\n    type: SseSubscription['type'],\n    path: string,\n    onPayload: (payload: unknown) => void\n  ): Promise<string> {\n    const id = `${type}-${this.nextSubscriptionId++}`\n    const abort = new AbortController()\n    const done = this.runSseWithReconnect(path, abort.signal, onPayload)\n    this.subscriptions.set(id, { id, type, abort, done })\n    done\n      .catch(() => {})\n      .finally(() => {\n        const active = this.subscriptions.get(id)\n        if (active?.abort === abort) this.subscriptions.delete(id)\n      })\n    return id\n  }\n\n  private async runSseWithReconnect(\n    path: string,\n    signal: AbortSignal,\n    onPayload: (payload: unknown) => void\n  ): Promise<void> {\n    let failures = 0\n    while (!signal.aborted) {\n      try {\n        const receivedEvent = await this.runSse(path, signal, onPayload)\n        failures = receivedEvent ? 0 : failures + 1\n      } catch {\n        if (signal.aborted) return\n        failures++\n      }\n      const multiplier = Math.min(2 ** Math.max(0, failures - 1), 64)\n      const delay = Math.min(this.reconnectWaitMsecs * multiplier, this.reconnectWaitMaxMsecs)\n      await this.waitForReconnect(delay, signal)\n    }\n  }\n\n  private async waitForReconnect(msecs: number, signal: AbortSignal): Promise<void> {\n    if (signal.aborted || msecs <= 0) return\n    await new Promise<void>(resolve => {\n      let timeout: ReturnType<typeof setTimeout>\n      const onAbort = () => done()\n      const done = () => {\n        clearTimeout(timeout)\n        signal.removeEventListener('abort', onAbort)\n        resolve()\n      }\n      timeout = setTimeout(done, msecs)\n      signal.addEventListener('abort', onAbort, { once: true })\n    })\n  }\n\n  private async runSse(path: string, signal: AbortSignal, onPayload: (payload: unknown) => void): Promise<boolean> {\n    const controller = new AbortController()\n    const onAbort = () => controller.abort()\n    signal.addEventListener('abort', onAbort, { once: true })\n    const timeout = setTimeout(() => controller.abort(), this.requestTimeoutMsecs)\n    let receivedEvent = false\n    const observePayload = (payload: unknown) => {\n      receivedEvent = true\n      onPayload(payload)\n    }\n    try {\n      const response = await this.fetcher(this.url(path), {\n        headers: { Accept: 'text/event-stream' },\n        signal: controller.signal\n      })\n      clearTimeout(timeout)\n      if (!response.ok) {\n        throw new Error(`GET ${this.url(path)} failed ${response.status} ${response.statusText}`)\n      }\n      if (response.body == null) {\n        throw new Error(`GET ${this.url(path)} returned no response body`)\n      }\n\n      const reader = response.body.getReader()\n      const decoder = new TextDecoder()\n      let buffer = ''\n      try {\n        for (;;) {\n          const { done, value } = await reader.read()\n          if (done) break\n          buffer += decoder.decode(value, { stream: true })\n          buffer = this.processSseBuffer(buffer, observePayload)\n        }\n        buffer += decoder.decode()\n        this.processSseBuffer(`${buffer}\\n\\n`, observePayload)\n      } finally {\n        reader.releaseLock()\n      }\n    } finally {\n      clearTimeout(timeout)\n      signal.removeEventListener('abort', onAbort)\n    }\n    return receivedEvent\n  }\n\n  private processSseBuffer(buffer: string, onPayload: (payload: unknown) => void): string {\n    buffer = buffer.replaceAll('\\r\\n', '\\n')\n    for (;;) {\n      const boundary = buffer.indexOf('\\n\\n')\n      if (boundary < 0) return buffer\n      const eventText = buffer.slice(0, boundary)\n      buffer = buffer.slice(boundary + 2)\n      const data = eventText\n        .split(/\\r?\\n/)\n        .filter(line => line.startsWith('data:'))\n        .map(line => line.slice(5).trimStart())\n        .join('\\n')\n      if (data === '') continue\n      try {\n        onPayload(JSON.parse(data))\n      } catch {\n        // Ignore malformed events; the next SSE event can still be valid.\n      }\n    }\n  }\n\n  private async getJson<T>(path: string): Promise<T> {\n    const r = await this.getJsonOrUndefined<T>(path)\n    if (r === undefined) throw new Error(`Value was undefined for ${path}. Requested object may not exist.`)\n    return r\n  }\n\n  private async getJsonOrUndefined<T>(path: string): Promise<T | undefined> {\n    const response = await this.fetchWithTimeout(this.url(path), { headers: { Accept: 'application/json' } })\n    if (response.status === 404) return undefined\n    if (!response.ok) {\n      throw new Error(`GET ${this.url(path)} failed ${response.status} ${response.statusText}`)\n    }\n    const value = (await response.json()) as unknown\n    if (value != null && typeof value === 'object' && 'status' in value) {\n      const envelope = value as { status?: string; value?: T; description?: string }\n      if (envelope.status === 'success') return envelope.value\n      if (envelope.status === 'error') throw new Error(envelope.description ?? `GET ${this.url(path)} failed`)\n    }\n    return value as T\n  }\n\n  private async getBinary(path: string): Promise<Uint8Array> {\n    const response = await this.fetchWithTimeout(this.url(path), { headers: { Accept: 'application/octet-stream' } })\n    if (!response.ok) {\n      throw new Error(`GET ${this.url(path)} failed ${response.status} ${response.statusText}`)\n    }\n    return new Uint8Array(await response.arrayBuffer())\n  }\n\n  private async fetchWithTimeout(url: string, init: RequestInit): Promise<Response> {\n    const controller = new AbortController()\n    const timeout = setTimeout(() => controller.abort(), this.requestTimeoutMsecs)\n    try {\n      return await this.fetcher(url, { ...init, signal: controller.signal })\n    } finally {\n      clearTimeout(timeout)\n    }\n  }\n\n  private url(path: string): string {\n    return `${this.baseUrl}${path}`\n  }\n\n  private normalizeChain(network: string): Chain {\n    switch (network.trim().toLowerCase()) {\n      case 'main':\n      case 'mainnet':\n        return 'main'\n      case 'test':\n      case 'testnet':\n        return 'test'\n      case 'stn':\n      case 'scalingtestnet':\n        return 'stn'\n      case 'ttn':\n      case 'teratest':\n      case 'teratestnet':\n        return 'ttn'\n      case 'tstn':\n      case 'teranodescalingtestnet':\n        return 'tstn'\n      default:\n        throw new Error(`Unsupported ChainTracks upstream network '${network}'.`)\n    }\n  }\n}\n","import { BulkIngestorApi, BulkIngestorBaseOptions, BulkSyncResult } from '../Api/BulkIngestorApi'\nimport { ChaintracksStorageApi } from '../Api/ChaintracksStorageApi'\n\nimport { BulkHeaderFilesInfo } from '../util/BulkHeaderFile'\nimport { HeightRange, HeightRanges } from '../util/HeightRange'\nimport { Chain } from '../../../../sdk/types'\nimport { BlockHeader } from '../Api/BlockHeaderApi'\nimport { ChaintracksStorageBase } from '../Storage/ChaintracksStorageBase'\n\nexport abstract class BulkIngestorBase implements BulkIngestorApi {\n  /**\n   *\n   * @param chain\n   * @param localCachePath defaults to './data/ingest_headers/'\n   * @returns\n   */\n  static createBulkIngestorBaseOptions (chain: Chain) {\n    const options: BulkIngestorBaseOptions = {\n      chain,\n      jsonResource: `${chain}NetBlockHeaders.json`\n    }\n    return options\n  }\n\n  chain: Chain\n  jsonFilename: string\n  log: (...args: any[]) => void = () => {}\n\n  constructor (options: BulkIngestorBaseOptions) {\n    if (!options.jsonResource) throw new Error('The jsonFilename options property is required.')\n    this.chain = options.chain\n    this.jsonFilename = options.jsonResource\n  }\n\n  private storageEngine: ChaintracksStorageBase | undefined\n\n  async setStorage (storage: ChaintracksStorageBase, log: (...args: any[]) => void): Promise<void> {\n    this.storageEngine = storage\n    this.log = log\n  }\n\n  async shutdown (): Promise<void> { /* intentional no-op: subclasses override when needed */ }\n\n  storageOrUndefined (): ChaintracksStorageApi | undefined {\n    return this.storageEngine\n  }\n\n  storage (): ChaintracksStorageBase {\n    if (this.storageEngine == null) throw new Error('storageEngine must be set.')\n    return this.storageEngine\n  }\n\n  /**\n   * information about locally cached bulk header files managed by this bulk ingestor\n   */\n  filesInfo: BulkHeaderFilesInfo | undefined\n\n  /**\n   * At least one derived BulkIngestor must override this method to provide the current height of the active chain tip.\n   * @returns undefined unless overridden\n   */\n  async getPresentHeight (): Promise<number | undefined> {\n    return undefined\n  }\n\n  /**\n   * A BulkIngestor fetches and updates storage with bulk headers in bulkRange.\n   *\n   * If it can, it must also fetch live headers in fetch range that are not in bulkRange and return them as an array.\n   *\n   * The storage methods `insertBulkFile`, `updateBulkFile`, and `addBulkHeaders` should be used to add bulk headers to storage.\n   *\n   * @param before bulk and live range of headers before ingesting any new headers.\n   * @param fetchRange range of headers still needed, includes both missing bulk and live headers.\n   * @param bulkRange range of bulk headers still needed\n   * @param priorLiveHeaders any headers accumulated by prior bulk ingestor(s) that are too recent for bulk storage.\n   * @returns new live headers: headers in fetchRange but not in bulkRange\n   */\n  abstract fetchHeaders (\n    before: HeightRanges,\n    fetchRange: HeightRange,\n    bulkRange: HeightRange,\n    priorLiveHeaders: BlockHeader[]\n  ): Promise<BlockHeader[]>\n\n  /**\n   * A BulkIngestor has two potential goals:\n   * 1. To source missing bulk headers and include them in bulk storage.\n   * 2. To source missing live headers to be forwarded to live storage.\n   *\n   * @param presentHeight current height of the active chain tip, may lag the true value.\n   * @param before current bulk and live storage height ranges, either may be empty.\n   * @param priorLiveHeaders any headers accumulated by prior bulk ingestor(s) that are too recent for bulk storage.\n   * @returns updated priorLiveHeaders including any accumulated by this ingestor\n   */\n  async synchronize (\n    presentHeight: number,\n    before: HeightRanges,\n    priorLiveHeaders: BlockHeader[]\n  ): Promise<BulkSyncResult> {\n    const storage = this.storage()\n\n    const r: BulkSyncResult = {\n      liveHeaders: priorLiveHeaders,\n      liveRange: HeightRange.from(priorLiveHeaders),\n      done: false,\n      log: ''\n    }\n\n    // Decisions to be made:\n    // Q1. Are we already done?\n    // Q2. Are there live headers that should be migrated to bulk?\n    // Q3. What range of headers do we still need to retrieve?\n\n    // Q1: We are done if we have enough live headers and they include presentHeight.\n    const currentFullRange = before.bulk.union(before.live)\n    if (currentFullRange.maxHeight >= presentHeight) {\n      r.done = true\n      return r\n    }\n\n    const targetBulkRange = new HeightRange(0, Math.max(0, presentHeight - storage.liveHeightThreshold))\n    let missingBulkRange = targetBulkRange.subtract(before.bulk)\n\n    const updateMissingBulkRange = async () => {\n      before = await storage.getAvailableHeightRanges()\n      missingBulkRange = targetBulkRange.subtract(before.bulk)\n    }\n\n    // Q2: If missingBulkRange isn't empty and there are live headers in storage,\n    // migrate from existing live headers in excess of reorgHeightThreshold.\n    if (!missingBulkRange.isEmpty && !before.live.isEmpty) {\n      const countToMigrate = Math.min(\n        missingBulkRange.length,\n        Math.max(0, before.live.length - storage.reorgHeightThreshold)\n      )\n      r.log += `Migrating ${countToMigrate} live headers to bulk storage.\\n`\n      await storage.migrateLiveToBulk(countToMigrate)\n      await updateMissingBulkRange()\n      if (!missingBulkRange.isEmpty) {\n        // If there are still missing bulk headers, MUST flush live storage.\n        const countToFlush = before.live.length\n        r.log += `Flushing ${countToFlush} live headers from live storage.\\n`\n        await storage.deleteLiveBlockHeaders()\n        await updateMissingBulkRange()\n      }\n    }\n\n    const targetFullRange = new HeightRange(0, presentHeight)\n    // Q3: What to fetch...\n    let rangeToFetch: HeightRange\n    if (missingBulkRange.isEmpty) {\n      // If there are no missing bulk headers, we don't need existing bulk range.\n      rangeToFetch = targetFullRange.subtract(before.bulk)\n      // And if there are live headers in excess of reorgHeightThreshold, they can be skipped as well.\n      if (before.live.length > storage.reorgHeightThreshold) {\n        rangeToFetch = rangeToFetch.subtract(\n          new HeightRange(before.live.minHeight, before.live.maxHeight - storage.reorgHeightThreshold)\n        )\n      }\n    } else {\n      // If there are missing bulk headers, ingest from start of missing through present height.\n      rangeToFetch = new HeightRange(missingBulkRange.minHeight, presentHeight)\n    }\n\n    const newLiveHeaders = await this.fetchHeaders(before, rangeToFetch, missingBulkRange, priorLiveHeaders)\n\n    await updateMissingBulkRange()\n\n    r.liveHeaders = newLiveHeaders\n    r.liveRange = HeightRange.from(r.liveHeaders)\n    r.done = missingBulkRange.isEmpty && r.liveRange.maxHeight >= presentHeight\n\n    return r\n  }\n}\n","/* eslint-disable @typescript-eslint/no-empty-function */\nimport { Chain } from '../../../../sdk/types'\nimport { LiveIngestorApi } from '../Api/LiveIngestorApi'\nimport { ChaintracksStorageApi } from '../Api/ChaintracksStorageApi'\nimport { BlockHeader } from '../Api/BlockHeaderApi'\n\nexport interface LiveIngestorBaseOptions {\n  /**\n   * The target chain: \"main\" or \"test\"\n   */\n  chain: Chain\n}\n\n/**\n *\n */\nexport abstract class LiveIngestorBase implements LiveIngestorApi {\n  static createLiveIngestorBaseOptions (chain: Chain) {\n    const options: LiveIngestorBaseOptions = {\n      chain\n    }\n    return options\n  }\n\n  chain: Chain\n  log: (...args: any[]) => void = () => {}\n\n  constructor (options: LiveIngestorBaseOptions) {\n    this.chain = options.chain\n  }\n\n  /**\n   * Release resources.\n   * Override if required.\n   */\n  async shutdown (): Promise<void> {}\n\n  private storageEngine?: ChaintracksStorageApi\n\n  /**\n   * Allocate resources.\n   * @param storage coordinating storage engine.\n   */\n  async setStorage (storage: ChaintracksStorageApi, log: (...args: any[]) => void): Promise<void> {\n    this.storageEngine = storage\n    this.log = log\n  }\n\n  /**\n   *\n   * @returns coordinating storage engine.\n   */\n  storage (): ChaintracksStorageApi {\n    if (this.storageEngine == null) throw new Error('storageEngine must be set.')\n    return this.storageEngine\n  }\n\n  /**\n   * Called to retrieve a missing block header,\n   * when the previousHash of a new header is unknown.\n   *\n   * @param hash block hash of missing header\n   */\n  abstract getHeaderByHash (hash: string): Promise<BlockHeader | undefined>\n\n  /**\n   * Begin retrieving new block headers.\n   *\n   * New headers are pushed onto the liveHeaders array.\n   *\n   * Continue waiting for new headers.\n   *\n   * Return only when either `stopListening` or `shutdown` are called.\n   *\n   * Be prepared to resume listening after `stopListening` but not\n   * after `shutdown`.\n   *\n   * @param liveHeaders\n   */\n  abstract startListening (liveHeaders: BlockHeader[]): Promise<void>\n\n  /**\n   * Causes `startListening` to stop listening for new block headers and return.\n   */\n  abstract stopListening (): void\n}\n","import { WERR_INTERNAL } from '../../../../sdk'\nimport { BulkFileDataManager } from './BulkFileDataManager'\nimport { BulkHeaderFileInfo } from './BulkHeaderFile'\nimport { HeightRange } from './HeightRange'\n\nexport class BulkFileDataReader {\n  readonly manager: BulkFileDataManager\n  readonly range: HeightRange\n  readonly maxBufferSize: number\n  nextHeight: number\n\n  constructor (manager: BulkFileDataManager, range: HeightRange, maxBufferSize: number) {\n    this.manager = manager\n    this.range = range\n    this.maxBufferSize = maxBufferSize\n    this.nextHeight = range.minHeight\n  }\n\n  /**\n   * Returns the Buffer of block headers from the given `file` for the given `range`.\n   * If `range` is undefined, the file's full height range is read.\n   * The returned Buffer will only contain headers in `file` and in `range`\n   * @param file\n   * @param range\n   */\n  private async readBufferFromFile (file: BulkHeaderFileInfo, range?: HeightRange): Promise<Uint8Array | undefined> {\n    // Constrain the range to the file's contents...\n    let fileRange = new HeightRange(file.firstHeight, file.firstHeight + file.count - 1)\n    if (range != null) fileRange = fileRange.intersect(range)\n    if (fileRange.isEmpty) return undefined\n    const offset = (fileRange.minHeight - file.firstHeight) * 80\n    const length = fileRange.length * 80\n    return await this.manager.getDataFromFile(file, offset, length)\n  }\n\n  /**\n   * @returns an array containing the next `maxBufferSize` bytes of headers from the files.\n   */\n  async read (): Promise<Uint8Array | undefined> {\n    if (this.nextHeight === undefined || !this.range || this.range.isEmpty || this.nextHeight > this.range.maxHeight) { return undefined }\n    let lastHeight = this.nextHeight + this.maxBufferSize / 80 - 1\n    lastHeight = Math.min(lastHeight, this.range.maxHeight)\n    let file = await this.manager.getFileForHeight(this.nextHeight)\n    if (file == null) throw new WERR_INTERNAL('logic error')\n    const readRange = new HeightRange(this.nextHeight, lastHeight)\n    const buffers = new Uint8Array(readRange.length * 80)\n    let offset = 0\n    while (file != null) {\n      const buffer = await this.readBufferFromFile(file, readRange)\n      if (buffer == null) break\n      buffers.set(buffer, offset)\n      offset += buffer.length\n      file = await this.manager.getFileForHeight(file.firstHeight + file.count)\n    }\n    if (!buffers.length || offset !== readRange.length * 80) return undefined\n    this.nextHeight = lastHeight + 1\n    return buffers\n  }\n}\n","import { defaultHttpClient, HttpClient } from '@bsv/sdk'\nimport { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'\nimport { wait } from '../../../../utility/utilityHelpers'\n\nconst MAX_RETRIES = 3\nconst DEFAULT_RETRY_MSECS = 1000\n\nexport class ChaintracksFetchError extends Error {\n  constructor (\n    message: string,\n    public readonly url: string,\n    public readonly status: number,\n    public readonly statusText: string,\n    public readonly retryAfterMsecs?: number\n  ) {\n    super(message)\n    this.name = 'ChaintracksFetchError'\n  }\n\n  get retryable (): boolean {\n    return isRetryableHttpStatus(this.status)\n  }\n}\n\nfunction isRetryableHttpStatus (status: number): boolean {\n  return status === 408 || status === 429 || status >= 500\n}\n\nfunction retryAfterMsecs (response: Response): number | undefined {\n  const retryAfter = response.headers.get('retry-after')\n  if (retryAfter == null || retryAfter === '') return undefined\n  const seconds = Number(retryAfter)\n  if (Number.isFinite(seconds) && seconds >= 0) return seconds * 1000\n  const dateMsecs = Date.parse(retryAfter)\n  if (!Number.isFinite(dateMsecs)) return undefined\n  return Math.max(0, dateMsecs - Date.now())\n}\n\nfunction retryWaitMsecs (retry: number, retryAfter?: number): number {\n  return Math.min(retryAfter ?? DEFAULT_RETRY_MSECS * (retry + 1), 2 * 60 * 1000)\n}\n\nasync function waitIfRetryable (response: Response, retry: number): Promise<boolean> {\n  if (!isRetryableHttpStatus(response.status) || retry >= MAX_RETRIES) return false\n  await wait(retryWaitMsecs(retry, retryAfterMsecs(response)))\n  return true\n}\n\nfunction fetchError (url: string, response: Response, kind: string): ChaintracksFetchError {\n  const retryAfter = retryAfterMsecs(response)\n  return new ChaintracksFetchError(\n    `Failed to ${kind} from ${url}: ${response.status} ${response.statusText}`,\n    url,\n    response.status,\n    response.statusText,\n    retryAfter\n  )\n}\n\n/**\n * This class implements the ChaintracksFetchApi\n * using the @bsv/sdk `defaultHttpClient`.\n */\nexport class ChaintracksFetch implements ChaintracksFetchApi {\n  httpClient: HttpClient = defaultHttpClient()\n\n  async download (url: string): Promise<Uint8Array> {\n    for (let retry = 0; ; retry++) {\n      const response = await fetch(url, {\n        method: 'GET',\n        headers: {\n          'Content-Type': 'application/octet-stream'\n        }\n      })\n\n      if (!response.ok) {\n        if (await waitIfRetryable(response, retry)) continue\n        throw fetchError(url, response, 'download')\n      }\n\n      const data = await response.arrayBuffer()\n\n      return new Uint8Array(data)\n    }\n  }\n\n  async fetchJson<R>(url: string): Promise<R> {\n    const requestJsonOptions = {\n      method: 'GET',\n      headers: {\n        Accept: 'application/json'\n      }\n    }\n    let json: R\n    for (let retry = 0; ; retry++) {\n      const response = await fetch(url, requestJsonOptions)\n      if (!response.ok) {\n        if (await waitIfRetryable(response, retry)) continue\n        throw fetchError(url, response, 'fetch JSON')\n      }\n      json = (await response.json()) as R\n      break\n    }\n    return json\n  }\n\n  pathJoin (baseUrl: string, subpath: string): string {\n    // Ensure the subpath doesn't start with a slash to avoid issues\n    const cleanSubpath = subpath.replace(/^\\/+/, '')\n    if (!baseUrl.endsWith('/')) baseUrl += '/'\n    // Create a new URL object and append the subpath\n    const url = new URL(cleanSubpath, baseUrl)\n    return url.toString()\n  }\n}\n","import { BulkFileDataReader } from './BulkFileDataReader'\nimport { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'\nimport { BlockHeader, Chain, WERR_INTERNAL, WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../../../sdk'\nimport { Hash } from '@bsv/sdk'\nimport { asArray, asString, asUint8Array } from '../../../../utility/utilityHelpers.noBuffer'\nimport { BulkHeaderFileInfo, BulkHeaderFilesInfo } from './BulkHeaderFile'\nimport { isKnownValidBulkHeaderFile, validBulkHeaderFiles } from './validBulkHeaderFilesByFileHash'\nimport { HeightRange } from './HeightRange'\nimport {\n  addWork,\n  convertBitsToWork,\n  deserializeBlockHeader,\n  serializeBaseBlockHeaders,\n  subWork,\n  validateBufferOfHeaders,\n  validateGenesisHeader\n} from './blockHeaderUtilities'\nimport { ChaintracksStorageBulkFileApi } from '../Api/ChaintracksStorageApi'\nimport { ChaintracksFetch } from './ChaintracksFetch'\nimport { ChaintracksFsApi } from '../Api/ChaintracksFsApi'\nimport { SingleWriterMultiReaderLock } from './SingleWriterMultiReaderLock'\n\nexport interface BulkFileDataManagerOptions {\n  chain: Chain\n  maxPerFile: number\n  maxRetained?: number\n  fetch?: ChaintracksFetchApi\n  fromKnownSourceUrl?: string\n}\n\n/**\n * Manages bulk file data (typically 8MB chunks of 100,000 headers each).\n *\n * If not cached in memory,\n * optionally fetches data by `sourceUrl` from CDN on demand,\n * optionally finds data by `fileId` in a database on demand,\n * and retains a limited number of files in memory,\n * subject to the optional `maxRetained` limit.\n */\nexport class BulkFileDataManager {\n  static createDefaultOptions(chain: Chain): BulkFileDataManagerOptions {\n    return {\n      chain,\n      maxPerFile: 100000,\n      maxRetained: 2,\n      fetch: new ChaintracksFetch(),\n      fromKnownSourceUrl: 'https://cdn.projectbabbage.com/blockheaders'\n    }\n  }\n\n  private log: (...args: any[]) => void = () => {}\n\n  private bfds: BulkFileData[] = []\n  private fileHashToIndex: Record<string, number> = {}\n  private readonly lock: SingleWriterMultiReaderLock = new SingleWriterMultiReaderLock()\n  private storage?: ChaintracksStorageBulkFileApi\n\n  readonly chain: Chain\n  readonly maxPerFile: number\n  readonly fetch?: ChaintracksFetchApi\n  readonly maxRetained?: number\n  readonly fromKnownSourceUrl?: string\n\n  constructor(options: BulkFileDataManagerOptions | Chain) {\n    const resolvedOptions = typeof options === 'object' ? options : BulkFileDataManager.createDefaultOptions(options)\n    this.chain = resolvedOptions.chain\n    this.maxPerFile = resolvedOptions.maxPerFile\n    this.maxRetained = resolvedOptions.maxRetained\n    this.fromKnownSourceUrl = resolvedOptions.fromKnownSourceUrl\n    this.fetch = resolvedOptions.fetch\n\n    this.deleteBulkFilesNoLock()\n  }\n\n  async deleteBulkFiles(): Promise<void> {\n    return await this.lock.withWriteLock(async () => this.deleteBulkFilesNoLock())\n  }\n\n  private deleteBulkFilesNoLock(): void {\n    this.bfds = []\n    this.fileHashToIndex = {}\n\n    if (this.fromKnownSourceUrl) {\n      const vbhfs = validBulkHeaderFiles\n      const filtered = vbhfs.filter(f => f.sourceUrl === this.fromKnownSourceUrl)\n      const files = selectBulkHeaderFiles(filtered, this.chain, this.maxPerFile)\n      for (const file of files) {\n        this.add({ ...file, fileHash: file.fileHash!, mru: Date.now() })\n      }\n    }\n  }\n\n  /**\n   * If `bfds` are going to be backed by persistent storage,\n   * must be called before making storage available.\n   *\n   * Synchronizes bfds and storage files, after which this manager maintains sync.\n   * There should be no changes to bulk files by direct access to storage bulk file methods.\n   */\n  async setStorage(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void> {\n    return await this.lock.withWriteLock(async () => await this.setStorageNoLock(storage, log))\n  }\n\n  private async setStorageNoLock(storage: ChaintracksStorageBulkFileApi, log: (...args: any[]) => void): Promise<void> {\n    this.storage = storage\n    this.log = log\n\n    // Get files currently in persistent storage.\n    const sfs = await this.storage.getBulkFiles()\n\n    // Sync bfds with storage. Two scenarios supported:\n\n    const bfdsRanges = this.heightRangesFromBulkFiles(this.bfds)\n    const sfsRanges = this.heightRangesFromBulkFiles(sfs)\n\n    if (sfsRanges.cdn.length >= bfdsRanges.cdn.length) {\n      // Storage win if it has greater or equal CDN coverage\n      // Replace all bfds with sfs\n      this.bfds = []\n      for (const file of sfs) {\n        const vbf: BulkFileData = await this.validateFileInfo(file)\n        this.bfds.push(vbf)\n      }\n    } else {\n      // Bfds win if they have greater CDN coverage\n      // Replace all sfs with bfds\n      const reversedFiles = [...sfs]\n      reversedFiles.reverse()\n      for (const s of reversedFiles) await this.storage.deleteBulkFile(s.fileId!)\n      for (const bfd of this.bfds) {\n        await this.ensureData(bfd)\n        bfd.fileId = await this.storage.insertBulkFile(bfdToInfo(bfd, true))\n      }\n    }\n  }\n\n  heightRangesFromBulkFiles(files: BulkHeaderFileInfo[]): {\n    all: HeightRange\n    cdn: HeightRange\n    incremental: HeightRange\n  } {\n    const ranges = { all: new HeightRange(0, -1), cdn: new HeightRange(0, -1), incremental: new HeightRange(0, -1) }\n    for (const file of files) {\n      const range = new HeightRange(file.firstHeight, file.firstHeight + file.count - 1)\n      ranges.all = ranges.all.union(range)\n      if (isBdfCdn(file)) ranges.cdn = ranges.cdn.union(range)\n      if (isBdfIncremental(file)) ranges.incremental = ranges.incremental.union(range)\n    }\n    return ranges\n  }\n\n  async createReader(range?: HeightRange, maxBufferSize?: number): Promise<BulkFileDataReader> {\n    range = range || (await this.getHeightRange())\n    maxBufferSize = maxBufferSize || 1000000 * 80 // 100,000 headers, 8MB\n    return new BulkFileDataReader(this, range, maxBufferSize)\n  }\n\n  async updateFromUrl(cdnUrl: string): Promise<void> {\n    if (this.fetch == null) throw new WERR_INVALID_OPERATION('fetch is not defined in the BulkFileDataManager.')\n\n    const toUrl = (file: string) => this.fetch!.pathJoin(cdnUrl, file)\n    const url = toUrl(`${this.chain}NetBlockHeaders.json`)\n\n    const availableBulkFiles = await this.fetch.fetchJson<BulkHeaderFilesInfo>(url)\n    if (!availableBulkFiles) {\n      throw new WERR_INVALID_PARAMETER('cdnUrl', `a valid BulkHeaderFilesInfo JSON resource available from ${url}`)\n    }\n\n    const selectedFiles = selectBulkHeaderFiles(\n      availableBulkFiles.files,\n      this.chain,\n      this.maxPerFile || availableBulkFiles.headersPerFile\n    )\n    for (const bf of selectedFiles) {\n      if (!bf.fileHash) {\n        throw new WERR_INVALID_PARAMETER('fileHash', `valid for all files in json downloaded from ${url}`)\n      }\n      if (!bf.chain || bf.chain !== this.chain) {\n        throw new WERR_INVALID_PARAMETER('chain', `\"${this.chain}\" for all files in json downloaded from ${url}`)\n      }\n      if (!bf.sourceUrl || bf.sourceUrl !== cdnUrl) bf.sourceUrl = cdnUrl\n    }\n\n    const rangeBefore = await this.getHeightRange()\n    await this.merge(selectedFiles)\n    const rangeAfter = await this.getHeightRange()\n\n    let log = 'BulkDataFileManager.updateFromUrl\\n'\n    log += `  url: ${url}\\n`\n    log += `  bulk range before: ${rangeBefore}\\n`\n    log += `  bulk range after:  ${rangeAfter}\\n`\n    this.log(log)\n  }\n\n  async merge(files: BulkHeaderFileInfo[]): Promise<BulkFileDataManagerMergeResult> {\n    return await this.lock.withWriteLock(async () => await this.mergeNoLock(files))\n  }\n\n  private async mergeNoLock(files: BulkHeaderFileInfo[]): Promise<BulkFileDataManagerMergeResult> {\n    const r: BulkFileDataManagerMergeResult = { inserted: [], updated: [], unchanged: [], dropped: [] }\n    for (const file of files) {\n      const hbf = this.getBfdForHeight(file.firstHeight)\n      if (hbf != null && file.fileId) hbf.fileId = file.fileId // Always update fileId if provided\n      const lbf = this.getLastBfd()\n      if (\n        hbf?.fileHash === file.fileHash &&\n        hbf.count === file.count &&\n        hbf.lastHash === file.lastHash &&\n        hbf.lastChainWork === file.lastChainWork\n      ) {\n        // We already have an identical matching file...\n        r.unchanged.push(bfdToInfo(hbf))\n        continue\n      }\n      const vbf: BulkFileData = await this.validateFileInfo(file)\n      if (hbf != null) {\n        // We have a matching file by firstHeight but count and fileHash differ\n        await this.update(vbf, hbf, r)\n      } else if (isBdfIncremental(vbf) && lbf != null && isBdfIncremental(lbf)) {\n        await this.mergeIncremental(lbf, vbf, r)\n      } else {\n        const added = await this.add(vbf)\n        r.inserted.push(added)\n      }\n    }\n    this.log(`BulkFileDataManager.merge:\\n${this.toLogString(r)}\\n`)\n    return r\n  }\n\n  private async mergeIncremental(lbf: BulkFileData, vbf: BulkFileData, r: BulkFileDataManagerMergeResult) {\n    lbf.count += vbf.count\n    lbf.lastHash = vbf.lastHash\n    lbf.lastChainWork = vbf.lastChainWork\n    await this.ensureData(lbf)\n    const newData = new Uint8Array(lbf.data!.length + vbf.data!.length)\n    newData.set(lbf.data!)\n    newData.set(vbf.data!, lbf.data!.length)\n    lbf.data = newData\n    delete this.fileHashToIndex[lbf.fileHash]\n    lbf.fileHash = asString(Hash.sha256(asArray(newData)), 'base64')\n    this.fileHashToIndex[lbf.fileHash] = this.bfds.length - 1\n    lbf.mru = Date.now()\n    const lbfInfo = bfdToInfo(lbf, true)\n    r.updated.push(lbfInfo)\n    if (this.storage != null && lbf.fileId) {\n      await this.storage.updateBulkFile(lbf.fileId, lbfInfo)\n    }\n  }\n\n  toLogString(what?: BulkFileDataManagerMergeResult | BulkFileData[] | BulkHeaderFileInfo[]): string {\n    let log = ''\n    if (what == null) {\n      log += this.toLogString(this.bfds)\n    } else if ((what as Partial<BulkFileDataManagerMergeResult>).updated) {\n      what = what as BulkFileDataManagerMergeResult\n      for (const { category, bfds } of [\n        { category: 'unchanged', bfds: what.unchanged },\n        { category: 'dropped', bfds: what.dropped },\n        { category: 'updated', bfds: what.updated },\n        { category: 'inserted', bfds: what.inserted }\n      ]) {\n        if (bfds.length > 0) {\n          log += `  ${category}:\\n`\n          log += this.toLogString(bfds)\n        }\n      }\n    } else if (Array.isArray(what)) {\n      what = what as BulkHeaderFileInfo[]\n      let i = -1\n      for (const bfd of what) {\n        i++\n        log += `  ${i}: ${bfd.fileName} fileId=${bfd.fileId} ${bfd.firstHeight}-${bfd.firstHeight + bfd.count - 1}\\n`\n      }\n    }\n\n    return log\n  }\n\n  async mergeIncrementalBlockHeaders(newBulkHeaders: BlockHeader[], incrementalChainWork?: string): Promise<void> {\n    if (newBulkHeaders.length === 0) return\n    return await this.lock.withWriteLock(async () => {\n      const lbf = this.getLastFileNoLock()\n      const nextHeight = lbf != null ? lbf.firstHeight + lbf.count : 0\n\n      // Trim headers that already exist in bulk storage, adjusting chain work accordingly.\n      ;({ headers: newBulkHeaders, incrementalChainWork } = trimAlreadyStoredHeaders(\n        newBulkHeaders,\n        nextHeight,\n        incrementalChainWork\n      ))\n\n      if (newBulkHeaders.length === 0) return\n      if (nextHeight !== newBulkHeaders[0].height) {\n        throw new WERR_INVALID_PARAMETER('newBulkHeaders', 'an extension of existing bulk headers')\n      }\n      if (lbf != null && !lbf.lastHash) {\n        throw new WERR_INTERNAL(`lastHash is not defined for the last bulk file ${lbf.fileName}`)\n      }\n\n      const prevChainWork = lbf?.lastChainWork ?? '00'.repeat(32)\n      const prevHash = lbf?.lastHash ?? '00'.repeat(32)\n\n      const lastChainWork = incrementalChainWork\n        ? addWork(incrementalChainWork, prevChainWork)\n        : computeChainWorkFromHeaders(newBulkHeaders, lbf)\n\n      const data = serializeBaseBlockHeaders(newBulkHeaders)\n      const fileHash = asString(Hash.sha256(asArray(data)), 'base64')\n      const bf: BulkHeaderFileInfo = {\n        fileId: undefined,\n        chain: this.chain,\n        sourceUrl: undefined,\n        fileName: 'incremental',\n        firstHeight: newBulkHeaders[0].height,\n        count: newBulkHeaders.length,\n        prevChainWork,\n        lastChainWork,\n        prevHash,\n        lastHash: newBulkHeaders.at(-1)!.hash,\n        fileHash,\n        data\n      }\n      await this.mergeNoLock([bf])\n    })\n  }\n\n  async getBulkFiles(keepData?: boolean): Promise<BulkHeaderFileInfo[]> {\n    return await this.lock.withReadLock(async () => {\n      return this.bfds.map(bfd => bfdToInfo(bfd, keepData))\n    })\n  }\n\n  async getHeightRange(): Promise<HeightRange> {\n    return await this.lock.withReadLock(async () => {\n      if (this.bfds.length === 0) return HeightRange.empty\n      const first = this.bfds[0]\n      const last = this.bfds.at(-1)!\n      return new HeightRange(first.firstHeight, last.firstHeight + last.count - 1)\n    })\n  }\n\n  async getDataFromFile(file: BulkHeaderFileInfo, offset?: number, length?: number): Promise<Uint8Array | undefined> {\n    const bfd = this.getBfdForHeight(file.firstHeight)\n    if (bfd == null || bfd.count < file.count) {\n      throw new WERR_INVALID_PARAMETER(\n        'file',\n        `a match for ${file.firstHeight}, ${file.count} in the BulkFileDataManager.`\n      )\n    }\n    return await this.lock.withReadLock(async () => await this.getDataFromFileNoLock(bfd, offset, length))\n  }\n\n  private async getDataFromFileNoLock(\n    bfd: BulkFileData,\n    offset?: number,\n    length?: number\n  ): Promise<Uint8Array | undefined> {\n    const fileLength = bfd.count * 80\n    offset = offset || 0\n    if (offset > fileLength - 1) return undefined\n    length = length || bfd.count * 80 - offset\n    length = Math.min(length, fileLength - offset)\n    let data: Uint8Array | undefined\n    if (bfd.data != null) {\n      data = bfd.data.slice(offset, offset + length)\n    } else if (bfd.fileId && this.storage != null) {\n      data = await this.storage.getBulkFileData(bfd.fileId, offset, length)\n    }\n    if (data == null) {\n      await this.ensureData(bfd)\n      if (bfd.data != null) data = bfd.data.slice(offset, offset + length)\n    }\n    if (data == null) return undefined\n    return data\n  }\n\n  async findHeaderForHeightOrUndefined(height: number): Promise<BlockHeader | undefined> {\n    return await this.lock.withReadLock(async () => {\n      if (!Number.isInteger(height) || height < 0) {\n        throw new WERR_INVALID_PARAMETER('height', `a non-negative integer (${height}).`)\n      }\n      const file = this.bfds.find(f => f.firstHeight <= height && f.firstHeight + f.count > height)\n      if (file == null) return undefined\n      const offset = (height - file.firstHeight) * 80\n      const data = await this.getDataFromFileNoLock(file, offset, 80)\n      if (data == null) return undefined\n      const header = deserializeBlockHeader(data, height, 0)\n      return header\n    })\n  }\n\n  async getFileForHeight(height: number): Promise<BulkHeaderFileInfo | undefined> {\n    return await this.lock.withReadLock(async () => {\n      const bfd = this.getBfdForHeight(height)\n      if (bfd == null) return undefined\n      return bfdToInfo(bfd)\n    })\n  }\n\n  private getBfdForHeight(height: number): BulkFileData | undefined {\n    if (!Number.isInteger(height) || height < 0) {\n      throw new WERR_INVALID_PARAMETER('height', `a non-negative integer (${height}).`)\n    }\n    const file = this.bfds.find(f => f.firstHeight <= height && f.firstHeight + f.count > height)\n    return file\n  }\n\n  private getLastBfd(fromEnd = 1): BulkFileData | undefined {\n    if (this.bfds.length < fromEnd) return undefined\n    const bfd = this.bfds[this.bfds.length - fromEnd]\n    return bfd\n  }\n\n  async getLastFile(fromEnd = 1): Promise<BulkHeaderFileInfo | undefined> {\n    return await this.lock.withReadLock(async () => this.getLastFileNoLock(fromEnd))\n  }\n\n  private getLastFileNoLock(fromEnd = 1): BulkHeaderFileInfo | undefined {\n    const bfd = this.getLastBfd(fromEnd)\n    if (bfd == null) return undefined\n    return bfdToInfo(bfd)\n  }\n\n  private async getDataByFileHash(fileHash: string): Promise<Uint8Array | undefined> {\n    const index = this.fileHashToIndex[fileHash]\n    if (index === undefined) {\n      throw new WERR_INVALID_PARAMETER('fileHash', `known to the BulkFileDataManager. ${fileHash} is unknown.`)\n    }\n    const bfd = this.bfds[index]\n    const data = await this.ensureData(bfd)\n    return data\n  }\n\n  private async getDataByFileId(fileId: number): Promise<Uint8Array | undefined> {\n    const bfd = this.bfds.find(f => f.fileId === fileId)\n    if (bfd === undefined) {\n      throw new WERR_INVALID_PARAMETER('fileId', `known to the BulkFileDataManager. ${fileId} is unknown.`)\n    }\n    const data = await this.ensureData(bfd)\n    return data\n  }\n\n  private async validateFileInfo(file: BulkHeaderFileInfo): Promise<BulkFileData> {\n    if (file.chain !== this.chain) throw new WERR_INVALID_PARAMETER('chain', `${this.chain}`)\n    if (file.count <= 0) {\n      throw new WERR_INVALID_PARAMETER('bf.count', `expected count to be greater than 0, but got ${file.count}`)\n    }\n    if (file.count > this.maxPerFile && file.fileName !== 'incremental') {\n      throw new WERR_INVALID_PARAMETER('count', `less than or equal to maxPerFile ${this.maxPerFile}`)\n    }\n    if (!file.fileHash) throw new WERR_INVALID_PARAMETER('fileHash', 'defined')\n    if (!file.sourceUrl && !file.fileId && file.data == null) {\n      throw new WERR_INVALID_PARAMETER('data', 'defined when sourceUrl and fileId are undefined')\n    }\n\n    const bfd: BulkFileData = { ...file, fileHash: file.fileHash, mru: Date.now() }\n\n    if (!bfd.validated) {\n      await this.validateBfdData(bfd, file.fileHash)\n      bfd.validated = true\n    }\n\n    return bfd\n  }\n\n  private async validateBfdData(bfd: BulkFileData, expectedFileHash: string): Promise<void> {\n    await this.ensureData(bfd)\n\n    if (bfd.data?.length !== bfd.count * 80) {\n      throw new WERR_INVALID_PARAMETER(\n        'file.data',\n        `bulk file ${bfd.fileName} data length ${bfd.data?.length} does not match expected count ${bfd.count}`\n      )\n    }\n\n    bfd.fileHash = asString(Hash.sha256(asArray(bfd.data)), 'base64')\n    if (expectedFileHash && expectedFileHash !== bfd.fileHash) {\n      throw new WERR_INVALID_PARAMETER('file.fileHash', `expected ${expectedFileHash} but got ${bfd.fileHash}`)\n    }\n\n    if (!isKnownValidBulkHeaderFile(bfd)) {\n      this.validateBfdHeaders(bfd)\n    }\n  }\n\n  private validateBfdHeaders(bfd: BulkFileData): void {\n    const pbf = bfd.firstHeight > 0 ? this.getBfdForHeight(bfd.firstHeight - 1) : undefined\n    const prevHash = pbf?.lastHash ?? '00'.repeat(32)\n    const prevChainWork = pbf?.lastChainWork ?? '00'.repeat(32)\n\n    const { lastHeaderHash, lastChainWork } = validateBufferOfHeaders(bfd.data!, prevHash, 0, undefined, prevChainWork)\n\n    if (bfd.lastHash && bfd.lastHash !== lastHeaderHash) {\n      throw new WERR_INVALID_PARAMETER('file.lastHash', `expected ${bfd.lastHash} but got ${lastHeaderHash}`)\n    }\n    if (bfd.lastChainWork && bfd.lastChainWork !== lastChainWork) {\n      throw new WERR_INVALID_PARAMETER('file.lastChainWork', `expected ${bfd.lastChainWork} but got ${lastChainWork}`)\n    }\n\n    bfd.lastHash = lastHeaderHash\n    bfd.lastChainWork = lastChainWork!\n\n    if (bfd.firstHeight === 0) validateGenesisHeader(bfd.data!, bfd.chain!)\n  }\n\n  async ReValidate(): Promise<void> {\n    return await this.lock.withReadLock(async () => await this.ReValidateNoLock())\n  }\n\n  private async ReValidateNoLock(): Promise<void> {\n    for (const file of this.bfds) {\n      await this.ensureData(file)\n      file.validated = false // Reset validation to re-validate on next access\n      const bfd = await this.validateFileInfo(file)\n      if (!bfd.validated) throw new WERR_INTERNAL(`BulkFileDataManager.ReValidate failed for file ${bfd.fileName}`)\n      file.validated = true\n    }\n  }\n\n  private validateBfdForAdd(bfd: BulkFileData): void {\n    if (this.bfds.length === 0 && bfd.firstHeight !== 0) {\n      throw new WERR_INVALID_PARAMETER('firstHeight', '0 for the first file')\n    }\n    if (this.bfds.length > 0) {\n      const last = this.bfds.at(-1)!\n      if (bfd.firstHeight !== last.firstHeight + last.count) {\n        throw new WERR_INVALID_PARAMETER('firstHeight', \"the last file's firstHeight + count\")\n      }\n      if (bfd.prevHash !== last.lastHash || bfd.prevChainWork !== last.lastChainWork) {\n        throw new WERR_INVALID_PARAMETER('prevHash/prevChainWork', \"the last file's lastHash/lastChainWork\")\n      }\n    }\n  }\n\n  private async add(bfd: BulkFileData): Promise<BulkHeaderFileInfo> {\n    this.validateBfdForAdd(bfd)\n    const index = this.bfds.length\n    this.bfds.push(bfd)\n    this.fileHashToIndex[bfd.fileHash] = index\n    this.ensureMaxRetained()\n    const info = bfdToInfo(bfd, true)\n    if (this.storage != null) {\n      info.fileId = bfd.fileId = await this.storage.insertBulkFile(info)\n    }\n    return info\n  }\n\n  private replaceBfdAtIndex(index: number, update: BulkFileData): void {\n    const oldBfd = this.bfds[index]\n    delete this.fileHashToIndex[oldBfd.fileHash]\n    this.bfds[index] = update\n    this.fileHashToIndex[update.fileHash] = index\n  }\n\n  /**\n   * Updating an existing file occurs in two specific contexts:\n   *\n   * 1. CDN Update: CDN files of a specific `maxPerFile` series typically ends in a partial file\n   * which may periodically add more headers until the next file is started.\n   * If the CDN update is the second to last file (followed by an incremental file),\n   * then the incremental file is updated or deleted and also returned as the result (with a count of zero if deleted).\n   *\n   * 2. Incremental Update: The last bulk file is almost always an \"incremental\" file\n   * which is not limited by \"maxPerFile\" and holds all non-CDN bulk headers.\n   * If is updated with new bulk headers which come either from non CDN ingestors or from live header migration to bulk.\n   *\n   * Updating preserves the following properties:\n   *\n   * - Any existing headers following this update are preserved and must form an unbroken chain.\n   * - There can be at most one incremental file and it must be the last file.\n   * - The update start conditions (height, prevHash, prevChainWork) must match an existing file which may be either CDN or internal.\n   * - The update fileId must match, it may be undefind.\n   * - The fileName does not need to match.\n   * - The incremental file must always have fileName \"incremental\" and sourceUrl must be undefined.\n   * - The update count must be greater than 0.\n   * - The update count must be greater than current count for CDN to CDN update.\n   *\n   * @param update new validated BulkFileData to update.\n   * @param hbf corresponding existing BulkFileData to update.\n   */\n  private async update(update: BulkFileData, hbf: BulkFileData, r: BulkFileDataManagerMergeResult): Promise<void> {\n    if (\n      hbf?.firstHeight !== update.firstHeight ||\n      hbf?.prevChainWork !== update.prevChainWork ||\n      hbf?.prevHash !== update.prevHash\n    ) {\n      throw new WERR_INVALID_PARAMETER('file', 'an existing file by height, prevChainWork and prevHash')\n    }\n    if (isBdfCdn(update) === isBdfCdn(hbf) && update.count <= hbf.count) {\n      throw new WERR_INVALID_PARAMETER('file.count', `greater than the current count ${hbf.count}`)\n    }\n\n    const { index, truncate, replaced, drop } = await this.resolveUpdatePlan(update, hbf)\n\n    this.replaceBfdAtIndex(index, update)\n    if (truncate != null) await this.shiftWork(update, truncate, replaced)\n    if (drop != null) this.dropLastBulkFile(drop)\n\n    await this.persistUpdate(update, truncate, replaced, drop)\n    this.recordUpdateResults(r, update, truncate, replaced, drop)\n    this.ensureMaxRetained()\n  }\n\n  private async resolveUpdatePlan(\n    update: BulkFileData,\n    hbf: BulkFileData\n  ): Promise<{ index: number; truncate?: BulkFileData; replaced?: BulkFileData; drop?: BulkFileData }> {\n    const lbf = this.getLastBfd()!\n    const index = this.bfds.length - 1\n\n    if (hbf.firstHeight === lbf.firstHeight) {\n      return await this.resolveLastFileUpdate(update, lbf, index)\n    }\n\n    return await this.resolvePenultimateFileUpdate(update, hbf, lbf, index)\n  }\n\n  private async resolveLastFileUpdate(\n    update: BulkFileData,\n    lastFile: BulkFileData,\n    index: number\n  ): Promise<{ index: number; truncate?: BulkFileData }> {\n    let truncate: BulkFileData | undefined\n\n    // Update targets the last file — three cases.\n    if (isBdfIncremental(update)) {\n      // 1. Incremental → incremental extension.\n      if (!isBdfIncremental(lastFile))\n        throw new WERR_INVALID_PARAMETER('file', 'an incremental file to update an existing incremental file')\n    } else if (isBdfCdn(lastFile)) {\n      // 2. CDN → CDN replacement (must grow).\n      if (update.count <= lastFile.count)\n        throw new WERR_INVALID_PARAMETER(\n          'update.count',\n          `CDN update must have more headers. ${update.count} <= ${lastFile.count}`\n        )\n    } else if (update.count < lastFile.count) {\n      // 3. New CDN partially replaces incremental tail — retain excess incremental headers.\n      await this.ensureData(lastFile)\n      truncate = lastFile\n    }\n\n    return { index, truncate }\n  }\n\n  private async resolvePenultimateFileUpdate(\n    update: BulkFileData,\n    expectedFile: BulkFileData,\n    lastFile: BulkFileData,\n    lastIndex: number\n  ): Promise<{ index: number; truncate?: BulkFileData; replaced?: BulkFileData; drop?: BulkFileData }> {\n    // Update targets the second-to-last file — it must replace a CDN file and\n    // the last file must be incremental.\n    const penultimateFile = this.getLastBfd(2)\n    if (penultimateFile?.firstHeight !== expectedFile.firstHeight)\n      throw new WERR_INVALID_PARAMETER('file', 'an update to last or second to last file')\n    if (!isBdfCdn(update) || !isBdfCdn(penultimateFile) || update.count <= penultimateFile.count)\n      throw new WERR_INVALID_PARAMETER('file', 'a CDN file update with more headers than the current CDN file')\n    if (!isBdfIncremental(lastFile))\n      throw new WERR_INVALID_PARAMETER('file', 'a CDN file update followed by an incremental file')\n    if (!update.fileId) update.fileId = penultimateFile.fileId\n\n    if (update.count >= penultimateFile.count + lastFile.count) {\n      return { index: lastIndex - 1, drop: lastFile }\n    }\n\n    await this.ensureData(lastFile)\n    return {\n      index: lastIndex - 1,\n      truncate: lastFile,\n      replaced: penultimateFile\n    }\n  }\n\n  private async persistUpdate(\n    update: BulkFileData,\n    truncate: BulkFileData | undefined,\n    replaced: BulkFileData | undefined,\n    drop: BulkFileData | undefined\n  ): Promise<void> {\n    if (this.storage == null) return\n    if (update.fileId) await this.storage.updateBulkFile(update.fileId, bfdToInfo(update, true))\n    if (truncate != null) {\n      const truncateInfo = bfdToInfo(truncate, true)\n      if (replaced != null) {\n        await this.storage.updateBulkFile(truncate.fileId!, truncateInfo)\n      } else {\n        truncateInfo.fileId = undefined\n        truncate.fileId = await this.storage.insertBulkFile(truncateInfo)\n      }\n    }\n    if (drop?.fileId) await this.storage.deleteBulkFile(drop.fileId)\n  }\n\n  private recordUpdateResults(\n    r: BulkFileDataManagerMergeResult,\n    update: BulkFileData,\n    truncate: BulkFileData | undefined,\n    replaced: BulkFileData | undefined,\n    drop: BulkFileData | undefined\n  ): void {\n    if (!r) return\n    r.updated.push(bfdToInfo(update, true))\n    if (truncate != null) {\n      const truncateInfo = bfdToInfo(truncate, true)\n      if (replaced != null) r.updated.push(truncateInfo)\n      else r.inserted.push(truncateInfo)\n    }\n    if (drop != null) r.dropped.push(bfdToInfo(drop))\n  }\n\n  private dropLastBulkFile(lbf: BulkFileData): void {\n    delete this.fileHashToIndex[lbf.fileHash]\n    const index = this.bfds.indexOf(lbf)\n    if (index !== this.bfds.length - 1) {\n      throw new WERR_INTERNAL('dropLastBulkFile requires lbf is the current last file.')\n    }\n    this.bfds.pop()\n  }\n\n  /**\n   * Remove work (and headers) from `truncate` that now exists in `update`.\n   * There are two scenarios:\n   * 1. `replaced` is undefined: update is a CDN file that splits an incremental file that must be truncated.\n   * 2. `replaced` is valid: update is a CDN update that replaced an existing CDN file and splits an incremental file that must be truncated.\n   * @param update the new CDN update file.\n   * @param truncate the incremental file to be truncated (losing work which now exists in `update`).\n   * @param replaced the existing CDN file that was replaced by `update` (if any).\n   */\n  private async shiftWork(update: BulkFileData, truncate: BulkFileData, replaced?: BulkFileData): Promise<void> {\n    const updateIndex = this.fileHashToIndex[update.fileHash]\n    // replaced will be valid if the update replaced it and it must become the new last file.\n    // truncateIndex will be updateIndex + 1 if the existing last file is being truncated and update is second to last.\n    const truncateIndex = this.fileHashToIndex[truncate.fileHash]\n    if (truncateIndex !== undefined && truncateIndex !== updateIndex + 1) {\n      throw new WERR_INTERNAL('shiftWork requires update to have replaced truncate or truncate to follow update')\n    }\n    if (truncateIndex !== undefined && replaced == null) {\n      throw new WERR_INTERNAL(\"shiftWork requires valid replaced when update hasn't replaced truncate\")\n    }\n\n    truncate.prevHash = update.lastHash!\n    truncate.prevChainWork = update.lastChainWork\n    // truncate.lastChainWork, truncate.lastHash remain unchanged\n    let count = update.count\n    if (replaced != null) {\n      count -= replaced.count\n    } else {\n      // The truncated file is itself being replaced by the update and must be inserted as a new file.\n      truncate.fileId = undefined\n      this.bfds.push(truncate) // Add the truncated file as a new entry.\n    }\n    truncate.count -= count\n    truncate.firstHeight += count\n\n    truncate.data = truncate.data?.slice(count * 80)\n    delete this.fileHashToIndex[truncate.fileHash]\n    truncate.fileHash = asString(Hash.sha256(asArray(truncate.data!)), 'base64')\n    this.fileHashToIndex[truncate.fileHash] = updateIndex + 1\n  }\n\n  /**\n   *\n   * @param bfd\n   * @returns\n   */\n  private async ensureData(bfd: BulkFileData): Promise<Uint8Array> {\n    if (bfd.data != null) return bfd.data\n\n    if (this.storage != null && bfd.fileId) {\n      bfd.data = await this.storage.getBulkFileData(bfd.fileId)\n      if (bfd.data == null) throw new WERR_INVALID_PARAMETER('fileId', `valid, data not found for fileId ${bfd.fileId}`)\n    }\n\n    if (bfd.data == null && this.fetch != null && bfd.sourceUrl) {\n      const url = this.fetch.pathJoin(bfd.sourceUrl, bfd.fileName)\n\n      try {\n        bfd.data = await this.fetch.download(url)\n      } catch (firstAttemptErr) {\n        // First download attempt failed (e.g. transient network error); retry once.\n        console.debug(`BulkFileDataManager: first download attempt failed for ${url}, retrying`, firstAttemptErr)\n        bfd.data = await this.fetch.download(url)\n      }\n      if (!bfd.data) throw new WERR_INVALID_PARAMETER('sourceUrl', `data not found for sourceUrl ${url}`)\n    }\n\n    if (bfd.data == null)\n      throw new WERR_INVALID_PARAMETER('data', `defined. Unable to retrieve data for ${bfd.fileName}`)\n\n    bfd.mru = Date.now()\n\n    // Validate retrieved data.\n    const fileHash = asString(Hash.sha256(asArray(bfd.data)), 'base64')\n    if (fileHash !== bfd.fileHash) {\n      throw new WERR_INVALID_PARAMETER('fileHash', `a match for retrieved data for ${bfd.fileName}`)\n    }\n\n    this.ensureMaxRetained()\n    return bfd.data\n  }\n\n  private ensureMaxRetained(): void {\n    if (this.maxRetained === undefined) return\n    const withData = this.bfds.filter(bfd => bfd.data != null && (bfd.fileId || bfd.sourceUrl))\n    let countToRelease = withData.length - this.maxRetained\n    if (countToRelease <= 0) return\n    const sorted = [...withData]\n    sorted.sort((a, b) => a.mru - b.mru)\n    while (countToRelease-- > 0 && sorted.length > 0) {\n      const oldest = sorted.shift()!\n      // Release the least recently used data\n      oldest.data = undefined // Release the data\n    }\n  }\n\n  async exportHeadersToFs(\n    toFs: ChaintracksFsApi,\n    toHeadersPerFile: number,\n    toFolder: string,\n    sourceUrl?: string,\n    maxHeight?: number\n  ): Promise<void> {\n    const chain = this.chain\n    const toFileName = (i: number) => `${chain}Net_${i}.headers`\n    const toPath = (i: number) => toFs.pathJoin(toFolder, toFileName(i))\n    const toJsonPath = () => toFs.pathJoin(toFolder, `${chain}NetBlockHeaders.json`)\n\n    const toBulkFiles: BulkHeaderFilesInfo = {\n      rootFolder: sourceUrl || toFolder,\n      jsonFilename: `${chain}NetBlockHeaders.json`,\n      headersPerFile: toHeadersPerFile,\n      files: []\n    }\n\n    let range = await this.getHeightRange()\n    if (maxHeight) range = range.intersect(new HeightRange(0, maxHeight))\n    const reader = await this.createReader(range, toHeadersPerFile * 80)\n\n    let firstHeight = 0\n    let lastHeaderHash = '00'.repeat(32)\n    let lastChainWork = '00'.repeat(32)\n\n    let i = -1\n    for (;;) {\n      i++\n      const data = await reader.read()\n      if (data == null || data.length === 0) {\n        break\n      }\n\n      const last = validateBufferOfHeaders(data, lastHeaderHash, 0, undefined, lastChainWork)\n\n      await toFs.writeFile(toPath(i), data)\n\n      const fileHash = asString(Hash.sha256(asArray(data)), 'base64')\n      const file: BulkHeaderFileInfo = {\n        chain,\n        count: data.length / 80,\n        fileHash,\n        fileName: toFileName(i),\n        firstHeight,\n        lastChainWork: last.lastChainWork!,\n        lastHash: last.lastHeaderHash,\n        prevChainWork: lastChainWork,\n        prevHash: lastHeaderHash,\n        sourceUrl\n      }\n      toBulkFiles.files.push(file)\n      firstHeight += file.count\n      lastHeaderHash = file.lastHash!\n      lastChainWork = file.lastChainWork!\n    }\n\n    await toFs.writeFile(toJsonPath(), asUint8Array(JSON.stringify(toBulkFiles), 'utf8'))\n  }\n}\n\ninterface BulkFileData extends BulkHeaderFileInfo {\n  mru: number\n  fileHash: string\n}\n\nexport function selectBulkHeaderFiles(\n  files: BulkHeaderFileInfo[],\n  chain: Chain,\n  maxPerFile: number\n): BulkHeaderFileInfo[] {\n  const r: BulkHeaderFileInfo[] = []\n  let height = 0\n  for (;;) {\n    const choices = files.filter(f => f.firstHeight === height && f.count <= maxPerFile && f.chain === chain)\n    // Pick the file with the maximum count\n    const choice = choices.reduce((a, b) => (a.count > b.count ? a : b), choices[0])\n    if (!choice) break // no more files to select\n    r.push(choice)\n    height += choice.count\n  }\n  return r\n}\n\nfunction isBdfIncremental(bfd: BulkFileData | BulkHeaderFileInfo): boolean {\n  return bfd.fileName === 'incremental' && !bfd.sourceUrl\n}\n\nfunction isBdfCdn(bfd: BulkFileData | BulkHeaderFileInfo): boolean {\n  return !isBdfIncremental(bfd)\n}\n\nfunction bfdToInfo(bfd: BulkFileData, keepData?: boolean): BulkHeaderFileInfo {\n  return {\n    chain: bfd.chain,\n    fileHash: bfd.fileHash,\n    fileName: bfd.fileName,\n    sourceUrl: bfd.sourceUrl,\n    fileId: bfd.fileId,\n    count: bfd.count,\n    prevChainWork: bfd.prevChainWork,\n    lastChainWork: bfd.lastChainWork,\n    firstHeight: bfd.firstHeight,\n    prevHash: bfd.prevHash,\n    lastHash: bfd.lastHash,\n    validated: bfd.validated || false,\n    data: keepData ? bfd.data : undefined\n  }\n}\n\nexport interface BulkFileDataManagerMergeResult {\n  unchanged: BulkHeaderFileInfo[]\n  inserted: BulkHeaderFileInfo[]\n  updated: BulkHeaderFileInfo[]\n  dropped: BulkHeaderFileInfo[]\n}\n\n/**\n * Drops any headers whose height is already covered by bulk storage,\n * reducing `incrementalChainWork` accordingly (when provided).\n */\nfunction trimAlreadyStoredHeaders(\n  headers: BlockHeader[],\n  nextHeight: number,\n  incrementalChainWork: string | undefined\n): { headers: BlockHeader[]; incrementalChainWork: string | undefined } {\n  if (nextHeight <= 0 || headers.length === 0 || headers[0].height >= nextHeight) {\n    return { headers, incrementalChainWork }\n  }\n  // Avoid mutating the caller's array.\n  headers = [...headers]\n  while (headers.length > 0 && headers[0].height < nextHeight) {\n    const h = headers.shift()\n    if (h != null && incrementalChainWork) {\n      incrementalChainWork = subWork(incrementalChainWork, convertBitsToWork(h.bits))\n    }\n  }\n  return { headers, incrementalChainWork }\n}\n\n/**\n * Computes `lastChainWork` for a sequence of new bulk headers extending `lbf`,\n * or beginning at genesis when bulk storage is empty, validating that the\n * sequence is contiguous.\n */\nfunction computeChainWorkFromHeaders(headers: BlockHeader[], lbf?: BulkHeaderFileInfo): string {\n  let lastHeight = lbf != null ? lbf.firstHeight + lbf.count - 1 : -1\n  let lastHash = lbf?.lastHash ?? '00'.repeat(32)\n  let lastChainWork = lbf?.lastChainWork ?? '00'.repeat(32)\n  for (const h of headers) {\n    if (h.height !== lastHeight + 1 || h.previousHash !== lastHash) {\n      throw new WERR_INVALID_PARAMETER(\n        'headers',\n        `an extension of existing bulk headers, header with height ${h.height} is non-sequential`\n      )\n    }\n    lastChainWork = addWork(lastChainWork, convertBitsToWork(h.bits))\n    lastHeight = h.height\n    lastHash = h.hash\n  }\n  return lastChainWork\n}\n\n// Re-export BulkFileDataReader for backward compatibility\nexport { BulkFileDataReader } from './BulkFileDataReader'\n","import { Chain } from '../../../../sdk/types'\nimport { BlockHeader } from '../Api/BlockHeaderApi'\nimport { BulkIngestorBaseOptions } from '../Api/BulkIngestorApi'\nimport { BulkIngestorBase } from './BulkIngestorBase'\nimport { BulkHeaderFileInfo, BulkHeaderFilesInfo } from '../util/BulkHeaderFile'\nimport { HeightRange, HeightRanges } from '../util/HeightRange'\nimport { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'\nimport { WERR_INVALID_PARAMETER } from '../../../../sdk'\nimport { selectBulkHeaderFiles } from '../util/BulkFileDataManager'\n\nexport interface BulkIngestorCDNOptions extends BulkIngestorBaseOptions {\n  /**\n   * Required.\n   *\n   * The name of the JSON resource to request from CDN which describes currently\n   * available bulk block header resources.\n   */\n  jsonResource: string | undefined\n\n  /**\n   * Required.\n   *\n   * URL to CDN implementing the bulk ingestor CDN service protocol\n   */\n  cdnUrl: string | undefined\n\n  maxPerFile: number | undefined\n\n  fetch: ChaintracksFetchApi\n}\n\nexport class BulkIngestorCDN extends BulkIngestorBase {\n  /**\n   *\n   * @param chain\n   * @param localCachePath defaults to './data/bulk_cdn_headers/'\n   * @returns\n   */\n  static createBulkIngestorCDNOptions (\n    chain: Chain,\n    cdnUrl: string,\n    fetch: ChaintracksFetchApi,\n    maxPerFile?: number\n  ): BulkIngestorCDNOptions {\n    const options: BulkIngestorCDNOptions = {\n      ...BulkIngestorBase.createBulkIngestorBaseOptions(chain),\n      fetch,\n      jsonResource: `${chain}NetBlockHeaders.json`,\n      cdnUrl,\n      maxPerFile\n    }\n    return options\n  }\n\n  fetch: ChaintracksFetchApi\n  jsonResource: string\n  cdnUrl: string\n  maxPerFile: number | undefined\n\n  availableBulkFiles: BulkHeaderFilesInfo | undefined\n  selectedFiles: BulkHeaderFileInfo[] | undefined\n  currentRange: HeightRange | undefined\n\n  constructor (options: BulkIngestorCDNOptions) {\n    super(options)\n    if (!options.jsonResource) throw new Error('The jsonResource options property is required.')\n    if (!options.cdnUrl) throw new Error('The cdnUrl options property is required.')\n\n    this.fetch = options.fetch\n    this.jsonResource = options.jsonResource\n    this.cdnUrl = options.cdnUrl\n    this.maxPerFile = options.maxPerFile\n  }\n\n  override async getPresentHeight (): Promise<number | undefined> {\n    return undefined\n  }\n\n  getJsonHttpHeaders (): Record<string, string> {\n    const headers: Record<string, string> = {\n      Accept: 'application/json'\n    }\n    return headers\n  }\n\n  /**\n   * A BulkFile CDN serves a JSON BulkHeaderFilesInfo resource which lists all the available binary bulk header files available and associated metadata.\n   *\n   * The term \"CDN file\" is used for a local bulk file that has a sourceUrl. (Not undefined)\n   * The term \"incremental file\" is used for the local bulk file that holds all the non-CDN bulk headers and must chain to the live headers if there are any.\n   *\n   * Bulk ingesting from a CDN happens in one of three contexts:\n   *\n   * 1. Cold Start: No local bulk or live headers.\n   * 2. Incremental: Available CDN files extend into an existing incremental file but not into the live headers.\n   * 3. Replace: Available CDN files extend into live headers.\n   *\n   * Context Cold Start:\n   * - The CDN files are selected in height order, starting at zero, always choosing the largest count less than the local maximum (maxPerFile).\n   *\n   * Context Incremental:\n   * - Last existing CDN file is updated if CDN now has a higher count.\n   * - Additional CDN files are added as in Cold Start.\n   * - The existing incremental file is truncated or deleted.\n   *\n   * Context Replace:\n   * - Existing live headers are truncated or deleted.\n   * - Proceed as context Incremental.\n   *\n   * @param before bulk and live range of headers before ingesting any new headers.\n   * @param fetchRange total range of header heights needed including live headers\n   * @param bulkRange range of missing bulk header heights required.\n   * @param priorLiveHeaders\n   * @returns\n   */\n  async fetchHeaders (\n    before: HeightRanges,\n    fetchRange: HeightRange,\n    bulkRange: HeightRange,\n    priorLiveHeaders: BlockHeader[]\n  ): Promise<BlockHeader[]> {\n    const storage = this.storage()\n\n    const toUrl = (file: string) => this.fetch.pathJoin(this.cdnUrl, file)\n\n    const url = toUrl(this.jsonResource)\n    this.availableBulkFiles = await this.fetch.fetchJson(url)\n    if (this.availableBulkFiles == null) {\n      throw new WERR_INVALID_PARAMETER(\n        `${this.jsonResource}`,\n        `a valid BulkHeaderFilesInfo JSON resource available from ${url}`\n      )\n    }\n    this.selectedFiles = selectBulkHeaderFiles(\n      this.availableBulkFiles.files,\n      this.chain,\n      this.maxPerFile || this.availableBulkFiles.headersPerFile\n    )\n    for (const bf of this.selectedFiles) {\n      if (!bf.fileHash) {\n        throw new WERR_INVALID_PARAMETER('fileHash', `valid for alll files in ${this.jsonResource} from ${url}`)\n      }\n      if (!bf.chain || bf.chain !== this.chain) {\n        throw new WERR_INVALID_PARAMETER('chain', `\"${this.chain}\" for all files in ${this.jsonResource} from ${url}`)\n      }\n      if (!bf.sourceUrl || bf.sourceUrl !== this.cdnUrl) bf.sourceUrl = this.cdnUrl\n    }\n\n    let log = 'BulkIngestorCDN fetchHeaders log:\\n'\n    log += `  url: ${url}\\n`\n\n    this.currentRange = await storage.bulkManager.getHeightRange()\n    log += `  bulk range before: ${this.currentRange}\\n`\n\n    const r = await storage.bulkManager.merge(this.selectedFiles)\n\n    this.currentRange = await storage.bulkManager.getHeightRange()\n    log += `  bulk range after:  ${this.currentRange}\\n`\n    for (const u of r.unchanged) {\n      log += `  unchanged: ${u.fileName}, fileId=${u.fileId}\\n`\n    }\n    for (const i of r.inserted) {\n      log += `  inserted: ${i.fileName}, fileId=${i.fileId}\\n`\n    }\n    for (const u of r.updated) {\n      log += `  updated: ${u.fileName}, fileId=${u.fileId}\\n`\n    }\n    this.log(log)\n\n    return priorLiveHeaders\n  }\n}\n","import { Chain } from '../../../../sdk/types'\nimport { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'\nimport { BulkIngestorCDN, BulkIngestorCDNOptions } from './BulkIngestorCDN'\n\nexport class BulkIngestorCDNBabbage extends BulkIngestorCDN {\n  /**\n   *\n   * @param chain\n   * @param rootFolder defaults to './data/bulk_cdn_babbage_headers/'\n   * @returns\n   */\n  static createBulkIngestorCDNBabbageOptions (chain: Chain, fetch: ChaintracksFetchApi): BulkIngestorCDNOptions {\n    const options: BulkIngestorCDNOptions = {\n      ...BulkIngestorCDN.createBulkIngestorCDNOptions(chain, 'https://cdn.projectbabbage.com/blockheaders/', fetch)\n    }\n    return options\n  }\n}\n","import { ChainTracker, defaultHttpClient, HttpClient, WhatsOnChainConfig } from '@bsv/sdk'\n\ninterface WhatsOnChainBlockHeader {\n  merkleroot: string\n}\n\n/**\n * Represents a chain tracker based on What's On Chain .\n */\nexport default class SdkWhatsOnChain implements ChainTracker {\n  readonly network: string\n  readonly apiKey: string\n  protected readonly URL: string\n  protected readonly httpClient: HttpClient\n\n  /**\n   * Constructs an instance of the WhatsOnChain ChainTracker.\n   *\n   * @param {'main' | 'test' | 'stn'} network - The BSV network to use when calling the WhatsOnChain API.\n   * @param {WhatsOnChainConfig} config - Configuration options for the WhatsOnChain ChainTracker.\n   */\n  constructor(network: 'main' | 'test' | 'stn' | 'ttn' | 'tstn' = 'main', config: WhatsOnChainConfig = {}) {\n    const { apiKey, httpClient } = config\n    this.network = network\n    if (network === 'ttn') {\n      this.URL = 'https://api.woc-ttn.bsvblockchain.tech/v1/bsv/test'\n    } else if (network === 'tstn') {\n      // tstn has no WhatsOnChain / explorer service. The instance is constructed for\n      // interface completeness but is not registered as a Services provider, so this URL\n      // is never used for requests.\n      this.URL = ''\n    } else {\n      this.URL = `https://api.whatsonchain.com/v1/bsv/${network}`\n    }\n    this.httpClient = httpClient ?? defaultHttpClient()\n    this.apiKey = apiKey ?? ''\n  }\n\n  async isValidRootForHeight(root: string, height: number): Promise<boolean> {\n    const requestOptions = {\n      method: 'GET',\n      headers: this.getHttpHeaders()\n    }\n\n    const response = await this.httpClient.request<WhatsOnChainBlockHeader>(\n      `${this.URL}/block/${height}/header`,\n      requestOptions\n    )\n    if (response.ok) {\n      const { merkleroot } = response.data\n      return merkleroot === root\n    } else if (response.status === 404) {\n      return false\n    } else {\n      throw new Error(\n        `Failed to verify merkleroot for height ${height} because of an error: ${JSON.stringify(response.data)} `\n      )\n    }\n  }\n\n  async currentHeight(): Promise<number> {\n    try {\n      const requestOptions = {\n        method: 'GET',\n        headers: this.getHttpHeaders()\n      }\n\n      const response = await this.httpClient.request<Array<{ height: number }>>(\n        `${this.URL}/block/headers`,\n        requestOptions\n      )\n      if (response.ok) {\n        return response.data[0]!.height\n      } else {\n        throw new Error(`Failed to get current height because of an error: ${JSON.stringify(response.data)} `)\n      }\n    } catch (error) {\n      throw new Error(\n        `Failed to get current height because of an error: ${error instanceof Error ? error.message : String(error)}`\n      )\n    }\n  }\n\n  protected getHttpHeaders(): Record<string, string> {\n    const headers: Record<string, string> = {\n      Accept: 'application/json'\n    }\n\n    if (typeof this.apiKey === 'string' && this.apiKey.trim() !== '') {\n      headers.Authorization = this.apiKey\n    }\n\n    return headers\n  }\n}\n","import { WalletError } from '../sdk/WalletError'\nimport { ProviderCallHistory, ServiceCallHistory } from '../sdk/WalletServices.interfaces'\n\nconst MAX_CALL_HISTORY = 32\n\nexport class ServiceCollection<T> {\n  services: Array<{ name: string, service: T }>\n  _index: number\n\n  /**\n   * Start of currentCounts interval. Initially instance construction time.\n   */\n  readonly since: Date\n  _historyByProvider: Record<string, ProviderCallHistory> = {}\n\n  constructor (\n    public serviceName: string,\n    services?: Array<{ name: string, service: T }>\n  ) {\n    this.services = services ?? []\n    this._index = 0\n    this.since = new Date()\n  }\n\n  add (s: { name: string, service: T }): this {\n    this.services.push(s)\n    return this\n  }\n\n  remove (name: string): void {\n    this.services = this.services.filter(s => s.name !== name)\n  }\n\n  get name (): string {\n    return this.services[this._index].name\n  }\n\n  get service (): T {\n    return this.services[this._index].service\n  }\n\n  getServiceToCall (i: number): ServiceToCall<T> {\n    const name = this.services[i].name\n    const service = this.services[i].service\n    const call = { name, when: new Date(), msecs: 0, success: false, result: undefined, error: undefined }\n    return { serviceName: this.serviceName, providerName: name, service, call }\n  }\n\n  get serviceToCall (): ServiceToCall<T> {\n    return this.getServiceToCall(this._index)\n  }\n\n  get allServicesToCall (): Array<ServiceToCall<T>> {\n    const all: Array<ServiceToCall<T>> = []\n    for (let i = 0; i < this.services.length; i++) {\n      all.push(this.getServiceToCall(i))\n    }\n    return all\n  }\n\n  /**\n   * Used to de-prioritize a service call by moving it to the end of the list.\n   * @param stc\n   */\n  moveServiceToLast (stc: ServiceToCall<T>): void {\n    const index = this.services.findIndex(s => s.name === stc.providerName)\n    if (index !== -1) {\n      const [service] = this.services.splice(index, 1)\n      this.services.push(service)\n    }\n  }\n\n  get allServices (): T[] {\n    return this.services.map(x => x.service)\n  }\n\n  get count (): number {\n    return this.services.length\n  }\n\n  get index (): number {\n    return this._index\n  }\n\n  reset (): void {\n    this._index = 0\n  }\n\n  next (): number {\n    this._index = (this._index + 1) % this.count\n    return this._index\n  }\n\n  clone (): ServiceCollection<T> {\n    return new ServiceCollection(this.serviceName, [...this.services])\n  }\n\n  _addServiceCall (providerName: string, call: ServiceCall): ProviderCallHistory {\n    const now = new Date()\n    let h = this._historyByProvider[providerName]\n    if (h == null) {\n      h = {\n        serviceName: this.serviceName,\n        providerName,\n        calls: [],\n        totalCounts: { success: 0, failure: 0, error: 0, since: this.since, until: now },\n        resetCounts: [{ success: 0, failure: 0, error: 0, since: this.since, until: now }]\n      }\n      this._historyByProvider[providerName] = h\n    }\n    h.calls.unshift(call)\n    h.calls = h.calls.slice(0, MAX_CALL_HISTORY)\n    h.totalCounts.until = now\n    h.resetCounts[0].until = now\n    return h\n  }\n\n  getDuration (since: Date | string): number {\n    const now = new Date()\n    if (typeof since === 'string') since = new Date(since)\n    return now.getTime() - since.getTime()\n  }\n\n  addServiceCallSuccess (stc: ServiceToCall<T>, result?: string): void {\n    const call = stc.call\n    call.success = true\n    call.result = result\n    call.error = undefined\n    call.msecs = this.getDuration(call.when)\n    const h = this._addServiceCall(stc.providerName, call)\n    h.totalCounts.success++\n    h.resetCounts[0].success++\n  }\n\n  addServiceCallFailure (stc: ServiceToCall<T>, result?: string): void {\n    const call = stc.call\n    call.success = false\n    call.result = result\n    call.error = undefined\n    call.msecs = this.getDuration(call.when)\n    const h = this._addServiceCall(this.name, call)\n    h.totalCounts.failure++\n    h.resetCounts[0].failure++\n  }\n\n  addServiceCallError (stc: ServiceToCall<T>, error: WalletError): void {\n    const call = stc.call\n    call.success = false\n    call.result = undefined\n    call.error = error\n    call.msecs = this.getDuration(call.when)\n    const h = this._addServiceCall(this.name, call)\n    h.totalCounts.failure++\n    h.totalCounts.error++\n    h.resetCounts[0].failure++\n    h.resetCounts[0].error++\n  }\n\n  /**\n   * @returns A copy of current service call history\n   */\n  getServiceCallHistory (reset?: boolean): ServiceCallHistory {\n    const now = new Date()\n    const history: ServiceCallHistory = { serviceName: this.serviceName, historyByProvider: {} }\n    for (const name of Object.keys(this._historyByProvider)) {\n      const h = this._historyByProvider[name]\n      const c: ProviderCallHistory = {\n        serviceName: h.serviceName,\n        providerName: h.providerName,\n        calls: h.calls.map(c => ({\n          when: dateToString(c.when),\n          msecs: c.msecs,\n          success: c.success,\n          result: c.result,\n          error: (c.error == null) ? undefined : { message: c.error.message, code: c.error.code }\n        })),\n        totalCounts: {\n          success: h.totalCounts.success,\n          failure: h.totalCounts.failure,\n          error: h.totalCounts.error,\n          since: dateToString(h.totalCounts.since),\n          until: dateToString(h.totalCounts.until)\n        },\n        resetCounts: []\n      }\n      for (const r of h.resetCounts) {\n        c.resetCounts.push({\n          success: r.success,\n          failure: r.failure,\n          error: r.error,\n          since: dateToString(r.since),\n          until: dateToString(r.until)\n        })\n      }\n      history.historyByProvider[name] = c\n      if (reset === true) {\n        // Make sure intervals are continuous.\n        h.resetCounts[0].until = now\n        // insert a new resetCounts interval\n        h.resetCounts.unshift({\n          success: 0,\n          failure: 0,\n          error: 0,\n          // start of new interval\n          since: now,\n          // end of new interval, gets bumped with each new call added\n          until: now\n        })\n        // limit history to most recent intervals\n        h.resetCounts = h.resetCounts.slice(0, MAX_CALL_HISTORY)\n      }\n    }\n    return history\n\n    function dateToString (d: Date | string): string {\n      return typeof d === 'string' ? d : d.toISOString()\n    }\n  }\n}\n\nexport interface ServiceCall {\n  /**\n   * string value must be Date's toISOString format.\n   */\n  when: Date | string\n  msecs: number\n  /**\n   * true iff service provider successfully processed the request\n   * false iff service provider failed to process the request which includes thrown errors.\n   */\n  success: boolean\n  /**\n   * Simple text summary of result. e.g. `not a valid utxo` or `valid utxo`\n   */\n  result?: string\n  /**\n   * Error code and message iff success is false and a exception was thrown.\n   */\n  error?: { message: string, code: string }\n}\n\nexport interface ServiceToCall<T> {\n  providerName: string\n  serviceName: string\n  service: T\n  call: ServiceCall\n}\n","import { Chain } from '../sdk/types'\n\n/**\n * Runtime service-endpoint configuration for Teranode networks that do not\n * have a public, operator-independent service endpoint.\n *\n * Unlike `main`, `test`, and `ttn`, the stn/tstn service endpoints are not public and must not be\n * hardcoded in this (public) source tree. They are supplied at runtime through environment\n * variables:\n *\n *   STN_ARCADE_URL        STN Arcade broadcaster / ARC endpoint base.\n *   STN_CHAINTRACKS_URL   STN ChainTracks service URL.\n *   TSTN_ARCADE_URL       Arcade broadcaster / ARC endpoint base. Also the fallback host for\n *                         ChainTracks when TSTN_CHAINTRACKS_URL is unset\n *                         (`${TSTN_ARCADE_URL}/chaintracks/v1`, mirroring the ttn layout).\n *   TSTN_CHAINTRACKS_URL  ChainTracks service URL.\n *\n * stn/tstn run only operator-configured Arcade and ChainTracks services; there is no\n * documented WhatsOnChain service for them, so no WhatsOnChain endpoint is configured and\n * the WhatsOnChain-only lookups (raw tx, utxo status, txid status, script-hash history) are not\n * available on stn/tstn.\n *\n * `process` is accessed defensively so importing this module remains safe in\n * browser bundles. Browser applications can still supply an explicit\n * ChaintracksClientApi without relying on environment variables.\n */\n\nfunction readEnv(name: string): string | undefined {\n  const env = typeof process !== 'undefined' ? process.env : undefined\n  const value = env?.[name]\n  return value != null && value.trim() !== '' ? value.trim() : undefined\n}\n\n/** Credential-free public Arcade host for supported networks. */\nexport function publicArcadeUrl(chain: Chain): string | undefined {\n  switch (chain) {\n    case 'main':\n      return 'https://arcade-v2-us-1.bsvblockchain.tech'\n    case 'test':\n      return 'https://arcade-v2-testnet-us-1.bsvblockchain.tech'\n    case 'ttn':\n      return 'https://arcade-v2-ttn-us-1.bsvblockchain.tech'\n    case 'stn':\n    case 'tstn':\n    case 'mock':\n      return undefined\n  }\n}\n\nconst stripTrailingSlash = (url: string): string => {\n  let end = url.length\n  while (end > 0 && url[end - 1] === '/') end--\n  return url.slice(0, end)\n}\n\n/** Arcade broadcaster / ARC endpoint for tstn, or `undefined` when `TSTN_ARCADE_URL` is unset. */\nexport function tstnArcadeUrl(): string | undefined {\n  return readEnv('TSTN_ARCADE_URL')\n}\n\n/** Arcade broadcaster / ARC endpoint for stn, or `undefined` when unset. */\nexport function stnArcadeUrl(): string | undefined {\n  return readEnv('STN_ARCADE_URL')\n}\n\n/**\n * ChainTracks service URL for tstn. Falls back to `${TSTN_ARCADE_URL}/chaintracks/v1` when\n * `TSTN_CHAINTRACKS_URL` is unset (mirrors the ttn layout). Throws when neither is configured.\n */\nexport function tstnChaintracksUrl(): string {\n  const explicit = readEnv('TSTN_CHAINTRACKS_URL')\n  if (explicit != null) return explicit\n  const arcade = tstnArcadeUrl()\n  if (arcade != null) return `${stripTrailingSlash(arcade)}/chaintracks/v1`\n  throw new Error(\n    'tstn chain requires a ChainTracks URL: set TSTN_CHAINTRACKS_URL (or TSTN_ARCADE_URL) in the environment.'\n  )\n}\n\n/**\n * ChainTracks service URL for stn. Falls back to the configured Arcade host's\n * legacy-compatible path when STN_CHAINTRACKS_URL is unset.\n */\nexport function stnChaintracksUrl(): string {\n  const explicit = readEnv('STN_CHAINTRACKS_URL')\n  if (explicit != null) return explicit\n  const arcade = stnArcadeUrl()\n  if (arcade != null) return `${stripTrailingSlash(arcade)}/chaintracks/v1`\n  throw new Error(\n    'stn chain requires a ChainTracks URL: set STN_CHAINTRACKS_URL (or STN_ARCADE_URL) in the environment.'\n  )\n}\n","import { Chain } from '../sdk/types'\nimport { WalletServicesOptions } from '../sdk/WalletServices.interfaces'\nimport { randomBytesHex } from '../utility/utilityHelpers'\nimport { ChaintracksClientApi } from './chaintracker/chaintracks/Api/ChaintracksClientApi'\nimport { ChaintracksServiceClient } from './chaintracker/chaintracks/ChaintracksServiceClient'\nimport { GoChaintracksServiceClient } from './chaintracker/chaintracks/GoChaintracksServiceClient'\nimport { publicArcadeUrl, stnArcadeUrl, stnChaintracksUrl, tstnArcadeUrl, tstnChaintracksUrl } from './networkConfig'\n\nfunction stripTrailingSlash(value: string): string {\n  let end = value.length\n  while (end > 0 && value[end - 1] === '/') end--\n  return value.slice(0, end)\n}\n\nfunction configuredChaintracksClient(chain: Chain, serviceUrl: string): ChaintracksClientApi {\n  let path = ''\n  try {\n    path = stripTrailingSlash(new URL(serviceUrl).pathname)\n  } catch {\n    // Preserve the legacy client's existing validation/error behavior for an\n    // operator-supplied non-URL value.\n  }\n  if (path.endsWith('/v2')) return new GoChaintracksServiceClient(chain, serviceUrl)\n  return new ChaintracksServiceClient(chain, serviceUrl)\n}\n\n/**\n * Returns the credential-free default ChainTracks client for a supported\n * public network, or an operator-configured client for stn/tstn.\n */\nexport function createDefaultChaintracksClient(chain: Exclude<Chain, 'mock'>): ChaintracksClientApi {\n  switch (chain) {\n    case 'main':\n    case 'test':\n    case 'ttn':\n      return new GoChaintracksServiceClient(chain, arcadeDefaultUrl(chain)!, {\n        apiPrefix: '/chaintracks/v2'\n      })\n    case 'stn':\n      return configuredChaintracksClient(chain, stnChaintracksUrl())\n    case 'tstn':\n      return configuredChaintracksClient(chain, tstnChaintracksUrl())\n  }\n}\n\nexport function createDefaultWalletServicesOptions(\n  ...[\n    chain,\n    arcCallbackUrl,\n    arcCallbackToken,\n    taalArcApiKey,\n    gorillaPoolArcApiKey,\n    bitailsApiKey,\n    deploymentId,\n    chaintracks,\n    arcadeUrl,\n    arcadeApiKey,\n    arcadeCallbackToken\n  ]: [\n    chain: Chain,\n    arcCallbackUrl?: string,\n    arcCallbackToken?: string,\n    taalArcApiKey?: string,\n    gorillaPoolArcApiKey?: string,\n    bitailsApiKey?: string,\n    deploymentId?: string,\n    chaintracks?: ChaintracksClientApi,\n    /**\n     * Optional Arcade endpoint. When provided (or when a default exists for the chain via\n     * `arcadeDefaultUrl`), Arcade is registered as the primary broadcaster ahead of ARC.\n     * Pass an empty string to explicitly disable the per-chain default.\n     */\n    arcadeUrl?: string,\n    /** Server-level API key (Bearer) for the Arcade endpoint, if it requires auth. */\n    arcadeApiKey?: string,\n    /**\n     * Stable SSE callback token. Must match the Monitor's `callbackToken` so Arcade routes\n     * each broadcast transaction's status events to this wallet's `/events` subscription.\n     */\n    arcadeCallbackToken?: string\n  ]\n): WalletServicesOptions {\n  if (chain === 'mock') {\n    throw new Error(\"createDefaultWalletServicesOptions does not support 'mock' chain. Use MockServices directly.\")\n  }\n\n  deploymentId ||= `wallet-toolbox-${randomBytesHex(16)}`\n\n  // The mainnet endpoint is always used since these are fiat exchange rates,\n  // independent of the chain being used.\n  const chaintracksFiatExchangeRatesUrl = 'https://mainnet-chaintracks.babbage.systems/getFiatExchangeRates'\n\n  chaintracks ||= createDefaultChaintracksClient(chain)\n\n  const o: WalletServicesOptions = {\n    chain,\n    taalApiKey: undefined,\n    bsvExchangeRate: {\n      timestamp: new Date('2025-08-31'),\n      base: 'USD',\n      rate: 26.17\n    },\n    bsvUpdateMsecs: 1000 * 60 * 15, // 15 minutes\n    fiatExchangeRates: {\n      timestamp: new Date('2025-08-31'),\n      base: 'USD',\n      rates: {\n        USD: 1,\n        GBP: 0.7528,\n        EUR: 0.8558\n      },\n      rateTimestamps: {\n        USD: new Date('2025-08-31'),\n        GBP: new Date('2025-08-31'),\n        EUR: new Date('2025-08-31')\n      }\n    },\n    fiatUpdateMsecs: 1000 * 60 * 60 * 24, // 24 hours\n    disableMapiCallback: true, // MAPI callback's are deprecated. Rely on WalletMonitor by default.\n    exchangeratesapiKey: undefined,\n    chaintracksFiatExchangeRatesUrl,\n    chaintracks,\n    arcUrl: arcDefaultUrl(chain),\n    arcConfig: {\n      apiKey: taalArcApiKey ?? undefined,\n      deploymentId,\n      callbackUrl: arcCallbackUrl ?? undefined,\n      callbackToken: arcCallbackToken ?? undefined\n    },\n    arcGorillaPoolUrl: arcGorillaPoolUrl(chain),\n    arcGorillaPoolConfig: {\n      apiKey: gorillaPoolArcApiKey ?? undefined,\n      deploymentId,\n      callbackUrl: arcCallbackUrl ?? undefined,\n      callbackToken: arcCallbackToken ?? undefined\n    },\n    bitailsApiKey\n  }\n\n  // Arcade (bsv-blockchain/arcade) primary broadcaster.\n  // Opt-in: enabled only when an explicit `arcadeUrl` is provided. Callers can pass\n  // `arcadeDefaultUrl(chain)` to use the known per-chain endpoint. Kept opt-in (rather\n  // than defaulted on) so existing consumers' broadcaster set is unchanged until the\n  // Arcade path has been validated end-to-end; flipping the default is a one-line change.\n  const resolvedArcadeUrl = arcadeUrl\n  if (resolvedArcadeUrl != null && resolvedArcadeUrl !== '') {\n    o.arcadeUrl = resolvedArcadeUrl\n    o.arcadeConfig = {\n      apiKey: arcadeApiKey ?? undefined,\n      deploymentId,\n      // SSE (pull) flow: token scopes the /events subscription; no webhook callbackUrl\n      // (Arcade rejects private/loopback URLs). Must match Monitor.options.callbackToken.\n      callbackToken: arcadeCallbackToken ?? arcCallbackToken ?? undefined\n    }\n  }\n\n  return o\n}\n\n/**\n * Default Arcade (bsv-blockchain/arcade) endpoint per chain.\n * Returns undefined when no public default is known for the chain.\n */\nexport function arcadeDefaultUrl(chain: Chain): string | undefined {\n  switch (chain) {\n    case 'main':\n    case 'test':\n    case 'ttn':\n      return publicArcadeUrl(chain)\n    case 'stn':\n      return stnArcadeUrl()\n    case 'tstn':\n      // Private per-deployment endpoint supplied via TSTN_ARCADE_URL (undefined when unset).\n      return tstnArcadeUrl()\n    case 'mock':\n      return undefined\n  }\n}\n\nexport function arcDefaultUrl(chain: Chain): string {\n  switch (chain) {\n    case 'main':\n      return 'https://arc.taal.com'\n    case 'test':\n      return 'https://arc-test.taal.com'\n    case 'stn':\n      return stnArcadeUrl() ?? ''\n    case 'ttn':\n      return 'https://arcade-v2-ttn-us-1.bsvblockchain.tech/'\n    case 'tstn':\n      // Private per-deployment endpoint supplied via TSTN_ARCADE_URL ('' when unset).\n      return tstnArcadeUrl() ?? ''\n    case 'mock':\n      return ''\n  }\n}\n\nexport function arcGorillaPoolUrl(chain: Chain): string | undefined {\n  return chain === 'main' ? 'https://arc.gorillapool.io' : undefined\n}\n","import { FiatExchangeRates, WalletServicesOptions } from '../../sdk/WalletServices.interfaces'\n\nimport { WERR_BAD_REQUEST, WERR_MISSING_PARAMETER } from '../../sdk/WERR_errors'\n\nexport async function updateChaintracksFiatExchangeRates (\n  targetCurrencies: string[],\n  options: WalletServicesOptions\n): Promise<FiatExchangeRates> {\n  const url = options.chaintracksFiatExchangeRatesUrl\n\n  if (!url) throw new WERR_MISSING_PARAMETER('options.chaintracksFiatExchangeRatesUrl')\n\n  const response = await fetch(url)\n  const data = await response.json()\n  const r = { status: response.status, data }\n\n  if (r.status !== 200 || r.data?.status !== 'success') {\n    throw new WERR_BAD_REQUEST(`${url} returned status ${r.status}`)\n  }\n\n  const rates = r.data.value as FiatExchangeRates\n  rates.timestamp = new Date(rates.timestamp)\n\n  return rates\n}\n\nexport async function updateExchangeratesapi (\n  targetCurrencies: string[],\n  options: WalletServicesOptions\n): Promise<FiatExchangeRates> {\n  if (!options.exchangeratesapiKey) throw new WERR_MISSING_PARAMETER('options.exchangeratesapiKey')\n\n  // Always update all rates in one request.\n  const unique = Array.from(new Set([...targetCurrencies, 'USD', 'EUR', 'GBP']))\n  const iorates = await getExchangeRatesIo(options.exchangeratesapiKey, unique)\n\n  if (!iorates.success) throw new WERR_BAD_REQUEST(`getExchangeRatesIo returned success ${iorates.success}`)\n\n  const base = iorates.base\n  const usdPerBase = base === 'USD' ? 1 : iorates.rates.USD\n  if (!usdPerBase || typeof usdPerBase !== 'number') {\n    throw new WERR_BAD_REQUEST('getExchangeRatesIo missing rate for \\'USD\\'')\n  }\n\n  const r: FiatExchangeRates = {\n    timestamp: new Date(iorates.timestamp * 1000),\n    base: 'USD',\n    rates: {}\n  }\n\n  for (const currency of unique) {\n    if (currency === 'USD') {\n      r.rates.USD = 1\n      continue\n    }\n\n    const curPerBase = currency === base ? 1 : iorates.rates[currency]\n    if (!curPerBase || typeof curPerBase !== 'number') {\n      throw new WERR_BAD_REQUEST(`getExchangeRatesIo missing rate for '${currency}'`)\n    }\n\n    r.rates[currency] = curPerBase / usdPerBase\n  }\n\n  return r\n}\n\nexport interface ExchangeRatesIoApi {\n  success: boolean\n  timestamp: number\n  base: 'EUR' | 'USD'\n  date: string\n  rates: Record<string, number>\n}\n\nexport async function getExchangeRatesIo (key: string, symbols?: string[]): Promise<ExchangeRatesIoApi> {\n  const list = (symbols != null) && (symbols.length > 0) ? symbols.join(',') : ''\n  const symbolsParam = list ? `&symbols=${encodeURIComponent(list)}` : ''\n  const url = `https://api.exchangeratesapi.io/v1/latest?access_key=${key}${symbolsParam}`\n\n  const response = await fetch(url)\n  const data = await response.json()\n  const r = { status: response.status, data }\n\n  if (r.status !== 200 || !r.data) {\n    throw new WERR_BAD_REQUEST(`getExchangeRatesIo returned status ${r.status}`)\n  }\n\n  const rates = r.data as ExchangeRatesIoApi\n\n  return rates\n}\n\n/*\n{\n    \"success\": true,\n    \"timestamp\": 1702405384,\n    \"base\": \"EUR\",\n    \"date\": \"2023-12-12\",\n    \"rates\": {\n        \"AED\": 3.96261,\n        \"AFN\": 74.453362,\n        \"ALL\": 101.807155,\n        \"AMD\": 435.489459,\n        \"ANG\": 1.944069,\n        \"AOA\": 897.226337,\n        \"ARS\": 395.468082,\n        \"AUD\": 1.646886,\n        \"AWG\": 1.942271,\n        \"AZN\": 1.832044,\n        \"BAM\": 1.95407,\n        \"BBD\": 2.177971,\n        \"BDT\": 118.654929,\n        \"BGN\": 1.956827,\n        \"BHD\": 0.406753,\n        \"BIF\": 3078.499675,\n        \"BMD\": 1.079039,\n        \"BND\": 1.446102,\n        \"BOB\": 7.4534,\n        \"BRL\": 5.35741,\n        \"BSD\": 1.07874,\n        \"BTC\": 0.000026145469,\n        \"BTN\": 89.916078,\n        \"BWP\": 14.715901,\n        \"BYN\": 3.553337,\n        \"BYR\": 21149.174075,\n        \"BZD\": 2.174364,\n        \"CAD\": 1.468287,\n        \"CDF\": 2875.640503,\n        \"CHF\": 0.945353,\n        \"CLF\": 0.034313,\n        \"CLP\": 948.09775,\n        \"CNY\": 7.743512,\n        \"COP\": 4307.525658,\n        \"CRC\": 569.093422,\n        \"CUC\": 1.079039,\n        \"CUP\": 28.594547,\n        \"CVE\": 110.978933,\n        \"CZK\": 24.507795,\n        \"DJF\": 191.766554,\n        \"DKK\": 7.457544,\n        \"DOP\": 61.505535,\n        \"DZD\": 145.236415,\n        \"EGP\": 33.367028,\n        \"ERN\": 16.185592,\n        \"ETB\": 60.199033,\n        \"EUR\": 1,\n        \"FJD\": 2.416779,\n        \"FKP\": 0.859886,\n        \"GBP\": 0.859574,\n        \"GEL\": 2.880527,\n        \"GGP\": 0.859886,\n        \"GHS\": 12.980915,\n        \"GIP\": 0.859886,\n        \"GMD\": 72.726644,\n        \"GNF\": 9285.134874,\n        \"GTQ\": 8.443457,\n        \"GYD\": 225.859997,\n        \"HKD\": 8.426031,\n        \"HNL\": 26.685156,\n        \"HRK\": 7.598132,\n        \"HTG\": 142.513142,\n        \"HUF\": 382.707793,\n        \"IDR\": 16801.292339,\n        \"ILS\": 4.007585,\n        \"IMP\": 0.859886,\n        \"INR\": 89.987955,\n        \"IQD\": 1414.081256,\n        \"IRR\": 45602.907562,\n        \"ISK\": 151.109018,\n        \"JEP\": 0.859886,\n        \"JMD\": 167.700721,\n        \"JOD\": 0.765366,\n        \"JPY\": 157.115675,\n        \"KES\": 165.523229,\n        \"KGS\": 96.379362,\n        \"KHR\": 4440.24707,\n        \"KMF\": 493.571281,\n        \"KPW\": 971.097551,\n        \"KRW\": 1417.685123,\n        \"KWD\": 0.332733,\n        \"KYD\": 0.8989,\n        \"KZT\": 493.04112,\n        \"LAK\": 22368.488843,\n        \"LBP\": 16154.243871,\n        \"LKR\": 352.747636,\n        \"LRD\": 203.02122,\n        \"LSL\": 20.582684,\n        \"LTL\": 3.186123,\n        \"LVL\": 0.6527,\n        \"LYD\": 5.211954,\n        \"MAD\": 10.976529,\n        \"MDL\": 19.340873,\n        \"MGA\": 4939.301335,\n        \"MKD\": 61.507276,\n        \"MMK\": 2265.283559,\n        \"MNT\": 3705.780074,\n        \"MOP\": 8.676817,\n        \"MRU\": 42.727878,\n        \"MUR\": 47.690625,\n        \"MVR\": 16.584924,\n        \"MWK\": 1816.023037,\n        \"MXN\": 18.69803,\n        \"MYR\": 5.052606,\n        \"MZN\": 68.249194,\n        \"NAD\": 20.588506,\n        \"NGN\": 865.924709,\n        \"NIO\": 39.6024,\n        \"NOK\": 11.848426,\n        \"NPR\": 143.865605,\n        \"NZD\": 1.761931,\n        \"OMR\": 0.415394,\n        \"PAB\": 1.07864,\n        \"PEN\": 4.073376,\n        \"PGK\": 4.025102,\n        \"PHP\": 59.974075,\n        \"PKR\": 306.446851,\n        \"PLN\": 4.334063,\n        \"PYG\": 7963.910929,\n        \"QAR\": 3.928776,\n        \"RON\": 4.973399,\n        \"RSD\": 117.196649,\n        \"RUB\": 97.248412,\n        \"RWF\": 1351.496966,\n        \"SAR\": 4.047186,\n        \"SBD\": 9.12268,\n        \"SCR\": 14.561036,\n        \"SDG\": 648.5028,\n        \"SEK\": 11.285032,\n        \"SGD\": 1.449037,\n        \"SHP\": 1.312921,\n        \"SLE\": 24.488188,\n        \"SLL\": 21311.029931,\n        \"SOS\": 616.131981,\n        \"SRD\": 40.655509,\n        \"STD\": 22333.938945,\n        \"SYP\": 14029.21897,\n        \"SZL\": 20.587826,\n        \"THB\": 38.597298,\n        \"TJS\": 11.757734,\n        \"TMT\": 3.776638,\n        \"TND\": 3.377493,\n        \"TOP\": 2.551714,\n        \"TRY\": 31.312865,\n        \"TTD\": 7.321483,\n        \"TWD\": 34.012943,\n        \"TZS\": 2697.598652,\n        \"UAH\": 39.917867,\n        \"UGX\": 4102.367289,\n        \"USD\": 1.079039,\n        \"UYU\": 42.422631,\n        \"UZS\": 13299.161683,\n        \"VEF\": 3838024.202021,\n        \"VES\": 38.392542,\n        \"VND\": 26188.28851,\n        \"VUV\": 129.693288,\n        \"WST\": 2.964402,\n        \"XAF\": 655.37362,\n        \"XAG\": 0.047456,\n        \"XAU\": 0.000545,\n        \"XCD\": 2.916158,\n        \"XDR\": 0.811478,\n        \"XOF\": 657.134976,\n        \"XPF\": 119.331742,\n        \"YER\": 270.110528,\n        \"ZAR\": 20.470755,\n        \"ZMK\": 9712.646776,\n        \"ZMW\": 26.319693,\n        \"ZWL\": 347.450277\n    }\n}\n*/\n","import {\n  Beef,\n  BEEF_V1,\n  BEEF_V2,\n  defaultHttpClient,\n  HexString,\n  HttpClient,\n  HttpClientResponse,\n  HttpClientRequestOptions,\n  Random,\n  Utils\n} from '@bsv/sdk'\nimport { PostBeefResult, PostTxResultForTxid, PostTxResultForTxidError } from '../../sdk/WalletServices.interfaces'\nimport { doubleSha256BE } from '../../utility/utilityHelpers'\nimport { ReqHistoryNote } from '../../sdk/types'\nimport { WalletError } from '../../sdk/WalletError'\n\n/** Configuration options for the ARC broadcaster. */\nexport interface ArcConfig {\n  /** Authentication token for the ARC API */\n  apiKey?: string\n  /** The HTTP client used to make requests to the ARC API. */\n  httpClient?: HttpClient\n  /** Deployment id used annotating api calls in XDeployment-ID header - this value will be randomly generated if not set */\n  deploymentId?: string\n  /** notification callback endpoint for proofs and double spend notification */\n  callbackUrl?: string\n  /** default access token for notification callback endpoint. It will be used as a Authorization header for the http callback */\n  callbackToken?: string\n  /** additional headers to be attached to all tx submissions. */\n  headers?: Record<string, string>\n}\n\nfunction defaultDeploymentId (): string {\n  return `ts-sdk-${Utils.toHex(Random(16))}`\n}\n\nconst arcAcceptedTxStatuses = new Set([\n  'RECEIVED',\n  'SENT_TO_NETWORK',\n  'ANNOUNCED_TO_NETWORK',\n  'ACCEPTED_BY_NETWORK',\n  'SEEN_ON_NETWORK',\n  'STORED',\n  'MINED',\n  'IMMUTABLE'\n])\n\nconst arcDoubleSpendTxStatuses = new Set([\n  'DOUBLE_SPEND_ATTEMPTED',\n  'SEEN_IN_ORPHAN_MEMPOOL'\n])\n\nconst arcInvalidTxStatuses = new Set([\n  'INVALID',\n  'MALFORMED',\n  'REJECTED'\n])\n\nexport function isArcAcceptedTxStatus (txStatus: string | undefined): boolean {\n  return txStatus != null && arcAcceptedTxStatuses.has(txStatus)\n}\n\nexport function isArcDoubleSpendTxStatus (txStatus: string | undefined): boolean {\n  return txStatus != null && arcDoubleSpendTxStatuses.has(txStatus)\n}\n\nexport function isArcInvalidTxStatus (txStatus: string | undefined): boolean {\n  return txStatus != null && arcInvalidTxStatuses.has(txStatus)\n}\n\nexport function isArcServiceErrorStatus (status: number | undefined, detail?: string): boolean {\n  if (status == null) return true\n  if (status === 408 || status === 429 || status === 476 || status >= 500) return true\n  if (detail == null) return false\n  const d = detail.toLowerCase()\n  return d.includes('maximum batch size') ||\n    d.includes('too many requests') ||\n    d.includes('rate limit') ||\n    d.includes('timeout') ||\n    d.includes('temporarily') ||\n    d.includes('backpressure') ||\n    d.includes('unavailable')\n}\n\ninterface ArcPostNoteContext {\n  nn: () => { name: string; when: string }\n  nne: () => {\n    rawTx: HexString\n    txids: string\n    url: string\n    name: string\n    when: string\n  }\n}\n\n/**\n * Represents an ARC transaction broadcaster.\n */\nexport class ARC {\n  readonly name: string\n  readonly URL: string\n  readonly apiKey: string | undefined\n  readonly deploymentId: string\n  readonly callbackUrl: string | undefined\n  readonly callbackToken: string | undefined\n  readonly headers: Record<string, string> | undefined\n  private readonly httpClient: HttpClient\n\n  /**\n   * Constructs an instance of the ARC broadcaster.\n   *\n   * @param {string} URL - The URL endpoint for the ARC API.\n   * @param {ArcConfig} config - Configuration options for the ARC broadcaster.\n   */\n  constructor (URL: string, config?: ArcConfig, name?: string)\n  /**\n   * Constructs an instance of the ARC broadcaster.\n   *\n   * @param {string} URL - The URL endpoint for the ARC API.\n   * @param {string} apiKey - The API key used for authorization with the ARC API.\n   */\n  constructor (URL: string, apiKey?: string, name?: string)\n\n  constructor (URL: string, config?: string | ArcConfig, name?: string) {\n    this.name = name ?? 'ARC'\n    this.URL = URL\n    if (typeof config === 'string') {\n      this.apiKey = config\n      this.httpClient = defaultHttpClient()\n      this.deploymentId = defaultDeploymentId()\n      this.callbackToken = undefined\n      this.callbackUrl = undefined\n    } else {\n      const configObj: ArcConfig = config ?? {}\n      const { apiKey, deploymentId, httpClient, callbackToken, callbackUrl, headers } = configObj\n      this.apiKey = apiKey\n      this.httpClient = httpClient ?? defaultHttpClient()\n      this.deploymentId = deploymentId ?? defaultDeploymentId()\n      this.callbackToken = callbackToken\n      this.callbackUrl = callbackUrl\n      this.headers = headers\n    }\n  }\n\n  /**\n   * Constructs a dictionary of the default & supplied request headers.\n   */\n  private requestHeaders (): Record<string, string> {\n    const headers: Record<string, string> = {\n      'Content-Type': 'application/json',\n      'XDeployment-ID': this.deploymentId\n    }\n\n    if (this.apiKey != null && this.apiKey !== '') {\n      headers.Authorization = `Bearer ${this.apiKey}`\n    }\n\n    if (this.callbackUrl != null && this.callbackUrl !== '') {\n      headers['X-CallbackUrl'] = this.callbackUrl\n    }\n\n    if (this.callbackToken != null && this.callbackToken !== '') {\n      headers['X-CallbackToken'] = this.callbackToken\n    }\n\n    if (this.headers != null) {\n      for (const key in this.headers) {\n        headers[key] = this.headers[key]\n      }\n    }\n\n    return headers\n  }\n\n  private applySuccessfulPostRawTx (\n    result: PostTxResultForTxid,\n    data: ArcResponse,\n    notes: ArcPostNoteContext\n  ): void {\n    const { txid, extraInfo, txStatus, competingTxs } = data\n    result.data = `${txStatus} ${extraInfo}`\n    if (result.txid !== txid) result.data += ` txid altered from ${result.txid} to ${txid}`\n    result.txid = txid\n    const responseNote = {\n      txid,\n      extraInfo,\n      txStatus,\n      competingTxs: competingTxs?.join(',')\n    }\n    if (isArcDoubleSpendTxStatus(txStatus)) {\n      result.status = 'error'\n      result.doubleSpend = true\n      result.competingTxs = competingTxs\n      result.notes!.push({ ...notes.nne(), ...responseNote, what: 'postRawTxDoubleSpend' })\n      return\n    }\n    result.notes!.push({ ...notes.nn(), ...responseNote, what: 'postRawTxSuccess' })\n  }\n\n  private applyFailedPostRawTx (\n    result: PostTxResultForTxid,\n    response: Exclude<HttpClientResponse<ArcResponse>, { ok: true }>,\n    data: ArcResponse,\n    notes: ArcPostNoteContext\n  ): void {\n    result.status = 'error'\n    const responseNote = {\n      txid: data.txid,\n      extraInfo: data.extraInfo,\n      txStatus: data.txStatus,\n      competingTxs: data.competingTxs?.join(',')\n    }\n    const note: ReqHistoryNote = {\n      ...notes.nn(),\n      ...notes.nne(),\n      ...responseNote,\n      what: 'postRawTxError'\n    }\n    const errorData: PostTxResultForTxidError = {}\n    result.data = errorData\n    const responseStatus: unknown = response.status\n    let numericStatus: number | undefined\n    if (typeof responseStatus === 'number' || typeof responseStatus === 'string') {\n      note.status = responseStatus\n      errorData.status = responseStatus.toString()\n      const parsed = Number(responseStatus)\n      if (Number.isFinite(parsed)) numericStatus = parsed\n    } else {\n      note.status = typeof responseStatus\n      errorData.status = 'ERR_UNKNOWN'\n    }\n\n    const responseData: unknown = response.data\n    if (typeof responseData === 'string' && responseData !== '') {\n      note.data = responseData.slice(0, 128)\n    } else if (responseData != null && typeof responseData === 'object') {\n      errorData.more = responseData\n      if ('detail' in responseData && typeof responseData.detail === 'string') {\n        errorData.detail = responseData.detail\n        note.detail = responseData.detail\n      }\n    }\n    result.serviceError = isArcServiceErrorStatus(numericStatus, errorData.detail)\n    result.notes!.push(note)\n  }\n\n  private applyPostRawTxResponse (\n    result: PostTxResultForTxid,\n    response: HttpClientResponse<ArcResponse>,\n    notes: ArcPostNoteContext\n  ): void {\n    if (response.ok) {\n      this.applySuccessfulPostRawTx(result, response.data, notes)\n    } else {\n      this.applyFailedPostRawTx(result, response, response.data as ArcResponse, notes)\n    }\n  }\n\n  private applyPostRawTxCatch (\n    result: PostTxResultForTxid,\n    error_: unknown,\n    notes: ArcPostNoteContext\n  ): void {\n    const error = WalletError.fromUnknown(error_)\n    result.status = 'error'\n    result.serviceError = true\n    result.data = `${error.code} ${error.message}`\n    result.notes!.push({\n      ...notes.nne(),\n      what: 'postRawTxCatch',\n      code: error.code,\n      description: error.description\n    })\n  }\n\n  /**\n   * The ARC '/v1/tx' endpoint, as of 2025-02-17 supports all of the following hex string formats:\n   *   1. Single serialized raw transaction.\n   *   2. Single EF serialized raw transaction (untested).\n   *   3. V1 serialized Beef (results returned reflect only the last transaction in the beef)\n   *\n   * The ARC '/v1/tx' endpoint, as of 2025-02-17 DOES NOT support the following hex string formats:\n   *   1. V2 serialized Beef\n   *\n   * @param rawTx\n   * @param txids\n   * @returns\n   */\n  async postRawTx (rawTx: HexString, txids?: string[]): Promise<PostTxResultForTxid> {\n    let txid = Utils.toHex(doubleSha256BE(Utils.toArray(rawTx, 'hex')))\n    if (txids == null) {\n      txids = [txid]\n    } else {\n      txid = txids.at(-1)!\n    }\n\n    const requestOptions: HttpClientRequestOptions = {\n      method: 'POST',\n      headers: this.requestHeaders(),\n      data: { rawTx },\n      signal: AbortSignal.timeout(1000 * 30) // 30 seconds timeout, error.code will be 'ABORT_ERR'\n    }\n\n    const r: PostTxResultForTxid = {\n      txid,\n      status: 'success',\n      notes: []\n    }\n\n    const url = `${this.URL}/v1/tx`\n    const notes: ArcPostNoteContext = {\n      nn: () => ({ name: this.name, when: new Date().toISOString() }),\n      nne: () => ({\n        name: this.name,\n        when: new Date().toISOString(),\n        rawTx,\n        txids: txids.join(','),\n        url\n      })\n    }\n\n    try {\n      const response = await this.httpClient.request<ArcResponse>(url, requestOptions)\n      this.applyPostRawTxResponse(r, response, notes)\n    } catch (error_: unknown) {\n      this.applyPostRawTxCatch(r, error_, notes)\n    }\n\n    return r\n  }\n\n  /**\n   * ARC does not natively support a postBeef end-point aware of multiple txids of interest in the Beef.\n   *\n   * It does process multiple new transactions, however, which allows results for all txids of interest\n   * to be collected by the `/v1/tx/${txid}` endpoint.\n   *\n   * @param beef\n   * @param txids\n   * @returns\n   */\n  async postBeef (beef: Beef, txids: string[]): Promise<PostBeefResult> {\n    const r: PostBeefResult = {\n      name: this.name,\n      status: 'success',\n      txidResults: [],\n      notes: []\n    }\n\n    const nn = () => ({ name: this.name, when: new Date().toISOString() })\n\n    if (beef.version === BEEF_V2 && beef.txs.every(btx => !btx.isTxidOnly)) {\n      beef.version = BEEF_V1\n      r.notes!.push({ ...nn(), what: 'postBeefV2ToV1' })\n    }\n\n    const beefHex = beef.toHex()\n\n    const prtr = await this.postRawTx(beefHex, txids)\n\n    r.status = prtr.status\n    r.txidResults = [prtr]\n\n    // Since postRawTx only returns results for a single txid,\n    // replicate the basic results any additional txids.\n    for (const txid of txids) {\n      if (prtr.txid === txid) continue\n      const tr: PostTxResultForTxid = {\n        txid,\n        status: 'success',\n        notes: []\n      }\n      // For the extra txids, go back to the service for confirmation...\n      const dr = await this.getTxData(txid)\n      if (dr.txid !== txid) {\n        tr.status = 'error'\n        tr.data = 'internal error'\n        tr.notes!.push({\n          ...nn(),\n          what: 'postBeefGetTxDataInternal',\n          txid,\n          returnedTxid: dr.txid\n        })\n      } else if (isArcAcceptedTxStatus(dr.txStatus)) {\n        tr.data = dr.txStatus\n        tr.notes!.push({\n          ...nn(),\n          what: 'postBeefGetTxDataSuccess',\n          txid,\n          txStatus: dr.txStatus\n        })\n      } else {\n        tr.status = 'error'\n        tr.data = dr\n        tr.serviceError = !isArcInvalidTxStatus(dr.txStatus)\n        if (isArcDoubleSpendTxStatus(dr.txStatus)) {\n          tr.doubleSpend = true\n          tr.competingTxs = dr.competingTxs ?? undefined\n          tr.serviceError = undefined\n        }\n        tr.notes!.push({\n          ...nn(),\n          what: 'postBeefGetTxDataError',\n          txid,\n          txStatus: dr.txStatus\n        })\n      }\n      r.txidResults.push(tr)\n      if (r.status === 'success' && tr.status === 'error') r.status = 'error'\n    }\n\n    return r\n  }\n\n  /**\n   * This seems to only work for recently submitted txids...but that's all we need to complete postBeef!\n   * @param txid\n   * @returns\n   */\n  async getTxData (txid: string): Promise<ArcMinerGetTxData> {\n    const requestOptions: HttpClientRequestOptions = {\n      method: 'GET',\n      headers: this.requestHeaders()\n    }\n\n    const response = await this.httpClient.request<ArcMinerGetTxData>(`${this.URL}/v1/tx/${txid}`, requestOptions)\n\n    return response.data\n  }\n}\n\ninterface ArcResponse {\n  txid: string\n  extraInfo: string\n  txStatus: string\n  competingTxs?: string[]\n}\n\nexport interface ArcMinerGetTxData {\n  status: number // 200\n  title: string // OK\n  blockHash: string\n  blockHeight: number\n  competingTxs: null | string[]\n  extraInfo: string\n  merklePath: string\n  timestamp: string // ISO Z\n  txid: string\n  txStatus: string // 'SEEN_IN_ORPHAN_MEMPOOL'\n}\n","import {\n  Beef,\n  defaultHttpClient,\n  HexString,\n  HttpClient,\n  HttpClientResponse,\n  HttpClientRequestOptions,\n  MerklePath,\n  Random,\n  Utils\n} from '@bsv/sdk'\nimport {\n  GetMerklePathResult,\n  PostBeefResult,\n  PostTxResultForTxid,\n  PostTxResultForTxidError,\n  WalletServices\n} from '../../sdk/WalletServices.interfaces'\nimport { doubleSha256BE } from '../../utility/utilityHelpers'\nimport { ReqHistoryNote } from '../../sdk/types'\nimport { WalletError } from '../../sdk/WalletError'\n// Shared wire-contract types only (no behavior coupling): Arcade is ARC-compatible on the\n// configuration and `getTxData` response shape, so it reuses those interfaces.\nimport { ArcConfig, ArcMinerGetTxData, isArcDoubleSpendTxStatus, isArcServiceErrorStatus } from './ARC'\n\nfunction defaultDeploymentId(): string {\n  return `ts-sdk-${Utils.toHex(Random(16))}`\n}\n\n// Storage sendWith can aggregate many transactions into one BEEF. Arcade accepts\n// one EF transaction per request, so submit independent transactions concurrently\n// while preserving dependency order and avoiding an unbounded burst.\nexport const ARCADE_POST_BEEF_CONCURRENCY = 4\n\ninterface ArcadePostNoteContext {\n  nn: () => { name: string; when: string }\n  nne: () => {\n    rawTx: HexString\n    txids: string\n    url: string\n    name: string\n    when: string\n  }\n}\n\n/**\n * Broadcaster for bsv-blockchain/arcade — the Teranode-native, ARC-compatible broadcaster.\n *\n * Arcade is intentionally a separate, self-contained class (not a subclass of {@link ARC}) so\n * the audited ARC transport is never altered. It is ARC-compatible on headers, configuration and\n * the `getTxData` response shape — but differs where it must:\n *\n *  - Endpoints are served at the root: `/tx` and `/tx/{txid}` (no `/v1` prefix).\n *  - A submit returns HTTP 202; HTTP 400 is a terminal validation failure (REJECTED) and is\n *    surfaced as an invalid-transaction status error rather than a transient service error.\n *  - Submission encoding is Extended Format (EF), not BEEF: Arcade's `/tx` parser rejects BEEF\n *    (\"failed to parse transaction\") and runs fee/script validation that needs per-input source\n *    data, which EF carries inline.\n */\nexport class Arcade {\n  readonly name: string\n  readonly URL: string\n  readonly apiKey: string | undefined\n  readonly deploymentId: string\n  readonly callbackUrl: string | undefined\n  readonly callbackToken: string | undefined\n  readonly headers: Record<string, string> | undefined\n  private readonly httpClient: HttpClient\n\n  /**\n   * @param URL - The Arcade endpoint base URL.\n   * @param config - Arcade configuration (shares ARC's {@link ArcConfig} shape).\n   */\n  constructor(URL: string, config?: ArcConfig, name?: string)\n  constructor(URL: string, apiKey?: string, name?: string)\n  constructor(URL: string, config?: string | ArcConfig, name?: string) {\n    this.name = name ?? 'arcade'\n    this.URL = URL\n    if (typeof config === 'string') {\n      this.apiKey = config\n      this.httpClient = defaultHttpClient()\n      this.deploymentId = defaultDeploymentId()\n      this.callbackToken = undefined\n      this.callbackUrl = undefined\n    } else {\n      const configObj: ArcConfig = config ?? {}\n      const { apiKey, deploymentId, httpClient, callbackToken, callbackUrl, headers } = configObj\n      this.apiKey = apiKey\n      this.httpClient = httpClient ?? defaultHttpClient()\n      this.deploymentId = deploymentId ?? defaultDeploymentId()\n      this.callbackToken = callbackToken\n      this.callbackUrl = callbackUrl\n      this.headers = headers\n    }\n  }\n\n  /** Constructs a dictionary of the default & supplied request headers. */\n  private requestHeaders(): Record<string, string> {\n    const headers: Record<string, string> = {\n      'Content-Type': 'application/json',\n      'XDeployment-ID': this.deploymentId\n    }\n\n    if (this.apiKey != null && this.apiKey !== '') {\n      headers.Authorization = `Bearer ${this.apiKey}`\n    }\n\n    if (this.callbackUrl != null && this.callbackUrl !== '') {\n      headers['X-CallbackUrl'] = this.callbackUrl\n    }\n\n    if (this.callbackToken != null && this.callbackToken !== '') {\n      headers['X-CallbackToken'] = this.callbackToken\n    }\n\n    if (this.headers != null) {\n      for (const key in this.headers) {\n        headers[key] = this.headers[key]\n      }\n    }\n\n    return headers\n  }\n\n  private applySuccessfulPostRawTx(\n    result: PostTxResultForTxid,\n    data: ArcadeResponse,\n    notes: ArcadePostNoteContext\n  ): void {\n    const { txid, extraInfo, txStatus, competingTxs } = data\n    result.data = extraInfo != null && extraInfo !== '' ? `${txStatus} ${extraInfo}` : `${txStatus}`\n    if (result.txid !== txid) result.data += ` txid altered from ${result.txid} to ${txid}`\n    result.txid = txid\n    const responseNote = {\n      txid,\n      extraInfo,\n      txStatus,\n      competingTxs: competingTxs?.join(',')\n    }\n    if (isArcDoubleSpendTxStatus(txStatus)) {\n      result.status = 'error'\n      result.doubleSpend = true\n      result.competingTxs = competingTxs\n      result.notes!.push({ ...notes.nne(), ...responseNote, what: 'postRawTxDoubleSpend' })\n      return\n    }\n    result.notes!.push({ ...notes.nn(), ...responseNote, what: 'postRawTxSuccess' })\n  }\n\n  private applyFailedPostRawTx(\n    result: PostTxResultForTxid,\n    response: Exclude<HttpClientResponse<ArcadeResponse>, { ok: true }>,\n    data: ArcadeResponse,\n    notes: ArcadePostNoteContext\n  ): void {\n    result.status = 'error'\n    const responseNote = {\n      txid: data.txid,\n      extraInfo: data.extraInfo,\n      txStatus: data.txStatus,\n      competingTxs: data.competingTxs?.join(',')\n    }\n    const note: ReqHistoryNote = {\n      ...notes.nn(),\n      ...notes.nne(),\n      ...responseNote,\n      what: 'postRawTxError'\n    }\n    const errorData: PostTxResultForTxidError = {}\n    result.data = errorData\n    const responseStatus: unknown = response.status\n    let numericStatus: number | undefined\n    if (typeof responseStatus === 'number' || typeof responseStatus === 'string') {\n      note.status = responseStatus\n      errorData.status = responseStatus.toString()\n      const parsed = Number(responseStatus)\n      if (Number.isFinite(parsed)) numericStatus = parsed\n    } else {\n      note.status = typeof responseStatus\n      errorData.status = 'ERR_UNKNOWN'\n    }\n\n    const responseData: unknown = response.data\n    if (typeof responseData === 'string' && responseData !== '') {\n      note.data = responseData.slice(0, 128)\n    } else if (responseData != null && typeof responseData === 'object') {\n      errorData.more = responseData\n      if ('detail' in responseData && typeof responseData.detail === 'string') {\n        errorData.detail = responseData.detail\n        note.detail = responseData.detail\n      }\n    }\n    result.serviceError = isArcServiceErrorStatus(numericStatus, errorData.detail)\n    result.notes!.push(note)\n  }\n\n  private applyPostRawTxResponse(\n    result: PostTxResultForTxid,\n    response: HttpClientResponse<ArcadeResponse>,\n    notes: ArcadePostNoteContext\n  ): void {\n    if (response.ok) {\n      this.applySuccessfulPostRawTx(result, response.data, notes)\n    } else {\n      this.applyFailedPostRawTx(result, response, response.data as ArcadeResponse, notes)\n    }\n  }\n\n  private applyPostRawTxCatch(\n    result: PostTxResultForTxid,\n    error_: unknown,\n    notes: ArcadePostNoteContext\n  ): void {\n    const error = WalletError.fromUnknown(error_)\n    result.status = 'error'\n    result.serviceError = true\n    result.data = `${error.code} ${error.message}`\n    result.notes!.push({\n      ...notes.nne(),\n      what: 'postRawTxCatch',\n      code: error.code,\n      description: error.description\n    })\n  }\n\n  /**\n   * Submit a single transaction to Arcade's `POST /tx` endpoint.\n   *\n   * `rawTx` must be a single (raw or Extended Format) transaction hex — NOT BEEF. The canonical\n   * txid is taken from `txids` when supplied (Arcade derives the same txid from the parsed tx).\n   */\n  async postRawTx(rawTx: HexString, txids?: string[]): Promise<PostTxResultForTxid> {\n    let txid = Utils.toHex(doubleSha256BE(Utils.toArray(rawTx, 'hex')))\n    if (txids == null) {\n      txids = [txid]\n    } else {\n      txid = txids.at(-1)!\n    }\n\n    const requestOptions: HttpClientRequestOptions = {\n      method: 'POST',\n      headers: this.requestHeaders(),\n      data: { rawTx },\n      signal: AbortSignal.timeout(1000 * 30) // 30 seconds timeout, error.code will be 'ABORT_ERR'\n    }\n\n    const r: PostTxResultForTxid = {\n      txid,\n      status: 'success',\n      notes: []\n    }\n\n    const url = `${this.URL}/tx`\n    const notes: ArcadePostNoteContext = {\n      nn: () => ({ name: this.name, when: new Date().toISOString() }),\n      nne: () => ({\n        name: this.name,\n        when: new Date().toISOString(),\n        rawTx,\n        txids: txids.join(','),\n        url\n      })\n    }\n\n    try {\n      const response = await this.httpClient.request<ArcadeResponse>(url, requestOptions)\n      this.applyPostRawTxResponse(r, response, notes)\n    } catch (error_: unknown) {\n      this.applyPostRawTxCatch(r, error_, notes)\n    }\n\n    return r\n  }\n\n  /**\n   * Post each tx of interest as Extended Format (EF).\n   *\n   * EF needs each input's source output (satoshis + locking script). For a BEEF that carries every\n   * direct parent transaction in full (e.g. the atomic BEEF produced by createAction), that data is\n   * present and {@link Transaction.fromBEEF} can reconstruct EF. A BEEF is NOT guaranteed to contain\n   * it, however: BEEF V2 `txidOnly` entries (or an otherwise pruned BEEF) can reference a direct\n   * parent without its bytes, leaving no source output to embed — so BEEF -> EF is not always\n   * possible. When EF cannot be built for a txid, it is recorded as a (non-terminal) service error\n   * so cross-provider aggregation falls through to a BEEF-capable broadcaster, which can still\n   * broadcast the (valid) transaction.\n   */\n  async postBeef(beef: Beef, txids: string[]): Promise<PostBeefResult> {\n    const r: PostBeefResult = {\n      name: this.name,\n      status: 'success',\n      txidResults: Array.from({ length: txids.length }),\n      notes: []\n    }\n    const nn = (): { name: string; when: string } => ({ name: this.name, when: new Date().toISOString() })\n\n    const txidSet = new Set(txids)\n    const prepared = txids.map(txid => {\n      try {\n        // Extract each transaction from the shared parsed bundle.\n        // findAtomicTransaction attaches the source-transaction ancestry\n        // required by the EF serialization below.\n        const tx = beef.findAtomicTransaction(txid)\n        if (tx == null) throw new Error(`transaction ${txid} not found in beef`)\n        const dependencies = tx.inputs\n          .map(input => input.sourceTXID ?? input.sourceTransaction?.id('hex'))\n          .filter(\n            (sourceTxid): sourceTxid is string => sourceTxid != null && sourceTxid !== txid && txidSet.has(sourceTxid)\n          )\n        return { txid, efHex: tx.toHexEF(), dependencies }\n      } catch (error_: unknown) {\n        const e = WalletError.fromUnknown(error_)\n        const error: PostTxResultForTxid = {\n          txid,\n          status: 'error',\n          serviceError: true,\n          notes: [{ ...nn(), what: 'arcadeEfBuildFailed', txid, code: e.code, description: e.description }]\n        }\n        return { txid, dependencies: [] as string[], error }\n      }\n    })\n    const indexByTxid = new Map(txids.map((txid, index) => [txid, index]))\n    const pending = new Set(txids.map((_, index) => index))\n\n    while (pending.size > 0) {\n      let ready = [...pending].filter(index =>\n        prepared[index].dependencies.every(dependency => {\n          const dependencyIndex = indexByTxid.get(dependency)\n          return dependencyIndex == null || !pending.has(dependencyIndex)\n        })\n      )\n      // A valid transaction graph is acyclic. Preserve forward progress for a\n      // malformed/cyclic graph and let Arcade return the authoritative error.\n      if (ready.length === 0) ready = [[...pending][0]]\n\n      let nextReady = 0\n      const worker = async (): Promise<void> => {\n        while (nextReady < ready.length) {\n          const index = ready[nextReady++]\n          const item = prepared[index]\n          r.txidResults[index] = item.error ?? (await this.postRawTx(item.efHex, [item.txid]))\n        }\n      }\n\n      await Promise.all(Array.from({ length: Math.min(ARCADE_POST_BEEF_CONCURRENCY, ready.length) }, worker))\n      for (const index of ready) pending.delete(index)\n    }\n    if (r.txidResults.some(result => result.status === 'error')) r.status = 'error'\n\n    return r\n  }\n\n  /** Look up a transaction's current status (and merkle path once mined) via `GET /tx/{txid}`. */\n  async getTxData(txid: string): Promise<ArcMinerGetTxData> {\n    const requestOptions: HttpClientRequestOptions = {\n      method: 'GET',\n      headers: this.requestHeaders()\n    }\n\n    const response = await this.httpClient.request<ArcMinerGetTxData>(`${this.URL}/tx/${txid}`, requestOptions)\n\n    return response.data\n  }\n\n  /**\n   * `getMerklePath` provider: obtain a BUMP merkle proof for a mined transaction from Arcade.\n   *\n   * Arcade only has a proof for transactions it tracked (i.e. broadcast through it) that have\n   * been mined while tracked; for anything else `GET /tx/{txid}` reports a non-mined status (or\n   * 404) and this returns no `merklePath`, so {@link Services.getMerklePath} falls through to the\n   * other providers (WhatsOnChain/Bitails).\n   *\n   * The proof is NOT trusted blindly: the canonical block header is resolved from the wallet's\n   * own chaintracker via `services.hashToHeader(blockHash)` (which only knows real, mined blocks),\n   * and the BUMP's computed merkle root must equal that header's `merkleRoot`. Only then is the\n   * proof returned, with the canonical `header` that downstream proof completion requires.\n   */\n  async getMerklePath(txid: string, services: WalletServices): Promise<GetMerklePathResult> {\n    const r: GetMerklePathResult = { name: this.name, notes: [] }\n    const nn = (): { name: string; when: string } => ({ name: this.name, when: new Date().toISOString() })\n\n    try {\n      const data = await this.getTxData(txid)\n      const mined = data.txStatus === 'MINED' || data.txStatus === 'IMMUTABLE'\n      if (\n        !mined ||\n        data.merklePath == null ||\n        data.merklePath === '' ||\n        data.blockHash == null ||\n        data.blockHash === ''\n      ) {\n        // No proof from Arcade yet (not mined / untracked / 404) — fall through to other providers.\n        r.notes!.push({ ...nn(), what: 'getMerklePathArcadeNoProof', txid, txStatus: data.txStatus })\n        return r\n      }\n\n      const merklePath = MerklePath.fromHex(data.merklePath)\n      // Resolve the canonical header from our own chaintracker; throws if the block is unknown.\n      const header = await services.hashToHeader(data.blockHash)\n      const computedRoot = merklePath.computeRoot(txid)\n      if (computedRoot !== header.merkleRoot) {\n        // Arcade's BUMP does not reconcile with the canonical block — reject and fall through.\n        r.notes!.push({\n          ...nn(),\n          what: 'getMerklePathArcadeRootMismatch',\n          txid,\n          computedRoot,\n          headerRoot: header.merkleRoot,\n          blockHash: data.blockHash\n        })\n        return r\n      }\n\n      r.merklePath = merklePath\n      r.header = header\n      r.notes!.push({\n        ...nn(),\n        what: 'getMerklePathArcadeSuccess',\n        txid,\n        height: header.height,\n        blockHash: header.hash\n      })\n    } catch (error_: unknown) {\n      const e = WalletError.fromUnknown(error_)\n      r.error = e\n      r.notes!.push({ ...nn(), what: 'getMerklePathArcadeError', txid, code: e.code, description: e.description })\n    }\n\n    return r\n  }\n}\n\n/** Arcade's `POST /tx` response body. `extraInfo`/`competingTxs` are absent on the 202. */\ninterface ArcadeResponse {\n  txid: string\n  extraInfo?: string\n  txStatus: string\n  competingTxs?: string[]\n  status?: number\n}\n","import { Beef, defaultHttpClient, HexString, HttpClient, Utils } from '@bsv/sdk'\nimport { Chain, ReqHistoryNote } from '../../sdk/types'\nimport {\n  GetMerklePathResult,\n  PostBeefResult,\n  PostTxResultForTxid,\n  WalletServices\n} from '../../sdk/WalletServices.interfaces'\nimport { doubleSha256BE } from '../../utility/utilityHelpers'\nimport { WalletError } from '../../sdk/WalletError'\nimport { convertProofToMerklePath } from '../../utility/tscProofToMerklePath'\n\nexport interface BitailsConfig {\n  /** Authentication token for BitTails API */\n  apiKey?: string\n  /** The HTTP client used to make requests to the API. */\n  httpClient?: HttpClient\n}\n\ninterface BitailsPostNoteContext {\n  nn: () => { name: string; when: string }\n  nne: () => {\n    name: string\n    when: string\n    raws: string\n    txids: string\n    url: string\n  }\n}\n\nfunction initializeBitailsPostResult(\n  raws: HexString[],\n  requestedTxids?: string[]\n): { result: PostBeefResult; rawTxids: string[] } {\n  const result: PostBeefResult = {\n    name: 'BitailsPostRaws',\n    status: 'success',\n    txidResults: [],\n    notes: []\n  }\n  const rawTxids: string[] = []\n  for (const raw of raws) {\n    const txid = Utils.toHex(doubleSha256BE(Utils.toArray(raw, 'hex')))\n    rawTxids.push(txid)\n    if (requestedTxids == null || requestedTxids.includes(txid)) {\n      result.txidResults.push({ txid, status: 'success', notes: [] })\n    }\n  }\n  return { result, rawTxids }\n}\n\nfunction reconcileBitailsResponseTxids(\n  result: PostBeefResult,\n  responseResults: BitailsPostRawsResult[],\n  rawTxids: string[],\n  notes: BitailsPostNoteContext\n): boolean {\n  if (responseResults.length !== rawTxids.length) {\n    result.status = 'error'\n    result.notes!.push({ ...notes.nne(), what: 'postRawsErrorResultsCount' })\n    return false\n  }\n  for (let index = 0; index < responseResults.length; index++) {\n    const response = responseResults[index]\n    if (response.txid == null || response.txid === '') {\n      response.txid = rawTxids[index]\n      result.notes!.push({\n        ...notes.nn(),\n        what: 'postRawsResultMissingTxids',\n        i: index,\n        rawsTxid: rawTxids[index]\n      })\n    } else if (response.txid !== rawTxids[index]) {\n      result.status = 'error'\n      result.notes!.push({\n        ...notes.nn(),\n        what: 'postRawsResultTxids',\n        i: index,\n        txid: response.txid,\n        rawsTxid: rawTxids[index]\n      })\n    }\n  }\n  return result.status === 'success'\n}\n\nfunction applyBitailsTransactionResult(\n  result: PostTxResultForTxid,\n  response: BitailsPostRawsResult,\n  notes: BitailsPostNoteContext\n): void {\n  if (response.error == null) {\n    result.notes!.push({ ...notes.nn(), what: 'postRawsSuccess' })\n    return\n  }\n  const { code, message } = response.error\n  if (code === -27) {\n    result.notes!.push({ ...notes.nne(), what: 'postRawsSuccessAlreadyInMempool' })\n    return\n  }\n\n  result.status = 'error'\n  if (code === -25) {\n    result.doubleSpend = true\n    result.competingTxs = undefined\n    result.notes!.push({ ...notes.nne(), what: 'postRawsErrorMissingInputs' })\n  } else if ((response as BitailsPostRawsResult & { code?: string }).code === 'ECONNRESET') {\n    result.notes!.push({\n      ...notes.nne(),\n      what: 'postRawsErrorECONNRESET',\n      txid: result.txid,\n      message\n    })\n  } else {\n    result.notes!.push({\n      ...notes.nne(),\n      what: 'postRawsError',\n      txid: result.txid,\n      code,\n      message\n    })\n  }\n}\n\nfunction applyRequestedBitailsResults(\n  result: PostBeefResult,\n  responseResults: BitailsPostRawsResult[],\n  notes: BitailsPostNoteContext\n): void {\n  for (const txResult of result.txidResults) {\n    const response = responseResults.find(item => item.txid === txResult.txid)!\n    applyBitailsTransactionResult(txResult, response, notes)\n    if (txResult.status !== 'success') result.status = 'error'\n  }\n}\n\n/**\n *\n */\nexport class Bitails {\n  readonly chain: Chain\n  readonly apiKey: string\n  readonly URL: string\n  readonly httpClient: HttpClient\n\n  constructor(chain: Chain = 'main', config: BitailsConfig = {}) {\n    const { apiKey, httpClient } = config\n    this.chain = chain\n    switch (chain) {\n      case 'main':\n        this.URL = 'https://api.bitails.io/'\n        break\n      case 'test':\n        this.URL = 'https://test-api.bitails.io/'\n        break\n      default:\n        throw new Error(`Bitails does not support '${chain}' chain.`)\n    }\n    this.httpClient = httpClient ?? defaultHttpClient()\n    this.apiKey = apiKey ?? ''\n  }\n\n  getHttpHeaders(): Record<string, string> {\n    const headers: Record<string, string> = {\n      Accept: 'application/json'\n    }\n\n    if (typeof this.apiKey === 'string' && this.apiKey.trim() !== '') {\n      headers.Authorization = this.apiKey\n    }\n\n    return headers\n  }\n\n  /**\n   * Bitails does not natively support a postBeef end-point aware of multiple txids of interest in the Beef.\n   *\n   * Send rawTx in `txids` order from beef.\n   *\n   * @param beef\n   * @param txids\n   * @returns\n   */\n  async postBeef(beef: Beef, txids: string[]): Promise<PostBeefResult> {\n    const nn = () => ({\n      name: 'BitailsPostBeef',\n      when: new Date().toISOString()\n    })\n    const nne = () => ({ ...nn(), beef: beef.toHex(), txids: txids.join(',') })\n\n    const note: ReqHistoryNote = { ...nn(), what: 'postBeef' }\n\n    const raws: string[] = []\n    for (const txid of txids) {\n      const rawTx = Utils.toHex(beef.findTxid(txid)!.rawTx!)\n      raws.push(rawTx)\n    }\n\n    const r = await this.postRaws(raws, txids)\n\n    r.notes!.unshift(note)\n    if (r.status === 'success') r.notes!.push({ ...nn(), what: 'postBeefSuccess' })\n    else r.notes!.push({ ...nne(), what: 'postBeefError' })\n\n    return r\n  }\n\n  /**\n   * @param raws Array of raw transactions to broadcast as hex strings\n   * @param txids Array of txids for transactions in raws for which results are requested, remaining raws are supporting only.\n   * @returns\n   */\n  async postRaws(raws: HexString[], txids?: string[]): Promise<PostBeefResult> {\n    const { result: r, rawTxids } = initializeBitailsPostResult(raws, txids)\n\n    const headers = this.getHttpHeaders()\n    headers['Content-Type'] = 'application/json'\n    // headers['Accept'] = 'text/json'\n\n    const data = { raws }\n    const requestOptions = {\n      method: 'POST',\n      headers,\n      data\n    }\n\n    const url = `${this.URL}tx/broadcast/multi`\n    const notes: BitailsPostNoteContext = {\n      nn: () => ({\n        name: 'BitailsPostRawTx',\n        when: new Date().toISOString()\n      }),\n      nne: () => ({\n        name: 'BitailsPostRawTx',\n        when: new Date().toISOString(),\n        raws: raws.join(','),\n        txids: r.txidResults.map(result => result.txid).join(','),\n        url\n      })\n    }\n\n    try {\n      const response = await this.httpClient.request<BitailsPostRawsResult[]>(url, requestOptions)\n      if (response.ok) {\n        if (reconcileBitailsResponseTxids(r, response.data, rawTxids, notes)) {\n          applyRequestedBitailsResults(r, response.data, notes)\n        }\n      } else {\n        r.status = 'error'\n        const n: ReqHistoryNote = { ...notes.nne(), what: 'postRawsError' }\n        r.notes!.push(n)\n      }\n    } catch (error_: unknown) {\n      r.status = 'error'\n      const e = WalletError.fromUnknown(error_)\n      const { code, description } = e\n      r.notes!.push({ ...notes.nne(), what: 'postRawsCatch', code, description })\n    }\n    return r\n  }\n\n  /**\n   *\n   * @param txid\n   * @param services\n   * @returns\n   */\n  async getMerklePath(txid: string, services: WalletServices): Promise<GetMerklePathResult> {\n    const r: GetMerklePathResult = { name: 'BitailsTsc', notes: [] }\n\n    const url = `${this.URL}tx/${txid}/proof/tsc`\n\n    const nn = () => ({ name: 'BitailsProofTsc', when: new Date().toISOString(), txid, url })\n\n    const headers = this.getHttpHeaders()\n    const requestOptions = { method: 'GET', headers }\n\n    try {\n      const response = await this.httpClient.request<BitailsMerkleProof>(url, requestOptions)\n\n      const nne = () => ({ ...nn(), txid, url, status: response.status, statusText: response.statusText })\n\n      if (response.status === 404 && response.statusText === 'Not Found') {\n        r.notes!.push({ ...nn(), what: 'getMerklePathNotFound' })\n      } else if (!response.ok || response.status !== 200 || response.statusText !== 'OK') {\n        r.notes!.push({ ...nne(), what: 'getMerklePathBadStatus' })\n      } else if (response.data) {\n        const p = response.data\n        const header = await services.hashToHeader(p.target)\n        if (header) {\n          const proof = { index: p.index, nodes: p.nodes, height: header.height }\n          r.merklePath = convertProofToMerklePath(txid, proof)\n          r.header = header\n          r.notes!.push({ ...nne(), what: 'getMerklePathSuccess' })\n        } else {\n          r.notes!.push({ ...nne(), what: 'getMerklePathNoHeader', target: p.target })\n        }\n      } else {\n        r.notes!.push({ ...nne(), what: 'getMerklePathNoData' })\n      }\n    } catch (error_: unknown) {\n      const e = WalletError.fromUnknown(error_)\n      const { code, description } = e\n      r.notes!.push({ ...nn(), what: 'getMerklePathCatch', code, description })\n      r.error = e\n    }\n    return r\n  }\n}\n\ninterface BitailsPostRawsResult {\n  txid?: string\n  error?: {\n    code: number\n    message: string\n  }\n}\n\nexport interface BitailsMerkleProof {\n  index: number\n  txOrId: string\n  target: string\n  nodes: string[]\n}\n","import { Beef, ListActionsResult, ListOutputsResult, Validation } from '@bsv/sdk'\nimport {\n  TrxToken,\n  PurgeParams,\n  PurgeResults,\n  ProvenOrRawTx,\n  AuthId,\n  FindCertificatesArgs,\n  FindOutputBasketsArgs,\n  FindOutputsArgs,\n  FindOutputTagMapsArgs,\n  FindProvenTxReqsArgs,\n  FindProvenTxsArgs,\n  FindTxLabelMapsArgs,\n  FindCertificateFieldsArgs,\n  FindCommissionsArgs,\n  FindMonitorEventsArgs,\n  FindOutputTagsArgs,\n  FindSyncStatesArgs,\n  FindTransactionsArgs,\n  FindTxLabelsArgs,\n  FindUsersArgs,\n  FindForUserSincePagedArgs,\n  StorageGetBeefOptions\n} from '../../sdk'\nimport {\n  TableCertificate,\n  TableCertificateField,\n  TableCertificateX,\n  TableCommission,\n  TableMonitorEvent,\n  TableOutput,\n  TableOutputBasket,\n  TableOutputTag,\n  TableOutputTagMap,\n  TableProvenTx,\n  TableProvenTxReq,\n  TableSettings,\n  TableSyncState,\n  TableTransaction,\n  TableTxLabel,\n  TableTxLabelMap,\n  TableUser\n} from '../../storage/schema/tables'\nimport { Services } from '../Services'\nimport { StorageProvider, StorageAdminStats } from '../../storage/StorageProvider'\n\nexport async function getBeefForTxid (services: Services, txid: string): Promise<Beef> {\n  const storage = new ServicesOnlyStorageProvider(services)\n  const beef = await storage.getBeefForTxid(txid)\n  return beef\n}\n\n/**\n * The generalized implementation of getBeefForTransaction uses storage to\n * avoid incurring the cost of redundant block chain data queries.\n *\n * This class makes the generalized implementation of getBeefForTransaction\n * available in situations where there storage is not relevant.\n */\nclass ServicesOnlyStorageProvider extends StorageProvider {\n  gbo: StorageGetBeefOptions\n\n  constructor (services: Services) {\n    const o = StorageProvider.createStorageBaseOptions(services.chain)\n    super(o)\n    this.setServices(services)\n    this.gbo = {\n      ignoreServices: false,\n      ignoreStorage: true,\n      ignoreNewProven: true\n    }\n  }\n\n  async getBeefForTxid (txid: string): Promise<Beef> {\n    const beef = await this.getBeefForTransaction(txid, this.gbo)\n    return beef\n  }\n\n  nip = new Error('Method not implemented.')\n  override reviewStatus (args: { agedLimit: Date, trx?: TrxToken }): Promise<{ log: string }> {\n    throw this.nip\n  }\n\n  override purgeData (params: PurgeParams, trx?: TrxToken): Promise<PurgeResults> {\n    throw this.nip\n  }\n\n  override allocateChangeInput (\n    userId: number,\n    basketId: number,\n    targetSatoshis: number,\n    exactSatoshis: number | undefined,\n    excludeSending: boolean,\n    transactionId: number\n  ): Promise<TableOutput | undefined> {\n    throw this.nip\n  }\n\n  override getProvenOrRawTx (txid: string, trx?: TrxToken): Promise<ProvenOrRawTx> {\n    throw this.nip\n  }\n\n  override getRawTxOfKnownValidTransaction (\n    txid?: string,\n    offset?: number,\n    length?: number,\n    trx?: TrxToken\n  ): Promise<number[] | undefined> {\n    throw this.nip\n  }\n\n  override getLabelsForTransactionId (transactionId?: number, trx?: TrxToken): Promise<TableTxLabel[]> {\n    throw this.nip\n  }\n\n  override getTagsForOutputId (outputId: number, trx?: TrxToken): Promise<TableOutputTag[]> {\n    throw this.nip\n  }\n\n  override listActions (auth: AuthId, args: Validation.ValidListActionsArgs): Promise<ListActionsResult> {\n    throw this.nip\n  }\n\n  override listOutputs (auth: AuthId, args: Validation.ValidListOutputsArgs): Promise<ListOutputsResult> {\n    throw this.nip\n  }\n\n  override countChangeInputs (userId: number, basketId: number, excludeSending: boolean): Promise<number> {\n    throw this.nip\n  }\n\n  override findCertificatesAuth (auth: AuthId, args: FindCertificatesArgs): Promise<TableCertificateX[]> {\n    throw this.nip\n  }\n\n  override findOutputBasketsAuth (auth: AuthId, args: FindOutputBasketsArgs): Promise<TableOutputBasket[]> {\n    throw this.nip\n  }\n\n  override findOutputsAuth (auth: AuthId, args: FindOutputsArgs): Promise<TableOutput[]> {\n    throw this.nip\n  }\n\n  override insertCertificateAuth (auth: AuthId, certificate: TableCertificateX): Promise<number> {\n    throw this.nip\n  }\n\n  override dropAllData (): Promise<void> {\n    throw this.nip\n  }\n\n  override migrate (storageName: string, storageIdentityKey: string): Promise<string> {\n    throw this.nip\n  }\n\n  override findOutputTagMaps (args: FindOutputTagMapsArgs): Promise<TableOutputTagMap[]> {\n    throw this.nip\n  }\n\n  override findProvenTxReqs (args: FindProvenTxReqsArgs): Promise<TableProvenTxReq[]> {\n    throw this.nip\n  }\n\n  override findProvenTxs (args: FindProvenTxsArgs): Promise<TableProvenTx[]> {\n    throw this.nip\n  }\n\n  override findTxLabelMaps (args: FindTxLabelMapsArgs): Promise<TableTxLabelMap[]> {\n    throw this.nip\n  }\n\n  override countOutputTagMaps (args: FindOutputTagMapsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countProvenTxReqs (args: FindProvenTxReqsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countProvenTxs (args: FindProvenTxsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countTxLabelMaps (args: FindTxLabelMapsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override insertCertificate (certificate: TableCertificate, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertCertificateField (certificateField: TableCertificateField, trx?: TrxToken): Promise<void> {\n    throw this.nip\n  }\n\n  override insertCommission (commission: TableCommission, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertMonitorEvent (event: TableMonitorEvent, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertOutput (output: TableOutput, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertOutputBasket (basket: TableOutputBasket, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertOutputTag (tag: TableOutputTag, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertOutputTagMap (tagMap: TableOutputTagMap, trx?: TrxToken): Promise<void> {\n    throw this.nip\n  }\n\n  override insertProvenTx (tx: TableProvenTx, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertProvenTxReq (tx: TableProvenTxReq, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertSyncState (syncState: TableSyncState, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertTransaction (tx: TableTransaction, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertTxLabel (label: TableTxLabel, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override insertTxLabelMap (labelMap: TableTxLabelMap, trx?: TrxToken): Promise<void> {\n    throw this.nip\n  }\n\n  override insertUser (user: TableUser, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateCertificate (id: number, update: Partial<TableCertificate>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateCertificateField (\n    certificateId: number,\n    fieldName: string,\n    update: Partial<TableCertificateField>,\n    trx?: TrxToken\n  ): Promise<number> {\n    throw this.nip\n  }\n\n  override updateCommission (id: number, update: Partial<TableCommission>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateMonitorEvent (id: number, update: Partial<TableMonitorEvent>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateOutput (id: number, update: Partial<TableOutput>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateOutputBasket (id: number, update: Partial<TableOutputBasket>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateOutputTag (id: number, update: Partial<TableOutputTag>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateOutputTagMap (\n    outputId: number,\n    tagId: number,\n    update: Partial<TableOutputTagMap>,\n    trx?: TrxToken\n  ): Promise<number> {\n    throw this.nip\n  }\n\n  override updateProvenTx (id: number, update: Partial<TableProvenTx>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateProvenTxReq (\n    id: number | number[],\n    update: Partial<TableProvenTxReq>,\n    trx?: TrxToken\n  ): Promise<number> {\n    throw this.nip\n  }\n\n  override updateSyncState (id: number, update: Partial<TableSyncState>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateTransaction (\n    id: number | number[],\n    update: Partial<TableTransaction>,\n    trx?: TrxToken\n  ): Promise<number> {\n    throw this.nip\n  }\n\n  override updateTxLabel (id: number, update: Partial<TableTxLabel>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override updateTxLabelMap (\n    transactionId: number,\n    txLabelId: number,\n    update: Partial<TableTxLabelMap>,\n    trx?: TrxToken\n  ): Promise<number> {\n    throw this.nip\n  }\n\n  override updateUser (id: number, update: Partial<TableUser>, trx?: TrxToken): Promise<number> {\n    throw this.nip\n  }\n\n  override destroy (): Promise<void> {\n    throw this.nip\n  }\n\n  override transaction<T>(scope: (trx: TrxToken) => Promise<T>, trx?: TrxToken): Promise<T> {\n    throw this.nip\n  }\n\n  override readSettings (trx?: TrxToken): Promise<TableSettings> {\n    throw this.nip\n  }\n\n  override findCertificateFields (args: FindCertificateFieldsArgs): Promise<TableCertificateField[]> {\n    throw this.nip\n  }\n\n  override findCertificates (args: FindCertificatesArgs): Promise<TableCertificateX[]> {\n    throw this.nip\n  }\n\n  override findCommissions (args: FindCommissionsArgs): Promise<TableCommission[]> {\n    throw this.nip\n  }\n\n  override findMonitorEvents (args: FindMonitorEventsArgs): Promise<TableMonitorEvent[]> {\n    throw this.nip\n  }\n\n  override findOutputBaskets (args: FindOutputBasketsArgs): Promise<TableOutputBasket[]> {\n    throw this.nip\n  }\n\n  override findOutputs (args: FindOutputsArgs): Promise<TableOutput[]> {\n    throw this.nip\n  }\n\n  override findOutputTags (args: FindOutputTagsArgs): Promise<TableOutputTag[]> {\n    throw this.nip\n  }\n\n  override findSyncStates (args: FindSyncStatesArgs): Promise<TableSyncState[]> {\n    throw this.nip\n  }\n\n  override findTransactions (args: FindTransactionsArgs): Promise<TableTransaction[]> {\n    throw this.nip\n  }\n\n  override findTxLabels (args: FindTxLabelsArgs): Promise<TableTxLabel[]> {\n    throw this.nip\n  }\n\n  override findUsers (args: FindUsersArgs): Promise<TableUser[]> {\n    throw this.nip\n  }\n\n  override countCertificateFields (args: FindCertificateFieldsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countCertificates (args: FindCertificatesArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countCommissions (args: FindCommissionsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countMonitorEvents (args: FindMonitorEventsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countOutputBaskets (args: FindOutputBasketsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countOutputs (args: FindOutputsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countOutputTags (args: FindOutputTagsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countSyncStates (args: FindSyncStatesArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countTransactions (args: FindTransactionsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countTxLabels (args: FindTxLabelsArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override countUsers (args: FindUsersArgs): Promise<number> {\n    throw this.nip\n  }\n\n  override getProvenTxsForUser (args: FindForUserSincePagedArgs): Promise<TableProvenTx[]> {\n    throw this.nip\n  }\n\n  override getProvenTxReqsForUser (args: FindForUserSincePagedArgs): Promise<TableProvenTxReq[]> {\n    throw this.nip\n  }\n\n  override getTxLabelMapsForUser (args: FindForUserSincePagedArgs): Promise<TableTxLabelMap[]> {\n    throw this.nip\n  }\n\n  override getOutputTagMapsForUser (args: FindForUserSincePagedArgs): Promise<TableOutputTagMap[]> {\n    throw this.nip\n  }\n\n  override adminStats (adminIdentityKey: string): Promise<StorageAdminStats> {\n    throw this.nip\n  }\n}\n","import { ChainTracker, Telemetry, TelemetryConfig, TelemetrySpan } from '@bsv/sdk'\nimport { ChaintracksServiceClient } from './chaintracks/ChaintracksServiceClient'\nimport { Chain } from '../../sdk/types'\nimport { WalletError } from '../../sdk/WalletError'\nimport { wait } from '../../utility/utilityHelpers'\nimport { BlockHeader } from '../../sdk/WalletServices.interfaces'\nimport { ChaintracksClientApi } from './chaintracks/Api/ChaintracksClientApi'\n\nexport interface ChaintracksChainTrackerOptions {\n  maxRetries?: number\n  retryDelayMs?: number\n  telemetry?: TelemetryConfig\n}\n\nexport class ChaintracksChainTracker implements ChainTracker {\n  chaintracks: ChaintracksClientApi\n  cache: Record<number, string>\n  options: ChaintracksChainTrackerOptions\n  readonly telemetry: Telemetry\n\n  constructor(chain?: Chain, chaintracks?: ChaintracksClientApi, options?: ChaintracksChainTrackerOptions) {\n    chain ||= 'main'\n    this.chaintracks =\n      chaintracks ?? new ChaintracksServiceClient(chain, `https://${chain}net-chaintracks.babbage.systems`)\n    this.cache = {}\n    this.options = options || {}\n    this.telemetry = new Telemetry(this.options.telemetry)\n  }\n\n  async currentHeight(): Promise<number> {\n    if (!this.telemetry.enabled) return await this.chaintracks.getPresentHeight()\n    return await this.telemetry.withSpan(\n      'wallet.chaintracks.current_height',\n      {\n        component: 'chaintracks-chain-tracker',\n        kind: 'client'\n      },\n      async () => await this.chaintracks.getPresentHeight()\n    )\n  }\n\n  async isValidRootForHeight(root: string, height: number): Promise<boolean> {\n    if (!this.telemetry.enabled) return await this.isValidRootForHeightCore(root, height)\n    return await this.telemetry.withSpan(\n      'wallet.chaintracks.validate_root',\n      {\n        component: 'chaintracks-chain-tracker',\n        kind: 'client'\n      },\n      async span => await this.isValidRootForHeightCore(root, height, span)\n    )\n  }\n\n  private async isValidRootForHeightCore(root: string, height: number, parent?: TelemetrySpan): Promise<boolean> {\n    const cachedRoot = this.cache[height]\n    if (cachedRoot) {\n      parent?.end({\n        attributes: {\n          'chaintracks.cache_hit': true,\n          'chaintracks.valid': cachedRoot === root\n        }\n      })\n      return cachedRoot === root\n    }\n\n    let header: BlockHeader | undefined\n\n    const retries = Math.max(1, this.options.maxRetries ?? 6)\n    const retryDelayMs = this.options.retryDelayMs ?? 250\n\n    let error: WalletError | undefined\n\n    for (let tryCount = 1; tryCount <= retries; tryCount++) {\n      try {\n        header =\n          parent == null\n            ? await this.chaintracks.findHeaderForHeight(height)\n            : await this.telemetry.withSpan(\n                'wallet.chaintracks.find_header',\n                {\n                  component: 'chaintracks-chain-tracker',\n                  kind: 'client',\n                  parent: parent.context,\n                  attributes: {\n                    'retry.attempt': tryCount\n                  }\n                },\n                async () => await this.chaintracks.findHeaderForHeight(height)\n              )\n\n        if (header == null) {\n          if (tryCount >= retries) return false\n          await wait(retryDelayMs)\n          continue\n        }\n\n        break\n      } catch (error_: unknown) {\n        error = WalletError.fromUnknown(error_)\n        if (tryCount >= retries) {\n          throw error\n        }\n        await wait(retryDelayMs)\n      }\n    }\n\n    if (header == null) return false\n\n    this.cache[height] = header.merkleRoot\n\n    const valid = header.merkleRoot === root\n    parent?.end({\n      attributes: {\n        'chaintracks.cache_hit': false,\n        'chaintracks.valid': valid\n      }\n    })\n    return valid\n  }\n}\n","import {\n  Transaction as BsvTransaction,\n  Beef,\n  ChainTracker,\n  Telemetry,\n  TelemetrySpan,\n  Utils,\n  WalletLoggerInterface\n} from '@bsv/sdk'\nimport { ServiceCollection, ServiceToCall } from './ServiceCollection'\nimport { createDefaultWalletServicesOptions } from './createDefaultWalletServicesOptions'\nimport { WhatsOnChain } from './providers/WhatsOnChain'\nimport { updateChaintracksFiatExchangeRates, updateExchangeratesapi } from './providers/exchangeRates'\nimport { ARC } from './providers/ARC'\nimport { Arcade } from './providers/Arcade'\nimport { Bitails } from './providers/Bitails'\nimport { getBeefForTxid } from './providers/getBeefForTxid'\nimport {\n  BaseBlockHeader,\n  BlockHeader,\n  FiatExchangeRates,\n  GetMerklePathResult,\n  GetMerklePathService,\n  GetRawTxResult,\n  GetRawTxService,\n  GetScriptHashHistoryResult,\n  GetScriptHashHistoryService,\n  GetStatusForTxidsResult,\n  GetStatusForTxidsService,\n  GetUtxoStatusOutputFormat,\n  GetUtxoStatusResult,\n  GetUtxoStatusService,\n  PostBeefResult,\n  PostBeefService,\n  ServicesCallHistory,\n  UpdateFiatExchangeRateService,\n  WalletServices,\n  WalletServicesOptions\n} from '../sdk/WalletServices.interfaces'\nimport type { FiatCurrencyCode } from '../sdk/WalletServices.interfaces'\nimport { Chain } from '../sdk/types'\nimport { WERR_INTERNAL, WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../sdk/WERR_errors'\nimport { ChaintracksChainTracker } from './chaintracker/ChaintracksChainTracker'\nimport { WalletError } from '../sdk/WalletError'\nimport { doubleSha256BE, sha256Hash, wait } from '../utility/utilityHelpers'\nimport { TableOutput } from '../storage/schema/tables/TableOutput'\nimport { asArray, asString } from '../utility/utilityHelpers.noBuffer'\n\nexport class Services implements WalletServices {\n  static readonly getStatusForTxidsBatchLimit = 20\n\n  static createDefaultOptions(chain: Chain): WalletServicesOptions {\n    return createDefaultWalletServicesOptions(chain)\n  }\n\n  options: WalletServicesOptions\n  whatsonchain: WhatsOnChain\n  arcTaal: ARC\n  arcGorillaPool?: ARC\n  /** Primary Arcade (bsv-blockchain/arcade) broadcaster, when `options.arcadeUrl` is set. */\n  arcade?: Arcade\n  bitails?: Bitails\n\n  getMerklePathServices!: ServiceCollection<GetMerklePathService>\n  getRawTxServices!: ServiceCollection<GetRawTxService>\n  postBeefServices!: ServiceCollection<PostBeefService>\n  getUtxoStatusServices!: ServiceCollection<GetUtxoStatusService>\n  getStatusForTxidsServices!: ServiceCollection<GetStatusForTxidsService>\n  getScriptHashHistoryServices!: ServiceCollection<GetScriptHashHistoryService>\n  updateFiatExchangeRateServices!: ServiceCollection<UpdateFiatExchangeRateService>\n\n  chain: Chain\n  readonly telemetry: Telemetry\n\n  constructor(optionsOrChain: Chain | WalletServicesOptions) {\n    this.chain = typeof optionsOrChain === 'string' ? optionsOrChain : optionsOrChain.chain\n\n    if (this.chain === 'mock') {\n      throw new WERR_INVALID_PARAMETER(\n        'chain',\n        \"'main', 'test', 'stn', 'ttn', or 'tstn'. Use MockServices for 'mock' chain.\"\n      )\n    }\n\n    this.options = typeof optionsOrChain === 'string' ? Services.createDefaultOptions(this.chain) : optionsOrChain\n    this.telemetry = new Telemetry(this.options.telemetry)\n\n    this.whatsonchain = new WhatsOnChain(this.chain, { apiKey: this.options.whatsOnChainApiKey }, this)\n\n    this.arcTaal = new ARC(this.options.arcUrl, this.options.arcConfig, 'arcTaal')\n    const { hasBitails, hasWhatsOnChain } = this.configureOptionalProviders()\n    this.initializeReadServices(hasBitails, hasWhatsOnChain)\n    this.initializePostBeefServices(hasBitails, hasWhatsOnChain)\n    this.initializeFiatRateServices()\n  }\n\n  private configureOptionalProviders(): { hasBitails: boolean; hasWhatsOnChain: boolean } {\n    if (this.options.arcGorillaPoolUrl != null && this.options.arcGorillaPoolUrl !== '') {\n      this.arcGorillaPool = new ARC(this.options.arcGorillaPoolUrl, this.options.arcGorillaPoolConfig, 'arcGorillaPool')\n    }\n    if (this.options.arcadeUrl != null && this.options.arcadeUrl !== '') {\n      this.arcade = new Arcade(this.options.arcadeUrl, this.options.arcadeConfig, 'arcade')\n    }\n\n    const hasBitails = this.chain === 'main' || this.chain === 'test'\n\n    // The public WhatsOnChain API documents mainnet and testnet only.\n    // Teranode-family networks use Arcade/ChainTracks and explicit operator\n    // endpoints instead of being silently aliased to testnet.\n    const hasWhatsOnChain = this.chain === 'main' || this.chain === 'test'\n\n    if (hasBitails) {\n      this.bitails = new Bitails(this.chain, { apiKey: this.options.bitailsApiKey })\n    }\n    return { hasBitails, hasWhatsOnChain }\n  }\n\n  private initializeReadServices(hasBitails: boolean, hasWhatsOnChain: boolean): void {\n    this.getMerklePathServices = new ServiceCollection<GetMerklePathService>('getMerklePath')\n    // Arcade is first when configured: it can return proofs for transactions\n    // it broadcast and otherwise allows the collection to fall through.\n    if (this.arcade != null) {\n      // prettier-ignore\n      this.getMerklePathServices.add({ name: 'Arcade', service: this.arcade.getMerklePath.bind(this.arcade) })\n    }\n    if (hasWhatsOnChain) {\n      // prettier-ignore\n      this.getMerklePathServices\n        .add({ name: 'WhatsOnChain', service: this.whatsonchain.getMerklePath.bind(this.whatsonchain) })\n    }\n    if (hasBitails && this.bitails != null) {\n      this.getMerklePathServices.add({ name: 'Bitails', service: this.bitails.getMerklePath.bind(this.bitails) })\n    }\n\n    this.getRawTxServices = new ServiceCollection<GetRawTxService>('getRawTx')\n    if (hasWhatsOnChain) {\n      // prettier-ignore\n      this.getRawTxServices\n        .add({ name: 'WhatsOnChain', service: this.whatsonchain.getRawTxResult.bind(this.whatsonchain) })\n    }\n\n    this.getUtxoStatusServices = new ServiceCollection<GetUtxoStatusService>('getUtxoStatus')\n    if (hasWhatsOnChain) {\n      // prettier-ignore\n      this.getUtxoStatusServices\n        .add({ name: 'WhatsOnChain', service: this.whatsonchain.getUtxoStatus.bind(this.whatsonchain) })\n    }\n\n    this.getStatusForTxidsServices = new ServiceCollection<GetStatusForTxidsService>('getStatusForTxids')\n    if (hasWhatsOnChain) {\n      // prettier-ignore\n      this.getStatusForTxidsServices\n        .add({ name: 'WhatsOnChain', service: this.whatsonchain.getStatusForTxids.bind(this.whatsonchain) })\n    }\n\n    this.getScriptHashHistoryServices = new ServiceCollection<GetScriptHashHistoryService>('getScriptHashHistory')\n    if (hasWhatsOnChain) {\n      // prettier-ignore\n      this.getScriptHashHistoryServices\n        .add({ name: 'WhatsOnChain', service: this.whatsonchain.getScriptHashHistory.bind(this.whatsonchain) })\n    }\n  }\n\n  private initializePostBeefServices(hasBitails: boolean, hasWhatsOnChain: boolean): void {\n    this.postBeefServices = new ServiceCollection<PostBeefService>('postBeef')\n    // Arcade remains the primary broadcaster. ARC and explorer providers\n    // retain their existing fallback order under the default UntilSuccess mode.\n    if (this.arcade != null) {\n      // prettier-ignore\n      this.postBeefServices.add({ name: 'ArcadeBeef', service: this.arcade.postBeef.bind(this.arcade) })\n    }\n    if (this.arcGorillaPool != null) {\n      // prettier-ignore\n      this.postBeefServices.add({ name: 'GorillaPoolArcBeef', service: this.arcGorillaPool.postBeef.bind(this.arcGorillaPool) })\n    }\n    // prettier-ignore\n    this.postBeefServices\n      .add({ name: 'TaalArcBeef', service: this.arcTaal.postBeef.bind(this.arcTaal) })\n    if (hasBitails && this.bitails != null) {\n      this.postBeefServices.add({ name: 'Bitails', service: this.bitails.postBeef.bind(this.bitails) })\n    }\n    if (hasWhatsOnChain) {\n      // prettier-ignore\n      this.postBeefServices\n        .add({ name: 'WhatsOnChain', service: this.whatsonchain.postBeef.bind(this.whatsonchain) })\n    }\n  }\n\n  private initializeFiatRateServices(): void {\n    // prettier-ignore\n    this.updateFiatExchangeRateServices = new ServiceCollection<UpdateFiatExchangeRateService>('updateFiatExchangeRate')\n    // A configured paid exchange-rate service is exclusive; otherwise use\n    // Chaintracks as the zero-configuration default.\n    if (this.options.exchangeratesapiKey != null && this.options.exchangeratesapiKey !== '') {\n      this.updateFiatExchangeRateServices.add({ name: 'exchangeratesapi', service: updateExchangeratesapi })\n    } else {\n      this.updateFiatExchangeRateServices.add({\n        name: 'ChaintracksFiatRates',\n        service: updateChaintracksFiatExchangeRates\n      })\n    }\n  }\n\n  getServicesCallHistory(reset?: boolean): ServicesCallHistory {\n    return {\n      version: 2,\n      getMerklePath: this.getMerklePathServices.getServiceCallHistory(reset),\n      getRawTx: this.getRawTxServices.getServiceCallHistory(reset),\n      postBeef: this.postBeefServices.getServiceCallHistory(reset),\n      getUtxoStatus: this.getUtxoStatusServices.getServiceCallHistory(reset),\n      getStatusForTxids: this.getStatusForTxidsServices.getServiceCallHistory(reset),\n      getScriptHashHistory: this.getScriptHashHistoryServices.getServiceCallHistory(reset),\n      updateFiatExchangeRates: this.updateFiatExchangeRateServices.getServiceCallHistory(reset)\n    }\n  }\n\n  async getChainTracker(): Promise<ChainTracker> {\n    if (this.options.chaintracks == null) {\n      throw new WERR_INVALID_PARAMETER('options.chaintracks', \"valid to enable 'getChainTracker' service.\")\n    }\n    return new ChaintracksChainTracker(this.chain, this.options.chaintracks, {\n      telemetry: this.options.telemetry\n    })\n  }\n\n  async getBsvExchangeRate(): Promise<number> {\n    this.options.bsvExchangeRate = await this.whatsonchain.updateBsvExchangeRate(\n      this.options.bsvExchangeRate,\n      this.options.bsvUpdateMsecs\n    )\n    return this.options.bsvExchangeRate.rate\n  }\n\n  async getFiatExchangeRate(currency: FiatCurrencyCode, base?: FiatCurrencyCode): Promise<number> {\n    base ||= 'USD'\n    if (currency === base) return 1\n\n    const required: FiatCurrencyCode[] = base === 'USD' ? [currency] : [currency, base]\n    await this.updateFiatExchangeRates(required, this.options.fiatUpdateMsecs)\n\n    const rates = this.options.fiatExchangeRates\n    const c = rates.rates?.[currency]\n    const b = rates.rates?.[base]\n    if (typeof c !== 'number') {\n      throw new WERR_INVALID_PARAMETER('currency', `valid fiat currency '${currency}' with an exchange rate.`)\n    }\n    if (typeof b !== 'number') {\n      throw new WERR_INVALID_PARAMETER('base', `valid fiat currency '${base}' with an exchange rate.`)\n    }\n    return c / b\n  }\n\n  async getFiatExchangeRates(targetCurrencies: FiatCurrencyCode[]): Promise<FiatExchangeRates> {\n    await this.updateFiatExchangeRates(targetCurrencies, this.options.fiatUpdateMsecs)\n\n    const stored = this.options.fiatExchangeRates\n    const rates: Record<string, number> = {}\n    for (const c of targetCurrencies) {\n      const v = stored.rates?.[c]\n      if (typeof v === 'number') {\n        rates[c] = v\n      }\n    }\n\n    return {\n      timestamp: stored.timestamp,\n      base: 'USD',\n      rates,\n      rateTimestamps: stored.rateTimestamps\n    }\n  }\n\n  get getProofsCount(): number {\n    return this.getMerklePathServices.count\n  }\n\n  get getRawTxsCount(): number {\n    return this.getRawTxServices.count\n  }\n\n  get postBeefServicesCount(): number {\n    return this.postBeefServices.count\n  }\n\n  get getUtxoStatsCount(): number {\n    return this.getUtxoStatusServices.count\n  }\n\n  async getStatusForTxids(txids: string[], useNext?: boolean): Promise<GetStatusForTxidsResult> {\n    const services = this.getStatusForTxidsServices\n    if (useNext === true) services.next()\n\n    let r0: GetStatusForTxidsResult = {\n      name: '<noservices>',\n      status: 'error',\n      error: new WERR_INTERNAL('No services available.'),\n      results: []\n    }\n\n    for (let tries = 0; tries < services.count; tries++) {\n      const stc = services.serviceToCall\n      try {\n        const r = await this.getStatusForTxidsBatched(stc, txids)\n        if (r.status === 'success') {\n          services.addServiceCallSuccess(stc)\n          r0 = r\n          break\n        }\n        if (r.error != null) services.addServiceCallError(stc, r.error)\n        else services.addServiceCallFailure(stc)\n      } catch (error_: unknown) {\n        const e = WalletError.fromUnknown(error_)\n        services.addServiceCallError(stc, e)\n      }\n      services.next()\n    }\n\n    return r0\n  }\n\n  private async getStatusForTxidsBatched(\n    stc: ServiceToCall<GetStatusForTxidsService>,\n    txids: string[]\n  ): Promise<GetStatusForTxidsResult> {\n    const results: GetStatusForTxidsResult['results'] = []\n    let error: GetStatusForTxidsResult['error']\n\n    for (let i = 0; i < txids.length; i += Services.getStatusForTxidsBatchLimit) {\n      const batch = txids.slice(i, i + Services.getStatusForTxidsBatchLimit)\n      const r = await stc.service(batch)\n      if (r.status !== 'success') {\n        return r\n      }\n      if (error == null && r.error != null) error = r.error\n      results.push(...r.results)\n    }\n\n    return {\n      name: stc.providerName,\n      status: 'success',\n      error,\n      results\n    }\n  }\n\n  /**\n   * @param script Output script to be hashed for `getUtxoStatus` default `outputFormat`\n   * @returns script hash in 'hashLE' format, which is the default.\n   */\n  hashOutputScript(script: string): string {\n    const hash = Utils.toHex(sha256Hash(Utils.toArray(script, 'hex')))\n    return hash\n  }\n\n  async isUtxo(output: TableOutput): Promise<boolean> {\n    if (output.lockingScript == null) {\n      throw new WERR_INVALID_PARAMETER('output.lockingScript', 'validated by storage provider validateOutputScript.')\n    }\n    const hash = this.hashOutputScript(Utils.toHex(output.lockingScript))\n    const or = await this.getUtxoStatus(hash, undefined, `${output.txid ?? ''}.${output.vout}`)\n    return or.isUtxo === true\n  }\n\n  async getUtxoStatus(\n    output: string,\n    outputFormat?: GetUtxoStatusOutputFormat,\n    outpoint?: string,\n    useNext?: boolean,\n    logger?: WalletLoggerInterface\n  ): Promise<GetUtxoStatusResult> {\n    const services = this.getUtxoStatusServices\n    if (useNext === true) services.next()\n\n    let r0: GetUtxoStatusResult = {\n      name: '<noservices>',\n      status: 'error',\n      error: new WERR_INTERNAL('No services available.'),\n      details: []\n    }\n\n    logger?.group('services getUtxoStatus')\n    for (let retry = 0; retry < 2; retry++) {\n      r0 = (await this.tryUtxoStatusProviders(services, output, outputFormat, outpoint, logger)) ?? r0\n      if (r0.status === 'success') break\n      await wait(2000)\n    }\n    logger?.groupEnd()\n    return r0\n  }\n\n  private async tryUtxoStatusProviders(\n    services: ServiceCollection<GetUtxoStatusService>,\n    output: string,\n    outputFormat: GetUtxoStatusOutputFormat | undefined,\n    outpoint: string | undefined,\n    logger?: WalletLoggerInterface\n  ): Promise<GetUtxoStatusResult | undefined> {\n    for (let tries = 0; tries < services.count; tries++) {\n      const stc = services.serviceToCall\n      try {\n        const r = await stc.service(output, outputFormat, outpoint)\n        logger?.log(`${stc.providerName} status ${r.status}`)\n        if (r.status === 'success') {\n          services.addServiceCallSuccess(stc)\n          return r\n        }\n        if (r.error != null) services.addServiceCallError(stc, r.error)\n        else services.addServiceCallFailure(stc)\n      } catch (error_: unknown) {\n        services.addServiceCallError(stc, WalletError.fromUnknown(error_))\n      }\n      services.next()\n    }\n    return undefined\n  }\n\n  async getScriptHashHistory(\n    hash: string,\n    useNext?: boolean,\n    logger?: WalletLoggerInterface\n  ): Promise<GetScriptHashHistoryResult> {\n    const services = this.getScriptHashHistoryServices\n    if (useNext === true) services.next()\n\n    let r0: GetScriptHashHistoryResult = {\n      name: '<noservices>',\n      status: 'error',\n      error: new WERR_INTERNAL('No services available.'),\n      history: []\n    }\n\n    logger?.group('services getScriptHashHistory')\n    for (let tries = 0; tries < services.count; tries++) {\n      const stc = services.serviceToCall\n      try {\n        const r = await stc.service(hash)\n        logger?.log(`${stc.providerName} status ${r.status}`)\n        if (r.status === 'success') {\n          r0 = r\n          break\n        }\n        if (r.error != null) services.addServiceCallError(stc, r.error)\n        else services.addServiceCallFailure(stc)\n      } catch (error_: unknown) {\n        const e = WalletError.fromUnknown(error_)\n        services.addServiceCallError(stc, e)\n      }\n      services.next()\n    }\n    logger?.groupEnd()\n    return r0\n  }\n\n  postBeefMode: 'PromiseAll' | 'UntilSuccess' = 'UntilSuccess'\n  /**\n   * Soft timeout used for each provider call in `UntilSuccess` mode.\n   * This bounds request latency when a provider hangs before failover.\n   */\n  postBeefUntilSuccessSoftTimeoutMs = 5000\n  /**\n   * Additional soft-timeout budget (ms) per KiB of serialized Beef payload.\n   * Helps avoid false timeout failover on legitimately large submissions.\n   */\n  postBeefUntilSuccessSoftTimeoutPerKbMs = 50\n  /**\n   * Upper bound for adaptive soft-timeout in `UntilSuccess` mode.\n   */\n  postBeefUntilSuccessSoftTimeoutMaxMs = 30000\n\n  /**\n   *\n   * @param beef\n   * @param chain\n   * @returns\n   */\n  async postBeef(beef: Beef, txids: string[], logger?: WalletLoggerInterface): Promise<PostBeefResult[]> {\n    let rs: PostBeefResult[] = []\n    const services = this.postBeefServices\n    const stcs = services.allServicesToCall\n    const softTimeoutMs = this.getPostBeefSoftTimeoutMs(beef)\n    logger?.group('services postBeef')\n    switch (this.postBeefMode) {\n      case 'UntilSuccess':\n        for (const stc of stcs) {\n          const r = await callService(stc, softTimeoutMs)\n          logger?.log(`${stc.providerName} status ${r.status}`)\n          rs.push(r)\n          if (r.status === 'success') break\n          const softTimedOut = r.notes?.some(n => n.what === 'postBeefServiceTimeout') === true\n          if (!softTimedOut && r.txidResults?.every(txr => txr.serviceError)) {\n            // move this service to the end of the list\n            this.postBeefServices.moveServiceToLast(stc)\n          }\n        }\n        break\n      case 'PromiseAll':\n        rs = await Promise.all(\n          stcs.map(async stc => {\n            const r = await callService(stc)\n            return r\n          })\n        )\n        break\n    }\n    logger?.groupEnd()\n    return rs\n\n    async function callService(stc: ServiceToCall<PostBeefService>, timeoutMs?: number): Promise<PostBeefResult> {\n      const callPromise = stc.service(beef, txids)\n      let r: PostBeefResult\n      if (timeoutMs == null || timeoutMs <= 0) {\n        r = await callPromise\n      } else {\n        let timeoutHandle: ReturnType<typeof setTimeout> | undefined\n        const timeoutPromise = new Promise<PostBeefResult>(resolve => {\n          timeoutHandle = setTimeout(\n            () => resolve(makeServiceTimeoutResult(stc.providerName, txids, timeoutMs)),\n            timeoutMs\n          )\n        })\n        r = await Promise.race([callPromise, timeoutPromise])\n        if (timeoutHandle != null) clearTimeout(timeoutHandle)\n        // Avoid unhandled rejection after timeout race wins.\n        void callPromise.catch(() => undefined)\n      }\n\n      if (r.status === 'success') {\n        services.addServiceCallSuccess(stc)\n      } else if (r.error != null) {\n        services.addServiceCallError(stc, r.error)\n      } else {\n        services.addServiceCallFailure(stc)\n      }\n      return r\n    }\n\n    function makeServiceTimeoutResult(providerName: string, txids: string[], timeoutMs: number): PostBeefResult {\n      return {\n        name: providerName,\n        status: 'error',\n        txidResults: txids.map(txid => ({\n          txid,\n          status: 'error',\n          serviceError: true,\n          data: { detail: `timeout after ${timeoutMs}ms` }\n        })),\n        notes: [{ when: new Date().toISOString(), what: 'postBeefServiceTimeout', providerName, timeoutMs }]\n      }\n    }\n  }\n\n  private getPostBeefSoftTimeoutMs(beef: Beef): number {\n    const baseMs = Math.max(0, this.postBeefUntilSuccessSoftTimeoutMs)\n    const perKbMs = Math.max(0, this.postBeefUntilSuccessSoftTimeoutPerKbMs)\n    const maxMs = Math.max(baseMs, this.postBeefUntilSuccessSoftTimeoutMaxMs)\n    if (perKbMs <= 0) return Math.min(baseMs, maxMs)\n\n    const beefBytes = beef.toBinary().length\n    const extraMs = Math.ceil((beefBytes / 1024) * perKbMs)\n    return Math.min(maxMs, baseMs + extraMs)\n  }\n\n  async getRawTx(txid: string, useNext?: boolean): Promise<GetRawTxResult> {\n    const services = this.getRawTxServices\n    if (useNext === true) services.next()\n\n    const r0: GetRawTxResult = { txid }\n\n    for (let tries = 0; tries < services.count; tries++) {\n      const stc = services.serviceToCall\n      try {\n        const done = this.applyRawTxResult(r0, txid, await stc.service(txid, this.chain), services, stc)\n        if (done) break\n      } catch (error_: unknown) {\n        services.addServiceCallError(stc, WalletError.fromUnknown(error_))\n      }\n      services.next()\n    }\n    return r0\n  }\n\n  private applyRawTxResult(\n    r0: GetRawTxResult,\n    txid: string,\n    r: GetRawTxResult,\n    services: ServiceCollection<GetRawTxService>,\n    stc: ServiceToCall<GetRawTxService>\n  ): boolean {\n    if (r.rawTx != null) {\n      const hash = asString(doubleSha256BE(r.rawTx))\n      if (hash === asString(txid)) {\n        r0.rawTx = r.rawTx\n        r0.name = r.name\n        r0.error = undefined\n        services.addServiceCallSuccess(stc)\n        return true\n      }\n      r.error = new WERR_INTERNAL(`computed txid ${hash} doesn't match requested value ${txid}`)\n      r.rawTx = undefined\n    }\n\n    if (r.error != null) services.addServiceCallError(stc, r.error)\n    else services.addServiceCallSuccess(stc, 'not found')\n\n    // If we have an error and didn't before, capture it.\n    if (r.error != null && r0.error == null && r0.rawTx == null) r0.error = r.error\n    return false\n  }\n\n  async invokeChaintracksWithRetry<R>(method: () => Promise<R>, operation: string = 'unknown'): Promise<R> {\n    if (this.options.chaintracks == null) {\n      throw new WERR_INVALID_PARAMETER('options.chaintracks', 'valid for this service operation.')\n    }\n    if (!this.telemetry.enabled) return await this.invokeChaintracksWithRetryCore(method)\n    return await this.telemetry.withSpan(\n      'wallet.chaintracks.request',\n      {\n        component: 'wallet-services',\n        kind: 'client',\n        attributes: {\n          'chaintracks.operation': operation\n        }\n      },\n      async span => await this.invokeChaintracksWithRetryCore(method, span)\n    )\n  }\n\n  private async invokeChaintracksWithRetryCore<R>(method: () => Promise<R>, parent?: TelemetrySpan): Promise<R> {\n    for (let retry = 0; retry < 3; retry++) {\n      try {\n        const r: R =\n          parent == null\n            ? await method()\n            : await this.telemetry.withSpan(\n                'wallet.chaintracks.attempt',\n                {\n                  component: 'wallet-services',\n                  kind: 'client',\n                  parent: parent.context,\n                  attributes: {\n                    'retry.attempt': retry + 1\n                  }\n                },\n                method\n              )\n        return r\n      } catch (error_: unknown) {\n        const e = WalletError.fromUnknown(error_)\n        if (e.code !== 'ECONNRESET') throw error_\n      }\n    }\n    throw new WERR_INVALID_OPERATION('hashToHeader service unavailable')\n  }\n\n  async getHeaderForHeight(height: number): Promise<number[]> {\n    const method = async (): Promise<number[]> => {\n      const chaintracks = this.options.chaintracks as NonNullable<typeof this.options.chaintracks>\n      const header = await chaintracks.findHeaderForHeight(height)\n      if (header == null)\n        throw new WERR_INVALID_PARAMETER('hash', `valid height '${height}' on mined chain ${this.chain}`)\n      return toBinaryBaseBlockHeader(header)\n    }\n    return await this.invokeChaintracksWithRetry(method, 'find_header_for_height')\n  }\n\n  async getHeight(): Promise<number> {\n    const method = async (): Promise<number> => {\n      const chaintracks = this.options.chaintracks as NonNullable<typeof this.options.chaintracks>\n      return await chaintracks.currentHeight()\n    }\n    return await this.invokeChaintracksWithRetry(method, 'current_height')\n  }\n\n  async hashToHeader(hash: string): Promise<BlockHeader> {\n    const method = async (): Promise<BlockHeader | undefined> => {\n      const chaintracks = this.options.chaintracks as NonNullable<typeof this.options.chaintracks>\n      const header = await chaintracks.findHeaderForBlockHash(hash)\n      return header\n    }\n    let header = await this.invokeChaintracksWithRetry(method, 'find_header_for_hash')\n    header ??= await this.whatsonchain.getBlockHeaderByHash(hash)\n    if (header == null)\n      throw new WERR_INVALID_PARAMETER('hash', `valid blockhash '${hash}' on mined chain ${this.chain}`)\n    return header\n  }\n\n  async getMerklePath(txid: string, useNext?: boolean, logger?: WalletLoggerInterface): Promise<GetMerklePathResult> {\n    const services = this.getMerklePathServices\n    if (useNext === true) services.next()\n\n    const r0: GetMerklePathResult = { notes: [] }\n\n    logger?.group('services getMerklePath')\n    for (let tries = 0; tries < services.count; tries++) {\n      const stc = services.serviceToCall\n      try {\n        const r = await stc.service(txid, this)\n        if (r.notes != null) {\n          r0.notes = r0.notes ?? []\n          r0.notes.push(...r.notes)\n        }\n        r0.name ??= r.name\n        if (r.merklePath == null) {\n          logger?.log(`${stc.providerName} no merklePath`)\n        } else {\n          logger?.log(`${stc.providerName} has merklePath`)\n          // If we have a proof, call it done.\n          r0.merklePath = r.merklePath\n          r0.header = r.header\n          r0.name = r.name\n          r0.error = undefined\n          services.addServiceCallSuccess(stc)\n          break\n        }\n\n        if (r.error != null) services.addServiceCallError(stc, r.error)\n        else services.addServiceCallFailure(stc)\n\n        if (r.error != null && r0.error == null) {\n          // If we have an error and didn't before...\n          r0.error = r.error\n        }\n      } catch (error_: unknown) {\n        const e = WalletError.fromUnknown(error_)\n        services.addServiceCallError(stc, e)\n      }\n      services.next()\n    }\n    return r0\n  }\n\n  async updateFiatExchangeRates(\n    targetCurrencies: FiatCurrencyCode[],\n    updateMsecs?: number\n  ): Promise<FiatExchangeRates> {\n    updateMsecs ??= 1000 * 60 * 60 * 24\n    const freshnessDate = new Date(Date.now() - updateMsecs)\n\n    const stored = this.options.fiatExchangeRates\n    const storedRates = stored.rates ?? {}\n\n    const toFetch = this.collectStaleCurrencies(targetCurrencies, storedRates, stored, freshnessDate)\n\n    if (toFetch.length === 0) {\n      this.options.fiatExchangeRates = {\n        timestamp: stored.timestamp,\n        base: stored.base,\n        rates: storedRates,\n        rateTimestamps: stored.rateTimestamps\n      }\n      return this.options.fiatExchangeRates\n    }\n\n    const fetched = await this.fetchFiatRates(toFetch)\n\n    if (fetched == null) {\n      if (Object.keys(storedRates).length > 0) return stored\n      throw new WERR_INTERNAL()\n    }\n\n    this.options.fiatExchangeRates = this.mergeFiatRates(stored, storedRates, fetched)\n    return this.options.fiatExchangeRates\n  }\n\n  private collectStaleCurrencies(\n    targetCurrencies: FiatCurrencyCode[],\n    storedRates: Record<string, number>,\n    stored: FiatExchangeRates,\n    freshnessDate: Date\n  ): FiatCurrencyCode[] {\n    const toFetch: FiatCurrencyCode[] = []\n    for (const c of targetCurrencies) {\n      if (c === 'USD') {\n        if (typeof storedRates.USD !== 'number') storedRates.USD = 1\n        continue\n      }\n      const v = storedRates[c]\n      const ts = stored.rateTimestamps?.[c] ?? stored.timestamp\n      const fresh = typeof v === 'number' && ts instanceof Date && ts > freshnessDate\n      if (!fresh) toFetch.push(c)\n    }\n    return toFetch\n  }\n\n  private async fetchFiatRates(toFetch: FiatCurrencyCode[]): Promise<FiatExchangeRates | undefined> {\n    const services = this.updateFiatExchangeRateServices.clone()\n    for (let tries = 0; tries < services.count; tries++) {\n      const stc = services.serviceToCall\n      try {\n        const r = await stc.service(toFetch as string[], this.options)\n        if (toFetch.every(c => c === 'USD' || typeof r.rates?.[c] === 'number')) {\n          services.addServiceCallSuccess(stc)\n          return r\n        }\n        services.addServiceCallFailure(stc)\n      } catch (error_: unknown) {\n        services.addServiceCallError(stc, WalletError.fromUnknown(error_))\n      }\n      services.next()\n    }\n    return undefined\n  }\n\n  private mergeFiatRates(\n    stored: FiatExchangeRates,\n    storedRates: Record<string, number>,\n    fetched: FiatExchangeRates\n  ): FiatExchangeRates {\n    const nextRates: Record<string, number> = { ...storedRates }\n    const nextTimestamps: Record<string, Date> = { ...stored.rateTimestamps }\n\n    for (const c of fetched.rates != null ? Object.keys(fetched.rates) : []) {\n      const v = fetched.rates?.[c]\n      if (typeof v === 'number') {\n        nextRates[c] = v\n        nextTimestamps[c] = fetched.timestamp\n      }\n    }\n\n    const storedMs =\n      stored.timestamp instanceof Date ? stored.timestamp.getTime() : new Date(stored.timestamp).getTime()\n    const nextTimestamp = new Date(Math.max(storedMs, fetched.timestamp.getTime()))\n\n    return { timestamp: nextTimestamp, base: stored.base, rates: nextRates, rateTimestamps: nextTimestamps }\n  }\n\n  async nLockTimeIsFinal(tx: string | number[] | BsvTransaction | number): Promise<boolean> {\n    const MAXINT = 0xffffffff\n    const BLOCK_LIMIT = 500000000\n\n    let nLockTime: number\n\n    if (typeof tx === 'number') nLockTime = tx\n    else {\n      if (typeof tx === 'string') {\n        tx = BsvTransaction.fromHex(tx)\n      } else if (Array.isArray(tx)) {\n        tx = BsvTransaction.fromBinary(tx)\n      }\n\n      if (tx instanceof BsvTransaction) {\n        if (tx.inputs.every(i => i.sequence === MAXINT)) {\n          return true\n        }\n        nLockTime = tx.lockTime\n      } else {\n        throw new WERR_INTERNAL('Should be either @bsv/sdk Transaction or babbage-bsv Transaction')\n      }\n    }\n\n    if (nLockTime >= BLOCK_LIMIT) {\n      const limit = Math.floor(Date.now() / 1000)\n      return nLockTime < limit\n    }\n\n    const height = await this.getHeight()\n    return nLockTime < height\n  }\n\n  async getBeefForTxid(txid: string): Promise<Beef> {\n    const beef = await getBeefForTxid(this, txid)\n    return beef\n  }\n}\n\nexport function validateScriptHash(output: string, outputFormat?: GetUtxoStatusOutputFormat): string {\n  let b = asArray(output)\n  if (outputFormat == null) {\n    if (b.length === 32) outputFormat = 'hashLE'\n    else outputFormat = 'script'\n  }\n  switch (outputFormat) {\n    case 'hashBE':\n      break\n    case 'hashLE':\n      b = b.reverse()\n      break\n    case 'script':\n      b = sha256Hash(b).reverse()\n      break\n    default:\n      throw new WERR_INVALID_PARAMETER('outputFormat', `not be ${String(outputFormat)}`)\n  }\n  return asString(b)\n}\n\n/**\n * Serializes a block header as an 80 byte array.\n * The exact serialized format is defined in the Bitcoin White Paper\n * such that computing a double sha256 hash of the array computes\n * the block hash for the header.\n * @returns 80 byte array\n * @publicbody\n */\nexport function toBinaryBaseBlockHeader(header: BaseBlockHeader): number[] {\n  const writer = new Utils.Writer()\n  writer.writeUInt32LE(header.version)\n  writer.writeReverse(asArray(header.previousHash))\n  writer.writeReverse(asArray(header.merkleRoot))\n  writer.writeUInt32LE(header.time)\n  writer.writeUInt32LE(header.bits)\n  writer.writeUInt32LE(header.nonce)\n  const r = writer.toArray()\n  return r\n}\n","import { Validation } from '@bsv/sdk'\nimport { WERR_BAD_REQUEST, WERR_INTERNAL } from '../../sdk/WERR_errors'\nimport { WalletError } from '../../sdk/WalletError'\nimport {\n  GetScriptHashHistoryResult,\n  GetUtxoStatusResult,\n  PostTxResultForTxid\n} from '../../sdk/WalletServices.interfaces'\nimport { ReqHistoryNote } from '../../sdk/types'\n\n// ---------------------------------------------------------------------------\n// postRawTx helpers\n// ---------------------------------------------------------------------------\n\n/** Handle a double-spend / missing-inputs error response from WoC */\nfunction handleDoubleSpendError (\n  r: PostTxResultForTxid,\n  nne: () => Record<string, unknown>,\n  what: string\n): void {\n  r.doubleSpend = true\n  r.competingTxs = undefined\n  r.notes!.push({ ...nne(), what })\n}\n\n/** Handle any other non-OK, non-recognised error response from WoC */\nfunction handleGenericPostError (\n  r: PostTxResultForTxid,\n  nne: () => Record<string, unknown>,\n  response: { data?: unknown; statusText?: unknown; status?: unknown }\n): void {\n  const n: ReqHistoryNote = { ...nne(), what: 'postRawTxError' }\n  if (typeof response.data === 'string') {\n    n.data = response.data.slice(0, 128)\n    r.data = response.data\n  } else {\n    r.data = ''\n  }\n  if (typeof response.statusText === 'string') {\n    n.statusText = response.statusText.slice(0, 128)\n    r.data += `,${response.statusText}`\n  }\n  if (typeof response.status === 'string') {\n    n.status = response.status.slice(0, 128)\n    r.data += `,${response.status}`\n  }\n  if (typeof response.status === 'number') {\n    n.status = response.status\n    r.data += `,${response.status}`\n  }\n  r.notes!.push(n)\n}\n\n/**\n * Classify an error-status WoC response and mutate `r` accordingly.\n */\nexport function handlePostRawTxErrorResponse (\n  r: PostTxResultForTxid,\n  nne: () => Record<string, unknown>,\n  response: { data?: unknown; statusText?: unknown; status?: unknown; ok?: boolean }\n): void {\n  r.status = 'error'\n  const data = response.data as string | undefined\n  if (data === 'unexpected response code 500: 258: txn-mempool-conflict') {\n    handleDoubleSpendError(r, nne, 'postRawTxErrorMempoolConflict')\n  } else if (data === 'unexpected response code 500: Missing inputs') {\n    handleDoubleSpendError(r, nne, 'postRawTxErrorMissingInputs')\n  } else {\n    handleGenericPostError(r, nne, response)\n  }\n}\n\n// ---------------------------------------------------------------------------\n// getUtxoStatus helpers\n// ---------------------------------------------------------------------------\n\n/** Populate UTXO details from a WoC result array */\nexport function populateUtxoDetails (\n  r: GetUtxoStatusResult,\n  result: Array<{ tx_hash: string; value: number; height: number; tx_pos: number }>,\n  outpoint?: string\n): void {\n  for (const s of result) {\n    r.details.push({\n      txid: s.tx_hash,\n      satoshis: s.value,\n      height: s.height,\n      index: s.tx_pos\n    })\n  }\n  if (outpoint) {\n    const { txid, vout } = Validation.parseWalletOutpoint(outpoint)\n    r.isUtxo = r.details.some(d => d.txid === txid && d.index === vout)\n  } else {\n    r.isUtxo = r.details.length > 0\n  }\n}\n\n/**\n * Decide whether the ECONNRESET error is retryable and, if not, set `r.error`.\n * Returns true when the caller should retry, false when it should return.\n */\nexport function handleUtxoConnReset (\n  r: GetUtxoStatusResult,\n  error_: unknown,\n  url: string,\n  retry: number,\n  maxRetry: number\n): boolean {\n  const e = WalletError.fromUnknown(error_)\n  if (e.code === 'ECONNRESET' && retry < maxRetry) return true\n  r.error = new WERR_INTERNAL(\n    `service failure: ${url}, error: ${JSON.stringify(e)}`\n  )\n  return false\n}\n\n// ---------------------------------------------------------------------------\n// getScriptHashHistory helpers (shared between confirmed + unconfirmed)\n// ---------------------------------------------------------------------------\n\nexport interface ScriptHashHistoryResponse {\n  ok: boolean\n  status: number\n  statusText: string\n  data?: {\n    result: Array<{ tx_hash: string; height?: number }>\n    error?: string\n  }\n}\n\n/**\n * Inspect a WoC script-hash history response and update `r` in-place.\n *\n * Returns:\n *  - `'continue'`  — rate-limited, caller should retry\n *  - `'return'`    — done, caller should return `r`\n *  - `'ok'`        — response was successful, continue parsing\n */\nexport function handleScriptHashHistoryResponse (\n  r: GetScriptHashHistoryResult,\n  response: ScriptHashHistoryResponse,\n  methodName: string,\n  retry: number\n): 'continue' | 'return' | 'ok' {\n  if (response.statusText === 'Too Many Requests' && retry < 2) {\n    return 'continue'\n  }\n\n  if (!response.ok && response.status === 404) {\n    r.status = 'success'\n    return 'return'\n  }\n\n  if (!response.data || !response.ok || response.status !== 200) {\n    r.error = new WERR_BAD_REQUEST(\n      `WoC ${methodName} response ${response.ok} ${response.status} ${response.statusText}`\n    )\n    return 'return'\n  }\n\n  if (response.data.error) {\n    r.error = new WERR_BAD_REQUEST(`WoC ${methodName} error ${response.data.error}`)\n    return 'return'\n  }\n\n  return 'ok'\n}\n\n/**\n * Decide whether a caught error is retryable for script-hash history calls.\n * If not retryable, sets `r.error` and returns false.\n */\nexport function handleScriptHashHistoryCatch (\n  r: GetScriptHashHistoryResult,\n  error_: unknown,\n  url: string,\n  methodName: string,\n  retry: number,\n  maxRetry: number\n): boolean {\n  const e = WalletError.fromUnknown(error_)\n  if (e.code === 'ECONNRESET' && retry < maxRetry) return true\n  r.error = new WERR_INTERNAL(\n    `WoC ${methodName} service failure: ${url}, error: ${JSON.stringify(e)}`\n  )\n  return false\n}\n\n// ---------------------------------------------------------------------------\n// getMerklePath helpers\n// ---------------------------------------------------------------------------\n\nexport type MerklePathNoteWhat =\n  | 'getMerklePathRetry'\n  | 'getMerklePathNotFound'\n  | 'getMerklePathBadStatus'\n  | 'getMerklePathNoData'\n  | 'getMerklePathSuccess'\n  | 'getMerklePathNoHeader'\n  | 'getMerklePathError'\n  | 'getMerklePathInternal'\n\nexport interface MerklePathNote {\n  what: MerklePathNoteWhat\n  name: string\n  status?: number\n  statusText?: string\n  target?: string\n  code?: string\n  description?: string\n  [key: string]: boolean | string | number | undefined\n}\n\nexport function makeMerklePathNote (\n  what: MerklePathNoteWhat,\n  name: string,\n  extra: Partial<MerklePathNote> = {}\n): MerklePathNote {\n  return { what, name, ...extra }\n}\n\n/**\n * Classify a non-OK status response for getMerklePath.\n *\n * Returns `'retry'` when the request was rate-limited and the caller should retry,\n * `'notFound'` for 404, `'badStatus'` for other non-200 codes.\n */\nexport function classifyMerklePathResponse (\n  status: number,\n  statusText: string,\n  retry: number\n): 'retry' | 'notFound' | 'badStatus' | 'ok' {\n  if (statusText === 'Too Many Requests' && retry < 2) return 'retry'\n  if (status === 404 && statusText === 'Not Found') return 'notFound'\n  return 'badStatus'\n}\n","import { Beef, HexString, HttpClientRequestOptions, HttpClientResponse, Utils, WhatsOnChainConfig } from '@bsv/sdk'\nimport { convertProofToMerklePath } from '../../utility/tscProofToMerklePath'\nimport SdkWhatsOnChain from './SdkWhatsOnChain'\nimport { Chain } from '../../sdk/types'\nimport {\n  BlockHeader,\n  BsvExchangeRate,\n  GetMerklePathResult,\n  GetRawTxResult,\n  GetScriptHashHistoryResult,\n  GetStatusForTxidsResult,\n  GetUtxoStatusOutputFormat,\n  GetUtxoStatusResult,\n  PostBeefResult,\n  PostTxResultForTxid,\n  WalletServices\n} from '../../sdk/WalletServices.interfaces'\nimport { WERR_INTERNAL, WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../sdk/WERR_errors'\nimport { WalletError } from '../../sdk/WalletError'\nimport { doubleSha256BE, wait } from '../../utility/utilityHelpers'\nimport { asArray, asString } from '../../utility/utilityHelpers.noBuffer'\nimport { Services, validateScriptHash } from '../Services'\nimport {\n  classifyMerklePathResponse,\n  handlePostRawTxErrorResponse,\n  handleScriptHashHistoryCatch,\n  handleScriptHashHistoryResponse,\n  handleUtxoConnReset,\n  makeMerklePathNote,\n  populateUtxoDetails,\n  ScriptHashHistoryResponse\n} from './whatsOnChainHelpers'\n\nexport interface WalletToolboxWhatsOnChainConfig extends WhatsOnChainConfig {\n  /** Optional request-start gate used by ChainTracks' shared public-rate scheduler. */\n  requestGate?: () => Promise<void>\n}\n\nexport class WhatsOnChainNoServices extends SdkWhatsOnChain {\n  private readonly requestGate?: () => Promise<void>\n\n  constructor(chain: Chain = 'main', config: WalletToolboxWhatsOnChainConfig = {}) {\n    if (chain === 'mock') throw new Error(\"WhatsOnChain does not support 'mock' chain. Use MockServices directly.\")\n    super(chain, config)\n    this.requestGate = config.requestGate\n  }\n\n  private async requestWithAnonymousAuthFallback<T>(\n    url: string,\n    requestOptions: HttpClientRequestOptions\n  ): Promise<HttpClientResponse<T>> {\n    await this.requestGate?.()\n    const response = await this.httpClient.request<T>(url, requestOptions)\n    if ((response.status !== 401 && response.status !== 403) || this.apiKey.trim() === '') {\n      return response\n    }\n\n    // Treat the anonymous retry as another public request start so a stale\n    // key cannot create a burst above the documented keyless allowance.\n    if (this.requestGate != null) await this.requestGate()\n    else await wait(350)\n    return await this.httpClient.request<T>(url, {\n      method: 'GET',\n      headers: { Accept: 'application/json' }\n    })\n  }\n\n  /**\n   * POST\n   * https://api.whatsonchain.com/v1/bsv/main/txs/status\n   * Content-Type: application/json\n   * data: \"{\\\"txids\\\":[\\\"6815f8014db74eab8b7f75925c68929597f1d97efa970109d990824c25e5e62b\\\"]}\"\n   *\n   * result for a mined txid:\n   *     [{\n   *        \"txid\":\"294cd1ebd5689fdee03509f92c32184c0f52f037d4046af250229b97e0c8f1aa\",\n   *        \"blockhash\":\"000000000000000004b5ce6670f2ff27354a1e87d0a01bf61f3307f4ccd358b5\",\n   *        \"blockheight\":612251,\n   *        \"blocktime\":1575841517,\n   *        \"confirmations\":278272\n   *      }]\n   *\n   * result for a valid recent txid:\n   *     [{\"txid\":\"6815f8014db74eab8b7f75925c68929597f1d97efa970109d990824c25e5e62b\"}]\n   *\n   * result for an unknown txid:\n   *     [{\"txid\":\"6815f8014db74eab8b7f75925c68929597f1d97efa970109d990824c25e5e62c\",\"error\":\"unknown\"}]\n   */\n  async getStatusForTxids(txids: string[]): Promise<GetStatusForTxidsResult> {\n    const r: GetStatusForTxidsResult = {\n      name: 'WoC',\n      status: 'error',\n      error: undefined,\n      results: []\n    }\n\n    const requestOptions = {\n      method: 'POST',\n      headers: this.getHttpHeaders(),\n      data: { txids }\n    }\n\n    const url = `${this.URL}/txs/status`\n\n    try {\n      const response = await this.httpClient.request<WhatsOnChainTxsStatusData[]>(url, requestOptions)\n\n      if (!response.data || !response.ok || response.status !== 200) {\n        throw new WERR_INVALID_OPERATION('Unable to get status for txids at this timei.')\n      }\n\n      const data = response.data\n      for (const txid of txids) {\n        const d = data.find(d => d.txid === txid)\n        if (d == null || d.error === 'unknown') r.results.push({ txid, status: 'unknown', depth: undefined })\n        else if (d.error !== undefined) {\n          console.log(`WhatsOnChain getStatusForTxids unexpected error ${d.error} ${txid}`)\n          r.results.push({ txid, status: 'unknown', depth: undefined })\n        } else if (d.confirmations === undefined) r.results.push({ txid, status: 'known', depth: 0 })\n        else r.results.push({ txid, status: 'mined', depth: d.confirmations })\n      }\n      r.status = 'success'\n    } catch (error_: unknown) {\n      const e = WalletError.fromUnknown(error_)\n      r.error = e\n    }\n\n    return r\n  }\n\n  /**\n   * 2025-02-16 throwing internal server error 500.\n   * @param txid\n   * @returns\n   */\n  async getTxPropagation(txid: string): Promise<number> {\n    const requestOptions = {\n      method: 'GET',\n      headers: this.getHttpHeaders()\n    }\n\n    const response = await this.httpClient.request<string>(`${this.URL}/tx/hash/${txid}/propagation`, requestOptions)\n\n    // response.statusText is often, but not always 'OK' on success...\n    if (!response.data || !response.ok || response.status !== 200) {\n      throw new WERR_INVALID_PARAMETER('txid', `valid transaction. '${txid}' response ${response.statusText}`)\n    }\n\n    return 0\n  }\n\n  /**\n   * May return undefined for unmined transactions that are in the mempool.\n   * @param txid\n   * @returns raw transaction as hex string or undefined if txid not found in mined block.\n   */\n  async getRawTx(txid: string): Promise<string | undefined> {\n    const headers = this.getHttpHeaders()\n    headers['Cache-Control'] = 'no-cache'\n\n    const requestOptions = {\n      method: 'GET',\n      headers\n    }\n\n    const url = `${this.URL}/tx/${txid}/hex`\n\n    for (let retry = 0; retry < 2; retry++) {\n      const response = await this.httpClient.request<string>(url, requestOptions)\n      if (response.statusText === 'Too Many Requests' && retry < 2) {\n        await wait(2000)\n        continue\n      }\n\n      if (response.status === 404 && response.statusText === 'Not Found') return undefined\n\n      // response.statusText is often, but not always 'OK' on success...\n      if (!response.data || !response.ok || response.status !== 200) {\n        throw new WERR_INVALID_PARAMETER('txid', `valid transaction. '${txid}' response ${response.statusText}`)\n      }\n\n      return response.data\n    }\n    throw new WERR_INTERNAL()\n  }\n\n  async getRawTxResult(txid: string): Promise<GetRawTxResult> {\n    const r: GetRawTxResult = { name: 'WoC', txid: asString(txid) }\n\n    try {\n      const rawTxHex = await this.getRawTx(txid)\n      if (rawTxHex) r.rawTx = asArray(rawTxHex)\n    } catch (err: unknown) {\n      r.error = WalletError.fromUnknown(err)\n    }\n\n    return r\n  }\n\n  /**\n   * WhatsOnChain does not natively support a postBeef end-point aware of multiple txids of interest in the Beef.\n   *\n   * Send rawTx in `txids` order from beef.\n   *\n   * @param beef\n   * @param txids\n   * @returns\n   */\n  async postBeef(beef: Beef, txids: string[]): Promise<PostBeefResult> {\n    const r: PostBeefResult = {\n      name: 'WoC',\n      status: 'success',\n      txidResults: [],\n      notes: []\n    }\n\n    let delay = false\n\n    const nn = () => ({ name: 'WoCpostBeef', when: new Date().toISOString() })\n    const nne = () => ({ ...nn(), beef: beef.toHex(), txids: txids.join(',') })\n\n    for (const txid of txids) {\n      const rawTx = Utils.toHex(beef.findTxid(txid)!.rawTx!)\n\n      if (delay) {\n        // For multiple txids, give WoC time to propagate each one.\n        await wait(3000)\n      }\n      delay = true\n\n      const tr = await this.postRawTx(rawTx)\n      if (txid !== tr.txid) {\n        tr.notes!.push({ ...nne(), what: 'postRawTxTxidChanged', txid, trTxid: tr.txid })\n      }\n\n      r.txidResults.push(tr)\n      if (r.status === 'success' && tr.status !== 'success') r.status = 'error'\n    }\n\n    if (r.status === 'success') {\n      r.notes!.push({ ...nn(), what: 'postBeefSuccess' })\n    } else {\n      r.notes!.push({ ...nne(), what: 'postBeefError' })\n    }\n\n    return r\n  }\n\n  /**\n   * @param rawTx raw transaction to broadcast as hex string\n   * @returns txid returned by transaction processor of transaction broadcast\n   */\n  async postRawTx(rawTx: HexString): Promise<PostTxResultForTxid> {\n    const txid = Utils.toHex(doubleSha256BE(Utils.toArray(rawTx, 'hex')))\n\n    const r: PostTxResultForTxid = {\n      txid,\n      status: 'success',\n      notes: []\n    }\n\n    const headers = this.getHttpHeaders()\n    headers['Content-Type'] = 'application/json'\n    headers.Accept = 'text/plain'\n\n    const requestOptions = {\n      method: 'POST',\n      headers,\n      data: { txhex: rawTx }\n    }\n\n    const url = `${this.URL}/tx/raw`\n    const nn = () => ({ name: 'WoCpostRawTx', when: new Date().toISOString() })\n    const nne = () => ({ ...nn(), rawTx, txid, url })\n\n    const retryLimit = 5\n    for (let retry = 0; retry < retryLimit; retry++) {\n      try {\n        const response = await this.httpClient.request<string>(url, requestOptions)\n        if (response.statusText === 'Too Many Requests' && retry < 2) {\n          r.notes!.push({ ...nn(), what: 'postRawTxRateLimit' })\n          await wait(2000)\n          continue\n        }\n        if (response.ok) {\n          r.notes!.push({ ...nn(), what: 'postRawTxSuccess' })\n        } else if (response.data === 'unexpected response code 500: Transaction already in the mempool') {\n          r.notes!.push({ ...nne(), what: 'postRawTxSuccessAlreadyInMempool' })\n        } else {\n          handlePostRawTxErrorResponse(r, nne, response)\n        }\n      } catch (error_: unknown) {\n        r.status = 'error'\n        const e = WalletError.fromUnknown(error_)\n        r.notes!.push({\n          ...nne(),\n          what: 'postRawTxCatch',\n          code: e.code,\n          description: e.description\n        })\n        r.serviceError = true\n        r.data = `${e.code} ${e.description}`\n      }\n      return r\n    }\n    r.status = 'error'\n    r.serviceError = true\n    r.notes!.push({\n      ...nne(),\n      what: 'postRawTxRetryLimit',\n      retryLimit\n    })\n    return r\n  }\n\n  async updateBsvExchangeRate(rate?: BsvExchangeRate, updateMsecs?: number): Promise<BsvExchangeRate> {\n    if (rate != null) {\n      // Check if the rate we know is stale enough to update.\n      updateMsecs ||= 1000 * 60 * 15\n      if (new Date(Date.now() - updateMsecs) < rate.timestamp) return rate\n    }\n\n    const requestOptions = {\n      method: 'GET',\n      headers: this.getHttpHeaders()\n    }\n\n    for (let retry = 0; retry < 2; retry++) {\n      const response = await this.httpClient.request<{\n        rate: number\n        time: number\n        currency: string\n      }>(`${this.URL}/exchangerate`, requestOptions)\n      if (response.statusText === 'Too Many Requests' && retry < 2) {\n        await wait(2000)\n        continue\n      }\n\n      // response.statusText is often, but not always 'OK' on success...\n      if (!response.data || !response.ok || response.status !== 200) {\n        throw new WERR_INVALID_OPERATION(`WoC exchangerate response ${response.statusText}`)\n      }\n\n      const wocrate = response.data\n      if (wocrate.currency !== 'USD') wocrate.rate = Number.NaN\n\n      const newRate: BsvExchangeRate = {\n        timestamp: new Date(),\n        base: 'USD',\n        rate: wocrate.rate\n      }\n\n      return newRate\n    }\n    throw new WERR_INTERNAL()\n  }\n\n  async getUtxoStatus(\n    output: string,\n    outputFormat?: GetUtxoStatusOutputFormat,\n    outpoint?: string\n  ): Promise<GetUtxoStatusResult> {\n    const r: GetUtxoStatusResult = { name: 'WoC', status: 'error', error: new WERR_INTERNAL(), details: [] }\n    const scriptHash = validateScriptHash(output, outputFormat)\n    const url = `${this.URL}/script/${scriptHash}/unspent/all`\n    const requestOptions = { method: 'GET', headers: this.getHttpHeaders() }\n\n    for (let retry = 0; retry <= 2; retry++) {\n      try {\n        const response = await this.httpClient.request<WhatsOnChainUtxoStatus>(url, requestOptions)\n        if (response.statusText === 'Too Many Requests' && retry < 2) {\n          await wait(2000)\n          continue\n        }\n        this.applyUtxoStatusResponse(r, response, scriptHash, outpoint)\n        return r\n      } catch (error_: unknown) {\n        const shouldRetry = handleUtxoConnReset(r, error_, url, retry, 2)\n        if (!shouldRetry) return r\n      }\n    }\n    return r\n  }\n\n  private applyUtxoStatusResponse(\n    r: GetUtxoStatusResult,\n    response: { data?: WhatsOnChainUtxoStatus; ok: boolean; status: number; statusText: string },\n    scriptHash: string,\n    outpoint?: string\n  ): void {\n    if (!response.data || !response.ok || response.status !== 200) {\n      throw new WERR_INVALID_OPERATION(`WoC getUtxoStatus response ${response.statusText}`)\n    }\n    const data = response.data\n    if (data.script !== scriptHash || !Array.isArray(data.result)) throw new WERR_INTERNAL('data. is not an array')\n    r.status = 'success'\n    r.error = undefined\n    if (data.result.length === 0) r.isUtxo = false\n    else populateUtxoDetails(r, data.result, outpoint)\n  }\n\n  async getScriptHashConfirmedHistory(hash: string): Promise<GetScriptHashHistoryResult> {\n    const r: GetScriptHashHistoryResult = {\n      name: 'WoC',\n      status: 'error',\n      error: undefined,\n      history: []\n    }\n\n    // reverse hash from LE to BE for Woc\n    hash = Utils.toHex(Utils.toArray(hash, 'hex').reverse())\n\n    const url = `${this.URL}/script/${hash}/confirmed/history`\n    const methodName = 'getScriptHashConfirmedHistory'\n\n    for (let retry = 0; retry <= 2; retry++) {\n      try {\n        const requestOptions = { method: 'GET', headers: this.getHttpHeaders() }\n        const response = await this.httpClient.request<WhatsOnChainScriptHashHistoryData>(url, requestOptions)\n\n        const action = handleScriptHashHistoryResponse(r, response as ScriptHashHistoryResponse, methodName, retry)\n        if (action === 'continue') {\n          await wait(2000)\n          continue\n        }\n        if (action === 'return') return r\n\n        r.history = response.data!.result.map((d: WhatsOnChainScriptHashHistory) => ({\n          txid: d.tx_hash,\n          height: d.height\n        }))\n        r.status = 'success'\n        return r\n      } catch (error_: unknown) {\n        const shouldRetry = handleScriptHashHistoryCatch(r, error_, url, methodName, retry, 2)\n        if (!shouldRetry) return r\n      }\n    }\n\n    return r\n  }\n\n  async getScriptHashUnconfirmedHistory(hash: string): Promise<GetScriptHashHistoryResult> {\n    const r: GetScriptHashHistoryResult = {\n      name: 'WoC',\n      status: 'error',\n      error: undefined,\n      history: []\n    }\n\n    // reverse hash from LE to BE for Woc\n    hash = Utils.toHex(Utils.toArray(hash, 'hex').reverse())\n\n    const url = `${this.URL}/script/${hash}/unconfirmed/history`\n    const methodName = 'getScriptHashUnconfirmedHistory'\n\n    for (let retry = 0; ; retry++) {\n      try {\n        const requestOptions = { method: 'GET', headers: this.getHttpHeaders() }\n        const response = await this.httpClient.request<WhatsOnChainScriptHashHistoryData>(url, requestOptions)\n\n        const action = handleScriptHashHistoryResponse(r, response as ScriptHashHistoryResponse, methodName, retry)\n        if (action === 'continue') {\n          await wait(2000)\n          continue\n        }\n        if (action === 'return') return r\n\n        r.history = response.data!.result.map((d: WhatsOnChainScriptHashHistory) => ({\n          txid: d.tx_hash,\n          height: d.height\n        }))\n        r.status = 'success'\n        return r\n      } catch (error_: unknown) {\n        // Note: original used retry > 2 (not >= 2) for the unconfirmed variant\n        const shouldRetry = handleScriptHashHistoryCatch(r, error_, url, methodName, retry, 3)\n        if (!shouldRetry) return r\n      }\n    }\n  }\n\n  async getScriptHashHistory(hash: string): Promise<GetScriptHashHistoryResult> {\n    const r1 = await this.getScriptHashConfirmedHistory(hash)\n    if (r1.error || r1.status !== 'success') return r1\n    const r2 = await this.getScriptHashUnconfirmedHistory(hash)\n    if (r2.error || r2.status !== 'success') return r2\n    r1.history = r1.history.concat(r2.history)\n    return r1\n  }\n\n  /**\n    {\n      \"hash\": \"000000000000000004a288072ebb35e37233f419918f9783d499979cb6ac33eb\",\n      \"confirmations\": 328433,\n      \"size\": 14421,\n      \"height\": 575045,\n      \"version\": 536928256,\n      \"versionHex\": \"2000e000\",\n      \"merkleroot\": \"4ebcba09addd720991d03473f39dce4b9a72cc164e505cd446687a54df9b1585\",\n      \"time\": 1553416668,\n      \"mediantime\": 1553414858,\n      \"nonce\": 87914848,\n      \"bits\": \"180997ee\",\n      \"difficulty\": 114608607557.4425,\n      \"chainwork\": \"000000000000000000000000000000000000000000ddf5d385546872bab7dc01\",\n      \"previousblockhash\": \"00000000000000000988156c7075dc9147a5b62922f1310862e8b9000d46dd9b\",\n      \"nextblockhash\": \"00000000000000000112b36a37c10235fa0c991f680bc5482ba9692e0ae697db\",\n      \"nTx\": 0,\n      \"num_tx\": 5\n    }\n   */\n  async getBlockHeaderByHash(hash: string): Promise<BlockHeader | undefined> {\n    const headers = this.getHttpHeaders()\n    const requestOptions = {\n      method: 'GET',\n      headers\n    }\n\n    const url = `${this.URL}/block/${hash}/header`\n\n    for (let retry = 0; retry < 2; retry++) {\n      const response = await this.requestWithAnonymousAuthFallback<WocHeader>(url, requestOptions)\n      if (response.statusText === 'Too Many Requests' && retry < 2) {\n        await wait(2000)\n        continue\n      }\n\n      if (response.status === 404 && response.statusText === 'Not Found') return undefined\n\n      // response.statusText is often, but not always 'OK' on success...\n      if (!response.data || !response.ok || response.status !== 200) {\n        throw new WERR_INVALID_PARAMETER('hash', `valid block hash. '${hash}' response ${response.statusText}`)\n      }\n\n      const header = convertWocToBlockHeaderHex(response.data)\n\n      return header\n    }\n    throw new WERR_INTERNAL()\n  }\n\n  async getChainInfo(): Promise<WocChainInfo> {\n    const headers = this.getHttpHeaders()\n    const requestOptions = {\n      method: 'GET',\n      headers\n    }\n\n    const url = `${this.URL}/chain/info`\n\n    for (let retry = 0; retry < 2; retry++) {\n      const response = await this.requestWithAnonymousAuthFallback<WocChainInfo>(url, requestOptions)\n      if (response.statusText === 'Too Many Requests' && retry < 2) {\n        await wait(2000)\n        continue\n      }\n\n      // response.statusText is often, but not always 'OK' on success...\n      if (!response.data || !response.ok || response.status !== 200) {\n        throw new WERR_INVALID_PARAMETER('hash', `valid block hash. '${url}' response ${response.statusText}`)\n      }\n\n      return response.data\n    }\n    throw new WERR_INTERNAL()\n  }\n}\n\n/**\n *\n */\nexport class WhatsOnChain extends WhatsOnChainNoServices {\n  services: Services\n\n  constructor(chain: Chain = 'main', config: WalletToolboxWhatsOnChainConfig = {}, services?: Services) {\n    super(chain, config)\n    this.services = services || new Services(chain)\n  }\n\n  /**\n   * @param txid\n   * @returns\n   */\n  async getMerklePath(txid: string, services: WalletServices): Promise<GetMerklePathResult> {\n    const r: GetMerklePathResult = { name: 'WoCTsc', notes: [] }\n    const name = r.name!\n    const requestOptions = { method: 'GET', headers: this.getHttpHeaders() }\n    const url = `${this.URL}/tx/${txid}/proof/tsc`\n\n    for (let retry = 0; retry < 2; retry++) {\n      try {\n        const response = await this.httpClient.request<WhatsOnChainTscProof | WhatsOnChainTscProof[]>(\n          url,\n          requestOptions\n        )\n        const classification = classifyMerklePathResponse(response.status, response.statusText, retry)\n\n        if (classification === 'retry') {\n          r.notes!.push(\n            makeMerklePathNote('getMerklePathRetry', name, { status: response.status, statusText: response.statusText })\n          )\n          await wait(2000)\n          continue\n        }\n        if (classification === 'notFound') {\n          r.notes!.push(\n            makeMerklePathNote('getMerklePathNotFound', name, {\n              status: response.status,\n              statusText: response.statusText\n            })\n          )\n          return r\n        }\n        await this.applyMerklePathResponse(r, name, txid, response, services)\n      } catch (error_: unknown) {\n        const e = WalletError.fromUnknown(error_)\n        r.notes!.push(makeMerklePathNote('getMerklePathError', name, { code: e.code, description: e.description }))\n        r.error = e\n      }\n      return r\n    }\n    r.notes!.push(makeMerklePathNote('getMerklePathInternal', name))\n    throw new WERR_INTERNAL()\n  }\n\n  private async applyMerklePathResponse(\n    r: GetMerklePathResult,\n    name: string,\n    txid: string,\n    response: { data?: WhatsOnChainTscProof | WhatsOnChainTscProof[]; ok: boolean; status: number; statusText: string },\n    services: WalletServices\n  ): Promise<void> {\n    if (!response.ok || response.status !== 200) {\n      r.notes!.push(\n        makeMerklePathNote('getMerklePathBadStatus', name, { status: response.status, statusText: response.statusText })\n      )\n      throw new WERR_INVALID_PARAMETER('txid', `valid transaction. '${txid}' response ${response.statusText}`)\n    }\n    if (!response.data) {\n      // Unmined, proof not yet available.\n      r.notes!.push(\n        makeMerklePathNote('getMerklePathNoData', name, { status: response.status, statusText: response.statusText })\n      )\n      return\n    }\n    if (!Array.isArray(response.data)) response.data = [response.data]\n    if (response.data.length !== 1) return\n\n    const p = response.data[0]\n    const header = await services.hashToHeader(p.target)\n    if (header) {\n      r.merklePath = convertProofToMerklePath(txid, { index: p.index, nodes: p.nodes, height: header.height })\n      r.header = header\n      r.notes!.push(\n        makeMerklePathNote('getMerklePathSuccess', name, { status: response.status, statusText: response.statusText })\n      )\n    } else {\n      r.notes!.push(\n        makeMerklePathNote('getMerklePathNoHeader', name, {\n          target: p.target,\n          status: response.status,\n          statusText: response.statusText\n        })\n      )\n      throw new WERR_INVALID_PARAMETER('blockhash', 'a valid on-chain block hash')\n    }\n  }\n}\n\ninterface WhatsOnChainTscProof {\n  index: number\n  nodes: string[]\n  target: string\n  txOrId: string\n}\n\ninterface WhatsOnChainScriptHashHistory {\n  tx_hash: string\n  height?: number\n}\n\ninterface WhatsOnChainScriptHashHistoryData {\n  script: string\n  result: WhatsOnChainScriptHashHistory[]\n  error?: string\n  nextPageToken?: string\n}\n\ninterface WhatsOnChainTxsStatusData {\n  txid: string\n  blockhash?: string\n  blockheight?: number\n  blocktime?: number\n  confirmations?: number\n  /**\n   * 'unknown' if txid isn't known\n   */\n  error?: string\n}\n\n/**\n * GET https://api.whatsonchain.com/v1/bsv/<network>/script/<scriptHash>/unspent/all\n *\n * Response\n{\n  \"error\":\"\",\n  \"status\":200,\n  \"statusText\":\"OK\",\n  \"ok\":true,\n  \"data\":{\n    \"script\":\"d3ef8eeb691e7405caca142bfcd6f499b142884d7883e6701a0ee76047b4af32\",\n    \"result\":[\n      {\n        \"height\":893652,\n        \"tx_pos\":11,\n        \"tx_hash\":\"2178a1e93d46edda946d9069f9b157ddfacb451fee0278e657941f09bfdb5d8f\",\n        \"value\":1005,\n        \"isSpentInMempoolTx\":false,\n        \"status\":\"confirmed\"\n      }\n    ]\n  }\n}\n *\n */\ninterface WhatsOnChainUtxoStatus {\n  script: string\n  result: Array<{\n    value: number\n    height: number\n    tx_pos: number\n    tx_hash: string\n    isSpentInMempoolTx: boolean\n    status: string // 'confirmed'\n  }>\n}\n\nexport interface WocChainInfo {\n  chain: string // \"main\",\n  blocks: number // 635302,\n  headers: number // 635299,\n  bestblockhash: string // \"000000000000000002a40d7410a6c08109521c14f4cf354e7b352b4eab8aa4ea\",\n  difficulty: number // 287310033717.7086,\n  mediantime: number // 1589703256,\n  verificationprogress: number // 0.9999754124031851,\n  pruned: boolean // false,\n  chainwork: string // \"0000000000000000000000000000000000000000010969f724913e0fe59377f4\"\n}\n\n// WhatsOnChain headers looks like:\nexport interface WocHeader {\n  hash: string // \"00000000000000000836c9c44151acbf374c6d4a9713d43b5e95011bdbd1ff2e\"\n  size: number // 71646128,\n  height: number // 760633,\n  version: number // 712441856,\n  versionHex: string // \"2a770000\",\n  merkleroot: string // \"af80d255ca21d9ccdd2cc3576dc532adc7fcbc324ce2db3dec8d54079b56a001\",\n  time: number // 1665274100,\n  mediantime: number // 1665270280,\n  nonce: number // 618555943,\n  bits: number | string // decimal of ox180dc8e5,\n  difficulty: number // 79761715531.82063,\n  chainwork: string // \"0000000000000000000000000000000000000000013d02d8de0ec6cd019bb3a1\",\n  previousblockhash: string // \"00000000000000000272ad9db518e5eeac702f1b00ffa6dc9605f687301dda99\",\n\n  confirmations: number // 3,\n  txcount: number // 45168,\n  nextblockhash: string // \"000000000000000004e01d72ccb7502f0412cc12d7e50f6fafa99ac6f89fd063\",\n  // coinbaseTx\n  // orphaned\n}\n\nexport function convertWocToBlockHeaderHex(woc: WocHeader): BlockHeader {\n  const bits: number = typeof woc.bits === 'string' ? Number.parseInt(woc.bits, 16) : woc.bits\n  if (!woc.previousblockhash) {\n    woc.previousblockhash = '0000000000000000000000000000000000000000000000000000000000000000' // genesis\n  }\n  return {\n    version: woc.version,\n    previousHash: woc.previousblockhash,\n    merkleRoot: woc.merkleroot,\n    time: woc.time,\n    bits,\n    nonce: woc.nonce,\n    hash: woc.hash,\n    height: woc.height\n  }\n}\n\nexport async function getWhatsOnChainBlockHeaderByHash(\n  hash: string,\n  chain: Chain = 'main',\n  apiKey?: string\n): Promise<BlockHeader | undefined> {\n  const config = apiKey ? { apiKey } : {}\n  const woc = new WhatsOnChain(chain, config)\n  const header = await woc.getBlockHeaderByHash(hash)\n  return header\n}\n","import { Chain } from '../../../../sdk/types'\nimport { BlockHeader } from '../../../../sdk/WalletServices.interfaces'\nimport { WhatsOnChain, WocChainInfo } from '../../../providers/WhatsOnChain'\nimport { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'\nimport { ChaintracksFetch } from '../util/ChaintracksFetch'\nimport { HeightRange } from '../util/HeightRange'\nimport { wait } from '../../../../utility/utilityHelpers'\n\n/**\n * return true to ignore error, false to close service connection\n */\nexport type ErrorHandler = (code: number, message: string) => boolean\nexport type EnqueueHandler = (header: BlockHeader) => void\n\nexport function parseFileLink(\n  file: string\n): { range: { fromHeight: number; toHeight: number } | 'latest'; sourceUrl: string; fileName: string } | undefined {\n  const url = new URL(file)\n  const parts = url.pathname.split('/')\n  const fileName = parts.pop()\n  if (!fileName) return undefined\n  const sourceUrl = `${url.protocol}//${url.hostname}${parts.join('/')}`\n  const bits = fileName.split('_')\n  if (bits.length === 1 && bits[0] === 'latest') {\n    return { range: 'latest', sourceUrl, fileName }\n  }\n  if (bits.length === 3) {\n    const fromHeight = Number.parseInt(bits[0], 10)\n    const toHeight = Number.parseInt(bits[1], 10)\n    if (Number.isInteger(fromHeight) && Number.isInteger(toHeight)) {\n      return { range: { fromHeight, toHeight }, sourceUrl, fileName }\n    }\n  }\n  return undefined\n}\n\ntype ParsedFileLink = NonNullable<ReturnType<typeof parseFileLink>>\n\nasync function resolveHeaderFileLink(\n  parsed: ParsedFileLink,\n  currentRange: HeightRange | undefined,\n  neededRange: HeightRange,\n  fetch: ChaintracksFetchApi,\n  link: string\n): Promise<{ range: HeightRange | undefined; result?: GetHeaderByteFileLinksResult }> {\n  if (parsed.range !== 'latest') {\n    const range = new HeightRange(parsed.range.fromHeight, parsed.range.toHeight)\n    const result = neededRange.intersect(range).isEmpty\n      ? undefined\n      : { sourceUrl: parsed.sourceUrl, fileName: parsed.fileName, range, data: undefined }\n    return { range, result }\n  }\n  if (currentRange == null) return { range: currentRange }\n  const fromHeight = currentRange.maxHeight + 1\n  if (neededRange.maxHeight < fromHeight) return { range: currentRange }\n  const data = await fetch.download(link)\n  const range = new HeightRange(fromHeight, fromHeight + data.length / 80 - 1)\n  const result = neededRange.intersect(range).isEmpty\n    ? undefined\n    : { sourceUrl: parsed.sourceUrl, fileName: parsed.fileName, range, data }\n  return { range, result }\n}\n\nexport interface WhatsOnChainServicesOptions {\n  /**\n   * Which chain is being tracked. The public WhatsOnChain fallback is only\n   * configured automatically for mainnet and testnet.\n   */\n  chain: Chain\n  /**\n   * Optional WhatsOnChain API key. ChainTracks works without one and limits\n   * anonymous traffic to the documented public rate.\n   * https://docs.whatsonchain.com/\n   */\n  apiKey?: string\n  /**\n   * Request timeout for GETs to https://api.whatsonchain.com/v1/bsv\n   */\n  timeout: number\n  /**\n   * User-Agent header value for requests to https://api.whatsonchain.com/v1/bsv\n   */\n  userAgent: string\n  /**\n   * Enable WhatsOnChain client cache option.\n   */\n  enableCache: boolean\n  /**\n   * How long chainInfo is considered still valid before updating (msecs).\n   */\n  chainInfoMsecs: number\n  /** Minimum interval between keyless API request starts. Defaults below 3 requests/second. */\n  minRequestIntervalMsecs?: number\n}\n\nexport class WhatsOnChainServices {\n  static createWhatsOnChainServicesOptions(chain: Chain): WhatsOnChainServicesOptions {\n    const options: WhatsOnChainServicesOptions = {\n      chain,\n      apiKey: '',\n      timeout: 30000,\n      userAgent: 'BabbageWhatsOnChainServices',\n      enableCache: true,\n      chainInfoMsecs: 5000,\n      minRequestIntervalMsecs: 350\n    }\n    return options\n  }\n\n  static readonly chainInfo: Array<WocChainInfo | undefined> = []\n  static readonly chainInfoTime: Array<Date | undefined> = []\n  static readonly chainInfoMsecs: number[] = []\n  static readonly chainInfoPromise: Partial<Record<Chain, Promise<WocChainInfo>>> = {}\n  private static requestTail: Promise<void> = Promise.resolve()\n  private static nextRequestMsecs = 0\n\n  chain: Chain\n  woc: WhatsOnChain\n\n  constructor(public options: WhatsOnChainServicesOptions) {\n    const config = {\n      apiKey: this.options.apiKey,\n      timeout: this.options.timeout,\n      userAgent: this.options.userAgent,\n      enableCache: this.options.enableCache,\n      requestGate: async () => await this.waitForRateLimit()\n    }\n    this.chain = options.chain\n    const chainInfoMsecs = WhatsOnChainServices.chainInfoMsecs as unknown as Record<Chain, number>\n    chainInfoMsecs[this.chain] = options.chainInfoMsecs\n    this.woc = new WhatsOnChain(this.chain, config)\n  }\n\n  async getHeaderByHash(hash: string): Promise<BlockHeader | undefined> {\n    const header = await this.woc.getBlockHeaderByHash(hash)\n    return header\n  }\n\n  async getChainInfo(): Promise<WocChainInfo> {\n    const chainInfo = WhatsOnChainServices.chainInfo as unknown as Partial<Record<Chain, WocChainInfo>>\n    const chainInfoTime = WhatsOnChainServices.chainInfoTime as unknown as Partial<Record<Chain, Date>>\n    const chainInfoMsecs = WhatsOnChainServices.chainInfoMsecs as unknown as Partial<Record<Chain, number>>\n    const now = new Date()\n    let update = chainInfo[this.chain] === undefined\n    if (!update && chainInfoTime[this.chain] !== undefined) {\n      const elapsed = now.getTime() - chainInfoTime[this.chain]!.getTime()\n      update = elapsed > chainInfoMsecs[this.chain]!\n    }\n    if (update) {\n      let pending = WhatsOnChainServices.chainInfoPromise[this.chain]\n      if (pending == null) {\n        pending = this.woc.getChainInfo()\n        WhatsOnChainServices.chainInfoPromise[this.chain] = pending\n      }\n      try {\n        chainInfo[this.chain] = await pending\n      } finally {\n        if (WhatsOnChainServices.chainInfoPromise[this.chain] === pending) {\n          delete WhatsOnChainServices.chainInfoPromise[this.chain]\n        }\n      }\n      chainInfoTime[this.chain] = now\n    }\n    if (!chainInfo[this.chain]) throw new Error('Unexpected failure to update chainInfo.')\n    return chainInfo[this.chain]!\n  }\n\n  async getChainTipHeight(): Promise<number> {\n    return (await this.getChainInfo()).blocks\n  }\n\n  async getChainTipHash(): Promise<string> {\n    return (await this.getChainInfo()).bestblockhash\n  }\n\n  /**\n   * @param fetch\n   * @returns returns the last 10 block headers including height, size, chainwork...\n   */\n  async getHeaders(fetch?: ChaintracksFetchApi): Promise<WocGetHeadersHeader[]> {\n    fetch ||= new ChaintracksFetch()\n    await this.waitForRateLimit()\n    const headers = await fetch.fetchJson<WocGetHeadersHeader[]>(\n      `https://api.whatsonchain.com/v1/bsv/${this.chain}/block/headers`\n    )\n    return headers\n  }\n\n  async getHeaderByteFileLinks(\n    neededRange: HeightRange,\n    fetch?: ChaintracksFetchApi\n  ): Promise<GetHeaderByteFileLinksResult[]> {\n    fetch ||= new ChaintracksFetch()\n    await this.waitForRateLimit()\n    const files = await fetch.fetchJson<WocGetHeaderByteFileLinks>(\n      `https://api.whatsonchain.com/v1/bsv/${this.chain}/block/headers/resources`\n    )\n    const r: GetHeaderByteFileLinksResult[] = []\n    let range: HeightRange | undefined\n    for (const link of files.files) {\n      const parsed = parseFileLink(link)\n      if (parsed === undefined) continue // parse error, return empty result\n      const resolved = await resolveHeaderFileLink(parsed, range, neededRange, fetch, link)\n      range = resolved.range\n      if (resolved.result != null) r.push(resolved.result)\n    }\n    return r\n  }\n\n  private async waitForRateLimit(): Promise<void> {\n    let release!: () => void\n    const previous = WhatsOnChainServices.requestTail\n    WhatsOnChainServices.requestTail = new Promise<void>(resolve => {\n      release = resolve\n    })\n    await previous\n    try {\n      const delay = Math.max(0, WhatsOnChainServices.nextRequestMsecs - Date.now())\n      if (delay > 0) await wait(delay)\n      WhatsOnChainServices.nextRequestMsecs = Date.now() + (this.options.minRequestIntervalMsecs ?? 350)\n    } finally {\n      release()\n    }\n  }\n}\n\nexport interface WocGetHeaderByteFileLinks {\n  files: string[]\n}\n\nexport interface WocGetHeadersHeader {\n  hash: string\n  confirmations: number\n  size: number\n  height: number\n  version: number\n  versionHex: string\n  merkleroot: string\n  time: number\n  mediantime: number\n  nonce: number\n  bits: string\n  difficulty: number\n  chainwork: string\n  previousblockhash: string\n  nextblockhash: string\n  nTx: number\n  num_tx: number\n}\n\nexport function wocGetHeadersHeaderToBlockHeader(h: WocGetHeadersHeader): BlockHeader {\n  const bits: number = typeof h.bits === 'string' ? Number.parseInt(h.bits, 16) : h.bits\n  if (!h.previousblockhash) {\n    h.previousblockhash = '0000000000000000000000000000000000000000000000000000000000000000' // genesis\n  }\n  const bh: BlockHeader = {\n    height: h.height,\n    hash: h.hash,\n    version: h.version,\n    previousHash: h.previousblockhash,\n    merkleRoot: h.merkleroot,\n    time: h.time,\n    bits,\n    nonce: h.nonce\n  }\n\n  return bh\n}\n\nexport interface GetHeaderByteFileLinksResult {\n  sourceUrl: string\n  fileName: string\n  range: HeightRange\n  data: Uint8Array | undefined\n}\n","import { Chain } from '../../../../sdk'\nimport { BlockHeader } from '../Api/BlockHeaderApi'\nimport { BulkIngestorBaseOptions } from '../Api/BulkIngestorApi'\nimport { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'\nimport { BulkIngestorBase } from './BulkIngestorBase'\nimport { deserializeBlockHeader } from '../util/blockHeaderUtilities'\nimport { ChaintracksFetch } from '../util/ChaintracksFetch'\nimport { HeightRange, HeightRanges } from '../util/HeightRange'\nimport { StopListenerToken } from './WhatsOnChainIngestorWs'\nimport { WhatsOnChainServices, WhatsOnChainServicesOptions } from './WhatsOnChainServices'\n\nexport interface BulkIngestorWhatsOnChainOptions extends BulkIngestorBaseOptions, WhatsOnChainServicesOptions {\n  /**\n   * Maximum msecs of \"normal\" pause with no new data arriving.\n   */\n  idleWait: number | undefined\n  /**\n   * Which chain is being tracked: main, test, or stn.\n   */\n  chain: Chain\n  /**\n   * WhatsOnChain.com API Key\n   * https://docs.taal.com/introduction/get-an-api-key\n   * If unknown or empty, maximum request rate is limited.\n   * https://developers.whatsonchain.com/#rate-limits\n   */\n  apiKey?: string\n  /**\n   * Request timeout for GETs to https://api.whatsonchain.com/v1/bsv\n   */\n  timeout: number\n  /**\n   * User-Agent header value for requests to https://api.whatsonchain.com/v1/bsv\n   */\n  userAgent: string\n  /**\n   * Enable WhatsOnChain client cache option.\n   */\n  enableCache: boolean\n  /**\n   * How long chainInfo is considered still valid before updating (msecs).\n   */\n  chainInfoMsecs: number\n  /**\n   *\n   */\n  fetch?: ChaintracksFetchApi\n}\n\nexport class BulkIngestorWhatsOnChainCdn extends BulkIngestorBase {\n  /**\n   *\n   * @param chain\n   * @param localCachePath defaults to './data/ingest_whatsonchain_headers'\n   * @returns\n   */\n  static createBulkIngestorWhatsOnChainOptions(chain: Chain): BulkIngestorWhatsOnChainOptions {\n    const options: BulkIngestorWhatsOnChainOptions = {\n      ...WhatsOnChainServices.createWhatsOnChainServicesOptions(chain),\n      ...BulkIngestorBase.createBulkIngestorBaseOptions(chain),\n      idleWait: 5000\n    }\n    return options\n  }\n\n  fetch: ChaintracksFetchApi\n  idleWait: number\n  woc: WhatsOnChainServices\n  stopOldListenersToken: StopListenerToken = { stop: undefined }\n\n  constructor(options: BulkIngestorWhatsOnChainOptions) {\n    super(options)\n    this.idleWait = options.idleWait || 5000\n    this.woc = new WhatsOnChainServices(options)\n    this.fetch = options.fetch || new ChaintracksFetch()\n  }\n\n  override async getPresentHeight(): Promise<number | undefined> {\n    const presentHeight = await this.woc.getChainTipHeight()\n    // this.log(`presentHeight=${presentHeight}`)\n    return presentHeight\n  }\n\n  async fetchHeaders(\n    before: HeightRanges,\n    fetchRange: HeightRange,\n    bulkRange: HeightRange,\n    priorLiveHeaders: BlockHeader[]\n  ): Promise<BlockHeader[]> {\n    const oldHeaders: BlockHeader[] = []\n\n    try {\n      const ranges = await this.woc.getHeaderByteFileLinks(fetchRange, this.fetch)\n\n      for (const range of ranges) {\n        for (let height = range.range.minHeight; height <= range.range.maxHeight; height++) {\n          if (fetchRange.contains(height)) {\n            range.data ??= await this.fetch.download(this.fetch.pathJoin(range.sourceUrl, range.fileName))\n            const h = deserializeBlockHeader(range.data, height, (height - range.range.minHeight) * 80)\n            oldHeaders.push(h)\n          }\n        }\n      }\n    } catch (e) {\n      this.log(`Errors during WhatsOnChain ingestion:\\n${e}`)\n    }\n\n    const liveHeaders = await this.storage().addBulkHeaders(oldHeaders, bulkRange, priorLiveHeaders)\n\n    return liveHeaders\n  }\n}\n","import { Chain } from '../../../../sdk'\nimport { asUint8Array } from '../../../../utility/utilityHelpers.noBuffer'\nimport { BulkIngestorBaseOptions } from '../Api/BulkIngestorApi'\nimport { BlockHeader } from '../Api/BlockHeaderApi'\nimport { ChaintracksClientApi } from '../Api/ChaintracksClientApi'\nimport { HeightRange, HeightRanges } from '../util/HeightRange'\nimport { deserializeBlockHeaders } from '../util/blockHeaderUtilities'\nimport { BulkIngestorBase } from './BulkIngestorBase'\n\nexport interface BulkIngestorChaintracksOptions extends BulkIngestorBaseOptions {\n  chain: Chain\n  chaintracks: ChaintracksClientApi\n  /** Maximum headers requested from the upstream service at once. */\n  maxHeadersPerRequest?: number\n}\n\n/**\n * Uses a go-chaintracks/Arcade-compatible service as a validated bulk source.\n * Retrieved bytes still pass through ChainTracks' local serialization, hash,\n * continuity, and genesis checks before storage.\n */\nexport class BulkIngestorChaintracks extends BulkIngestorBase {\n  private readonly chaintracks: ChaintracksClientApi\n  private readonly maxHeadersPerRequest: number\n  private networkChecked = false\n\n  constructor(options: BulkIngestorChaintracksOptions) {\n    super(options)\n    this.chaintracks = options.chaintracks\n    this.maxHeadersPerRequest = options.maxHeadersPerRequest ?? 1000\n    if (!Number.isInteger(this.maxHeadersPerRequest) || this.maxHeadersPerRequest < 1) {\n      throw new Error('maxHeadersPerRequest must be a positive integer.')\n    }\n  }\n\n  override async getPresentHeight(): Promise<number> {\n    await this.ensureNetwork()\n    return await this.chaintracks.getPresentHeight()\n  }\n\n  async fetchHeaders(\n    _before: HeightRanges,\n    fetchRange: HeightRange,\n    bulkRange: HeightRange,\n    priorLiveHeaders: BlockHeader[]\n  ): Promise<BlockHeader[]> {\n    if (fetchRange.isEmpty) return priorLiveHeaders\n    await this.ensureNetwork()\n\n    let liveHeaders = priorLiveHeaders\n    let height = fetchRange.minHeight\n    while (height <= fetchRange.maxHeight) {\n      const requested = Math.min(this.maxHeadersPerRequest, fetchRange.maxHeight - height + 1)\n      const hex = await this.chaintracks.getHeaders(height, requested)\n      const bytes = asUint8Array(hex)\n      if (bytes.length === 0) {\n        throw new Error(`ChainTracks upstream returned no headers at height ${height}.`)\n      }\n      if (bytes.length % 80 !== 0 || bytes.length > requested * 80) {\n        throw new Error(\n          `ChainTracks upstream returned ${bytes.length} bytes for ${requested} headers at height ${height}.`\n        )\n      }\n      const headers = deserializeBlockHeaders(height, bytes)\n      liveHeaders = await this.storage().addBulkHeaders(headers, bulkRange, liveHeaders)\n      height += headers.length\n      if (headers.length < requested && height <= fetchRange.maxHeight) {\n        throw new Error(\n          `ChainTracks upstream returned ${headers.length} of ${requested} headers at height ${height - headers.length}.`\n        )\n      }\n    }\n    return liveHeaders\n  }\n\n  private async ensureNetwork(): Promise<void> {\n    if (this.networkChecked) return\n    const actual = await this.chaintracks.getChain()\n    if (actual !== this.chain) {\n      throw new Error(`ChainTracks upstream network '${actual}' does not match configured chain '${this.chain}'.`)\n    }\n    this.networkChecked = true\n  }\n}\n","import { BlockHeader, Chain } from '../../../../sdk'\nimport { wait } from '../../../../utility/utilityHelpers'\nimport { LiveIngestorBase, LiveIngestorBaseOptions } from './LiveIngestorBase'\nimport {\n  WhatsOnChainServices,\n  WhatsOnChainServicesOptions,\n  WocGetHeadersHeader,\n  wocGetHeadersHeaderToBlockHeader\n} from './WhatsOnChainServices'\nimport { ChaintracksFetchError } from '../util/ChaintracksFetch'\n\nexport interface LiveIngestorWhatsOnChainOptions extends LiveIngestorBaseOptions, WhatsOnChainServicesOptions {\n  /**\n   * Maximum msces of \"normal\" time with no ping received from connected WoC service.\n   */\n  idleWait: number | undefined\n  /**\n   * Which chain is being tracked: main, test, or stn.\n   */\n  chain: Chain\n  /**\n   * WhatsOnChain.com API Key\n   * https://docs.taal.com/introduction/get-an-api-key\n   * If unknown or empty, maximum request rate is limited.\n   * https://developers.whatsonchain.com/#rate-limits\n   */\n  apiKey?: string\n  /**\n   * Request timeout for GETs to https://api.whatsonchain.com/v1/bsv\n   */\n  timeout: number\n  /**\n   * User-Agent header value for requests to https://api.whatsonchain.com/v1/bsv\n   */\n  userAgent: string\n  /**\n   * Enable WhatsOnChain client cache option.\n   */\n  enableCache: boolean\n  /**\n   * How long chainInfo is considered still valid before updating (msecs).\n   */\n  chainInfoMsecs: number\n  /**\n   * Initial delay before retrying a failed polling request.\n   */\n  retryWait?: number\n  /**\n   * Maximum delay before retrying repeated failed polling requests.\n   */\n  retryWaitMax?: number\n}\n\n/**\n * Reports new headers by polling periodically.\n */\nexport class LiveIngestorWhatsOnChainPoll extends LiveIngestorBase {\n  static createLiveIngestorWhatsOnChainOptions (chain: Chain): LiveIngestorWhatsOnChainOptions {\n    const options: LiveIngestorWhatsOnChainOptions = {\n      ...WhatsOnChainServices.createWhatsOnChainServicesOptions(chain),\n      ...LiveIngestorBase.createLiveIngestorBaseOptions(chain),\n      idleWait: 100000,\n      retryWait: 5000,\n      retryWaitMax: 120000\n    }\n    return options\n  }\n\n  idleWait: number\n  retryWait: number\n  retryWaitMax: number\n  woc: WhatsOnChainServices\n  done: boolean = false\n\n  constructor (options: LiveIngestorWhatsOnChainOptions) {\n    super(options)\n    this.idleWait = options.idleWait ?? 100000\n    this.retryWait = options.retryWait ?? 5000\n    this.retryWaitMax = options.retryWaitMax ?? 120000\n    this.woc = new WhatsOnChainServices(options)\n  }\n\n  async getHeaderByHash (hash: string): Promise<BlockHeader | undefined> {\n    const header = await this.woc.getHeaderByHash(hash)\n    return header\n  }\n\n  async startListening (liveHeaders: BlockHeader[]): Promise<void> {\n    this.done = false\n    let lastHeaders: WocGetHeadersHeader[] = []\n    let failureCount = 0\n\n    while (!this.done) {\n      let headers: WocGetHeadersHeader[]\n      try {\n        headers = await this.woc.getHeaders()\n        failureCount = 0\n      } catch (error: unknown) {\n        failureCount++\n        const retryMsecs = this.getRetryWaitMsecs(error, failureCount)\n        this.log(`LiveIngestorWhatsOnChainPoll getHeaders failed attempt=${failureCount} retryMsecs=${retryMsecs} error=${this.errorMessage(error)}`)\n        await this.waitUnlessStopped(retryMsecs)\n        continue\n      }\n\n      const newHeaders = headers.filter(h => !lastHeaders.some(lh => lh.hash === h.hash))\n\n      for (const h of newHeaders) {\n        const bh = wocGetHeadersHeaderToBlockHeader(h)\n        liveHeaders.unshift(bh)\n      }\n\n      lastHeaders = headers\n\n      await this.waitUnlessStopped(60 * 1000)\n    }\n    this.log('LiveIngestorWhatsOnChainPoll stopped')\n  }\n\n  private getRetryWaitMsecs (error: unknown, failureCount: number): number {\n    if (error instanceof ChaintracksFetchError && error.retryAfterMsecs != null) {\n      return Math.min(Math.max(error.retryAfterMsecs, 0), this.retryWaitMax)\n    }\n    const multiplier = Math.min(2 ** (failureCount - 1), 16)\n    return Math.min(this.retryWait * multiplier, this.retryWaitMax)\n  }\n\n  private errorMessage (error: unknown): string {\n    if (error instanceof ChaintracksFetchError) return `${error.status} ${error.statusText}: ${error.message}`\n    if (error instanceof Error) return error.message\n    return String(error)\n  }\n\n  private async waitUnlessStopped (msecs: number): Promise<void> {\n    let remaining = msecs\n    while (remaining > 0 && !this.done) {\n      const chunk = Math.min(1000, remaining)\n      await wait(chunk)\n      remaining -= chunk\n    }\n  }\n\n  stopListening (): void {\n    this.done = true\n  }\n\n  override async shutdown (): Promise<void> {\n    this.stopListening()\n  }\n}\n","import { Chain } from '../../../../sdk'\nimport { ChaintracksClientApi } from '../Api/ChaintracksClientApi'\nimport { BlockHeader } from '../Api/BlockHeaderApi'\nimport { LiveIngestorBase, LiveIngestorBaseOptions } from './LiveIngestorBase'\n\nexport interface LiveIngestorChaintracksSSEOptions extends LiveIngestorBaseOptions {\n  chaintracks: ChaintracksClientApi\n}\n\n/**\n * Adapts a remote Chaintracks event stream, such as Arcade/go-chaintracks\n * `/chaintracks/v2/tip/stream`, into the local Chaintracks live-ingestor API.\n */\nexport class LiveIngestorChaintracksSSE extends LiveIngestorBase {\n  static createLiveIngestorChaintracksSSEOptions(\n    chain: Chain,\n    chaintracks: ChaintracksClientApi\n  ): LiveIngestorChaintracksSSEOptions {\n    return {\n      ...LiveIngestorBase.createLiveIngestorBaseOptions(chain),\n      chaintracks\n    }\n  }\n\n  private subscriptionId?: string\n  private stopped = false\n  private resolveStopped?: () => void\n\n  constructor(private readonly options: LiveIngestorChaintracksSSEOptions) {\n    super(options)\n  }\n\n  async getHeaderByHash(hash: string): Promise<BlockHeader | undefined> {\n    return await this.options.chaintracks.findHeaderForBlockHash(hash)\n  }\n\n  async startListening(liveHeaders: BlockHeader[]): Promise<void> {\n    this.stopped = false\n    const actual = await this.options.chaintracks.getChain()\n    if (actual !== this.chain) {\n      throw new Error(`ChainTracks upstream network '${actual}' does not match configured chain '${this.chain}'.`)\n    }\n    if (this.stopped) return\n    const subscriptionId = await this.options.chaintracks.subscribeHeaders(header => {\n      if (!this.stopped) liveHeaders.push(header)\n    })\n    if (this.stopped) {\n      await this.options.chaintracks.unsubscribe(subscriptionId)\n      return\n    }\n    this.subscriptionId = subscriptionId\n    await new Promise<void>(resolve => {\n      this.resolveStopped = resolve\n      if (this.stopped) resolve()\n    })\n  }\n\n  stopListening(): void {\n    this.stopped = true\n    const subscriptionId = this.subscriptionId\n    this.subscriptionId = undefined\n    if (subscriptionId != null) {\n      this.options.chaintracks.unsubscribe(subscriptionId).catch(e => {\n        this.log(`LiveIngestorChaintracksSSE unsubscribe failed: ${e}`)\n      })\n    }\n    const resolveStopped = this.resolveStopped\n    this.resolveStopped = undefined\n    resolveStopped?.()\n  }\n\n  override async shutdown(): Promise<void> {\n    this.stopListening()\n  }\n}\n","// /* eslint-disable @typescript-eslint/no-empty-function */\n/* eslint-disable @typescript-eslint/no-unused-vars */\nimport { BulkStorageApi, BulkStorageBaseOptions } from '../Api/BulkStorageApi'\n\nimport { ChaintracksStorageBase } from './ChaintracksStorageBase'\n\nimport { HeightRange } from '../util/HeightRange'\nimport { BulkHeaderFileInfo, BulkHeaderFilesInfo } from '../util/BulkHeaderFile'\nimport { Chain } from '../../../../sdk/types'\nimport { BlockHeader } from '../Api/BlockHeaderApi'\n\nimport { ChaintracksFsApi } from '../Api/ChaintracksFsApi'\nimport { asUint8Array } from '../../../../utility/utilityHelpers.noBuffer'\n\nexport abstract class BulkStorageBase implements BulkStorageApi {\n  static createBulkStorageBaseOptions (chain: Chain, fs: ChaintracksFsApi): BulkStorageBaseOptions {\n    const options: BulkStorageBaseOptions = {\n      chain,\n      fs\n    }\n    return options\n  }\n\n  chain: Chain\n  fs: ChaintracksFsApi\n  log: (...args: any[]) => void = () => {}\n\n  constructor (options: BulkStorageBaseOptions) {\n    this.chain = options.chain\n    this.fs = options.fs\n  }\n\n  async shutdown (): Promise<void> { /* intentional no-op: subclasses override when needed */ }\n\n  abstract appendHeaders (minHeight: number, count: number, newBulkHeaders: Uint8Array): Promise<void>\n  abstract getMaxHeight (): Promise<number>\n  abstract headersToBuffer (height: number, count: number): Promise<Uint8Array>\n  abstract findHeaderForHeightOrUndefined (height: number): Promise<BlockHeader | undefined>\n\n  async findHeaderForHeight (height: number): Promise<BlockHeader> {\n    const header = await this.findHeaderForHeightOrUndefined(height)\n    if (header == null) throw new Error(`No header found for height ${height}`)\n    return header\n  }\n\n  async getHeightRange (): Promise<HeightRange> {\n    return new HeightRange(0, await this.getMaxHeight())\n  }\n\n  async setStorage (storage: ChaintracksStorageBase, log: (...args: any[]) => void): Promise<void> { /* intentional no-op: subclasses override when needed */ }\n\n  async exportBulkHeaders (rootFolder: string, jsonFilename: string, maxPerFile: number): Promise<void> {\n    const info: BulkHeaderFilesInfo = {\n      rootFolder,\n      jsonFilename,\n      files: [],\n      headersPerFile: maxPerFile\n    }\n    const maxHeight = await this.getMaxHeight()\n    const baseFilename = jsonFilename.slice(0, -5) // remove \".json\"\n    const prevHash = '00'.repeat(32)\n    const prevChainWork = '00'.repeat(32)\n    for (let height = 0; height <= maxHeight; height += maxPerFile) {\n      const count = Math.min(maxPerFile, maxHeight - height + 1)\n      const file: BulkHeaderFileInfo = {\n        fileName: `${baseFilename}_${info.files.length}.headers`,\n        firstHeight: height,\n        prevHash,\n        prevChainWork,\n        count,\n        lastHash: null,\n        fileHash: null,\n        lastChainWork: ''\n      }\n      const buffer = await this.headersToBuffer(height, count)\n      await this.fs.writeFile(this.fs.pathJoin(rootFolder, file.fileName), buffer)\n    }\n    const bytes = asUint8Array(JSON.stringify(info), 'utf8')\n    await this.fs.writeFile(this.fs.pathJoin(rootFolder, jsonFilename), bytes)\n  }\n}\n","import { HeightRange } from './HeightRange'\nimport { ChaintracksFsApi } from '../Api/ChaintracksFsApi'\nimport { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'\nimport { ChaintracksStorageBase } from '../Storage/ChaintracksStorageBase'\nimport { Hash } from '@bsv/sdk'\nimport { Chain } from '../../../../sdk/types'\nimport { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../../../sdk/WERR_errors'\nimport { asArray, asString } from '../../../../utility/utilityHelpers.noBuffer'\n\n/**\n * Descriptive information about a single bulk header file.\n */\nexport interface BulkHeaderFileInfo {\n  /**\n   * filename and extension, no path\n   */\n  fileName: string\n  /**\n   * chain height of first header in file\n   */\n  firstHeight: number\n  /**\n   * count of how many headers the file contains. File size must be 80 * count.\n   */\n  count: number\n  /**\n   * prevChainWork is the cummulative chain work up to the first header in this file's data, as a hex string.\n   */\n  prevChainWork: string\n  /**\n   * lastChainWork is the cummulative chain work including the last header in this file's data, as a hex string.\n   */\n  lastChainWork: string\n  /**\n   * previousHash of first header in file in standard hex string block hash encoding\n   */\n  prevHash: string\n  /**\n   * block hash of last header in the file in standard hex string block hash encoding\n   */\n  lastHash: string | null\n  /**\n   * file contents single sha256 hash as base64 string\n   */\n  fileHash: string | null\n  /**\n   * Which chain: 'main' or 'test'\n   */\n  chain?: Chain\n\n  data?: Uint8Array // optional, used for validation\n\n  /**\n   * true iff these properties should be considered pre-validated, including a valid required fileHash of data (when not undefined).\n   */\n  validated?: boolean\n  /**\n   * optional, used for database storage\n   */\n  fileId?: number\n  /**\n   * optional, if valid `${sourceUrl}/${fileName}` is the source of this data.\n   */\n  sourceUrl?: string\n}\n\nexport abstract class BulkHeaderFile implements BulkHeaderFileInfo {\n  chain?: Chain\n  count: number\n  data?: Uint8Array<ArrayBufferLike>\n  fileHash: string | null\n  fileId?: number\n  fileName: string\n  firstHeight: number\n  lastChainWork: string\n  lastHash: string | null\n  prevChainWork: string\n  prevHash: string\n  sourceUrl?: string\n  validated?: boolean\n\n  constructor (info: BulkHeaderFileInfo) {\n    this.chain = info.chain\n    this.count = info.count\n    this.data = info.data\n    this.fileHash = info.fileHash\n    this.fileId = info.fileId\n    this.fileName = info.fileName\n    this.firstHeight = info.firstHeight\n    this.lastChainWork = info.lastChainWork\n    this.lastHash = info.lastHash\n    this.prevChainWork = info.prevChainWork\n    this.prevHash = info.prevHash\n    this.sourceUrl = info.sourceUrl\n    this.validated = info.validated\n  }\n\n  abstract readDataFromFile (length: number, offset: number): Promise<Uint8Array | undefined>\n\n  get heightRange (): HeightRange {\n    return new HeightRange(this.firstHeight, this.firstHeight + this.count - 1)\n  }\n\n  async ensureData (): Promise<Uint8Array> {\n    if (this.data == null) throw new WERR_INVALID_OPERATION('data is undefined and no ensureData() override')\n    return this.data\n  }\n\n  /**\n   * Whenever reloading data from a backing store, validated fileHash must be re-verified\n   * @returns the sha256 hash of the file's data as base64 string.\n   */\n  async computeFileHash (): Promise<string> {\n    if (this.data == null) throw new WERR_INVALID_OPERATION('requires defined data')\n    return asString(Hash.sha256(asArray(this.data)), 'base64')\n  }\n\n  async releaseData (): Promise<void> {\n    this.data = undefined\n  }\n\n  toCdnInfo (): BulkHeaderFileInfo {\n    return {\n      count: this.count,\n      fileHash: this.fileHash,\n      fileName: this.fileName,\n      firstHeight: this.firstHeight,\n      lastChainWork: this.lastChainWork,\n      lastHash: this.lastHash,\n      prevChainWork: this.prevChainWork,\n      prevHash: this.prevHash\n    }\n  }\n\n  toStorageInfo (): BulkHeaderFileInfo {\n    return {\n      count: this.count,\n      fileHash: this.fileHash,\n      fileName: this.fileName,\n      firstHeight: this.firstHeight,\n      lastChainWork: this.lastChainWork,\n      lastHash: this.lastHash,\n      prevChainWork: this.prevChainWork,\n      prevHash: this.prevHash,\n      chain: this.chain,\n      validated: this.validated,\n      sourceUrl: this.sourceUrl,\n      fileId: this.fileId\n    }\n  }\n}\n\nexport class BulkHeaderFileFs extends BulkHeaderFile {\n  constructor (\n    info: BulkHeaderFileInfo,\n    public fs: ChaintracksFsApi,\n    public rootFolder: string\n  ) {\n    super(info)\n  }\n\n  override async readDataFromFile (length: number, offset: number): Promise<Uint8Array | undefined> {\n    if (this.data != null) {\n      return this.data.slice(offset, offset + length)\n    }\n    const f = await this.fs.openReadableFile(this.fs.pathJoin(this.rootFolder, this.fileName))\n    try {\n      const buffer = await f.read(length, offset)\n      return buffer\n    } finally {\n      await f.close()\n    }\n  }\n\n  override async ensureData (): Promise<Uint8Array> {\n    if (this.data != null) return this.data\n    this.data = await this.readDataFromFile(this.count * 80, 0)\n    if (this.data == null) throw new WERR_INVALID_OPERATION(`failed to read data for ${this.fileName}`)\n    if (this.validated) {\n      const hash = await this.computeFileHash()\n      if (hash !== this.fileHash) { throw new WERR_INVALID_OPERATION(`BACKING FILE DATA CORRUPTION: invalid fileHash for ${this.fileName}`) }\n    }\n    return this.data\n  }\n}\n\nexport class BulkHeaderFileStorage extends BulkHeaderFile {\n  constructor (\n    info: BulkHeaderFileInfo,\n    public storage: ChaintracksStorageBase,\n    public fetch?: ChaintracksFetchApi\n  ) {\n    super(info)\n  }\n\n  override async readDataFromFile (length: number, offset: number): Promise<Uint8Array | undefined> {\n    return (await this.ensureData()).slice(offset, offset + length)\n  }\n\n  override async ensureData (): Promise<Uint8Array> {\n    if (this.data != null) return this.data\n    if (!this.sourceUrl || (this.fetch == null)) {\n      throw new WERR_INVALID_PARAMETER('sourceUrl and fetch', 'defined. Or data must be defined.')\n    }\n    const url = this.fetch.pathJoin(this.sourceUrl, this.fileName)\n    this.data = await this.fetch.download(url)\n    if (!this.data) throw new WERR_INVALID_OPERATION(`failed to download data from ${url}`)\n    if (this.validated) {\n      const hash = await this.computeFileHash()\n      if (hash !== this.fileHash) { throw new WERR_INVALID_OPERATION(`BACKING DOWNLOAD DATA CORRUPTION: invalid fileHash for ${this.fileName}`) }\n    }\n    return this.data\n  }\n}\n\n/**\n * Describes a collection of bulk block header files.\n */\nexport interface BulkHeaderFilesInfo {\n  /**\n   * Where this file was fetched or read from.\n   */\n  rootFolder: string\n  /**\n   * Sub-path to this resource on rootFolder\n   */\n  jsonFilename: string\n  /**\n   * Array of information about each bulk block header file.\n   */\n  files: BulkHeaderFileInfo[]\n  /**\n   * Maximum number of headers in a single file in this collection of files.\n   */\n  headersPerFile: number\n}\n\nexport abstract class BulkHeaderFiles implements BulkHeaderFilesInfo {\n  constructor (\n    public rootFolder: string,\n    public jsonFilename: string,\n    public files: BulkHeaderFileInfo[],\n    public headersPerFile: number\n  ) {}\n}\n","import { HeightRange } from './HeightRange'\nimport { deserializeBaseBlockHeader, validateBufferOfHeaders } from './blockHeaderUtilities'\nimport { BaseBlockHeader } from '../../../../sdk/WalletServices.interfaces'\nimport { asArray, asString, asUint8Array } from '../../../../utility/utilityHelpers.noBuffer'\nimport { ChaintracksFsApi } from '../Api/ChaintracksFsApi'\nimport { Hash } from '@bsv/sdk'\nimport { WERR_INTERNAL, WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../../../sdk'\nimport { ChaintracksStorageBase } from '../Storage/ChaintracksStorageBase'\nimport { ChaintracksFetchApi } from '../Api/ChaintracksFetchApi'\nimport {\n  BulkHeaderFile,\n  BulkHeaderFileFs,\n  BulkHeaderFileInfo,\n  BulkHeaderFilesInfo,\n  BulkHeaderFileStorage\n} from './BulkHeaderFile'\n\n/**\n * Breaks available bulk headers stored in multiple files into a sequence of buffers with\n * limited maximum size.\n */\nexport class BulkFilesReader {\n  /**\n   * Previously validated bulk header files which may pull data from backing storage on demand.\n   */\n  files: BulkHeaderFile[]\n  /**\n   * Subset of headers currently being \"read\".\n   */\n  range: HeightRange\n  /**\n   * Maximum buffer size returned from `read()` in bytes.\n   */\n  maxBufferSize = 400 * 80\n  /**\n   * \"Read pointer\", the next height to be \"read\".\n   */\n  nextHeight: number | undefined\n\n  constructor(files: BulkHeaderFile[], range?: HeightRange, maxBufferSize?: number) {\n    this.files = files\n    this.range = HeightRange.empty\n    this.setRange(range)\n    this.setMaxBufferSize(maxBufferSize || 400 * 80)\n  }\n\n  protected setRange(range?: HeightRange) {\n    this.range = this.heightRange\n    if (range != null) {\n      this.range = this.range.intersect(range)\n    }\n    this.nextHeight = this.range.isEmpty ? undefined : this.range.minHeight\n  }\n\n  setMaxBufferSize(maxBufferSize: number | undefined) {\n    this.maxBufferSize = maxBufferSize || 400 * 80\n    if (this.maxBufferSize % 80 !== 0) throw new Error('maxBufferSize must be a multiple of 80 bytes.')\n  }\n\n  private getLastFile(): BulkHeaderFileInfo | undefined {\n    return this.files.at(-1)\n  }\n\n  get heightRange(): HeightRange {\n    const last = this.getLastFile()\n    if (last == null || !this.files) return HeightRange.empty\n    const first = this.files[0]\n    return new HeightRange(first.firstHeight, last.firstHeight + last.count - 1)\n  }\n\n  private getFileForHeight(height: number): BulkHeaderFile | undefined {\n    if (!this.files) return undefined\n    return this.files.find(file => file.firstHeight <= height && file.firstHeight + file.count > height)\n  }\n\n  async readBufferForHeightOrUndefined(height: number): Promise<Uint8Array | undefined> {\n    const file = this.getFileForHeight(height)\n    if (file == null) return undefined\n    const buffer = await file.readDataFromFile(80, (height - file.firstHeight) * 80)\n    return buffer\n  }\n\n  async readBufferForHeight(height: number): Promise<Uint8Array> {\n    const header = await this.readBufferForHeightOrUndefined(height)\n    if (header == null) throw new Error(`Failed to read bulk header buffer at height=${height}`)\n    return header\n  }\n\n  async readHeaderForHeight(height: number): Promise<BaseBlockHeader> {\n    const buffer = await this.readBufferForHeight(height)\n    return deserializeBaseBlockHeader(buffer, 0)\n  }\n\n  async readHeaderForHeightOrUndefined(height: number): Promise<BaseBlockHeader | undefined> {\n    const buffer = await this.readBufferForHeightOrUndefined(height)\n    return buffer != null ? deserializeBaseBlockHeader(buffer, 0) : undefined\n  }\n\n  /**\n   * Returns the Buffer of block headers from the given `file` for the given `range`.\n   * If `range` is undefined, the file's full height range is read.\n   * The returned Buffer will only contain headers in `file` and in `range`\n   * @param file\n   * @param range\n   */\n  private async readBufferFromFile(file: BulkHeaderFile, range?: HeightRange): Promise<Uint8Array | undefined> {\n    // Constrain the range to the file's contents...\n    let fileRange = file.heightRange\n    if (range != null) fileRange = fileRange.intersect(range)\n    if (fileRange.isEmpty) return undefined\n    const position = (fileRange.minHeight - file.firstHeight) * 80\n    const length = fileRange.length * 80\n    return await file.readDataFromFile(length, position)\n  }\n\n  private nextFile(file: BulkHeaderFile | undefined): BulkHeaderFile | undefined {\n    if (file == null) return this.files[0]\n    const i = this.files.indexOf(file)\n    if (i < 0) throw new WERR_INVALID_PARAMETER('file', 'a valid file from this.files')\n    return this.files[i + 1]\n  }\n\n  /**\n   * @returns an array containing the next `maxBufferSize` bytes of headers from the files.\n   */\n  async read(): Promise<Uint8Array | undefined> {\n    if (this.nextHeight === undefined || !this.range || this.nextHeight > this.range.maxHeight) return undefined\n    let lastHeight = this.nextHeight + this.maxBufferSize / 80 - 1\n    lastHeight = Math.min(lastHeight, this.range.maxHeight)\n    let file = this.getFileForHeight(this.nextHeight)\n    if (file == null) throw new WERR_INTERNAL('logic error')\n    const readRange = new HeightRange(this.nextHeight, lastHeight)\n    const buffers = new Uint8Array(readRange.length * 80)\n    let offset = 0\n    while (file != null) {\n      const buffer = await this.readBufferFromFile(file, readRange)\n      if (buffer == null) break\n      buffers.set(buffer, offset)\n      offset += buffer.length\n      file = this.nextFile(file)\n    }\n    if (!buffers.length || offset !== readRange.length * 80) return undefined\n    this.nextHeight = lastHeight + 1\n    return buffers\n  }\n\n  /**\n   * Reset the reading process and adjust the range to be read to a new subset of what's available...\n   * @param range new range for subsequent `read` calls to return.\n   * @param maxBufferSize optionally update largest buffer size for `read` to return\n   */\n  resetRange(range: HeightRange, maxBufferSize?: number) {\n    this.setRange(range)\n    this.setMaxBufferSize(maxBufferSize || 400 * 80)\n  }\n\n  async validateFiles(): Promise<void> {\n    let lastChainWork: string | undefined = '00'.repeat(32)\n    let lastHeaderHash = '00'.repeat(32)\n    for (const file of this.files) {\n      if (file.prevChainWork !== lastChainWork) {\n        throw new WERR_INVALID_OPERATION(\n          `prevChainWork mismatch for file ${file.fileName}: expected ${file.prevChainWork}, got ${lastChainWork}`\n        )\n      }\n      if (file.prevHash !== lastHeaderHash) {\n        throw new WERR_INVALID_OPERATION(\n          `prevHash mismatch for file ${file.fileName}: expected ${file.prevHash}, got ${lastHeaderHash}`\n        )\n      }\n      const data = await file.ensureData()\n      if (data.length !== file.count * 80) {\n        throw new WERR_INVALID_OPERATION(\n          `data length mismatch for file ${file.fileName}: expected ${file.count * 80} bytes, got ${data.length} bytes`\n        )\n      }\n      const fileHash = await file.computeFileHash()\n      if (!file.fileHash) throw new WERR_INVALID_OPERATION(`fileHash missing for file ${file.fileName}`)\n      if (file.fileHash !== fileHash) {\n        throw new WERR_INVALID_OPERATION(\n          `fileHash mismatch for file ${file.fileName}: expected ${file.fileHash}, got ${fileHash}`\n        )\n      }\n      ;({ lastHeaderHash, lastChainWork } = validateBufferOfHeaders(data, lastHeaderHash, 0, file.count, lastChainWork))\n\n      if (file.lastHash !== lastHeaderHash) {\n        throw new WERR_INVALID_OPERATION(\n          `lastHash mismatch for file ${file.fileName}: expected ${file.lastHash}, got ${lastHeaderHash}`\n        )\n      }\n      if (file.lastChainWork !== lastChainWork) {\n        throw new WERR_INVALID_OPERATION(\n          `lastChainWork mismatch for file ${file.fileName}: expected ${file.lastChainWork}, got ${lastChainWork}`\n        )\n      }\n\n      file.validated = true\n    }\n  }\n\n  async exportHeadersToFs(toFs: ChaintracksFsApi, toHeadersPerFile: number, toFolder: string): Promise<void> {\n    if (!this.files || this.files.length === 0 || this.files[0].count === 0) {\n      throw new WERR_INVALID_OPERATION('no headers currently available to export')\n    }\n    if (!this.files[0].chain) throw new WERR_INVALID_OPERATION('chain is not defined for the first file')\n\n    const chain = this.files[0].chain\n    const toFileName = (i: number) => `${chain}Net_${i}.headers`\n    const toPath = (i: number) => toFs.pathJoin(toFolder, toFileName(i))\n    const toJsonPath = () => toFs.pathJoin(toFolder, `${chain}NetBlockHeaders.json`)\n\n    const toBulkFiles: BulkHeaderFilesInfo = {\n      rootFolder: toFolder,\n      jsonFilename: `${chain}NetBlockHeaders.json`,\n      headersPerFile: toHeadersPerFile,\n      files: []\n    }\n\n    const bf0 = this.files[0]\n\n    let firstHeight = bf0.firstHeight\n    let lastHeaderHash = bf0.prevHash\n    let lastChainWork = bf0.prevChainWork\n\n    const reader = new BulkFilesReader(this.files, this.heightRange, toHeadersPerFile * 80)\n\n    let i = -1\n    for (;;) {\n      i++\n      const data = await reader.read()\n      if (data == null || data.length === 0) {\n        break\n      }\n\n      const last = validateBufferOfHeaders(data, lastHeaderHash, 0, undefined, lastChainWork)\n\n      await toFs.writeFile(toPath(i), data)\n\n      const fileHash = asString(Hash.sha256(asArray(data)), 'base64')\n      const file: BulkHeaderFileInfo = {\n        chain,\n        count: data.length / 80,\n        fileHash,\n        fileName: toFileName(i),\n        firstHeight,\n        lastChainWork: last.lastChainWork!,\n        lastHash: last.lastHeaderHash,\n        prevChainWork: lastChainWork,\n        prevHash: lastHeaderHash\n      }\n      toBulkFiles.files.push(file)\n      firstHeight += file.count\n      lastHeaderHash = file.lastHash!\n      lastChainWork = file.lastChainWork!\n    }\n\n    await toFs.writeFile(toJsonPath(), asUint8Array(JSON.stringify(toBulkFiles), 'utf8'))\n  }\n}\n\nexport class BulkFilesReaderFs extends BulkFilesReader {\n  constructor(\n    public fs: ChaintracksFsApi,\n    files: BulkHeaderFileFs[],\n    range?: HeightRange,\n    maxBufferSize?: number\n  ) {\n    super(files, range, maxBufferSize)\n  }\n\n  /**\n   * Return a BulkFilesReader configured to access the intersection of `range` and available headers.\n   * @param rootFolder\n   * @param jsonFilename\n   * @param range\n   * @returns\n   */\n  static async fromFs(\n    fs: ChaintracksFsApi,\n    rootFolder: string,\n    jsonFilename: string,\n    range?: HeightRange,\n    maxBufferSize?: number\n  ): Promise<BulkFilesReaderFs> {\n    const filesInfo = await this.readJsonFile(fs, rootFolder, jsonFilename)\n    const readerFiles = filesInfo.files.map(file => new BulkHeaderFileFs(file, fs, rootFolder))\n    return new BulkFilesReaderFs(fs, readerFiles, range, maxBufferSize)\n  }\n\n  static async writeEmptyJsonFile(fs: ChaintracksFsApi, rootFolder: string, jsonFilename: string): Promise<string> {\n    const json = JSON.stringify({ files: [], rootFolder })\n    await fs.writeFile(fs.pathJoin(rootFolder, jsonFilename), asUint8Array(json, 'utf8'))\n    return json\n  }\n\n  static async readJsonFile(\n    fs: ChaintracksFsApi,\n    rootFolder: string,\n    jsonFilename: string,\n    failToEmptyRange: boolean = true\n  ): Promise<BulkHeaderFilesInfo> {\n    const filePath = (file: string) => fs.pathJoin(rootFolder, file)\n\n    const jsonPath = filePath(jsonFilename)\n\n    let json: string\n\n    try {\n      json = asString(await fs.readFile(jsonPath), 'utf8')\n    } catch {\n      // File does not exist yet.  When failToEmptyRange is false we treat a missing\n      // JSON index as an empty range and create it; otherwise we surface a clear error.\n      if (!failToEmptyRange) {\n        throw new WERR_INVALID_PARAMETER(`${rootFolder}/${jsonFilename}`, 'a valid, existing JSON file.')\n      }\n      json = await this.writeEmptyJsonFile(fs, rootFolder, jsonFilename)\n    }\n\n    const readerFiles = JSON.parse(json) as BulkHeaderFilesInfo\n    readerFiles.jsonFilename = jsonFilename\n    readerFiles.rootFolder = rootFolder\n    return readerFiles\n  }\n}\n\nexport class BulkFilesReaderStorage extends BulkFilesReader {\n  constructor(\n    storage: ChaintracksStorageBase,\n    files: BulkHeaderFileStorage[],\n    range?: HeightRange,\n    maxBufferSize?: number\n  ) {\n    super(files, range, maxBufferSize)\n  }\n\n  static async fromStorage(\n    storage: ChaintracksStorageBase,\n    fetch?: ChaintracksFetchApi,\n    range?: HeightRange,\n    maxBufferSize?: number\n  ): Promise<BulkFilesReaderStorage> {\n    const files = await storage.bulkManager.getBulkFiles(true)\n    const readerFiles = files.map(file => new BulkHeaderFileStorage(file, storage, fetch))\n    return new BulkFilesReaderStorage(storage, readerFiles, range, maxBufferSize)\n  }\n}\n","import { WERR_INTERNAL, WERR_INVALID_PARAMETER, Chain } from '../../../../sdk'\nimport {\n  InsertHeaderResult,\n  ChaintracksStorageBaseOptions,\n  ChaintracksStorageIngestApi,\n  ChaintracksStorageQueryApi\n} from '../Api/ChaintracksStorageApi'\nimport { BaseBlockHeader, BlockHeader, LiveBlockHeader } from '../Api/BlockHeaderApi'\nimport { HeightRange } from '../util/HeightRange'\nimport {\n  addWork,\n  convertBitsToWork,\n  deserializeBaseBlockHeaders,\n  isMoreWork,\n  serializeBaseBlockHeaders,\n  subWork\n} from '../util/blockHeaderUtilities'\nimport { BulkFileDataManager } from '../util/BulkFileDataManager'\nimport { BulkFilesReaderStorage } from '../util/BulkFilesReader'\n\n/**\n * Required interface methods of a Chaintracks Storage Engine implementation.\n */\nexport abstract class ChaintracksStorageBase implements ChaintracksStorageQueryApi, ChaintracksStorageIngestApi {\n  static createStorageBaseOptions (chain: Chain): ChaintracksStorageBaseOptions {\n    const options: ChaintracksStorageBaseOptions = {\n      chain,\n      liveHeightThreshold: 2000,\n      reorgHeightThreshold: 400,\n      bulkMigrationChunkSize: 500,\n      batchInsertLimit: 400,\n      bulkFileDataManager: undefined\n    }\n    return options\n  }\n\n  log: (...args: any[]) => void = () => {}\n\n  chain: Chain\n  liveHeightThreshold: number\n  reorgHeightThreshold: number\n  bulkMigrationChunkSize: number\n  batchInsertLimit: number\n\n  isAvailable: boolean = false\n  hasMigrated: boolean = false\n  bulkManager: BulkFileDataManager\n\n  constructor (options: ChaintracksStorageBaseOptions) {\n    this.chain = options.chain\n    this.liveHeightThreshold = options.liveHeightThreshold\n    this.reorgHeightThreshold = options.reorgHeightThreshold\n    this.bulkMigrationChunkSize = options.bulkMigrationChunkSize\n    this.batchInsertLimit = options.batchInsertLimit\n    this.bulkManager =\n      options.bulkFileDataManager || new BulkFileDataManager(BulkFileDataManager.createDefaultOptions(this.chain))\n  }\n\n  async shutdown (): Promise<void> {\n    /* base class does notning */\n  }\n\n  async makeAvailable (): Promise<void> {\n    if (this.isAvailable) return\n    this.isAvailable = true\n  }\n\n  async migrateLatest (): Promise<void> {\n    this.hasMigrated = true\n  }\n\n  async dropAllData (): Promise<void> {\n    await this.bulkManager.deleteBulkFiles()\n    await this.makeAvailable()\n  }\n\n  // Abstract functions to be defined by implementation classes\n\n  abstract deleteLiveBlockHeaders (): Promise<void>\n  abstract deleteOlderLiveBlockHeaders (maxHeight: number): Promise<number>\n  abstract findChainTipHeader (): Promise<LiveBlockHeader>\n  abstract findChainTipHeaderOrUndefined (): Promise<LiveBlockHeader | undefined>\n  abstract findLiveHeaderForBlockHash (hash: string): Promise<LiveBlockHeader | null>\n  abstract findLiveHeaderForHeaderId (headerId: number): Promise<LiveBlockHeader>\n  abstract findLiveHeaderForHeight (height: number): Promise<LiveBlockHeader | null>\n  abstract findLiveHeaderForMerkleRoot (merkleRoot: string): Promise<LiveBlockHeader | null>\n  abstract findLiveHeightRange (): Promise<HeightRange>\n  abstract findMaxHeaderId (): Promise<number>\n  abstract liveHeadersForBulk (count: number): Promise<LiveBlockHeader[]>\n  abstract getLiveHeaders (range: HeightRange): Promise<LiveBlockHeader[]>\n\n  /**\n   * @param header Header to attempt to add to live storage.\n   * @returns details of conditions found attempting to insert header\n   */\n  abstract insertHeader (header: BlockHeader): Promise<InsertHeaderResult>\n  abstract destroy (): Promise<void>\n\n  // BASE CLASS IMPLEMENTATIONS - MAY BE OVERRIDEN\n\n  async getBulkHeaders (range: HeightRange): Promise<Uint8Array> {\n    if (range.isEmpty) return new Uint8Array()\n\n    const fetch = this.bulkManager.fetch\n    const reader = await BulkFilesReaderStorage.fromStorage(this, fetch, range, range.length * 80)\n    const data = await reader.read()\n    if (data == null) return new Uint8Array()\n    return data\n  }\n\n  async getHeadersUint8Array (height: number, count: number): Promise<Uint8Array> {\n    if (count <= 0) return new Uint8Array()\n    const ranges = await this.getAvailableHeightRanges()\n    const range = new HeightRange(height, height + count - 1)\n    const bulkRange = ranges.bulk.intersect(range)\n    const liveRange = ranges.live.intersect(range)\n\n    if (liveRange.isEmpty && bulkRange.isEmpty) return new Uint8Array()\n\n    const liveHeaders = await this.getLiveHeaders(liveRange)\n    const liveData = serializeBaseBlockHeaders(liveHeaders)\n    const bulkData = await this.getBulkHeaders(bulkRange)\n\n    const data = new Uint8Array(liveData.length + bulkData.length)\n\n    if (bulkData.length > 0) data.set(bulkData, 0)\n\n    if (liveData.length > 0) data.set(liveData, bulkData.length)\n\n    return data\n  }\n\n  async getHeaders (height: number, count: number): Promise<BaseBlockHeader[]> {\n    const data = await this.getHeadersUint8Array(height, count)\n    const headers = deserializeBaseBlockHeaders(data)\n    return headers\n  }\n\n  async deleteBulkBlockHeaders (): Promise<void> {\n    await this.bulkManager.deleteBulkFiles()\n  }\n\n  async getAvailableHeightRanges (): Promise<{ bulk: HeightRange, live: HeightRange }> {\n    await this.makeAvailable()\n    const bulk = await this.bulkManager.getHeightRange()\n    const live = await this.findLiveHeightRange()\n    if (bulk.isEmpty) {\n      if (!live.isEmpty && live.minHeight !== 0) { throw new Error('With empty bulk storage, live storage must start with genesis header.') }\n    } else {\n      if (!bulk.isEmpty && bulk.minHeight != 0) throw new Error(\"Bulk storage doesn't start with genesis header.\")\n      if (!live.isEmpty && !bulk.isEmpty && bulk.maxHeight + 1 !== live.minHeight) { throw new Error('There is a gap or overlap between bulk and live header storage.') }\n    }\n    return { bulk, live }\n  }\n\n  private lastActiveMinHeight: number | undefined\n\n  async pruneLiveBlockHeaders (activeTipHeight: number): Promise<void> {\n    await this.makeAvailable()\n    try {\n      const minHeight = this.lastActiveMinHeight || (await this.findLiveHeightRange()).minHeight\n\n      let totalCount = activeTipHeight - minHeight + 1 - this.liveHeightThreshold\n      while (totalCount >= this.bulkMigrationChunkSize) {\n        const count = Math.min(totalCount, this.bulkMigrationChunkSize)\n        await this.migrateLiveToBulk(count)\n        totalCount -= count\n        this.lastActiveMinHeight = undefined\n      }\n    } catch (err: unknown) {\n      this.log(err)\n      throw err\n    }\n  }\n\n  async findChainTipHash (): Promise<string> {\n    await this.makeAvailable()\n    const tip = await this.findChainTipHeader()\n    return tip.hash\n  }\n\n  async findChainTipWork (): Promise<string> {\n    await this.makeAvailable()\n    const tip = await this.findChainTipHeader()\n    return tip.chainWork\n  }\n\n  async findChainWorkForBlockHash (hash: string): Promise<string> {\n    await this.makeAvailable()\n    const header = await this.findLiveHeaderForBlockHash(hash)\n    if (header !== null) return header.chainWork\n    throw new Error(`Header with hash of ${hash} was not found in the live headers database.`)\n  }\n\n  async findBulkFilesHeaderForHeightOrUndefined (height: number): Promise<BlockHeader | undefined> {\n    await this.makeAvailable()\n    return await this.bulkManager.findHeaderForHeightOrUndefined(height)\n  }\n\n  async findHeaderForHeightOrUndefined (height: number): Promise<LiveBlockHeader | BlockHeader | undefined> {\n    await this.makeAvailable()\n    if (Number.isNaN(height) || height < 0 || Math.ceil(height) !== height) { throw new WERR_INVALID_PARAMETER('height', `a non-negative integer (${height}).`) }\n    const liveHeader = await this.findLiveHeaderForHeight(height)\n    if (liveHeader !== null) return liveHeader\n    const header = await this.findBulkFilesHeaderForHeightOrUndefined(height)\n    return header\n  }\n\n  async findHeaderForHeight (height: number): Promise<LiveBlockHeader | BlockHeader> {\n    await this.makeAvailable()\n    const header = await this.findHeaderForHeightOrUndefined(height)\n    if (header != null) return header\n    throw new Error(`Header with height of ${height} was not found.`)\n  }\n\n  async isMerkleRootActive (merkleRoot: string): Promise<boolean> {\n    await this.makeAvailable()\n    const header = await this.findLiveHeaderForMerkleRoot(merkleRoot)\n    return header?.isActive ?? false\n  }\n\n  async findCommonAncestor (header1: LiveBlockHeader, header2: LiveBlockHeader): Promise<LiveBlockHeader> {\n    await this.makeAvailable()\n    /* eslint no-constant-condition: [\"error\", { \"checkLoops\": false }] */\n    while (true) {\n      if (header1.previousHeaderId === null || header2.previousHeaderId === null) { throw new Error('Reached start of live database without resolving the reorg.') }\n      if (header1.previousHeaderId === header2.previousHeaderId) { return await this.findLiveHeaderForHeaderId(header1.previousHeaderId) }\n      const backupHeader1 = header1.height >= header2.height\n      if (header2.height >= header1.height) header2 = await this.findLiveHeaderForHeaderId(header2.previousHeaderId)\n      if (backupHeader1) header1 = await this.findLiveHeaderForHeaderId(header1.previousHeaderId)\n    }\n  }\n\n  async findReorgDepth (header1: LiveBlockHeader, header2: LiveBlockHeader): Promise<number> {\n    await this.makeAvailable()\n    const ancestor = await this.findCommonAncestor(header1, header2)\n    return Math.max(header1.height, header2.height) - ancestor.height\n  }\n\n  private nowMigratingLiveToBulk = false\n\n  async migrateLiveToBulk (count: number, ignoreLimits = false): Promise<void> {\n    await this.makeAvailable()\n    if (!ignoreLimits && count > this.bulkMigrationChunkSize) return\n\n    if (this.nowMigratingLiveToBulk) {\n      this.log('Already migrating live to bulk.')\n      return\n    }\n\n    try {\n      this.nowMigratingLiveToBulk = true\n\n      const headers = await this.liveHeadersForBulk(count)\n\n      await this.addLiveHeadersToBulk(headers)\n\n      await this.deleteOlderLiveBlockHeaders(headers.at(-1)!.height)\n    } finally {\n      this.nowMigratingLiveToBulk = false\n    }\n  }\n\n  async addBulkHeaders (\n    headers: BlockHeader[],\n    bulkRange: HeightRange,\n    priorLiveHeaders: BlockHeader[]\n  ): Promise<BlockHeader[]> {\n    await this.makeAvailable()\n\n    if (!headers || headers.length === 0) return priorLiveHeaders\n\n    // Get the current extent of validated bulk and live block headers.\n    const before = await this.getAvailableHeightRanges()\n\n    // Review `headers`, applying the following rules:\n    // 1. Height must be outside the current bulk HeightRange.\n    // 2. Height must not exceed presentHeight - liveHeightThreshold. If presentHeight is unknown, use maximum height across all headers.\n    // 3. Compute chainWork for each header.\n    // 4. Verify chain of header hash and previousHash values. One header at each height. Retain chain with most chainWork.\n\n    const minHeight = this.getMinimumBulkHeaderHeight(before.bulk, bulkRange)\n    const filteredHeaders = headers.concat(priorLiveHeaders || []).filter(h => h.height >= minHeight)\n    const sortedHeaders = [...filteredHeaders]\n    sortedHeaders.sort((a, b) => a.height - b.height)\n    const liveHeaders = sortedHeaders.filter(h => bulkRange.isEmpty || !bulkRange.contains(h.height))\n\n    if (liveHeaders.length === sortedHeaders.length) {\n      // All headers are live, no bulk headers to add.\n      return liveHeaders\n    }\n\n    const chains = this.buildBulkHeaderChains(sortedHeaders, bulkRange)\n    const bestChain = chains.reduce(\n      (best, chain) => isMoreWork(chain.chainWork, best.chainWork) ? chain : best,\n      chains[0]\n    )\n    const newBulkHeaderCount = bulkRange.maxHeight - bestChain.headers[0].height + 1\n    const newBulkHeaders = bestChain.headers.slice(0, newBulkHeaderCount)\n\n    await this.addBulkHeadersFromBestChain(newBulkHeaders, bestChain)\n\n    return liveHeaders\n  }\n\n  private getMinimumBulkHeaderHeight (availableBulk: HeightRange, requestedBulk: HeightRange): number {\n    if (!requestedBulk.isEmpty) return requestedBulk.minHeight\n    return availableBulk.isEmpty ? 0 : availableBulk.maxHeight + 1\n  }\n\n  private buildBulkHeaderChains (\n    sortedHeaders: BlockHeader[],\n    bulkRange: HeightRange\n  ): AddBulkHeadersChain[] {\n    const chains: AddBulkHeadersChain[] = []\n    for (const header of sortedHeaders) {\n      this.addHeaderToBulkChains(chains, header, bulkRange)\n    }\n    return chains\n  }\n\n  private addHeaderToBulkChains (\n    chains: AddBulkHeadersChain[],\n    header: BlockHeader,\n    bulkRange: HeightRange\n  ): void {\n    const duplicate = chains.some(chain => chain.headers.at(-1)!.hash === header.hash)\n    if (duplicate) return\n\n    const headerWork = convertBitsToWork(header.bits)\n    const extendedChain = chains.find(chain => {\n      const tip = chain.headers.at(-1)!\n      return tip.height + 1 === header.height && tip.hash === header.previousHash\n    })\n    if (extendedChain != null) {\n      extendedChain.headers.push(header)\n      extendedChain.chainWork = addWork(extendedChain.chainWork, headerWork)\n      if (header.height <= bulkRange.maxHeight) {\n        extendedChain.bulkChainWork = extendedChain.chainWork\n      }\n      return\n    }\n\n    // Sorted headers may branch from the parent of an existing chain tip.\n    const forkedChain = chains.find(chain => {\n      const parent = chain.headers.at(-2)!\n      return parent.height + 1 === header.height && parent.hash === header.previousHash\n    })\n    if (forkedChain != null) {\n      const forkHeaders = forkedChain.headers.slice(0, -1)\n      forkHeaders.push(header)\n      const replacedTipWork = convertBitsToWork(forkedChain.headers.at(-1)!.bits)\n      const forkWork = addWork(subWork(forkedChain.chainWork, replacedTipWork), headerWork)\n      chains.push({\n        headers: forkHeaders,\n        chainWork: forkWork,\n        bulkChainWork: header.height <= bulkRange.maxHeight ? forkWork : undefined\n      })\n      return\n    }\n\n    chains.push({\n      headers: [header],\n      chainWork: headerWork,\n      bulkChainWork: header.height <= bulkRange.maxHeight ? headerWork : undefined\n    })\n  }\n\n  private async addBulkHeadersFromBestChain (newBulkHeaders: BlockHeader[], bestChain: AddBulkHeadersChain) {\n    if (!bestChain.bulkChainWork) {\n      throw new WERR_INTERNAL(\n        `bulkChainWork is not defined for the best chain with height ${bestChain.headers[0].height}`\n      )\n    }\n    await this.bulkManager.mergeIncrementalBlockHeaders(newBulkHeaders, bestChain.bulkChainWork)\n  }\n\n  private async addLiveHeadersToBulk (liveHeaders: LiveBlockHeader[]) {\n    if (liveHeaders.length === 0) return\n    const lastChainWork = liveHeaders.at(-1)!.chainWork\n    const firstHeader = liveHeaders[0]\n    const previousWork = subWork(firstHeader.chainWork, convertBitsToWork(liveHeaders[0].bits))\n    const incrementalWork = subWork(lastChainWork, previousWork)\n    await this.bulkManager.mergeIncrementalBlockHeaders(liveHeaders, incrementalWork)\n  }\n}\n\ninterface AddBulkHeadersChain {\n  headers: BlockHeader[]\n  /**\n   * Total chainwork of headers.\n   */\n  chainWork: string\n  /**\n   * Total chainwork of headers with height not greater than maxBulkHeight.\n   */\n  bulkChainWork?: string\n}\n","import { ChaintracksStorageBaseOptions, InsertHeaderResult } from '../Api/ChaintracksStorageApi'\nimport { ChaintracksStorageBase } from '../Storage/ChaintracksStorageBase'\nimport { LiveBlockHeader } from '../Api/BlockHeaderApi'\nimport { addWork, convertBitsToWork, isMoreWork } from '../util/blockHeaderUtilities'\n\nimport { HeightRange } from '../util/HeightRange'\nimport { Chain } from '../../../../sdk/types'\nimport { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../../../sdk/WERR_errors'\nimport { BlockHeader } from '../../../../sdk/WalletServices.interfaces'\n\ninterface ChaintracksNoDbData {\n  chain: Chain\n  liveHeaders: Map<number, LiveBlockHeader>\n  maxHeaderId: number\n  tipHeaderId: number\n  hashToHeaderId: Map<string, number>\n}\n\nexport interface ChaintracksStorageNoDbOptions extends ChaintracksStorageBaseOptions {}\n\nfunction createInsertHeaderResult(): InsertHeaderResult {\n  return {\n    added: false,\n    dupe: false,\n    noPrev: false,\n    badPrev: false,\n    noActiveAncestor: false,\n    isActiveTip: false,\n    reorgDepth: 0,\n    priorTip: undefined,\n    noTip: false,\n    deactivatedHeaders: []\n  }\n}\n\nexport class ChaintracksStorageNoDb extends ChaintracksStorageBase {\n  static readonly mainData: ChaintracksNoDbData = {\n    chain: 'main',\n    liveHeaders: new Map<number, LiveBlockHeader>(),\n    maxHeaderId: 0,\n    tipHeaderId: 0,\n    hashToHeaderId: new Map<string, number>()\n  }\n\n  static readonly testData: ChaintracksNoDbData = {\n    chain: 'test',\n    liveHeaders: new Map<number, LiveBlockHeader>(),\n    maxHeaderId: 0,\n    tipHeaderId: 0,\n    hashToHeaderId: new Map<string, number>()\n  }\n\n  static readonly stnData: ChaintracksNoDbData = {\n    chain: 'stn',\n    liveHeaders: new Map<number, LiveBlockHeader>(),\n    maxHeaderId: 0,\n    tipHeaderId: 0,\n    hashToHeaderId: new Map<string, number>()\n  }\n\n  static readonly ttnData: ChaintracksNoDbData = {\n    chain: 'ttn',\n    liveHeaders: new Map<number, LiveBlockHeader>(),\n    maxHeaderId: 0,\n    tipHeaderId: 0,\n    hashToHeaderId: new Map<string, number>()\n  }\n\n  static readonly tstnData: ChaintracksNoDbData = {\n    chain: 'tstn',\n    liveHeaders: new Map<number, LiveBlockHeader>(),\n    maxHeaderId: 0,\n    tipHeaderId: 0,\n    hashToHeaderId: new Map<string, number>()\n  }\n\n  constructor(options: ChaintracksStorageNoDbOptions) {\n    super(options)\n  }\n\n  override async destroy(): Promise<void> {\n    /* intentional no-op: in-memory storage has no cleanup */\n  }\n\n  async getData(): Promise<ChaintracksNoDbData> {\n    switch (this.chain) {\n      case 'main':\n        return ChaintracksStorageNoDb.mainData\n      case 'test':\n        return ChaintracksStorageNoDb.testData\n      case 'stn':\n        return ChaintracksStorageNoDb.stnData\n      case 'ttn':\n        return ChaintracksStorageNoDb.ttnData\n      case 'tstn':\n        return ChaintracksStorageNoDb.tstnData\n      default:\n        throw new WERR_INVALID_PARAMETER(\n          'chain',\n          `'main', 'test', 'stn', 'ttn', or 'tstn'. '${this.chain}' is unsupported.`\n        )\n    }\n  }\n\n  override async deleteLiveBlockHeaders(): Promise<void> {\n    const data = await this.getData()\n    data.liveHeaders.clear()\n    data.maxHeaderId = 0\n    data.tipHeaderId = 0\n    data.hashToHeaderId.clear()\n  }\n\n  override async deleteOlderLiveBlockHeaders(maxHeight: number): Promise<number> {\n    const data = await this.getData()\n    let deletedCount = 0\n\n    // Clear previousHeaderId references\n    for (const [headerId, header] of data.liveHeaders) {\n      if (header.previousHeaderId) {\n        const prevHeader = data.liveHeaders.get(header.previousHeaderId)\n        if (prevHeader != null && prevHeader.height <= maxHeight) {\n          data.liveHeaders.set(headerId, { ...header, previousHeaderId: null })\n        }\n      }\n    }\n\n    // Delete headers up to maxHeight\n    const headersToDelete = new Set<number>()\n    for (const [headerId, header] of data.liveHeaders) {\n      if (header.height <= maxHeight) {\n        headersToDelete.add(headerId)\n        data.hashToHeaderId.delete(header.hash)\n      }\n    }\n    deletedCount = headersToDelete.size\n    for (const headerId of headersToDelete) {\n      data.liveHeaders.delete(headerId)\n    }\n\n    // Update tipHeaderId if necessary\n    if (data.liveHeaders.size > 0) {\n      const tip = Array.from(data.liveHeaders.values()).find(h => h.isActive && h.isChainTip)\n      data.tipHeaderId = tip?.headerId ?? 0\n    } else {\n      data.tipHeaderId = 0\n    }\n\n    return deletedCount\n  }\n\n  override async findChainTipHeader(): Promise<LiveBlockHeader> {\n    const data = await this.getData()\n    const tip = Array.from(data.liveHeaders.values()).find(h => h.isActive && h.isChainTip)\n    if (tip == null) throw new Error('Database contains no active chain tip header.')\n    return tip\n  }\n\n  override async findChainTipHeaderOrUndefined(): Promise<LiveBlockHeader | undefined> {\n    const data = await this.getData()\n    return Array.from(data.liveHeaders.values()).find(h => h.isActive && h.isChainTip)\n  }\n\n  override async findLiveHeaderForBlockHash(hash: string): Promise<LiveBlockHeader | null> {\n    const data = await this.getData()\n    const headerId = data.hashToHeaderId.get(hash)\n    return headerId ? data.liveHeaders.get(headerId) || null : null\n  }\n\n  override async findLiveHeaderForHeaderId(headerId: number): Promise<LiveBlockHeader> {\n    const data = await this.getData()\n    const header = data.liveHeaders.get(headerId)\n    if (header == null) throw new Error(`HeaderId ${headerId} not found in live header database.`)\n    return header\n  }\n\n  override async findLiveHeaderForHeight(height: number): Promise<LiveBlockHeader | null> {\n    const data = await this.getData()\n    return Array.from(data.liveHeaders.values()).find(h => h.height === height && h.isActive) || null\n  }\n\n  override async findLiveHeaderForMerkleRoot(merkleRoot: string): Promise<LiveBlockHeader | null> {\n    const data = await this.getData()\n    return Array.from(data.liveHeaders.values()).find(h => h.merkleRoot === merkleRoot) || null\n  }\n\n  override async findLiveHeightRange(): Promise<HeightRange> {\n    const data = await this.getData()\n    const activeHeaders = Array.from(data.liveHeaders.values()).filter(h => h.isActive)\n    if (activeHeaders.length === 0) {\n      return HeightRange.empty\n    }\n    const minHeight = Math.min(...activeHeaders.map(h => h.height))\n    const maxHeight = Math.max(...activeHeaders.map(h => h.height))\n    return new HeightRange(minHeight, maxHeight)\n  }\n\n  override async findMaxHeaderId(): Promise<number> {\n    const data = await this.getData()\n    return data.maxHeaderId\n  }\n\n  override async liveHeadersForBulk(count: number): Promise<LiveBlockHeader[]> {\n    const data = await this.getData()\n    return Array.from(data.liveHeaders.values())\n      .filter(h => h.isActive)\n      .sort((a, b) => a.height - b.height)\n      .slice(0, count)\n  }\n\n  override async getLiveHeaders(range: HeightRange): Promise<LiveBlockHeader[]> {\n    if (range.isEmpty) return []\n    const data = await this.getData()\n    const headers = Array.from(data.liveHeaders.values())\n      .filter(h => h.isActive && h.height >= range.minHeight && h.height <= range.maxHeight)\n      .sort((a, b) => a.height - b.height)\n    return headers\n  }\n\n  private async insertFirstHeader(\n    data: ChaintracksNoDbData,\n    header: BlockHeader,\n    result: InsertHeaderResult\n  ): Promise<boolean> {\n    if (data.liveHeaders.size !== 0) return false\n    const lastBulkFile = await this.bulkManager.getLastFile()\n    if (lastBulkFile == null) {\n      throw new WERR_INVALID_OPERATION('bulk headers must exist before first live header can be added')\n    }\n    if (\n      header.previousHash !== lastBulkFile.lastHash ||\n      header.height !== lastBulkFile.firstHeight + lastBulkFile.count\n    ) {\n      return false\n    }\n    const newHeader: LiveBlockHeader = {\n      ...header,\n      headerId: ++data.maxHeaderId,\n      previousHeaderId: null,\n      chainWork: addWork(lastBulkFile.lastChainWork, convertBitsToWork(header.bits)),\n      isChainTip: true,\n      isActive: true\n    }\n    data.liveHeaders.set(newHeader.headerId, newHeader)\n    data.hashToHeaderId.set(header.hash, newHeader.headerId)\n    data.tipHeaderId = newHeader.headerId\n    result.isActiveTip = true\n    result.added = true\n    return true\n  }\n\n  private findActiveAncestor(\n    data: ChaintracksNoDbData,\n    oneBack: LiveBlockHeader,\n    result: InsertHeaderResult\n  ): LiveBlockHeader | undefined {\n    let activeAncestor = oneBack\n    while (!activeAncestor.isActive) {\n      const previousHeader = data.liveHeaders.get(activeAncestor.previousHeaderId!)\n      if (previousHeader == null) {\n        result.noActiveAncestor = true\n        return undefined\n      }\n      activeAncestor = previousHeader\n    }\n    return activeAncestor\n  }\n\n  private applyReorganization(\n    data: ChaintracksNoDbData,\n    oneBack: LiveBlockHeader,\n    activeAncestor: LiveBlockHeader,\n    result: InsertHeaderResult\n  ): void {\n    if (activeAncestor.headerId === oneBack.headerId) return\n    let headerToDeactivate = Array.from(data.liveHeaders.values()).find(\n      candidate => candidate.isChainTip && candidate.isActive\n    )\n    while (headerToDeactivate != null && headerToDeactivate.headerId !== activeAncestor.headerId) {\n      result.deactivatedHeaders.push(headerToDeactivate)\n      data.liveHeaders.set(headerToDeactivate.headerId, {\n        ...headerToDeactivate,\n        isActive: false\n      })\n      headerToDeactivate = data.liveHeaders.get(headerToDeactivate.previousHeaderId!)\n    }\n    let headerToActivate = oneBack\n    while (headerToActivate.headerId !== activeAncestor.headerId) {\n      data.liveHeaders.set(headerToActivate.headerId, {\n        ...headerToActivate,\n        isActive: true\n      })\n      headerToActivate = data.liveHeaders.get(headerToActivate.previousHeaderId!)!\n    }\n  }\n\n  private prepareActiveTip(\n    data: ChaintracksNoDbData,\n    header: BlockHeader,\n    oneBack: LiveBlockHeader,\n    result: InsertHeaderResult\n  ): boolean {\n    if (!result.isActiveTip) return true\n    const activeAncestor = this.findActiveAncestor(data, oneBack, result)\n    if (activeAncestor == null) return false\n    if (!(oneBack.isActive && oneBack.isChainTip)) {\n      result.reorgDepth = Math.min(result.priorTip!.height, header.height) - activeAncestor.height\n    }\n    this.applyReorganization(data, oneBack, activeAncestor, result)\n    return true\n  }\n\n  override async insertHeader(header: BlockHeader): Promise<InsertHeaderResult> {\n    const data = await this.getData()\n    const r = createInsertHeaderResult()\n\n    // Check for duplicate\n    if (data.hashToHeaderId.has(header.hash)) {\n      r.dupe = true\n      return r\n    }\n\n    // Find previous header\n    const oneBack = Array.from(data.liveHeaders.values()).find(h => h.hash === header.previousHash)\n\n    if (oneBack == null) {\n      if (await this.insertFirstHeader(data, header, r)) return r\n      r.noPrev = true\n      return r\n    }\n\n    // This header's previousHash matches an existing live header's hash, if height isn't +1, reject it.\n    if (oneBack.height + 1 !== header.height) {\n      r.badPrev = true\n      return r\n    }\n\n    r.priorTip =\n      oneBack.isActive && oneBack.isChainTip\n        ? oneBack\n        : Array.from(data.liveHeaders.values()).find(h => h.isActive && h.isChainTip)\n\n    if (r.priorTip == null) {\n      // No active chain tip found. This is a logic error in state of live headers.\n      r.noTip = true\n      return r\n    }\n\n    // We have an acceptable new live header...and live headers has an active chain tip.\n\n    const chainWork = addWork(oneBack.chainWork, convertBitsToWork(header.bits))\n\n    r.isActiveTip = isMoreWork(chainWork, r.priorTip.chainWork)\n\n    const newHeader = {\n      ...header,\n      headerId: ++data.maxHeaderId,\n      previousHeaderId: oneBack.headerId,\n      chainWork,\n      isChainTip: r.isActiveTip,\n      isActive: r.isActiveTip\n    }\n\n    if (!this.prepareActiveTip(data, header, oneBack, r)) return r\n\n    if (oneBack.isChainTip) {\n      data.liveHeaders.set(oneBack.headerId, { ...oneBack, isChainTip: false })\n    }\n\n    data.liveHeaders.set(newHeader.headerId, newHeader)\n    data.hashToHeaderId.set(newHeader.hash, newHeader.headerId)\n    r.added = true\n\n    if (r.added && r.isActiveTip) {\n      data.tipHeaderId = newHeader.headerId\n      this.pruneLiveBlockHeaders(newHeader.height)\n    }\n\n    return r\n  }\n}\n","import {\n  ChaintracksStorageBaseOptions,\n  ChaintracksStorageBulkFileApi,\n  InsertHeaderResult\n} from '../Api/ChaintracksStorageApi'\nimport { ChaintracksStorageBase } from './ChaintracksStorageBase'\nimport { LiveBlockHeader } from '../Api/BlockHeaderApi'\nimport { addWork, convertBitsToWork, isMoreWork } from '../util/blockHeaderUtilities'\n\nimport { HeightRange } from '../util/HeightRange'\nimport { WERR_INVALID_OPERATION, WERR_INVALID_PARAMETER } from '../../../../sdk/WERR_errors'\nimport { BlockHeader } from '../../../../sdk/WalletServices.interfaces'\nimport { IDBPDatabase, IDBPTransaction, openDB } from 'idb'\n\nimport { BulkHeaderFileInfo } from '../util/BulkHeaderFile'\n\nexport interface ChaintracksStorageIdbOptions extends ChaintracksStorageBaseOptions {}\n\ntype IdbWriteTransaction = IDBPTransaction<ChaintracksStorageIdbSchema, string[], 'readwrite'>\n\nfunction createInsertHeaderResult(): InsertHeaderResult {\n  return {\n    added: false,\n    dupe: false,\n    noPrev: false,\n    badPrev: false,\n    noActiveAncestor: false,\n    isActiveTip: false,\n    reorgDepth: 0,\n    priorTip: undefined,\n    noTip: false,\n    deactivatedHeaders: []\n  }\n}\n\nexport class ChaintracksStorageIdb extends ChaintracksStorageBase implements ChaintracksStorageBulkFileApi {\n  dbName: string\n\n  db?: IDBPDatabase<ChaintracksStorageIdbSchema>\n\n  whenLastAccess?: Date\n\n  allStores: string[] = ['live_headers', 'bulk_headers']\n\n  constructor(options: ChaintracksStorageIdbOptions) {\n    super(options)\n    this.dbName = `chaintracks-${this.chain}net`\n  }\n\n  override async makeAvailable(): Promise<void> {\n    if (this.isAvailable && this.hasMigrated) return\n    // Not a base class policy, but we want to ensure migrations are run before getting to business.\n    if (!this.hasMigrated) {\n      await this.migrateLatest()\n    }\n    if (!this.isAvailable) {\n      await super.makeAvailable()\n      // Connect the bulk data file manager to the table provided by this storage class.\n      await this.bulkManager.setStorage(this, this.log)\n    }\n  }\n\n  override async migrateLatest(): Promise<void> {\n    if (this.db != null) return\n    this.db = await this.initDB()\n    await super.migrateLatest()\n  }\n\n  override async destroy(): Promise<void> {\n    /* intentional no-op: IDB cleanup handled by openDB */\n  }\n\n  override async deleteLiveBlockHeaders(): Promise<void> {\n    await this.makeAvailable()\n    await this.db?.clear('live_headers')\n  }\n\n  /**\n   * Delete live headers with height less or equal to `maxHeight`\n   *\n   * Set existing headers with previousHeaderId value set to the headerId value of\n   * a header which is to be deleted to null.\n   *\n   * @param maxHeight delete all records with less or equal `height`\n   * @returns number of deleted records\n   */\n  override async deleteOlderLiveBlockHeaders(maxHeight: number): Promise<number> {\n    await this.makeAvailable()\n\n    const trx = this.toDbTrxReadWrite(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    const heightIndex = store.index('height')\n    const previousHeaderIdIndex = store.index('previousHeaderId')\n\n    // Get all headers with height <= maxHeight\n    const range = IDBKeyRange.upperBound(maxHeight)\n    const headersToDelete: LiveBlockHeader[] = await heightIndex.getAll(range)\n    const headerIdsToDelete = new Set(headersToDelete.map(header => header.headerId))\n    const deletedCount = headersToDelete.length\n\n    for (const id of headerIdsToDelete) {\n      const headerToUpdate = await previousHeaderIdIndex.get(id)\n      await store.put({ ...headerToUpdate, previousHeaderId: null })\n    }\n\n    // Delete the headers\n    for (const id of headerIdsToDelete) {\n      await store.delete(id)\n    }\n\n    await trx.done\n    return deletedCount\n  }\n\n  /**\n   * @returns the active chain tip header\n   * @throws an error if there is no tip.\n   */\n  override async findChainTipHeader(): Promise<LiveBlockHeader> {\n    const header = await this.findChainTipHeaderOrUndefined()\n    if (header == null) throw new Error('Database contains no active chain tip header.')\n    return header\n  }\n\n  /**\n   *\n   * @returns the active chain tip header\n   * @throws an error if there is no tip.\n   */\n  override async findChainTipHeaderOrUndefined(): Promise<LiveBlockHeader | undefined> {\n    await this.makeAvailable()\n    const trx = this.toDbTrxReadOnly(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    const activeTipIndex = store.index('activeTip')\n    let header = await activeTipIndex.get([1, 1])\n    header = this.repairStoredLiveHeader(header)\n    await trx.done\n    return header\n  }\n\n  override async findLiveHeaderForBlockHash(hash: string): Promise<LiveBlockHeader | null> {\n    await this.makeAvailable()\n    const trx = this.toDbTrxReadOnly(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    const hashIndex = store.index('hash')\n    let header = await hashIndex.get(hash)\n    header = this.repairStoredLiveHeader(header)\n    await trx.done\n    return header\n  }\n\n  override async findLiveHeaderForHeaderId(headerId: number): Promise<LiveBlockHeader> {\n    await this.makeAvailable()\n    const trx = this.toDbTrxReadOnly(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    let header = await store.get(headerId)\n    header = this.repairStoredLiveHeader(header)\n    await trx.done\n    return header\n  }\n\n  override async findLiveHeaderForHeight(height: number): Promise<LiveBlockHeader | null> {\n    await this.makeAvailable()\n    const trx = this.toDbTrxReadOnly(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    const heightIndex = store.index('height')\n    let header = await heightIndex.get(height)\n    header = this.repairStoredLiveHeader(header)\n    await trx.done\n    return header || null\n  }\n\n  override async findLiveHeaderForMerkleRoot(merkleRoot: string): Promise<LiveBlockHeader | null> {\n    await this.makeAvailable()\n    const trx = this.toDbTrxReadOnly(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    const merkleRootIndex = store.index('merkleRoot')\n    let header = await merkleRootIndex.get(merkleRoot)\n    header = this.repairStoredLiveHeader(header)\n    await trx.done\n    return header || null\n  }\n\n  override async findLiveHeightRange(): Promise<HeightRange> {\n    await this.makeAvailable()\n    const trx = this.toDbTrxReadOnly(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    const heightIndex = store.index('height')\n\n    const minCursor = await heightIndex.openCursor(null, 'next')\n    const minValue = minCursor?.value.height ?? null\n\n    const maxCursor = await heightIndex.openCursor(null, 'prev')\n    const maxValue = maxCursor?.value.height ?? null\n\n    const range = minValue === null || maxValue === null ? HeightRange.empty : new HeightRange(minValue, maxValue)\n\n    await trx.done\n    return range\n  }\n\n  override async findMaxHeaderId(): Promise<number> {\n    await this.makeAvailable()\n    const trx = this.toDbTrxReadOnly(['live_headers'])\n    const store = trx.objectStore('live_headers')\n\n    const maxCursor = await store.openKeyCursor(null, 'prev')\n    const maxValue: number = maxCursor != null ? Number(maxCursor.key) : 0\n    await trx.done\n    return maxValue\n  }\n\n  override async liveHeadersForBulk(count: number): Promise<LiveBlockHeader[]> {\n    await this.makeAvailable()\n\n    const trx = this.toDbTrxReadWrite(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    const heightIndex = store.index('height')\n\n    let cursor = await heightIndex.openCursor(null, 'next')\n    const headers: LiveBlockHeader[] = []\n\n    while (cursor != null && count > 0) {\n      const header = this.repairStoredLiveHeader(cursor.value)\n      if (header?.isActive) {\n        count--\n        headers.push(header)\n      }\n      cursor = await cursor.continue()\n    }\n\n    await trx.done\n    return headers\n  }\n\n  override async getLiveHeaders(range: HeightRange): Promise<LiveBlockHeader[]> {\n    if (range.isEmpty) return []\n    await this.makeAvailable()\n\n    const trx = this.toDbTrxReadWrite(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    const heightIndex = store.index('height')\n\n    let cursor = await heightIndex.openCursor(null, 'next')\n    const headers: LiveBlockHeader[] = []\n\n    while (cursor != null) {\n      const header = this.repairStoredLiveHeader(cursor.value)\n      if (header != null && range.contains(header.height)) {\n        headers.push(header)\n      }\n      cursor = await cursor.continue()\n    }\n\n    await trx.done\n    return headers\n  }\n\n  private async insertFirstHeader(\n    trx: IdbWriteTransaction,\n    header: BlockHeader,\n    result: InsertHeaderResult\n  ): Promise<boolean> {\n    const store = trx.objectStore('live_headers')\n    if ((await store.count()) !== 0) return false\n    const lastBulkFile = await this.bulkManager.getLastFile()\n    if (lastBulkFile == null) {\n      throw new WERR_INVALID_OPERATION('bulk headers must exist before first live header can be added')\n    }\n    if (\n      header.previousHash !== lastBulkFile.lastHash ||\n      header.height !== lastBulkFile.firstHeight + lastBulkFile.count\n    ) {\n      return false\n    }\n    const newHeader: LiveBlockHeader = {\n      ...header,\n      headerId: 0,\n      previousHeaderId: null,\n      chainWork: addWork(lastBulkFile.lastChainWork, convertBitsToWork(header.bits)),\n      isChainTip: true,\n      isActive: true\n    }\n    newHeader.headerId = Number(await store.add(this.prepareStoredLiveHeader(newHeader, true)))\n    result.isActiveTip = true\n    result.added = true\n    return true\n  }\n\n  private async findActiveAncestor(\n    trx: IdbWriteTransaction,\n    oneBack: LiveBlockHeader,\n    result: InsertHeaderResult\n  ): Promise<LiveBlockHeader | undefined> {\n    const store = trx.objectStore('live_headers')\n    let activeAncestor = oneBack\n    while (!activeAncestor.isActive) {\n      const previousHeader = this.repairStoredLiveHeader(await store.get(activeAncestor.previousHeaderId!))\n      if (previousHeader == null) {\n        result.noActiveAncestor = true\n        return undefined\n      }\n      activeAncestor = previousHeader\n    }\n    return activeAncestor\n  }\n\n  private async applyReorganization(\n    trx: IdbWriteTransaction,\n    oneBack: LiveBlockHeader,\n    activeAncestor: LiveBlockHeader,\n    result: InsertHeaderResult\n  ): Promise<void> {\n    if (activeAncestor.headerId === oneBack.headerId) return\n    const store = trx.objectStore('live_headers')\n    const activeTipIndex = store.index('activeTip')\n    let headerToDeactivate = this.repairStoredLiveHeader(await activeTipIndex.get([1, 1]))!\n    while (headerToDeactivate != null && headerToDeactivate.headerId !== activeAncestor.headerId) {\n      result.deactivatedHeaders.push(headerToDeactivate)\n      await store.put(\n        this.prepareStoredLiveHeader({\n          ...headerToDeactivate,\n          isActive: false\n        })\n      )\n      headerToDeactivate = this.repairStoredLiveHeader(await store.get(headerToDeactivate.previousHeaderId!))!\n    }\n    let headerToActivate = oneBack\n    while (headerToActivate.headerId !== activeAncestor.headerId) {\n      await store.put(this.prepareStoredLiveHeader({ ...headerToActivate, isActive: true }))\n      headerToActivate = this.repairStoredLiveHeader(await store.get(headerToActivate.previousHeaderId!))!\n    }\n  }\n\n  private async prepareActiveTip(\n    trx: IdbWriteTransaction,\n    header: BlockHeader,\n    oneBack: LiveBlockHeader,\n    result: InsertHeaderResult\n  ): Promise<boolean> {\n    if (!result.isActiveTip) return true\n    const activeAncestor = await this.findActiveAncestor(trx, oneBack, result)\n    if (activeAncestor == null) return false\n    if (!(oneBack.isActive && oneBack.isChainTip)) {\n      result.reorgDepth = Math.min(result.priorTip!.height, header.height) - activeAncestor.height\n    }\n    await this.applyReorganization(trx, oneBack, activeAncestor, result)\n    return true\n  }\n\n  override async insertHeader(header: BlockHeader): Promise<InsertHeaderResult> {\n    await this.makeAvailable()\n\n    const trx = this.toDbTrxReadWrite(['live_headers'])\n    const store = trx.objectStore('live_headers')\n    const hashIndex = store.index('hash')\n    const activeTipIndex = store.index('activeTip')\n\n    const r = createInsertHeaderResult()\n\n    // Check for duplicate\n    if (await hashIndex.get(header.hash)) {\n      r.dupe = true\n      await trx.done\n      return r\n    }\n\n    // let all = await store.getAll()\n    // console.log(`idb store length: ${all.length} last: ${all[all.length - 1]?.height}`)\n    // let allHash = await hashIndex.getAll()\n\n    // Find previous header\n    const oneBack: LiveBlockHeader | undefined = this.repairStoredLiveHeader(await hashIndex.get(header.previousHash))\n\n    if (oneBack == null) {\n      if (await this.insertFirstHeader(trx, header, r)) {\n        await trx.done\n        return r\n      }\n      r.noPrev = true\n      await trx.done\n      return r\n    }\n\n    if (oneBack.isActive && oneBack.isChainTip) {\n      r.priorTip = oneBack\n    } else {\n      r.priorTip = this.repairStoredLiveHeader(await activeTipIndex.get([1, 1]))\n    }\n\n    if (r.priorTip == null) {\n      // No active chain tip found. This is a logic error in state of live headers.\n      r.noTip = true\n      await trx.done\n      return r\n    }\n\n    // We have an acceptable new live header...and live headers has an active chain tip.\n\n    const chainWork = addWork(oneBack.chainWork, convertBitsToWork(header.bits))\n\n    r.isActiveTip = isMoreWork(chainWork, r.priorTip.chainWork)\n\n    const newHeader: LiveBlockHeader = {\n      ...header,\n      headerId: 0,\n      previousHeaderId: oneBack.headerId,\n      chainWork,\n      isChainTip: r.isActiveTip,\n      isActive: r.isActiveTip\n    }\n\n    if (!(await this.prepareActiveTip(trx, header, oneBack, r))) {\n      await trx.done\n      return r\n    }\n\n    if (oneBack.isChainTip) {\n      await store.put(this.prepareStoredLiveHeader({ ...oneBack, isChainTip: false }))\n    }\n\n    await store.put(this.prepareStoredLiveHeader(newHeader, true))\n    r.added = true\n\n    // all = await store.getAll()\n    // console.log(`idb store length: ${all.length} last: ${all[all.length - 1]?.height}`)\n\n    if (r.added && r.isActiveTip) {\n      // this.pruneLiveBlockHeaders(newHeader.height)\n    }\n\n    await trx.done\n    return r\n  }\n\n  async deleteBulkFile(fileId: number): Promise<number> {\n    await this.makeAvailable()\n\n    const trx = this.toDbTrxReadWrite(['bulk_headers'])\n    const store = trx.objectStore('bulk_headers')\n    await store.delete(fileId)\n    await trx.done\n    // return number of records affected\n    return 1\n  }\n\n  async insertBulkFile(file: BulkHeaderFileInfo): Promise<number> {\n    await this.makeAvailable()\n\n    const trx = this.toDbTrxReadWrite(['bulk_headers'])\n    const store = trx.objectStore('bulk_headers')\n    const fileObj: Record<string, unknown> = { ...file }\n    delete fileObj['fileId']\n    file.fileId = Number(await store.put(fileObj))\n    await trx.done\n    return file.fileId\n  }\n\n  async updateBulkFile(fileId: number, file: BulkHeaderFileInfo): Promise<number> {\n    await this.makeAvailable()\n\n    const trx = this.toDbTrxReadWrite(['bulk_headers'])\n    const store = trx.objectStore('bulk_headers')\n    file.fileId = fileId\n    await store.put(file)\n    await trx.done\n    // return number of records affected\n    return 1\n  }\n\n  async getBulkFiles(): Promise<BulkHeaderFileInfo[]> {\n    await this.makeAvailable()\n\n    const trx = this.toDbTrxReadWrite(['bulk_headers'])\n    const store = trx.objectStore('bulk_headers')\n\n    const files: BulkHeaderFileInfo[] = await store.getAll()\n    files.sort((a, b) => a.firstHeight - b.firstHeight)\n    for (const file of files) file.data = undefined\n    return files\n  }\n\n  async getBulkFileData(fileId: number, offset?: number, length?: number): Promise<Uint8Array | undefined> {\n    if (!Number.isInteger(fileId)) throw new WERR_INVALID_PARAMETER('fileId', 'a valid, integer bulk_files fileId')\n    await this.makeAvailable()\n\n    const trx = this.toDbTrxReadWrite(['bulk_headers'])\n    const store = trx.objectStore('bulk_headers')\n\n    const info: BulkHeaderFileInfo | undefined = await store.get(fileId)\n    if (info == null) throw new WERR_INVALID_PARAMETER('fileId', `an existing record. ${fileId} not found`)\n\n    let data: Uint8Array | undefined\n\n    if (info.data == null) return undefined\n\n    if (offset !== undefined && length !== undefined && Number.isInteger(offset) && Number.isInteger(length)) {\n      data = info.data.slice(offset, offset + length)\n    } else {\n      data = info.data\n    }\n    await trx.done\n    return data\n  }\n\n  /**\n   * IndexedDB does not do indices of boolean properties.\n   * So true is stored as a 1, and false is stored as no property value (delete v['property'])\n   *\n   * This function restores these property values to true and false.\n   *\n   * @param header\n   * @returns copy of header with updated properties\n   */\n  private repairStoredLiveHeader(header?: LiveBlockHeader): LiveBlockHeader | undefined {\n    if (header == null) return undefined\n    const h: LiveBlockHeader = {\n      ...header,\n      isActive: !!header.isActive,\n      isChainTip: !!header.isChainTip\n    }\n    return h\n  }\n\n  private prepareStoredLiveHeader(header: LiveBlockHeader, forInsert?: boolean): object {\n    const h: Record<string, unknown> = { ...header }\n    if (forInsert) delete h['headerId']\n\n    if (header.isActive) h['isActive'] = 1\n    else delete h['isActive']\n    if (header.isChainTip) h['isChainTip'] = 1\n    else delete h['isChainTip']\n\n    return h\n  }\n\n  async insertLiveHeader(header: LiveBlockHeader): Promise<LiveBlockHeader> {\n    const trx = this.toDbTrxReadWrite(['live_headers'])\n    const store = trx.objectStore('live_headers')\n\n    const h = this.prepareStoredLiveHeader(header, true)\n\n    header.headerId = Number(await store.add(h))\n\n    await trx.done\n\n    return header\n  }\n\n  async initDB(): Promise<IDBPDatabase<ChaintracksStorageIdbSchema>> {\n    const db = await openDB<ChaintracksStorageIdbSchema>(this.dbName, 1, {\n      upgrade(db, _oldVersion, _newVersion, _transaction) {\n        if (!db.objectStoreNames.contains('live_headers')) {\n          const liveHeadersStore = db.createObjectStore('live_headers', {\n            keyPath: 'headerId',\n            autoIncrement: true\n          })\n          liveHeadersStore.createIndex('hash', 'hash', { unique: true })\n          liveHeadersStore.createIndex('height', 'height', { unique: false })\n          liveHeadersStore.createIndex('previousHeaderId', 'previousHeaderId', { unique: false })\n          liveHeadersStore.createIndex('merkleRoot', 'merkleRoot', { unique: false })\n          liveHeadersStore.createIndex('activeTip', ['isActive', 'isChainTip'], { unique: false })\n        }\n\n        if (!db.objectStoreNames.contains('bulk_headers')) {\n          db.createObjectStore('bulk_headers', {\n            keyPath: 'fileId',\n            autoIncrement: true\n          })\n        }\n      }\n    })\n    return db\n  }\n\n  toDbTrxReadOnly(stores: string[]): IDBPTransaction<ChaintracksStorageIdbSchema, string[], 'readonly'> {\n    if (this.db == null) throw new Error('not initialized')\n    const db = this.db\n    const trx = db.transaction(stores || this.allStores, 'readonly')\n    this.whenLastAccess = new Date()\n    return trx\n  }\n\n  toDbTrxReadWrite(stores: string[]): IDBPTransaction<ChaintracksStorageIdbSchema, string[], 'readwrite'> {\n    if (this.db == null) throw new Error('not initialized')\n    const db = this.db\n    const trx = db.transaction(stores || this.allStores, 'readwrite')\n    this.whenLastAccess = new Date()\n    return trx\n  }\n}\n\nexport interface ChaintracksStorageIdbSchema {\n  liveHeaders: {\n    key: number\n    value: LiveBlockHeader\n    indexes: {\n      hash: string\n      previousHash: string\n      previousHeaderId: number | null\n      isActive: boolean\n      activeTip: [boolean, boolean]\n      height: number\n    }\n  }\n  bulkHeaders: {\n    key: number\n    value: BulkHeaderFileInfo\n    indexes: {\n      firstHeight: number\n    }\n  }\n}\n","import { Chain } from '../../../sdk'\nimport { ChaintracksOptions } from './Api/ChaintracksApi'\nimport { Chaintracks } from './Chaintracks'\nimport { BulkIngestorCDNBabbage } from './Ingest/BulkIngestorCDNBabbage'\nimport { LiveIngestorWhatsOnChainOptions, LiveIngestorWhatsOnChainPoll } from './Ingest/LiveIngestorWhatsOnChainPoll'\nimport { BulkIngestorWhatsOnChainCdn, BulkIngestorWhatsOnChainOptions } from './Ingest/BulkIngestorWhatsOnChainCdn'\nimport { ChaintracksFetchApi } from './Api/ChaintracksFetchApi'\nimport { BulkIngestorCDNOptions } from './Ingest/BulkIngestorCDN'\nimport { WhatsOnChainServicesOptions } from './Ingest/WhatsOnChainServices'\nimport { BulkFileDataManager, BulkFileDataManagerOptions } from './util/BulkFileDataManager'\nimport { ChaintracksFetch } from './util/ChaintracksFetch'\nimport { ChaintracksClientApi } from './Api/ChaintracksClientApi'\nimport { BulkIngestorChaintracks } from './Ingest/BulkIngestorChaintracks'\nimport { LiveIngestorChaintracksSSE } from './Ingest/LiveIngestorChaintracksSSE'\nimport { GoChaintracksServiceClient } from './GoChaintracksServiceClient'\nimport { publicArcadeUrl } from '../../networkConfig'\n\nexport interface ChaintracksSourceOptions {\n  /** Preferred go-chaintracks or Arcade source. */\n  chaintracks?: ChaintracksClientApi\n  /** Disable the credential-free public Arcade default. */\n  disableChaintracks?: boolean\n  /** Maximum number of headers requested from the remote source at once. */\n  remoteMaxHeadersPerRequest?: number\n  /** Disable the configured CDN source without changing its URL. */\n  disableCdn?: boolean\n  /** Disable the keyless WhatsOnChain fallback on mainnet/testnet. */\n  disableWhatsOnChain?: boolean\n}\n\nexport type ChaintracksArgumentsTail = [\n  whatsonchainApiKey?: string,\n  maxPerFile?: number,\n  maxRetained?: number,\n  fetch?: ChaintracksFetchApi,\n  cdnUrl?: string,\n  liveHeightThreshold?: number,\n  reorgHeightThreshold?: number,\n  bulkMigrationChunkSize?: number,\n  batchInsertLimit?: number,\n  addLiveRecursionLimit?: number,\n  sources?: ChaintracksSourceOptions\n]\n\nexport type DefaultChaintracksArguments = [chain: Chain, ...options: ChaintracksArgumentsTail]\n\n/**\n * Shared parameters for configuring Chaintracks ingestors.\n */\nexport interface ChaintracksIngestorParams {\n  chain: Chain\n  whatsonchainApiKey: string\n  maxPerFile: number\n  fetch: ChaintracksFetchApi\n  cdnUrl: string\n  addLiveRecursionLimit: number\n  sources: ChaintracksSourceOptions\n}\n\nexport interface ResolvedDefaultChaintracksParams extends ChaintracksIngestorParams {\n  maxRetained: number\n  liveHeightThreshold: number\n  reorgHeightThreshold: number\n  bulkMigrationChunkSize: number\n  batchInsertLimit: number\n}\n\nexport interface CreatedChaintracks<TStorage extends ChaintracksOptions['storage']> {\n  chain: Chain\n  maxPerFile: number\n  fetch: ChaintracksFetchApi\n  storage: TStorage\n  chaintracks: Chaintracks\n  available: Promise<void>\n}\n\nexport function resolveDefaultChaintracksArguments(\n  args: DefaultChaintracksArguments\n): ResolvedDefaultChaintracksParams {\n  const [\n    chain,\n    whatsonchainApiKey = '',\n    maxPerFile = 100000,\n    maxRetained = 2,\n    fetch = new ChaintracksFetch(),\n    cdnUrl = chain === 'main' || chain === 'test' ? 'https://cdn.projectbabbage.com/blockheaders/' : '',\n    liveHeightThreshold = 2000,\n    reorgHeightThreshold = 400,\n    bulkMigrationChunkSize = 500,\n    batchInsertLimit = 400,\n    addLiveRecursionLimit = 36,\n    sources = {}\n  ] = args\n\n  return {\n    chain,\n    whatsonchainApiKey,\n    maxPerFile,\n    maxRetained,\n    fetch,\n    cdnUrl,\n    liveHeightThreshold,\n    reorgHeightThreshold,\n    bulkMigrationChunkSize,\n    batchInsertLimit,\n    addLiveRecursionLimit,\n    sources\n  }\n}\n\nexport function toDefaultChaintracksArguments(params: ResolvedDefaultChaintracksParams): DefaultChaintracksArguments {\n  const args: DefaultChaintracksArguments = [\n    params.chain,\n    params.whatsonchainApiKey,\n    params.maxPerFile,\n    params.maxRetained,\n    params.fetch,\n    params.cdnUrl,\n    params.liveHeightThreshold,\n    params.reorgHeightThreshold,\n    params.bulkMigrationChunkSize,\n    params.batchInsertLimit,\n    params.addLiveRecursionLimit\n  ]\n  // Preserve the exact pre-resiliency positional tuple when no source options\n  // were supplied. This keeps wrappers that inspect or forward arguments\n  // byte-for-byte compatible while allowing the new options to be appended.\n  if (Object.keys(params.sources).length > 0) args.push(params.sources)\n  return args\n}\n\nexport function createDefaultBulkFileDataManager(params: ResolvedDefaultChaintracksParams): BulkFileDataManager {\n  const options: BulkFileDataManagerOptions = {\n    chain: params.chain,\n    fetch: params.fetch,\n    maxPerFile: params.maxPerFile,\n    maxRetained: params.maxRetained,\n    fromKnownSourceUrl: params.cdnUrl\n  }\n  return new BulkFileDataManager(options)\n}\n\nexport function createDefaultChaintracksStorageOptions(params: ResolvedDefaultChaintracksParams) {\n  return {\n    chain: params.chain,\n    bulkFileDataManager: createDefaultBulkFileDataManager(params),\n    liveHeightThreshold: params.liveHeightThreshold,\n    reorgHeightThreshold: params.reorgHeightThreshold,\n    bulkMigrationChunkSize: params.bulkMigrationChunkSize,\n    batchInsertLimit: params.batchInsertLimit\n  }\n}\n\nexport function startChaintracks<TStorage extends ChaintracksOptions['storage']>(\n  params: ResolvedDefaultChaintracksParams,\n  options: ChaintracksOptions\n): CreatedChaintracks<TStorage> {\n  const chaintracks = new Chaintracks(options)\n  return {\n    chain: params.chain,\n    fetch: params.fetch,\n    maxPerFile: params.maxPerFile,\n    storage: options.storage as TStorage,\n    chaintracks,\n    available: chaintracks.makeAvailable()\n  }\n}\n\nexport function createAndStartDefaultChaintracks<TStorage extends ChaintracksOptions['storage']>(\n  args: DefaultChaintracksArguments,\n  createOptions: (...args: DefaultChaintracksArguments) => ChaintracksOptions\n): CreatedChaintracks<TStorage> {\n  const params = resolveDefaultChaintracksArguments(args)\n  const options = createOptions(...toDefaultChaintracksArguments(params))\n  return startChaintracks<TStorage>(params, options)\n}\n\n/**\n * Builds the shared portion of ChaintracksOptions that all storage backends\n * (Knex, Idb, NoDb) have in common: the options shell and bulk/live ingestors.\n *\n * The caller is responsible for providing the storage implementation.\n */\nexport function buildChaintracksOptionsWithIngestors(\n  params: ChaintracksIngestorParams,\n  storage: ChaintracksOptions['storage']\n): ChaintracksOptions {\n  const { chain, whatsonchainApiKey, maxPerFile, fetch, cdnUrl, addLiveRecursionLimit, sources } = params\n\n  const co: ChaintracksOptions = {\n    chain,\n    storage,\n    bulkIngestors: [],\n    liveIngestors: [],\n    addLiveRecursionLimit,\n    logging: (...args) => console.log(new Date().toISOString(), ...args),\n    readonly: false\n  }\n\n  const jsonResource = `${chain}NetBlockHeaders.json`\n\n  if (!sources.disableCdn && cdnUrl !== '') {\n    const bulkCdnOptions: BulkIngestorCDNOptions = {\n      chain,\n      jsonResource,\n      fetch,\n      cdnUrl,\n      maxPerFile\n    }\n    co.bulkIngestors.push(new BulkIngestorCDNBabbage(bulkCdnOptions))\n  }\n\n  const chaintracksSource =\n    sources.chaintracks ?? (sources.disableChaintracks ? undefined : createPublicChaintracksSource(chain))\n  if (chaintracksSource != null) {\n    co.bulkIngestors.push(\n      new BulkIngestorChaintracks({\n        chain,\n        jsonResource,\n        chaintracks: chaintracksSource,\n        maxHeadersPerRequest: sources.remoteMaxHeadersPerRequest\n      })\n    )\n    co.liveIngestors.push(\n      new LiveIngestorChaintracksSSE({\n        chain,\n        chaintracks: chaintracksSource\n      })\n    )\n  }\n\n  if ((chain === 'main' || chain === 'test') && !sources.disableWhatsOnChain) {\n    const wocOptions: WhatsOnChainServicesOptions = {\n      chain,\n      apiKey: whatsonchainApiKey,\n      timeout: 30000,\n      userAgent: 'BabbageWhatsOnChainServices',\n      enableCache: true,\n      chainInfoMsecs: 5000\n    }\n\n    const bulkOptions: BulkIngestorWhatsOnChainOptions = {\n      ...wocOptions,\n      jsonResource,\n      idleWait: 5000\n    }\n    co.bulkIngestors.push(new BulkIngestorWhatsOnChainCdn(bulkOptions))\n\n    const liveOptions: LiveIngestorWhatsOnChainOptions = {\n      ...wocOptions,\n      idleWait: 100000\n    }\n    co.liveIngestors.push(new LiveIngestorWhatsOnChainPoll(liveOptions))\n  }\n\n  if (co.bulkIngestors.length === 0 || co.liveIngestors.length === 0) {\n    throw new Error(\n      `ChainTracks ${chain} requires at least one bulk and live source. Configure sources.chaintracks for Teranode networks.`\n    )\n  }\n\n  return co\n}\n\nfunction createPublicChaintracksSource(chain: Chain): ChaintracksClientApi | undefined {\n  const serviceUrl = publicArcadeUrl(chain)\n  if (serviceUrl == null) return undefined\n  return new GoChaintracksServiceClient(chain, serviceUrl, {\n    apiPrefix: '/chaintracks/v2'\n  })\n}\n","import { ChaintracksOptions } from './Api/ChaintracksApi'\nimport { ChaintracksStorageNoDb } from './Storage/ChaintracksStorageNoDb'\nimport {\n  buildChaintracksOptionsWithIngestors,\n  createDefaultChaintracksStorageOptions,\n  type DefaultChaintracksArguments,\n  resolveDefaultChaintracksArguments\n} from './configureChaintracksIngestors'\n\nexport function createDefaultNoDbChaintracksOptions (...args: DefaultChaintracksArguments): ChaintracksOptions {\n  const params = resolveDefaultChaintracksArguments(args)\n  const storage = new ChaintracksStorageNoDb(createDefaultChaintracksStorageOptions(params))\n  return buildChaintracksOptionsWithIngestors(params, storage)\n}\n","import { Chain } from '../../../sdk'\nimport { Chaintracks } from './Chaintracks'\nimport { ChaintracksFetchApi } from './Api/ChaintracksFetchApi'\nimport { ChaintracksStorageNoDb } from './Storage/ChaintracksStorageNoDb'\nimport { createDefaultNoDbChaintracksOptions } from './createDefaultNoDbChaintracksOptions'\nimport {\n  createAndStartDefaultChaintracks,\n  type DefaultChaintracksArguments\n} from './configureChaintracksIngestors'\n\nexport async function createNoDbChaintracks (...args: DefaultChaintracksArguments): Promise<{\n  chain: Chain\n  maxPerFile: number\n  fetch: ChaintracksFetchApi\n  storage: ChaintracksStorageNoDb\n  chaintracks: Chaintracks\n  available: Promise<void>\n}> {\n  try {\n    return createAndStartDefaultChaintracks<ChaintracksStorageNoDb>(args, createDefaultNoDbChaintracksOptions)\n  } catch (error) {\n    console.error('Error setting up Chaintracks with NoDb Storage:', error)\n    throw error\n  }\n}\n","import {\n  Hash,\n  Utils,\n  Random,\n  SymmetricKey,\n  AbortActionArgs,\n  AbortActionResult,\n  AcquireCertificateArgs,\n  AcquireCertificateResult,\n  AuthenticatedResult,\n  CreateActionArgs,\n  CreateActionResult,\n  CreateHmacArgs,\n  CreateHmacResult,\n  CreateSignatureArgs,\n  CreateSignatureResult,\n  DiscoverByAttributesArgs,\n  DiscoverByIdentityKeyArgs,\n  DiscoverCertificatesResult,\n  GetHeaderArgs,\n  GetHeaderResult,\n  GetHeightResult,\n  GetNetworkResult,\n  GetPublicKeyArgs,\n  GetPublicKeyResult,\n  GetVersionResult,\n  InternalizeActionArgs,\n  InternalizeActionResult,\n  ListActionsArgs,\n  ListActionsResult,\n  ListCertificatesArgs,\n  ListCertificatesResult,\n  ListOutputsArgs,\n  ListOutputsResult,\n  OriginatorDomainNameStringUnder250Bytes,\n  ProveCertificateArgs,\n  ProveCertificateResult,\n  RelinquishCertificateArgs,\n  RelinquishCertificateResult,\n  RelinquishOutputArgs,\n  RelinquishOutputResult,\n  RevealCounterpartyKeyLinkageArgs,\n  RevealCounterpartyKeyLinkageResult,\n  RevealSpecificKeyLinkageArgs,\n  RevealSpecificKeyLinkageResult,\n  SignActionArgs,\n  SignActionResult,\n  VerifyHmacArgs,\n  VerifyHmacResult,\n  VerifySignatureArgs,\n  VerifySignatureResult,\n  WalletDecryptArgs,\n  WalletDecryptResult,\n  WalletEncryptArgs,\n  WalletEncryptResult,\n  WalletInterface,\n  OutpointString,\n  PrivateKey,\n  Signature,\n  LookupResolver,\n  LookupAnswer,\n  LookupResolution,\n  Transaction,\n  PushDrop,\n  CreateActionInput,\n  SHIPBroadcaster,\n  Telemetry,\n  TelemetryConfig\n} from '@bsv/sdk'\nimport { PrivilegedKeyManager } from './sdk/PrivilegedKeyManager'\nimport { argon2id, createSHA256, createSHA512, pbkdf2 } from './utility/hashWasm'\n\n/**\n * Number of rounds used in PBKDF2 for deriving password keys.\n */\nexport const PBKDF2_NUM_ROUNDS = 7777\n\n/**\n * Default Argon2id parameters for password-key derivation (UMP v3).\n */\nexport const ARGON2ID_DEFAULT_ITERATIONS = 7\nexport const ARGON2ID_DEFAULT_MEMORY_KIB = 131072\nexport const ARGON2ID_DEFAULT_PARALLELISM = 1\nexport const ARGON2ID_DEFAULT_HASH_LENGTH = 32\nexport const ARGON2ID_MAX_ITERATIONS = 20\nexport const ARGON2ID_MAX_MEMORY_KIB = 262144\nexport const ARGON2ID_MAX_PARALLELISM = 16\nexport const KDF_MAX_HASH_LENGTH = 64\nexport const PBKDF2_MAX_ITERATIONS = 10_000_000\nexport const MAX_STATE_SNAPSHOT_BYTES = 16 * 1024 * 1024\n\nfunction isPositiveIntegerInRange(value: unknown, maximum: number): value is number {\n  return typeof value === 'number' && Number.isInteger(value) && value > 0 && value <= maximum\n}\n\nfunction isValidKdfConfig(kdf: UMPToken['passwordKdf']): boolean {\n  if (kdf == null) return false\n  if (\n    !isPositiveIntegerInRange(\n      kdf.iterations,\n      kdf.algorithm === 'argon2id' ? ARGON2ID_MAX_ITERATIONS : PBKDF2_MAX_ITERATIONS\n    )\n  ) {\n    return false\n  }\n  if (kdf.algorithm === 'pbkdf2-sha512') {\n    return kdf.hashLength === undefined || isPositiveIntegerInRange(kdf.hashLength, KDF_MAX_HASH_LENGTH)\n  }\n  if (kdf.algorithm !== 'argon2id') return false\n  return (\n    isPositiveIntegerInRange(kdf.memoryKiB, ARGON2ID_MAX_MEMORY_KIB) &&\n    isPositiveIntegerInRange(kdf.parallelism, ARGON2ID_MAX_PARALLELISM) &&\n    isPositiveIntegerInRange(kdf.hashLength, KDF_MAX_HASH_LENGTH)\n  )\n}\n\nfunction findKdfVersionFieldIndex(protocolFields: number[][]): number {\n  const hasMetadataWithProfiles =\n    protocolFields.length >= 15 &&\n    protocolFields[12]?.length === 1 &&\n    protocolFields[12][0] === 3\n  if (hasMetadataWithProfiles) return 12\n  const hasMetadataWithoutProfiles =\n    protocolFields.length >= 14 &&\n    protocolFields[11]?.length === 1 &&\n    protocolFields[11][0] === 3\n  return hasMetadataWithoutProfiles ? 11 : -1\n}\n\nfunction addProfilesField(\n  token: UMPToken,\n  protocolFields: number[][],\n  kdfVersionFieldIndex: number\n): boolean {\n  const hasProfilesField =\n    kdfVersionFieldIndex === 12 || (kdfVersionFieldIndex !== 11 && protocolFields[11] != null)\n  if (!hasProfilesField || protocolFields[11].length === 0) return true\n  if (protocolFields[11].length > MAX_STATE_SNAPSHOT_BYTES) return false\n  token.profilesEncrypted = protocolFields[11]\n  return true\n}\n\nfunction addPasswordKdf(\n  token: UMPToken,\n  protocolFields: number[][],\n  kdfVersionFieldIndex: number\n): boolean {\n  if (kdfVersionFieldIndex === -1) return true\n  const kdfAlgorithmField = protocolFields[kdfVersionFieldIndex + 1]\n  const kdfParamsField = protocolFields[kdfVersionFieldIndex + 2]\n  if (kdfAlgorithmField == null || kdfParamsField == null || kdfParamsField.length > 1024) {\n    return false\n  }\n  const kdfParams = JSON.parse(Utils.toUTF8(kdfParamsField)) as Record<string, unknown>\n  const passwordKdf: UMPToken['passwordKdf'] = {\n    algorithm: Utils.toUTF8(kdfAlgorithmField) as 'pbkdf2-sha512' | 'argon2id',\n    iterations: kdfParams.iterations as number,\n    memoryKiB: kdfParams.memoryKiB as number | undefined,\n    parallelism: kdfParams.parallelism as number | undefined,\n    hashLength: kdfParams.hashLength as number | undefined\n  }\n  if (!isValidKdfConfig(passwordKdf)) return false\n  token.umpVersion = 3\n  token.passwordKdf = passwordKdf\n  return true\n}\n\nfunction isLikelyDerSignatureField(field: number[]): boolean {\n  if (!field || field.length < 8 || field.length > 80) {\n    return false\n  }\n\n  if (field[0] !== 0x30) {\n    return false\n  }\n\n  const declaredLen = field[1]\n  return declaredLen === field.length - 2\n}\n\nfunction stripVerifiedPushDropSignature(fields: number[][], lockingPublicKey: any): number[][] {\n  if (fields.length <= 11) {\n    return fields\n  }\n\n  const protocolFieldCount = fields.length - 1\n  const trailingField = fields[protocolFieldCount]\n  if (!trailingField || !isLikelyDerSignatureField(trailingField)) {\n    return fields\n  }\n\n  try {\n    let dataLength = 0\n    for (let i = 0; i < protocolFieldCount; i++) {\n      dataLength += fields[i].length\n    }\n\n    const dataToVerify = Array.from({ length: dataLength }, () => 0)\n    let writeOffset = 0\n    for (let i = 0; i < protocolFieldCount; i++) {\n      const field = fields[i]\n      for (const byte of field) {\n        dataToVerify[writeOffset++] = byte\n      }\n    }\n\n    const signature = Signature.fromDER(trailingField)\n\n    if (signature.verify(dataToVerify, lockingPublicKey)) {\n      return fields.slice(0, protocolFieldCount)\n    }\n  } catch {\n    return fields\n  }\n\n  return fields\n}\n\n/**\n * PBKDF-2 that prefers WebCrypto and falls back to hash-wasm.\n *\n * @param passwordBytes   Raw password bytes.\n * @param salt            Salt bytes.\n * @param iterations      Number of rounds.\n * @param keyLen          Desired key length in bytes.\n * @param hash            Digest algorithm (default \"sha512\").\n * @returns               Derived key bytes.\n */\nasync function pbkdf2NativeOrWasm(\n  passwordBytes: number[],\n  salt: number[],\n  iterations: number,\n  keyLen: number,\n  hash: 'sha256' | 'sha512' = 'sha512'\n): Promise<number[]> {\n  // ----- fast-path: WebCrypto (both browser & recent Node expose globalThis.crypto.subtle)\n  const subtle = (globalThis as any)?.crypto?.subtle as SubtleCrypto | undefined\n  if (subtle != null) {\n    try {\n      const baseKey = await subtle.importKey(\n        'raw',\n        new Uint8Array(passwordBytes),\n        { name: 'PBKDF2' },\n        /* extractable */ false,\n        ['deriveBits']\n      )\n\n      const bits = await subtle.deriveBits(\n        {\n          name: 'PBKDF2',\n          salt: new Uint8Array(salt),\n          iterations,\n          hash: hash.toUpperCase() as AlgorithmIdentifier\n        },\n        baseKey,\n        keyLen * 8\n      )\n      return Array.from(new Uint8Array(bits))\n    } catch {\n      // WebCrypto is unavailable or refused the algorithm (e.g. non-secure context, old\n      // Safari).  Fall through to the pure-JS hash-wasm implementation below.\n    }\n  }\n\n  const hashFunction = hash === 'sha256' ? createSHA256() : createSHA512()\n  const derived = await pbkdf2({\n    password: new Uint8Array(passwordBytes),\n    salt: new Uint8Array(salt),\n    iterations,\n    hashLength: keyLen,\n    hashFunction,\n    outputType: 'binary'\n  })\n\n  return Array.from(derived)\n}\n\n/**\n * Derives the password key from a password using the KDF specified in the UMP token.\n * For legacy tokens (no KDF metadata), uses PBKDF2 with fixed rounds (7777).\n * For v3 tokens, uses the algorithm specified in passwordKdf metadata.\n *\n * @param token          The UMP token containing KDF metadata and salt.\n * @param passwordBytes  Raw password bytes.\n * @param overrideKdf    Optional KDF config to override token/default settings.\n * @returns              Derived password key bytes.\n */\nasync function derivePasswordKey(\n  token: Pick<UMPToken, 'passwordSalt' | 'passwordKdf'>,\n  passwordBytes: number[],\n  overrideKdf?: {\n    algorithm?: 'pbkdf2-sha512' | 'argon2id'\n    iterations?: number\n    memoryKiB?: number\n    parallelism?: number\n    hashLength?: number\n  }\n): Promise<number[]> {\n  const kdf = overrideKdf || token.passwordKdf\n  if (kdf != null && !isValidKdfConfig(kdf as UMPToken['passwordKdf'])) {\n    throw new Error('UMP token contains unsupported or unsafe KDF parameters.')\n  }\n\n  // Legacy token or explicit PBKDF2 request\n  if (kdf == null || kdf.algorithm === 'pbkdf2-sha512') {\n    return await pbkdf2NativeOrWasm(\n      passwordBytes,\n      token.passwordSalt,\n      kdf?.iterations ?? PBKDF2_NUM_ROUNDS,\n      32,\n      'sha512'\n    )\n  }\n\n  // Argon2id path (UMP v3)\n  if (kdf.algorithm === 'argon2id') {\n    const iterations = kdf.iterations ?? ARGON2ID_DEFAULT_ITERATIONS\n    const memorySize = kdf.memoryKiB ?? ARGON2ID_DEFAULT_MEMORY_KIB\n    const parallelism = kdf.parallelism ?? ARGON2ID_DEFAULT_PARALLELISM\n    const hashLength = kdf.hashLength ?? ARGON2ID_DEFAULT_HASH_LENGTH\n\n    const hash = await argon2id({\n      password: new Uint8Array(passwordBytes),\n      salt: new Uint8Array(token.passwordSalt),\n      iterations,\n      memorySize,\n      parallelism,\n      hashLength,\n      outputType: 'binary'\n    })\n\n    return Array.from(hash)\n  }\n\n  throw new Error(`Unsupported KDF algorithm: ${(kdf as any).algorithm}`)\n}\n\n/**\n * Unique Identifier for the default profile (16 zero bytes).\n */\nexport const DEFAULT_PROFILE_ID = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n\n/**\n * Describes the structure of a user profile within the wallet.\n */\nexport interface Profile {\n  /**\n   * User-defined name for the profile.\n   */\n  name: string\n\n  /**\n   * Unique 16-byte identifier for the profile.\n   */\n  id: number[]\n\n  /**\n   * 32-byte random pad XOR'd with the root primary key to derive the profile's primary key.\n   */\n  primaryPad: number[]\n\n  /**\n   * 32-byte random pad XOR'd with the root privileged key to derive the profile's privileged key.\n   */\n  privilegedPad: number[]\n\n  /**\n   * Timestamp (seconds since epoch) when the profile was created.\n   */\n  createdAt: number\n}\n\nfunction isByteArrayOfLength(value: unknown, length: number): value is number[] {\n  return (\n    Array.isArray(value) &&\n    value.length === length &&\n    value.every(byte => Number.isInteger(byte) && byte >= 0 && byte <= 255)\n  )\n}\n\nfunction isValidProfile(value: unknown): value is Profile {\n  if (value == null || typeof value !== 'object') return false\n  const profile = value as Partial<Profile>\n  return (\n    typeof profile.name === 'string' &&\n    profile.name.length > 0 &&\n    profile.name.length <= 250 &&\n    isByteArrayOfLength(profile.id, 16) &&\n    isByteArrayOfLength(profile.primaryPad, 32) &&\n    isByteArrayOfLength(profile.privilegedPad, 32) &&\n    typeof profile.createdAt === 'number' &&\n    Number.isFinite(profile.createdAt) &&\n    profile.createdAt >= 0\n  )\n}\n\n/**\n * Describes the structure of a User Management Protocol (UMP) token.\n */\nexport interface UMPToken {\n  /**\n   * Root Primary key encrypted by the XOR of the password and presentation keys.\n   */\n  passwordPresentationPrimary: number[]\n\n  /**\n   * Root Primary key encrypted by the XOR of the password and recovery keys.\n   */\n  passwordRecoveryPrimary: number[]\n\n  /**\n   * Root Primary key encrypted by the XOR of the presentation and recovery keys.\n   */\n  presentationRecoveryPrimary: number[]\n\n  /**\n   * Root Privileged key encrypted by the XOR of the password and primary keys.\n   */\n  passwordPrimaryPrivileged: number[]\n\n  /**\n   * Root Privileged key encrypted by the XOR of the presentation and recovery keys.\n   */\n  presentationRecoveryPrivileged: number[]\n\n  /**\n   * Hash of the presentation key.\n   */\n  presentationHash: number[]\n\n  /**\n   * PBKDF2 salt used in conjunction with the password to derive the password key.\n   */\n  passwordSalt: number[]\n\n  /**\n   * Hash of the recovery key.\n   */\n  recoveryHash: number[]\n\n  /**\n   * A copy of the presentation key encrypted with the root privileged key.\n   */\n  presentationKeyEncrypted: number[]\n\n  /**\n   * A copy of the recovery key encrypted with the root privileged key.\n   */\n  recoveryKeyEncrypted: number[]\n\n  /**\n   * A copy of the password key encrypted with the root privileged key.\n   */\n  passwordKeyEncrypted: number[]\n\n  /**\n   * Optional field containing the encrypted profile data.\n   * JSON string -> Encrypted Bytes using root privileged key.\n   */\n  profilesEncrypted?: number[]\n\n  /**\n   * On-chain UMP protocol version (3 for tokens with KDF metadata).\n   */\n  umpVersion?: number\n\n  /**\n   * Password-based key derivation function metadata.\n   * Present for UMP v3 tokens; absent for legacy tokens.\n   */\n  passwordKdf?: {\n    algorithm: 'pbkdf2-sha512' | 'argon2id'\n    iterations: number\n    memoryKiB?: number\n    parallelism?: number\n    hashLength?: number\n  }\n\n  /**\n   * Describes the token's location on-chain, if it's already been published.\n   */\n  currentOutpoint?: OutpointString\n}\n\n/**\n * Configuration options for KDF (Key Derivation Function) used in UMP tokens.\n */\nexport interface KdfConfig {\n  /**\n   * Algorithm to use for new UMP tokens.\n   */\n  algorithm?: 'pbkdf2-sha512' | 'argon2id'\n\n  /**\n   * Number of iterations/rounds.\n   */\n  iterations?: number\n\n  /**\n   * Memory size in KiB (Argon2id only).\n   */\n  memoryKiB?: number\n\n  /**\n   * Degree of parallelism (Argon2id only).\n   */\n  parallelism?: number\n\n  /**\n   * Hash output length in bytes.\n   */\n  hashLength?: number\n}\n\n/**\n * Describes a system capable of finding and updating UMP tokens on the blockchain.\n */\nexport interface UMPTokenInteractor {\n  /**\n   * Locates the latest valid copy of a UMP token (including its outpoint)\n   * based on the presentation key hash.\n   *\n   * @param hash The hash of the presentation key.\n   * @returns The UMP token if found; otherwise, undefined.\n   * @throws Implementations should throw when no verified token or clean empty response is available.\n   */\n  findByPresentationKeyHash: (hash: number[]) => Promise<UMPToken | undefined>\n\n  /**\n   * Locates the latest valid copy of a UMP token (including its outpoint)\n   * based on the recovery key hash.\n   *\n   * @param hash The hash of the recovery key.\n   * @returns The UMP token if found; otherwise, undefined.\n   * @throws Implementations should throw when no verified token or clean empty response is available.\n   */\n  findByRecoveryKeyHash: (hash: number[]) => Promise<UMPToken | undefined>\n\n  /**\n   * Creates (and optionally consumes the previous version of) a UMP token on-chain.\n   *\n   * @param wallet            The wallet that might be used to create a new token (MUST be operating under the DEFAULT profile).\n   * @param adminOriginator   The domain name of the administrative originator.\n   * @param token             The new UMP token to create.\n   * @param oldTokenToConsume If provided, the old token that must be consumed in the same transaction.\n   * @returns                 The newly created outpoint.\n   */\n  buildAndSend: (\n    wallet: WalletInterface, // This wallet MUST be the one built for the default profile\n    adminOriginator: OriginatorDomainNameStringUnder250Bytes,\n    token: UMPToken,\n    oldTokenToConsume?: UMPToken\n  ) => Promise<OutpointString>\n}\n\nexport interface UMPTokenLookupDiagnostics {\n  hostCount: number\n  completedHosts: number\n  successfulHosts: number\n  emptyHosts: number\n  failedHosts: number\n  rejectedHosts: number\n  freeformHosts: number\n  outputCount: number\n  correlationId?: string\n}\n\nexport type UMPTokenLookupFailureReason =\n  'lookup-unavailable' | 'lookup-incomplete' | 'token-malformed' | 'token-ambiguous'\n\n/**\n * Raised when a UMP lookup yields neither a verified token nor a clean empty response.\n *\n * Callers must offer retry/recovery rather than treating this error as a new\n * account. Diagnostics contain counts only and never hashes, keys, or tokens.\n */\nexport class UMPTokenLookupError extends Error {\n  readonly code = 'WERR_UMP_LOOKUP_INDETERMINATE'\n\n  constructor(\n    public readonly reason: UMPTokenLookupFailureReason,\n    public readonly diagnostics: UMPTokenLookupDiagnostics,\n    options?: { cause?: unknown }\n  ) {\n    super('Unable to determine whether the wallet account already exists. Retry or use account recovery.', options)\n    this.name = 'UMPTokenLookupError'\n  }\n}\n\n/**\n * @class OverlayUMPTokenInteractor\n *\n * A concrete implementation of the UMPTokenInteractor interface that interacts\n * with Overlay Services and the UMP (User Management Protocol) topic. This class\n * is responsible for:\n *\n * 1) Locating UMP tokens via overlay lookups (ls_users).\n * 2) Creating and publishing new or updated UMP token outputs on-chain under\n *    the \"tm_users\" topic.\n * 3) Consuming (spending) an old token if provided.\n */\nexport class OverlayUMPTokenInteractor implements UMPTokenInteractor {\n  /**\n   * A `LookupResolver` instance used to query overlay networks.\n   */\n  private readonly resolver: LookupResolver\n\n  /**\n   * A SHIP broadcaster that can be used to publish updated UMP tokens\n   * under the `tm_users` topic to overlay service peers.\n   */\n  private readonly broadcaster: SHIPBroadcaster\n  private readonly telemetry: Telemetry\n\n  /**\n   * Construct a new OverlayUMPTokenInteractor.\n   *\n   * @param resolver     A LookupResolver instance for performing overlay queries (ls_users).\n   * @param broadcaster  A SHIPBroadcaster instance for sharing new or updated tokens across the `tm_users` overlay.\n   */\n  constructor(\n    resolver: LookupResolver = new LookupResolver(),\n    broadcaster: SHIPBroadcaster = new SHIPBroadcaster(['tm_users']),\n    telemetry?: TelemetryConfig\n  ) {\n    this.resolver = resolver\n    this.broadcaster = broadcaster\n    this.telemetry = new Telemetry(telemetry)\n  }\n\n  /**\n   * Finds a UMP token on-chain by the given presentation key hash, if it exists.\n   * Uses the ls_users overlay service to perform the lookup.\n   *\n   * @param hash The 32-byte SHA-256 hash of the presentation key.\n   * @returns A UMPToken object (including currentOutpoint) if found, otherwise undefined.\n   */\n  public async findByPresentationKeyHash(hash: number[]): Promise<UMPToken | undefined> {\n    return await this.findToken(\n      {\n        service: 'ls_users',\n        query: { presentationHash: Utils.toHex(hash) }\n      },\n      'presentation'\n    )\n  }\n\n  /**\n   * Finds a UMP token on-chain by the given recovery key hash, if it exists.\n   * Uses the ls_users overlay service to perform the lookup.\n   *\n   * @param hash The 32-byte SHA-256 hash of the recovery key.\n   * @returns A UMPToken object (including currentOutpoint) if found, otherwise undefined.\n   */\n  public async findByRecoveryKeyHash(hash: number[]): Promise<UMPToken | undefined> {\n    return await this.findToken(\n      {\n        service: 'ls_users',\n        query: { recoveryHash: Utils.toHex(hash) }\n      },\n      'recovery'\n    )\n  }\n\n  private async findToken(\n    question: { service: string; query: Record<string, string> },\n    lookupKind: 'presentation' | 'recovery'\n  ): Promise<UMPToken | undefined> {\n    const correlationId = this.telemetry.enabled === true ? this.telemetry.createCorrelationId() : undefined\n    const startedAt = Date.now()\n    this.telemetry.capture({\n      name: 'wallet-toolbox.ump.lookup.started',\n      component: 'wallet-toolbox.ump',\n      severity: 'debug',\n      correlationId,\n      attributes: { lookupKind }\n    })\n\n    let resolution: LookupResolution\n    try {\n      resolution = await this.resolver.queryDetailed(question, undefined, {\n        waitForAllHosts: true,\n        correlationId\n      })\n    } catch (error) {\n      const diagnostics = this.emptyLookupDiagnostics(correlationId)\n      this.captureLookupFailure(lookupKind, 'lookup-unavailable', diagnostics, startedAt, error)\n      throw new UMPTokenLookupError('lookup-unavailable', diagnostics, { cause: error })\n    }\n\n    const diagnostics = this.toLookupDiagnostics(resolution)\n    const tokens = this.parseLookupAnswers(resolution.answer)\n    const expectedHash =\n      question.query[lookupKind === 'presentation' ? 'presentationHash' : 'recoveryHash'].toLowerCase()\n    const matchingTokens = tokens.filter(\n      token =>\n        Utils.toHex(lookupKind === 'presentation' ? token.presentationHash : token.recoveryHash).toLowerCase() ===\n        expectedHash\n    )\n\n    // A verified token is positive account-existence evidence. Empty, malformed,\n    // rejected, or unavailable peers cannot override it. The resolver de-duplicates\n    // identical outputs, so multiple matching tokens represent distinct records.\n    // Competing records are usually stale renditions: a token update spends its\n    // predecessor's outpoint, so the newest rendition is the sole candidate not\n    // spent by another candidate's transaction history. Only unrelated (forked)\n    // tokens remain indeterminate.\n    if (matchingTokens.length > 1) {\n      const newest = this.resolveNewestToken(matchingTokens, resolution.answer.outputs)\n      if (newest != null) {\n        this.captureLookupCompleted(lookupKind, 'found', diagnostics, startedAt, {\n          supersededTokens: matchingTokens.length - 1\n        })\n        return newest\n      }\n      const reason = 'token-ambiguous'\n      this.captureLookupFailure(lookupKind, reason, diagnostics, startedAt)\n      throw new UMPTokenLookupError(reason, diagnostics)\n    }\n    if (matchingTokens.length === 1) {\n      this.captureLookupCompleted(lookupKind, 'found', diagnostics, startedAt)\n      return matchingTokens[0]\n    }\n\n    // A clean empty response is sufficient negative evidence once no verified\n    // token exists. Malformed outputs and failed peers are ignored so they cannot\n    // deny onboarding by advertising corrupt data or remaining unavailable.\n    if (resolution.progress.emptyHosts > 0) {\n      this.captureLookupCompleted(lookupKind, 'not-found', diagnostics, startedAt)\n      return undefined\n    }\n\n    const reason = resolution.answer.outputs.length > 0 ? 'token-malformed' : 'lookup-incomplete'\n    this.captureLookupFailure(lookupKind, reason, diagnostics, startedAt)\n    throw new UMPTokenLookupError(reason, diagnostics)\n  }\n\n  /**\n   * Picks the newest rendition among distinct verified tokens, when possible.\n   *\n   * The on-chain UMP protocol expresses token updates by consumption: the\n   * transaction creating a new rendition spends the previous rendition's\n   * outpoint (there is no rendition counter field in the current format).\n   * A candidate is therefore superseded when any other candidate's ancestry\n   * (available from its BEEF) spends the candidate's outpoint.\n   *\n   * @returns The single unsuperseded candidate, or undefined when supersession\n   * cannot be established for every stale candidate (e.g. forked tokens).\n   */\n  private resolveNewestToken(matchingTokens: UMPToken[], outputs: LookupAnswer['outputs']): UMPToken | undefined {\n    const candidates = new Map<string, UMPToken>()\n    for (const token of matchingTokens) {\n      if (token.currentOutpoint == null) return undefined\n      candidates.set(token.currentOutpoint, token)\n    }\n\n    // Hosts may serve the same token with different BEEF depth, so evidence\n    // for a candidate is merged across every copy rather than first-wins: a\n    // shallow copy must not mask the supersession proof a deeper copy carries.\n    const evidenceByCandidate = new Map<string, { txs: Transaction[]; spent: Set<string> }>()\n    for (const output of outputs) {\n      try {\n        const tx = Transaction.fromBEEF(output.beef)\n        const outpoint = `${tx.id('hex')}.${output.outputIndex}`\n        if (!candidates.has(outpoint)) continue\n        const evidence = evidenceByCandidate.get(outpoint) ?? { txs: [], spent: new Set<string>() }\n        evidence.txs.push(tx)\n        this.collectSpentOutpoints(tx, evidence.spent, new Set())\n        evidenceByCandidate.set(outpoint, evidence)\n      } catch {\n        // Malformed outputs never produced candidates; nothing to correlate.\n      }\n    }\n\n    // Without an evidence transaction for every candidate, an unexamined\n    // candidate would trivially survive — refuse to guess.\n    if (evidenceByCandidate.size !== candidates.size) return undefined\n\n    const survivors = [...candidates.keys()].filter(\n      outpoint =>\n        ![...evidenceByCandidate.entries()].some(([other, { spent }]) => other !== outpoint && spent.has(outpoint))\n    )\n    if (survivors.length === 1) return candidates.get(survivors[0])\n\n    // Forked candidates: no spend relationship connects them. Updating a token\n    // requires unlocking its predecessor, so a candidate whose transaction\n    // provably consumed a same-identity token demonstrates continuity of key\n    // control; a freshly minted competitor (funding inputs only) is the anomaly\n    // — typically a historical erroneous re-onboarding. Prefer the sole proven\n    // continuation; anything less decisive stays indeterminate.\n    const provenContinuations = survivors.filter(outpoint => {\n      const evidence = evidenceByCandidate.get(outpoint)\n      const token = candidates.get(outpoint)\n      return (\n        evidence != null && token != null && evidence.txs.some(tx => this.consumesSameIdentityToken(tx, token))\n      )\n    })\n    if (provenContinuations.length !== 1) return undefined\n    return candidates.get(provenContinuations[0])\n  }\n\n  /**\n   * Whether `tx` spends an input whose source output (available in the BEEF)\n   * decodes as a UMP token sharing the candidate's presentation or recovery\n   * hash — on-chain proof that the candidate is an update of a same-identity\n   * predecessor rather than an independently minted token.\n   */\n  private consumesSameIdentityToken(tx: Transaction, token: UMPToken): boolean {\n    const presentationHash = Utils.toHex(token.presentationHash)\n    const recoveryHash = Utils.toHex(token.recoveryHash)\n    for (const input of tx.inputs) {\n      const source = input.sourceTransaction\n      if (source == null || input.sourceOutputIndex == null) continue\n      const sourceOutput = source.outputs[input.sourceOutputIndex]\n      if (sourceOutput == null) continue\n      try {\n        const decoded = PushDrop.decode(sourceOutput.lockingScript)\n        if (decoded.fields == null) continue\n        const fields = stripVerifiedPushDropSignature(decoded.fields, decoded.lockingPublicKey)\n        if (fields.length < 11 || fields[6]?.length !== 32 || fields[7]?.length !== 32) continue\n        if (Utils.toHex(fields[6]) === presentationHash || Utils.toHex(fields[7]) === recoveryHash) {\n          return true\n        }\n      } catch {\n        continue\n      }\n    }\n    return false\n  }\n\n  /**\n   * Accumulates every outpoint spent by `tx` and by the ancestor transactions\n   * embedded in its BEEF, so supersession is detected even when intermediate\n   * renditions are absent from the lookup answer. Iterative so arbitrarily\n   * long update chains cannot exhaust the call stack.\n   */\n  private collectSpentOutpoints(tx: Transaction, spent: Set<string>, visited: Set<string>): void {\n    const pending: Transaction[] = [tx]\n    while (pending.length > 0) {\n      const current = pending.pop() as Transaction\n      const txid = current.id('hex')\n      if (visited.has(txid)) continue\n      visited.add(txid)\n      for (const input of current.inputs) {\n        const sourceTxid = input.sourceTXID ?? input.sourceTransaction?.id('hex')\n        if (sourceTxid == null || input.sourceOutputIndex == null) continue\n        spent.add(`${sourceTxid}.${input.sourceOutputIndex}`)\n        if (input.sourceTransaction != null) {\n          pending.push(input.sourceTransaction)\n        }\n      }\n    }\n  }\n\n  private emptyLookupDiagnostics(correlationId?: string): UMPTokenLookupDiagnostics {\n    return {\n      hostCount: 0,\n      completedHosts: 0,\n      successfulHosts: 0,\n      emptyHosts: 0,\n      failedHosts: 0,\n      rejectedHosts: 0,\n      freeformHosts: 0,\n      outputCount: 0,\n      ...(correlationId !== undefined ? { correlationId } : {})\n    }\n  }\n\n  private toLookupDiagnostics(resolution: LookupResolution): UMPTokenLookupDiagnostics {\n    const progress = resolution.progress\n    return {\n      hostCount: progress.hostCount,\n      completedHosts: progress.completedHosts,\n      successfulHosts: progress.successfulHosts,\n      emptyHosts: progress.emptyHosts,\n      failedHosts: progress.failedHosts,\n      rejectedHosts: progress.rejectedHosts,\n      freeformHosts: progress.freeformHosts,\n      outputCount: resolution.answer.outputs.length,\n      ...(progress.correlationId !== undefined ? { correlationId: progress.correlationId } : {})\n    }\n  }\n\n  private lookupDiagnosticAttributes(diagnostics: UMPTokenLookupDiagnostics): Record<string, number> {\n    return {\n      hostCount: diagnostics.hostCount,\n      completedHosts: diagnostics.completedHosts,\n      successfulHosts: diagnostics.successfulHosts,\n      emptyHosts: diagnostics.emptyHosts,\n      failedHosts: diagnostics.failedHosts,\n      rejectedHosts: diagnostics.rejectedHosts,\n      freeformHosts: diagnostics.freeformHosts,\n      outputCount: diagnostics.outputCount\n    }\n  }\n\n  private captureLookupCompleted(\n    lookupKind: 'presentation' | 'recovery',\n    result: 'found' | 'not-found',\n    diagnostics: UMPTokenLookupDiagnostics,\n    startedAt: number,\n    extraAttributes: Record<string, number> = {}\n  ): void {\n    this.telemetry.capture({\n      name: 'wallet-toolbox.ump.lookup.completed',\n      component: 'wallet-toolbox.ump',\n      severity: 'info',\n      correlationId: diagnostics.correlationId,\n      attributes: {\n        lookupKind,\n        result,\n        durationMs: Date.now() - startedAt,\n        ...this.lookupDiagnosticAttributes(diagnostics),\n        ...extraAttributes\n      }\n    })\n  }\n\n  private captureLookupFailure(\n    lookupKind: 'presentation' | 'recovery' | 'outpoint',\n    reason: UMPTokenLookupFailureReason,\n    diagnostics: UMPTokenLookupDiagnostics,\n    startedAt: number,\n    error?: unknown\n  ): void {\n    this.telemetry.capture({\n      name: 'wallet-toolbox.ump.lookup.indeterminate',\n      component: 'wallet-toolbox.ump',\n      severity: 'warn',\n      correlationId: diagnostics.correlationId,\n      attributes: {\n        lookupKind,\n        reason,\n        durationMs: Date.now() - startedAt,\n        ...this.lookupDiagnosticAttributes(diagnostics)\n      },\n      error\n    })\n  }\n\n  /**\n   * Creates or updates (replaces) a UMP token on-chain. If `oldTokenToConsume` is provided,\n   * it is spent in the same transaction that creates the new token output. The new token is\n   * then broadcast and published under the `tm_users` topic using a SHIP broadcast, ensuring\n   * overlay participants see the updated token.\n   *\n   * @param wallet            The wallet used to build and sign the transaction (MUST be operating under the DEFAULT profile).\n   * @param adminOriginator   The domain/FQDN of the administrative originator (wallet operator).\n   * @param token             The new UMPToken to create on-chain.\n   * @param oldTokenToConsume Optionally, an existing token to consume/spend in the same transaction.\n   * @returns The outpoint of the newly created UMP token (e.g. \"abcd1234...ef.0\").\n   */\n  public async buildAndSend(\n    wallet: WalletInterface, // This wallet MUST be the one built for the default profile\n    adminOriginator: OriginatorDomainNameStringUnder250Bytes,\n    token: UMPToken,\n    oldTokenToConsume?: UMPToken\n  ): Promise<OutpointString> {\n    // 1) Construct the data fields and PushDrop locking script for the new UMP token.\n    const fields = this.buildUMPTokenFields(token)\n    const script = await new PushDrop(wallet, adminOriginator).lock(\n      fields,\n      [2, 'admin user management token'],\n      '1',\n      'self',\n      /* forSelf= */ true,\n      /* includeSignature= */ true\n    )\n    const tokenOutput = [{ lockingScript: script.toHex(), satoshis: 1, outputDescription: 'New UMP token output' }]\n\n    // 2) Resolve the old-token input (if provided) and create the action.\n    const { resolvedOldToken, inputToken } = await this.resolveOldTokenInput(oldTokenToConsume)\n    const inputs: CreateActionInput[] = resolvedOldToken?.currentOutpoint\n      ? [\n          {\n            outpoint: resolvedOldToken.currentOutpoint,\n            unlockingScriptLength: 73,\n            inputDescription: 'Consume old UMP token'\n          }\n        ]\n      : []\n\n    const createResult = await this.createUMPAction(\n      wallet,\n      adminOriginator,\n      inputs,\n      tokenOutput,\n      inputToken,\n      resolvedOldToken\n    )\n\n    // 3) If the wallet fully processed it (no signable tx), broadcast and return.\n    if (!createResult.signableTransaction) {\n      return await this.broadcastFinishedUMPAction(createResult)\n    }\n\n    // 4) Sign and broadcast: with old token input or without.\n    const reference = createResult.signableTransaction.reference\n    const partialTx = Transaction.fromBEEF(createResult.signableTransaction.tx)\n    if (resolvedOldToken?.currentOutpoint) {\n      return await this.signAndBroadcastWithOldToken(wallet, adminOriginator, reference, partialTx)\n    }\n    return await this.signAndBroadcastNewToken(wallet, adminOriginator, reference)\n  }\n\n  /** Assembles the ordered number[][] fields array from a UMPToken. */\n  private buildUMPTokenFields(token: UMPToken): number[][] {\n    const fields: number[][] = []\n    fields[0] = token.passwordSalt\n    fields[1] = token.passwordPresentationPrimary\n    fields[2] = token.passwordRecoveryPrimary\n    fields[3] = token.presentationRecoveryPrimary\n    fields[4] = token.passwordPrimaryPrivileged\n    fields[5] = token.presentationRecoveryPrivileged\n    fields[6] = token.presentationHash\n    fields[7] = token.recoveryHash\n    fields[8] = token.presentationKeyEncrypted\n    fields[9] = token.passwordKeyEncrypted\n    fields[10] = token.recoveryKeyEncrypted\n    if (token.profilesEncrypted != null) fields[11] = token.profilesEncrypted\n    if (token.umpVersion === 3 && token.passwordKdf != null) {\n      const vi = token.profilesEncrypted == null ? 11 : 12\n      fields[vi] = [token.umpVersion]\n      fields[vi + 1] = Utils.toArray(token.passwordKdf.algorithm, 'utf8')\n      const kdfParams: Record<string, number> = { iterations: token.passwordKdf.iterations }\n      if (token.passwordKdf.memoryKiB !== undefined) kdfParams.memoryKiB = token.passwordKdf.memoryKiB\n      if (token.passwordKdf.parallelism !== undefined) kdfParams.parallelism = token.passwordKdf.parallelism\n      if (token.passwordKdf.hashLength !== undefined) kdfParams.hashLength = token.passwordKdf.hashLength\n      fields[vi + 2] = Utils.toArray(JSON.stringify(kdfParams), 'utf8')\n    }\n    return fields\n  }\n\n  /** Looks up the old token on the overlay; returns undefined resolved token if not found. */\n  private async resolveOldTokenInput(\n    oldTokenToConsume?: UMPToken\n  ): Promise<{ resolvedOldToken?: UMPToken; inputToken?: { beef: number[]; outputIndex: number } }> {\n    if (!oldTokenToConsume?.currentOutpoint) return { resolvedOldToken: undefined, inputToken: undefined }\n    const inputToken = await this.findByOutpoint(oldTokenToConsume.currentOutpoint)\n    if (inputToken == null) {\n      throw new Error('The previous UMP token could not be resolved; refusing to publish a duplicate token.')\n    }\n    return { resolvedOldToken: oldTokenToConsume, inputToken }\n  }\n\n  /** Creates the UMP action without dropping a required old-token input on failure. */\n  private async createUMPAction(\n    wallet: WalletInterface,\n    adminOriginator: OriginatorDomainNameStringUnder250Bytes,\n    inputs: CreateActionInput[],\n    outputs: Array<{ lockingScript: string; satoshis: number; outputDescription: string }>,\n    inputToken: { beef: number[]; outputIndex: number } | undefined,\n    resolvedOldToken: UMPToken | undefined\n  ): Promise<Awaited<ReturnType<WalletInterface['createAction']>>> {\n    try {\n      return await wallet.createAction(\n        {\n          description: resolvedOldToken == null ? 'Create new UMP token' : 'Renew UMP token (consume old, create new)',\n          inputs,\n          outputs,\n          inputBEEF: inputToken?.beef,\n          options: { randomizeOutputs: false, acceptDelayedBroadcast: false }\n        },\n        adminOriginator\n      )\n    } catch (error) {\n      this.telemetry.capture({\n        name: 'wallet-toolbox.ump.action.failed',\n        component: 'wallet-toolbox.ump',\n        severity: 'error',\n        attributes: {\n          operation: resolvedOldToken == null ? 'create' : 'renew',\n          oldTokenInputRequired: resolvedOldToken != null\n        },\n        error\n      })\n      throw error\n    }\n  }\n\n  /** Handles a fully-finalized (no signable tx) createAction result — broadcasts and returns outpoint. */\n  private async broadcastFinishedUMPAction(\n    createResult: Awaited<ReturnType<WalletInterface['createAction']>>\n  ): Promise<OutpointString> {\n    const finalTxid =\n      createResult.txid || (createResult.tx != null ? Transaction.fromAtomicBEEF(createResult.tx).id('hex') : undefined)\n    if (!finalTxid) throw new Error('No signableTransaction and no final TX found.')\n    if (createResult.tx == null) throw new Error('No final TX data to broadcast.')\n    const broadcastTx = Transaction.fromAtomicBEEF(createResult.tx)\n    const result = await this.broadcaster.broadcast(broadcastTx)\n    this.assertSuccessfulBroadcast(result, 'create-finalized')\n    return `${finalTxid}.0`\n  }\n\n  /** Signs the old-token input and broadcasts — used during UMP token renewal. */\n  private async signAndBroadcastWithOldToken(\n    wallet: WalletInterface,\n    adminOriginator: OriginatorDomainNameStringUnder250Bytes,\n    reference: string,\n    partialTx: Transaction\n  ): Promise<OutpointString> {\n    const unlocker = new PushDrop(wallet, adminOriginator).unlock([2, 'admin user management token'], '1', 'self')\n    const unlockingScript = await unlocker.sign(partialTx, 0)\n    const signResult = await wallet.signAction(\n      { reference, spends: { 0: { unlockingScript: unlockingScript.toHex() } } },\n      adminOriginator\n    )\n    const finalTxid =\n      signResult.txid || (signResult.tx == null ? '' : Transaction.fromAtomicBEEF(signResult.tx).id('hex'))\n    if (!finalTxid) throw new Error('Could not finalize transaction for renewed UMP token.')\n    if (signResult.tx == null) throw new Error('Final transaction data missing after signing renewed UMP token.')\n    const result = await this.broadcaster.broadcast(Transaction.fromAtomicBEEF(signResult.tx))\n    this.assertSuccessfulBroadcast(result, 'renew')\n    return `${finalTxid}.0`\n  }\n\n  /** Signs without input spending and broadcasts — used when creating a brand-new UMP token. */\n  private async signAndBroadcastNewToken(\n    wallet: WalletInterface,\n    adminOriginator: OriginatorDomainNameStringUnder250Bytes,\n    reference: string\n  ): Promise<OutpointString> {\n    const signResult = await wallet.signAction({ reference, spends: {} }, adminOriginator)\n    const finalTxid =\n      signResult.txid || (signResult.tx == null ? '' : Transaction.fromAtomicBEEF(signResult.tx).id('hex'))\n    if (!finalTxid) throw new Error('Failed to finalize new UMP token transaction.')\n    if (signResult.tx == null) throw new Error('Final transaction data missing after signing new UMP token.')\n    const result = await this.broadcaster.broadcast(Transaction.fromAtomicBEEF(signResult.tx))\n    this.assertSuccessfulBroadcast(result, 'create')\n    return `${finalTxid}.0`\n  }\n\n  private assertSuccessfulBroadcast(\n    result: Awaited<ReturnType<SHIPBroadcaster['broadcast']>>,\n    operation: 'create-finalized' | 'renew' | 'create'\n  ): void {\n    const succeeded = result.status === 'success'\n    this.telemetry.capture({\n      name: succeeded ? 'wallet-toolbox.ump.broadcast.completed' : 'wallet-toolbox.ump.broadcast.failed',\n      component: 'wallet-toolbox.ump',\n      severity: succeeded ? 'info' : 'error',\n      attributes: {\n        operation,\n        outcome: result.status,\n        ...(result.status === 'error' ? { code: result.code } : {})\n      }\n    })\n    if (!succeeded) {\n      throw new Error(`UMP token broadcast failed (${result.code}).`)\n    }\n  }\n\n  /**\n   * Attempts to parse a LookupAnswer from the UMP lookup service. If successful,\n   * extracts the token fields from the resulting transaction and constructs\n   * a UMPToken object.\n   *\n   * @param answer The LookupAnswer returned by a query to ls_users.\n   * @returns The parsed UMPToken or `undefined` if none found/decodable.\n   */\n  private parseLookupAnswer(answer: LookupAnswer): UMPToken | undefined {\n    return this.parseLookupAnswers(answer)[0]\n  }\n\n  private parseLookupAnswers(answer: LookupAnswer): UMPToken[] {\n    if (answer.type !== 'output-list' || answer.outputs.length === 0) return []\n    const tokens: UMPToken[] = []\n    for (const output of answer.outputs) {\n      const token = this.parseLookupOutput(output)\n      if (token != null) tokens.push(token)\n    }\n    return tokens\n  }\n\n  private parseLookupOutput(output: LookupAnswer['outputs'][number]): UMPToken | undefined {\n    try {\n      const tx = Transaction.fromBEEF(output.beef)\n      const txOutput = tx.outputs[output.outputIndex]\n      if (txOutput == null) return undefined\n      const decoded = PushDrop.decode(txOutput.lockingScript)\n      if (decoded.fields == null || decoded.fields.length < 11 || decoded.fields.length > 16) {\n        return undefined\n      }\n\n      const protocolFields = stripVerifiedPushDropSignature(decoded.fields, decoded.lockingPublicKey)\n      if (\n        protocolFields.length < 11 ||\n        protocolFields.slice(0, 11).some(field => field.length === 0 || field.length > MAX_STATE_SNAPSHOT_BYTES)\n      ) {\n        return undefined\n      }\n\n      const kdfVersionFieldIndex = findKdfVersionFieldIndex(protocolFields)\n\n      const token: UMPToken = {\n        passwordSalt: protocolFields[0],\n        passwordPresentationPrimary: protocolFields[1],\n        passwordRecoveryPrimary: protocolFields[2],\n        presentationRecoveryPrimary: protocolFields[3],\n        passwordPrimaryPrivileged: protocolFields[4],\n        presentationRecoveryPrivileged: protocolFields[5],\n        presentationHash: protocolFields[6],\n        recoveryHash: protocolFields[7],\n        presentationKeyEncrypted: protocolFields[8],\n        passwordKeyEncrypted: protocolFields[9],\n        recoveryKeyEncrypted: protocolFields[10],\n        currentOutpoint: `${tx.id('hex')}.${output.outputIndex}`\n      }\n      if (token.presentationHash.length !== 32 || token.recoveryHash.length !== 32) return undefined\n\n      if (!addProfilesField(token, protocolFields, kdfVersionFieldIndex)) return undefined\n      if (!addPasswordKdf(token, protocolFields, kdfVersionFieldIndex)) return undefined\n\n      return token\n    } catch {\n      return undefined\n    }\n  }\n\n  /**\n   * Finds by outpoint for unlocking / spending previous tokens.\n   * @param outpoint The outpoint we are searching by\n   * @returns The result so that we can use it to unlock the transaction\n   */\n  private async findByOutpoint(outpoint: string): Promise<{ beef: number[]; outputIndex: number } | undefined> {\n    const correlationId = this.telemetry.enabled === true ? this.telemetry.createCorrelationId() : undefined\n    const startedAt = Date.now()\n    let resolution: LookupResolution\n    try {\n      resolution = await this.resolver.queryDetailed(\n        {\n          service: 'ls_users',\n          query: {\n            outpoint\n          }\n        },\n        undefined,\n        {\n          waitForAllHosts: true,\n          correlationId\n        }\n      )\n    } catch (error) {\n      const diagnostics = this.emptyLookupDiagnostics(correlationId)\n      this.captureLookupFailure('outpoint', 'lookup-unavailable', diagnostics, startedAt, error)\n      throw new UMPTokenLookupError('lookup-unavailable', diagnostics, { cause: error })\n    }\n    if (resolution.answer.outputs.length === 0) {\n      const p = resolution.progress\n      if (p.emptyHosts === 0) {\n        const diagnostics = this.toLookupDiagnostics(resolution)\n        this.captureLookupFailure('outpoint', 'lookup-incomplete', diagnostics, startedAt)\n        throw new UMPTokenLookupError('lookup-incomplete', diagnostics)\n      }\n      return undefined\n    }\n    return resolution.answer.outputs[0]\n  }\n}\n\n/**\n * Manages a \"CWI-style\" wallet that uses a UMP token and a\n * multi-key authentication scheme (password, presentation key, and recovery key),\n * supporting multiple user profiles under a single account.\n */\nexport class CWIStyleWalletManager implements WalletInterface {\n  /**\n   * Whether the user is currently authenticated (i.e., root keys are available).\n   */\n  authenticated: boolean\n\n  /**\n   * Resolves once the optional snapshot (if provided to the constructor) has been\n   * fully loaded and the wallet is ready to accept calls.\n   * When no snapshot is provided this resolves immediately.\n   * Await `ready` before calling wallet methods after constructing with a snapshot.\n   */\n  get ready(): Promise<void> {\n    this._readyInit ??= this._init()\n    return this._readyInit\n  }\n\n  private _readyInit?: Promise<void>\n\n  private readonly _initSnapshot?: number[]\n\n  /**\n   * The domain name of the administrative originator (wallet operator / vendor, or your own).\n   */\n  private readonly adminOriginator: OriginatorDomainNameStringUnder250Bytes\n\n  /**\n   * The system that locates and publishes UMP tokens on-chain.\n   */\n  private readonly UMPTokenInteractor: UMPTokenInteractor\n\n  /**\n   * Privacy-bounded diagnostic channel for wallet state transitions.\n   */\n  protected readonly telemetry: Telemetry\n\n  /**\n   * A function called to persist the newly generated recovery key.\n   * It should generally trigger a UI prompt where the user is asked to write it down.\n   */\n  private readonly recoveryKeySaver: (key: number[]) => Promise<true>\n\n  /**\n   * Asks the user to enter their password, for a given reason.\n   * The test function can be used to see if the password is correct before resolving.\n   * Only resolve with the correct password or reject with an error.\n   * Resolving with an incorrect password will throw an error.\n   */\n  private readonly passwordRetriever: (\n    reason: string,\n    test: (passwordCandidate: string) => boolean | Promise<boolean>\n  ) => Promise<string>\n\n  /**\n   * Optional function to fund a new Wallet after the new-user flow.\n   */\n  private readonly newWalletFunder?: (\n    presentationKey: number[],\n    wallet: WalletInterface, // The default profile wallet\n    adminOriginator: OriginatorDomainNameStringUnder250Bytes\n  ) => Promise<void>\n\n  /**\n   * Builds the underlying wallet for a specific profile.\n   */\n  private readonly walletBuilder: (\n    profilePrimaryKey: number[],\n    profilePrivilegedKeyManager: PrivilegedKeyManager,\n    profileId: number[]\n  ) => Promise<WalletInterface>\n\n  /**\n   * Current mode of authentication.\n   */\n  authenticationMode:\n    'presentation-key-and-password' | 'presentation-key-and-recovery-key' | 'recovery-key-and-password' =\n    'presentation-key-and-password'\n\n  /**\n   * Indicates new user or existing user flow.\n   */\n  authenticationFlow: 'unknown' | 'new-user' | 'existing-user' = 'unknown'\n\n  /**\n   * The current UMP token in use.\n   */\n  private currentUMPToken?: UMPToken\n\n  /**\n   * Temporarily retained presentation key.\n   */\n  private presentationKey?: number[]\n\n  /**\n   * Temporarily retained recovery key.\n   */\n  private recoveryKey?: number[]\n\n  /**\n   * The user's *root* primary key, derived from authentication factors.\n   */\n  private rootPrimaryKey?: number[]\n\n  /**\n   * The currently active profile ID (null or DEFAULT_PROFILE_ID means default profile).\n   */\n  private activeProfileId: number[] = DEFAULT_PROFILE_ID\n\n  /**\n   * List of loaded non-default profiles.\n   */\n  private profiles: Profile[] = []\n\n  /**\n   * The underlying wallet instance for the *active* profile.\n   */\n  private underlying?: WalletInterface\n\n  /**\n   * Privileged key manager associated with the *root* keys, aware of the active profile.\n   */\n  private rootPrivilegedKeyManager?: PrivilegedKeyManager\n\n  /**\n   * KDF configuration for new UMP tokens. Defaults to Argon2id for v3 tokens.\n   */\n  private readonly kdfConfig: Required<KdfConfig>\n\n  /**\n   * Constructs a new CWIStyleWalletManager.\n   *\n   * @param adminOriginator   The domain name of the administrative originator.\n   * @param walletBuilder     A function that can build an underlying wallet instance for a profile.\n   * @param interactor        An instance of UMPTokenInteractor.\n   * @param recoveryKeySaver  A function to persist a new recovery key.\n   * @param passwordRetriever A function to request the user's password.\n   * @param newWalletFunder   Optional function to fund a new wallet.\n   * @param stateSnapshot     Optional previously saved state snapshot.\n   * @param kdfConfig         Optional KDF configuration for new UMP tokens.\n   */\n  constructor(\n    ...[\n      adminOriginator,\n      walletBuilder,\n      interactor,\n      recoveryKeySaver,\n      passwordRetriever,\n      newWalletFunder,\n      stateSnapshot,\n      kdfConfig,\n      telemetry\n    ]: [\n      adminOriginator: OriginatorDomainNameStringUnder250Bytes,\n      walletBuilder: (\n        profilePrimaryKey: number[],\n        profilePrivilegedKeyManager: PrivilegedKeyManager,\n        profileId: number[]\n      ) => Promise<WalletInterface>,\n      interactor: UMPTokenInteractor | undefined,\n      recoveryKeySaver: (key: number[]) => Promise<true>,\n      passwordRetriever: (\n        reason: string,\n        test: (passwordCandidate: string) => boolean | Promise<boolean>\n      ) => Promise<string>,\n      newWalletFunder?: (\n        presentationKey: number[],\n        wallet: WalletInterface,\n        adminOriginator: OriginatorDomainNameStringUnder250Bytes\n      ) => Promise<void>,\n      stateSnapshot?: number[],\n      kdfConfig?: KdfConfig,\n      telemetry?: TelemetryConfig\n    ]\n  ) {\n    this.adminOriginator = adminOriginator\n    this.walletBuilder = walletBuilder\n    this.telemetry = new Telemetry(telemetry)\n    this.UMPTokenInteractor = interactor ?? new OverlayUMPTokenInteractor(undefined, undefined, telemetry)\n    this.recoveryKeySaver = recoveryKeySaver\n    this.passwordRetriever = passwordRetriever\n    this.authenticated = false\n    this.newWalletFunder = newWalletFunder\n\n    // Initialize KDF config with Argon2id defaults for v3 tokens\n    const kdfAlgorithm = kdfConfig?.algorithm ?? 'argon2id'\n    this.kdfConfig = {\n      algorithm: kdfAlgorithm,\n      iterations:\n        kdfConfig?.iterations ?? (kdfAlgorithm === 'argon2id' ? ARGON2ID_DEFAULT_ITERATIONS : PBKDF2_NUM_ROUNDS),\n      memoryKiB: kdfConfig?.memoryKiB ?? ARGON2ID_DEFAULT_MEMORY_KIB,\n      parallelism: kdfConfig?.parallelism ?? ARGON2ID_DEFAULT_PARALLELISM,\n      hashLength: kdfConfig?.hashLength ?? ARGON2ID_DEFAULT_HASH_LENGTH\n    }\n    if (!isValidKdfConfig(this.kdfConfig)) {\n      throw new Error('Unsupported or unsafe KDF configuration.')\n    }\n\n    // Store snapshot for lazy init; callers await ready before calling wallet methods.\n    this._initSnapshot = stateSnapshot\n  }\n\n  private async _init(): Promise<void> {\n    if (this._initSnapshot !== undefined) {\n      this.telemetry.capture({\n        name: 'wallet-toolbox.snapshot.initialization.started',\n        component: 'wallet-toolbox.cwi-manager',\n        severity: 'debug'\n      })\n      try {\n        await this.loadSnapshot(this._initSnapshot)\n        this.telemetry.capture({\n          name: 'wallet-toolbox.snapshot.initialization.completed',\n          component: 'wallet-toolbox.cwi-manager',\n          severity: 'info'\n        })\n      } catch (error) {\n        this.telemetry.capture({\n          name: 'wallet-toolbox.snapshot.initialization.failed',\n          component: 'wallet-toolbox.cwi-manager',\n          severity: 'error',\n          error\n        })\n        throw error\n      }\n    }\n  }\n\n  // --- Authentication Methods ---\n\n  /**\n   * Provides the presentation key.\n   */\n  async providePresentationKey(key: number[]): Promise<void> {\n    if (this.authenticated) {\n      throw new Error('User is already authenticated')\n    }\n    if (this.authenticationMode === 'recovery-key-and-password') {\n      throw new Error('Presentation key is not needed in this mode')\n    }\n    if (key.length !== 32 || key.some(byte => !Number.isInteger(byte) || byte < 0 || byte > 255)) {\n      throw new TypeError('Presentation key must contain exactly 32 bytes.')\n    }\n\n    this.authenticationFlow = 'unknown'\n    const hash = Hash.sha256(key)\n    const startedAt = Date.now()\n    this.telemetry.capture({\n      name: 'wallet-toolbox.authentication.account-lookup.started',\n      component: 'wallet-toolbox.cwi-manager',\n      severity: 'debug',\n      attributes: { lookupKind: 'presentation' }\n    })\n    let token: UMPToken | undefined\n    try {\n      token = await this.UMPTokenInteractor.findByPresentationKeyHash(hash)\n    } catch (error) {\n      this.telemetry.capture({\n        name: 'wallet-toolbox.authentication.account-lookup.failed',\n        component: 'wallet-toolbox.cwi-manager',\n        severity: 'warn',\n        attributes: {\n          lookupKind: 'presentation',\n          durationMs: Date.now() - startedAt\n        },\n        error\n      })\n      throw error\n    }\n\n    if (token == null) {\n      // No token found -> New user\n      this.authenticationFlow = 'new-user'\n      this.presentationKey = key\n    } else {\n      // Found token -> existing user\n      this.authenticationFlow = 'existing-user'\n      this.presentationKey = key\n      this.currentUMPToken = token\n    }\n    this.telemetry.capture({\n      name: 'wallet-toolbox.authentication.account-lookup.completed',\n      component: 'wallet-toolbox.cwi-manager',\n      severity: 'info',\n      attributes: {\n        lookupKind: 'presentation',\n        accountStatus: this.authenticationFlow,\n        durationMs: Date.now() - startedAt\n      }\n    })\n  }\n\n  /**\n   * Provides the password.\n   */\n  async providePassword(password: string): Promise<void> {\n    if (this.authenticated) throw new Error('User is already authenticated')\n    if (this.authenticationMode === 'presentation-key-and-recovery-key') {\n      throw new Error('Password is not needed in this mode')\n    }\n    if (this.authenticationFlow === 'unknown') {\n      throw new Error('Determine account status with a presentation or recovery key before providing a password.')\n    }\n    if (this.authenticationFlow === 'existing-user') {\n      await this.handleExistingUserPassword(password)\n    } else {\n      await this.handleNewUserPassword(password)\n    }\n  }\n\n  /** Handles the password step for an existing user — derives keys, sets up infrastructure. */\n  private async handleExistingUserPassword(password: string): Promise<void> {\n    if (this.currentUMPToken == null) throw new Error('Provide presentation or recovery key first.')\n    const derivedPasswordKey = await derivePasswordKey(this.currentUMPToken, Utils.toArray(password, 'utf8'))\n    let rootPrimaryKey: number[]\n    let rootPrivilegedKey: number[] | undefined\n\n    if (this.authenticationMode === 'presentation-key-and-password') {\n      if (this.presentationKey == null) throw new Error('No presentation key found!')\n      rootPrimaryKey = new SymmetricKey(this.XOR(this.presentationKey, derivedPasswordKey)).decrypt(\n        this.currentUMPToken.passwordPresentationPrimary\n      ) as number[]\n    } else {\n      // 'recovery-key-and-password'\n      if (this.recoveryKey == null) throw new Error('No recovery key found!')\n      const primaryDecryptionKey = this.XOR(this.recoveryKey, derivedPasswordKey)\n      rootPrimaryKey = new SymmetricKey(primaryDecryptionKey).decrypt(\n        this.currentUMPToken.passwordRecoveryPrimary\n      ) as number[]\n      rootPrivilegedKey = new SymmetricKey(this.XOR(rootPrimaryKey, derivedPasswordKey)).decrypt(\n        this.currentUMPToken.passwordPrimaryPrivileged\n      ) as number[]\n    }\n    await this.setupRootInfrastructure(rootPrimaryKey, rootPrivilegedKey)\n    await this.switchProfile(this.activeProfileId)\n  }\n\n  /** Handles the password step for a new user — generates keys, builds UMP token, publishes on-chain. */\n  private async handleNewUserPassword(password: string): Promise<void> {\n    if (this.authenticationMode !== 'presentation-key-and-password') {\n      throw new Error('New-user flow requires presentation key and password mode.')\n    }\n    if (this.presentationKey == null) throw new Error('No presentation key provided for new-user flow.')\n\n    // Generate new keys/salt\n    const recoveryKey = Random(32)\n    await this.recoveryKeySaver(recoveryKey)\n    const passwordSalt = Random(32)\n    const passwordKey = await derivePasswordKey(\n      { passwordSalt, passwordKdf: this.kdfConfig },\n      Utils.toArray(password, 'utf8')\n    )\n    const rootPrimaryKey = Random(32)\n    const rootPrivilegedKey = Random(32)\n\n    // Build XOR-combined symmetric keys\n    const presentationPassword = new SymmetricKey(this.XOR(this.presentationKey, passwordKey))\n    const presentationRecovery = new SymmetricKey(this.XOR(this.presentationKey, recoveryKey))\n    const recoveryPassword = new SymmetricKey(this.XOR(recoveryKey, passwordKey))\n    const primaryPassword = new SymmetricKey(this.XOR(rootPrimaryKey, passwordKey))\n\n    const tempPrivilegedKeyManager = new PrivilegedKeyManager(async () => new PrivateKey(rootPrivilegedKey))\n    const wrapKey = async (plaintext: number[]): Promise<number[]> =>\n      (await tempPrivilegedKeyManager.encrypt({ plaintext, protocolID: [2, 'admin key wrapping'], keyID: '1' }))\n        .ciphertext\n\n    // Build new UMP token (v3 with KDF metadata, no profiles initially)\n    const newToken: UMPToken = {\n      passwordSalt,\n      passwordPresentationPrimary: presentationPassword.encrypt(rootPrimaryKey) as number[],\n      passwordRecoveryPrimary: recoveryPassword.encrypt(rootPrimaryKey) as number[],\n      presentationRecoveryPrimary: presentationRecovery.encrypt(rootPrimaryKey) as number[],\n      passwordPrimaryPrivileged: primaryPassword.encrypt(rootPrivilegedKey) as number[],\n      presentationRecoveryPrivileged: presentationRecovery.encrypt(rootPrivilegedKey) as number[],\n      presentationHash: Hash.sha256(this.presentationKey),\n      recoveryHash: Hash.sha256(recoveryKey),\n      presentationKeyEncrypted: await wrapKey(this.presentationKey),\n      passwordKeyEncrypted: await wrapKey(passwordKey),\n      recoveryKeyEncrypted: await wrapKey(recoveryKey),\n      profilesEncrypted: undefined,\n      umpVersion: 3,\n      passwordKdf: this.kdfConfig\n    }\n    this.currentUMPToken = newToken\n\n    await this.setupRootInfrastructure(rootPrimaryKey)\n    await this.switchProfile(DEFAULT_PROFILE_ID)\n\n    // Fund the *default* wallet if funder provided\n    if (this.newWalletFunder != null && this.underlying != null) {\n      try {\n        await this.newWalletFunder(this.presentationKey, this.underlying, this.adminOriginator)\n      } catch (error) {\n        this.telemetry.capture({\n          name: 'wallet-toolbox.authentication.new-wallet-funding.failed',\n          component: 'wallet-toolbox.cwi-manager',\n          severity: 'error',\n          error: new Error('New wallet funding failed.')\n        })\n        const message = error instanceof Error ? error.message : String(error)\n        throw new Error(`Failed to fund new wallet before publishing UMP token: ${message}`, { cause: error })\n      }\n    }\n\n    if (this.underlying == null)\n      throw new Error('Default profile wallet not built before attempting to publish UMP token.')\n    this.currentUMPToken.currentOutpoint = await this.UMPTokenInteractor.buildAndSend(\n      this.underlying,\n      this.adminOriginator,\n      newToken\n    )\n  }\n\n  /**\n   * Provides the recovery key.\n   */\n  async provideRecoveryKey(recoveryKey: number[]): Promise<void> {\n    if (this.authenticated) {\n      throw new Error('Already authenticated')\n    }\n    if (this.authenticationFlow === 'new-user' && this.authenticationMode !== 'recovery-key-and-password') {\n      throw new Error('Do not submit recovery key in new-user flow')\n    }\n    if (this.authenticationMode === 'presentation-key-and-password') {\n      throw new Error('No recovery key required in this mode')\n    }\n    if (recoveryKey.length !== 32 || recoveryKey.some(byte => !Number.isInteger(byte) || byte < 0 || byte > 255)) {\n      throw new TypeError('Recovery key must contain exactly 32 bytes.')\n    }\n\n    if (this.authenticationMode === 'recovery-key-and-password') {\n      // Wait for password\n      const hash = Hash.sha256(recoveryKey)\n      const token = await this.UMPTokenInteractor.findByRecoveryKeyHash(hash)\n      if (token == null) throw new Error('No user found with this recovery key')\n      this.authenticationFlow = 'existing-user'\n      this.recoveryKey = recoveryKey\n      this.currentUMPToken = token\n    } else {\n      // 'presentation-key-and-recovery-key'\n      if (this.presentationKey == null) throw new Error('Provide the presentation key first')\n      if (this.currentUMPToken == null) throw new Error('Current UMP token not found')\n\n      const xorKey = this.XOR(this.presentationKey, recoveryKey)\n      const rootPrimaryKey = new SymmetricKey(xorKey).decrypt(\n        this.currentUMPToken.presentationRecoveryPrimary\n      ) as number[]\n      const rootPrivilegedKey = new SymmetricKey(xorKey).decrypt(\n        this.currentUMPToken.presentationRecoveryPrivileged\n      ) as number[]\n\n      // Build root infrastructure, load profiles, switch to default\n      await this.setupRootInfrastructure(rootPrimaryKey, rootPrivilegedKey)\n      await this.switchProfile(this.activeProfileId)\n    }\n  }\n\n  // --- State Management Methods ---\n\n  /**\n   * Saves the current wallet state (root key, UMP token, active profile) into an encrypted snapshot.\n   * Version 2 format: [1 byte version=2] + [32 byte snapshot key] + [16 byte activeProfileId] + [encrypted payload]\n   * Encrypted Payload: [32 byte rootPrimaryKey] + [varint token length + serialized UMP token]\n   *\n   * @returns Encrypted snapshot bytes.\n   */\n  saveSnapshot(): number[] {\n    if (this.rootPrimaryKey == null || this.currentUMPToken == null) {\n      throw new Error('No root primary key or current UMP token set')\n    }\n\n    const snapshotKey = Random(32)\n    const snapshotPreimageWriter = new Utils.Writer()\n\n    // Write root primary key\n    snapshotPreimageWriter.write(this.rootPrimaryKey)\n\n    // Write serialized UMP token (must have outpoint)\n    if (!this.currentUMPToken.currentOutpoint) {\n      throw new Error('UMP token cannot be saved without a current outpoint.')\n    }\n    const serializedToken = this.serializeUMPToken(this.currentUMPToken)\n    snapshotPreimageWriter.writeVarIntNum(serializedToken.length)\n    snapshotPreimageWriter.write(serializedToken)\n\n    // Encrypt the payload\n    const snapshotPreimage = snapshotPreimageWriter.toArray()\n    const snapshotPayload = new SymmetricKey(snapshotKey).encrypt(snapshotPreimage) as number[]\n\n    // Build final snapshot (Version 2)\n    const snapshotWriter = new Utils.Writer()\n    snapshotWriter.writeUInt8(2) // Version\n    snapshotWriter.write(snapshotKey)\n    snapshotWriter.write(this.activeProfileId) // Active profile ID\n    snapshotWriter.write(snapshotPayload) // Encrypted data\n\n    const snapshot = snapshotWriter.toArray()\n    if (snapshot.length > MAX_STATE_SNAPSHOT_BYTES) {\n      throw new Error('Snapshot exceeds the maximum supported size.')\n    }\n    this.telemetry.capture({\n      name: 'wallet-toolbox.snapshot.saved',\n      component: 'wallet-toolbox.cwi-manager',\n      severity: 'info',\n      attributes: {\n        formatVersion: 2,\n        profileCount: this.profiles.length\n      }\n    })\n    return snapshot\n  }\n\n  /**\n   * Loads a previously saved state snapshot. Restores root key, UMP token, profiles, and active profile.\n   * Handles Version 1 (legacy) and Version 2 formats.\n   *\n   * @param snapshot Encrypted snapshot bytes.\n   */\n  async loadSnapshot(snapshot: number[]): Promise<void> {\n    try {\n      if (\n        snapshot.length === 0 ||\n        snapshot.length > MAX_STATE_SNAPSHOT_BYTES ||\n        snapshot.some(byte => !Number.isInteger(byte) || byte < 0 || byte > 255)\n      ) {\n        throw new Error('Snapshot is empty, oversized, or contains invalid bytes.')\n      }\n      const reader = new Utils.Reader(snapshot)\n      const version = reader.readUInt8()\n\n      let snapshotKey: number[]\n      let encryptedPayload: number[]\n      let activeProfileId = DEFAULT_PROFILE_ID // Default for V1\n\n      if (version === 1) {\n        snapshotKey = reader.read(32)\n        encryptedPayload = reader.read()\n      } else if (version === 2) {\n        snapshotKey = reader.read(32)\n        activeProfileId = reader.read(16) // Read active profile ID\n        encryptedPayload = reader.read()\n      } else {\n        throw new Error(`Unsupported snapshot version: ${version}`)\n      }\n\n      // Decrypt payload\n      const decryptedPayload = new SymmetricKey(snapshotKey).decrypt(encryptedPayload) as number[]\n      const payloadReader = new Utils.Reader(decryptedPayload)\n\n      // Read root primary key\n      const rootPrimaryKey = payloadReader.read(32)\n\n      // Read serialized UMP token\n      const tokenLen = payloadReader.readVarIntNum()\n      const tokenBytes = payloadReader.read(tokenLen)\n      const token = this.deserializeUMPToken(tokenBytes)\n\n      // Assign loaded data\n      this.currentUMPToken = token\n\n      // Setup root infrastructure, load profiles, and switch to the loaded active profile\n      await this.setupRootInfrastructure(rootPrimaryKey) // Will automatically load profiles\n      await this.switchProfile(activeProfileId) // Switch to the profile saved in the snapshot\n\n      this.authenticationFlow = 'existing-user' // Loading implies existing user\n      this.telemetry.capture({\n        name: 'wallet-toolbox.snapshot.loaded',\n        component: 'wallet-toolbox.cwi-manager',\n        severity: 'info',\n        attributes: {\n          formatVersion: version,\n          profileCount: this.profiles.length\n        }\n      })\n    } catch (error) {\n      this.destroy() // Clear state on error\n      this.telemetry.capture({\n        name: 'wallet-toolbox.snapshot.load-failed',\n        component: 'wallet-toolbox.cwi-manager',\n        severity: 'error',\n        error\n      })\n      const message = error instanceof Error ? error.message : 'Unknown error'\n      throw new Error(`Failed to load snapshot: ${message}`, { cause: error })\n    }\n  }\n\n  async syncUMPToken(): Promise<boolean> {\n    if (!this.authenticated || this.currentUMPToken == null || this.rootPrimaryKey == null) {\n      throw new Error('Wallet not authenticated or missing UMP token.')\n    }\n\n    const currentToken = this.currentUMPToken\n    let refreshed: UMPToken | undefined\n\n    if (currentToken.presentationHash && currentToken.presentationHash.length > 0) {\n      refreshed = await this.UMPTokenInteractor.findByPresentationKeyHash(currentToken.presentationHash)\n    }\n\n    if (refreshed == null && currentToken.recoveryHash && currentToken.recoveryHash.length > 0) {\n      refreshed = await this.UMPTokenInteractor.findByRecoveryKeyHash(currentToken.recoveryHash)\n    }\n\n    if (refreshed == null) {\n      return false\n    }\n\n    if (\n      refreshed.currentOutpoint &&\n      currentToken.currentOutpoint &&\n      refreshed.currentOutpoint === currentToken.currentOutpoint\n    ) {\n      return false\n    }\n\n    this.currentUMPToken = refreshed\n    await this.setupRootInfrastructure(this.rootPrimaryKey)\n    this.saveSnapshot()\n    return true\n  }\n\n  /**\n   * Destroys the wallet state, clearing keys, tokens, and profiles.\n   */\n  destroy(): void {\n    this.underlying = undefined\n    this.rootPrivilegedKeyManager = undefined\n    this.authenticated = false\n    this.rootPrimaryKey = undefined\n    this.currentUMPToken = undefined\n    this.presentationKey = undefined\n    this.recoveryKey = undefined\n    this.profiles = []\n    this.activeProfileId = DEFAULT_PROFILE_ID\n    this.authenticationMode = 'presentation-key-and-password'\n    this.authenticationFlow = 'unknown'\n  }\n\n  // --- Profile Management Methods ---\n\n  /**\n   * Lists all available profiles, including the default profile.\n   * @returns Array of profile info objects, including an 'active' flag.\n   */\n  listProfiles(): Array<{\n    id: number[]\n    name: string\n    createdAt: number | null\n    active: boolean\n    identityKey: string\n  }> {\n    if (!this.authenticated) {\n      throw new Error('Not authenticated.')\n    }\n    const profileList = [\n      // Default profile\n      {\n        id: DEFAULT_PROFILE_ID,\n        name: 'default',\n        createdAt: null, // Default profile doesn't have a creation timestamp in the same way\n        active: this.activeProfileId.every(x => x === 0),\n        identityKey: new PrivateKey(this.rootPrimaryKey).toPublicKey().toString()\n      },\n      // Other profiles\n      ...this.profiles.map(p => ({\n        id: p.id,\n        name: p.name,\n        createdAt: p.createdAt,\n        active: this.activeProfileId.every((x, i) => x === p.id[i]),\n        identityKey: new PrivateKey(this.XOR(this.rootPrimaryKey as number[], p.primaryPad)).toPublicKey().toString()\n      }))\n    ]\n    return profileList\n  }\n\n  /**\n   * Adds a new profile with the given name.\n   * Generates necessary pads and updates the UMP token.\n   * Does not switch to the new profile automatically.\n   *\n   * @param name The desired name for the new profile.\n   * @returns The ID of the newly created profile.\n   */\n  async addProfile(name: string): Promise<number[]> {\n    if (\n      !this.authenticated ||\n      this.rootPrimaryKey == null ||\n      this.currentUMPToken == null ||\n      this.rootPrivilegedKeyManager == null\n    ) {\n      throw new Error('Wallet not fully initialized or authenticated.')\n    }\n\n    // Ensure name is unique (including 'default')\n    if (name === 'default' || this.profiles.some(p => p.name.toLowerCase() === name.toLowerCase())) {\n      throw new Error(`Profile name \"${name}\" is already in use.`)\n    }\n\n    const newProfile: Profile = {\n      name,\n      id: Random(16),\n      primaryPad: Random(32),\n      privilegedPad: Random(32),\n      createdAt: Math.floor(Date.now() / 1000)\n    }\n\n    this.profiles.push(newProfile)\n\n    // Update the UMP token with the new profile list\n    await this.updateAuthFactors(\n      this.currentUMPToken.passwordSalt,\n      // Need to re-derive/decrypt factors needed for re-encryption\n      await this.getFactor('passwordKey'),\n      await this.getFactor('presentationKey'),\n      await this.getFactor('recoveryKey'),\n      this.rootPrimaryKey,\n      await this.getFactor('privilegedKey'), // Get ROOT privileged key\n      this.profiles // Pass the updated profile list\n    )\n\n    return newProfile.id\n  }\n\n  /**\n   * Deletes a profile by its ID.\n   * Cannot delete the default profile. If the active profile is deleted,\n   * it switches back to the default profile.\n   *\n   * @param profileId The 16-byte ID of the profile to delete.\n   */\n  async deleteProfile(profileId: number[]): Promise<void> {\n    if (\n      !this.authenticated ||\n      this.rootPrimaryKey == null ||\n      this.currentUMPToken == null ||\n      this.rootPrivilegedKeyManager == null\n    ) {\n      throw new Error('Wallet not fully initialized or authenticated.')\n    }\n    if (profileId.every(x => x === 0)) {\n      throw new Error('Cannot delete the default profile.')\n    }\n\n    const profileIndex = this.profiles.findIndex(p => p.id.every((x, i) => x === profileId[i]))\n    if (profileIndex === -1) {\n      throw new Error('Profile not found.')\n    }\n\n    // Remove the profile\n    this.profiles.splice(profileIndex, 1)\n\n    // If the deleted profile was active, switch to default\n    if (this.activeProfileId.every((x, i) => x === profileId[i])) {\n      await this.switchProfile(DEFAULT_PROFILE_ID) // This rebuilds the wallet\n    }\n\n    // Update the UMP token\n    await this.updateAuthFactors(\n      this.currentUMPToken.passwordSalt,\n      await this.getFactor('passwordKey'),\n      await this.getFactor('presentationKey'),\n      await this.getFactor('recoveryKey'),\n      this.rootPrimaryKey,\n      await this.getFactor('privilegedKey'), // Get ROOT privileged key\n      this.profiles // Pass updated list\n    )\n  }\n\n  /**\n   * Switches the active profile. This re-derives keys and rebuilds the underlying wallet.\n   *\n   * @param profileId The 16-byte ID of the profile to switch to (use DEFAULT_PROFILE_ID for default).\n   */\n  async switchProfile(profileId: number[]): Promise<void> {\n    if (!this.authenticated || this.rootPrimaryKey == null || this.rootPrivilegedKeyManager == null) {\n      throw new Error('Cannot switch profile: Wallet not authenticated or root keys missing.')\n    }\n\n    let profilePrimaryKey: number[]\n    let profilePrivilegedPad: number[] | undefined // Pad for the target profile\n\n    if (profileId.every(x => x === 0)) {\n      // Switching to default profile\n      profilePrimaryKey = this.rootPrimaryKey\n      profilePrivilegedPad = undefined // No pad for default\n      this.activeProfileId = DEFAULT_PROFILE_ID\n    } else {\n      // Switching to a non-default profile\n      const profile = this.profiles.find(p => p.id.every((x, i) => x === profileId[i]))\n      if (profile == null) {\n        throw new Error('Profile not found.')\n      }\n      profilePrimaryKey = this.XOR(this.rootPrimaryKey, profile.primaryPad)\n      profilePrivilegedPad = profile.privilegedPad\n      this.activeProfileId = profileId\n    }\n\n    // Create a *profile-specific* PrivilegedKeyManager.\n    // It uses the ROOT manager internally but applies the profile's pad.\n    const profilePrivilegedKeyManager = new PrivilegedKeyManager(async (reason: string) => {\n      // Request the ROOT privileged key using the root manager\n      const rootPrivileged: PrivateKey = await (this.rootPrivilegedKeyManager as any).getPrivilegedKey(reason)\n      const rootPrivilegedBytes = rootPrivileged.toArray()\n\n      // Apply the profile's pad if applicable\n      const profilePrivilegedBytes =\n        profilePrivilegedPad == null ? rootPrivilegedBytes : this.XOR(rootPrivilegedBytes, profilePrivilegedPad)\n\n      return new PrivateKey(profilePrivilegedBytes)\n    })\n\n    // Build the underlying wallet for the specific profile\n    this.underlying = await this.walletBuilder(\n      profilePrimaryKey,\n      profilePrivilegedKeyManager, // Pass the profile-specific manager\n      this.activeProfileId // Pass the ID of the profile being activated\n    )\n  }\n\n  // --- Key Management Methods ---\n\n  /**\n   * Changes the user's password. Re-wraps keys and updates the UMP token.\n   */\n  async changePassword(newPassword: string): Promise<void> {\n    if (\n      !this.authenticated ||\n      this.currentUMPToken == null ||\n      this.rootPrimaryKey == null ||\n      this.rootPrivilegedKeyManager == null\n    ) {\n      throw new Error('Not authenticated or missing required data.')\n    }\n\n    const passwordSalt = Random(32)\n    // Preserve current token's KDF metadata (or use manager's kdfConfig for legacy tokens)\n    const kdfToUse = this.currentUMPToken.passwordKdf ?? this.kdfConfig\n    const tempTokenForKdf = {\n      passwordSalt,\n      passwordKdf: kdfToUse\n    }\n    const newPasswordKey = await derivePasswordKey(tempTokenForKdf, Utils.toArray(newPassword, 'utf8'))\n\n    // Decrypt existing factors needed for re-encryption, using the *root* privileged key manager\n    const recoveryKey = await this.getFactor('recoveryKey')\n    const presentationKey = await this.getFactor('presentationKey')\n    const rootPrivilegedKey = await this.getFactor('privilegedKey') // Get ROOT privileged key\n\n    await this.updateAuthFactors(\n      passwordSalt,\n      newPasswordKey,\n      presentationKey,\n      recoveryKey,\n      this.rootPrimaryKey,\n      rootPrivilegedKey, // Pass the explicitly fetched root key\n      this.profiles // Preserve existing profiles\n    )\n  }\n\n  /**\n   * Retrieves the current recovery key. Requires privileged access.\n   */\n  async getRecoveryKey(): Promise<number[]> {\n    if (!this.authenticated || this.currentUMPToken == null || this.rootPrivilegedKeyManager == null) {\n      throw new Error('Not authenticated or missing required data.')\n    }\n    return await this.getFactor('recoveryKey')\n  }\n\n  /**\n   * Changes the user's recovery key. Prompts user to save the new key.\n   */\n  async changeRecoveryKey(): Promise<void> {\n    if (\n      !this.authenticated ||\n      this.currentUMPToken == null ||\n      this.rootPrimaryKey == null ||\n      this.rootPrivilegedKeyManager == null\n    ) {\n      throw new Error('Not authenticated or missing required data.')\n    }\n\n    // Decrypt existing factors needed\n    const passwordKey = await this.getFactor('passwordKey')\n    const presentationKey = await this.getFactor('presentationKey')\n    const rootPrivilegedKey = await this.getFactor('privilegedKey') // Get ROOT privileged key\n\n    // Generate and save new recovery key\n    const newRecoveryKey = Random(32)\n    await this.recoveryKeySaver(newRecoveryKey)\n\n    await this.updateAuthFactors(\n      this.currentUMPToken.passwordSalt,\n      passwordKey,\n      presentationKey,\n      newRecoveryKey, // Use the new key\n      this.rootPrimaryKey,\n      rootPrivilegedKey,\n      this.profiles // Preserve profiles\n    )\n  }\n\n  /**\n   * Changes the user's presentation key.\n   */\n  async changePresentationKey(newPresentationKey: number[]): Promise<void> {\n    if (\n      !this.authenticated ||\n      this.currentUMPToken == null ||\n      this.rootPrimaryKey == null ||\n      this.rootPrivilegedKeyManager == null\n    ) {\n      throw new Error('Not authenticated or missing required data.')\n    }\n    if (newPresentationKey.length !== 32) {\n      throw new Error('Presentation key must be 32 bytes.')\n    }\n\n    // Decrypt existing factors\n    const recoveryKey = await this.getFactor('recoveryKey')\n    const passwordKey = await this.getFactor('passwordKey')\n    const rootPrivilegedKey = await this.getFactor('privilegedKey') // Get ROOT privileged key\n\n    await this.updateAuthFactors(\n      this.currentUMPToken.passwordSalt,\n      passwordKey,\n      newPresentationKey, // Use the new key\n      recoveryKey,\n      this.rootPrimaryKey,\n      rootPrivilegedKey,\n      this.profiles // Preserve profiles\n    )\n    // Update the temporarily stored key if it was set\n    if (this.presentationKey != null) {\n      this.presentationKey = newPresentationKey\n    }\n  }\n\n  // --- Internal Helper Methods ---\n\n  /**\n   * Performs XOR operation on two byte arrays.\n   */\n  private XOR(n1: number[], n2: number[]): number[] {\n    if (n1.length !== n2.length) {\n      // Provide more context in error\n      throw new Error(`XOR length mismatch: ${n1.length} vs ${n2.length}`)\n    }\n    const r = Array.from({ length: n1.length }, () => 0)\n    for (let i = 0; i < n1.length; i++) {\n      r[i] = n1[i] ^ n2[i]\n    }\n    return r\n  }\n\n  /**\n   * Helper to decrypt a specific factor (key) stored encrypted in the UMP token.\n   * Requires the root privileged key manager.\n   * @param factorName Name of the factor to decrypt ('passwordKey', 'presentationKey', 'recoveryKey', 'privilegedKey').\n   * @param getRoot If true and factorName is 'privilegedKey', returns the root privileged key bytes directly.\n   * @returns The decrypted key bytes.\n   */\n  private async getFactor(\n    factorName: 'passwordKey' | 'presentationKey' | 'recoveryKey' | 'privilegedKey'\n  ): Promise<number[]> {\n    if (!this.authenticated || this.currentUMPToken == null || this.rootPrivilegedKeyManager == null) {\n      throw new Error(`Cannot get factor \"${factorName}\": Wallet not ready.`)\n    }\n\n    const protocolID: [0 | 1 | 2, string] = [2, 'admin key wrapping'] // Protocol used for encrypting factors\n    const keyID = '1' // Key ID used\n\n    try {\n      switch (factorName) {\n        case 'passwordKey':\n          return (\n            await this.rootPrivilegedKeyManager.decrypt({\n              ciphertext: this.currentUMPToken.passwordKeyEncrypted,\n              protocolID,\n              keyID\n            })\n          ).plaintext\n        case 'presentationKey':\n          return (\n            await this.rootPrivilegedKeyManager.decrypt({\n              ciphertext: this.currentUMPToken.presentationKeyEncrypted,\n              protocolID,\n              keyID\n            })\n          ).plaintext\n        case 'recoveryKey':\n          return (\n            await this.rootPrivilegedKeyManager.decrypt({\n              ciphertext: this.currentUMPToken.recoveryKeyEncrypted,\n              protocolID,\n              keyID\n            })\n          ).plaintext\n        case 'privilegedKey': {\n          // This needs careful handling based on whether the ROOT or PROFILE key is needed.\n          // This helper is mostly used for UMP updates, which need the ROOT key.\n          // We retrieve the PrivateKey object first.\n          const pk = await (this.rootPrivilegedKeyManager as any).getPrivilegedKey('UMP token update', true) // Force retrieval of root key\n          return pk.toArray() // Return bytes\n        }\n        default:\n          throw new Error(`Unknown factor name: ${factorName}`)\n      }\n    } catch (error) {\n      this.telemetry.capture({\n        name: 'wallet-toolbox.authentication.factor-decryption.failed',\n        component: 'wallet-toolbox.cwi-manager',\n        severity: 'error',\n        attributes: { factor: factorName },\n        error\n      })\n      const message = error instanceof Error ? error.message : 'Unknown error'\n      throw new Error(`Failed to decrypt factor \"${factorName}\": ${message}`, { cause: error })\n    }\n  }\n\n  /**\n   * Recomputes UMP token fields with updated factors and profiles, then publishes the update.\n   * This operation requires the *root* privileged key and the *default* profile wallet.\n   */\n  private async updateAuthFactors(\n    passwordSalt: number[],\n    passwordKey: number[],\n    presentationKey: number[],\n    recoveryKey: number[],\n    rootPrimaryKey: number[],\n    rootPrivilegedKey: number[], // Explicitly pass the root key bytes\n    profiles?: Profile[] // Pass current/new profiles list\n  ): Promise<void> {\n    if (!this.authenticated || this.rootPrimaryKey == null || this.currentUMPToken == null) {\n      throw new Error('Wallet is not properly authenticated or missing data for update.')\n    }\n    // Ensure we have the OLD token to consume\n    const oldTokenToConsume = { ...this.currentUMPToken }\n    if (!oldTokenToConsume.currentOutpoint) {\n      throw new Error('Cannot update UMP token: Old token has no outpoint.')\n    }\n\n    // Derive symmetrical encryption keys using XOR for the *root* keys\n    const presentationPassword = new SymmetricKey(this.XOR(presentationKey, passwordKey))\n    const presentationRecovery = new SymmetricKey(this.XOR(presentationKey, recoveryKey))\n    const recoveryPassword = new SymmetricKey(this.XOR(recoveryKey, passwordKey))\n    const primaryPassword = new SymmetricKey(this.XOR(rootPrimaryKey, passwordKey)) // Use rootPrimaryKey\n\n    // Build a temporary privileged key manager using the explicit ROOT privileged key\n    const tempRootPrivilegedKeyManager = new PrivilegedKeyManager(async () => new PrivateKey(rootPrivilegedKey))\n\n    // Encrypt profiles if provided\n    let profilesEncrypted: number[] | undefined\n    if (profiles != null && profiles.length > 0) {\n      const profilesJson = JSON.stringify(profiles)\n      const profilesBytes = Utils.toArray(profilesJson, 'utf8')\n      profilesEncrypted = new SymmetricKey(rootPrimaryKey).encrypt(profilesBytes) as number[]\n    }\n\n    // Construct the new UMP token data.\n    // IMPORTANT: For non-password updates (e.g. add/remove profile), preserve legacy\n    // KDF layout exactly. Upgrading legacy tokens to v3 here would require re-deriving\n    // passwordKey from plaintext password, which we do not have in this code path.\n    const kdfMetadata = this.currentUMPToken.passwordKdf\n    const newTokenData: UMPToken = {\n      passwordSalt,\n      passwordPresentationPrimary: presentationPassword.encrypt(rootPrimaryKey) as number[],\n      passwordRecoveryPrimary: recoveryPassword.encrypt(rootPrimaryKey) as number[],\n      presentationRecoveryPrimary: presentationRecovery.encrypt(rootPrimaryKey) as number[],\n      passwordPrimaryPrivileged: primaryPassword.encrypt(rootPrivilegedKey) as number[],\n      presentationRecoveryPrivileged: presentationRecovery.encrypt(rootPrivilegedKey) as number[],\n      presentationHash: Hash.sha256(presentationKey),\n      recoveryHash: Hash.sha256(recoveryKey),\n      presentationKeyEncrypted: (\n        await tempRootPrivilegedKeyManager.encrypt({\n          plaintext: presentationKey,\n          protocolID: [2, 'admin key wrapping'],\n          keyID: '1'\n        })\n      ).ciphertext,\n      passwordKeyEncrypted: (\n        await tempRootPrivilegedKeyManager.encrypt({\n          plaintext: passwordKey,\n          protocolID: [2, 'admin key wrapping'],\n          keyID: '1'\n        })\n      ).ciphertext,\n      recoveryKeyEncrypted: (\n        await tempRootPrivilegedKeyManager.encrypt({\n          plaintext: recoveryKey,\n          protocolID: [2, 'admin key wrapping'],\n          keyID: '1'\n        })\n      ).ciphertext,\n      profilesEncrypted, // Add encrypted profiles\n      ...(kdfMetadata == null\n        ? {}\n        : {\n            umpVersion: 3,\n            passwordKdf: kdfMetadata\n          })\n      // currentOutpoint will be set after publishing\n    }\n\n    // We need the wallet built for the DEFAULT profile to publish the UMP token.\n    // If the current active profile is not default, temporarily switch, publish, then switch back.\n    const currentActiveId = this.activeProfileId\n    let walletToUse: WalletInterface | undefined = this.underlying\n\n    if (!currentActiveId.every(x => x === 0)) {\n      this.telemetry.capture({\n        name: 'wallet-toolbox.ump.profile-switch.started',\n        component: 'wallet-toolbox.cwi-manager',\n        severity: 'debug',\n        attributes: { reason: 'token-update' }\n      })\n      await this.switchProfile(DEFAULT_PROFILE_ID) // This rebuilds this.underlying\n      walletToUse = this.underlying\n    }\n\n    if (walletToUse == null) {\n      throw new Error('Default profile wallet could not be activated for UMP token update.')\n    }\n\n    // Publish the new token on-chain, consuming the old one\n    try {\n      newTokenData.currentOutpoint = await this.UMPTokenInteractor.buildAndSend(\n        walletToUse,\n        this.adminOriginator,\n        newTokenData,\n        oldTokenToConsume // Consume the previous token\n      )\n      // Update the manager's state\n      this.currentUMPToken = newTokenData\n      // Profiles are already updated in this.profiles if they were passed in\n    } finally {\n      // Switch back if we temporarily switched\n      if (!currentActiveId.every(x => x === 0)) {\n        await this.switchProfile(currentActiveId)\n        this.telemetry.capture({\n          name: 'wallet-toolbox.ump.profile-switch.completed',\n          component: 'wallet-toolbox.cwi-manager',\n          severity: 'debug',\n          attributes: { reason: 'token-update' }\n        })\n      }\n    }\n  }\n\n  /**\n   * Serializes a UMP token to binary format (Version 3 with KDF metadata, Version 2 with profiles).\n   * V3 Layout: [1 byte version=3] + [11 * (varint len + bytes) for standard fields] + [1 byte profile_flag] + [IF flag=1 THEN varint len + profile bytes] + [1 byte kdf_flag] + [IF flag=1 THEN kdf metadata] + [varint len + outpoint bytes]\n   */\n  private serializeUMPToken(token: UMPToken): number[] {\n    if (!token.currentOutpoint) {\n      throw new Error('Token must have outpoint for serialization')\n    }\n\n    const writer = new Utils.Writer()\n    const hasKdfMetadata = token.umpVersion === 3 && token.passwordKdf\n    writer.writeUInt8(hasKdfMetadata ? 3 : 2) // Version 3 for KDF, 2 for legacy\n\n    const writeArray = (arr: number[]) => {\n      writer.writeVarIntNum(arr.length)\n      writer.write(arr)\n    }\n\n    // Write standard fields in specific order\n    writeArray(token.passwordSalt) // 0\n    writeArray(token.passwordPresentationPrimary) // 1\n    writeArray(token.passwordRecoveryPrimary) // 2\n    writeArray(token.presentationRecoveryPrimary) // 3\n    writeArray(token.passwordPrimaryPrivileged) // 4\n    writeArray(token.presentationRecoveryPrivileged) // 5\n    writeArray(token.presentationHash) // 6\n    writeArray(token.recoveryHash) // 7\n    writeArray(token.presentationKeyEncrypted) // 8\n    writeArray(token.passwordKeyEncrypted) // 9\n    writeArray(token.recoveryKeyEncrypted) // 10\n\n    // Write optional profiles field\n    if (token.profilesEncrypted != null && token.profilesEncrypted.length > 0) {\n      writer.writeUInt8(1) // Flag indicating profiles present\n      writeArray(token.profilesEncrypted)\n    } else {\n      writer.writeUInt8(0) // Flag indicating no profiles\n    }\n\n    // V3: Write KDF metadata\n    if (hasKdfMetadata) {\n      writer.writeUInt8(1) // Flag indicating KDF metadata present\n      writer.writeUInt8(token.umpVersion!) // On-chain UMP version\n      const algorithmBytes = Utils.toArray(token.passwordKdf!.algorithm, 'utf8')\n      writeArray(algorithmBytes)\n\n      // Serialize KDF params as JSON\n      const kdfParams: Record<string, number> = {\n        iterations: token.passwordKdf!.iterations\n      }\n      if (token.passwordKdf!.memoryKiB !== undefined) {\n        kdfParams.memoryKiB = token.passwordKdf!.memoryKiB\n      }\n      if (token.passwordKdf!.parallelism !== undefined) {\n        kdfParams.parallelism = token.passwordKdf!.parallelism\n      }\n      if (token.passwordKdf!.hashLength !== undefined) {\n        kdfParams.hashLength = token.passwordKdf!.hashLength\n      }\n      const kdfParamsBytes = Utils.toArray(JSON.stringify(kdfParams), 'utf8')\n      writeArray(kdfParamsBytes)\n    } else if (writer.toArray()[0] === 3) {\n      // Version 3 without KDF metadata (shouldn't happen, but handle gracefully)\n      writer.writeUInt8(0) // Flag indicating no KDF metadata\n    }\n\n    // Write outpoint string\n    const outpointBytes = Utils.toArray(token.currentOutpoint, 'utf8')\n    writer.writeVarIntNum(outpointBytes.length)\n    writer.write(outpointBytes)\n\n    return writer.toArray()\n  }\n\n  /**\n   * Deserializes a UMP token from binary format (Handles Version 1, 2, and 3).\n   */\n  private deserializeUMPToken(bin: number[]): UMPToken {\n    const reader = new Utils.Reader(bin)\n    const version = reader.readUInt8()\n\n    if (version !== 1 && version !== 2 && version !== 3) {\n      throw new Error(`Unsupported UMP token serialization version: ${version}`)\n    }\n\n    const readArray = (): number[] => {\n      const length = reader.readVarIntNum()\n      if (length <= 0 || length > MAX_STATE_SNAPSHOT_BYTES) {\n        throw new Error('UMP token field exceeds allowed bounds.')\n      }\n      return reader.read(length)\n    }\n\n    // Read standard fields (order matches serialization)\n    const passwordSalt = readArray() // 0\n    const passwordPresentationPrimary = readArray() // 1\n    const passwordRecoveryPrimary = readArray() // 2\n    const presentationRecoveryPrimary = readArray() // 3\n    const passwordPrimaryPrivileged = readArray() // 4\n    const presentationRecoveryPrivileged = readArray() // 5\n    const presentationHash = readArray() // 6\n    const recoveryHash = readArray() // 7\n    const presentationKeyEncrypted = readArray() // 8\n    const passwordKeyEncrypted = readArray() // 9\n    const recoveryKeyEncrypted = readArray() // 10\n\n    // Read optional profiles (V2 and V3)\n    let profilesEncrypted: number[] | undefined\n    if (version >= 2) {\n      const profilesFlag = reader.readUInt8()\n      if (profilesFlag === 1) {\n        profilesEncrypted = readArray()\n      }\n    }\n\n    // Read KDF metadata (V3 only)\n    let umpVersion: number | undefined\n    let passwordKdf: UMPToken['passwordKdf']\n    if (version === 3) {\n      const kdfFlag = reader.readUInt8()\n      if (kdfFlag === 1) {\n        umpVersion = reader.readUInt8() // On-chain UMP version\n        const algorithmBytes = readArray()\n        const algorithm = Utils.toUTF8(algorithmBytes) as 'pbkdf2-sha512' | 'argon2id'\n\n        const kdfParamsBytes = readArray()\n        const kdfParamsJson = Utils.toUTF8(kdfParamsBytes)\n\n        const kdfParams = JSON.parse(kdfParamsJson) as Record<string, unknown>\n        passwordKdf = {\n          algorithm,\n          iterations: kdfParams.iterations as number,\n          memoryKiB: kdfParams.memoryKiB as number | undefined,\n          parallelism: kdfParams.parallelism as number | undefined,\n          hashLength: kdfParams.hashLength as number | undefined\n        }\n        if (!isValidKdfConfig(passwordKdf)) {\n          throw new Error('Serialized UMP token contains unsupported or unsafe KDF parameters.')\n        }\n      }\n    }\n\n    // Read outpoint string\n    const outpointLen = reader.readVarIntNum()\n    const outpointBytes = reader.read(outpointLen)\n    const currentOutpoint = Utils.toUTF8(outpointBytes)\n    if (currentOutpoint.length > 128 || !/^[^\\s.:]+[.:]\\d+$/.test(currentOutpoint)) {\n      throw new Error('Serialized UMP token contains an invalid outpoint.')\n    }\n\n    const token: UMPToken = {\n      passwordSalt,\n      passwordPresentationPrimary,\n      passwordRecoveryPrimary,\n      presentationRecoveryPrimary,\n      passwordPrimaryPrivileged,\n      presentationRecoveryPrivileged,\n      presentationHash,\n      recoveryHash,\n      presentationKeyEncrypted,\n      passwordKeyEncrypted,\n      recoveryKeyEncrypted,\n      profilesEncrypted,\n      currentOutpoint,\n      umpVersion,\n      passwordKdf\n    }\n\n    return token\n  }\n\n  /**\n   * Sets up the root key infrastructure after authentication or loading from snapshot.\n   * Initializes the root primary key, root privileged key manager, loads profiles,\n   * and sets the authenticated flag. Does NOT switch profile initially.\n   *\n   * @param rootPrimaryKey      The user's root primary key (32 bytes).\n   * @param ephemeralRootPrivilegedKey Optional root privileged key (e.g., during recovery flows).\n   */\n  private async setupRootInfrastructure(\n    rootPrimaryKey: number[],\n    ephemeralRootPrivilegedKey?: number[]\n  ): Promise<void> {\n    if (this.currentUMPToken == null) {\n      throw new Error('A UMP token must exist before setting up root infrastructure!')\n    }\n    this.rootPrimaryKey = rootPrimaryKey\n\n    // Store ephemeral key if provided, for one-time use by the manager\n    let oneTimePrivilegedKey: PrivateKey | undefined =\n      ephemeralRootPrivilegedKey == null ? undefined : new PrivateKey(ephemeralRootPrivilegedKey)\n\n    // Create the ROOT PrivilegedKeyManager\n    this.rootPrivilegedKeyManager = new PrivilegedKeyManager(async (reason: string) => {\n      // 1. Use one-time key if available (for recovery)\n      if (oneTimePrivilegedKey != null) {\n        const tempKey = oneTimePrivilegedKey\n        oneTimePrivilegedKey = undefined // Consume it\n        return tempKey\n      }\n\n      // 2. Otherwise, derive from password\n      const password = await this.passwordRetriever(reason, async (passwordCandidate: string) => {\n        try {\n          const derivedPasswordKey = await derivePasswordKey(\n            this.currentUMPToken!,\n            Utils.toArray(passwordCandidate, 'utf8')\n          )\n          const privilegedDecryptor = this.XOR(this.rootPrimaryKey!, derivedPasswordKey)\n          const decryptedPrivileged = new SymmetricKey(privilegedDecryptor).decrypt(\n            this.currentUMPToken!.passwordPrimaryPrivileged\n          ) as number[]\n          return !!decryptedPrivileged // Test passes if decryption works\n        } catch {\n          // Decryption failure means the password candidate is wrong — this is the\n          // expected rejection path for an incorrect password.  Returning false causes\n          // the password-retriever loop to prompt the user again rather than crashing.\n          return false\n        }\n      })\n\n      // Decrypt the root privileged key using the confirmed password (with token-driven KDF)\n      const derivedPasswordKey = await derivePasswordKey(this.currentUMPToken!, Utils.toArray(password, 'utf8'))\n      const privilegedDecryptor = this.XOR(this.rootPrimaryKey!, derivedPasswordKey)\n      const rootPrivilegedBytes = new SymmetricKey(privilegedDecryptor).decrypt(\n        this.currentUMPToken!.passwordPrimaryPrivileged\n      ) as number[]\n\n      return new PrivateKey(rootPrivilegedBytes) // Return the ROOT key object\n    })\n\n    // Decrypt and load profiles if present in the token\n    this.profiles = [] // Clear existing profiles before loading\n    if (this.currentUMPToken.profilesEncrypted != null && this.currentUMPToken.profilesEncrypted.length > 0) {\n      try {\n        const decryptedProfileBytes = new SymmetricKey(rootPrimaryKey).decrypt(\n          this.currentUMPToken.profilesEncrypted\n        ) as number[]\n        const profilesJson = Utils.toUTF8(decryptedProfileBytes)\n        const profiles = JSON.parse(profilesJson) as unknown\n        if (!Array.isArray(profiles) || profiles.length > 1000 || !profiles.every(isValidProfile)) {\n          throw new Error('Decrypted profile data is invalid or exceeds supported bounds.')\n        }\n        this.profiles = profiles\n      } catch (error) {\n        this.profiles = []\n        this.telemetry.capture({\n          name: 'wallet-toolbox.profile.load-failed',\n          component: 'wallet-toolbox.cwi-manager',\n          severity: 'error',\n          error\n        })\n        const message = error instanceof Error ? error.message : 'Unknown error'\n        throw new Error(`Failed to load profiles: ${message}`, { cause: error })\n      }\n    }\n\n    this.authenticated = true\n    // Note: We don't call switchProfile here anymore.\n    // It's called by the auth methods (providePassword/provideRecoveryKey) or loadSnapshot after this.\n  }\n\n  /*\n   * ---------------------------------------------------------------------------------------\n   * Standard WalletInterface methods proxying to the *active* underlying wallet.\n   * Includes authentication checks and admin originator protection.\n   * ---------------------------------------------------------------------------------------\n   */\n\n  private checkAuthAndUnderlying(originator?: string): void {\n    if (!this.authenticated) {\n      throw new Error('User is not authenticated.')\n    }\n    if (this.underlying == null) {\n      // This might happen if authentication succeeded but profile switching failed\n      throw new Error('Underlying wallet for the active profile is not initialized.')\n    }\n    if (originator === this.adminOriginator) {\n      throw new Error('External applications are not allowed to use the admin originator.')\n    }\n  }\n\n  // Example proxy method (repeat pattern for all others)\n  async getPublicKey(\n    args: GetPublicKeyArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<GetPublicKeyResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.getPublicKey(args, originator)\n  }\n\n  async revealCounterpartyKeyLinkage(\n    args: RevealCounterpartyKeyLinkageArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RevealCounterpartyKeyLinkageResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.revealCounterpartyKeyLinkage(args, originator)\n  }\n\n  async revealSpecificKeyLinkage(\n    args: RevealSpecificKeyLinkageArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RevealSpecificKeyLinkageResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.revealSpecificKeyLinkage(args, originator)\n  }\n\n  async encrypt(\n    args: WalletEncryptArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<WalletEncryptResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.encrypt(args, originator)\n  }\n\n  async decrypt(\n    args: WalletDecryptArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<WalletDecryptResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.decrypt(args, originator)\n  }\n\n  async createHmac(\n    args: CreateHmacArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<CreateHmacResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.createHmac(args, originator)\n  }\n\n  async verifyHmac(\n    args: VerifyHmacArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<VerifyHmacResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.verifyHmac(args, originator)\n  }\n\n  async createSignature(\n    args: CreateSignatureArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<CreateSignatureResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.createSignature(args, originator)\n  }\n\n  async verifySignature(\n    args: VerifySignatureArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<VerifySignatureResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.verifySignature(args, originator)\n  }\n\n  async createAction(\n    args: CreateActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<CreateActionResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.createAction(args, originator)\n  }\n\n  async signAction(\n    args: SignActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<SignActionResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.signAction(args, originator)\n  }\n\n  async abortAction(\n    args: AbortActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<AbortActionResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.abortAction(args, originator)\n  }\n\n  async listActions(\n    args: ListActionsArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ListActionsResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.listActions(args, originator)\n  }\n\n  async internalizeAction(\n    args: InternalizeActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<InternalizeActionResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.internalizeAction(args, originator)\n  }\n\n  async listOutputs(\n    args: ListOutputsArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ListOutputsResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.listOutputs(args, originator)\n  }\n\n  async relinquishOutput(\n    args: RelinquishOutputArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RelinquishOutputResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.relinquishOutput(args, originator)\n  }\n\n  async acquireCertificate(\n    args: AcquireCertificateArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<AcquireCertificateResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.acquireCertificate(args, originator)\n  }\n\n  async listCertificates(\n    args: ListCertificatesArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ListCertificatesResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.listCertificates(args, originator)\n  }\n\n  async proveCertificate(\n    args: ProveCertificateArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ProveCertificateResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.proveCertificate(args, originator)\n  }\n\n  async relinquishCertificate(\n    args: RelinquishCertificateArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RelinquishCertificateResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.relinquishCertificate(args, originator)\n  }\n\n  async discoverByIdentityKey(\n    args: DiscoverByIdentityKeyArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<DiscoverCertificatesResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.discoverByIdentityKey(args, originator)\n  }\n\n  async discoverByAttributes(\n    args: DiscoverByAttributesArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<DiscoverCertificatesResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.discoverByAttributes(args, originator)\n  }\n\n  async isAuthenticated(_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<AuthenticatedResult> {\n    if (!this.authenticated) {\n      throw new Error('User is not authenticated.')\n    }\n    if (originator === this.adminOriginator) {\n      throw new Error('External applications are not allowed to use the admin originator.')\n    }\n    return { authenticated: true }\n  }\n\n  async waitForAuthentication(\n    _: {},\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<AuthenticatedResult> {\n    if (originator === this.adminOriginator) {\n      throw new Error('External applications are not allowed to use the admin originator.')\n    }\n    while (!this.authenticated || this.underlying == null) {\n      await new Promise(resolve => setTimeout(resolve, 100))\n    }\n    return await this.underlying.waitForAuthentication({}, originator)\n  }\n\n  async getHeight(_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetHeightResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.getHeight({}, originator)\n  }\n\n  async getHeaderForHeight(\n    args: GetHeaderArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<GetHeaderResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.getHeaderForHeight(args, originator)\n  }\n\n  async getNetwork(_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetNetworkResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.getNetwork({}, originator)\n  }\n\n  async getVersion(_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetVersionResult> {\n    this.checkAuthAndUnderlying(originator)\n    return await this.underlying!.getVersion({}, originator)\n  }\n}\n","import { MonitorStorage, Monitor } from '../Monitor'\n\n/**\n * A monitor task performs some periodic or state triggered maintenance function\n * on the data managed by a wallet (Bitcoin UTXO manager, aka wallet)\n *\n * The monitor maintains a collection of tasks.\n *\n * It runs each task's non-asynchronous trigger to determine if the runTask method needs to run.\n *\n * Tasks that need to be run are run consecutively by awaiting their async runTask override method.\n *\n * The monitor then waits a fixed interval before repeating...\n *\n * Tasks may use the monitor_events table to persist their execution history.\n * This is done by accessing the wathman.storage object.\n */\n\nexport abstract class WalletMonitorTask {\n  /**\n   * Set by monitor each time runTask completes\n   */\n  lastRunMsecsSinceEpoch = 0\n\n  storage: MonitorStorage\n\n  constructor (\n    public monitor: Monitor,\n    public name: string\n  ) {\n    this.storage = monitor.storage\n  }\n\n  /**\n   * Override to handle async task setup configuration.\n   *\n   * Called before first call to `trigger`\n   */\n  async asyncSetup (): Promise<void> {\n    // Default no-op; override in subclasses that require async setup\n  }\n\n  /**\n   * Return true if `runTask` needs to be called now.\n   */\n  abstract trigger (nowMsecsSinceEpoch: number): { run: boolean }\n\n  abstract runTask (): Promise<string>\n}\n","import { PurgeParams } from '../../sdk/WalletStorage.interfaces'\nimport { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\n/**\n * The database stores a variety of data that may be considered transient.\n *\n * At one extreme, the data that must be preserved:\n *   - unspent outputs (UTXOs)\n *   - in-use metadata (labels, baskets, tags...)\n *\n * At the other extreme, everything can be preserved to fully log all transaction creation and processing actions.\n *\n * The following purge actions are available to support sustained operation:\n *   - Failed transactions, delete all associated data including:\n *       + Delete tag and label mapping records\n *       + Delete output records\n *       + Delete transaction records\n *       + Delete mapi_responses records\n *       + Delete proven_tx_reqs records\n *       + Delete commissions records\n *       + Update output records marked spentBy failed transactions\n *   - Completed transactions, delete transient data including:\n *       + transactions table set truncatedExternalInputs = null\n *       + transactions table set beef = null\n *       + transactions table set rawTx = null\n *       + Delete mapi_responses records\n *       + proven_tx_reqs table delete records\n */\nexport interface TaskPurgeParams extends PurgeParams {}\n\nexport class TaskPurge extends WalletMonitorTask {\n  static readonly taskName = 'Purge'\n\n  /**\n   * Set to true to trigger running this task\n   */\n  private static checkNowRequested = false\n  static get checkNow (): boolean { return this.checkNowRequested }\n  static set checkNow (value: boolean) { this.checkNowRequested = value }\n\n  constructor (\n    monitor: Monitor,\n    public params: TaskPurgeParams,\n    public triggerMsecs = 0\n  ) {\n    super(monitor, TaskPurge.taskName)\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run:\n        TaskPurge.checkNow ||\n        (this.triggerMsecs > 0 && nowMsecsSinceEpoch - this.lastRunMsecsSinceEpoch > this.triggerMsecs)\n    }\n  }\n\n  async runTask (): Promise<string> {\n    let log = ''\n    TaskPurge.checkNow = false\n\n    const r = await this.storage.runAsStorageProvider(async sp => {\n      return await sp.purgeData(this.params)\n    })\n\n    if (r.count > 0) log = `${r.count} records updated or deleted.\\n${r.log}`\n\n    return log\n  }\n}\n","import { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\n/**\n * Notify Transaction records of changes in ProvenTxReq records they may have missed.\n *\n * The `notified` property flags reqs that do not need to be checked.\n *\n * Looks for aged Transactions with provenTxId with status != 'completed', sets status to 'completed'.\n *\n * Looks for reqs with 'invalid' status that have corresonding transactions with status other than 'failed'.\n */\nexport class TaskReviewStatus extends WalletMonitorTask {\n  static readonly taskName = 'ReviewStatus'\n\n  /**\n   * Set to true to trigger running this task\n   */\n  private static checkNowRequested = false\n  static get checkNow (): boolean { return this.checkNowRequested }\n  static set checkNow (value: boolean) { this.checkNowRequested = value }\n\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = 1000 * 60 * 15,\n    public agedMsecs = 1000 * 60 * 5\n  ) {\n    super(monitor, TaskReviewStatus.taskName)\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run: this.triggerMsecs > 0 && nowMsecsSinceEpoch - this.lastRunMsecsSinceEpoch > this.triggerMsecs\n    }\n  }\n\n  async runTask (): Promise<string> {\n    let log = ''\n\n    const agedLimit = new Date(Date.now() - this.agedMsecs)\n    const r = await this.storage.runAsStorageProvider(async sp => {\n      // Reconcile completed-but-unnotified proof requests first. This path\n      // restores failed transaction bookkeeping before completion; the generic\n      // reviewStatus SQL repair cannot reconstruct that state after changing a\n      // failed row directly to completed.\n      const reconciliation = await sp.reconcileCompletedProvenTxReqs()\n      const review = await sp.reviewStatus({ agedLimit })\n      return { log: reconciliation.log + review.log }\n    })\n\n    if (r.log.length > 0) log += `${r.log}`\n\n    return log\n  }\n}\n","import { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\n/**\n * Handles transactions which do not have terminal status and have not been\n * updated for an extended time period.\n *\n * Calls `updateTransactionStatus` to set `status` to `failed`.\n * This returns inputs to spendable status and verifies that any\n * outputs are not spendable.\n */\n\nexport class TaskFailAbandoned extends WalletMonitorTask {\n  static readonly taskName = 'FailAbandoned'\n\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = 1000 * 60 * 5\n  ) {\n    super(monitor, TaskFailAbandoned.taskName)\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run: nowMsecsSinceEpoch > this.lastRunMsecsSinceEpoch + this.triggerMsecs\n    }\n  }\n\n  async runTask (): Promise<string> {\n    let log = ''\n    const limit = 100\n    let offset = 0\n    for (;;) {\n      const now = new Date()\n      const abandoned = new Date(now.getTime() - this.monitor.options.abandonedMsecs)\n      const done = await this.storage.runAsStorageProvider(async sp => {\n        const txsAll = await sp.findTransactions({\n          partial: {},\n          status: ['unprocessed', 'unsigned'],\n          paged: { limit, offset }\n        })\n        const txs = txsAll.filter(t => t.updated_at && t.updated_at < abandoned)\n        for (const tx of txs) {\n          await sp.updateTransactionStatus('failed', tx.transactionId)\n          log += `updated tx ${tx.transactionId} status to 'failed'\\n`\n        }\n        return txs.length < limit\n      })\n      if (done) break\n      offset += limit\n    }\n    return log\n  }\n}\n","import { GetMerklePathResult } from '../../sdk'\nimport { EntityProvenTx, EntityProvenTxReq } from '../../storage/schema/entities'\nimport { TableProvenTxReq } from '../../storage/schema/tables'\nimport { doubleSha256BE } from '../../utility/utilityHelpers'\nimport { asString } from '../../utility/utilityHelpers.noBuffer'\nimport { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\n/**\n * `TaskCheckForProofs` is a WalletMonitor task that retreives merkle proofs for\n * transactions.\n *\n * It is normally triggered by the Chaintracks new block header event.\n *\n * When a new block is found, cwi-external-services are used to obtain proofs for\n * any transactions that are currently in the 'unmined' or 'unknown' state.\n *\n * If a proof is obtained and validated, a new ProvenTx record is created and\n * the original ProvenTxReq status is advanced to 'notifying'.\n */\nexport class TaskCheckForProofs extends WalletMonitorTask {\n  static readonly taskName = 'CheckForProofs'\n\n  /**\n   * An external service such as the chaintracks new block header\n   * listener can set this true to cause\n   */\n  private static checkNowRequested = false\n  static get checkNow (): boolean { return this.checkNowRequested }\n  static set checkNow (value: boolean) { this.checkNowRequested = value }\n\n  constructor(\n    monitor: Monitor,\n    public triggerMsecs = 0\n  ) {\n    super(monitor, TaskCheckForProofs.taskName)\n  }\n\n  /**\n   * Normally triggered by checkNow getting set by new block header found event from chaintracks\n   */\n  trigger(_nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run: TaskCheckForProofs.checkNow\n      // Check only when checkNow flag is set.\n      // || (this.triggerMsecs > 0 && nowMsecsSinceEpoch - this.lastRunMsecsSinceEpoch > this.triggerMsecs)\n    }\n  }\n\n  async runTask(): Promise<string> {\n    let log = ''\n    const countsAsAttempt = TaskCheckForProofs.checkNow\n    TaskCheckForProofs.checkNow = false\n\n    const maxAcceptableHeight = this.monitor.lastNewHeader?.height\n    if (maxAcceptableHeight === undefined) {\n      return log\n    }\n\n    const limit = 100\n    let offset = 0\n    for (;;) {\n      const reqs = await this.storage.findProvenTxReqs({\n        partial: {},\n        status: ['callback', 'unmined', 'sending', 'unknown', 'unconfirmed'],\n        paged: { limit, offset }\n      })\n      if (reqs.length === 0) break\n      log += `${reqs.length} reqs with status 'callback', 'unmined', 'sending', 'unknown', or 'unconfirmed'\\n`\n      const r = await getProofs(this, reqs, maxAcceptableHeight, 2, countsAsAttempt, false)\n      log += `${r.log}\\n`\n      if (reqs.length < limit) break\n      offset += limit\n    }\n    return log\n  }\n}\n\ninterface ProofRequestResult {\n  log: string\n  proven?: TableProvenTxReq\n  invalid?: TableProvenTxReq\n}\n\nconst PROVABLE_STATUSES = new Set([\n  'callback',\n  'unmined',\n  'unknown',\n  'unconfirmed',\n  'nosend',\n  'sending'\n])\n\nfunction requestIsReadyForProof (\n  req: TableProvenTxReq,\n  ignoreStatus: boolean\n): boolean {\n  return ignoreStatus || PROVABLE_STATUSES.has(req.status)\n}\n\nfunction rawTransactionMatchesTxid (req: EntityProvenTxReq): boolean {\n  return req.rawTx != null && asString(doubleSha256BE(req.rawTx)) === req.txid\n}\n\nasync function completeLinkedRequest (\n  task: WalletMonitorTask,\n  req: EntityProvenTxReq,\n  reqApi: TableProvenTxReq,\n  log: string\n): Promise<ProofRequestResult> {\n  log += `Already linked to provenTxId ${req.provenTxId}.\\n`\n  req.notified = false\n  req.status = 'completed'\n  await req.updateStorageDynamicProperties(task.storage)\n  return { log, proven: reqApi }\n}\n\nasync function invalidateMalformedRequest (\n  task: WalletMonitorTask,\n  req: EntityProvenTxReq,\n  reqApi: TableProvenTxReq,\n  log: string\n): Promise<ProofRequestResult> {\n  log += \" rawTx doesn't hash to txid. status => invalid.\\n\"\n  req.notified = false\n  req.status = 'invalid'\n  await req.updateStorageDynamicProperties(task.storage)\n  return { log, invalid: reqApi }\n}\n\nasync function applyProofTimeout (\n  task: WalletMonitorTask,\n  req: EntityProvenTxReq,\n  reqApi: TableProvenTxReq,\n  ignoreStatus: boolean,\n  log: string\n): Promise<ProofRequestResult | undefined> {\n  const limit = task.monitor.chain === 'main'\n    ? task.monitor.options.unprovenAttemptsLimitMain\n    : task.monitor.options.unprovenAttemptsLimitTest\n  if (ignoreStatus || req.attempts <= limit) return undefined\n\n  const maxRebroadcast = task.monitor.options.maxRebroadcastAttempts ?? 0\n  const wasBroadcast = req.wasBroadcast\n  const timedOutAttempts = req.attempts\n  const timeout = req.applyProofTimeout(maxRebroadcast)\n  if (timeout.action === 'rebroadcast') {\n    log += ` too many failed attempts ${timedOutAttempts}, resetting to unsent for rebroadcast (cycle ${timeout.rebroadcastAttempts})\\n`\n    await req.updateStorageDynamicProperties(task.storage)\n    return { log }\n  }\n\n  log += wasBroadcast\n    ? ` too many failed attempts ${timedOutAttempts} and rebroadcast limit ${maxRebroadcast} reached, marking invalid\\n`\n    : ` too many failed attempts ${timedOutAttempts} and tx was never broadcast, marking invalid\\n`\n  await req.updateStorageDynamicProperties(task.storage)\n  return { log, invalid: reqApi }\n}\n\nasync function applyProvenTransaction (\n  task: WalletMonitorTask,\n  req: EntityProvenTxReq,\n  provenTx: EntityProvenTx\n): Promise<void> {\n  await req.updateStorageDynamicProperties(task.storage)\n  await req.refreshFromStorage(task.storage)\n  const { provenTxReqId, status, txid, attempts, history } = req.toApi()\n  const { index, height, blockHash, merklePath, merkleRoot } = provenTx.toApi()\n  const result = await task.storage.runAsStorageProvider(async provider => {\n    return await provider.updateProvenTxReqWithNewProvenTx({\n      provenTxReqId,\n      status,\n      txid,\n      attempts,\n      history,\n      index,\n      height,\n      blockHash,\n      merklePath,\n      merkleRoot\n    })\n  })\n  req.status = result.status\n  req.apiHistory = result.history\n  req.provenTxId = result.provenTxId\n  if (result.notify != null) req.apiNotify = result.notify\n  req.notified = result.notified ?? true\n\n  task.monitor.callOnProvenTransaction({\n    txid,\n    txIndex: index,\n    blockHeight: height,\n    blockHash,\n    merklePath,\n    merkleRoot\n  })\n}\n\nasync function processProofRequest (\n  task: WalletMonitorTask,\n  reqApi: TableProvenTxReq,\n  maxAcceptableHeight: number,\n  indent: number,\n  countsAsAttempt: boolean,\n  ignoreStatus: boolean\n): Promise<ProofRequestResult> {\n  let log = `${' '.repeat(indent)}reqId ${reqApi.provenTxReqId} txid ${reqApi.txid}: `\n  if (!requestIsReadyForProof(reqApi, ignoreStatus)) {\n    return { log: `${log}status of '${reqApi.status}' is not ready to be proven.\\n` }\n  }\n\n  const req = new EntityProvenTxReq(reqApi)\n  if (req.provenTxId != null && Number.isInteger(req.provenTxId)) {\n    return await completeLinkedRequest(task, req, reqApi, log)\n  }\n\n  log += '\\n'\n  if (!rawTransactionMatchesTxid(req)) {\n    return await invalidateMalformedRequest(task, req, reqApi, log)\n  }\n\n  const timedOut = await applyProofTimeout(task, req, reqApi, ignoreStatus, log)\n  if (timedOut != null) return timedOut\n\n  const since = new Date()\n  const merklePathResult: GetMerklePathResult =\n    await task.monitor.services.getMerklePath(req.txid)\n  if (\n    merklePathResult.header != null &&\n    merklePathResult.header.height > maxAcceptableHeight\n  ) {\n    log += ` ignoring possible proof from very new block at height ${merklePathResult.header.height} ${merklePathResult.header.hash}\\n`\n    return { log }\n  }\n\n  const provenTx = await EntityProvenTx.fromReq(\n    req,\n    merklePathResult,\n    countsAsAttempt && req.status !== 'nosend',\n    task.monitor.options.maxRebroadcastAttempts ?? 0\n  )\n  if (provenTx != null) {\n    await applyProvenTransaction(task, req, provenTx)\n  } else if (countsAsAttempt && ['callback', 'unmined', 'unknown', 'unconfirmed', 'sending'].includes(req.status)) {\n    req.attempts++\n  }\n  await req.updateStorageDynamicProperties(task.storage)\n  await req.refreshFromStorage(task.storage)\n  log += req.historyPretty(since, indent + 2) + '\\n'\n  return {\n    log,\n    ...(req.status === 'completed' ? { proven: req.api } : {}),\n    ...(req.status === 'invalid' ? { invalid: req.api } : {})\n  }\n}\n\n/**\n * Process an array of table.ProvenTxReq (typically with status 'unmined' or 'unknown')\n *\n * If req is invalid, set status 'invalid'\n *\n * Verify the requests are valid, lookup proofs or updated transaction status using the array of getProofServices,\n *\n * When proofs are found, create new ProvenTxApi records and transition the requests' status to 'unconfirmed' or 'notifying',\n * depending on chaintracks succeeding on proof verification.\n *\n * Increments attempts if proofs where requested.\n *\n * @param reqs\n * @returns reqs partitioned by status\n */\nexport async function getProofs(\n  task: WalletMonitorTask,\n  reqs: TableProvenTxReq[],\n  maxAcceptableHeight: number,\n  indent = 0,\n  countsAsAttempt = false,\n  ignoreStatus = false\n): Promise<{\n  proven: TableProvenTxReq[]\n  invalid: TableProvenTxReq[]\n  log: string\n}> {\n  const proven: TableProvenTxReq[] = []\n  const invalid: TableProvenTxReq[] = []\n\n  let log = ''\n  for (const reqApi of reqs) {\n    const result = await processProofRequest(\n      task,\n      reqApi,\n      maxAcceptableHeight,\n      indent,\n      countsAsAttempt,\n      ignoreStatus\n    )\n    log += result.log\n    if (result.proven != null) proven.push(result.proven)\n    if (result.invalid != null) invalid.push(result.invalid)\n  }\n\n  return { proven, invalid, log }\n}\n","import { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\nexport class TaskClock extends WalletMonitorTask {\n  static readonly taskName = 'Clock'\n  nextMinute: number\n\n  constructor(\n    monitor: Monitor,\n    public triggerMsecs = 1 * Monitor.oneSecond\n  ) {\n    super(monitor, TaskClock.taskName)\n    this.nextMinute = this.getNextMinute()\n  }\n\n  trigger(_nowMsecsSinceEpoch: number): { run: boolean } {\n    const run = Date.now() > this.nextMinute\n    return { run }\n  }\n\n  async runTask(): Promise<string> {\n    const log = `${new Date(this.nextMinute).toISOString()}`\n    this.nextMinute = this.getNextMinute()\n    return log\n  }\n\n  getNextMinute(): number {\n    return Math.ceil(Date.now() / Monitor.oneMinute) * Monitor.oneMinute\n  }\n}\n","import { BlockHeader } from '../../sdk/WalletServices.interfaces'\nimport { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\n/**\n * This task polls for new block headers performing two essential functions:\n * 1. The arrival of a new block is the right time to check for proofs for recently broadcast transactions.\n * 2. The height of the block is used to limit which proofs are accepted with the aim of avoiding re-orged proofs.\n *\n * The most common new block orphan is one which is almost immediately orphaned.\n * Waiting a minute before pursuing proof requests avoids almost all the re-org work that could be done.\n * Thus this task queues new headers for one cycle.\n * If a new header arrives during that cycle, it replaces the queued header and delays again.\n * Only when there is an elapsed cycle without a new header does proof solicitation get triggered,\n * with that header height as the limit for which proofs are accepted.\n */\nexport class TaskNewHeader extends WalletMonitorTask {\n  static readonly taskName = 'NewHeader'\n  /**\n   * This is always the most recent chain tip header returned from the chaintracker.\n   */\n  header?: BlockHeader\n  /**\n   * Tracks the value of `header` except that it is set to undefined\n   * when a cycle without a new header occurs and `processNewBlockHeader` is called.\n   */\n  queuedHeader?: BlockHeader\n  queuedHeaderWhen?: Date\n\n  constructor(\n    monitor: Monitor,\n    public triggerMsecs = 1 * Monitor.oneMinute\n  ) {\n    super(monitor, TaskNewHeader.taskName)\n  }\n\n  async getHeader(): Promise<BlockHeader> {\n    return await this.monitor.chaintracks.findChainTipHeader()\n  }\n\n  /**\n   * This task intentionally polls for new headers. Reorganization notification\n   * is outside this task's current contract and requires a chaintracker event\n   * source before it can be added without changing monitor behavior.\n   *\n   * New header events drive retrieving merklePaths for newly mined transactions.\n   * This implementation performs this function.\n   *\n   * Reorg events are needed to know when previously retrieved mekrlePaths need to be\n   * updated in the proven_txs table (and ideally notifications delivered to users).\n   * Note that in-general, a reorg only shifts where in the block a transaction is mined,\n   * and sometimes which block. In the case of coinbase transactions, a transaction may\n   * also fail after a reorg.\n   */\n  override async asyncSetup(): Promise<void> {\n    // No async setup required for this task\n  }\n\n  trigger(_nowMsecsSinceEpoch: number): { run: boolean } {\n    const run = true\n    return { run }\n  }\n\n  async runTask(): Promise<string> {\n    let log = ''\n    const oldHeader = this.header\n    this.header = await this.getHeader()\n    let isNew = true\n    if (oldHeader == null) {\n      log = `first header: ${this.header.height} ${this.header.hash}`\n    } else if (oldHeader.height > this.header.height) {\n      log = `old header: ${this.header.height} vs ${oldHeader.height}`\n      this.header = oldHeader // Revert to old header with the higher height\n      isNew = false\n    } else if (oldHeader.height < this.header.height) {\n      const skip = this.header.height - oldHeader.height - 1\n      const skipped = skip > 0 ? ` SKIPPED ${skip}` : ''\n      log = `new header: ${this.header.height} ${this.header.hash}${skipped}`\n    } else if (oldHeader.height === this.header.height && oldHeader.hash != this.header.hash) {\n      log = `reorg header: ${this.header.height} ${this.header.hash}`\n    } else {\n      isNew = false\n    }\n    if (isNew) {\n      this.queuedHeader = this.header\n      this.queuedHeaderWhen = new Date()\n    } else if (this.queuedHeader != null) {\n      // Only process new block header if it has remained the chain tip for a full cycle\n      const delay = (Date.now() - this.queuedHeaderWhen!.getTime()) / 1000 // seconds\n      log = `process header: ${this.header.height} ${this.header.hash} delayed ${delay.toFixed(1)} secs`\n      this.monitor.processNewBlockHeader(this.queuedHeader)\n      this.queuedHeader = undefined\n    }\n    return log\n  }\n}\n","import { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\nexport class TaskMonitorCallHistory extends WalletMonitorTask {\n  static readonly taskName = 'MonitorCallHistory'\n\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = Monitor.oneMinute * 12\n  ) {\n    super(monitor, TaskMonitorCallHistory.taskName)\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run: nowMsecsSinceEpoch > this.lastRunMsecsSinceEpoch + this.triggerMsecs\n    }\n  }\n\n  async runTask (): Promise<string> {\n    const r = this.monitor.services.getServicesCallHistory(true)\n    const log = JSON.stringify(r)\n    return log\n  }\n}\n","import { DeactivedHeader, Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\n/**\n * Check the `monitor.deactivatedHeaders` for any headers that have been deactivated.\n *\n * When headers are found, review matching ProvenTx records and update proof data as appropriate.\n *\n * New deactivated headers are pushed onto the `deactivatedHeaders` array.\n * They must be shifted out as they are processed.\n *\n * The current implementation ages deactivation notifications by 10 minutes with each retry.\n * If a successful proof update confirms original proof data after 3 retries, the original is retained.\n *\n * In normal operation there should rarely be any work for this task to perform.\n * The most common result is that there are no matching proven_txs records because\n * generating new proven_txs records intentionally lags new block generation to\n * minimize this disruption.\n *\n * It is very disruptive to update a proven_txs record because:\n * - Sync'ed storage is impacted.\n * - Generated beefs are impacted.\n * - Updated proof data may be unavailable at the time a reorg is first reported.\n *\n * Proper reorg handling also requires repairing invalid beefs for new transactions when\n * createAction fails to verify a generated beef against the chaintracker.\n */\nexport class TaskReorg extends WalletMonitorTask {\n  static readonly taskName = 'Reorg'\n\n  process: DeactivedHeader[] = []\n\n  constructor (\n    monitor: Monitor,\n    public agedMsecs = Monitor.oneMinute * 10,\n    public maxRetries = 3\n  ) {\n    super(monitor, TaskReorg.taskName)\n  }\n\n  /**\n   * Shift aged deactivated headers onto `process` array.\n   * @param nowMsecsSinceEpoch current time in milliseconds since epoch.\n   * @returns `run` true iff there are aged deactivated headers to process.\n   */\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    const cutoff = nowMsecsSinceEpoch - this.agedMsecs\n    const q = this.monitor.deactivatedHeaders\n    while (q.length > 0 && cutoff > q[0].whenMsecs) {\n      // Prepare to process deactivated headers that have aged sufficiently (agedMsecs)\n      const header = q.shift()!\n      this.process.push(header)\n    }\n    return {\n      run: this.process.length > 0\n    }\n  }\n\n  async runTask (): Promise<string> {\n    let log = ''\n\n    for (;;) {\n      // Loop over deactivated headers to process\n      const header = this.process.shift()\n      if (header == null) break\n\n      const r = await this.storage.reproveHeader(header.header.hash)\n\n      log += r.log\n\n      if (r.unavailable.length > 0 || r.unchanged.length > 0) {\n        if (header.tries + 1 >= this.maxRetries) {\n          log += `      maximum retries ${this.maxRetries} exceeded\\n`\n        } else {\n          log += '    retrying...\\n'\n          this.monitor.deactivatedHeaders.push({\n            header: header.header,\n            whenMsecs: Date.now(),\n            tries: header.tries + 1\n          })\n        }\n      }\n    }\n\n    return log\n  }\n}\n","/**\n * Client for Arcade transaction status updates.\n *\n * Uses react-native-sse EventSource to connect to Arcade's\n * `GET /events?callbackToken=<token>` endpoint for real-time\n * status updates via SSE.\n *\n * Supports on-demand fetching via fetchEvents() for use on\n * app open, balance refresh, transaction list view, etc.\n * The EventSource stays connected between fetches for live updates.\n */\n\nconst TAG = '[ArcSSE]'\n\nexport interface ArcSSEEvent {\n  txid: string\n  txStatus: string\n  timestamp: string\n}\n\nexport interface ArcSSEClientOptions {\n  /** Base URL of the Arcade instance (e.g. \"https://arcade-us-1.bsvb.tech\") */\n  baseUrl: string\n  /** Stable per-wallet token matching the X-CallbackToken sent on broadcast */\n  callbackToken: string\n  /** Server-level API key for Authorization header (from ArcConfig.apiKey) */\n  arcApiKey?: string\n  /** Called for each status event received */\n  onEvent: (event: ArcSSEEvent) => void\n  /** Called when a connection error occurs */\n  onError?: (error: Error) => void\n  /** Initial lastEventId for catchup */\n  lastEventId?: string\n  /** Called whenever lastEventId changes, for persistence to storage */\n  onLastEventIdChanged?: (lastEventId: string) => void\n  /** The react-native-sse EventSource class — passed in to avoid import from wallet-toolbox */\n  EventSourceClass: any\n}\n\nexport class ArcSSEClient {\n  private _lastEventId: string | undefined\n  private es: any = null\n  private readonly url: string\n  private readonly displayUrl: string\n  private connected = false\n  private connecting = false\n\n  constructor (private readonly options: ArcSSEClientOptions) {\n    this._lastEventId = options.lastEventId\n    let base = options.baseUrl\n    while (base.endsWith('/')) {\n      base = base.slice(0, -1)\n    }\n    this.url = `${base}/events?callbackToken=${encodeURIComponent(options.callbackToken)}`\n    this.displayUrl = `${base}/events?callbackToken=<redacted>`\n  }\n\n  get lastEventId (): string | undefined {\n    return this._lastEventId\n  }\n\n  /**\n   * Open the SSE connection. Events will be dispatched via onEvent as they arrive.\n   */\n  connect (): void {\n    if (this.es != null) {\n      console.log(`${TAG} already connected`)\n      return\n    }\n\n    this.connecting = true\n    const ESClass = this.options.EventSourceClass\n    const headers: Record<string, string> = {\n      'Last-Event-ID': this._lastEventId ?? '0'\n    }\n    if (this.options.arcApiKey != null && this.options.arcApiKey !== '') {\n      headers.Authorization = `Bearer ${this.options.arcApiKey}`\n    }\n\n    console.log(`${TAG} connecting to ${this.displayUrl} (Last-Event-ID: ${headers['Last-Event-ID']})`)\n\n    this.es = new ESClass(this.url, {\n      headers,\n      debug: true,\n      pollingInterval: 0 // Don't auto-reconnect on close — we manage lifecycle\n    })\n\n    this.es.addEventListener('open', () => {\n      this.connected = true\n      this.connecting = false\n      console.log(`${TAG} connected`)\n    })\n\n    this.es.addEventListener('status', (event: any) => {\n      try {\n        const data: ArcSSEEvent = JSON.parse(event.data)\n        console.log(`${TAG} event: txid=${data.txid} status=${data.txStatus}`)\n\n        if (typeof event.lastEventId === 'string' && event.lastEventId !== '') {\n          this._lastEventId = event.lastEventId\n          this.options.onLastEventIdChanged?.(event.lastEventId)\n        }\n\n        this.options.onEvent(data)\n      } catch {\n        console.log(`${TAG} malformed event: ${String(event.data).substring(0, 200)}`)\n      }\n    })\n\n    this.es.addEventListener('error', (event: any) => {\n      console.log(`${TAG} error:`, JSON.stringify(event))\n      this.connected = false\n      this.connecting = false\n      const message = typeof event.message === 'string' && event.message !== '' ? event.message : 'SSE error'\n      this.options.onError?.(new Error(message))\n    })\n  }\n\n  /** Close the connection and clean up */\n  close (): void {\n    if (this.es != null) {\n      console.log(`${TAG} closing`)\n      this.es.close()\n      this.es = null\n      this.connected = false\n      this.connecting = false\n    }\n  }\n\n  /**\n   * Ensure connection is open. If already connected, this is a no-op.\n   * If not connected, opens a new connection with catchup from lastEventId.\n   * Returns immediately — events arrive asynchronously via onEvent callback.\n   */\n  async fetchEvents (): Promise<number> {\n    if (this.es == null && !this.connecting) {\n      this.connect()\n    } else if (this.es != null && !this.connected && !this.connecting) {\n      // Connection exists but failed — reconnect\n      this.close()\n      this.connect()\n    }\n    // Events arrive asynchronously — return 0 since we can't know the count synchronously\n    return 0\n  }\n}\n","import { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\nimport { TableProvenTxReq } from '../../storage/schema/tables'\nimport { EntityProvenTxReq } from '../../storage/schema/entities'\n/**\n * Setting provenTxReq status to 'unfail' when 'invalid' will attempt to find a merklePath, and if successful:\n *\n * 1. set the req status to 'unmined'\n * 2. set the referenced txs to 'unproven'\n * 3. determine if any inputs match user's existing outputs and if so update spentBy and spendable of those outputs.\n * 4. set the txs outputs to spendable\n *\n * If it fails (to find a merklePath), returns the req status to 'invalid'.\n */\nexport class TaskUnFail extends WalletMonitorTask {\n  static readonly taskName = 'UnFail'\n\n  /**\n   * Set to true to trigger running this task\n   */\n  private static checkNowRequested = false\n  static get checkNow (): boolean { return this.checkNowRequested }\n  static set checkNow (value: boolean) { this.checkNowRequested = value }\n\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = Monitor.oneMinute * 10\n  ) {\n    super(monitor, TaskUnFail.taskName)\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run:\n        TaskUnFail.checkNow ||\n        (this.triggerMsecs > 0 && nowMsecsSinceEpoch - this.lastRunMsecsSinceEpoch > this.triggerMsecs)\n    }\n  }\n\n  async runTask (): Promise<string> {\n    let log = ''\n    TaskUnFail.checkNow = false\n\n    const limit = 100\n    let offset = 0\n    for (;;) {\n      const reqs = await this.storage.findProvenTxReqs({\n        partial: {},\n        status: ['unfail'],\n        paged: { limit, offset }\n      })\n      if (reqs.length === 0) break\n      log += `${reqs.length} reqs with status 'unfail'\\n`\n      const r = await this.unfail(reqs, 2)\n      log += `${r.log}\\n`\n      if (reqs.length < limit) break\n      offset += limit\n    }\n\n    return log\n  }\n\n  async unfail (reqs: TableProvenTxReq[], indent = 0): Promise<{ log: string }> {\n    let log = ''\n    for (const reqApi of reqs) {\n      const req = new EntityProvenTxReq(reqApi)\n      log += ' '.repeat(indent)\n      log += `reqId ${reqApi.provenTxReqId} txid ${reqApi.txid}: `\n      const r = await this.monitor.services.getMerklePath(req.txid)\n      if (r.merklePath != null) {\n        log += 'unfailed. status is now \\'unmined\\'\\n'\n        log += await this.unfailReq(req, indent + 2)\n      } else {\n        req.status = 'invalid'\n        log += 'returned to status \\'invalid\\'\\n'\n        await req.updateStorageDynamicProperties(this.storage)\n      }\n    }\n    return { log }\n  }\n\n  /**\n   * 2. set the referenced txs to 'unproven'\n   * 3. determine if any inputs match user's existing outputs and if so update spentBy and spendable of those outputs.\n   * 4. set the txs outputs to spendable\n   *\n   * @param req\n   * @param indent\n   * @returns\n   */\n  async unfailReq (req: EntityProvenTxReq, indent: number): Promise<string> {\n    return await this.storage.runAsStorageProvider(async sp =>\n      await sp.unfailTransactionsForProof(req, indent, { status: 'unmined', attempts: 0 })\n    )\n  }\n}\n","import { ProvenTxReqTerminalStatus } from '../../sdk/types'\nimport { EntityProvenTx } from '../../storage/schema/entities'\nimport { EntityProvenTxReq } from '../../storage/schema/entities/EntityProvenTxReq'\nimport { ArcSSEClient, ArcSSEEvent } from '../../services/providers/ArcSSEClient'\nimport { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\nimport { Services } from '../../services/Services'\nimport { TaskUnFail } from './TaskUnFail'\n\n/**\n * Monitor task that receives transaction status updates from Arcade via SSE\n * and processes them — including fetching merkle proofs directly from Arcade\n * when transactions are MINED.\n */\nexport class TaskArcadeSSE extends WalletMonitorTask {\n  static readonly taskName = 'ArcadeSSE'\n\n  sseClient: ArcSSEClient | null = null\n  private readonly pendingEvents: ArcSSEEvent[] = []\n\n  constructor (monitor: Monitor) {\n    super(monitor, TaskArcadeSSE.taskName)\n  }\n\n  override async asyncSetup (): Promise<void> {\n    const callbackToken = this.monitor.options.callbackToken\n    if (callbackToken == null || callbackToken === '') {\n      await this.logSetupEvent('no callbackToken configured; SSE disabled')\n      return\n    }\n\n    const arcadeUrl = (this.monitor.services as Services).options?.arcadeUrl\n    if (arcadeUrl == null || arcadeUrl === '') {\n      await this.logSetupEvent('no arcadeUrl configured; SSE disabled')\n      return\n    }\n\n    const EventSourceClass = this.monitor.options.EventSourceClass\n    if (EventSourceClass == null) {\n      await this.logSetupEvent('no EventSourceClass provided; SSE disabled')\n      return\n    }\n\n    let lastEventId: string | undefined\n    try {\n      lastEventId = await this.monitor.options.loadLastSSEEventId?.()\n    } catch (e) {\n      await this.logSetupEvent(`failed to load lastEventId: ${stringifyError(e)}`)\n    }\n\n    const arcadeApiKey = (this.monitor.services as Services).options?.arcadeConfig?.apiKey\n\n    await this.logSetupEvent(`setting up SSE for arcadeUrl=${arcadeUrl}; lastEventId=${lastEventId ?? '(none)'}`)\n\n    this.sseClient = new ArcSSEClient({\n      baseUrl: arcadeUrl,\n      callbackToken,\n      arcApiKey: arcadeApiKey,\n      lastEventId,\n      EventSourceClass,\n      onEvent: event => {\n        this.pendingEvents.push(event)\n      },\n      onError: err => {\n        void this.logSetupEvent(`SSE error: ${err.message}`)\n      },\n      onLastEventIdChanged: (id: string) => {\n        this.monitor.options.saveLastSSEEventId?.(id).catch(e => {\n          void this.logSetupEvent(`failed to persist lastEventId: ${stringifyError(e)}`)\n        })\n      }\n    })\n\n    this.sseClient.connect()\n  }\n\n  private async logSetupEvent (details: string): Promise<void> {\n    try {\n      await this.monitor.logEvent(this.name, details)\n    } catch {\n      // Setup diagnostics must not become a new monitor startup failure path.\n    }\n  }\n\n  trigger (_nowMsecsSinceEpoch: number): { run: boolean } {\n    return { run: this.pendingEvents.length > 0 }\n  }\n\n  async runTask (): Promise<string> {\n    const events = this.pendingEvents.splice(0)\n    if (events.length === 0) return ''\n\n    let log = ''\n    for (const event of events) {\n      log += await this.processStatusEvent(event)\n    }\n    return log\n  }\n\n  async fetchNow (): Promise<number> {\n    if (this.sseClient == null) return 0\n    return await this.sseClient.fetchEvents()\n  }\n\n  private async processStatusEvent (event: ArcSSEEvent): Promise<string> {\n    let log = `SSE: txid=${event.txid} status=${event.txStatus}\\n`\n\n    const reqs = await this.storage.findProvenTxReqs({\n      partial: { txid: event.txid }\n    })\n\n    if (reqs.length === 0) {\n      log += '  No matching ProvenTxReq\\n'\n      return log\n    }\n\n    for (const reqApi of reqs) {\n      const req = new EntityProvenTxReq(reqApi)\n      // Arcade can emit REJECTED before another node accepts the same transaction.\n      // Permit a later positive network observation to heal requests that an older\n      // Monitor version prematurely marked invalid.\n      const canRecoverRejectedRequest = this.canRecoverRejectedRequest(req, event)\n      if (ProvenTxReqTerminalStatus.includes(req.status) && !canRecoverRejectedRequest) {\n        log += `  req ${req.id} already terminal: ${req.status}\\n`\n        continue\n      }\n\n      const note = {\n        when: new Date().toISOString(),\n        what: 'arcSSE',\n        arcStatus: event.txStatus\n      }\n\n      log += await this.applyStatusEvent(req, event, note)\n    }\n\n    this.monitor.callOnTransactionStatusChanged(event.txid, event.txStatus)\n\n    return log\n  }\n\n  private canRecoverRejectedRequest(req: EntityProvenTxReq, event: ArcSSEEvent): boolean {\n    const acceptedStatuses = [\n      'SENT_TO_NETWORK',\n      'ACCEPTED_BY_NETWORK',\n      'SEEN_ON_NETWORK',\n      'SEEN_MULTIPLE_NODES'\n    ]\n    const confirmedStatuses = ['MINED', 'IMMUTABLE']\n    return req.status === 'invalid' &&\n      (acceptedStatuses.includes(event.txStatus) || confirmedStatuses.includes(event.txStatus))\n  }\n\n  private async applyStatusEvent(\n    req: EntityProvenTxReq,\n    event: ArcSSEEvent,\n    note: { when: string; what: string; arcStatus: string }\n  ): Promise<string> {\n    switch (event.txStatus) {\n      case 'SENT_TO_NETWORK':\n      case 'ACCEPTED_BY_NETWORK':\n      case 'SEEN_ON_NETWORK':\n      case 'SEEN_MULTIPLE_NODES':\n        return await this.applyAcceptedStatus(req, note)\n      case 'MINED':\n      case 'IMMUTABLE':\n        return await this.applyMinedStatus(req, note)\n      case 'DOUBLE_SPEND_ATTEMPTED':\n        return await this.applyDoubleSpendStatus(req, note)\n      case 'REJECTED':\n        // REJECTED is not a final consensus result: production Arcade has\n        // subsequently reported SEEN_MULTIPLE_NODES for the same txid. Keep\n        // wallet inputs reserved while proof/rebroadcast processing resolves\n        // the transaction authoritatively.\n        req.addHistoryNote(note)\n        await req.updateStorageDynamicProperties(this.storage)\n        return `  req ${req.id} rejection recorded; awaiting resolution\\n`\n      default:\n        return `  req ${req.id} unhandled status: ${event.txStatus}\\n`\n    }\n  }\n\n  private async applyAcceptedStatus(\n    req: EntityProvenTxReq,\n    note: { when: string; what: string; arcStatus: string }\n  ): Promise<string> {\n    if (!['unsent', 'sending', 'callback', 'invalid'].includes(req.status)) return ''\n\n    const wasInvalid = req.status === 'invalid'\n    let log = ''\n    if (wasInvalid) {\n      // Restore transaction state, re-reserve wallet inputs, and verify output\n      // spendability using the established unfail repair path.\n      log += await new TaskUnFail(this.monitor).unfailReq(req, 4)\n    } else if (req.notify.transactionIds != null) {\n      await this.storage.runAsStorageProvider(async sp => {\n        await sp.updateTransactionsStatus(req.notify.transactionIds ?? [], 'unproven')\n      })\n    }\n\n    // Apply event state after recovery because the recovery helper refreshes\n    // the entity from storage before its atomic update.\n    req.status = 'unmined'\n    if (wasInvalid) req.attempts = 0\n    req.wasBroadcast = true\n    req.addHistoryNote(note)\n    await req.updateStorageDynamicProperties(this.storage)\n    return log + `  req ${req.id} => unmined\\n`\n  }\n\n  private async applyMinedStatus(\n    req: EntityProvenTxReq,\n    note: { when: string; what: string; arcStatus: string }\n  ): Promise<string> {\n    let log = ''\n    if (req.status === 'invalid') {\n      log += await new TaskUnFail(this.monitor).unfailReq(req, 4)\n      req.status = 'unmined'\n      req.attempts = 0\n      req.wasBroadcast = true\n    }\n    req.addHistoryNote(note)\n    await req.updateStorageDynamicProperties(this.storage)\n    return log + await this.fetchProofFromServices(req)\n  }\n\n  private async applyDoubleSpendStatus(\n    req: EntityProvenTxReq,\n    note: { when: string; what: string; arcStatus: string }\n  ): Promise<string> {\n    req.status = 'doubleSpend'\n    req.addHistoryNote(note)\n    await req.updateStorageDynamicProperties(this.storage)\n    const ids = req.notify.transactionIds\n    if (ids != null) {\n      await this.storage.runAsStorageProvider(async sp => {\n        await sp.updateTransactionsStatus(ids, 'failed')\n      })\n    }\n    return `  req ${req.id} => doubleSpend\\n`\n  }\n\n  /**\n   * Complete a MINED/IMMUTABLE status by using the configured proof providers.\n   * Arcade is first when configured, but the shared provider path validates the\n   * proof against the wallet chaintracker before a ProvenTx is persisted.\n   */\n  private async fetchProofFromServices (req: EntityProvenTxReq): Promise<string> {\n    const txid = req.txid\n    let log = `  req ${req.id} MINED/IMMUTABLE — fetching proof from configured services\\n`\n\n    try {\n      const proof = await this.monitor.services.getMerklePath(txid)\n      const ptx = await EntityProvenTx.fromReq(\n        req,\n        proof,\n        false,\n        this.monitor.options.maxRebroadcastAttempts ?? 0\n      )\n      if (ptx == null) {\n        log += `    No validated merkle proof available from ${proof.name ?? 'configured services'}\\n`\n        return log\n      }\n\n      await req.refreshFromStorage(this.storage)\n      const { provenTxReqId, status, attempts, history } = req.toApi()\n      const { index, height, blockHash, merklePath, merkleRoot } = ptx.toApi()\n      const r = await this.storage.runAsStorageProvider(async sp => {\n        return await sp.updateProvenTxReqWithNewProvenTx({\n          provenTxReqId,\n          status,\n          txid,\n          attempts,\n          history,\n          index,\n          height,\n          blockHash,\n          merklePath,\n          merkleRoot\n        })\n      })\n      req.status = r.status\n      req.apiHistory = r.history\n      req.provenTxId = r.provenTxId\n      if (r.notify != null) req.apiNotify = r.notify\n      req.notified = r.notified ?? true\n      await req.updateStorageDynamicProperties(this.storage)\n\n      this.monitor.callOnProvenTransaction({\n        txid,\n        txIndex: index,\n        blockHeight: height,\n        blockHash,\n        merklePath,\n        merkleRoot\n      })\n\n      log += `    proved by ${proof.name ?? 'configured services'} at height ${height}, index ${index} => ${r.status}\\n`\n    } catch (err: unknown) {\n      const msg = err instanceof Error ? err.message : String(err)\n      log += `    error fetching proof: ${msg}\\n`\n      req.addHistoryNote({ when: new Date().toISOString(), what: 'arcProofError', error: msg })\n      await req.updateStorageDynamicProperties(this.storage)\n    }\n\n    return log\n  }\n}\n\nfunction stringifyError (error: unknown): string {\n  return error instanceof Error ? error.message : String(error)\n}\n","import { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\nimport { MockServices } from '../../mockchain/MockServices'\n\nexport class TaskMineBlock extends WalletMonitorTask {\n  static readonly taskName = 'MineBlock'\n  private static mineNowRequested = false\n  static get mineNow (): boolean { return this.mineNowRequested }\n  static set mineNow (value: boolean) { this.mineNowRequested = value }\n\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = 10 * Monitor.oneMinute\n  ) {\n    super(monitor, TaskMineBlock.taskName)\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    if (TaskMineBlock.mineNow) return { run: true }\n    if (nowMsecsSinceEpoch - this.lastRunMsecsSinceEpoch >= this.triggerMsecs) return { run: true }\n    return { run: false }\n  }\n\n  async runTask (): Promise<string> {\n    TaskMineBlock.mineNow = false\n    const mockServices = this.monitor.services as unknown as MockServices\n    const header = await mockServices.mineBlock()\n    this.monitor.processNewBlockHeader(header)\n    return `Mined block ${header.height} hash ${header.hash}`\n  }\n}\n","import { SendWithResult } from '@bsv/sdk'\n\nimport { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\nimport { attemptToPostReqsToNetwork } from '../../storage/methods/attemptToPostReqsToNetwork'\nimport { aggregateActionResults } from '../../utility/aggregateResults'\nimport { ProvenTxReqStatus } from '../../sdk/types'\nimport { verifyTruthy } from '../../utility/utilityHelpers'\nimport { TableProvenTxReq } from '../../storage/schema/tables/TableProvenTxReq'\nimport { EntityProvenTxReq } from '../../storage/schema/entities/EntityProvenTxReq'\n\nexport class TaskSendWaiting extends WalletMonitorTask {\n  static readonly taskName = 'SendWaiting'\n\n  lastSendingRunMsecsSinceEpoch: number | undefined\n  includeSending: boolean = true\n  triggerNextMsecs: number\n\n  /**\n   * @param monitor Wallet monitor owning this task.\n   * @param triggerMsecs Normal interval between SendWaiting runs when no backlog remains.\n   * @param agedMsecs Minimum age a request must reach before this task will attempt to send it.\n   * @param sendingMsecs Minimum interval before stale `sending` requests are included again.\n   * @param triggerQuickMsecs Follow-up interval used when a full chunk was consumed and more work may remain.\n   * @param chunkLimit Maximum number of waiting requests to fetch and inspect in a single run.\n   */\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = Monitor.oneSecond * 8,\n    public agedMsecs = Monitor.oneSecond * 7,\n    public sendingMsecs = Monitor.oneMinute * 5,\n    public triggerQuickMsecs = Monitor.oneSecond * 1,\n    public chunkLimit = 100\n  ) {\n    super(monitor, TaskSendWaiting.taskName)\n    this.triggerNextMsecs = this.triggerQuickMsecs\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    this.includeSending =\n      !this.lastSendingRunMsecsSinceEpoch || nowMsecsSinceEpoch > this.lastSendingRunMsecsSinceEpoch + this.sendingMsecs\n    if (this.includeSending) this.lastSendingRunMsecsSinceEpoch = nowMsecsSinceEpoch\n    return {\n      run: nowMsecsSinceEpoch > this.lastRunMsecsSinceEpoch + this.triggerNextMsecs\n    }\n  }\n\n  async runTask (): Promise<string> {\n    let log = ''\n    const nowMsecsSinceEpoch = Date.now()\n    const agedLimit = new Date(nowMsecsSinceEpoch - this.agedMsecs)\n    const status: ProvenTxReqStatus[] = this.includeSending ? ['unsent', 'sending'] : ['unsent']\n    const reqs = await this.storage.findProvenTxReqs({\n      partial: {},\n      status,\n      paged: { limit: this.chunkLimit, offset: 0 }\n    })\n\n    const count = reqs.length\n    if (count > 0) {\n      log += `${count} reqs with status ${status.join(' or ')}\\n`\n      const filteredReqs = await this.expandBatches(reqs, status)\n      const agedReqs = this.filterAgedReqs(filteredReqs, agedLimit)\n      log += `  Of those reqs, ${agedReqs.length} where last updated before ${agedLimit.toISOString()}.\\n`\n      log += await this.processUnsent(agedReqs, 2)\n\n      if (count >= this.chunkLimit) {\n        this.triggerNextMsecs = this.triggerQuickMsecs\n      } else if (agedReqs.length < filteredReqs.length) {\n        const ageAllMsecs = Math.max(\n          ...filteredReqs.map(req => verifyTruthy(req.updated_at).getTime() + this.agedMsecs - nowMsecsSinceEpoch),\n          0\n        )\n        this.triggerNextMsecs = ageAllMsecs\n      } else {\n        this.triggerNextMsecs = this.triggerMsecs\n      }\n    } else {\n      this.triggerNextMsecs = this.triggerMsecs\n    }\n\n    return log\n  }\n\n  private async expandBatches (reqs: TableProvenTxReq[], status: ProvenTxReqStatus[]): Promise<TableProvenTxReq[]> {\n    const expanded: TableProvenTxReq[] = []\n    const seenReqIds = new Set<number>()\n    const seenBatches = new Set<string>()\n\n    for (const req of reqs) {\n      if (seenReqIds.has(req.provenTxReqId)) continue\n\n      if (!req.batch || seenBatches.has(req.batch)) {\n        seenReqIds.add(req.provenTxReqId)\n        expanded.push(req)\n        continue\n      }\n\n      seenBatches.add(req.batch)\n      const batchReqs = await this.storage.findProvenTxReqs({\n        partial: { batch: req.batch },\n        status\n      })\n\n      for (const batchReq of batchReqs) {\n        if (seenReqIds.has(batchReq.provenTxReqId)) continue\n        seenReqIds.add(batchReq.provenTxReqId)\n        expanded.push(batchReq)\n      }\n    }\n\n    return expanded\n  }\n\n  private filterAgedReqs (reqs: TableProvenTxReq[], agedLimit: Date): TableProvenTxReq[] {\n    const agedReqs: TableProvenTxReq[] = []\n    const seenBatches = new Set<string>()\n\n    for (const req of reqs) {\n      if (!req.batch) {\n        if (verifyTruthy(req.updated_at) < agedLimit) agedReqs.push(req)\n        continue\n      }\n\n      if (seenBatches.has(req.batch)) continue\n      seenBatches.add(req.batch)\n\n      const batchReqs = reqs.filter(candidate => candidate.batch === req.batch)\n      const youngestUpdatedAt = Math.max(...batchReqs.map(batchReq => verifyTruthy(batchReq.updated_at).getTime()))\n      if (youngestUpdatedAt < agedLimit.getTime()) {\n        agedReqs.push(...batchReqs)\n      }\n    }\n\n    return agedReqs\n  }\n\n  /**\n   * Process an array of 'unsent' status table.ProvenTxReq\n   *\n   * Send rawTx to transaction processor(s), requesting proof callbacks when possible.\n   *\n   * Set status 'invalid' if req is invalid.\n   *\n   * Set status to 'callback' on successful network submission with callback service.\n   *\n   * Set status to 'unmined' on successful network submission without callback service.\n   *\n   * Add mapi responses to database table if received.\n   *\n   * Increments attempts if sending was attempted.\n   *\n   * @param reqApis\n   */\n  async processUnsent (reqApis: TableProvenTxReq[], indent = 0): Promise<string> {\n    const txids = reqApis.map(r => r.txid)\n    const logs = this.initializeRequestLogs(reqApis)\n    const reqApiIds = new Set(reqApis.map(r => r.provenTxReqId))\n    const groupedReqIds = new Set<number>()\n\n    for (const reqApi of reqApis) {\n      await this.processUnsentRequest(reqApi, reqApiIds, groupedReqIds, logs)\n    }\n\n    let log = ''\n    for (const txid of txids) {\n      log += `${' '.repeat(indent)}${logs[txid]}\\n`\n    }\n    return log\n  }\n\n  private initializeRequestLogs(reqApis: TableProvenTxReq[]): Record<string, string> {\n    const logs: Record<string, string> = {}\n    for (let i = 0; i < reqApis.length; i++) {\n      const req = reqApis[i]\n      logs[req.txid] = `${i} reqId=${req.provenTxReqId} attempts=${req.attempts} txid=${req.txid}:`\n    }\n    return logs\n  }\n\n  private async processUnsentRequest(\n    reqApi: TableProvenTxReq,\n    reqApiIds: Set<number>,\n    groupedReqIds: Set<number>,\n    logs: Record<string, string>\n  ): Promise<void> {\n    if (groupedReqIds.has(reqApi.provenTxReqId)) {\n      logs[reqApi.txid] += ' processed with batch'\n      return\n    }\n    if (reqApi.status !== 'unsent' && reqApi.status !== 'sending') {\n      logs[reqApi.txid] += ` status now ${reqApi.status}`\n      return\n    }\n\n    const req = new EntityProvenTxReq(reqApi)\n    const reqs = await this.expandRequestBatch(req, reqApiIds, groupedReqIds, logs)\n    const result = await this.storage.runAsStorageProvider(async sp => {\n      return await attemptToPostReqsToNetwork(sp, reqs)\n    })\n\n    for (const detail of result.details) {\n      logs[detail.txid] += ` req.status ${detail.req.status} post.status ${detail.status}`\n    }\n\n    if (this.monitor.onTransactionBroadcasted != null) {\n      const aggregateResults = await this.storage.runAsStorageProvider(async sp => {\n        const actions: SendWithResult[] = [{ txid: req.txid, status: 'sending' }]\n        const { rar } = await aggregateActionResults(sp, actions, result)\n        return rar\n      })\n      this.monitor.callOnBroadcastedTransaction(aggregateResults[0])\n    }\n  }\n\n  private async expandRequestBatch(\n    req: EntityProvenTxReq,\n    reqApiIds: Set<number>,\n    groupedReqIds: Set<number>,\n    logs: Record<string, string>\n  ): Promise<EntityProvenTxReq[]> {\n    if (!req.batch) return [req]\n\n    logs[req.txid] += ` batch ${req.batch}`\n    // Process the entire batch together for efficient BEEF generation.\n    const batchReqApis = await this.storage.findProvenTxReqs({\n      partial: { batch: req.batch },\n      status: this.includeSending ? ['unsent', 'sending'] : ['unsent']\n    })\n    const reqs: EntityProvenTxReq[] = []\n    for (const batchReq of batchReqApis) {\n      if (reqApiIds.has(batchReq.provenTxReqId)) groupedReqIds.add(batchReq.provenTxReqId)\n      reqs.push(new EntityProvenTxReq(batchReq))\n    }\n    return reqs\n  }\n}\n","import { Monitor } from '../Monitor'\nimport { getProofs } from './TaskCheckForProofs'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\n/**\n * `TaskCheckNoSends` is a WalletMonitor task that retrieves merkle proofs for\n * 'nosend' transactions that MAY have been shared externally.\n *\n * Unlike intentionally processed transactions, 'nosend' transactions are fully valid\n * transactions which have not been processed by the wallet.\n *\n * By default, this task runs once a day to check if any 'nosend' transaction has\n * managed to get mined by some external process.\n *\n * If a proof is obtained and validated, a new ProvenTx record is created and\n * the original ProvenTxReq status is advanced to 'notifying'.\n *\n * # Aging schedule on the checkNow path\n *\n * When this task is triggered by a new block header (`checkNow = true`, wired in\n * `Monitor.processNewBlockHeader`), it does NOT scan every `nosend` row on every\n * block. The set of `nosend` rows can grow large over a wallet's lifetime\n * (txs sitting in escrow, un-aborted tests, abandoned batches), and a fast,\n * unfiltered scan on every block would do an unbounded number of external\n * `getMerklePath` lookups per block.\n *\n * Instead, the row's age (now - `created_at`) determines how often it is\n * eligible for a checkNow-triggered chain check. The schedule starts at \"skip\n * entirely\" for very fresh rows (to protect in-flight batched-tx workflows\n * where chained `createAction({ noSend: true, sendWith: [...] })` builds\n * deliberately keep rows in `nosend` until a single terminator broadcasts the\n * whole BEEF), then progresses to \"every block\", \"hourly\", \"daily\", and\n * \"weekly\" as rows age:\n *\n *   age < 5 min                 → skip (in-flight batch protection)\n *   5 min ≤ age < 1 hr          → check on every checkNow trigger\n *   1 hr   ≤ age < 24 hr        → check on ~hourly cadence (block-height % 6)\n *   24 hr  ≤ age < 7 days       → check on ~daily cadence  (block-height % 144)\n *   age ≥ 7 days                → check on ~weekly cadence (block-height % 1008)\n *\n * Block-height modulo gives a deterministic, stateless way to schedule\n * checks for older rows; no per-row \"last checked\" persistence is required.\n * Each row's modulo offset is keyed by its `provenTxReqId` so that rows in\n * the same age tier are staggered across the modulo cycle rather than all\n * firing on the same block — `(blockHeight + provenTxReqId) % tierInterval`.\n * For a wallet with N rows in tier T and tier interval K, this gives\n * roughly N/K rows fired per block instead of N rows fired every K blocks.\n *\n * The scheduled daily cadence (no `checkNow`) is unaffected — it still scans\n * every row regardless of age. That path is the once-per-day fallback that\n * guarantees externally-broadcast `nosend` txs are eventually recognized\n * even if the aging schedule on the checkNow path defers them.\n */\nexport class TaskCheckNoSends extends WalletMonitorTask {\n  static readonly taskName = 'CheckNoSends'\n\n  /**\n   * An external service such as the chaintracks new block header\n   * listener can set this true to cause\n   */\n  private static checkNowRequested = false\n  static get checkNow (): boolean { return this.checkNowRequested }\n  static set checkNow (value: boolean) { this.checkNowRequested = value }\n\n  /**\n   * Aging-schedule constants for the `checkNow` path. Rows below `tier0FreshSkipMsecs`\n   * are never checked via checkNow (batched-tx protection). Rows from tier 0 up\n   * to `tier1EveryBlockMsecs` are checked on every checkNow trigger. Beyond that,\n   * checks happen on `block-height % tierNBlockInterval === 0` cadences with\n   * growing intervals. The scheduled daily cadence (no checkNow) is unaffected.\n   */\n  static readonly tier0FreshSkipMsecs   = 5 * 60 * 1000             // 5 min\n  static readonly tier1EveryBlockMsecs  = 60 * 60 * 1000            // 1 hr\n  static readonly tier2HourlyMsecs      = 24 * 60 * 60 * 1000       // 24 hr\n  static readonly tier3DailyMsecs       = 7 * 24 * 60 * 60 * 1000   // 7 days\n  static readonly tier2BlockInterval    = 6        // ~hourly on 10-min blocks\n  static readonly tier3BlockInterval    = 144      // ~daily  on 10-min blocks\n  static readonly tier4BlockInterval    = 1008     // ~weekly on 10-min blocks\n\n  /**\n   * Decide whether a single `nosend` row should be chain-checked on the\n   * current `checkNow` trigger, based on its age, the current block\n   * height, and its `provenTxReqId` (used to stagger same-tier rows\n   * across the modulo cycle). See class docstring for the full schedule\n   * and staggering rationale.\n   */\n  static shouldCheckOnCheckNow (\n    createdAt: Date,\n    nowMs: number,\n    currentBlockHeight: number,\n    provenTxReqId: number\n  ): boolean {\n    const ageMs = nowMs - createdAt.getTime()\n    if (ageMs < TaskCheckNoSends.tier0FreshSkipMsecs) return false\n    if (ageMs < TaskCheckNoSends.tier1EveryBlockMsecs) return true\n    // Stagger same-tier rows by `provenTxReqId` so they fire on different\n    // blocks within the modulo cycle, not all on the same block.\n    if (ageMs < TaskCheckNoSends.tier2HourlyMsecs) {\n      return (currentBlockHeight + provenTxReqId) % TaskCheckNoSends.tier2BlockInterval === 0\n    }\n    if (ageMs < TaskCheckNoSends.tier3DailyMsecs) {\n      return (currentBlockHeight + provenTxReqId) % TaskCheckNoSends.tier3BlockInterval === 0\n    }\n    return (currentBlockHeight + provenTxReqId) % TaskCheckNoSends.tier4BlockInterval === 0\n  }\n\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = Monitor.oneDay * 1\n  ) {\n    super(monitor, TaskCheckNoSends.taskName)\n  }\n\n  /**\n   * Normally triggered by checkNow getting set by new block header found event from chaintracks\n   */\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run:\n        TaskCheckNoSends.checkNow ||\n        (this.triggerMsecs > 0 && nowMsecsSinceEpoch - this.lastRunMsecsSinceEpoch > this.triggerMsecs)\n    }\n  }\n\n  async runTask (): Promise<string> {\n    let log = ''\n    const wasCheckNow = TaskCheckNoSends.checkNow\n    const countsAsAttempt = wasCheckNow\n    TaskCheckNoSends.checkNow = false\n\n    const maxAcceptableHeight = this.monitor.lastNewHeader?.height\n    if (maxAcceptableHeight === undefined) {\n      return log\n    }\n\n    const nowMs = Date.now()\n\n    const limit = 100\n    let offset = 0\n    for (;;) {\n      const reqs = await this.storage.findProvenTxReqs({\n        partial: {},\n        status: ['nosend'],\n        paged: { limit, offset }\n      })\n      if (reqs.length === 0) break\n      log += `${reqs.length} reqs with status 'nosend'\\n`\n\n      // On the checkNow (block-triggered) path, apply the aging schedule\n      // — see class docstring. The scheduled daily cadence is unfiltered\n      // so externally-broadcast unmined nosend txs are eventually caught\n      // regardless of age.\n      let eligible = reqs\n      if (wasCheckNow) {\n        eligible = reqs.filter(r =>\n          TaskCheckNoSends.shouldCheckOnCheckNow(\n            r.created_at,\n            nowMs,\n            maxAcceptableHeight,\n            r.provenTxReqId\n          )\n        )\n        const skipped = reqs.length - eligible.length\n        if (skipped > 0) {\n          log += `aging schedule: skipping ${skipped} of ${reqs.length} reqs on checkNow path (block-triggered)\\n`\n        }\n      }\n\n      if (eligible.length > 0) {\n        const r = await getProofs(this, eligible, maxAcceptableHeight, 2, countsAsAttempt, false)\n        log += `${r.log}\\n`\n      }\n      if (reqs.length < limit) break\n      offset += limit\n    }\n    return log\n  }\n}\n","import { Validation, WalletOutput } from '@bsv/sdk'\nimport { specOpInvalidChange } from '../../sdk'\nimport { TableUser } from '../../storage/schema/tables'\nimport { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\n/**\n * Use the reviewByIdentityKey method to review the utxos of a specific user by their identityKey.\n *\n * The task itself is disabled and will not run on a schedule; review must be triggered manually by calling reviewByIdentityKey.\n */\nexport class TaskReviewUtxos extends WalletMonitorTask {\n  static readonly taskName = 'ReviewUtxos'\n\n  private static checkNowRequested = false\n  static get checkNow (): boolean { return this.checkNowRequested }\n  static set checkNow (value: boolean) { this.checkNowRequested = value }\n\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = 0,\n    public userLimit = 10,\n    public userOffset = 0,\n    public tags: string[] = ['release', 'all']\n  ) {\n    super(monitor, TaskReviewUtxos.taskName)\n  }\n\n  trigger (_nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run: false\n    }\n  }\n\n  async runTask (): Promise<string> {\n    TaskReviewUtxos.checkNow = false\n    return 'TaskReviewUtxos is disabled; use reviewByIdentityKey instead.\\n'\n  }\n\n  async reviewByIdentityKey (identityKey: string, mode: 'all' | 'change' = 'all'): Promise<string> {\n    const tags = ['release', ...(mode === 'all' ? ['all'] : [])]\n    const vargs: Validation.ValidListOutputsArgs = {\n      basket: specOpInvalidChange,\n      tags,\n      tagQueryMode: 'all',\n      includeLockingScripts: false,\n      includeTransactions: false,\n      includeCustomInstructions: false,\n      includeTags: false,\n      includeLabels: false,\n      limit: 0,\n      offset: 0,\n      seekPermission: false,\n      knownTxids: []\n    }\n\n    return await this.storage.runAsStorageProvider(async sp => {\n      const user = (await sp.findUsers({ partial: { identityKey } }))[0]\n      if (!user) {\n        return `identityKey ${identityKey} was not found\\n`\n      }\n\n      const auth = { userId: user.userId, identityKey: user.identityKey }\n      const result = await sp.listOutputs(auth, vargs)\n      if (result.totalOutputs === 0) {\n        return `userId ${user.userId}: no invalid utxos found, ${user.identityKey}\\n`\n      }\n\n      const total = result.outputs.reduce((sum, output) => sum + output.satoshis, 0)\n      return this.toUserLog(user, result.outputs, result.totalOutputs, total, tags)\n    })\n  }\n\n  private toUserLog (\n    user: TableUser,\n    outputs: WalletOutput[],\n    totalOutputs: number,\n    total: number,\n    tags: string[]\n  ): string {\n    const action = tags.includes('release') ? 'updated to unspendable' : 'found'\n    const target = tags.includes('all') ? 'spendable utxos' : 'spendable change utxos'\n    let log = `userId ${user.userId}: ${totalOutputs} ${target} ${action}, total ${total}, ${user.identityKey}\\n`\n    for (const output of outputs) {\n      log += `  ${output.outpoint} ${output.satoshis} now ${output.spendable ? 'spendable' : 'spent'}\\n`\n    }\n    return log\n  }\n}\n","import { TableProvenTxReq } from '../../storage/schema/tables'\nimport { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\ninterface ReviewDoubleSpendsCheckpoint {\n  reviewLimit: number\n  minAgeMinutes: number\n  reviewed: number\n  unfails: number\n  provenTxReqIds?: number[]\n  reviewLog?: string\n  resumeOffset?: number\n  expectedProvenTxReqId?: number\n}\n\n/**\n * Review recent reqs in terminal 'doubleSpend' state and move any false positives\n * back to 'unfail' so existing recovery handling can re-process them.\n */\nexport class TaskReviewDoubleSpends extends WalletMonitorTask {\n  static readonly taskName = 'ReviewDoubleSpends'\n\n  private static checkNowRequested = false\n  static get checkNow (): boolean { return this.checkNowRequested }\n  static set checkNow (value: boolean) { this.checkNowRequested = value }\n\n  triggerNextMsecs: number\n\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = Monitor.oneMinute * 12,\n    public reviewLimit = 100,\n    public minAgeMinutes = 60,\n    public triggerQuickMsecs = Monitor.oneMinute * 1\n  ) {\n    super(monitor, TaskReviewDoubleSpends.taskName)\n    this.triggerNextMsecs = this.triggerQuickMsecs\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run:\n        TaskReviewDoubleSpends.checkNow ||\n        (this.triggerNextMsecs > 0 && nowMsecsSinceEpoch - this.lastRunMsecsSinceEpoch > this.triggerNextMsecs)\n    }\n  }\n\n  async getLastReviewedCheckpoint (): Promise<{ resumeOffset: number, expectedProvenTxReqId?: number } | undefined> {\n    let events: Array<{ details?: string }> = []\n    await this.storage.runAsStorageProvider(async sp => {\n      events = await sp.findMonitorEvents({\n        partial: { event: TaskReviewDoubleSpends.taskName },\n        orderDescending: true,\n        paged: { limit: 5 }\n      })\n    })\n\n    for (const event of events) {\n      if (!event.details) continue\n      try {\n        const parsed = JSON.parse(event.details) as Partial<ReviewDoubleSpendsCheckpoint>\n        if (typeof parsed.resumeOffset === 'number') {\n          return {\n            resumeOffset: parsed.resumeOffset,\n            expectedProvenTxReqId: parsed.expectedProvenTxReqId\n          }\n        }\n      } catch {\n        continue\n      }\n    }\n\n    return undefined\n  }\n\n  async runTask (): Promise<string> {\n    TaskReviewDoubleSpends.checkNow = false\n\n    const checkpoint = await this.getLastReviewedCheckpoint()\n    const updatedBefore = new Date(Date.now() - this.minAgeMinutes * 60 * 1000)\n    const reqs = await this.findReqsToReview(checkpoint, updatedBefore)\n    if (reqs.length === 0) {\n      this.triggerNextMsecs = this.triggerMsecs\n      return ''\n    }\n\n    this.triggerNextMsecs = reqs.length >= this.reviewLimit ? this.triggerQuickMsecs : this.triggerMsecs\n\n    const reviewed: TableProvenTxReq[] = []\n    const unfails: number[] = []\n    let log = ''\n    let lastRetainedDoubleSpendIndex = -1\n    let retainedDoubleSpendCount = 0\n\n    for (const req of reqs) {\n      const gsr = await this.monitor.services.getStatusForTxids([req.txid])\n      const status = gsr.results[0]?.status\n      reviewed.push(req)\n      if (status === 'unknown') {\n        lastRetainedDoubleSpendIndex = reviewed.length - 1\n        retainedDoubleSpendCount += 1\n      } else {\n        unfails.push(req.provenTxReqId)\n        log += `unfail ${req.provenTxReqId} ${req.txid} status:${status}\\n`\n      }\n    }\n\n    if (unfails.length > 0) {\n      await this.storage.runAsStorageProvider(async sp => {\n        await sp.updateProvenTxReq(unfails, { status: 'unfail' })\n      })\n    }\n\n    return JSON.stringify({\n      minAgeMinutes: this.minAgeMinutes,\n      reviewed: reviewed.length,\n      unfails: unfails.length,\n      reviewLimit: this.reviewLimit,\n      provenTxReqIds: unfails,\n      resumeOffset: lastRetainedDoubleSpendIndex >= 0 ? reqs.sourceOffset! + retainedDoubleSpendCount - 1 : undefined,\n      expectedProvenTxReqId:\n        lastRetainedDoubleSpendIndex >= 0 ? reviewed[lastRetainedDoubleSpendIndex].provenTxReqId : undefined,\n      reviewLog: `${reviewed.length} reqs with status 'doubleSpend'\\n${log}`\n    } satisfies ReviewDoubleSpendsCheckpoint)\n  }\n\n  private async findReqsToReview (\n    checkpoint: { resumeOffset: number, expectedProvenTxReqId?: number } | undefined,\n    updatedBefore: Date\n  ): Promise<TableProvenTxReq[] & { sourceOffset?: number }> {\n    let offset = checkpoint?.resumeOffset || 0\n\n    if (checkpoint?.expectedProvenTxReqId !== undefined) {\n      const verify = await this.storage.findProvenTxReqs({\n        partial: { status: 'doubleSpend' },\n        paged: { limit: 1, offset: checkpoint.resumeOffset }\n      })\n      if (verify[0]?.provenTxReqId === checkpoint.expectedProvenTxReqId) {\n        offset += 1\n      } else {\n        offset = 0\n      }\n    }\n\n    const batch = await this.storage.findProvenTxReqs({\n      partial: { status: 'doubleSpend' },\n      paged: { limit: this.reviewLimit, offset }\n    })\n    const reqs = batch.filter(req => req.updated_at <= updatedBefore) as TableProvenTxReq[] & { sourceOffset?: number }\n    reqs.sourceOffset = offset\n    return reqs\n  }\n}\n","import { HeightRange } from '../../services/chaintracker/chaintracks/util/HeightRange'\nimport { Monitor } from '../Monitor'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\nexport interface ReviewHeightRangeResult {\n  log: string\n  reviewedHeights: number\n  mismatchedHeights: number\n  affectedTransactions: number\n  updatedTransactions: number\n}\n\ninterface ReviewProvenTxsCheckpoint {\n  tipHeight: number\n  minBlockAge: number\n  maxHeightsPerRun: number\n  startHeight: number\n  reviewedThroughHeight: number\n  reviewedHeights: number\n  mismatchedHeights: number\n  affectedTransactions: number\n  updatedTransactions: number\n  reviewLog?: string\n}\n\n/**\n * Backup verification task for recent proven_txs records.\n *\n * Reorg handling should normally be driven by TaskReorg via deactivated-header events.\n * This task runs a lagged audit over recent heights and only reproves transactions when\n * the currently canonical merkleRoot at a height no longer matches stored proven_txs roots.\n */\nexport class TaskReviewProvenTxs extends WalletMonitorTask {\n  static readonly taskName = 'ReviewProvenTxs'\n\n  private static checkNowRequested = false\n  static get checkNow (): boolean { return this.checkNowRequested }\n  static set checkNow (value: boolean) { this.checkNowRequested = value }\n\n  triggerNextMsecs: number\n\n  constructor (\n    monitor: Monitor,\n    public triggerMsecs = Monitor.oneMinute * 10,\n    public maxHeightsPerRun = 100,\n    public minBlockAge = 100,\n    public triggerQuickMsecs = Monitor.oneMinute * 1\n  ) {\n    super(monitor, TaskReviewProvenTxs.taskName)\n    this.triggerNextMsecs = this.triggerQuickMsecs\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    return {\n      run:\n        TaskReviewProvenTxs.checkNow ||\n        (this.triggerNextMsecs > 0 && nowMsecsSinceEpoch - this.lastRunMsecsSinceEpoch > this.triggerNextMsecs)\n    }\n  }\n\n  async runTask (): Promise<string> {\n    TaskReviewProvenTxs.checkNow = false\n\n    const chaintracks = this.monitor.chaintracksWithEvents || this.monitor.chaintracks\n    const tipHeight = await chaintracks.currentHeight()\n    const maxEligibleHeight = tipHeight - this.minBlockAge\n    const lastReviewedHeight = await this.getLastReviewedHeight()\n    const startHeight = lastReviewedHeight === undefined ? 0 : lastReviewedHeight + 1\n    const endHeight = Math.min(startHeight + this.maxHeightsPerRun - 1, maxEligibleHeight)\n    const range = new HeightRange(startHeight, endHeight)\n    if (range.isEmpty) return ''\n\n    let log = `reviewing heights ${range.minHeight}..${range.maxHeight} tip=${tipHeight} minAge=${this.minBlockAge} maxPerRun=${this.maxHeightsPerRun}\\n`\n    const review = await this.reviewHeightRange(range)\n    log += review.log\n\n    return JSON.stringify({\n      tipHeight,\n      minBlockAge: this.minBlockAge,\n      maxHeightsPerRun: this.maxHeightsPerRun,\n      startHeight,\n      reviewedThroughHeight: range.maxHeight,\n      reviewedHeights: review.reviewedHeights,\n      mismatchedHeights: review.mismatchedHeights,\n      affectedTransactions: review.affectedTransactions,\n      updatedTransactions: review.updatedTransactions,\n      reviewLog: log\n    } satisfies ReviewProvenTxsCheckpoint)\n  }\n\n  async reviewHeightRange (range: HeightRange): Promise<ReviewHeightRangeResult> {\n    const result: ReviewHeightRangeResult = {\n      log: '',\n      reviewedHeights: 0,\n      mismatchedHeights: 0,\n      affectedTransactions: 0,\n      updatedTransactions: 0\n    }\n\n    if (range.isEmpty) {\n      this.triggerNextMsecs = this.triggerMsecs\n      return result\n    }\n\n    // If there is work to do, trigger a quick follow-up to continue processing the next range.\n    this.triggerNextMsecs = this.triggerQuickMsecs\n\n    const chaintracks = this.monitor.chaintracksWithEvents || this.monitor.chaintracks\n\n    for (let height = range.minHeight; height <= range.maxHeight; height++) {\n      result.reviewedHeights++\n\n      const header = await chaintracks.findHeaderForHeight(height)\n      if (header == null) {\n        result.log += `  height ${height} canonical header unavailable\\n`\n        continue\n      }\n\n      let staleRoots: string[] = []\n      await this.storage.runAsStorageProvider(async sp => {\n        staleRoots = await sp.findStaleMerkleRoots({ height, merkleRoot: header.merkleRoot })\n      })\n\n      if (staleRoots.length === 0) continue\n\n      result.mismatchedHeights++\n      result.log += `  height ${height} canonical ${header.merkleRoot} stale ${staleRoots.join(',')}\\n`\n\n      for (const staleRoot of staleRoots) {\n        const reprove = await this.storage.reproveHeightMerkleRoot(height, staleRoot)\n        result.affectedTransactions += reprove.updated.length + reprove.unchanged.length + reprove.unavailable.length\n        result.updatedTransactions += reprove.updated.length\n        result.log += reprove.log\n      }\n    }\n\n    return result\n  }\n\n  async getLastReviewedHeight (): Promise<number | undefined> {\n    let events: Array<{ details?: string }> = []\n    await this.storage.runAsStorageProvider(async sp => {\n      events = await sp.findMonitorEvents({\n        partial: { event: TaskReviewProvenTxs.taskName },\n        orderDescending: true,\n        paged: { limit: 5 }\n      })\n    })\n\n    for (const event of events) {\n      if (!event.details) continue\n      try {\n        const parsed = JSON.parse(event.details) as Partial<ReviewProvenTxsCheckpoint>\n        if (typeof parsed.reviewedThroughHeight === 'number') {\n          return parsed.reviewedThroughHeight\n        }\n      } catch {\n        continue\n      }\n    }\n\n    let lastReviewedHeight: number | undefined\n    await this.storage.runAsStorageProvider(async sp => {\n      // Start at height of first proven tx when it appears...\n      const ptxs = await sp.findProvenTxs({ partial: {}, paged: { limit: 1, offset: 0 }, orderDescending: false })\n      if (ptxs.length > 0) {\n        lastReviewedHeight = ptxs[0].height - 1\n      }\n    })\n\n    return lastReviewedHeight\n  }\n}\n","import { Monitor } from '../Monitor'\nimport { cleanupExpiredActionBatches } from '../../storage/methods/actionBatch'\nimport { WalletMonitorTask } from './WalletMonitorTask'\n\n/** Releases expired action-batch reservations and incomplete staged blobs. */\nexport class TaskCleanupActionBatches extends WalletMonitorTask {\n  static readonly taskName = 'CleanupActionBatches'\n\n  constructor (monitor: Monitor, public triggerMsecs = Monitor.oneMinute) {\n    super(monitor, TaskCleanupActionBatches.taskName)\n  }\n\n  trigger (nowMsecsSinceEpoch: number): { run: boolean } {\n    return { run: nowMsecsSinceEpoch - this.lastRunMsecsSinceEpoch >= this.triggerMsecs }\n  }\n\n  async runTask (): Promise<string> {\n    const count = await this.storage.runAsStorageProvider(cleanupExpiredActionBatches)\n    return count > 0 ? `released ${count} expired action batches` : ''\n  }\n}\n","import { wait } from '../utility/utilityHelpers'\n\nimport { WalletMonitorTask } from './tasks/WalletMonitorTask'\nimport { WalletStorageManager } from '../storage/WalletStorageManager'\n\nimport { TaskPurge, TaskPurgeParams } from './tasks/TaskPurge'\nimport { TaskReviewStatus } from './tasks/TaskReviewStatus'\nimport { TaskFailAbandoned } from './tasks/TaskFailAbandoned'\nimport { TaskCheckForProofs } from './tasks/TaskCheckForProofs'\nimport { TaskClock } from './tasks/TaskClock'\nimport { TaskNewHeader } from './tasks/TaskNewHeader'\nimport { TaskMonitorCallHistory } from './tasks/TaskMonitorCallHistory'\nimport { TaskReorg } from './tasks/TaskReorg'\nimport { TaskArcadeSSE } from './tasks/TaskArcSSE'\nimport { TaskMineBlock } from './tasks/TaskMineBlock'\n\nimport { TaskSendWaiting } from './tasks/TaskSendWaiting'\nimport { TaskCheckNoSends } from './tasks/TaskCheckNoSends'\nimport { TaskUnFail } from './tasks/TaskUnFail'\nimport { TaskReviewUtxos } from './tasks/TaskReviewUtxos'\nimport { TaskReviewDoubleSpends } from './tasks/TaskReviewDoubleSpends'\nimport { TaskReviewProvenTxs } from './tasks/TaskReviewProvenTxs'\nimport { TaskCleanupActionBatches } from './tasks/TaskCleanupActionBatches'\nimport { Chain, ProvenTransactionStatus } from '../sdk/types'\nimport { ReviewActionResult } from '../sdk/WalletStorage.interfaces'\nimport { WERR_BAD_REQUEST, WERR_INVALID_PARAMETER } from '../sdk/WERR_errors'\nimport { WalletError } from '../sdk/WalletError'\nimport { BlockHeader, WalletServices } from '../sdk/WalletServices.interfaces'\nimport { Services } from '../services/Services'\nimport { ChaintracksClientApi } from '../services/chaintracker/chaintracks/Api/ChaintracksClientApi'\n\nexport type MonitorStorage = WalletStorageManager\nexport type MonitorStartupTaskMode = 'none' | 'default' | 'multiuser' | 'alltoother'\n\nexport interface MonitorOptions {\n  chain: Chain\n\n  services: Services | WalletServices\n\n  storage: MonitorStorage\n\n  chaintracks: ChaintracksClientApi\n\n  chaintracksWithEvents?: ChaintracksClientApi\n\n  startupTaskMode?: MonitorStartupTaskMode\n\n  /**\n   * How many msecs to wait after each getMerkleProof service request.\n   */\n  msecsWaitPerMerkleProofServiceReq: number\n\n  taskRunWaitMsecs: number\n\n  abandonedMsecs: number\n\n  unprovenAttemptsLimitTest: number\n\n  unprovenAttemptsLimitMain: number\n\n  /**\n   * Maximum number of times a broadcast transaction may be reset to 'unsent' for\n   * rebroadcast after proof check timeout (circuit breaker).\n   *\n   * Default 0 means unlimited — the tx is rebroadcast indefinitely until a proof\n   * is found. Set to a positive integer to cap rebroadcast cycles; once the limit\n   * is reached the req is marked 'invalid'.\n   */\n  maxRebroadcastAttempts: number\n\n  /**\n   * Stable callback token for ARC SSE event streaming.\n   * When set, TaskArcadeSSE will open an SSE connection to Arcade's\n   * /events endpoint and receive real-time transaction status updates.\n   * Must match the X-CallbackToken header sent during broadcast.\n   */\n  callbackToken?: string\n\n  /** Load persisted SSE lastEventId (e.g. from SQLite) for catchup on startup */\n  loadLastSSEEventId?: () => Promise<string | undefined>\n  /** Save SSE lastEventId to persistent storage */\n  saveLastSSEEventId?: (lastEventId: string) => Promise<void>\n  /** The react-native-sse EventSource class for SSE support in React Native */\n  EventSourceClass?: any\n\n  /**\n   * These are hooks for a wallet-toolbox client to get transaction updates.\n   */\n  onTransactionBroadcasted?: (broadcastResult: ReviewActionResult) => Promise<void>\n  onTransactionProven?: (txStatus: ProvenTransactionStatus) => Promise<void>\n  onTransactionStatusChanged?: (txid: string, newStatus: string) => Promise<void>\n}\n\n/**\n * Background task to make sure transactions are processed, transaction proofs are received and propagated,\n * and potentially that reorgs update proofs that were already received.\n */\nexport class Monitor {\n  static createDefaultWalletMonitorOptions (\n    chain: Chain,\n    storage: MonitorStorage,\n    services?: Services,\n    chaintracks?: ChaintracksClientApi,\n    startupTaskMode: MonitorStartupTaskMode = 'none'\n  ): MonitorOptions {\n    services ??= new Services(chain)\n    if (services.options.chaintracks == null) throw new WERR_INVALID_PARAMETER('services.options.chaintracks', 'valid')\n    const o: MonitorOptions = {\n      chain,\n      services,\n      storage,\n      msecsWaitPerMerkleProofServiceReq: 500,\n      taskRunWaitMsecs: 5000,\n      abandonedMsecs: 1000 * 60 * 5,\n      unprovenAttemptsLimitTest: 100,\n      unprovenAttemptsLimitMain: 144,\n      maxRebroadcastAttempts: 0,\n      chaintracks: services.options.chaintracks,\n      chaintracksWithEvents: chaintracks,\n      startupTaskMode\n    }\n    return o\n  }\n\n  options: MonitorOptions\n  services: Services | WalletServices\n  chain: Chain\n  storage: MonitorStorage\n  chaintracks: ChaintracksClientApi\n  chaintracksWithEvents?: ChaintracksClientApi\n  reorgSubscriptionPromise?: Promise<string>\n  headersSubscriptionPromise?: Promise<string>\n  onTransactionBroadcasted?: (broadcastResult: ReviewActionResult) => Promise<void>\n  onTransactionProven?: (txStatus: ProvenTransactionStatus) => Promise<void>\n  onTransactionStatusChanged?: (txid: string, newStatus: string) => Promise<void>\n\n  /**\n   * Resolves once the optional Chaintracks subscriptions have been registered.\n   * Await this before calling `startTasks()` if `chaintracksWithEvents` is provided\n   * and you need subscriptions to be active before the first task loop runs.\n   */\n  get ready (): Promise<void> {\n    this._readyInit ??= this._init()\n    return this._readyInit\n  }\n\n  private _readyInit?: Promise<void>\n\n  constructor (options: MonitorOptions) {\n    this.options = { ...options }\n    this.services = options.services\n    this.chain = this.services.chain\n    this.storage = options.storage\n    this.chaintracks = options.chaintracks\n    this.chaintracksWithEvents = options.chaintracksWithEvents\n    this.onTransactionProven = options.onTransactionProven\n    this.onTransactionBroadcasted = options.onTransactionBroadcasted\n    this.onTransactionStatusChanged = options.onTransactionStatusChanged\n\n    this.applyStartupTaskMode(options.startupTaskMode ?? 'none')\n  }\n\n  private async _init (): Promise<void> {\n    if (this.chaintracksWithEvents != null) {\n      this.reorgSubscriptionPromise = this.chaintracksWithEvents.subscribeReorgs(this.processReorg.bind(this))\n      this.headersSubscriptionPromise = this.chaintracksWithEvents.subscribeHeaders(this.processHeader.bind(this))\n      await Promise.all([this.reorgSubscriptionPromise, this.headersSubscriptionPromise])\n    }\n  }\n\n  private applyStartupTaskMode (mode: MonitorStartupTaskMode): void {\n    switch (mode) {\n      case 'default':\n        this.addDefaultTasks()\n        break\n      case 'multiuser':\n        this.addMultiUserTasks()\n        break\n      case 'alltoother':\n        this.addAllTasksToOther()\n        break\n      case 'none':\n        break\n      default:\n        throw new WERR_INVALID_PARAMETER('startupTaskMode', '\\'none\\', \\'default\\', \\'multiuser\\', or \\'alltoother\\'')\n    }\n  }\n\n  async destroy (): Promise<void> {\n    if (this.chaintracksWithEvents != null) {\n      const c = this.chaintracksWithEvents\n      if (this.reorgSubscriptionPromise != null) await c.unsubscribe(await this.reorgSubscriptionPromise)\n      if (this.headersSubscriptionPromise != null) await c.unsubscribe(await this.headersSubscriptionPromise)\n    }\n  }\n\n  static readonly oneSecond = 1000\n  static readonly oneMinute = 60 * Monitor.oneSecond\n  static readonly oneHour = 60 * Monitor.oneMinute\n  static readonly oneDay = 24 * Monitor.oneHour\n  static readonly oneWeek = 7 * Monitor.oneDay\n\n  /**\n   * _tasks are typically run by the scheduler but may also be run by runTask.\n   */\n  _tasks: WalletMonitorTask[] = []\n  /**\n   * _otherTasks can be run by runTask but not by scheduler.\n   */\n  _otherTasks: WalletMonitorTask[] = []\n  _tasksRunning = false\n\n  defaultPurgeParams: TaskPurgeParams = {\n    purgeSpent: false,\n    purgeCompleted: false,\n    purgeFailed: true,\n    purgeSpentAge: 2 * Monitor.oneWeek,\n    purgeCompletedAge: 2 * Monitor.oneWeek,\n    purgeFailedAge: 5 * Monitor.oneDay\n  }\n\n  addAllTasksToOther (): void {\n    this._otherTasks.push(\n      new TaskClock(this),\n      new TaskNewHeader(this),\n      new TaskMonitorCallHistory(this),\n      new TaskSendWaiting(this),\n      new TaskCheckForProofs(this),\n      new TaskCheckNoSends(this),\n      new TaskFailAbandoned(this),\n      new TaskUnFail(this),\n      new TaskReviewStatus(this),\n      new TaskReorg(this),\n      new TaskReviewUtxos(this),\n      new TaskReviewDoubleSpends(this),\n      new TaskReviewProvenTxs(this),\n      new TaskCleanupActionBatches(this),\n      new TaskPurge(this, this.defaultPurgeParams)\n    )\n    if (this.chain === 'mock') {\n      this._otherTasks.push(new TaskMineBlock(this))\n    }\n  }\n\n  /**\n   * Default tasks with settings appropriate for a single user storage\n   */\n  addDefaultTasks (): void {\n    this._tasks.push(\n      new TaskClock(this),\n      new TaskNewHeader(this),\n      new TaskMonitorCallHistory(this),\n      new TaskSendWaiting(this, 8 * Monitor.oneSecond, 7 * Monitor.oneSecond), // Check every 8 seconds but must be 7 seconds old\n      new TaskCheckForProofs(this, 2 * Monitor.oneHour), // Every two hours if no block found\n      new TaskCheckNoSends(this),\n      new TaskFailAbandoned(this, 8 * Monitor.oneMinute),\n      new TaskUnFail(this),\n      new TaskReviewStatus(this),\n      new TaskReorg(this),\n      new TaskReviewDoubleSpends(this),\n      new TaskReviewProvenTxs(this),\n      new TaskCleanupActionBatches(this),\n      new TaskArcadeSSE(this)\n    )\n    this._otherTasks.push(\n      new TaskPurge(this, this.defaultPurgeParams, 6 * Monitor.oneHour),\n      new TaskReviewUtxos(this)\n    )\n    if (this.chain === 'mock') {\n      this._tasks.push(new TaskMineBlock(this))\n    }\n  }\n\n  /**\n   * Tasks appropriate for multi-user storage\n   */\n  addMultiUserTasks (): void {\n    this._tasks.push(\n      new TaskClock(this),\n      new TaskNewHeader(this),\n      new TaskMonitorCallHistory(this),\n      new TaskSendWaiting(this, 8 * Monitor.oneSecond, 7 * Monitor.oneSecond), // Check every 8 seconds but must be 7 seconds old\n      new TaskCheckForProofs(this, 2 * Monitor.oneHour), // Every two hours if no block found\n      new TaskCheckNoSends(this),\n      new TaskFailAbandoned(this, 8 * Monitor.oneMinute),\n      new TaskUnFail(this),\n      new TaskReviewStatus(this),\n      new TaskReorg(this),\n      new TaskReviewDoubleSpends(this),\n      new TaskReviewProvenTxs(this),\n      new TaskCleanupActionBatches(this),\n      new TaskArcadeSSE(this)\n    )\n    this._otherTasks.push(\n      new TaskPurge(this, this.defaultPurgeParams),\n      new TaskReviewUtxos(this)\n    )\n    if (this.chain === 'mock') {\n      this._tasks.push(new TaskMineBlock(this))\n    }\n  }\n\n  addTask (task: WalletMonitorTask): void {\n    if (this._tasks.some(t => t.name === task.name)) { throw new WERR_BAD_REQUEST(`task ${task.name} has already been added.`) }\n    this._tasks.push(task)\n  }\n\n  removeTask (name: string): void {\n    this._tasks = this._tasks.filter(t => t.name !== name)\n  }\n\n  async runTask (name: string): Promise<string> {\n    let task = this._tasks.find(t => t.name === name)\n    let log = ''\n    task ??= this._otherTasks.find(t => t.name === name)\n    if (task != null) {\n      await task.asyncSetup()\n      log = await task.runTask()\n    }\n    return log\n  }\n\n  async runOnce (): Promise<void> {\n    await this.setupTasksOnce()\n    if (!this.storage.getActive().isStorageProvider()) return\n    for (const task of await this.tasksReadyToRun()) {\n      await this.runScheduledTask(task)\n    }\n  }\n\n  private async setupTasksOnce (): Promise<void> {\n    if (!this._runAsyncSetup) return\n    for (const task of this._tasks) {\n      try {\n        await task.asyncSetup()\n      } catch (error_: unknown) {\n        await this.logTaskError(task, 'asyncSetup', 'error0', error_)\n      }\n      if (!this._tasksRunning) break\n    }\n    this._runAsyncSetup = false\n  }\n\n  private async tasksReadyToRun (): Promise<WalletMonitorTask[]> {\n    const tasks: WalletMonitorTask[] = []\n    const now = Date.now()\n    for (const task of this._tasks) {\n      try {\n        if (task.trigger(now).run) tasks.push(task)\n      } catch (error_: unknown) {\n        await this.logTaskError(task, 'trigger', 'error0', error_)\n      }\n    }\n    return tasks\n  }\n\n  private async runScheduledTask (task: WalletMonitorTask): Promise<void> {\n    try {\n      if (!this.storage.getActive().isStorageProvider()) return\n      const log = await task.runTask()\n      if (log.length === 0) return\n      const details = task.name === 'MonitorCallHistory' ? '...' : log.slice(0, 1024)\n      console.log(`Task${task.name} ${details}`)\n      await this.logEvent(task.name, log)\n    } catch (error_: unknown) {\n      await this.logTaskError(task, 'runTask', 'error1', error_, true)\n    } finally {\n      task.lastRunMsecsSinceEpoch = Date.now()\n    }\n  }\n\n  private async logTaskError (\n    task: WalletMonitorTask,\n    operation: 'asyncSetup' | 'trigger' | 'runTask',\n    event: 'error0' | 'error1',\n    error_: unknown,\n    includeStack = false\n  ): Promise<void> {\n    const error = WalletError.fromUnknown(error_)\n    const stack = includeStack ? `\\n${error.stack ?? ''}` : ''\n    const details = `monitor task ${task.name} ${operation} error ${error.code} ${error.description}${stack}`\n    console.log(details)\n    await this.logEvent(event, details)\n  }\n\n  _runAsyncSetup: boolean = true\n  _tasksRunningPromise?: PromiseLike<void>\n  resolveCompletion: ((value: void | PromiseLike<void>) => void) | undefined = undefined\n\n  async startTasks (): Promise<void> {\n    if (this._tasksRunning) throw new WERR_BAD_REQUEST('monitor tasks are already runnining.')\n\n    this._tasksRunning = true\n    this._tasksRunningPromise = new Promise(resolve => {\n      this.resolveCompletion = resolve\n    })\n\n    while (this._tasksRunning) {\n      await this.runOnce()\n\n      // console.log(`${new Date().toISOString()} tasks run, waiting...`)\n      await wait(this.options.taskRunWaitMsecs)\n    }\n\n    if (this.resolveCompletion != null) {\n      this.resolveCompletion()\n      this.resolveCompletion = undefined\n    }\n  }\n\n  async logEvent (event: string, details?: string): Promise<void> {\n    await this.storage.runAsStorageProvider(async sp => {\n      await sp.insertMonitorEvent({\n        created_at: new Date(),\n        updated_at: new Date(),\n        id: 0,\n        event,\n        details\n      })\n    })\n  }\n\n  stopTasks (): void {\n    this._tasksRunning = false\n  }\n\n  lastNewHeader: BlockHeader | undefined\n  lastNewHeaderWhen: Date | undefined\n\n  /**\n   * Process new chain header event received from Chaintracks\n   *\n   * Kicks processing 'unconfirmed' and 'unmined' request processing.\n   *\n   * @param reqs\n   */\n  processNewBlockHeader (header: BlockHeader): void {\n    const h = header\n    this.lastNewHeader = h\n    this.lastNewHeaderWhen = new Date()\n    // console.log(`WalletMonitor notified of new block header ${h.height}`)\n    // Nudge the proof checker to try again.\n    TaskCheckForProofs.checkNow = true\n    // Nudge the nosend checker too. Externally-broadcast nosend txs\n    // (created via createAction({noSend:true}) and broadcast by the\n    // caller through ARC, a ladder, or other external paths) may have\n    // confirmed in this new block. TaskCheckNoSends.runTask processes\n    // 'nosend' reqs via getProofs the same way TaskCheckForProofs\n    // processes 'unmined'/'unknown'/... reqs; without this nudge the\n    // task only fires on its triggerMsecs cadence (default once per\n    // day) which combined with intermittent wallet uptime means the\n    // nosend lifecycle has no reliable retirement path. The\n    // TaskCheckNoSends.checkNow flag was designed for this signal\n    // (see TaskCheckNoSends.ts:22-25) but was never wired.\n    TaskCheckNoSends.checkNow = true\n  }\n\n  /**\n   * This is a function run from a TaskSendWaiting Monitor task.\n   *\n   * This allows the user of wallet-toolbox to 'subscribe' for transaction broadcast updates.\n   *\n   * @param broadcastResult\n   */\n  callOnBroadcastedTransaction (broadcastResult: ReviewActionResult): void {\n    if (this.onTransactionBroadcasted != null) {\n      void this.onTransactionBroadcasted(broadcastResult)\n    }\n  }\n\n  /**\n   * This is a function run from a TaskCheckForProofs Monitor task.\n   *\n   * This allows the user of wallet-toolbox to 'subscribe' for transaction updates.\n   *\n   * @param txStatus\n   */\n  callOnProvenTransaction (txStatus: ProvenTransactionStatus): void {\n    if (this.onTransactionProven != null) {\n      void this.onTransactionProven(txStatus)\n    }\n  }\n\n  /**\n   * Called by TaskArcadeSSE when an SSE status event is received from Arcade.\n   */\n  callOnTransactionStatusChanged (txid: string, newStatus: string): void {\n    if (this.onTransactionStatusChanged != null) {\n      void this.onTransactionStatusChanged(txid, newStatus)\n    }\n  }\n\n  /**\n   * Fetch pending transaction status events from Arcade on demand.\n   * Call this on app open, balance refresh, transaction list view, etc.\n   */\n  async fetchSSEEvents (): Promise<number> {\n    const sseTask = this._tasks.find(t => t.name === TaskArcadeSSE.taskName) as TaskArcadeSSE | undefined\n    return (await sseTask?.fetchNow()) ?? 0\n  }\n\n  deactivatedHeaders: DeactivedHeader[] = []\n\n  /**\n   * Process reorg event received from Chaintracks\n   *\n   * Reorgs can move recent transactions to new blocks at new index positions.\n   * Affected transaction proofs become invalid and must be updated.\n   *\n   * It is possible for a transaction to become invalid.\n   *\n   * Coinbase transactions always become invalid.\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  processReorg (depth: number, oldTip: BlockHeader, newTip: BlockHeader, deactivatedHeaders?: BlockHeader[]): void {\n    if (deactivatedHeaders != null) {\n      for (const header of deactivatedHeaders) {\n        this.deactivatedHeaders.push({\n          whenMsecs: Date.now(),\n          tries: 0,\n          header\n        })\n      }\n    }\n  }\n\n  /**\n   * Handler for new header events from Chaintracks.\n   *\n   * To minimize reorg processing, new headers are aged before processing via TaskNewHeader.\n   * Therefore this handler is intentionally a no-op.\n   *\n   * @param header\n   */\n  // eslint-disable-next-line @typescript-eslint/no-unused-vars\n  processHeader (header: BlockHeader): void {\n    // Intentional no-op: new headers are aged via TaskNewHeader before processing\n  }\n}\n\nexport interface DeactivedHeader {\n  /**\n   * To control aging of notification before pursuing updated proof data.\n   */\n  whenMsecs: number\n  /**\n   * Number of attempts made to process the header.\n   * Supports returning deactivation notification to the queue if proof data is not yet available.\n   */\n  tries: number\n  /**\n   * The deactivated block header.\n   */\n  header: BlockHeader\n}\n","import { KeyDeriverApi } from '@bsv/sdk'\nimport { WalletStorageManager } from '../storage/WalletStorageManager'\nimport { Chain } from '../sdk/types'\n\nexport class WalletSigner {\n  isWalletSigner = true as const\n\n  chain: Chain\n  keyDeriver: KeyDeriverApi\n  storage: WalletStorageManager\n\n  constructor (chain: Chain, keyDeriver: KeyDeriverApi, storage: WalletStorageManager) {\n    this.chain = chain\n    this.keyDeriver = keyDeriver\n    this.storage = storage\n  }\n}\n","import { WalletInterface, OriginatorDomainNameStringUnder250Bytes, GetPublicKeyArgs, GetPublicKeyResult, RevealCounterpartyKeyLinkageArgs, RevealCounterpartyKeyLinkageResult, RevealSpecificKeyLinkageArgs, RevealSpecificKeyLinkageResult, WalletEncryptArgs, WalletEncryptResult, WalletDecryptArgs, WalletDecryptResult, CreateHmacArgs, CreateHmacResult, VerifyHmacArgs, VerifyHmacResult, CreateSignatureArgs, CreateSignatureResult, VerifySignatureArgs, VerifySignatureResult, CreateActionArgs, CreateActionResult, SignActionArgs, SignActionResult, AbortActionArgs, AbortActionResult, ListActionsArgs, ListActionsResult, InternalizeActionArgs, InternalizeActionResult, ListOutputsArgs, ListOutputsResult, RelinquishOutputArgs, RelinquishOutputResult, AcquireCertificateArgs, AcquireCertificateResult, ListCertificatesArgs, ListCertificatesResult, ProveCertificateArgs, ProveCertificateResult, RelinquishCertificateArgs, RelinquishCertificateResult, DiscoverByIdentityKeyArgs, DiscoverByAttributesArgs, DiscoverCertificatesResult, AuthenticatedResult, GetHeightResult, GetHeaderArgs, GetHeaderResult, GetNetworkResult, GetVersionResult, Utils, Random, SymmetricKey } from '@bsv/sdk'\n\nimport { PrivilegedKeyManager } from './sdk/PrivilegedKeyManager'\n\n/**\n * SimpleWalletManager is a slimmed-down wallet manager that only requires two things to authenticate:\n *  1. A primary key (32 bytes), which represents the core secret for the wallet.\n *  2. A privileged key manager (an instance of `PrivilegedKeyManager`), responsible for\n *     more sensitive operations.\n *\n * Once both pieces are provided (or if a snapshot containing the primary key is loaded,\n * and the privileged key manager is provided separately), the wallet becomes authenticated.\n *\n * After authentication, calls to the standard wallet methods (`createAction`, `signAction`, etc.)\n * are proxied to an underlying `WalletInterface` instance returned by a user-supplied `walletBuilder`.\n *\n * **Important**: This manager does not handle user password flows, recovery, or on-chain\n * token management. It is a straightforward wrapper that ensures the user has provided\n * both their main secret (primary key) and a privileged key manager before allowing usage.\n *\n * It also prevents calls from the special \"admin originator\" from being used externally.\n * (Any call that tries to use the admin originator as its originator, other than the manager itself,\n * will result in an error, ensuring that only internal operations can use that originator.)\n *\n * The manager can also save and load snapshots of its state. In this simplified version,\n * the snapshot only contains the primary key. If you load a snapshot, you still need to\n * re-provide the privileged key manager to complete authentication.\n */\nexport class SimpleWalletManager implements WalletInterface {\n  /**\n   * Whether the user is currently authenticated (meaning both the primary key\n   * and privileged key manager have been provided).\n   */\n  authenticated = false\n\n  /**\n   * Resolves once the optional snapshot (if provided to the constructor) has been\n   * fully loaded and the wallet is ready to accept calls.\n   * When no snapshot is provided this resolves immediately.\n   * Await `ready` before calling wallet methods after constructing with a snapshot.\n   */\n  get ready (): Promise<void> {\n    this._readyInit ??= this._init()\n    return this._readyInit\n  }\n\n  private _readyInit?: Promise<void>\n\n  private readonly _initSnapshot?: number[]\n\n  /**\n   * The domain name of the administrative originator (wallet operator / vendor, or your own).\n   */\n  private readonly adminOriginator: OriginatorDomainNameStringUnder250Bytes\n\n  /**\n   * A function that, given the user's primary key and privileged key manager,\n   * returns a new `WalletInterface` instance that handles the actual signing,\n   * encryption, transaction building, etc.\n   */\n  private readonly walletBuilder: (primaryKey: number[], privilegedKeyManager: PrivilegedKeyManager) => Promise<WalletInterface>\n\n  /**\n   * The underlying wallet instance that is built once authenticated.\n   */\n  private underlying?: WalletInterface\n\n  /**\n   * The privileged key manager, responsible for sensitive tasks.\n   */\n  private underlyingPrivilegedKeyManager?: PrivilegedKeyManager\n\n  /**\n   * The primary key (32 bytes) that unlocks the wallet functionality.\n   */\n  private primaryKey?: number[]\n\n  /**\n   * Constructs a new `SimpleWalletManager`.\n   *\n   * @param adminOriginator The domain name of the administrative originator.\n   * @param walletBuilder   A function that, given a primary key and privileged key manager,\n   *                        returns a fully functional `WalletInterface`.\n   * @param stateSnapshot   If provided, a previously saved snapshot of the wallet's state.\n   *                        If the snapshot contains a primary key, it will be loaded immediately\n   *                        (though you will still need to provide a privileged key manager to authenticate).\n   */\n  constructor (\n    adminOriginator: OriginatorDomainNameStringUnder250Bytes,\n    walletBuilder: (primaryKey: number[], privilegedKeyManager: PrivilegedKeyManager) => Promise<WalletInterface>,\n    stateSnapshot?: number[]\n  ) {\n    this.adminOriginator = adminOriginator\n    this.walletBuilder = walletBuilder\n\n    // Store snapshot for lazy init; callers await ready before calling wallet methods.\n    this._initSnapshot = stateSnapshot\n  }\n\n  private async _init (): Promise<void> {\n    if (this._initSnapshot !== undefined) {\n      await this.loadSnapshot(this._initSnapshot)\n    }\n  }\n\n  /**\n   * Provides the primary key (32 bytes) needed for authentication.\n   * If a privileged key manager has already been provided, we attempt to build\n   * the underlying wallet. Otherwise, we wait until the manager is also provided.\n   *\n   * @param key A 32-byte primary key.\n   */\n  async providePrimaryKey (key: number[]): Promise<void> {\n    this.primaryKey = key\n    await this.tryBuildUnderlying()\n  }\n\n  /**\n   * Provides the privileged key manager needed for sensitive tasks.\n   * If a primary key has already been provided (or loaded from a snapshot),\n   * we attempt to build the underlying wallet. Otherwise, we wait until the key is provided.\n   *\n   * @param manager An instance of `PrivilegedKeyManager`.\n   */\n  async providePrivilegedKeyManager (manager: PrivilegedKeyManager): Promise<void> {\n    this.underlyingPrivilegedKeyManager = manager\n    await this.tryBuildUnderlying()\n  }\n\n  /**\n   * Internal method that checks if we have both the primary key and privileged manager.\n   * If so, we build the underlying wallet instance and become authenticated.\n   */\n  private async tryBuildUnderlying (): Promise<void> {\n    if (this.authenticated) {\n      throw new Error('The user is already authenticated.')\n    }\n    if ((this.primaryKey == null) || (this.underlyingPrivilegedKeyManager == null)) {\n      return\n    }\n    // Build the underlying wallet:\n    this.underlying = await this.walletBuilder(this.primaryKey, this.underlyingPrivilegedKeyManager)\n    this.authenticated = true\n  }\n\n  /**\n   * Destroys the underlying wallet, returning to a default (unauthenticated) state.\n   *\n   * This clears the primary key, the privileged key manager, and the `authenticated` flag.\n   */\n  destroy (): void {\n    this.underlying = undefined\n    this.underlyingPrivilegedKeyManager = undefined\n    this.authenticated = false\n    this.primaryKey = undefined\n  }\n\n  /**\n   * Saves the current wallet state (including just the primary key)\n   * into an encrypted snapshot. This snapshot can be stored and later\n   * passed to `loadSnapshot` to restore the primary key (and partially authenticate).\n   *\n   * **Note**: The snapshot does NOT include the privileged key manager.\n   * You must still provide that separately after loading the snapshot\n   * in order to complete authentication.\n   *\n   * @remarks\n   * Storing the snapshot (which contains the primary key) provides a significant\n   * portion of the wallet's secret material. It must be protected carefully.\n   *\n   * @returns A byte array representing the encrypted snapshot.\n   * @throws {Error} if no primary key is currently set.\n   */\n  saveSnapshot (): number[] {\n    if (this.primaryKey == null) {\n      throw new Error('No primary key is set; cannot save snapshot.')\n    }\n\n    // Generate a random snapshot encryption key:\n    const snapshotKey = Random(32)\n\n    // For this simple wallet manager, we only store the primary key.\n    const writer = new Utils.Writer()\n    // Write a 1-byte version:\n    writer.writeUInt8(1)\n    // Write a varint length and then the primary key bytes:\n    writer.writeVarIntNum(this.primaryKey.length)\n    writer.write(this.primaryKey)\n\n    const snapshotPreimage = writer.toArray()\n\n    // Encrypt the data with the snapshotKey:\n    const encryptedPayload = new SymmetricKey(snapshotKey).encrypt(snapshotPreimage) as number[]\n\n    // Build the final snapshot: [ snapshotKey (32 bytes) + encryptedPayload ]\n    const snapshotWriter = new Utils.Writer()\n    snapshotWriter.write(snapshotKey)\n    snapshotWriter.write(encryptedPayload)\n\n    return snapshotWriter.toArray()\n  }\n\n  /**\n   * Loads a previously saved state snapshot (produced by `saveSnapshot`).\n   * This will restore the primary key but will **not** restore the privileged key manager\n   * (that must be provided separately to complete authentication).\n   *\n   * @param snapshot A byte array that was previously returned by `saveSnapshot`.\n   * @throws {Error} If the snapshot format is invalid or decryption fails.\n   */\n  async loadSnapshot (snapshot: number[]): Promise<void> {\n    try {\n      const reader = new Utils.Reader(snapshot)\n\n      // First 32 bytes is the snapshotKey:\n      const snapshotKey = reader.read(32)\n\n      // The rest is the encrypted payload:\n      const encryptedPayload = reader.read()\n\n      // Decrypt the payload with the snapshotKey:\n      const decrypted = new SymmetricKey(snapshotKey).decrypt(encryptedPayload) as number[]\n\n      const payloadReader = new Utils.Reader(decrypted)\n\n      // Check version:\n      const version = payloadReader.readUInt8()\n      if (version !== 1) {\n        throw new Error(`Unsupported snapshot version: ${version}`)\n      }\n\n      // Read the varint length and the primary key:\n      const pkLength = payloadReader.readVarIntNum()\n      const pk = payloadReader.read(pkLength)\n\n      this.primaryKey = pk\n\n      // Attempt to build the underlying wallet if the privileged manager is already provided:\n      await this.tryBuildUnderlying()\n    } catch (error) {\n      throw new Error(`Failed to load snapshot: ${(error as Error).message}`)\n    }\n  }\n\n  /**\n   * Returns whether the user is currently authenticated (the wallet has a primary key\n   * and a privileged key manager). If not authenticated, an error is thrown.\n   *\n   * @param _ Not used in this manager.\n   * @param originator The originator domain, which must not be the admin originator.\n   * @throws If not authenticated, or if the originator is the admin.\n   */\n  async isAuthenticated (_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<AuthenticatedResult> {\n    this.ensureCanCall(originator)\n    return { authenticated: true }\n  }\n\n  /**\n   * Blocks until the user is authenticated (by providing primaryKey and privileged manager).\n   * If not authenticated yet, it waits until that occurs.\n   *\n   * @param _ Not used in this manager.\n   * @param originator The originator domain, which must not be the admin originator.\n   * @throws If the originator is the admin.\n   */\n  async waitForAuthentication (\n    _: {},\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<AuthenticatedResult> {\n    if (originator === this.adminOriginator) {\n      throw new Error('External applications cannot use the admin originator.')\n    }\n    while (!this.authenticated) {\n      await new Promise(resolve => setTimeout(resolve, 100))\n    }\n    return { authenticated: true }\n  }\n\n  async getPublicKey (\n    args: GetPublicKeyArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<GetPublicKeyResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.getPublicKey(args, originator)\n  }\n\n  async revealCounterpartyKeyLinkage (\n    args: RevealCounterpartyKeyLinkageArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RevealCounterpartyKeyLinkageResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.revealCounterpartyKeyLinkage(args, originator)\n  }\n\n  async revealSpecificKeyLinkage (\n    args: RevealSpecificKeyLinkageArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RevealSpecificKeyLinkageResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.revealSpecificKeyLinkage(args, originator)\n  }\n\n  async encrypt (\n    args: WalletEncryptArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<WalletEncryptResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.encrypt(args, originator)\n  }\n\n  async decrypt (\n    args: WalletDecryptArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<WalletDecryptResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.decrypt(args, originator)\n  }\n\n  async createHmac (\n    args: CreateHmacArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<CreateHmacResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.createHmac(args, originator)\n  }\n\n  async verifyHmac (\n    args: VerifyHmacArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<VerifyHmacResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.verifyHmac(args, originator)\n  }\n\n  async createSignature (\n    args: CreateSignatureArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<CreateSignatureResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.createSignature(args, originator)\n  }\n\n  async verifySignature (\n    args: VerifySignatureArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<VerifySignatureResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.verifySignature(args, originator)\n  }\n\n  async createAction (\n    args: CreateActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<CreateActionResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.createAction(args, originator)\n  }\n\n  async signAction (\n    args: SignActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<SignActionResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.signAction(args, originator)\n  }\n\n  async abortAction (\n    args: AbortActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<AbortActionResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.abortAction(args, originator)\n  }\n\n  async listActions (\n    args: ListActionsArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ListActionsResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.listActions(args, originator)\n  }\n\n  async internalizeAction (\n    args: InternalizeActionArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<InternalizeActionResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.internalizeAction(args, originator)\n  }\n\n  async listOutputs (\n    args: ListOutputsArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ListOutputsResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.listOutputs(args, originator)\n  }\n\n  async relinquishOutput (\n    args: RelinquishOutputArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RelinquishOutputResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.relinquishOutput(args, originator)\n  }\n\n  async acquireCertificate (\n    args: AcquireCertificateArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<AcquireCertificateResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.acquireCertificate(args, originator)\n  }\n\n  async listCertificates (\n    args: ListCertificatesArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ListCertificatesResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.listCertificates(args, originator)\n  }\n\n  async proveCertificate (\n    args: ProveCertificateArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<ProveCertificateResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.proveCertificate(args, originator)\n  }\n\n  async relinquishCertificate (\n    args: RelinquishCertificateArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<RelinquishCertificateResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.relinquishCertificate(args, originator)\n  }\n\n  async discoverByIdentityKey (\n    args: DiscoverByIdentityKeyArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<DiscoverCertificatesResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.discoverByIdentityKey(args, originator)\n  }\n\n  async discoverByAttributes (\n    args: DiscoverByAttributesArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<DiscoverCertificatesResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.discoverByAttributes(args, originator)\n  }\n\n  async getHeight (_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetHeightResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.getHeight({}, originator)\n  }\n\n  async getHeaderForHeight (\n    args: GetHeaderArgs,\n    originator?: OriginatorDomainNameStringUnder250Bytes\n  ): Promise<GetHeaderResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.getHeaderForHeight(args, originator)\n  }\n\n  async getNetwork (_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetNetworkResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.getNetwork({}, originator)\n  }\n\n  async getVersion (_: {}, originator?: OriginatorDomainNameStringUnder250Bytes): Promise<GetVersionResult> {\n    this.ensureCanCall(originator)\n    return await this.underlying!.getVersion({}, originator)\n  }\n\n  /**\n   * A small helper that throws if the user is not authenticated or if the\n   * provided originator is the admin (which is not permitted externally).\n   */\n  private ensureCanCall (originator?: OriginatorDomainNameStringUnder250Bytes) {\n    if (originator === this.adminOriginator) {\n      throw new Error('External applications cannot use the admin originator.')\n    }\n    if (!this.authenticated) {\n      throw new Error('User is not authenticated.')\n    }\n  }\n}\n","import { Telemetry, TelemetryConfig } from '@bsv/sdk'\n\nconst DEFAULT_TIMEOUT_MS = 10_000\nconst DEFAULT_MAX_REQUEST_BYTES = 1024 * 1024\nconst DEFAULT_MAX_RESPONSE_BYTES = 1024 * 1024\nconst MAX_CONFIGURED_TIMEOUT_MS = 120_000\nconst MAX_CONFIGURED_REQUEST_BYTES = 10 * 1024 * 1024\nconst MAX_CONFIGURED_RESPONSE_BYTES = 10 * 1024 * 1024\n\nconst defaultFetch: typeof fetch | undefined =\n  typeof globalThis !== 'undefined' && typeof globalThis.fetch === 'function'\n    ? globalThis.fetch.bind(globalThis)\n    : undefined\n\nexport type WABClientErrorCode =\n  | 'WAB_INVALID_CONFIGURATION'\n  | 'WAB_INVALID_REQUEST'\n  | 'WAB_NETWORK_ERROR'\n  | 'WAB_TIMEOUT'\n  | 'WAB_HTTP_ERROR'\n  | 'WAB_ENDPOINT_MISMATCH'\n  | 'WAB_REQUEST_TOO_LARGE'\n  | 'WAB_RESPONSE_TOO_LARGE'\n  | 'WAB_INVALID_RESPONSE'\n\nexport interface WABClientErrorOptions {\n  cause?: unknown\n  correlationId?: string\n  operation?: string\n  route?: string\n  endpointMarkerPresent?: boolean\n  responseCorrelationMatched?: boolean\n}\n\n/**\n * A privacy-safe WAB transport failure. Response bodies and request payloads\n * are deliberately excluded from the error.\n */\nexport class WABClientError extends Error {\n  constructor (\n    public readonly code: WABClientErrorCode,\n    message: string,\n    public readonly retryable: boolean,\n    public readonly status?: number,\n    options: WABClientErrorOptions = {}\n  ) {\n    super(message, options)\n    this.name = 'WABClientError'\n    this.correlationId = options.correlationId\n    this.operation = options.operation\n    this.route = options.route\n    this.endpointMarkerPresent = options.endpointMarkerPresent\n    this.responseCorrelationMatched = options.responseCorrelationMatched\n  }\n\n  public readonly correlationId?: string\n  public readonly operation?: string\n  public readonly route?: string\n  public readonly endpointMarkerPresent?: boolean\n  public readonly responseCorrelationMatched?: boolean\n}\n\nexport interface WABTransportOptions {\n  /** Injectable fetch implementation for React Native, tests, and custom runtimes. */\n  fetch?: typeof fetch\n  /** Hard wall-clock request timeout. Defaults to 10 seconds. */\n  timeoutMs?: number\n  /** Maximum encoded JSON request size. Defaults to 1 MiB. */\n  maxRequestBytes?: number\n  /** Maximum accepted JSON response size. Defaults to 1 MiB. */\n  maxResponseBytes?: number\n  /** Optional privacy-bounded telemetry integration. */\n  telemetry?: TelemetryConfig\n}\n\nexport interface WABRequestOptions {\n  method?: 'GET' | 'POST'\n  body?: unknown\n  operation: string\n  correlationId?: string\n}\n\ninterface WABRequestMetadata {\n  method: 'GET' | 'POST'\n  path: string\n  operation: string\n  correlationId: string\n  startedAt: number\n  errorContext: WABClientErrorOptions\n}\n\ninterface WABRequestTimeout {\n  controller: AbortController\n  promise: Promise<never>\n  timer?: ReturnType<typeof setTimeout>\n  timedOut: boolean\n}\n\nfunction isLocalHostname (hostname: string): boolean {\n  const normalized = hostname.toLowerCase()\n  return normalized === 'localhost' ||\n    normalized === '127.0.0.1' ||\n    normalized === '[::1]' ||\n    normalized.endsWith('.localhost')\n}\n\ninterface NormalizedServerUrl {\n  baseUrl: string\n  origin: string\n}\n\nfunction normalizeServerUrl (serverUrl: string): NormalizedServerUrl {\n  let parsed: URL\n  try {\n    parsed = new URL(serverUrl)\n  } catch {\n    throw new WABClientError(\n      'WAB_INVALID_CONFIGURATION',\n      'WAB server URL must be an absolute URL.',\n      false\n    )\n  }\n\n  if (parsed.username !== '' || parsed.password !== '' || parsed.search !== '' || parsed.hash !== '') {\n    throw new WABClientError(\n      'WAB_INVALID_CONFIGURATION',\n      'WAB server URL must not contain credentials, a query, or a fragment.',\n      false\n    )\n  }\n  if (parsed.protocol !== 'https:' && !(parsed.protocol === 'http:' && isLocalHostname(parsed.hostname))) {\n    throw new WABClientError(\n      'WAB_INVALID_CONFIGURATION',\n      'WAB server URL must use HTTPS. Plain HTTP is allowed only for localhost development.',\n      false\n    )\n  }\n\n  let pathname = parsed.pathname\n  while (pathname.endsWith('/')) {\n    pathname = pathname.slice(0, -1)\n  }\n  return {\n    baseUrl: `${parsed.origin}${pathname}`,\n    origin: parsed.origin\n  }\n}\n\nfunction normalizePositiveInteger (\n  value: number | undefined,\n  fallback: number,\n  maximum: number,\n  name: string\n): number {\n  const resolved = value ?? fallback\n  if (!Number.isInteger(resolved) || resolved <= 0 || resolved > maximum) {\n    throw new WABClientError(\n      'WAB_INVALID_CONFIGURATION',\n      `${name} must be a positive integer no greater than ${maximum}.`,\n      false\n    )\n  }\n  return resolved\n}\n\nfunction assertSafePath (path: string): void {\n  if (!/^\\/[a-zA-Z0-9/_-]*$/.test(path) || path.includes('..')) {\n    throw new WABClientError('WAB_INVALID_REQUEST', 'Invalid WAB endpoint path.', false)\n  }\n}\n\nfunction isRetryableStatus (status: number): boolean {\n  return status === 408 || status === 425 || status === 429 || status >= 500\n}\n\nfunction isSafeCorrelationId (value: string): boolean {\n  return /^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(value)\n}\n\nfunction isWabResponse (response: Response): boolean {\n  return response.headers.get('X-WAB-Service')?.toLowerCase() === 'wab-server'\n}\n\n/**\n * Centralized, bounded transport used by every WAB client operation.\n *\n * Only fixed endpoint metadata is reported. Request bodies and response bodies\n * never cross the telemetry boundary.\n */\nexport class WABTransport {\n  readonly serverUrl: string\n  readonly serverOrigin: string\n  readonly telemetry: Telemetry\n\n  private readonly fetchClient: typeof fetch\n  private readonly timeoutMs: number\n  private readonly maxRequestBytes: number\n  private readonly maxResponseBytes: number\n\n  constructor (serverUrl: string, options: WABTransportOptions = {}) {\n    const normalized = normalizeServerUrl(serverUrl)\n    this.serverUrl = normalized.baseUrl\n    this.serverOrigin = normalized.origin\n    const fetchClient = options.fetch ?? defaultFetch\n    if (typeof fetchClient !== 'function') {\n      throw new WABClientError(\n        'WAB_INVALID_CONFIGURATION',\n        'WABClient requires a fetch implementation.',\n        false\n      )\n    }\n    this.fetchClient = fetchClient\n    this.timeoutMs = normalizePositiveInteger(\n      options.timeoutMs,\n      DEFAULT_TIMEOUT_MS,\n      MAX_CONFIGURED_TIMEOUT_MS,\n      'timeoutMs'\n    )\n    this.maxRequestBytes = normalizePositiveInteger(\n      options.maxRequestBytes,\n      DEFAULT_MAX_REQUEST_BYTES,\n      MAX_CONFIGURED_REQUEST_BYTES,\n      'maxRequestBytes'\n    )\n    this.maxResponseBytes = normalizePositiveInteger(\n      options.maxResponseBytes,\n      DEFAULT_MAX_RESPONSE_BYTES,\n      MAX_CONFIGURED_RESPONSE_BYTES,\n      'maxResponseBytes'\n    )\n    this.telemetry = new Telemetry(options.telemetry)\n  }\n\n  createCorrelationId (): string {\n    const correlationId = this.telemetry.createCorrelationId()\n    return isSafeCorrelationId(correlationId)\n      ? correlationId\n      : new Telemetry().createCorrelationId()\n  }\n\n  async request<T>(path: string, options: WABRequestOptions): Promise<T> {\n    const metadata = this.createRequestMetadata(path, options)\n    this.captureRequestStarted(metadata)\n    const body = this.encodeRequestBody(options, metadata)\n    const timeout = this.startRequestTimeout(metadata.errorContext)\n    const response = await this.fetchResponse(metadata, body, timeout)\n    const responseContext = this.createResponseContext(response, metadata)\n    this.assertSuccessfulResponse(response, responseContext, metadata, timeout)\n    const responseText = await this.readResponseText(response, responseContext, metadata, timeout)\n\n    const parsed = this.parseResponseObject<T>(\n      responseText,\n      response,\n      responseContext,\n      metadata\n    )\n\n    this.telemetry.capture({\n      name: 'wallet-toolbox.wab.request.completed',\n      component: 'wallet-toolbox.wab-transport',\n      severity: 'info',\n      correlationId: metadata.correlationId,\n      attributes: {\n        operation: metadata.operation,\n        method: metadata.method,\n        route: metadata.path,\n        serverOrigin: this.serverOrigin,\n        status: response.status,\n        endpointMarkerPresent: responseContext.endpointMarkerPresent,\n        responseCorrelationMatched: responseContext.responseCorrelationMatched,\n        responseBytes: new TextEncoder().encode(responseText).byteLength,\n        durationMs: Date.now() - metadata.startedAt\n      }\n    })\n    return parsed\n  }\n\n  private createRequestMetadata (\n    path: string,\n    options: WABRequestOptions\n  ): WABRequestMetadata {\n    assertSafePath(path)\n    const correlationId = options.correlationId != null &&\n      isSafeCorrelationId(options.correlationId)\n      ? options.correlationId\n      : this.createCorrelationId()\n    return {\n      method: options.method ?? 'POST',\n      path,\n      operation: options.operation,\n      correlationId,\n      startedAt: Date.now(),\n      errorContext: {\n        correlationId,\n        operation: options.operation,\n        route: path\n      }\n    }\n  }\n\n  private captureRequestStarted (metadata: WABRequestMetadata): void {\n    this.telemetry.capture({\n      name: 'wallet-toolbox.wab.request.started',\n      component: 'wallet-toolbox.wab-transport',\n      severity: 'debug',\n      correlationId: metadata.correlationId,\n      attributes: {\n        operation: metadata.operation,\n        method: metadata.method,\n        route: metadata.path,\n        serverOrigin: this.serverOrigin\n      }\n    })\n  }\n\n  private encodeRequestBody (\n    options: WABRequestOptions,\n    metadata: WABRequestMetadata\n  ): string | undefined {\n    let body: string | undefined\n    try {\n      body = options.body === undefined ? undefined : JSON.stringify(options.body)\n    } catch (cause) {\n      const error = new WABClientError(\n        'WAB_INVALID_REQUEST',\n        'WAB request payload could not be encoded.',\n        false,\n        undefined,\n        { ...metadata.errorContext, cause }\n      )\n      this.captureRequestFailure(metadata, error)\n      throw error\n    }\n    if (options.body !== undefined && body === undefined) {\n      const error = new WABClientError(\n        'WAB_INVALID_REQUEST',\n        'WAB request payload must be JSON-serializable.',\n        false,\n        undefined,\n        metadata.errorContext\n      )\n      this.captureRequestFailure(metadata, error)\n      throw error\n    }\n    if (body != null && new TextEncoder().encode(body).byteLength > this.maxRequestBytes) {\n      const error = new WABClientError(\n        'WAB_REQUEST_TOO_LARGE',\n        'WAB request exceeded the configured size limit.',\n        false,\n        undefined,\n        metadata.errorContext\n      )\n      this.captureRequestFailure(metadata, error)\n      throw error\n    }\n    return body\n  }\n\n  private startRequestTimeout (errorContext: WABClientErrorOptions): WABRequestTimeout {\n    const timeout = {\n      controller: new AbortController(),\n      timedOut: false\n    } as WABRequestTimeout\n    timeout.promise = new Promise<never>((_resolve, reject) => {\n      timeout.timer = setTimeout(() => {\n        timeout.timedOut = true\n        timeout.controller.abort()\n        reject(new WABClientError(\n          'WAB_TIMEOUT',\n          'WAB request timed out.',\n          true,\n          undefined,\n          errorContext\n        ))\n      }, this.timeoutMs)\n    })\n    return timeout\n  }\n\n  private async fetchResponse (\n    metadata: WABRequestMetadata,\n    body: string | undefined,\n    timeout: WABRequestTimeout\n  ): Promise<Response> {\n    const requestPromise = Promise.resolve().then(() =>\n      this.fetchClient(`${this.serverUrl}${metadata.path}`, {\n        method: metadata.method,\n        headers: {\n          Accept: 'application/json',\n          ...(body !== undefined ? { 'Content-Type': 'application/json' } : {}),\n          'X-Correlation-ID': metadata.correlationId\n        },\n        ...(body !== undefined ? { body } : {}),\n        signal: timeout.controller.signal,\n        credentials: 'omit',\n        redirect: 'error',\n        referrerPolicy: 'no-referrer'\n      })\n    )\n    requestPromise.catch(() => { /* timeout may settle the public request first */ })\n    try {\n      return await Promise.race([requestPromise, timeout.promise])\n    } catch (cause) {\n      if (timeout.timer !== undefined) clearTimeout(timeout.timer)\n      let error: WABClientError\n      if (cause instanceof WABClientError) {\n        error = cause\n      } else if (timeout.timedOut) {\n        error = new WABClientError(\n          'WAB_TIMEOUT',\n          'WAB request timed out.',\n          true,\n          undefined,\n          { ...metadata.errorContext, cause }\n        )\n      } else {\n        error = new WABClientError(\n          'WAB_NETWORK_ERROR',\n          'WAB request failed before receiving a response.',\n          true,\n          undefined,\n          { ...metadata.errorContext, cause }\n        )\n      }\n      this.captureRequestFailure(metadata, error)\n      throw error\n    }\n  }\n\n  private createResponseContext (\n    response: Response,\n    metadata: WABRequestMetadata\n  ): WABClientErrorOptions {\n    return {\n      ...metadata.errorContext,\n      endpointMarkerPresent: isWabResponse(response),\n      responseCorrelationMatched:\n        response.headers.get('X-Correlation-ID') === metadata.correlationId\n    }\n  }\n\n  private assertSuccessfulResponse (\n    response: Response,\n    responseContext: WABClientErrorOptions,\n    metadata: WABRequestMetadata,\n    timeout: WABRequestTimeout\n  ): void {\n    if (response.ok) return\n    if (timeout.timer !== undefined) clearTimeout(timeout.timer)\n    const endpointMismatch = response.status === 404 &&\n      responseContext.endpointMarkerPresent !== true\n    const error = new WABClientError(\n      endpointMismatch ? 'WAB_ENDPOINT_MISMATCH' : 'WAB_HTTP_ERROR',\n      endpointMismatch\n        ? 'Configured WAB endpoint did not return a compatible WAB response.'\n        : `WAB request failed with HTTP status ${response.status}.`,\n      isRetryableStatus(response.status),\n      response.status,\n      responseContext\n    )\n    this.captureRequestFailure(metadata, error)\n    void response.body?.cancel().catch(() => { /* best effort only */ })\n    throw error\n  }\n\n  private async readResponseText (\n    response: Response,\n    responseContext: WABClientErrorOptions,\n    metadata: WABRequestMetadata,\n    timeout: WABRequestTimeout\n  ): Promise<string> {\n    try {\n      return await Promise.race([\n        this.readBoundedResponse(response, responseContext),\n        timeout.promise\n      ])\n    } catch (cause) {\n      let error: WABClientError\n      if (cause instanceof WABClientError) {\n        error = cause\n      } else if (timeout.timedOut) {\n        error = new WABClientError(\n          'WAB_TIMEOUT',\n          'WAB request timed out.',\n          true,\n          response.status,\n          { ...responseContext, cause }\n        )\n      } else {\n        error = new WABClientError(\n          'WAB_INVALID_RESPONSE',\n          'WAB response could not be read.',\n          true,\n          response.status,\n          { ...responseContext, cause }\n        )\n      }\n      this.captureRequestFailure(metadata, error)\n      throw error\n    } finally {\n      if (timeout.timer !== undefined) clearTimeout(timeout.timer)\n    }\n  }\n\n  private parseResponseObject<T> (\n    responseText: string,\n    response: Response,\n    responseContext: WABClientErrorOptions,\n    metadata: WABRequestMetadata\n  ): T {\n    let parsed: unknown\n    try {\n      parsed = JSON.parse(responseText)\n    } catch (cause) {\n      const error = new WABClientError(\n        'WAB_INVALID_RESPONSE',\n        'WAB response was not valid JSON.',\n        true,\n        response.status,\n        { ...responseContext, cause }\n      )\n      this.captureRequestFailure(metadata, error)\n      throw error\n    }\n    if (parsed === null || typeof parsed !== 'object' || Array.isArray(parsed)) {\n      const error = new WABClientError(\n        'WAB_INVALID_RESPONSE',\n        'WAB response must be a JSON object.',\n        true,\n        response.status,\n        responseContext\n      )\n      this.captureRequestFailure(metadata, error)\n      throw error\n    }\n    return parsed as T\n  }\n\n  private captureRequestFailure (\n    metadata: WABRequestMetadata,\n    error: WABClientError\n  ): void {\n    this.captureFailure(\n      metadata.operation,\n      metadata.method,\n      metadata.path,\n      metadata.correlationId,\n      metadata.startedAt,\n      error\n    )\n  }\n\n  private async readBoundedResponse (\n    response: Response,\n    responseContext: WABClientErrorOptions\n  ): Promise<string> {\n    await this.rejectOversizedDeclaredResponse(response, responseContext)\n\n    const reader = response.body?.getReader()\n    if (reader == null) {\n      return await this.readBoundedArrayBuffer(response, responseContext)\n    }\n\n    return await this.readBoundedStream(reader, response, responseContext)\n  }\n\n  private async rejectOversizedDeclaredResponse (\n    response: Response,\n    responseContext: WABClientErrorOptions\n  ): Promise<void> {\n    const contentLength = Number(response.headers.get('content-length'))\n    if (!Number.isFinite(contentLength) || contentLength <= this.maxResponseBytes) return\n\n    await this.cancelResponseBody(response)\n    throw this.responseTooLargeError(response, responseContext)\n  }\n\n  private async readBoundedArrayBuffer (\n    response: Response,\n    responseContext: WABClientErrorOptions\n  ): Promise<string> {\n    const bytes = new Uint8Array(await response.arrayBuffer())\n    if (bytes.byteLength > this.maxResponseBytes) {\n      throw this.responseTooLargeError(response, responseContext)\n    }\n    return new TextDecoder().decode(bytes)\n  }\n\n  private async readBoundedStream (\n    reader: ReadableStreamDefaultReader<Uint8Array>,\n    response: Response,\n    responseContext: WABClientErrorOptions\n  ): Promise<string> {\n    const chunks: Uint8Array[] = []\n    let total = 0\n    while (true) {\n      const { done, value } = await reader.read()\n      if (done) break\n      if (value == null) continue\n      total += value.byteLength\n      if (total > this.maxResponseBytes) {\n        await this.cancelResponseReader(reader)\n        throw this.responseTooLargeError(response, responseContext)\n      }\n      chunks.push(value)\n    }\n\n    return this.decodeChunks(chunks, total)\n  }\n\n  private decodeChunks (chunks: Uint8Array[], total: number): string {\n    const bytes = new Uint8Array(total)\n    let offset = 0\n    for (const chunk of chunks) {\n      bytes.set(chunk, offset)\n      offset += chunk.byteLength\n    }\n    return new TextDecoder().decode(bytes)\n  }\n\n  private responseTooLargeError (\n    response: Response,\n    responseContext: WABClientErrorOptions\n  ): WABClientError {\n    return new WABClientError(\n      'WAB_RESPONSE_TOO_LARGE',\n      'WAB response exceeded the configured size limit.',\n      false,\n      response.status,\n      responseContext\n    )\n  }\n\n  private async cancelResponseBody (response: Response): Promise<void> {\n    try {\n      await response.body?.cancel()\n    } catch {\n      // Best effort only.\n    }\n  }\n\n  private async cancelResponseReader (\n    reader: ReadableStreamDefaultReader<Uint8Array>\n  ): Promise<void> {\n    try {\n      await reader.cancel()\n    } catch {\n      // Best effort only.\n    }\n  }\n\n  private captureFailure (\n    operation: string,\n    method: 'GET' | 'POST',\n    path: string,\n    correlationId: string,\n    startedAt: number,\n    error: WABClientError\n  ): void {\n    this.telemetry.capture({\n      name: 'wallet-toolbox.wab.request.failed',\n      component: 'wallet-toolbox.wab-transport',\n      severity: error.retryable ? 'warn' : 'error',\n      correlationId,\n      attributes: {\n        operation,\n        method,\n        route: path,\n        serverOrigin: this.serverOrigin,\n        retryable: error.retryable,\n        ...(error.status !== undefined ? { status: error.status } : {}),\n        ...(error.endpointMarkerPresent !== undefined\n          ? { endpointMarkerPresent: error.endpointMarkerPresent }\n          : {}),\n        ...(error.responseCorrelationMatched !== undefined\n          ? { responseCorrelationMatched: error.responseCorrelationMatched }\n          : {}),\n        durationMs: Date.now() - startedAt\n      },\n      error\n    })\n  }\n}\n","import { WABTransport } from '../WABTransport'\n\nexport interface AuthPayload {\n  [key: string]: unknown\n}\n\nexport interface StartAuthResponse {\n  success: boolean\n  message?: string\n  data?: unknown\n}\n\nexport interface CompleteAuthResponse {\n  success: boolean\n  message?: string\n  presentationKey?: string\n  /** Preferred explicit continuity signal for newer WAB servers. */\n  accountStatus?: 'new-user' | 'existing-user'\n  /** Compatibility signal accepted from WAB deployments using a boolean. */\n  existingUser?: boolean\n}\n\n/**\n * Abstract client-side interactor for an Auth Method.\n *\n * Subclasses only need to set `methodType`; the HTTP calls to\n * `/auth/start` and `/auth/complete` are handled here.\n */\nexport abstract class AuthMethodInteractor {\n  public abstract methodType: string\n\n  protected preparePayload (payload: AuthPayload): AuthPayload {\n    return payload\n  }\n\n  /**\n   * Shared POST helper for auth endpoints.\n   */\n  private async postAuth<T extends { success: boolean, message?: string }>(\n    serverUrl: string,\n    endpoint: string,\n    presentationKey: string,\n    payload: AuthPayload,\n    transport?: WABTransport,\n    correlationId?: string\n  ): Promise<T> {\n    const client = transport ?? new WABTransport(serverUrl)\n    return await client.request<T>(`/auth/${endpoint}`, {\n      operation: `auth-${endpoint}`,\n      correlationId,\n      body: {\n        methodType: this.methodType,\n        presentationKey,\n        payload: this.preparePayload(payload)\n      }\n    })\n  }\n\n  /**\n   * Start the flow (e.g. request an OTP or create a session).\n   */\n  public async startAuth (\n    serverUrl: string,\n    presentationKey: string,\n    payload: AuthPayload,\n    transport?: WABTransport,\n    correlationId?: string\n  ): Promise<StartAuthResponse> {\n    return await this.postAuth<StartAuthResponse>(\n      serverUrl,\n      'start',\n      presentationKey,\n      payload,\n      transport,\n      correlationId\n    )\n  }\n\n  /**\n   * Complete the flow (e.g. confirm OTP).\n   */\n  public async completeAuth (\n    serverUrl: string,\n    presentationKey: string,\n    payload: AuthPayload,\n    transport?: WABTransport,\n    correlationId?: string\n  ): Promise<CompleteAuthResponse> {\n    return await this.postAuth<CompleteAuthResponse>(\n      serverUrl,\n      'complete',\n      presentationKey,\n      payload,\n      transport,\n      correlationId\n    )\n  }\n}\n","import { AuthMethodInteractor } from './AuthMethodInteractor'\n\nexport class PersonaIDInteractor extends AuthMethodInteractor {\n  public methodType = 'PersonaID'\n}\n","import { AuthMethodInteractor, AuthPayload } from './AuthMethodInteractor'\n\n/**\n * TwilioPhoneInteractor\n *\n * A client-side class that knows how to call the WAB server for Twilio-based phone verification.\n */\nexport class TwilioPhoneInteractor extends AuthMethodInteractor {\n  public methodType = 'TwilioPhone'\n\n  protected override preparePayload (payload: AuthPayload): AuthPayload {\n    const phoneNumber = payload.phoneNumber\n    if (typeof phoneNumber !== 'string') {\n      throw new TypeError('TwilioPhone authentication requires phoneNumber.')\n    }\n    const normalized = phoneNumber.trim()\n    if (!/^\\+[1-9]\\d{7,14}$/.test(normalized)) {\n      throw new TypeError('phoneNumber must use canonical E.164 format.')\n    }\n    return {\n      ...payload,\n      phoneNumber: normalized\n    }\n  }\n}\n","import { AuthMethodInteractor } from './AuthMethodInteractor'\n\n/**\n * DevConsoleInteractor\n *\n * A client-side class that knows how to call the WAB server for DevConsole-based authentication.\n * This is a development-only auth method that generates OTP codes and logs them to the console.\n */\nexport class DevConsoleInteractor extends AuthMethodInteractor {\n  public methodType = 'DevConsole'\n}\n","import { PrivateKey } from '@bsv/sdk'\nimport {\n  AuthMethodInteractor,\n  AuthPayload,\n  CompleteAuthResponse,\n  StartAuthResponse\n} from './auth-method-interactors/AuthMethodInteractor'\nimport { WABTransport, WABTransportOptions } from './WABTransport'\n\nexport interface WABClientOptions extends WABTransportOptions {}\n\nexport interface WABServerInfo {\n  supportedAuthMethods?: string[]\n  [key: string]: unknown\n}\n\nexport interface WABOperationResponse {\n  success: boolean\n  message?: string\n  [key: string]: unknown\n}\n\nexport interface WABFaucetResponse extends WABOperationResponse {\n  paymentData?: {\n    k?: string\n    tx?: number[]\n    txid?: string\n  }\n}\n\nfunction assertHexIdentifier (value: string, name: string): void {\n  if (!/^[0-9a-fA-F]{64}$/.test(value)) {\n    throw new TypeError(`${name} must be a 32-byte hexadecimal string.`)\n  }\n}\n\nfunction assertMethodType (methodType: string): void {\n  if (!/^[a-zA-Z0-9_-]{1,64}$/.test(methodType)) {\n    throw new TypeError('methodType contains unsupported characters.')\n  }\n}\n\nfunction normalizeAuthPayload (methodType: string, payload: AuthPayload): AuthPayload {\n  if (methodType !== 'TwilioPhone') return payload\n  const phoneNumber = payload.phoneNumber\n  if (typeof phoneNumber !== 'string') {\n    throw new TypeError('TwilioPhone authentication requires phoneNumber.')\n  }\n  const normalized = phoneNumber.trim()\n  if (!/^\\+[1-9]\\d{7,14}$/.test(normalized)) {\n    throw new TypeError('phoneNumber must use canonical E.164 format.')\n  }\n  return {\n    ...payload,\n    phoneNumber: normalized\n  }\n}\n\n/**\n * Production-oriented WAB client with one security and observability boundary\n * for every endpoint.\n */\nexport class WABClient {\n  readonly transport: WABTransport\n\n  constructor (serverUrl: string, options: WABClientOptions = {}) {\n    this.transport = new WABTransport(serverUrl, options)\n  }\n\n  public async getInfo (): Promise<WABServerInfo> {\n    return await this.transport.request<WABServerInfo>('/info', {\n      method: 'GET',\n      operation: 'get-info'\n    })\n  }\n\n  public generateRandomPresentationKey (): string {\n    return PrivateKey.fromRandom().toHex()\n  }\n\n  public async startAuthMethod (\n    authMethod: AuthMethodInteractor,\n    presentationKey: string,\n    payload: AuthPayload,\n    correlationId?: string\n  ): Promise<StartAuthResponse> {\n    assertHexIdentifier(presentationKey, 'presentationKey')\n    return await authMethod.startAuth(\n      this.transport.serverUrl,\n      presentationKey,\n      payload,\n      this.transport,\n      correlationId\n    )\n  }\n\n  public async completeAuthMethod (\n    authMethod: AuthMethodInteractor,\n    presentationKey: string,\n    payload: AuthPayload,\n    correlationId?: string\n  ): Promise<CompleteAuthResponse> {\n    assertHexIdentifier(presentationKey, 'presentationKey')\n    return await authMethod.completeAuth(\n      this.transport.serverUrl,\n      presentationKey,\n      payload,\n      this.transport,\n      correlationId\n    )\n  }\n\n  public async listLinkedMethods (presentationKey: string): Promise<WABOperationResponse> {\n    assertHexIdentifier(presentationKey, 'presentationKey')\n    return await this.transport.request<WABOperationResponse>('/user/linkedMethods', {\n      operation: 'list-linked-methods',\n      body: { presentationKey }\n    })\n  }\n\n  public async unlinkMethod (\n    presentationKey: string,\n    authMethodId: number\n  ): Promise<WABOperationResponse> {\n    assertHexIdentifier(presentationKey, 'presentationKey')\n    if (!Number.isSafeInteger(authMethodId) || authMethodId <= 0) {\n      throw new TypeError('authMethodId must be a positive safe integer.')\n    }\n    return await this.transport.request<WABOperationResponse>('/user/unlinkMethod', {\n      operation: 'unlink-method',\n      body: { presentationKey, authMethodId }\n    })\n  }\n\n  public async requestFaucet (presentationKey: string): Promise<WABFaucetResponse> {\n    assertHexIdentifier(presentationKey, 'presentationKey')\n    return await this.transport.request<WABFaucetResponse>('/faucet/request', {\n      operation: 'request-faucet',\n      body: { presentationKey }\n    })\n  }\n\n  public async deleteUser (presentationKey: string): Promise<WABOperationResponse> {\n    assertHexIdentifier(presentationKey, 'presentationKey')\n    return await this.transport.request<WABOperationResponse>('/user/delete', {\n      operation: 'delete-user',\n      body: { presentationKey }\n    })\n  }\n\n  public async startShareAuth (\n    methodType: string,\n    userIdHash: string,\n    payload: AuthPayload\n  ): Promise<{ success: boolean, message: string }> {\n    assertMethodType(methodType)\n    assertHexIdentifier(userIdHash, 'userIdHash')\n    const normalizedPayload = normalizeAuthPayload(methodType, payload)\n    return await this.transport.request('/auth/start', {\n      operation: 'start-share-auth',\n      body: {\n        methodType,\n        presentationKey: userIdHash,\n        payload: normalizedPayload\n      }\n    })\n  }\n\n  public async storeShare (\n    methodType: string,\n    payload: AuthPayload,\n    shareB: string,\n    userIdHash: string\n  ): Promise<{ success: boolean, message: string, userId?: number }> {\n    assertMethodType(methodType)\n    assertHexIdentifier(userIdHash, 'userIdHash')\n    const normalizedPayload = normalizeAuthPayload(methodType, payload)\n    return await this.transport.request('/share/store', {\n      operation: 'store-share',\n      body: { methodType, payload: normalizedPayload, shareB, userIdHash }\n    })\n  }\n\n  public async retrieveShare (\n    methodType: string,\n    payload: AuthPayload,\n    userIdHash: string\n  ): Promise<{ success: boolean, shareB?: string, message: string }> {\n    assertMethodType(methodType)\n    assertHexIdentifier(userIdHash, 'userIdHash')\n    const normalizedPayload = normalizeAuthPayload(methodType, payload)\n    return await this.transport.request('/share/retrieve', {\n      operation: 'retrieve-share',\n      body: { methodType, payload: normalizedPayload, userIdHash }\n    })\n  }\n\n  public async updateShare (\n    methodType: string,\n    payload: AuthPayload,\n    userIdHash: string,\n    newShareB: string\n  ): Promise<{ success: boolean, message: string, shareVersion?: number }> {\n    assertMethodType(methodType)\n    assertHexIdentifier(userIdHash, 'userIdHash')\n    const normalizedPayload = normalizeAuthPayload(methodType, payload)\n    return await this.transport.request('/share/update', {\n      operation: 'update-share',\n      body: { methodType, payload: normalizedPayload, userIdHash, newShareB }\n    })\n  }\n\n  public async deleteShamirUser (\n    methodType: string,\n    payload: AuthPayload,\n    userIdHash: string\n  ): Promise<{ success: boolean, message: string }> {\n    assertMethodType(methodType)\n    assertHexIdentifier(userIdHash, 'userIdHash')\n    const normalizedPayload = normalizeAuthPayload(methodType, payload)\n    return await this.transport.request('/share/delete', {\n      operation: 'delete-share-user',\n      body: { methodType, payload: normalizedPayload, userIdHash }\n    })\n  }\n}\n","import { Beef, CreateActionArgs, WalletLoggerInterface, WalletLoggerLog } from '@bsv/sdk'\n\nimport { WalletError } from './sdk/WalletError'\n\nfunction logMarker (entry: WalletLoggerLog): string {\n  if (entry.isBegin) return ' begin'\n  if (entry.isEnd) return ' end'\n  if (entry.isError) return ' ERROR'\n  return ''\n}\n\nfunction logMessage (entry: WalletLoggerLog, begins: WalletLoggerLog[]): string {\n  if (entry.isBegin) begins.push(entry)\n  if (!entry.log && entry.isEnd && begins.length > 0) {\n    return begins.pop()!.log\n  }\n  return entry.log\n}\n\nfunction formatLogLine (\n  entry: WalletLoggerLog,\n  previous: WalletLoggerLog,\n  begins: WalletLoggerLog[]\n): string {\n  const elapsed = (entry.when - previous.when).toString()\n  const paddedElapsed = `${' '.repeat(8 - elapsed.length)}${elapsed}`\n  return `${paddedElapsed}${'  '.repeat(entry.indent)}${logMarker(entry)} ${logMessage(entry, begins)}\\n`\n}\n\nexport class WalletLogger implements WalletLoggerInterface {\n  indent: number = 0\n  logs: WalletLoggerLog[] = []\n  isOrigin: boolean = true\n  isError: boolean = false\n  level?: WalletLoggerLevel\n  flushFormat?: 'json'\n\n  constructor (log?: string | WalletLoggerInterface) {\n    if (log) {\n      const lo = typeof log === 'string' ? JSON.parse(log) : log\n      this.indent = lo.indent || 0\n      this.logs = lo.logs || []\n      this.isOrigin = this.indent === 0\n      this.level = lo.level\n    }\n  }\n\n  private logAny (message?: any): string {\n    if (!message) return ''\n    if (typeof message === 'string') return message\n    if (typeof message === 'object') return JSON.stringify(message)\n    return ''\n  }\n\n  private toAdd (\n    isBegin: boolean,\n    isEnd: boolean,\n    isError: boolean,\n    message?: any,\n    optionalParams?: any[]\n  ): WalletLoggerLog {\n    let add = ''\n    if (message) add += this.logAny(message)\n    if (optionalParams != null) for (const p of optionalParams) add += this.logAny(p)\n    const log = {\n      when: Date.now(),\n      indent: this.indent,\n      isBegin,\n      isEnd,\n      isError,\n      log: add\n    }\n    return log\n  }\n\n  private stampLog (isBegin: boolean, isEnd: boolean, isError: boolean, message?: any, optionalParams?: any[]) {\n    const add = this.toAdd(isBegin, isEnd, isError, message, optionalParams)\n    this.logs.push(add)\n  }\n\n  group (...label: any[]): void {\n    this.stampLog(true, false, false, undefined, label)\n    this.indent++\n  }\n\n  groupEnd (): void {\n    this.indent--\n    if (this.indent < 0) this.indent = 0\n    this.stampLog(false, true, false)\n  }\n\n  log (message?: any, ...optionalParams: any[]): void {\n    this.stampLog(false, false, false, message, optionalParams)\n  }\n\n  error (message?: any, ...optionalParams: any[]): void {\n    this.stampLog(false, false, true, message, optionalParams)\n    this.isError = true\n  }\n\n  toWalletLoggerJson (): object {\n    const json: object = {\n      isWalletLoggerJson: true,\n      indent: this.indent,\n      logs: this.logs,\n      isError: this.isError\n    }\n    return json\n  }\n\n  toLogString (): string {\n    if (this.logs.length === 0) return ''\n\n    const first = this.logs[0]\n    const last = this.logs.at(-1)!\n    const msecs = last.when - first.when\n    let log = `   msecs WalletLogger ${new Date(first.when).toISOString()} logged ${msecs / 1000} seconds\\n`\n    let previous = first\n    const begins: WalletLoggerLog[] = []\n\n    for (const entry of this.logs) {\n      log += formatLogLine(entry, previous, begins)\n      previous = entry\n    }\n\n    return log\n  }\n\n  flush (): object | undefined {\n    if (this.logs.length > 0) {\n      const trace = this.toLogString()\n      const output = this.isError ? console.error : console.log\n      if (this.flushFormat === 'json') {\n        const name = this.logs[0].log\n        const log = {\n          name,\n          trace\n        }\n        output(JSON.stringify(log))\n      } else {\n        output(trace)\n      }\n    }\n    const r = this.isOrigin ? undefined : this.toWalletLoggerJson()\n    return r\n  }\n\n  merge (log: WalletLoggerInterface): void {\n    if (log.logs != null) {\n      this.logs.push(...log.logs)\n    }\n  }\n}\n\nexport function logWalletError (eu: unknown, logger?: WalletLoggerInterface, label?: string): void {\n  if (logger == null) return\n  logger.error(label || 'WalletError', WalletError.unknownToJson(eu))\n}\n\nexport function logCreateActionArgs (args: CreateActionArgs): object {\n  const o: any = {\n    description: args.description\n  }\n  if (args.labels != null) o.labels = args.labels\n  if (args.inputBEEF != null) o.inputBEEF = Beef.fromBinary(args.inputBEEF).toLogString()\n  if (args.lockTime !== undefined) o.lockTime = args.lockTime\n  if (args.version !== undefined) o.version = args.version\n  /*\n    if (args.inputs) {\n\n    }\n    if (args.outputs) {\n\n    }\n    options: validateCreateActionOptions(args.options),\n    isSendWith: false,\n    isDelayed: false,\n    isNoSend: false,\n    isNewTx: false,\n    isRemixChange: false,\n    isSignAction: false,\n    randomVals: undefined,\n    includeAllSourceTransactions: false,\n    isTestWerrReviewActions: false\n  */\n  return o\n}\n\n/**\n * Optional. Logging levels that may influence what is logged.\n *\n * 'error' Only requests resulting in an exception should be logged.\n * 'warn' Also log requests that succeed but with an abnormal condition.\n * 'info' Also log normal successful requests.\n * 'debug' Add input parm and result details where possible.\n * 'trace' Instead of adding debug details, focus on execution path and timing.\n */\nexport type WalletLoggerLevel = 'error' | 'warn' | 'info' | 'debug' | 'trace'\n\n/**\n * Constructor properties available to `WalletLogger`\n */\nexport interface WalletLoggerArgs {\n  /**\n   * Optional. Logging levels that may influence what is logged.\n   *\n   * 'error' Only requests resulting in an exception should be logged.\n   * 'warn' Also log requests that succeed but with an abnormal condition.\n   * 'info' Also log normal successful requests.\n   * 'debug' Add input parm and result details where possible.\n   * 'trace' Instead of adding debug details, focus on execution path and timing.\n   */\n  level?: 'error' | 'warn' | 'info' | 'debug' | 'trace'\n\n  /**\n   * Valid if an accumulating logger. Count of `group` calls without matching `groupEnd`.\n   */\n  indent?: number\n  /**\n   * True if this is an accumulating logger and the logger belongs to the object servicing the initial request.\n   */\n  isOrigin?: boolean\n  /**\n   * True if this is an accumulating logger and an error was logged.\n   */\n  isError?: boolean\n\n  /**\n   * Optional array of accumulated logged data and errors.\n   */\n  logs?: WalletLoggerLog[]\n}\n","import { CWIStyleWalletManager, UMPTokenInteractor } from './CWIStyleWalletManager'\nimport { PrivilegedKeyManager } from './sdk/PrivilegedKeyManager'\nimport {\n  WalletInterface,\n  Random,\n  Utils,\n  Transaction,\n  RPuzzle,\n  PrivateKey,\n  BigNumber,\n  TelemetryConfig\n} from '@bsv/sdk'\nimport { WABClient } from './wab-client/WABClient'\nimport { WABClientError } from './wab-client/WABTransport'\nimport {\n  AuthMethodInteractor,\n  AuthPayload,\n  CompleteAuthResponse\n} from './wab-client/auth-method-interactors/AuthMethodInteractor'\n\nconst DEFAULT_AUTH_SESSION_TTL_MS = 10 * 60 * 1000\nconst MAX_AUTH_SESSION_TTL_MS = 60 * 60 * 1000\n\nexport interface WalletAuthenticationManagerOptions {\n  telemetry?: TelemetryConfig\n  /** Maximum lifetime of a temporary WAB presentation key. Defaults to 10 minutes. */\n  authSessionTtlMs?: number\n}\n\nexport class WABAccountContinuityError extends Error {\n  readonly code = 'WERR_WAB_ACCOUNT_CONTINUITY'\n\n  constructor (message: string = 'WAB and UMP account state did not agree. Retry or use account recovery.') {\n    super(message)\n    this.name = 'WABAccountContinuityError'\n  }\n}\n\ninterface WABAuthSession {\n  presentationKey: string\n  methodType: string\n  expiresAt: number\n  correlationId?: string\n}\n\n/**\n * WalletAuthenticationManager\n *\n * A wallet manager that integrates\n * with a WABClient for user authentication flows (e.g. Twilio phone).\n */\nexport class WalletAuthenticationManager extends CWIStyleWalletManager {\n  private readonly wabClient: WABClient // instance of WABClient\n  private authMethod?: AuthMethodInteractor // chosen AuthMethod interactor\n  private authSession?: WABAuthSession\n  private readonly authSessionTtlMs: number\n\n  constructor (\n    ...[\n      adminOriginator,\n      walletBuilder,\n      interactor,\n      recoveryKeySaver,\n      passwordRetriever,\n      wabClient,\n      authMethod,\n      stateSnapshot,\n      options = {}\n    ]: [\n      adminOriginator: string,\n      walletBuilder: (primaryKey: number[], privilegedKeyManager: PrivilegedKeyManager) => Promise<WalletInterface>,\n      interactor: UMPTokenInteractor | undefined,\n      recoveryKeySaver: (key: number[]) => Promise<true>,\n      passwordRetriever: (\n        reason: string,\n        test: (passwordCandidate: string) => boolean | Promise<boolean>\n      ) => Promise<string>,\n      wabClient: WABClient,\n      authMethod?: AuthMethodInteractor,\n      stateSnapshot?: number[],\n      options?: WalletAuthenticationManagerOptions\n    ]\n  ) {\n    super(\n      adminOriginator,\n      walletBuilder,\n      interactor,\n      recoveryKeySaver,\n      passwordRetriever,\n      // Here, we provide a custom new wallet funder that uses the Secret Server\n      async (presentationKey: number[], wallet: WalletInterface, adminOriginator: string) => {\n        const faucetResponse = await this.wabClient.requestFaucet(Utils.toHex(presentationKey))\n        const paymentData = faucetResponse.paymentData\n        const faucetSucceeded: unknown = faucetResponse.success\n\n        if (faucetSucceeded !== true || paymentData == null) {\n          const message = faucetResponse.message != null && faucetResponse.message.length > 0\n            ? faucetResponse.message\n            : 'Missing paymentData from WAB'\n          throw new Error(`Faucet request failed: ${message}`)\n        }\n\n        if (\n          paymentData.k == null ||\n          paymentData.k.length === 0 ||\n          paymentData.tx == null ||\n          paymentData.tx.length === 0 ||\n          paymentData.txid == null ||\n          paymentData.txid.length === 0\n        ) {\n          throw new Error('Faucet response missing required fields: k, tx, or txid')\n        }\n\n        try {\n          const tx = Transaction.fromAtomicBEEF(paymentData.tx)\n          const faucetRedeemTXCreationResult = await wallet.createAction(\n            {\n              inputBEEF: tx.toBEEF(),\n              inputs: [\n                {\n                  outpoint: `${paymentData.txid}.0`,\n                  unlockingScriptLength: 108,\n                  inputDescription: 'Fund from faucet'\n                }\n              ],\n              description: 'Fund wallet',\n              options: {\n                acceptDelayedBroadcast: false\n              }\n            },\n            adminOriginator\n          )\n\n          if (faucetRedeemTXCreationResult.signableTransaction == null) {\n            throw new Error('Faucet redemption did not return a signableTransaction')\n          }\n\n          const faucetRedeemTX = Transaction.fromAtomicBEEF(faucetRedeemTXCreationResult.signableTransaction.tx)\n          const faucetRedemptionPuzzle = new RPuzzle()\n          const randomRedemptionPrivateKey = PrivateKey.fromRandom()\n          const faucetRedeemUnlocker = faucetRedemptionPuzzle.unlock(\n            new BigNumber(paymentData.k, 16),\n            randomRedemptionPrivateKey\n          )\n          const faucetRedeemUnlockingScript = await faucetRedeemUnlocker.sign(faucetRedeemTX, 0)\n\n          await wallet.signAction({\n            reference: faucetRedeemTXCreationResult.signableTransaction.reference,\n            spends: {\n              0: {\n                unlockingScript: faucetRedeemUnlockingScript.toHex()\n              }\n            }\n          })\n        } catch (error) {\n          const message = error instanceof Error ? error.message : String(error)\n          throw new Error(`Faucet redemption failed: ${message}`)\n        }\n      },\n      stateSnapshot,\n      undefined,\n      options.telemetry\n    )\n\n    this.wabClient = wabClient\n    this.authMethod = authMethod\n    const authSessionTtlMs = options.authSessionTtlMs ?? DEFAULT_AUTH_SESSION_TTL_MS\n    if (\n      !Number.isInteger(authSessionTtlMs) ||\n      authSessionTtlMs <= 0 ||\n      authSessionTtlMs > MAX_AUTH_SESSION_TTL_MS\n    ) {\n      throw new TypeError(`authSessionTtlMs must be between 1 and ${MAX_AUTH_SESSION_TTL_MS}.`)\n    }\n    this.authSessionTtlMs = authSessionTtlMs\n  }\n\n  /**\n   * Sets (or switches) the chosen AuthMethodInteractor at runtime,\n   * in case the user changes their mind or picks a new method in the UI.\n   */\n  public setAuthMethod (method: AuthMethodInteractor): void {\n    if (this.authMethod?.methodType !== method.methodType) this.cancelAuth()\n    this.authMethod = method\n  }\n\n  /**\n   * Initiate the WAB-based flow, e.g. sending an SMS code or starting an ID check,\n   * using the chosen AuthMethodInteractor.\n   */\n  public async startAuth (payload: AuthPayload): Promise<void> {\n    if (this.authMethod == null) {\n      throw new Error('No AuthMethod selected in WalletAuthenticationManager')\n    }\n    const authMethod = this.authMethod\n    if (this.authenticated) throw new Error('User is already authenticated')\n    this.cancelAuth()\n\n    const presentationKey = this.generateTemporaryPresentationKey()\n    const correlationId = this.telemetry.enabled === true ? this.telemetry.createCorrelationId() : undefined\n    this.authSession = {\n      presentationKey,\n      methodType: authMethod.methodType,\n      expiresAt: Date.now() + this.authSessionTtlMs,\n      ...(correlationId !== undefined ? { correlationId } : {})\n    }\n    this.telemetry.capture({\n      name: 'wallet-toolbox.authentication.wab-start.started',\n      component: 'wallet-toolbox.authentication-manager',\n      severity: 'debug',\n      correlationId,\n      attributes: { methodType: authMethod.methodType }\n    })\n\n    try {\n      const startRes = await this.wabClient.startAuthMethod(\n        authMethod,\n        presentationKey,\n        payload,\n        correlationId\n      )\n\n      const startSucceeded: unknown = startRes.success\n      if (startSucceeded !== true) {\n        const message = startRes.message != null && startRes.message.length > 0\n          ? startRes.message\n          : 'Failed to start WAB auth method'\n        throw new Error(message)\n      }\n      this.telemetry.capture({\n        name: 'wallet-toolbox.authentication.wab-start.completed',\n        component: 'wallet-toolbox.authentication-manager',\n        severity: 'info',\n        correlationId,\n        attributes: { methodType: authMethod.methodType }\n      })\n    } catch (error) {\n      this.cancelAuth()\n      this.telemetry.capture({\n        name: 'wallet-toolbox.authentication.wab-start.failed',\n        component: 'wallet-toolbox.authentication-manager',\n        severity: 'warn',\n        correlationId,\n        attributes: { methodType: authMethod.methodType },\n        error: error instanceof WABClientError\n          ? error\n          : new Error('WAB authentication start failed.')\n      })\n      throw error\n    }\n  }\n\n  /**\n   * Completes the WAB-based flow, retrieving the final presentationKey from WAB if successful.\n   */\n  public async completeAuth (payload: AuthPayload): Promise<void> {\n    if (this.authMethod == null || this.authSession == null) {\n      throw new Error('No AuthMethod selected in WalletAuthenticationManager or startAuth has yet to be called.')\n    }\n    const authMethod = this.authMethod\n    if (this.authSession.methodType !== authMethod.methodType) {\n      this.cancelAuth()\n      throw new Error('The selected authentication method changed. Start authentication again.')\n    }\n    if (Date.now() >= this.authSession.expiresAt) {\n      this.cancelAuth()\n      throw new Error('The WAB authentication session expired. Start authentication again.')\n    }\n\n    const session = this.authSession\n    const result = await this.wabClient.completeAuthMethod(\n      authMethod,\n      session.presentationKey,\n      payload,\n      session.correlationId\n    )\n\n    const authSucceeded: unknown = result.success\n    if (authSucceeded !== true || result.presentationKey == null || result.presentationKey.length === 0) {\n      this.telemetry.capture({\n        name: 'wallet-toolbox.authentication.wab-complete.rejected',\n        component: 'wallet-toolbox.authentication-manager',\n        severity: 'warn',\n        correlationId: session.correlationId,\n        attributes: { methodType: session.methodType }\n      })\n      const message = result.message != null && result.message.length > 0\n        ? result.message\n        : 'Failed to complete WAB auth'\n      throw new Error(message)\n    }\n    if (!/^[0-9a-fA-F]{64}$/.test(result.presentationKey)) {\n      this.cancelAuth()\n      throw new WABAccountContinuityError('WAB returned an invalid presentation key.')\n    }\n\n    this.cancelAuth()\n    const wabAccountStatus = this.inferAccountStatus(result, session.presentationKey)\n    try {\n      await this.providePresentationKey(Utils.toArray(result.presentationKey, 'hex'))\n    } catch (error) {\n      this.telemetry.capture({\n        name: 'wallet-toolbox.authentication.ump-continuity.failed',\n        component: 'wallet-toolbox.authentication-manager',\n        severity: 'warn',\n        correlationId: session.correlationId,\n        attributes: {\n          methodType: session.methodType,\n          wabAccountStatus\n        },\n        error\n      })\n      throw error\n    }\n\n    if (wabAccountStatus === 'existing-user' && this.authenticationFlow !== 'existing-user') {\n      super.destroy()\n      const error = new WABAccountContinuityError()\n      this.telemetry.capture({\n        name: 'wallet-toolbox.authentication.account-continuity.mismatch',\n        component: 'wallet-toolbox.authentication-manager',\n        severity: 'error',\n        correlationId: session.correlationId,\n        attributes: {\n          methodType: session.methodType,\n          wabAccountStatus,\n          umpAccountStatus: 'new-user'\n        },\n        error\n      })\n      throw error\n    }\n\n    const continuity = wabAccountStatus === this.authenticationFlow ? 'matched' : 'ump-existing'\n    this.telemetry.capture({\n      name: 'wallet-toolbox.authentication.completed',\n      component: 'wallet-toolbox.authentication-manager',\n      severity: continuity === 'matched' ? 'info' : 'warn',\n      correlationId: session.correlationId,\n      attributes: {\n        methodType: session.methodType,\n        wabAccountStatus,\n        umpAccountStatus: this.authenticationFlow,\n        continuity\n      }\n    })\n  }\n\n  public cancelAuth (): void {\n    this.authSession = undefined\n  }\n\n  public override destroy (): void {\n    this.cancelAuth()\n    super.destroy()\n  }\n\n  private inferAccountStatus (\n    result: CompleteAuthResponse,\n    temporaryPresentationKey: string\n  ): 'new-user' | 'existing-user' {\n    if (result.presentationKey == null) {\n      throw new WABAccountContinuityError('WAB did not return a presentation key.')\n    }\n    const keyMatchesTemporary = this.constantTimeHexEqual(\n      result.presentationKey,\n      temporaryPresentationKey\n    )\n    const rawAccountStatus: unknown = result.accountStatus\n    if (\n      rawAccountStatus !== undefined &&\n      rawAccountStatus !== 'new-user' &&\n      rawAccountStatus !== 'existing-user'\n    ) {\n      throw new WABAccountContinuityError('WAB returned an invalid account-continuity status.')\n    }\n    const rawExistingUser: unknown = result.existingUser\n    if (rawExistingUser !== undefined && typeof rawExistingUser !== 'boolean') {\n      throw new WABAccountContinuityError('WAB returned an invalid existing-user status.')\n    }\n    if (\n      rawAccountStatus !== undefined &&\n      rawExistingUser !== undefined &&\n      (rawAccountStatus === 'existing-user') !== rawExistingUser\n    ) {\n      throw new WABAccountContinuityError('WAB returned contradictory account-continuity statuses.')\n    }\n    let compatibilityStatus: 'existing-user' | 'new-user' | undefined\n    if (typeof rawExistingUser === 'boolean') {\n      compatibilityStatus = rawExistingUser ? 'existing-user' : 'new-user'\n    }\n    const explicitStatus = rawAccountStatus ?? compatibilityStatus\n\n    if (\n      (explicitStatus === 'new-user' && !keyMatchesTemporary) ||\n      (explicitStatus === 'existing-user' && keyMatchesTemporary)\n    ) {\n      throw new WABAccountContinuityError('WAB returned contradictory account-continuity data.')\n    }\n    return explicitStatus ?? (keyMatchesTemporary ? 'new-user' : 'existing-user')\n  }\n\n  private constantTimeHexEqual (left: string, right: string): boolean {\n    if (left.length !== right.length) return false\n    const normalizedLeft = left.toLowerCase()\n    const normalizedRight = right.toLowerCase()\n    let difference = 0\n    for (let i = 0; i < normalizedLeft.length; i++) {\n      difference |= normalizedLeft.codePointAt(i)! ^ normalizedRight.codePointAt(i)!\n    }\n    return difference === 0\n  }\n\n  private generateTemporaryPresentationKey (): string {\n    // For the 'startAuth' call, we can generate a random 32 bytes → 64 hex chars.\n    const randomBytes = Random(32) // array of length 32\n    return Utils.toHex(randomBytes)\n  }\n}\n","import {\n  WalletInterface,\n  Utils,\n  PushDrop,\n  LockingScript,\n  Transaction,\n  WalletProtocol,\n  Base64String,\n  PubKeyHex,\n  Beef,\n  Validation,\n  WalletEncryptArgs,\n  WalletDecryptArgs,\n  CreateHmacArgs,\n  VerifyHmacArgs,\n  CreateSignatureArgs,\n  VerifySignatureArgs,\n  InternalizeActionArgs,\n  ListOutputsArgs,\n  RelinquishOutputArgs,\n  GetPublicKeyArgs,\n  CreateActionArgs,\n  ListOutputsResult,\n  ListActionsArgs,\n  ListActionsResult,\n  Telemetry,\n  TelemetryConfig\n} from '@bsv/sdk'\n\nimport { parseBrc114ActionTimeLabels } from './utility/brc114ActionTimeLabels'\n\n// Security invariant: only the configured admin originator bypasses permission\n// prompts. Admin-reserved protocols, baskets, and labels are rejected for all\n// other originators; counterparty bypasses require an explicit configuration\n// allowlist.\n\nfunction deepEqual(object1: any, object2: any): boolean {\n  if (object1 === null || object1 === undefined || object2 === null || object2 === undefined) {\n    return object1 === object2\n  }\n  const keys1 = Object.keys(object1)\n  const keys2 = Object.keys(object2)\n\n  if (keys1.length !== keys2.length) {\n    return false\n  }\n\n  for (const key of keys1) {\n    const val1 = object1[key]\n    const val2 = object2[key]\n    const areObjects = isObject(val1) && isObject(val2)\n    if ((areObjects && !deepEqual(val1, val2)) || (!areObjects && val1 !== val2)) {\n      return false\n    }\n  }\n\n  return true\n}\n\nfunction isObject(object: any): boolean {\n  return object != null && typeof object === 'object'\n}\n\n/** Line item type for spending authorization requests. */\nexport type LineItemType = 'input' | 'output' | 'fee'\n\n/** Security level for DPACP protocol permissions. */\nexport type SecurityLevel = 0 | 1 | 2\n\n/**\n * A permissions module handles request/response transformation for a specific P-protocol or P-basket scheme under BRC-98/99.\n * Modules are registered in the config mapped by their scheme ID.\n */\nexport interface PermissionsModule {\n  /**\n   * Transforms the request before it's passed to the underlying wallet.\n   * Can check and enforce permissions, throw errors, or modify any arguments as needed prior to invocation.\n   *\n   * @param req - The incoming request with method, args, and originator\n   * @returns Transformed arguments that will be passed to the underlying wallet\n   */\n  onRequest: (req: { method: string; args: object; originator: string }) => Promise<{ args: object }>\n\n  /**\n   * Transforms the response from the underlying wallet before returning to caller.\n   *\n   * @param res - The response from the underlying wallet\n   * @param context - Metadata about the original request (method, originator)\n   * @returns Transformed response to return to the caller\n   */\n  onResponse: (\n    res: any,\n    context: {\n      method: string\n      originator: string\n    }\n  ) => Promise<any>\n}\n\n/**\n * Describes a group of permissions that can be requested together.\n * This structure is based on BRC-73.\n */\nexport interface GroupedPermissions {\n  description?: string\n  spendingAuthorization?: {\n    amount: number\n    description: string\n  }\n  protocolPermissions?: Array<{\n    protocolID: WalletProtocol\n    counterparty?: string\n    description: string\n  }>\n  basketAccess?: Array<{\n    basket: string\n    description: string\n  }>\n  certificateAccess?: Array<{\n    type: string\n    fields: string[]\n    verifierPublicKey: string\n    description: string\n  }>\n}\n\n/**\n * The object passed to the UI when a grouped permission is requested.\n */\nexport interface GroupedPermissionRequest {\n  originator: string\n  requestID: string\n  permissions: GroupedPermissions\n}\n\n/**\n * Signature for functions that handle a grouped permission request event.\n */\nexport type GroupedPermissionEventHandler = (request: GroupedPermissionRequest) => void | Promise<void>\n\nexport interface CounterpartyPermissions {\n  description?: string\n  protocols: Array<{\n    protocolName: string\n    protocolID?: WalletProtocol\n    description?: string\n  }>\n}\n\nexport interface CounterpartyPermissionRequest {\n  originator: string\n  requestID: string\n  counterparty: PubKeyHex\n  counterpartyLabel?: string\n  permissions: CounterpartyPermissions\n}\n\nexport type CounterpartyPermissionEventHandler = (request: CounterpartyPermissionRequest) => void | Promise<void>\n\n/**\n * Describes a single requested permission that the user must either grant or deny.\n *\n * Four categories of permission are supported, each with a unique protocol:\n *  1) protocol - \"DPACP\" (Domain Protocol Access Control Protocol)\n *  2) basket   - \"DBAP\"  (Domain Basket Access Protocol)\n *  3) certificate - \"DCAP\" (Domain Certificate Access Protocol)\n *  4) spending - \"DSAP\"  (Domain Spending Authorization Protocol)\n *\n * This model underpins \"requests\" made to the user for permission, which the user can\n * either grant or deny. The manager can then create on-chain tokens (PushDrop outputs)\n * if permission is granted. Denying requests cause the underlying operation to throw,\n * and no token is created. An \"ephemeral\" grant is also possible, denoting a one-time\n * authorization without an associated persistent on-chain token.\n */\nexport interface PermissionRequest {\n  type: 'protocol' | 'basket' | 'certificate' | 'spending'\n  originator: string // The domain or FQDN of the requesting application\n  displayOriginator?: string // Optional raw/original originator string for UI purposes\n  usageType?: string // The usage context of the request (used for prompt coalescing)\n  privileged?: boolean // For \"protocol\" or \"certificate\" usage, indicating privileged key usage\n  protocolID?: WalletProtocol // For type='protocol': BRC-43 style (securityLevel, protocolName)\n  counterparty?: string // For type='protocol': e.g. target public key or \"self\"/\"anyone\"\n\n  basket?: string // For type='basket': the basket name being requested\n\n  certificate?: {\n    // For type='certificate': details about the cert usage\n    verifier: string\n    certType: string\n    fields: string[]\n  }\n\n  spending?: {\n    // For type='spending': details about the requested spend\n    satoshis: number\n    lineItems?: Array<{\n      type: LineItemType\n      description: string\n      satoshis: number\n    }>\n  }\n\n  reason?: string // Human-readable explanation for requesting permission\n  renewal?: boolean // Whether this request is for renewing an expired token\n  previousToken?: PermissionToken // If renewing an expired permission, reference to the old token\n}\n\n/**\n * Signature for functions that handle a permission request event, e.g. \"Please ask the user to allow basket X\".\n */\nexport type PermissionEventHandler = (request: PermissionRequest & { requestID: string }) => void | Promise<void>\n\n/**\n * Data structure representing an on-chain permission token.\n * It is typically stored as a single unspent PushDrop output in a special \"internal\" admin basket belonging to\n * the user, held in their underlying wallet.\n *\n * It can represent any of the four permission categories by having the relevant fields:\n *  - DPACP: originator, privileged, protocol, securityLevel, counterparty\n *  - DBAP:  originator, basketName\n *  - DCAP:  originator, privileged, verifier, certType, certFields\n *  - DSAP:  originator, authorizedAmount\n */\nexport interface PermissionToken {\n  /** The transaction ID where this token resides. */\n  txid: string\n\n  /** The current transaction encapsulating the token. */\n  tx: number[]\n\n  /** The output index within that transaction. */\n  outputIndex: number\n\n  /** The exact script hex for the locking script. */\n  outputScript: string\n\n  /** The amount of satoshis assigned to the permission output (often 1). */\n  satoshis: number\n\n  /** The originator domain or FQDN that is allowed to use this permission. */\n  originator: string\n\n  /**\n   * The raw, unnormalized originator string captured at the time the permission\n   * token was created. This is preserved so we can continue to recognize legacy\n   * permissions that were stored with different casing or explicit default ports.\n   */\n  rawOriginator?: string\n\n  /** The expiration time for this token in UNIX epoch seconds. (0 or omitted for spending authorizations, which are indefinite) */\n  expiry: number\n\n  /** Whether this token grants privileged usage (for protocol or certificate). */\n  privileged?: boolean\n\n  /** The protocol name, if this is a DPACP token. */\n  protocol?: string\n\n  /** The security level (0,1,2) for DPACP. */\n  securityLevel?: SecurityLevel\n\n  /** The counterparty, for DPACP. */\n  counterparty?: string\n\n  /** The name of a basket, if this is a DBAP token. */\n  basketName?: string\n\n  /** The certificate type, if this is a DCAP token. */\n  certType?: string\n\n  /** The certificate fields that this token covers, if DCAP token. */\n  certFields?: string[]\n\n  /** The \"verifier\" public key string, if DCAP. */\n  verifier?: string\n\n  /** For DSAP, the maximum authorized spending for the month. */\n  authorizedAmount?: number\n}\n\n/**\n * A map from each permission type to a special \"admin basket\" name used for storing\n * the tokens. The tokens themselves are unspent transaction outputs (UTXOs) with a\n * specialized PushDrop script that references the originator, expiry, etc.\n */\nconst BASKET_MAP = {\n  protocol: 'admin protocol-permission',\n  basket: 'admin basket-access',\n  certificate: 'admin certificate-access',\n  spending: 'admin spending-authorization'\n}\n\n/**\n * The set of callbacks that external code can bind to, e.g. to display UI prompts or logs\n * when a permission is requested.\n */\nexport interface WalletPermissionsManagerCallbacks {\n  onProtocolPermissionRequested?: PermissionEventHandler[]\n  onBasketAccessRequested?: PermissionEventHandler[]\n  onCertificateAccessRequested?: PermissionEventHandler[]\n  onSpendingAuthorizationRequested?: PermissionEventHandler[]\n  onGroupedPermissionRequested?: GroupedPermissionEventHandler[]\n  onCounterpartyPermissionRequested?: CounterpartyPermissionEventHandler[]\n}\n\n/**\n * Configuration object for the WalletPermissionsManager. If a given option is `false`,\n * the manager will skip or alter certain permission checks or behaviors.\n *\n * By default, all of these are `true` unless specified otherwise. This is the most secure configuration.\n */\nexport interface PermissionsManagerConfig {\n  /**\n   * Optional provider-neutral permission timing. Originators, permission-token\n   * contents, manifests, descriptions, labels, and transaction data are never\n   * emitted by the generic instrumentation.\n   */\n  telemetry?: TelemetryConfig\n\n  /**\n   * A map of P-basket/protocol permission scheme modules.\n   *\n   * Keys are scheme IDs (e.g., \"btms\"), values are PermissionsModule instances.\n   *\n   * Each module handles basket/protocol names of the form: `p <schemeID> <rest...>`\n   *\n   * The WalletPermissionManager detects P-prefix baskets/protocols and delegates\n   * request/response transformation to the corresponding module.\n   *\n   * If no module exists for a given schemeID, the wallet will reject access.\n   */\n  permissionModules?: Record<string, PermissionsModule>\n\n  /**\n   * For `createSignature` and `verifySignature`,\n   * require a \"protocol usage\" permission check?\n   */\n  seekProtocolPermissionsForSigning?: boolean\n\n  /**\n   * For methods that perform encryption (encrypt/decrypt), require\n   * a \"protocol usage\" permission check?\n   */\n  seekProtocolPermissionsForEncrypting?: boolean\n\n  /**\n   * For methods that perform HMAC creation or verification (createHmac, verifyHmac),\n   * require a \"protocol usage\" permission check?\n   */\n  seekProtocolPermissionsForHMAC?: boolean\n\n  /**\n   * For revealing counterparty-level or specific key linkage revelation information,\n   * should we require permission?\n   */\n  seekPermissionsForKeyLinkageRevelation?: boolean\n\n  /**\n   * For revealing any user public key (getPublicKey) **other** than the identity key,\n   * should we require permission?\n   */\n  seekPermissionsForPublicKeyRevelation?: boolean\n\n  /**\n   * If getPublicKey is requested with `identityKey=true`, do we require permission?\n   */\n  seekPermissionsForIdentityKeyRevelation?: boolean\n\n  /**\n   * If discoverByIdentityKey / discoverByAttributes are called, do we require permission\n   * for \"identity resolution\" usage?\n   */\n  seekPermissionsForIdentityResolution?: boolean\n\n  /**\n   * When we do internalizeAction with `basket insertion`, or include outputs in baskets\n   * with `createAction, do we ask for basket permission?\n   */\n  seekBasketInsertionPermissions?: boolean\n\n  /**\n   * When relinquishOutput is called, do we ask for basket permission?\n   */\n  seekBasketRemovalPermissions?: boolean\n\n  /**\n   * When listOutputs is called, do we ask for basket permission?\n   */\n  seekBasketListingPermissions?: boolean\n\n  /**\n   * When createAction is called with labels, do we ask for \"label usage\" permission?\n   */\n  seekPermissionWhenApplyingActionLabels?: boolean\n\n  /**\n   * When listActions is called with labels, do we ask for \"label usage\" permission?\n   */\n  seekPermissionWhenListingActionsByLabel?: boolean\n\n  /**\n   * If proving a certificate (proveCertificate) or revealing certificate fields,\n   * do we require a \"certificate access\" permission?\n   */\n  seekCertificateDisclosurePermissions?: boolean\n\n  /**\n   * If acquiring a certificate (acquireCertificate), do we require a permission check?\n   */\n  seekCertificateAcquisitionPermissions?: boolean\n\n  /**\n   * If relinquishing a certificate (relinquishCertificate), do we require a permission check?\n   */\n  seekCertificateRelinquishmentPermissions?: boolean\n\n  /**\n   * If listing a user's certificates (listCertificates), do we require a permission check?\n   */\n  seekCertificateListingPermissions?: boolean\n\n  /**\n   * Should transaction descriptions, input descriptions, and output descriptions be encrypted\n   * when before they are passed to the underlying wallet, and transparently decrypted when retrieved?\n   */\n  encryptWalletMetadata?: boolean\n\n  /**\n   * If the originator tries to spend wallet funds (netSpent > 0 in createAction),\n   * do we seek spending authorization?\n   */\n  seekSpendingPermissions?: boolean\n\n  /**\n   * If true, triggers a grouped permission request flow based on the originator's `manifest.json`.\n   */\n  seekGroupedPermission?: boolean\n\n  /**\n   * If false, permissions are checked without regard for whether we are in\n   * privileged mode. Privileged status is ignored with respect to whether\n   * permissions are granted. Internally, they are always sought and checked\n   * with privileged=false, regardless of the actual value.\n   */\n  differentiatePrivilegedOperations?: boolean\n\n  /**\n   * An allowlist mapping counterparty identity public keys (hex)\n   * to protocol names that are automatically permitted\n   * without prompting the user.\n   */\n  whitelistedCounterparties?: { [counterparty: PubKeyHex]: string[] }\n}\n\n/**\n * @class WalletPermissionsManager\n *\n * Wraps an underlying BRC-100 `Wallet` implementation with permissions management capabilities.\n * The manager intercepts calls from external applications (identified by originators), checks if the request is allowed,\n * and if not, orchestrates user permission flows. It creates or renews on-chain tokens in special\n * admin baskets to track these authorizations. Finally, it proxies the actual call to the underlying wallet.\n *\n * ### Key Responsibilities:\n *  - **Permission Checking**: Before standard wallet operations (e.g. `encrypt`),\n *    the manager checks if a valid permission token exists. If not, it attempts to request permission from the user.\n *  - **On-Chain Tokens**: When permission is granted, the manager stores it as an unspent \"PushDrop\" output.\n *    This can be spent later to revoke or renew the permission.\n *  - **Callbacks**: The manager triggers user-defined callbacks on permission requests (to show a UI prompt),\n *    on grants/denials, and on internal processes.\n *\n * ### Implementation Notes:\n *  - The manager follows the BRC-100 `createAction` + `signAction` pattern for building or spending these tokens.\n *  - Token revocation or renewal uses standard BRC-100 flows: we build a transaction that consumes\n *    the old token UTXO and outputs a new one (or none, if fully revoked).\n */\nexport class WalletPermissionsManager implements WalletInterface {\n  /** A reference to the BRC-100 wallet instance. */\n  private readonly underlying: WalletInterface\n\n  /** The \"admin\" domain or FQDN that is implicitly allowed to do everything. */\n  private readonly adminOriginator: string\n\n  /**\n   * Event callbacks that external code can subscribe to, e.g. to show a UI prompt\n   * or log events. Each event can have multiple handlers.\n   */\n  private readonly callbacks: WalletPermissionsManagerCallbacks = {\n    onProtocolPermissionRequested: [],\n    onBasketAccessRequested: [],\n    onCertificateAccessRequested: [],\n    onSpendingAuthorizationRequested: [],\n    onGroupedPermissionRequested: [],\n    onCounterpartyPermissionRequested: []\n  }\n\n  /**\n   * We queue parallel requests for the same resource so that only one\n   * user prompt is created for a single resource. If multiple calls come\n   * in at once for the same \"protocol:domain:privileged:counterparty\" etc.,\n   * they get merged.\n   *\n   * The key is a string derived from the operation; the value is an object with a reference to the\n   * associated request and an array of pending promise resolve/reject pairs, one for each active\n   * operation that's waiting on the particular resource described by the key.\n   */\n  private readonly activeRequests: Map<\n    string,\n    {\n      request:\n        | PermissionRequest\n        | { originator: string; permissions: GroupedPermissions; displayOriginator?: string }\n        | {\n            originator: string\n            counterparty: PubKeyHex\n            permissions: CounterpartyPermissions\n            displayOriginator?: string\n            counterpartyLabel?: string\n          }\n      pending: Array<{\n        resolve: (val: any) => void\n        reject: (err: any) => void\n      }>\n    }\n  > = new Map()\n\n  /** Cache recently confirmed permissions to avoid repeated lookups. */\n  private readonly permissionCache: Map<string, { expiry: number; cachedAt: number }> = new Map()\n  private readonly recentGrants: Map<string, number> = new Map()\n\n  /**\n   * Token mints currently being written on-chain, keyed by permission cache\n   * key. A granted permission is only cached once its token finishes minting\n   * (network seconds); ensures arriving in that window await the in-flight\n   * mint instead of re-prompting the user for a permission they just granted.\n   * Stored promises never reject.\n   */\n  private readonly mintsInFlight: Map<string, Promise<void>> = new Map()\n\n  private readonly manifestCache: Map<\n    string,\n    {\n      groupPermissions: GroupedPermissions | null\n      counterpartyPermissions: CounterpartyPermissions | null\n      fetchedAt: number\n    }\n  > = new Map()\n\n  private readonly manifestFetchInProgress: Map<\n    string,\n    Promise<{ groupPermissions: GroupedPermissions | null; counterpartyPermissions: CounterpartyPermissions | null }>\n  > = new Map()\n\n  private static readonly MANIFEST_CACHE_TTL_MS = 5 * 60 * 1000\n\n  private readonly groupedPermissionFlowTail: Map<string, Promise<void>> = new Map()\n\n  private readonly pactEstablishedCache: Map<string, number> = new Map()\n\n  /**\n   * Parsed BEEF bundles keyed by the raw BEEF array of a `listOutputs`\n   * result, so token scans parse each bundle once instead of once per output.\n   * `null` records a bundle that failed to parse. WeakMap-keyed so entries\n   * are released with their results.\n   */\n  private readonly parsedBeefCache = new WeakMap<number[] | Uint8Array, Beef | null>()\n\n  /** Counts token-field decrypts so long scans can periodically yield. */\n  private tokenFieldDecryptCount = 0\n\n  /** How long a cached permission remains valid (5 minutes). */\n  private static readonly CACHE_TTL_MS = 5 * 60 * 1000\n  /** Window during which freshly granted permissions are auto-allowed (except spending). */\n  private static readonly RECENT_GRANT_COVER_MS = 15 * 1000\n\n  /** Default ports used when normalizing originator values. */\n  private static readonly DEFAULT_PORTS: Record<string, string> = {\n    'http:': '80',\n    'https:': '443'\n  }\n\n  /**\n   * Configuration that determines whether to skip or apply various checks and encryption.\n   */\n  private readonly config: PermissionsManagerConfig\n  private readonly telemetry: Telemetry\n\n  /**\n   * Constructs a new Permissions Manager instance.\n   *\n   * @param underlyingWallet           The underlying BRC-100 wallet, where requests are forwarded after permission is granted\n   * @param adminOriginator            The domain or FQDN that is automatically allowed everything\n   * @param config                     A set of boolean flags controlling how strictly permissions are enforced\n   */\n  constructor(underlyingWallet: WalletInterface, adminOriginator: string, config: PermissionsManagerConfig = {}) {\n    this.underlying = underlyingWallet\n    this.adminOriginator = this.normalizeOriginator(adminOriginator) || adminOriginator\n    this.telemetry = new Telemetry(config.telemetry)\n\n    // Default all config options to true unless specified\n    this.config = {\n      seekProtocolPermissionsForSigning: true,\n      seekProtocolPermissionsForEncrypting: true,\n      seekProtocolPermissionsForHMAC: true,\n      seekPermissionsForKeyLinkageRevelation: true,\n      seekPermissionsForPublicKeyRevelation: true,\n      seekPermissionsForIdentityKeyRevelation: true,\n      seekPermissionsForIdentityResolution: true,\n      seekBasketInsertionPermissions: true,\n      seekBasketRemovalPermissions: true,\n      seekBasketListingPermissions: true,\n      seekPermissionWhenApplyingActionLabels: true,\n      seekPermissionWhenListingActionsByLabel: true,\n      seekCertificateDisclosurePermissions: true,\n      seekCertificateAcquisitionPermissions: true,\n      seekCertificateRelinquishmentPermissions: true,\n      seekCertificateListingPermissions: true,\n      encryptWalletMetadata: true,\n      seekSpendingPermissions: true,\n      seekGroupedPermission: true,\n      differentiatePrivilegedOperations: true,\n      whitelistedCounterparties: {},\n      ...config // override with user-specified config\n    }\n  }\n\n  /* ---------------------------------------------------------------------\n   *  HELPER METHODS FOR P-MODULE DELEGATION\n   * --------------------------------------------------------------------- */\n\n  /**\n   * Delegates a wallet method call to a P-module if the basket or protocol name uses a P-scheme.\n   * Handles the full request/response transformation flow.\n   *\n   * @param basketOrProtocolName - The basket or protocol name to check for p-module delegation\n   * @param method - The wallet method name being called\n   * @param args - The original args passed to the method\n   * @param originator - The originator of the request\n   * @param underlyingCall - Callback that executes the underlying wallet method with transformed args\n   * @returns The transformed response, or null if not a P-basket/protocol (caller should continue normal flow)\n   */\n  private async delegateToPModuleIfNeeded<T>(\n    basketOrProtocolName: string,\n    method: string,\n    args: object,\n    originator: string,\n    underlyingCall: (transformedArgs: object, originator: string) => Promise<T>\n  ): Promise<T | null> {\n    // Check if this is a P-protocol/basket\n    if (!basketOrProtocolName.startsWith('p ')) {\n      return null // If not, caller should continue normal flow\n    }\n\n    const schemeID = basketOrProtocolName.split(' ')[1]\n    const module = this.config.permissionModules?.[schemeID]\n\n    if (module == null) {\n      throw new Error(`Unsupported P-module scheme: p ${schemeID}`)\n    }\n\n    // Transform request with module\n    const transformedReq = await module.onRequest({\n      method,\n      args,\n      originator\n    })\n\n    // Call underlying method with transformed request\n    const results = await underlyingCall(transformedReq.args, originator)\n\n    // Transform response with module\n    return await module.onResponse(results, {\n      method,\n      originator\n    })\n  }\n\n  /**\n   * Adds a permission module for the given schemeID if needed, throwing if unsupported.\n   */\n  private addPModuleByScheme(\n    schemeID: string,\n    kind: 'label' | 'basket',\n    pModulesByScheme: Map<string, PermissionsModule>\n  ): void {\n    if (pModulesByScheme.has(schemeID)) return\n    const module = this.config.permissionModules?.[schemeID]\n    if (module == null) {\n      throw new Error(`Unsupported P-${kind} scheme: p ${schemeID}`)\n    }\n    pModulesByScheme.set(schemeID, module)\n  }\n\n  /**\n   * Splits labels into P and non-P lists, registering any P-modules encountered.\n   *\n   * P-labels follow BRC-111 format: `p <moduleId> <payload>`\n   * - Must start with \"p \" (lowercase p + space)\n   * - Module ID must be at least 1 character with no spaces\n   * - Single space separates module ID from payload\n   * - Payload must be at least 1 character\n   *\n   * @example Valid: \"p btms token123\", \"p invoicing invoice 2026-02-02\"\n   * @example Invalid: \"p btms\" (no payload), \"p btms \" (empty payload), \"p  data\" (empty moduleId)\n   *\n   * @param labels - Array of label strings to process\n   * @param pModulesByScheme - Map to populate with discovered p-modules\n   * @returns Array of non-P labels for normal permission checks\n   * @throws Error if p-label format is invalid or module is unsupported\n   */\n  private splitLabelsByPermissionModule(\n    labels: string[] | undefined,\n    pModulesByScheme: Map<string, PermissionsModule>\n  ): string[] {\n    const nonPLabels: string[] = []\n    if (labels == null) return nonPLabels\n\n    for (const label of labels) {\n      if (label.startsWith('p ')) {\n        // Remove \"p \" prefix to get \"moduleId payload\"\n        const remainder = label.slice(2)\n\n        // Find the space that separates moduleId from payload\n        const separatorIndex = remainder.indexOf(' ')\n\n        // Validate: must have a space (separatorIndex > 0) and payload after it\n        // separatorIndex <= 0 means no space found or moduleId is empty\n        // separatorIndex === remainder.length - 1 means space is last char (no payload)\n        if (separatorIndex <= 0 || separatorIndex === remainder.length - 1) {\n          throw new Error(`Invalid P-label format: ${label}`)\n        }\n\n        // Reject double spaces after moduleId (payload can't start with space)\n        if (remainder[separatorIndex + 1] === ' ') {\n          throw new Error(`Invalid P-label format: ${label}`)\n        }\n\n        // Extract moduleId (substring before first space)\n        const schemeID = remainder.slice(0, separatorIndex)\n\n        // Register the module (throws if unsupported)\n        this.addPModuleByScheme(schemeID, 'label', pModulesByScheme)\n      } else {\n        // Regular label - add to list for normal permission checks\n        nonPLabels.push(label)\n      }\n    }\n\n    return nonPLabels\n  }\n\n  /**\n   * Decrypts custom instructions in listOutputs results if encryption is configured.\n   */\n  private async decryptListOutputsMetadata(results: ListOutputsResult): Promise<ListOutputsResult> {\n    if (results.outputs) {\n      for (const output of results.outputs) {\n        if (output.customInstructions) {\n          output.customInstructions = await this.maybeDecryptMetadata(output.customInstructions)\n        }\n      }\n    }\n    return results\n  }\n\n  /**\n   * Decrypts metadata in listActions results if encryption is configured.\n   */\n  private async decryptListActionsMetadata(results: ListActionsResult): Promise<ListActionsResult> {\n    if (results.actions) {\n      for (const action of results.actions) {\n        await this.decryptSingleActionMetadata(action)\n      }\n    }\n    return results\n  }\n\n  private async decryptSingleActionMetadata(action: ListActionsResult['actions'][number]): Promise<void> {\n    if (action.description) {\n      action.description = await this.maybeDecryptMetadata(action.description)\n    }\n    if (action.inputs != null) {\n      for (const input of action.inputs) {\n        if (input.inputDescription) {\n          input.inputDescription = await this.maybeDecryptMetadata(input.inputDescription)\n        }\n      }\n    }\n    if (action.outputs != null) {\n      for (const output of action.outputs) {\n        await this.decryptActionOutputMetadata(output)\n      }\n    }\n  }\n\n  private async decryptActionOutputMetadata(\n    output: NonNullable<ListActionsResult['actions'][number]['outputs']>[number]\n  ): Promise<void> {\n    if (output.outputDescription) {\n      output.outputDescription = await this.maybeDecryptMetadata(output.outputDescription)\n    }\n    if (output.customInstructions) {\n      output.customInstructions = await this.maybeDecryptMetadata(output.customInstructions)\n    }\n  }\n\n  /* ---------------------------------------------------------------------\n   *  1) PUBLIC API FOR REGISTERING CALLBACKS (UI PROMPTS, LOGGING, ETC.)\n   * --------------------------------------------------------------------- */\n\n  /**\n   * Binds a callback function to a named event, such as `onProtocolPermissionRequested`.\n   *\n   * @param eventName The name of the event to listen to\n   * @param handler   A function that handles the event\n   * @returns         A numeric ID you can use to unbind later\n   */\n  public bindCallback(\n    eventName: keyof WalletPermissionsManagerCallbacks,\n    handler: PermissionEventHandler | GroupedPermissionEventHandler | CounterpartyPermissionEventHandler\n  ): number {\n    const arr = this.callbacks[eventName]! as any[]\n    arr.push(handler)\n    return arr.length - 1\n  }\n\n  /**\n   * Unbinds a previously registered callback by either its numeric ID (returned by `bindCallback`)\n   * or by exact function reference.\n   *\n   * @param eventName  The event name, e.g. \"onProtocolPermissionRequested\"\n   * @param reference  Either the numeric ID or the function reference\n   * @returns          True if successfully unbound, false otherwise\n   */\n  public unbindCallback(eventName: keyof WalletPermissionsManagerCallbacks, reference: number | Function): boolean {\n    if (this.callbacks[eventName] == null) return false\n    const arr = this.callbacks[eventName] as any[]\n    if (typeof reference === 'number') {\n      if (arr[reference]) {\n        arr[reference] = null\n        return true\n      }\n      return false\n    } else {\n      const index = arr.indexOf(reference)\n      if (index !== -1) {\n        arr[index] = null\n        return true\n      }\n      return false\n    }\n  }\n\n  /**\n   * Internally triggers a named event, calling all subscribed listeners.\n   * Each callback is awaited in turn (though errors are swallowed so that\n   * one failing callback doesn't prevent the others).\n   *\n   * @param eventName The event name\n   * @param param     The parameter object passed to all listeners\n   */\n  private async callEvent(eventName: keyof WalletPermissionsManagerCallbacks, param: any): Promise<void> {\n    const arr = this.callbacks[eventName] || []\n    for (const [callbackIndex, cb] of arr.entries()) {\n      if (typeof cb === 'function') {\n        try {\n          if (this.telemetry.enabled && typeof param === 'object' && param != null) {\n            await this.telemetry.withSpan(\n              'wallet.permission.callback',\n              {\n                component: 'wallet-permissions',\n                carrier: param,\n                attributes: {\n                  'permission.callback': eventName,\n                  'permission.callback_index': callbackIndex\n                }\n              },\n              async () => await cb(param)\n            )\n          } else {\n            await cb(param)\n          }\n        } catch {\n          // Intentionally swallow errors from user-provided callbacks to prevent\n          // a misbehaving callback from disrupting the event dispatch loop.\n        }\n      }\n    }\n  }\n\n  /* ---------------------------------------------------------------------\n   *  2) PERMISSION (GRANT / DENY) METHODS\n   * --------------------------------------------------------------------- */\n\n  /**\n   * Grants a previously requested permission.\n   * This method:\n   *  1) Resolves all pending promise calls waiting on this request\n   *  2) Optionally creates or renews an on-chain PushDrop token (unless `ephemeral===true`)\n   *\n   * @param params      requestID to identify which request is granted, plus optional expiry\n   *                    or `ephemeral` usage, etc.\n   */\n  public async grantPermission(params: {\n    requestID: string\n    expiry?: number\n    ephemeral?: boolean\n    amount?: number\n  }): Promise<void> {\n    // 1) Identify the matching queued requests in `activeRequests`\n    const matching = this.activeRequests.get(params.requestID)\n    if (matching == null) {\n      throw new Error('Request ID not found.')\n    }\n\n    // 2) Mark all matching requests as resolved, deleting the entry\n    for (const x of matching.pending) {\n      x.resolve(true)\n    }\n    this.activeRequests.delete(params.requestID)\n\n    // 3) If `ephemeral !== true`, we create or renew an on-chain token\n    // Only cache non-ephemeral permissions\n    // Ephemeral permissions should not be cached as they are one-time authorizations\n    if (!params.ephemeral) {\n      const request = matching.request as PermissionRequest\n      const expiry = params.expiry || 0 // default: never expires\n      const key = this.buildRequestKey(request)\n\n      // Several first-contact prompts for the same permission can stack up\n      // before any token exists (e.g. one per usage type). Granting them all\n      // should yield ONE token: if an identical non-renewal grant just minted\n      // (or is minting), don't mint a duplicate. Spending authorizations are\n      // excluded — their tokens carry amounts, so every grant is honored.\n      let skipDuplicateMint =\n        !request.renewal &&\n        request.type !== 'spending' &&\n        (this.isPermissionCached(key) || this.isRecentlyGranted(key) || this.mintsInFlight.has(key))\n\n      if (skipDuplicateMint) {\n        const inFlight = this.mintsInFlight.get(key)\n        if (inFlight != null) {\n          await inFlight\n          // The awaited mint may have failed; only skip if it landed.\n          skipDuplicateMint = this.isPermissionCached(key) || this.isRecentlyGranted(key)\n        }\n      }\n\n      if (!skipDuplicateMint) {\n        const mint = request.renewal\n          ? this.renewPermissionOnChain(request.previousToken!, request, expiry, params.amount)\n          : this.createPermissionOnChain(request, expiry, params.amount)\n        // Publish the in-flight mint so concurrent ensures for the same\n        // permission wait for it instead of re-prompting (stored promise\n        // never rejects; failures still propagate to this caller below).\n        this.mintsInFlight.set(\n          key,\n          mint.then(\n            () => {},\n            () => {}\n          )\n        )\n        try {\n          await mint\n        } finally {\n          this.mintsInFlight.delete(key)\n        }\n      }\n\n      this.cachePermission(key, expiry)\n      this.markRecentGrant(request)\n    }\n  }\n\n  /**\n   * Denies a previously requested permission.\n   * This method rejects all pending promise calls waiting on that request\n   *\n   * @param requestID    requestID identifying which request to deny\n   */\n  public async denyPermission(requestID: string): Promise<void> {\n    // 1) Identify the matching requests\n    const matching = this.activeRequests.get(requestID)\n    if (matching == null) {\n      throw new Error('Request ID not found.')\n    }\n\n    // 2) Reject all matching requests, deleting the entry\n    // Denials carry the canonical machine-readable code so applications can\n    // distinguish user denial from other failures (matches denyActiveRequest).\n    const err: Error & { code?: string } = new Error('Permission denied.')\n    err.code = 'ERR_PERMISSION_DENIED'\n    for (const x of matching.pending) {\n      x.reject(err)\n    }\n    this.activeRequests.delete(requestID)\n  }\n\n  /**\n   * Grants a previously requested grouped permission.\n   * @param params.requestID The ID of the request being granted.\n   * @param params.granted A subset of the originally requested permissions that the user has granted.\n   * @param params.expiry An optional expiry time (in seconds) for the new permission tokens.\n   */\n  public async grantGroupedPermission(params: {\n    requestID: string\n    granted: Partial<GroupedPermissions>\n    expiry?: number\n  }): Promise<void> {\n    const matching = this.activeRequests.get(params.requestID)\n    if (matching == null) {\n      throw new Error('Request ID not found.')\n    }\n\n    try {\n      const originalRequest = matching.request as {\n        originator: string\n        permissions: GroupedPermissions\n        displayOriginator?: string\n      }\n      const { originator, permissions: requestedPermissions, displayOriginator } = originalRequest\n      const originLookupValues = this.buildOriginatorLookupValues(displayOriginator, originator)\n\n      this.validateGrantedPermissionsSubset(params.granted, requestedPermissions)\n\n      const expiry = params.expiry || 0 // default: never expires\n\n      const toCreate: Array<{ request: PermissionRequest; expiry: number; amount?: number }> = []\n      const toRenew: Array<{ oldToken: PermissionToken; request: PermissionRequest; expiry: number; amount?: number }> =\n        []\n\n      if (params.granted.spendingAuthorization != null) {\n        toCreate.push({\n          request: {\n            type: 'spending',\n            originator,\n            spending: { satoshis: params.granted.spendingAuthorization.amount },\n            reason: params.granted.spendingAuthorization.description\n          },\n          expiry: 0,\n          amount: params.granted.spendingAuthorization.amount\n        })\n      }\n\n      const grantedProtocols = params.granted.protocolPermissions || []\n      const protocolTokens = await this.mapWithConcurrency(grantedProtocols, 8, async p => {\n        const counterparty = (p.protocolID?.[0] ?? 0) === 1 ? '' : p.counterparty || 'self'\n        const token = await this.findProtocolToken(\n          originator,\n          false,\n          p.protocolID,\n          counterparty,\n          true,\n          originLookupValues\n        )\n        return { p, token, counterparty }\n      })\n\n      for (const { p, token, counterparty } of protocolTokens) {\n        const request: PermissionRequest = {\n          type: 'protocol',\n          originator,\n          privileged: false,\n          protocolID: p.protocolID,\n          counterparty,\n          reason: p.description\n        }\n        if (token == null) {\n          toCreate.push({ request, expiry })\n        } else {\n          toRenew.push({ oldToken: token, request, expiry })\n        }\n      }\n\n      for (const b of params.granted.basketAccess || []) {\n        toCreate.push({\n          request: { type: 'basket', originator, basket: b.basket, reason: b.description },\n          expiry\n        })\n      }\n\n      for (const c of params.granted.certificateAccess || []) {\n        toCreate.push({\n          request: {\n            type: 'certificate',\n            originator,\n            privileged: false,\n            certificate: {\n              verifier: c.verifierPublicKey,\n              certType: c.type,\n              fields: c.fields\n            },\n            reason: c.description\n          },\n          expiry\n        })\n      }\n\n      // A user-visible grouped grant is atomic from the caller's perspective:\n      // never resolve the waiting wallet call if one of the requested tokens\n      // failed to persist. The best-effort helpers intentionally suppress\n      // singleton failures and are therefore only suitable for maintenance\n      // operations where a partial result is explicitly returned.\n      await this.persistPermissionGrant(toCreate, toRenew)\n      this.settleActiveGrant(params.requestID, matching, 'resolve', true)\n    } catch (error) {\n      this.settleActiveGrant(params.requestID, matching, 'reject', error)\n      throw error\n    }\n  }\n\n  /**\n   * Denies a previously requested grouped permission.\n   * @param requestID The ID of the request being denied.\n   */\n  /**\n   * Validates that every entry in `granted` was part of the original `requested` set.\n   * Throws an error on the first mismatch.\n   */\n  private validateGrantedPermissionsSubset(granted: Partial<GroupedPermissions>, requested: GroupedPermissions): void {\n    if (granted.spendingAuthorization != null && requested.spendingAuthorization == null) {\n      throw new Error('Granted spending authorization was not part of the original request.')\n    }\n    if (granted.protocolPermissions?.some(g => requested.protocolPermissions?.find(r => deepEqual(r, g)) == null)) {\n      throw new Error('Granted protocol permissions are not a subset of the original request.')\n    }\n    if (granted.basketAccess?.some(g => requested.basketAccess?.find(r => deepEqual(r, g)) == null)) {\n      throw new Error('Granted basket access permissions are not a subset of the original request.')\n    }\n    if (granted.certificateAccess?.some(g => requested.certificateAccess?.find(r => deepEqual(r, g)) == null)) {\n      throw new Error('Granted certificate access permissions are not a subset of the original request.')\n    }\n  }\n\n  private denyActiveRequest(requestID: string): void {\n    const matching = this.activeRequests.get(requestID)\n    if (matching == null) {\n      throw new Error('Request ID not found.')\n    }\n    const err = new Error('The user has denied the request for permission.')\n    ;(err as any).code = 'ERR_PERMISSION_DENIED'\n    for (const p of matching.pending) {\n      p.reject(err)\n    }\n    this.activeRequests.delete(requestID)\n  }\n\n  private settleActiveGrant(\n    requestID: string,\n    matching: { pending: Array<{ resolve: (value: any) => void; reject: (error: any) => void }> },\n    method: 'resolve' | 'reject',\n    value: any\n  ): void {\n    for (const pending of matching.pending) pending[method](value)\n    this.activeRequests.delete(requestID)\n  }\n\n  private async persistPermissionGrant(\n    toCreate: Array<{ request: PermissionRequest; expiry: number; amount?: number }>,\n    toRenew: Array<{ oldToken: PermissionToken; request: PermissionRequest; expiry: number; amount?: number }>\n  ): Promise<void> {\n    const created = await this.createPermissionTokensBestEffort(toCreate, true)\n    const renewed = await this.renewPermissionTokensBestEffort(toRenew, true)\n    for (const request of [...created, ...renewed]) this.markRecentGrant(request)\n  }\n\n  public async denyGroupedPermission(requestID: string): Promise<void> {\n    this.denyActiveRequest(requestID)\n  }\n\n  public async dismissGroupedPermission(requestID: string): Promise<void> {\n    const matching = this.activeRequests.get(requestID)\n    if (matching == null) {\n      throw new Error('Request ID not found.')\n    }\n    for (const p of matching.pending) {\n      p.resolve(true)\n    }\n    this.activeRequests.delete(requestID)\n  }\n\n  public async grantCounterpartyPermission(params: {\n    requestID: string\n    granted: Partial<CounterpartyPermissions>\n    expiry?: number\n  }): Promise<void> {\n    const matching = this.activeRequests.get(params.requestID)\n    if (matching == null) {\n      throw new Error('Request ID not found.')\n    }\n\n    const originalRequest = matching.request as {\n      originator: string\n      counterparty: PubKeyHex\n      permissions: CounterpartyPermissions\n      displayOriginator?: string\n      counterpartyLabel?: string\n    }\n    const { originator, counterparty, permissions: requestedPermissions, displayOriginator } = originalRequest\n    const originLookupValues = this.buildOriginatorLookupValues(displayOriginator, originator)\n\n    const getProtoName = (p: any): string | undefined => {\n      if (!p) return undefined\n      if (typeof p.protocolName === 'string') return p.protocolName\n      if (Array.isArray(p.protocolID) && typeof p.protocolID[1] === 'string') return p.protocolID[1]\n      return undefined\n    }\n\n    if (\n      params.granted.protocols?.some(g => {\n        const gName = getProtoName(g)\n        if (!gName) return true\n        return !requestedPermissions.protocols.some(r => r.protocolName === gName)\n      })\n    ) {\n      throw new Error('Granted protocol permissions are not a subset of the original request.')\n    }\n\n    const expiry = params.expiry || 0\n\n    const toCreate: Array<{ request: PermissionRequest; expiry: number; amount?: number }> = []\n    const toRenew: Array<{ oldToken: PermissionToken; request: PermissionRequest; expiry: number; amount?: number }> =\n      []\n\n    const grantedProtocols = params.granted.protocols || []\n    const protocolTokens = await this.mapWithConcurrency(grantedProtocols, 8, async p => {\n      const protocolName = getProtoName(p)\n      if (!protocolName) {\n        throw new Error('Invalid counterparty permission protocol entry: missing protocolName/protocolID.')\n      }\n      const protocolID: WalletProtocol = [2, protocolName]\n      const token = await this.findProtocolToken(originator, false, protocolID, counterparty, true, originLookupValues)\n      return { p, token, protocolID }\n    })\n\n    for (const { p, token, protocolID } of protocolTokens) {\n      const request: PermissionRequest = {\n        type: 'protocol',\n        originator,\n        privileged: false,\n        protocolID,\n        counterparty,\n        reason: p.description\n      }\n      if (token == null) {\n        toCreate.push({ request, expiry })\n      } else {\n        toRenew.push({ oldToken: token, request, expiry })\n      }\n    }\n\n    try {\n      await this.persistPermissionGrant(toCreate, toRenew)\n      this.settleActiveGrant(params.requestID, matching, 'resolve', true)\n    } catch (error) {\n      this.settleActiveGrant(params.requestID, matching, 'reject', error)\n      throw error\n    }\n  }\n\n  public async denyCounterpartyPermission(requestID: string): Promise<void> {\n    this.denyActiveRequest(requestID)\n  }\n\n  /* ---------------------------------------------------------------------\n   *  3) THE \"ENSURE\" METHODS: CHECK IF PERMISSION EXISTS, OTHERWISE PROMPT\n   * --------------------------------------------------------------------- */\n\n  /**\n   * Ensures the originator has protocol usage permission.\n   * If no valid (unexpired) permission token is found, triggers a permission request flow.\n   */\n  public async ensureProtocolPermission({\n    originator,\n    privileged,\n    protocolID,\n    counterparty,\n    reason,\n    seekPermission = true,\n    usageType\n  }: {\n    originator: string\n    privileged: boolean\n    protocolID: WalletProtocol\n    counterparty: string\n    reason?: string\n    seekPermission?: boolean\n    usageType: 'signing' | 'encrypting' | 'hmac' | 'publicKey' | 'identityKey' | 'linkageRevelation' | 'generic'\n  }): Promise<boolean> {\n    const { normalized: normalizedOriginator, lookupValues } = this.prepareOriginator(originator)\n    originator = normalizedOriginator\n    // 1) adminOriginator can do anything\n    if (this.isAdminOriginator(originator)) return true\n\n    // 2) If security level=0, we consider it “open” usage\n    const [level, protoName] = protocolID\n    if (level === 0) return true\n    if (level === 1) counterparty = ''\n\n    // 3) If protocol is admin-reserved, block\n    if (this.isAdminProtocol(protocolID)) {\n      throw new Error(`Protocol “${protoName}” is admin-only.`)\n    }\n\n    // Allow the configured exceptions.\n    if (this.isProtocolUsageTypeExempted(usageType)) return true\n    if (!this.config.differentiatePrivilegedOperations) privileged = false\n    if (!privileged && this.isWhitelistedCounterpartyProtocol(counterparty, protocolID)) return true\n\n    const cacheKey = this.buildRequestKey({ type: 'protocol', originator, privileged, protocolID, counterparty })\n    if (await this.hasRecentOrPendingGrant(cacheKey)) return true\n\n    // 4) Attempt to find a valid token in the internal basket\n    const token = await this.findProtocolToken(\n      originator,\n      privileged,\n      protocolID,\n      counterparty,\n      /* includeExpired= */ true,\n      lookupValues\n    )\n\n    if (token == null) {\n      // No token found => request a new one if allowed\n      if (!seekPermission) throw new Error('No protocol permission token found (seekPermission=false).')\n      return await this.requestPermissionFlow({\n        type: 'protocol',\n        originator,\n        privileged,\n        protocolID,\n        counterparty,\n        usageType,\n        reason,\n        renewal: false\n      })\n    }\n\n    if (this.isTokenExpired(token.expiry)) {\n      // has a token but expired => request renewal if allowed\n      if (!seekPermission) {\n        throw new Error('Protocol permission expired and no further user consent allowed (seekPermission=false).')\n      }\n      return await this.requestPermissionFlow({\n        type: 'protocol',\n        originator,\n        privileged,\n        protocolID,\n        counterparty,\n        usageType,\n        reason,\n        renewal: true,\n        previousToken: token\n      })\n    }\n\n    // valid and unexpired\n    this.cachePermission(cacheKey, token.expiry)\n    return true\n  }\n\n  /**\n   * Ensures the originator has basket usage permission for the specified basket.\n   * If not, triggers a permission request flow.\n   */\n  public async ensureBasketAccess({\n    originator,\n    basket,\n    reason,\n    seekPermission = true,\n    usageType\n  }: {\n    originator: string\n    basket: string\n    reason?: string\n    seekPermission?: boolean\n    usageType: 'insertion' | 'removal' | 'listing'\n  }): Promise<boolean> {\n    const { normalized: normalizedOriginator, lookupValues } = this.prepareOriginator(originator)\n    originator = normalizedOriginator\n    if (this.isAdminOriginator(originator)) return true\n    if (this.isAdminBasket(basket)) throw new Error(`Basket “${basket}” is admin-only.`)\n    if (!this.isBasketUsageRequired(usageType)) return true\n\n    const cacheKey = this.buildRequestKey({ type: 'basket', originator, basket })\n    if (await this.hasRecentOrPendingGrant(cacheKey)) return true\n\n    const token = await this.findBasketToken(originator, basket, true, lookupValues)\n    if (token == null) {\n      if (!seekPermission)\n        throw new Error('No basket permission found, and no user consent allowed (seekPermission=false).')\n      return await this.requestPermissionFlow({ type: 'basket', originator, basket, usageType, reason, renewal: false })\n    }\n\n    if (this.isTokenExpired(token.expiry)) {\n      if (!seekPermission) throw new Error('Basket permission expired (seekPermission=false).')\n      return await this.requestPermissionFlow({\n        type: 'basket',\n        originator,\n        basket,\n        usageType,\n        reason,\n        renewal: true,\n        previousToken: token\n      })\n    }\n\n    this.cachePermission(cacheKey, token.expiry)\n    return true\n  }\n\n  /** Returns false when the basket usageType does NOT need a permission check (config-gated). */\n  private isBasketUsageRequired(usageType: 'insertion' | 'removal' | 'listing'): boolean {\n    if (usageType === 'insertion' && !this.config.seekBasketInsertionPermissions) return false\n    if (usageType === 'removal' && !this.config.seekBasketRemovalPermissions) return false\n    if (usageType === 'listing' && !this.config.seekBasketListingPermissions) return false\n    return true\n  }\n\n  /**\n   * Ensures the originator has a valid certificate permission.\n   * This is relevant when revealing certificate fields in DCAP contexts.\n   */\n  public async ensureCertificateAccess({\n    originator,\n    privileged,\n    verifier,\n    certType,\n    fields,\n    reason,\n    seekPermission = true,\n    usageType\n  }: {\n    originator: string\n    privileged: boolean\n    verifier: string\n    certType: string\n    fields: string[]\n    reason?: string\n    seekPermission?: boolean\n    usageType: 'disclosure'\n  }): Promise<boolean> {\n    const { normalized: normalizedOriginator, lookupValues } = this.prepareOriginator(originator)\n    originator = normalizedOriginator\n    if (this.isAdminOriginator(originator)) return true\n    if (usageType === 'disclosure' && !this.config.seekCertificateDisclosurePermissions) {\n      return true\n    }\n    if (!this.config.differentiatePrivilegedOperations) {\n      privileged = false\n    }\n    const cacheKey = this.buildRequestKey({\n      type: 'certificate',\n      originator,\n      privileged,\n      certificate: { verifier, certType, fields }\n    })\n    if (await this.hasRecentOrPendingGrant(cacheKey)) {\n      return true\n    }\n\n    const token = await this.findCertificateToken(\n      originator,\n      privileged,\n      verifier,\n      certType,\n      fields,\n      /* includeExpired= */ true,\n      lookupValues\n    )\n    if (token == null) {\n      if (!seekPermission) {\n        throw new Error('No certificate permission found (seekPermission=false).')\n      }\n      return await this.requestPermissionFlow({\n        type: 'certificate',\n        originator,\n        privileged,\n        certificate: { verifier, certType, fields },\n        usageType,\n        reason,\n        renewal: false\n      })\n    }\n\n    if (this.isTokenExpired(token.expiry)) {\n      if (!seekPermission) {\n        throw new Error('Certificate permission expired (seekPermission=false).')\n      }\n      return await this.requestPermissionFlow({\n        type: 'certificate',\n        originator,\n        privileged,\n        certificate: { verifier, certType, fields },\n        usageType,\n        reason,\n        renewal: true,\n        previousToken: token\n      })\n    }\n\n    this.cachePermission(cacheKey, token.expiry)\n    return true\n  }\n\n  /**\n   * Ensures the originator has spending authorization (DSAP) for a certain satoshi amount.\n   * If the existing token limit is insufficient, attempts to renew. If no token, attempts to create one.\n   */\n  public async ensureSpendingAuthorization({\n    originator,\n    satoshis,\n    lineItems,\n    reason,\n    seekPermission = true\n  }: {\n    originator: string\n    satoshis: number\n    lineItems?: Array<{\n      type: LineItemType\n      description: string\n      satoshis: number\n    }>\n    reason?: string\n    seekPermission?: boolean\n  }): Promise<boolean> {\n    const { normalized: normalizedOriginator, lookupValues } = this.prepareOriginator(originator)\n    originator = normalizedOriginator\n    if (this.isAdminOriginator(originator)) return true\n    if (!this.config.seekSpendingPermissions) {\n      // We skip spending permission entirely\n      return true\n    }\n    const cacheKey = this.buildRequestKey({ type: 'spending', originator, spending: { satoshis } })\n    // Spending keys are amount-scoped. The recent-grant window this adds sits\n    // inside the pre-existing permissionCache window grantPermission already\n    // wrote for spending, so accounting exposure is unchanged.\n    if (await this.hasRecentOrPendingGrant(cacheKey)) {\n      return true\n    }\n    const token = await this.findSpendingToken(originator, lookupValues)\n    if (token?.authorizedAmount) {\n      // Check how much has been spent so far\n      const spentSoFar = await this.querySpentSince(token)\n      if (spentSoFar + satoshis <= token.authorizedAmount) {\n        this.cachePermission(cacheKey, token.expiry)\n        return true\n      } else {\n        // Renew if possible\n        if (!seekPermission) {\n          throw new Error(\n            `Spending authorization insufficient for ${satoshis}, no user consent (seekPermission=false).`\n          )\n        }\n        return await this.requestPermissionFlow({\n          type: 'spending',\n          originator,\n          spending: { satoshis, lineItems },\n          reason,\n          renewal: true,\n          previousToken: token\n        })\n      }\n    } else {\n      // no token\n      if (!seekPermission) {\n        throw new Error('No spending authorization found, (seekPermission=false).')\n      }\n      return await this.requestPermissionFlow({\n        type: 'spending',\n        originator,\n        spending: { satoshis, lineItems },\n        reason,\n        renewal: false\n      })\n    }\n  }\n\n  /**\n   * Ensures the originator has label usage permission.\n   * If no valid (unexpired) permission token is found, triggers a permission request flow.\n   */\n  public async ensureLabelAccess({\n    originator,\n    label,\n    reason,\n    seekPermission = true,\n    usageType\n  }: {\n    originator: string\n    label: string\n    reason?: string\n    seekPermission?: boolean\n    usageType: 'apply' | 'list'\n  }): Promise<boolean> {\n    const { normalized: normalizedOriginator } = this.prepareOriginator(originator)\n    originator = normalizedOriginator\n    // 1) adminOriginator can do anything\n    if (this.isAdminOriginator(originator)) return true\n\n    // 2) If label is admin-reserved, block\n    if (this.isAdminLabel(label)) {\n      throw new Error(`Label “${label}” is admin-only.`)\n    }\n\n    if (usageType === 'apply' && !this.config.seekPermissionWhenApplyingActionLabels) {\n      return true\n    }\n    if (usageType === 'list' && !this.config.seekPermissionWhenListingActionsByLabel) {\n      return true\n    }\n\n    const cacheKey = this.buildRequestKey({\n      type: 'protocol',\n      originator,\n      privileged: false,\n      protocolID: [1, `action label ${label}`],\n      counterparty: 'self'\n    })\n    if (this.isPermissionCached(cacheKey)) {\n      return true\n    }\n\n    // 3) Let ensureProtocolPermission handle the rest.\n    return await this.ensureProtocolPermission({\n      originator,\n      privileged: false,\n      protocolID: [1, `action label ${label}`],\n      counterparty: 'self',\n      reason,\n      seekPermission,\n      usageType: 'generic'\n    })\n  }\n\n  /**\n   * Returns true when the given usageType is configured to skip permission checks.\n   */\n  private isProtocolUsageTypeExempted(\n    usageType: 'signing' | 'encrypting' | 'hmac' | 'publicKey' | 'identityKey' | 'linkageRevelation' | 'generic'\n  ): boolean {\n    if (usageType === 'signing' && !this.config.seekProtocolPermissionsForSigning) return true\n    if (usageType === 'encrypting' && !this.config.seekProtocolPermissionsForEncrypting) return true\n    if (usageType === 'hmac' && !this.config.seekProtocolPermissionsForHMAC) return true\n    if (usageType === 'publicKey' && !this.config.seekPermissionsForPublicKeyRevelation) return true\n    if (usageType === 'identityKey' && !this.config.seekPermissionsForIdentityKeyRevelation) return true\n    if (usageType === 'linkageRevelation' && !this.config.seekPermissionsForKeyLinkageRevelation) return true\n    return false\n  }\n\n  private isProtocolInCounterpartyPermissions(\n    protocolID: WalletProtocol,\n    counterpartyPermissions: CounterpartyPermissions\n  ): boolean {\n    const [, name] = protocolID\n    return counterpartyPermissions.protocols.some(p => p.protocolName === name)\n  }\n\n  private validateCounterpartyPermissions(raw: any): CounterpartyPermissions | null {\n    if (!raw || !Array.isArray(raw.protocols) || raw.protocols.length === 0) return null\n\n    const getCI = (obj: any, key: string): any => {\n      if (!obj || typeof obj !== 'object') return undefined\n      const lower = key.toLowerCase()\n      const found = Object.keys(obj).find(k => k.toLowerCase() === lower)\n      return found ? obj[found] : undefined\n    }\n\n    const parseProtocolId = (v: any): string | null => {\n      if (!Array.isArray(v)) return null\n      if (v[0] !== 2) return null\n      if (typeof v[1] !== 'string') return null\n      return v[1]\n    }\n\n    const validProtocols: CounterpartyPermissions['protocols'] = raw.protocols\n      .map((p: any) => {\n        const protocolName = getCI(p, 'protocolName')\n        if (typeof protocolName === 'string') {\n          return {\n            protocolName,\n            protocolID: [2, protocolName] as WalletProtocol,\n            description: typeof p?.description === 'string' ? p.description : undefined\n          }\n        }\n\n        const protocolIdRaw = getCI(p, 'protocolID') ?? getCI(p, 'protocolId') ?? getCI(p, 'protocolid')\n\n        const parsed = parseProtocolId(protocolIdRaw)\n        if (!parsed) return null\n\n        return {\n          protocolName: parsed,\n          protocolID: [2, parsed] as WalletProtocol,\n          description: typeof p?.description === 'string' ? p.description : undefined\n        }\n      })\n      .filter(Boolean)\n\n    if (validProtocols.length === 0) return null\n\n    return {\n      description: typeof raw.description === 'string' ? raw.description : undefined,\n      protocols: validProtocols\n    }\n  }\n\n  private async fetchManifestPermissions(originator: string): Promise<{\n    groupPermissions: GroupedPermissions | null\n    counterpartyPermissions: CounterpartyPermissions | null\n  }> {\n    const cached = this.manifestCache.get(originator)\n    if (cached != null && Date.now() - cached.fetchedAt < WalletPermissionsManager.MANIFEST_CACHE_TTL_MS) {\n      return {\n        groupPermissions: cached.groupPermissions,\n        counterpartyPermissions: cached.counterpartyPermissions\n      }\n    }\n\n    const inProgress = this.manifestFetchInProgress.get(originator)\n    if (inProgress != null) {\n      return await inProgress\n    }\n\n    const fetchPromise = (async (): Promise<{\n      groupPermissions: GroupedPermissions | null\n      counterpartyPermissions: CounterpartyPermissions | null\n    }> => {\n      try {\n        const proto = originator.startsWith('localhost:') ? 'http' : 'https'\n        const response = await fetch(`${proto}://${originator}/manifest.json`)\n        if (response.ok) {\n          const manifest = await response.json()\n          const namespace = manifest?.metanet || manifest?.babbage\n          const groupPermissions: GroupedPermissions | null = namespace?.groupPermissions || null\n          const counterpartyPermissionsDeclared: CounterpartyPermissions | null = this.validateCounterpartyPermissions(\n            namespace?.counterpartyPermissions\n          )\n          this.manifestCache.set(originator, {\n            groupPermissions,\n            counterpartyPermissions: counterpartyPermissionsDeclared,\n            fetchedAt: Date.now()\n          })\n          return { groupPermissions, counterpartyPermissions: counterpartyPermissionsDeclared }\n        }\n      } catch {\n        // Manifest fetch or parse failed — fall through to return null/null defaults below\n      }\n\n      const result = { groupPermissions: null, counterpartyPermissions: null }\n      this.manifestCache.set(originator, { ...result, fetchedAt: Date.now() })\n      return result\n    })()\n\n    this.manifestFetchInProgress.set(originator, fetchPromise)\n    try {\n      return await fetchPromise\n    } finally {\n      this.manifestFetchInProgress.delete(originator)\n    }\n  }\n\n  private async fetchManifestGroupPermissions(originator: string): Promise<GroupedPermissions | null> {\n    const { groupPermissions } = await this.fetchManifestPermissions(originator)\n    return groupPermissions\n  }\n\n  private async filterAlreadyGrantedPermissions(\n    originator: string,\n    groupPermissions: GroupedPermissions\n  ): Promise<GroupedPermissions> {\n    const permissionsToRequest: GroupedPermissions = {\n      description: groupPermissions.description,\n      protocolPermissions: [],\n      basketAccess: [],\n      certificateAccess: []\n    }\n\n    const [spendingAuthorization, protocolPermissions, basketAccess, certificateAccess] = await Promise.all([\n      (async () => {\n        if (groupPermissions.spendingAuthorization == null) return undefined\n        // A standing authorization is a grant regardless of how much of the\n        // monthly allowance has been used — exhaustion is handled by renewal\n        // at spend time. Checking remaining headroom here re-requests (and,\n        // if approved, re-mints) spending after any monthly usage.\n        const { normalized, lookupValues } = this.prepareOriginator(originator)\n        const token = await this.findSpendingToken(normalized, lookupValues)\n        return token != null ? undefined : groupPermissions.spendingAuthorization\n      })(),\n      (async () => {\n        const protocolChecks = await Promise.all(\n          (groupPermissions.protocolPermissions || []).map(async p => {\n            if (p.counterparty === '') return null\n            const [level] = p.protocolID || [0]\n            if (level === 2 && (p.counterparty === undefined || p.counterparty === null)) {\n              return null\n            }\n            const hasPerm = await this.hasProtocolPermission({\n              originator,\n              privileged: false,\n              protocolID: p.protocolID,\n              counterparty: p.counterparty ?? 'self'\n            })\n            return hasPerm ? null : p\n          })\n        )\n        return protocolChecks.filter(Boolean) as any\n      })(),\n      (async () => {\n        const basketChecks = await Promise.all(\n          (groupPermissions.basketAccess || []).map(async b => {\n            const hasAccess = await this.hasBasketAccess({\n              originator,\n              basket: b.basket\n            })\n            return hasAccess ? null : b\n          })\n        )\n        return basketChecks.filter(Boolean) as any\n      })(),\n      (async () => {\n        const certChecks = await Promise.all(\n          (groupPermissions.certificateAccess || []).map(async c => {\n            const hasAccess = await this.hasCertificateAccess({\n              originator,\n              privileged: false,\n              verifier: c.verifierPublicKey,\n              certType: c.type,\n              fields: c.fields\n            })\n            return hasAccess ? null : c\n          })\n        )\n        return certChecks.filter(Boolean) as any\n      })()\n    ])\n\n    if (spendingAuthorization != null) {\n      permissionsToRequest.spendingAuthorization = spendingAuthorization\n    }\n    permissionsToRequest.protocolPermissions = protocolPermissions\n    permissionsToRequest.basketAccess = basketAccess\n    permissionsToRequest.certificateAccess = certificateAccess\n\n    return permissionsToRequest\n  }\n\n  private hasAnyPermissionsToRequest(permissions: GroupedPermissions): boolean {\n    return !!(\n      permissions.spendingAuthorization ||\n      (permissions.protocolPermissions?.length ?? 0) > 0 ||\n      (permissions.basketAccess?.length ?? 0) > 0 ||\n      (permissions.certificateAccess?.length ?? 0) > 0\n    )\n  }\n\n  private hasGroupedPermissionRequestedHandlers(): boolean {\n    const handlers = this.callbacks.onGroupedPermissionRequested || []\n    return handlers.some(h => typeof h === 'function')\n  }\n\n  private hasCounterpartyPermissionRequestedHandlers(): boolean {\n    const handlers = this.callbacks.onCounterpartyPermissionRequested || []\n    return handlers.some(h => typeof h === 'function')\n  }\n\n  private async hasPactEstablished(originator: string, counterparty: string): Promise<boolean> {\n    if (counterparty === 'self' || counterparty === 'anyone') {\n      return true\n    }\n\n    const cacheKey = `${originator}:${counterparty}`\n    if (this.pactEstablishedCache.has(cacheKey)) {\n      return true\n    }\n\n    const { counterpartyPermissions } = await this.fetchManifestPermissions(originator)\n    if (!counterpartyPermissions?.protocols?.length) {\n      return true\n    }\n\n    const firstProtocol = counterpartyPermissions.protocols[0]\n    const hasToken = await this.hasProtocolPermission({\n      originator,\n      privileged: false,\n      protocolID: [2, firstProtocol.protocolName],\n      counterparty\n    })\n\n    if (hasToken) {\n      this.pactEstablishedCache.set(cacheKey, Date.now())\n      return true\n    }\n\n    return false\n  }\n\n  private markPactEstablished(originator: string, counterparty: string): void {\n    const cacheKey = `${originator}:${counterparty}`\n    this.pactEstablishedCache.set(cacheKey, Date.now())\n  }\n\n  private async maybeRequestPact(currentRequest: PermissionRequest): Promise<boolean | null> {\n    if (!this.config.seekGroupedPermission) {\n      return null\n    }\n    if (!this.hasCounterpartyPermissionRequestedHandlers()) {\n      return null\n    }\n    if (currentRequest.type !== 'protocol') {\n      return null\n    }\n    if (currentRequest.privileged) {\n      return null\n    }\n    const [level] = currentRequest.protocolID!\n    if (level !== 2) {\n      return null\n    }\n\n    const originator = currentRequest.originator\n    const counterparty = currentRequest.counterparty\n    if (!counterparty || counterparty === 'self' || counterparty === 'anyone') {\n      return null\n    }\n    if (!/^[0-9a-fA-F]{66}$/.test(counterparty)) {\n      return null\n    }\n\n    const { counterpartyPermissions } = await this.fetchManifestPermissions(originator)\n    if (!counterpartyPermissions?.protocols?.length) {\n      return null\n    }\n\n    if (!this.isProtocolInCounterpartyPermissions(currentRequest.protocolID!, counterpartyPermissions)) {\n      return null\n    }\n\n    if (await this.hasPactEstablished(originator, counterparty)) {\n      return null\n    }\n\n    const protocolChecks = await Promise.all(\n      counterpartyPermissions.protocols.map(async p => {\n        const hasPerm = await this.hasProtocolPermission({\n          originator,\n          privileged: false,\n          protocolID: [2, p.protocolName],\n          counterparty\n        })\n        return hasPerm ? null : p\n      })\n    )\n    const protocolsToRequest: CounterpartyPermissions['protocols'] = protocolChecks.filter(Boolean) as any\n\n    if (protocolsToRequest.length === 0) {\n      this.markPactEstablished(originator, counterparty)\n      return null\n    }\n\n    const permissionsToRequest: CounterpartyPermissions = {\n      description: counterpartyPermissions.description,\n      protocols: protocolsToRequest\n    }\n\n    const key = `pact:${originator}:${counterparty}`\n    await this.joinOrCreatePactRequest(\n      key,\n      originator,\n      counterparty,\n      permissionsToRequest,\n      currentRequest.displayOriginator\n    )\n\n    this.markPactEstablished(originator, counterparty)\n    const satisfied = await this.hasProtocolPermission({\n      originator,\n      privileged: false,\n      protocolID: currentRequest.protocolID!,\n      counterparty\n    })\n    return satisfied ? true : null\n  }\n\n  private async joinOrCreatePactRequest(\n    key: string,\n    originator: string,\n    counterparty: string,\n    permissionsToRequest: CounterpartyPermissions,\n    displayOriginator?: string\n  ): Promise<void> {\n    const existing = this.activeRequests.get(key)\n    if (existing == null) {\n      const counterpartyPromise = new Promise<boolean>((resolve, reject) => {\n        this.activeRequests.set(key, {\n          request: { originator, counterparty, permissions: permissionsToRequest, displayOriginator },\n          pending: [{ resolve, reject }]\n        })\n      })\n      await this.callEvent('onCounterpartyPermissionRequested', {\n        requestID: key,\n        originator,\n        counterparty,\n        permissions: permissionsToRequest\n      })\n      await counterpartyPromise\n    } else {\n      const existingRequest = existing.request as {\n        originator: string\n        counterparty: PubKeyHex\n        permissions: CounterpartyPermissions\n        displayOriginator?: string\n        counterpartyLabel?: string\n      }\n      for (const p of permissionsToRequest.protocols) {\n        if (!existingRequest.permissions.protocols.some(x => x.protocolName === p.protocolName)) {\n          existingRequest.permissions.protocols.push(p)\n        }\n      }\n      await new Promise<boolean>((resolve, reject) => {\n        existing.pending.push({ resolve, reject })\n      })\n    }\n  }\n\n  private async maybeRequestPeerGroupedLevel2ProtocolPermissions(\n    currentRequest: PermissionRequest\n  ): Promise<boolean | null> {\n    if (!this.config.seekGroupedPermission) {\n      return null\n    }\n    if (!this.hasGroupedPermissionRequestedHandlers()) {\n      return null\n    }\n    if (currentRequest.type !== 'protocol') {\n      return null\n    }\n    const [level] = currentRequest.protocolID!\n    if (level !== 2) {\n      return null\n    }\n\n    const originator = currentRequest.originator\n    const privileged = currentRequest.privileged ?? false\n    const counterparty = currentRequest.counterparty ?? 'self'\n\n    const groupPermissions = await this.fetchManifestGroupPermissions(originator)\n    if (groupPermissions == null) {\n      return null\n    }\n\n    const normalizeManifestCounterparty = (cp: string | undefined): string => {\n      if (cp === '') return ''\n      if (cp === undefined || cp === null) return counterparty\n      return cp\n    }\n\n    const manifestLevel2ForThisPeer = (groupPermissions.protocolPermissions || [])\n      .filter(p => (p.protocolID?.[0] ?? 0) === 2)\n      .map(p => ({\n        protocolID: p.protocolID,\n        counterparty: normalizeManifestCounterparty(p.counterparty),\n        description: p.description\n      }))\n      .filter(p => p.counterparty !== '')\n      .filter(p => p.counterparty === counterparty)\n\n    const isCurrentRequestInManifest = manifestLevel2ForThisPeer.some(p =>\n      deepEqual(p.protocolID, currentRequest.protocolID!)\n    )\n    if (!isCurrentRequestInManifest) {\n      return null\n    }\n\n    const permissionsToRequest: GroupedPermissions = {\n      protocolPermissions: []\n    }\n\n    const protocolChecks = await Promise.all(\n      manifestLevel2ForThisPeer.map(async p => {\n        const hasPerm = await this.hasProtocolPermission({\n          originator,\n          privileged,\n          protocolID: p.protocolID,\n          counterparty: p.counterparty\n        })\n        return hasPerm\n          ? null\n          : {\n              protocolID: p.protocolID,\n              counterparty: p.counterparty,\n              description: p.description\n            }\n      })\n    )\n    permissionsToRequest.protocolPermissions = protocolChecks.filter(Boolean) as any\n\n    if (!this.hasAnyPermissionsToRequest(permissionsToRequest)) {\n      return null\n    }\n\n    const key = `group-peer:${originator}:${privileged}:${counterparty}`\n    await this.joinOrCreateGroupedRequest(key, originator, permissionsToRequest, currentRequest.displayOriginator)\n\n    const satisfied = await this.checkSpecificPermissionAfterGroupFlow(currentRequest)\n    return satisfied ? true : null\n  }\n\n  private async withGroupedPermissionFlowLock<T>(originator: string, fn: () => Promise<T>): Promise<T> {\n    const priorTail = this.groupedPermissionFlowTail.get(originator) || Promise.resolve()\n    const safePriorTail = priorTail.catch(() => {})\n\n    let release: (() => void) | undefined\n    const gate = new Promise<void>(resolve => {\n      release = resolve\n    })\n\n    const currentTail = safePriorTail.then(async () => await gate)\n    this.groupedPermissionFlowTail.set(originator, currentTail)\n\n    await safePriorTail\n    try {\n      return await fn()\n    } finally {\n      release?.()\n      currentTail.finally(() => {\n        if (this.groupedPermissionFlowTail.get(originator) === currentTail) {\n          this.groupedPermissionFlowTail.delete(originator)\n        }\n      })\n    }\n  }\n\n  private async checkSpecificPermissionAfterGroupFlow(request: PermissionRequest): Promise<boolean> {\n    switch (request.type) {\n      case 'protocol':\n        return await this.hasProtocolPermission({\n          originator: request.originator,\n          privileged: request.privileged ?? false,\n          protocolID: request.protocolID!,\n          counterparty: request.counterparty ?? 'self'\n        })\n      case 'basket':\n        return await this.hasBasketAccess({\n          originator: request.originator,\n          basket: request.basket!\n        })\n      case 'certificate':\n        return await this.hasCertificateAccess({\n          originator: request.originator,\n          privileged: request.privileged ?? false,\n          verifier: request.certificate!.verifier,\n          certType: request.certificate!.certType,\n          fields: request.certificate!.fields\n        })\n      case 'spending':\n        return await this.hasSpendingAuthorization({\n          originator: request.originator,\n          satoshis: request.spending!.satoshis\n        })\n      default:\n        return false\n    }\n  }\n\n  private isRequestIncludedInGroupPermissions(\n    request: PermissionRequest,\n    groupPermissions: GroupedPermissions\n  ): boolean {\n    switch (request.type) {\n      case 'protocol': {\n        if (request.privileged) return false\n        const pid = request.protocolID\n        if (pid == null) return false\n        const cp = request.counterparty ?? 'self'\n        return !!groupPermissions.protocolPermissions?.some(p => {\n          if (p.counterparty === '') return false\n          const [level] = p.protocolID || [0]\n          if (level === 2 && (p.counterparty === undefined || p.counterparty === null)) {\n            return false\n          }\n          const manifestCp = level === 1 ? '' : (p.counterparty ?? 'self')\n          return deepEqual(p.protocolID, pid) && manifestCp === cp\n        })\n      }\n      case 'basket': {\n        const basket = request.basket\n        if (!basket) return false\n        return !!groupPermissions.basketAccess?.some(b => b.basket === basket)\n      }\n      case 'certificate': {\n        if (request.privileged) return false\n        const cert = request.certificate\n        if (cert == null) return false\n        return !!groupPermissions.certificateAccess?.some(c => {\n          const fieldsA = new Set(c.fields || [])\n          const fieldsB = new Set(cert.fields || [])\n          if (fieldsA.size !== fieldsB.size) return false\n          for (const f of fieldsA) if (!fieldsB.has(f)) return false\n          return c.type === cert.certType && c.verifierPublicKey === cert.verifier\n        })\n      }\n      case 'spending':\n        return groupPermissions.spendingAuthorization != null\n      default:\n        return false\n    }\n  }\n\n  private async maybeRequestGroupedPermissions(currentRequest: PermissionRequest): Promise<boolean | null> {\n    if (!this.config.seekGroupedPermission) {\n      return null\n    }\n\n    const originator = currentRequest.originator\n\n    const groupPermissions = await this.fetchManifestGroupPermissions(originator)\n    if (groupPermissions == null) {\n      return null\n    }\n\n    if (!this.isRequestIncludedInGroupPermissions(currentRequest, groupPermissions)) {\n      return null\n    }\n\n    const permissionsToRequest = await this.filterAlreadyGrantedPermissions(originator, groupPermissions)\n    if (!this.hasAnyPermissionsToRequest(permissionsToRequest)) {\n      return null\n    }\n\n    const key = `group:${originator}`\n    await this.joinOrCreateGroupedRequest(key, originator, permissionsToRequest, currentRequest.displayOriginator)\n\n    const satisfied = await this.checkSpecificPermissionAfterGroupFlow(currentRequest)\n    return satisfied ? true : null\n  }\n\n  /**\n   * Joins an existing grouped permission request (piggybacks on the existing promise), or creates\n   * a new one and fires the onGroupedPermissionRequested event.\n   */\n  private async joinOrCreateGroupedRequest(\n    key: string,\n    originator: string,\n    permissionsToRequest: GroupedPermissions,\n    displayOriginator?: string\n  ): Promise<void> {\n    const existing = this.activeRequests.get(key)\n    if (existing == null) {\n      const permPromise = new Promise<boolean>((resolve, reject) => {\n        this.activeRequests.set(key, {\n          request: { originator, permissions: permissionsToRequest, displayOriginator },\n          pending: [{ resolve, reject }]\n        })\n      })\n      await this.callEvent('onGroupedPermissionRequested', {\n        requestID: key,\n        originator,\n        permissions: permissionsToRequest\n      })\n      await permPromise\n    } else {\n      const existingRequest = existing.request as {\n        originator: string\n        permissions: GroupedPermissions\n        displayOriginator?: string\n      }\n      existingRequest.permissions.protocolPermissions ??= []\n      for (const p of permissionsToRequest.protocolPermissions || []) {\n        if (!existingRequest.permissions.protocolPermissions.some(x => deepEqual(x, p))) {\n          existingRequest.permissions.protocolPermissions.push(p)\n        }\n      }\n      await new Promise<boolean>((resolve, reject) => {\n        existing.pending.push({ resolve, reject })\n      })\n    }\n  }\n\n  /**\n   * A central method that triggers the permission request flow.\n   * - It checks if there's already an active request for the same key\n   * - If so, we wait on that existing request rather than creating a duplicative one\n   * - Otherwise we create a new request queue, call the relevant \"onXXXRequested\" event,\n   *   and return a promise that resolves once permission is granted or rejects if denied.\n   */\n  private async requestPermissionFlow(r: PermissionRequest): Promise<boolean> {\n    if (!this.telemetry.enabled) return await this.requestPermissionFlowCore(r)\n    return await this.telemetry.withSpan(\n      'wallet.permission.request',\n      {\n        component: 'wallet-permissions',\n        carrier: r,\n        attributes: {\n          'permission.type': r.type,\n          'permission.renewal': r.renewal === true\n        }\n      },\n      async span => {\n        const result = await this.requestPermissionFlowCore(r, span.context)\n        span.end({\n          attributes: {\n            'permission.granted': result\n          }\n        })\n        return result\n      }\n    )\n  }\n\n  private async requestPermissionFlowCore(\n    r: PermissionRequest,\n    context?: { traceId: string; spanId: string; traceFlags?: number }\n  ): Promise<boolean> {\n    if (context != null) this.telemetry.bindContext(r, context)\n    const normalizedOriginator = this.normalizeOriginator(r.originator) || r.originator\n    const preparedRequest: PermissionRequest = {\n      ...r,\n      originator: normalizedOriginator,\n      displayOriginator: r.displayOriginator ?? r.previousToken?.rawOriginator ?? r.originator\n    }\n    if (context != null) this.telemetry.bindContext(preparedRequest, context)\n\n    if (preparedRequest.type === 'protocol' && preparedRequest.protocolID?.[0] === 1) {\n      preparedRequest.counterparty = ''\n    }\n\n    const key = this.buildActiveRequestKey(preparedRequest)\n\n    // If there's already a queue for the same resource, we piggyback on it\n    if (this.isPiggybacking(key)) {\n      return await this.piggybackOnExistingQueue(key)\n    }\n\n    const pactResult = await this.maybeRequestPact(preparedRequest)\n    if (pactResult !== null) return pactResult\n\n    const peerGroupResult = await this.maybeRequestPeerGroupedLevel2ProtocolPermissions(preparedRequest)\n    if (peerGroupResult !== null) return peerGroupResult\n\n    const groupResult = await this.resolveGroupedFlow(preparedRequest, key)\n    if (groupResult !== null) return groupResult\n\n    // Re-check after grouped flow — another waiter may have set up a queue\n    if (this.isPiggybacking(key)) return await this.piggybackOnExistingQueue(key)\n\n    return await this.enqueueAndFireEvent(preparedRequest, key)\n  }\n\n  /** Returns true when an active-request queue already has pending waiters for this key. */\n  private isPiggybacking(key: string): boolean {\n    const q = this.activeRequests.get(key)\n    return q != null && q.pending.length > 0\n  }\n\n  /** Appends to an existing request queue and waits for resolution. */\n  private async piggybackOnExistingQueue(key: string): Promise<boolean> {\n    const q = this.activeRequests.get(key)!\n    return await new Promise<boolean>((resolve, reject) => {\n      q.pending.push({ resolve, reject })\n    })\n  }\n\n  /** Runs the grouped-permission flow (with or without a lock) and checks post-group satisfaction. */\n  private async resolveGroupedFlow(preparedRequest: PermissionRequest, _key: string): Promise<boolean | null> {\n    const hadPendingGroupedFlowBefore =\n      this.config.seekGroupedPermission && this.groupedPermissionFlowTail.has(preparedRequest.originator)\n\n    let groupResult: boolean | null\n    if (this.config.seekGroupedPermission) {\n      groupResult = await this.withGroupedPermissionFlowLock(preparedRequest.originator, async () => {\n        return await this.maybeRequestGroupedPermissions(preparedRequest)\n      })\n    } else {\n      groupResult = await this.maybeRequestGroupedPermissions(preparedRequest)\n    }\n\n    if (groupResult !== null) return groupResult\n\n    if (hadPendingGroupedFlowBefore) {\n      const satisfiedAfterGroup = await this.checkSpecificPermissionAfterGroupFlow(preparedRequest)\n      if (satisfiedAfterGroup) return true\n    }\n\n    return null\n  }\n\n  /** Creates a new active-request queue entry, fires the event, and returns the promise. */\n  private async enqueueAndFireEvent(preparedRequest: PermissionRequest, key: string): Promise<boolean> {\n    const requestPromise = new Promise<boolean>((resolve, reject) => {\n      this.activeRequests.set(key, { request: preparedRequest, pending: [{ resolve, reject }] })\n    })\n\n    try {\n      await this.firePermissionRequestEvent(preparedRequest, key)\n    } catch (e) {\n      const matching = this.activeRequests.get(key)\n      if (matching != null) {\n        for (const p of matching.pending) p.reject(e)\n        this.activeRequests.delete(key)\n      }\n    }\n\n    return await requestPromise\n  }\n\n  /** Fires the appropriate onXXXRequested event based on the request type. */\n  private async firePermissionRequestEvent(request: PermissionRequest, key: string): Promise<void> {\n    switch (request.type) {\n      case 'protocol':\n        await this.callPermissionEvent(request, 'onProtocolPermissionRequested', {\n          ...request,\n          counterparty: request.protocolID?.[0] === 1 ? undefined : request.counterparty,\n          requestID: key\n        })\n        break\n      case 'basket':\n        await this.callPermissionEvent(request, 'onBasketAccessRequested', { ...request, requestID: key })\n        break\n      case 'certificate':\n        await this.callPermissionEvent(request, 'onCertificateAccessRequested', { ...request, requestID: key })\n        break\n      case 'spending':\n        await this.callPermissionEvent(request, 'onSpendingAuthorizationRequested', { ...request, requestID: key })\n        break\n    }\n  }\n\n  private async callPermissionEvent(\n    request: PermissionRequest,\n    eventName: keyof WalletPermissionsManagerCallbacks,\n    param: object\n  ): Promise<void> {\n    this.telemetry.linkContext(request, param)\n    await this.callEvent(eventName, param)\n  }\n\n  /* ---------------------------------------------------------------------\n   *  4) SEARCH / DECODE / DECRYPT ON-CHAIN TOKENS (PushDrop Scripts)\n   * --------------------------------------------------------------------- */\n\n  /**\n   * We will use a administrative \"permission token encryption\" protocol to store fields\n   * in each permission's PushDrop script. This ensures that only the user's wallet\n   * can decrypt them. In practice, this data is not super sensitive, but we still\n   * follow the principle of least exposure.\n   */\n  private static readonly PERM_TOKEN_ENCRYPTION_PROTOCOL: [2, 'admin permission token encryption'] = [\n    2,\n    'admin permission token encryption'\n  ]\n\n  /**\n   * Similarly, we will use a \"metadata encryption\" protocol to preserve the confidentiality\n   * of transaction descriptions and input/output descriptions from lower storage layers.\n   */\n  private static readonly METADATA_ENCRYPTION_PROTOCOL: [2, 'admin metadata encryption'] = [\n    2,\n    'admin metadata encryption'\n  ]\n\n  /** We always use `keyID=\"1\"` and `counterparty=\"self\"` for these encryption ops. */\n  private async encryptPermissionTokenField(plaintext: string | number[]): Promise<number[]> {\n    const data = typeof plaintext === 'string' ? Utils.toArray(plaintext, 'utf8') : plaintext\n    const { ciphertext } = await this.underlying.encrypt(\n      {\n        plaintext: data,\n        protocolID: WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n        keyID: '1'\n      },\n      this.adminOriginator\n    )\n    return ciphertext\n  }\n\n  /**\n   * Extracts a transaction from a `listOutputs` result's BEEF bundle, parsing\n   * the bundle only once per result. Calling\n   * `Transaction.fromBEEF(result.BEEF, txid)` per output re-parses the entire\n   * bundle every time — O(n²) in the number of outputs — which can block the\n   * caller's thread (in browser wallets, the UI) for seconds on large\n   * permission baskets.\n   */\n  private transactionFromResultBeef(result: { BEEF?: number[] | Uint8Array }, txid: string): Transaction {\n    const beef = result.BEEF\n    if (beef != null) {\n      let parsed = this.parsedBeefCache.get(beef)\n      if (parsed === undefined) {\n        try {\n          parsed = Beef.fromBinary(beef)\n        } catch {\n          parsed = null\n        }\n        this.parsedBeefCache.set(beef, parsed)\n      }\n      // findAtomicTransaction (not findTxid().tx) matches fromBEEF exactly:\n      // it attaches merkle paths and sourceTransaction ancestry, which token\n      // consumers rely on when re-serializing via tx.toBEEF().\n      const tx = parsed?.findAtomicTransaction(txid)\n      if (tx != null) return tx\n    }\n    // Preserve the original behavior (including throwing) for bundles the\n    // fast path can't serve.\n    return Transaction.fromBEEF(beef ?? [], txid)\n  }\n\n  private async decryptPermissionTokenField(ciphertext: number[]): Promise<number[]> {\n    // Field decrypts run in tight loops over every token in a basket; yield a\n    // macrotask periodically so large scans don't starve the caller's event\n    // loop (in browser wallets, that means blocking rendering and input).\n    if (++this.tokenFieldDecryptCount % 8 === 0) {\n      await new Promise(resolve => setTimeout(resolve, 0))\n    }\n    try {\n      const { plaintext } = await this.underlying.decrypt(\n        {\n          ciphertext,\n          protocolID: WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n          keyID: '1'\n        },\n        this.adminOriginator\n      )\n      return plaintext\n    } catch {\n      // Decryption failed (e.g. wrong key, unencrypted legacy value) — return the raw bytes unchanged\n      return ciphertext\n    }\n  }\n\n  /**\n   * Encrypts wallet metadata if configured to do so, otherwise returns the original plaintext for storage.\n   * @param plaintext The metadata to encrypt if configured to do so\n   * @returns The encrypted metadata, or the original value if encryption was disabled.\n   */\n  private async maybeEncryptMetadata(plaintext: string): Promise<Base64String> {\n    if (!this.config.encryptWalletMetadata) {\n      return plaintext\n    }\n    const { ciphertext } = await this.underlying.encrypt(\n      {\n        plaintext: Utils.toArray(plaintext, 'utf8'),\n        protocolID: WalletPermissionsManager.METADATA_ENCRYPTION_PROTOCOL,\n        keyID: '1'\n      },\n      this.adminOriginator\n    )\n    return Utils.toBase64(ciphertext)\n  }\n\n  /**\n   * Attempts to decrypt metadata. if decryption fails, assumes the value is already plaintext and returns it.\n   * @param ciphertext The metadata to attempt decryption for.\n   * @returns The decrypted metadata. If decryption fails, returns the original value instead.\n   */\n  private async maybeDecryptMetadata(ciphertext: Base64String): Promise<string> {\n    try {\n      const { plaintext } = await this.underlying.decrypt(\n        {\n          ciphertext: Utils.toArray(ciphertext, 'base64'),\n          protocolID: WalletPermissionsManager.METADATA_ENCRYPTION_PROTOCOL,\n          keyID: '1'\n        },\n        this.adminOriginator\n      )\n      return Utils.toUTF8(plaintext)\n    } catch {\n      // Decryption failed (e.g. wrong key, unencrypted legacy value) — return original string unchanged\n      return ciphertext\n    }\n  }\n\n  /** Helper to see if a token's expiry is in the past. */\n  private isTokenExpired(expiry: number): boolean {\n    const now = Math.floor(Date.now() / 1000)\n    return expiry > 0 && expiry < now\n  }\n\n  /** Decrypts the standard 6 fields from a protocol (DPACP) PushDrop script. */\n  private async decryptProtocolTokenFields(fields: number[][]): Promise<{\n    domainDecoded: string\n    expiryDecoded: number\n    privDecoded: boolean\n    secLevelDecoded: 0 | 1 | 2\n    protoNameDecoded: string\n    cptyDecoded: string\n  }> {\n    const domainDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(fields[0]))\n    const expiryDecoded = Number.parseInt(Utils.toUTF8(await this.decryptPermissionTokenField(fields[1])), 10)\n    const privDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(fields[2])) === 'true'\n    const secLevelDecoded = Number.parseInt(Utils.toUTF8(await this.decryptPermissionTokenField(fields[3])), 10) as\n      0 | 1 | 2\n    const protoNameDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(fields[4]))\n    const cptyDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(fields[5]))\n    return { domainDecoded, expiryDecoded, privDecoded, secLevelDecoded, protoNameDecoded, cptyDecoded }\n  }\n\n  private protocolTokenTags(\n    originator: string,\n    privileged: boolean,\n    securityLevel: SecurityLevel,\n    protocolName: string,\n    counterparty: string\n  ): string[] {\n    const tags = [\n      `originator ${originator}`,\n      `privileged ${!!privileged}`,\n      `protocolName ${protocolName}`,\n      `protocolSecurityLevel ${securityLevel}`\n    ]\n    if (securityLevel === 2) tags.push(`counterparty ${counterparty}`)\n    return tags\n  }\n\n  private async parseProtocolTokenOutput(\n    result: ListOutputsResult,\n    output: ListOutputsResult['outputs'][number],\n    expected: {\n      originator: string\n      privileged: boolean\n      securityLevel: SecurityLevel\n      protocolName: string\n      counterparty: string\n    }\n  ): Promise<PermissionToken | undefined> {\n    const [txid, outputIndex] = this.parseOutpoint(output.outpoint)\n    const tx = this.transactionFromResultBeef(result, txid)\n    const decoded = PushDrop.decode(tx.outputs[outputIndex].lockingScript)\n    if (decoded?.fields == null || decoded.fields.length < 6) return undefined\n    const fields = await this.decryptProtocolTokenFields(decoded.fields)\n    if (this.normalizeOriginator(fields.domainDecoded) !== expected.originator) return undefined\n    const matches =\n      fields.privDecoded === !!expected.privileged &&\n      fields.secLevelDecoded === expected.securityLevel &&\n      fields.protoNameDecoded === expected.protocolName &&\n      (fields.secLevelDecoded !== 2 || fields.cptyDecoded === expected.counterparty)\n    if (!matches) return undefined\n    return {\n      tx: tx.toBEEF(),\n      txid,\n      outputIndex,\n      outputScript: tx.outputs[outputIndex].lockingScript.toHex(),\n      satoshis: output.satoshis,\n      originator: expected.originator,\n      rawOriginator: fields.domainDecoded,\n      privileged: expected.privileged,\n      protocol: expected.protocolName,\n      securityLevel: expected.securityLevel,\n      expiry: fields.expiryDecoded,\n      counterparty: fields.cptyDecoded\n    }\n  }\n\n  private async parseBasketTokenOutput(\n    result: ListOutputsResult,\n    output: ListOutputsResult['outputs'][number],\n    originator: string,\n    basket: string\n  ): Promise<PermissionToken | undefined> {\n    const [txid, outputIndex] = this.parseOutpoint(output.outpoint)\n    const tx = this.transactionFromResultBeef(result, txid)\n    const decoded = PushDrop.decode(tx.outputs[outputIndex].lockingScript)\n    if (decoded?.fields == null || decoded.fields.length < 3) return undefined\n    const domainDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(decoded.fields[0]))\n    if (this.normalizeOriginator(domainDecoded) !== originator) return undefined\n    const expiryDecoded = Number.parseInt(Utils.toUTF8(await this.decryptPermissionTokenField(decoded.fields[1])), 10)\n    const basketDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(decoded.fields[2]))\n    if (basketDecoded !== basket) return undefined\n    return {\n      tx: tx.toBEEF(),\n      txid,\n      outputIndex,\n      outputScript: tx.outputs[outputIndex].lockingScript.toHex(),\n      satoshis: output.satoshis,\n      originator,\n      rawOriginator: domainDecoded,\n      basketName: basketDecoded,\n      expiry: expiryDecoded\n    }\n  }\n\n  private async parseCertificateTokenOutput(\n    result: ListOutputsResult,\n    output: ListOutputsResult['outputs'][number],\n    expected: {\n      originator: string\n      privileged: boolean\n      verifier: string\n      certType: string\n      fields: string[]\n    }\n  ): Promise<PermissionToken | undefined> {\n    const [txid, outputIndex] = this.parseOutpoint(output.outpoint)\n    const tx = this.transactionFromResultBeef(result, txid)\n    const decoded = PushDrop.decode(tx.outputs[outputIndex].lockingScript)\n    if (decoded?.fields == null || decoded.fields.length < 6) return undefined\n    const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = decoded.fields\n    const domainDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw))\n    if (this.normalizeOriginator(domainDecoded) !== expected.originator) return undefined\n    const expiryDecoded = Number.parseInt(Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10)\n    const privileged = Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true'\n    const certType = Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw))\n    const verifier = Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw))\n    const allFields = JSON.parse(Utils.toUTF8(await this.decryptPermissionTokenField(fieldsRaw))) as string[]\n    const metadataMatches =\n      privileged === !!expected.privileged && certType === expected.certType && verifier === expected.verifier\n    if (!metadataMatches) return undefined\n    const availableFields = new Set(allFields)\n    if (expected.fields.some(field => !availableFields.has(field))) return undefined\n    return {\n      tx: tx.toBEEF(),\n      txid,\n      outputIndex,\n      outputScript: tx.outputs[outputIndex].lockingScript.toHex(),\n      satoshis: output.satoshis,\n      originator: expected.originator,\n      rawOriginator: domainDecoded,\n      privileged: expected.privileged,\n      verifier,\n      certType,\n      certFields: allFields,\n      expiry: expiryDecoded\n    }\n  }\n\n  /** Parses outpoint string \"txid.vout\" into [txid, outputIndex]. */\n  private parseOutpoint(outpoint: string): [string, number] {\n    const [txid, indexStr] = outpoint.split('.')\n    return [txid, Number.parseInt(indexStr, 10)]\n  }\n\n  /** Normalizes a txid string to lowercase. */\n  private normalizeTxid(txid?: string): string {\n    return (txid ?? '').toLowerCase()\n  }\n\n  /** Reverses a 32-byte hex txid (for endian normalization). */\n  private reverseHexTxid(txid: string): string {\n    const hex = this.normalizeTxid(txid)\n    if (!/^[0-9a-f]{64}$/.test(hex)) return hex\n    const bytes = hex.match(/../g)\n    return bytes != null ? bytes.reverse().join('') : hex\n  }\n\n  /**\n   * Returns true when an outpoint string (e.g. \"txid.vout\" or \"txid:vout\") refers to `token`.\n   */\n  private tokenMatchesOutpointString(outpoint: string, token: PermissionToken): boolean {\n    const dot = outpoint.lastIndexOf('.')\n    const colon = outpoint.lastIndexOf(':')\n    const sep = Math.max(dot, colon)\n    if (sep === -1) return false\n    const txidPart = outpoint.slice(0, sep)\n    const vout = Number(outpoint.slice(sep + 1))\n    if (!Number.isFinite(vout)) return false\n    return this.normalizeTxid(txidPart) === this.normalizeTxid(token.txid) && vout === token.outputIndex\n  }\n\n  /**\n   * Finds the index of the tx input that spends the given permission token.\n   * Handles multiple potential field names for TXID and vout.\n   */\n  private findInputIndexForToken(tx: Transaction, token: PermissionToken): number {\n    return (tx.inputs as any[]).findIndex((input: any) => {\n      const txidCandidate: unknown =\n        input?.sourceTXID ??\n        input?.sourceTxid ??\n        input?.sourceTxId ??\n        input?.prevTxId ??\n        input?.prevTxid ??\n        input?.prevTXID ??\n        input?.txid ??\n        input?.txID\n\n      const voutCandidate: unknown =\n        input?.sourceOutputIndex ?? input?.sourceOutput ?? input?.outputIndex ?? input?.vout ?? input?.prevOutIndex\n\n      if (typeof txidCandidate === 'string' && typeof voutCandidate === 'number') {\n        const cand = this.normalizeTxid(txidCandidate)\n        if (cand === this.normalizeTxid(token.txid) && voutCandidate === token.outputIndex) return true\n        if (cand === this.reverseHexTxid(token.txid) && voutCandidate === token.outputIndex) return true\n      }\n\n      const outpointCandidate: unknown = input?.outpoint ?? input?.sourceOutpoint ?? input?.prevOutpoint\n      return typeof outpointCandidate === 'string' && this.tokenMatchesOutpointString(outpointCandidate, token)\n    })\n  }\n\n  /** Looks for a DPACP permission token matching origin/domain, privileged, protocol, cpty. */\n  private async findProtocolToken(\n    originator: string,\n    privileged: boolean,\n    protocolID: WalletProtocol,\n    counterparty: string,\n    includeExpired: boolean,\n    originatorLookupValues?: string[]\n  ): Promise<PermissionToken | undefined> {\n    const [secLevel, protoName] = protocolID\n    const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator]\n\n    for (const originTag of originsToTry) {\n      const result = await this.underlying.listOutputs(\n        {\n          basket: BASKET_MAP.protocol,\n          tags: this.protocolTokenTags(originTag, privileged, secLevel, protoName, counterparty),\n          tagQueryMode: 'all',\n          include: 'entire transactions'\n        },\n        this.adminOriginator\n      )\n\n      for (const out of result.outputs) {\n        const token = await this.parseProtocolTokenOutput(result, out, {\n          originator,\n          privileged,\n          securityLevel: secLevel,\n          protocolName: protoName,\n          counterparty\n        })\n        if (token == null) continue\n        if (!includeExpired && this.isTokenExpired(token.expiry!)) continue\n        return token\n      }\n    }\n    return undefined\n  }\n\n  /** Finds ALL DPACP permission tokens matching origin/domain, privileged, protocol, cpty. Never filters by expiry. */\n  private async findAllProtocolTokens(\n    originator: string,\n    privileged: boolean,\n    protocolID: WalletProtocol,\n    counterparty: string,\n    originatorLookupValues?: string[]\n  ): Promise<PermissionToken[]> {\n    const [secLevel, protoName] = protocolID\n    const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator]\n    const matches: PermissionToken[] = []\n    const seen = new Set<string>()\n\n    for (const originTag of originsToTry) {\n      const result = await this.underlying.listOutputs(\n        {\n          basket: BASKET_MAP.protocol,\n          tags: this.protocolTokenTags(originTag, privileged, secLevel, protoName, counterparty),\n          tagQueryMode: 'all',\n          include: 'entire transactions'\n        },\n        this.adminOriginator\n      )\n\n      for (const out of result.outputs) {\n        if (seen.has(out.outpoint)) continue\n        const token = await this.parseProtocolTokenOutput(result, out, {\n          originator,\n          privileged,\n          securityLevel: secLevel,\n          protocolName: protoName,\n          counterparty\n        })\n        if (token == null) continue\n        seen.add(out.outpoint)\n        matches.push(token)\n      }\n    }\n\n    return matches\n  }\n\n  /** Looks for a DBAP token matching (originator, basket). */\n  private async findBasketToken(\n    originator: string,\n    basket: string,\n    includeExpired: boolean,\n    originatorLookupValues?: string[]\n  ): Promise<PermissionToken | undefined> {\n    const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator]\n\n    for (const originTag of originsToTry) {\n      const result = await this.underlying.listOutputs(\n        {\n          basket: BASKET_MAP.basket,\n          tags: [`originator ${originTag}`, `basket ${basket}`],\n          tagQueryMode: 'all',\n          include: 'entire transactions'\n        },\n        this.adminOriginator\n      )\n\n      for (const out of result.outputs) {\n        const token = await this.parseBasketTokenOutput(result, out, originator, basket)\n        if (token == null) continue\n        if (!includeExpired && this.isTokenExpired(token.expiry!)) continue\n        return token\n      }\n    }\n    return undefined\n  }\n\n  /** Looks for a DCAP token matching (origin, privileged, verifier, certType, fields subset). */\n  private async findCertificateToken(\n    originator: string,\n    privileged: boolean,\n    verifier: string,\n    certType: string,\n    fields: string[],\n    includeExpired: boolean,\n    originatorLookupValues?: string[]\n  ): Promise<PermissionToken | undefined> {\n    const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator]\n\n    for (const originTag of originsToTry) {\n      const result = await this.underlying.listOutputs(\n        {\n          basket: BASKET_MAP.certificate,\n          tags: [`originator ${originTag}`, `privileged ${!!privileged}`, `type ${certType}`, `verifier ${verifier}`],\n          tagQueryMode: 'all',\n          include: 'entire transactions'\n        },\n        this.adminOriginator\n      )\n\n      for (const out of result.outputs) {\n        const token = await this.parseCertificateTokenOutput(result, out, {\n          originator,\n          privileged,\n          verifier,\n          certType,\n          fields\n        })\n        if (token == null) continue\n        if (!includeExpired && this.isTokenExpired(token.expiry!)) continue\n        return token\n      }\n    }\n    return undefined\n  }\n\n  /** Looks for a DSAP token matching origin, returning the first one found. */\n  private async findSpendingToken(\n    originator: string,\n    originatorLookupValues?: string[]\n  ): Promise<PermissionToken | undefined> {\n    const originsToTry = originatorLookupValues?.length ? originatorLookupValues : [originator]\n\n    for (const originTag of originsToTry) {\n      const result = await this.underlying.listOutputs(\n        {\n          basket: BASKET_MAP.spending,\n          tags: [`originator ${originTag}`],\n          tagQueryMode: 'all',\n          include: 'entire transactions'\n        },\n        this.adminOriginator\n      )\n\n      for (const out of result.outputs) {\n        const [txid, outputIndexStr] = out.outpoint.split('.')\n        const tx = this.transactionFromResultBeef(result, txid)\n        const dec = PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript)\n        if (!dec?.fields || dec.fields.length < 2) continue\n        const domainRaw = dec.fields[0]\n        const amtRaw = dec.fields[1]\n\n        const domainDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw))\n        const normalizedDomain = this.normalizeOriginator(domainDecoded)\n        if (normalizedDomain !== originator) continue\n        const amtDecodedStr = Utils.toUTF8(await this.decryptPermissionTokenField(amtRaw))\n        const authorizedAmount = Number.parseInt(amtDecodedStr, 10)\n\n        return {\n          tx: tx.toBEEF(),\n          txid: out.outpoint.split('.')[0],\n          outputIndex: Number.parseInt(out.outpoint.split('.')[1], 10),\n          outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),\n          satoshis: out.satoshis,\n          originator,\n          rawOriginator: domainDecoded,\n          authorizedAmount,\n          expiry: 0 // Not time-limited, monthly authorization\n        }\n      }\n    }\n    return undefined\n  }\n\n  /**\n   * Returns the current month and year in UTC as a string in the format \"YYYY-MM\".\n   *\n   * @returns {string} The current month and year in UTC.\n   */\n  private getCurrentMonthYearUTC(): string {\n    const now = new Date()\n    const year = now.getUTCFullYear()\n    const month = (now.getUTCMonth() + 1).toString().padStart(2, '0') // Ensure 2-digit month\n    return `${year}-${month}`\n  }\n\n  /**\n   * Returns spending for an originator in the current calendar month.\n   */\n  public async querySpentSince(token: PermissionToken): Promise<number> {\n    const labelOrigins = this.buildOriginatorLookupValues(token.rawOriginator, token.originator)\n    let total = 0\n\n    for (const labelOrigin of labelOrigins) {\n      const { actions } = await this.underlying.listActions(\n        {\n          labels: [`admin originator ${labelOrigin}`, `admin month ${this.getCurrentMonthYearUTC()}`],\n          labelQueryMode: 'all'\n        },\n        this.adminOriginator\n      )\n      total += actions.reduce((a, e) => a - e.satoshis, 0)\n    }\n\n    return total\n  }\n\n  /* ---------------------------------------------------------------------\n   *  5) CREATE / RENEW / REVOKE PERMISSION TOKENS ON CHAIN\n   * --------------------------------------------------------------------- */\n\n  /**\n   * Creates a brand-new permission token as a single-output PushDrop script in the relevant admin basket.\n   *\n   * The main difference between each type of token is in the \"fields\" we store in the PushDrop script.\n   *\n   * @param r        The permission request\n   * @param expiry   The expiry epoch time\n   * @param amount   For DSAP, the authorized spending limit\n   */\n  private async createPermissionOnChain(r: PermissionRequest, expiry: number, amount?: number): Promise<void> {\n    const normalizedOriginator = this.normalizeOriginator(r.originator) || r.originator\n    r.originator = normalizedOriginator\n    const basketName = BASKET_MAP[r.type]\n    if (!basketName) return\n\n    // Build the array of encrypted fields for the PushDrop script\n    const fields: number[][] = await this.buildPushdropFields(r, expiry, amount)\n\n    // Construct the script. We do a simple P2PK check. We ask `PushDrop.lock(...)`\n    // to create a script with a single OP_CHECKSIG verifying ownership to redeem.\n    const script = await new PushDrop(this.underlying).lock(\n      fields,\n      WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n      '1',\n      'self',\n      true,\n      true\n    )\n\n    // Create tags\n    const tags = this.buildTagsForRequest(r)\n\n    // Build a transaction with exactly one output, no explicit inputs since the wallet\n    // can internally fund it from its balance.\n    await this.createAction(\n      {\n        description: `Grant ${r.type} permission`,\n        outputs: [\n          {\n            lockingScript: script.toHex(),\n            satoshis: 1,\n            outputDescription: `${r.type} permission token`,\n            basket: basketName,\n            tags\n          }\n        ],\n        options: {\n          // The application request resumes as soon as this durable grant\n          // returns. Finish broadcasting first so the grant transaction's\n          // funding change is reusable by that request.\n          acceptDelayedBroadcast: false\n        }\n      },\n      this.adminOriginator\n    )\n  }\n\n  private async mapWithConcurrency<T, R>(items: T[], concurrency: number, fn: (item: T) => Promise<R>): Promise<R[]> {\n    if (items.length === 0) return []\n    const results: R[] = Array.from({ length: items.length })\n    let i = 0\n    const worker = async () => {\n      while (true) {\n        const idx = i++\n        if (idx >= items.length) return\n        results[idx] = await fn(items[idx])\n      }\n    }\n    await Promise.all(Array.from({ length: Math.min(concurrency, items.length) }, async () => await worker()))\n    return results\n  }\n\n  private async runBestEffortBatches<T, R>(\n    items: T[],\n    chunkSize: number,\n    runChunk: (chunk: T[]) => Promise<R[]>,\n    strict = false\n  ): Promise<R[]> {\n    if (items.length === 0) return []\n    const out: R[] = []\n    for (let i = 0; i < items.length; i += chunkSize) {\n      const chunk = items.slice(i, i + chunkSize)\n      out.push(...(strict ? await runChunk(chunk) : await this.runBestEffortChunk(chunk, runChunk)))\n    }\n    return out\n  }\n\n  private async runBestEffortChunk<T, R>(chunk: T[], runChunk: (chunk: T[]) => Promise<R[]>): Promise<R[]> {\n    try {\n      return await runChunk(chunk)\n    } catch (e) {\n      if (chunk.length <= 1) {\n        console.error('Permission batch failed:', e)\n        return []\n      }\n      const mid = Math.ceil(chunk.length / 2)\n      const left = await this.runBestEffortChunk(chunk.slice(0, mid), runChunk)\n      const right = await this.runBestEffortChunk(chunk.slice(mid), runChunk)\n      return [...left, ...right]\n    }\n  }\n\n  private async buildPermissionOutput(\n    r: PermissionRequest,\n    expiry: number,\n    amount?: number\n  ): Promise<{\n    output: { lockingScript: string; satoshis: number; outputDescription: string; basket: string; tags: string[] }\n    request: PermissionRequest\n  }> {\n    const normalizedOriginator = this.normalizeOriginator(r.originator) || r.originator\n    r.originator = normalizedOriginator\n    const basketName = BASKET_MAP[r.type]\n    if (!basketName) {\n      throw new Error(`Unsupported permission type: ${r.type}`)\n    }\n    const fields: number[][] = await this.buildPushdropFields(r, expiry, amount)\n    const script = await new PushDrop(this.underlying).lock(\n      fields,\n      WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n      '1',\n      'self',\n      true,\n      true\n    )\n    const tags = this.buildTagsForRequest(r)\n    return {\n      request: r,\n      output: {\n        lockingScript: script.toHex(),\n        satoshis: 1,\n        outputDescription: `${r.type} permission token`,\n        basket: basketName,\n        tags\n      }\n    }\n  }\n\n  private async createPermissionTokensBestEffort(\n    items: Array<{ request: PermissionRequest; expiry: number; amount?: number }>,\n    strict = false\n  ): Promise<PermissionRequest[]> {\n    const CHUNK = 25\n    return await this.runBestEffortBatches(items, CHUNK, async chunk => {\n      const built = await this.mapWithConcurrency(\n        chunk,\n        8,\n        async c => await this.buildPermissionOutput(c.request, c.expiry, c.amount)\n      )\n      // Grouped callers resume immediately after this method returns. Delayed\n      // broadcast can leave the grant transaction's funding inputs reserved\n      // while the resumed request is being planned.\n      await this.createAction(\n        {\n          description: `Grant ${built.length} permissions`,\n          outputs: built.map(b => b.output),\n          options: { acceptDelayedBroadcast: false }\n        },\n        this.adminOriginator\n      )\n      return built.map(b => b.request)\n    }, strict)\n  }\n\n  private async renewPermissionTokensBestEffort(\n    items: Array<{ oldToken: PermissionToken; request: PermissionRequest; expiry: number; amount?: number }>,\n    strict = false\n  ): Promise<PermissionRequest[]> {\n    const CHUNK = 15\n    return await this.runBestEffortBatches(items, CHUNK, async chunk => {\n      const built = await this.mapWithConcurrency(\n        chunk,\n        8,\n        async c => await this.buildPermissionOutput(c.request, c.expiry, c.amount)\n      )\n\n      const inputBeef = new Beef()\n      for (const c of chunk) {\n        inputBeef.mergeBeef(Beef.fromBinary(c.oldToken.tx))\n      }\n\n      const { signableTransaction } = await this.createAction(\n        {\n          description: `Renew ${chunk.length} permissions`,\n          inputBEEF: inputBeef.toBinary(),\n          inputs: chunk.map((c, i) => ({\n            outpoint: `${c.oldToken.txid}.${c.oldToken.outputIndex}`,\n            unlockingScriptLength: 73,\n            inputDescription: `Consume old permission token #${i + 1}`\n          })),\n          outputs: built.map(b => b.output),\n          options: {\n            acceptDelayedBroadcast: true,\n            randomizeOutputs: false,\n            signAndProcess: false\n          }\n        },\n        this.adminOriginator\n      )\n\n      if (!signableTransaction?.reference || !signableTransaction.tx) {\n        throw new Error('Failed to create signable transaction')\n      }\n\n      const partialTx = Transaction.fromAtomicBEEF(signableTransaction.tx)\n      const pushdrop = new PushDrop(this.underlying)\n      const spends: Record<number, { unlockingScript: string }> = {}\n\n      for (let i = 0; i < chunk.length; i++) {\n        const token = chunk[i].oldToken\n        const unlocker = pushdrop.unlock(\n          WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n          '1',\n          'self',\n          'all',\n          false,\n          1,\n          LockingScript.fromHex(token.outputScript)\n        )\n        const unlockingScript = await unlocker.sign(partialTx, i)\n        spends[i] = { unlockingScript: unlockingScript.toHex() }\n      }\n\n      const { txid } = await this.underlying.signAction({\n        reference: signableTransaction.reference,\n        spends\n      })\n      if (!txid) throw new Error('Failed to finalize renewal transaction')\n      return built.map(b => b.request)\n    }, strict)\n  }\n\n  private async coalescePermissionTokens(\n    oldTokens: PermissionToken[],\n    newScript: LockingScript,\n    opts?: {\n      tags?: string[]\n      basket?: string\n      description?: string\n    }\n  ): Promise<string> {\n    if (!oldTokens?.length) throw new Error('No permission tokens to coalesce')\n    if (oldTokens.length < 2) throw new Error('Need at least 2 tokens to coalesce')\n    // 1) Create a signable action with N inputs and a single renewed output\n    // Merge all input token BEEFs into a single BEEF structure\n    const inputBeef = new Beef()\n    for (const token of oldTokens) {\n      inputBeef.mergeBeef(Beef.fromBinary(token.tx))\n    }\n\n    const { signableTransaction } = await this.createAction(\n      {\n        description: opts?.description ?? `Coalesce ${oldTokens.length} permission tokens`,\n        inputBEEF: inputBeef.toBinary(),\n        inputs: oldTokens.map((t, i) => ({\n          outpoint: `${t.txid}.${t.outputIndex}`,\n          unlockingScriptLength: 74,\n          inputDescription: `Consume permission token #${i + 1}`\n        })),\n        outputs: [\n          {\n            lockingScript: newScript.toHex(),\n            satoshis: 1,\n            outputDescription: 'Renewed permission token',\n            ...(opts?.basket ? { basket: opts.basket } : {}),\n            ...(opts?.tags == null ? {} : { tags: opts.tags })\n          }\n        ],\n        options: {\n          acceptDelayedBroadcast: true,\n          randomizeOutputs: false,\n          signAndProcess: false\n        }\n      },\n      this.adminOriginator\n    )\n\n    if (!signableTransaction?.reference || !signableTransaction.tx) {\n      throw new Error('Failed to create signable transaction')\n    }\n\n    // 2) Sign each input - each token needs its own unlocker with the correct locking script\n    const partialTx = Transaction.fromAtomicBEEF(signableTransaction.tx)\n    const pushdrop = new PushDrop(this.underlying)\n\n    const spends: Record<number, { unlockingScript: string }> = {}\n    for (let i = 0; i < oldTokens.length; i++) {\n      const token = oldTokens[i]\n      // Each token requires its own unlocker with the specific locking script\n      const unlocker = pushdrop.unlock(\n        WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n        '1',\n        'self',\n        'all',\n        false,\n        1,\n        LockingScript.fromHex(token.outputScript)\n      )\n      const unlockingScript = await unlocker.sign(partialTx, i)\n      spends[i] = { unlockingScript: unlockingScript.toHex() }\n    }\n\n    // 3) Finalize the action\n    const { txid } = await this.underlying.signAction({\n      reference: signableTransaction.reference,\n      spends\n    })\n    if (!txid) throw new Error('Failed to finalize coalescing transaction')\n    return txid\n  }\n\n  /**\n   * Renews a permission token by spending the old token as input and creating a new token output.\n   * This invalidates the old token and replaces it with a new one.\n   *\n   * @param oldToken The old token to consume\n   * @param r        The permission request being renewed\n   * @param newExpiry The new expiry epoch time\n   * @param newAmount For DSAP, the new authorized amount\n   */\n  private async renewPermissionOnChain(\n    oldToken: PermissionToken,\n    r: PermissionRequest,\n    newExpiry: number,\n    newAmount?: number\n  ): Promise<void> {\n    r.originator = this.normalizeOriginator(r.originator) || r.originator\n    // 1) build new fields\n    const newFields = await this.buildPushdropFields(r, newExpiry, newAmount)\n\n    // 2) new script\n    const newScript = await new PushDrop(this.underlying).lock(\n      newFields,\n      WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n      '1',\n      'self',\n      true,\n      true\n    )\n    const tags = this.buildTagsForRequest(r)\n    // Check if there are multiple old tokens for the same parameters (shouldn't usually happen)\n    const oldTokens = await this.findAllProtocolTokens(\n      oldToken.originator,\n      oldToken.privileged!,\n      [oldToken.securityLevel!, oldToken.protocol!],\n      oldToken.counterparty!,\n      this.buildOriginatorLookupValues(oldToken.rawOriginator, oldToken.originator)\n    )\n\n    // If so, coalesce them into a single token first, to avoid bloat\n    if (oldTokens.length > 1) {\n      await this.coalescePermissionTokens(oldTokens, newScript, {\n        tags,\n        basket: BASKET_MAP[r.type],\n        description: `Coalesce ${r.type} permission tokens`\n      })\n    } else {\n      // Otherwise, just proceed with the single-token renewal\n      // 3) For BRC-100, we do a \"createAction\" with a partial input referencing oldToken\n      //    plus a single new output. We'll hydrate the template, then signAction for the wallet to finalize.\n      const oldOutpoint = `${oldToken.txid}.${oldToken.outputIndex}`\n      const { signableTransaction } = await this.createAction(\n        {\n          description: `Renew ${r.type} permission`,\n          inputBEEF: oldToken.tx,\n          inputs: [\n            {\n              outpoint: oldOutpoint,\n              unlockingScriptLength: 73, // length of signature\n              inputDescription: `Consume old ${r.type} token`\n            }\n          ],\n          outputs: [\n            {\n              lockingScript: newScript.toHex(),\n              satoshis: 1,\n              outputDescription: `Renewed ${r.type} permission token`,\n              basket: BASKET_MAP[r.type],\n              tags\n            }\n          ],\n          options: {\n            acceptDelayedBroadcast: true\n          }\n        },\n        this.adminOriginator\n      )\n      const tx = Transaction.fromBEEF(signableTransaction!.tx)\n      const unlocker = new PushDrop(this.underlying).unlock(\n        WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n        '1',\n        'self',\n        'all',\n        false,\n        1,\n        LockingScript.fromHex(oldToken.outputScript)\n      )\n      const unlockingScript = await unlocker.sign(tx, 0)\n      await this.underlying.signAction({\n        reference: signableTransaction!.reference,\n        spends: {\n          0: {\n            unlockingScript: unlockingScript.toHex()\n          }\n        }\n      })\n    }\n  }\n\n  /**\n   * Builds the encrypted array of fields for a PushDrop permission token\n   * (protocol / basket / certificate / spending).\n   */\n  private async buildPushdropFields(r: PermissionRequest, expiry: number, amount?: number): Promise<number[][]> {\n    switch (r.type) {\n      case 'protocol': {\n        const [secLevel, protoName] = r.protocolID!\n        const counterparty = secLevel === 2 ? (r.counterparty ?? 'self') : ''\n        return [\n          await this.encryptPermissionTokenField(r.originator), // domain\n          await this.encryptPermissionTokenField(String(expiry)), // expiry\n          await this.encryptPermissionTokenField(r.privileged === true ? 'true' : 'false'),\n          await this.encryptPermissionTokenField(String(secLevel)),\n          await this.encryptPermissionTokenField(protoName),\n          await this.encryptPermissionTokenField(counterparty)\n        ]\n      }\n      case 'basket': {\n        return [\n          await this.encryptPermissionTokenField(r.originator),\n          await this.encryptPermissionTokenField(String(expiry)),\n          await this.encryptPermissionTokenField(r.basket!)\n        ]\n      }\n      case 'certificate': {\n        const { certType, fields, verifier } = r.certificate!\n        return [\n          await this.encryptPermissionTokenField(r.originator),\n          await this.encryptPermissionTokenField(String(expiry)),\n          await this.encryptPermissionTokenField(r.privileged ? 'true' : 'false'),\n          await this.encryptPermissionTokenField(certType),\n          await this.encryptPermissionTokenField(JSON.stringify(fields)),\n          await this.encryptPermissionTokenField(verifier)\n        ]\n      }\n      case 'spending': {\n        // DSAP\n        const authAmt = amount ?? (r.spending?.satoshis || 0)\n        return [\n          await this.encryptPermissionTokenField(r.originator),\n          await this.encryptPermissionTokenField(String(authAmt))\n        ]\n      }\n    }\n  }\n\n  /**\n   * Helper to build an array of tags for the new output, matching the user request's\n   * origin, basket, privileged, protocol name, etc.\n   */\n  private buildTagsForRequest(r: PermissionRequest): string[] {\n    const tags: string[] = [`originator ${r.originator}`]\n    switch (r.type) {\n      case 'protocol': {\n        tags.push(\n          `privileged ${!!r.privileged}`,\n          `protocolName ${r.protocolID![1]}`,\n          `protocolSecurityLevel ${r.protocolID![0]}`\n        )\n        if (r.protocolID![0] === 2) {\n          tags.push(`counterparty ${r.counterparty ?? 'self'}`)\n        }\n        break\n      }\n      case 'basket': {\n        tags.push(`basket ${r.basket}`)\n        break\n      }\n      case 'certificate': {\n        tags.push(\n          `privileged ${!!r.privileged}`,\n          `type ${r.certificate!.certType}`,\n          `verifier ${r.certificate!.verifier}`\n        )\n        break\n      }\n      case 'spending': {\n        // Only 'originator' is strictly required as a tag.\n        break\n      }\n    }\n    return tags\n  }\n\n  /* ---------------------------------------------------------------------\n   *  6) PUBLIC \"LIST/HAS/REVOKE\" METHODS\n   * --------------------------------------------------------------------- */\n\n  /**\n   * Lists all protocol permission tokens (DPACP) with optional filters.\n   * @param originator Optional originator domain to filter by\n   * @param privileged Optional boolean to filter by privileged status\n   * @param protocolName Optional protocol name to filter by\n   * @param protocolSecurityLevel Optional protocol security level to filter by\n   * @param counterparty Optional counterparty to filter by\n   * @returns Array of permission tokens that match the filter criteria\n   */\n  public async listProtocolPermissions({\n    originator,\n    privileged,\n    protocolName,\n    protocolSecurityLevel,\n    counterparty\n  }: {\n    originator?: string\n    privileged?: boolean\n    protocolName?: string\n    protocolSecurityLevel?: number\n    counterparty?: string\n  } = {}): Promise<PermissionToken[]> {\n    const baseTags = this.buildProtocolFilterTags({ privileged, protocolName, protocolSecurityLevel, counterparty })\n    const originFilter = originator ? this.prepareOriginator(originator) : undefined\n    const originVariants = originFilter == null ? [undefined] : originFilter.lookupValues\n    const seen = new Set<string>()\n    const tokens: PermissionToken[] = []\n\n    for (const originTag of originVariants) {\n      const tags = originTag != null ? [...baseTags, `originator ${originTag}`] : [...baseTags]\n      const result = await this.underlying.listOutputs(\n        { basket: BASKET_MAP.protocol, tags, tagQueryMode: 'all', include: 'entire transactions', limit: 10000 },\n        this.adminOriginator\n      )\n      await this.collectProtocolTokens(result, originFilter, seen, tokens)\n    }\n    return tokens\n  }\n\n  /** Builds the base tag array for protocol permission listing. */\n  private buildProtocolFilterTags({\n    privileged,\n    protocolName,\n    protocolSecurityLevel,\n    counterparty\n  }: {\n    privileged?: boolean\n    protocolName?: string\n    protocolSecurityLevel?: number\n    counterparty?: string\n  }): string[] {\n    const tags: string[] = []\n    if (privileged !== undefined) tags.push(`privileged ${!!privileged}`)\n    if (protocolName) tags.push(`protocolName ${protocolName}`)\n    if (protocolSecurityLevel !== undefined) tags.push(`protocolSecurityLevel ${protocolSecurityLevel}`)\n    if (counterparty) tags.push(`counterparty ${counterparty}`)\n    return tags\n  }\n\n  /** Decodes and appends protocol permission tokens from a listOutputs result. */\n  private async collectProtocolTokens(\n    result: Awaited<ReturnType<WalletInterface['listOutputs']>>,\n    originFilter: ReturnType<WalletPermissionsManager['prepareOriginator']> | undefined,\n    seen: Set<string>,\n    tokens: PermissionToken[]\n  ): Promise<void> {\n    for (const out of result.outputs) {\n      if (seen.has(out.outpoint)) continue\n      const [txid, outputIndex] = this.parseOutpoint(out.outpoint)\n      const tx = this.transactionFromResultBeef(result, txid)\n      const dec = PushDrop.decode(tx.outputs[outputIndex].lockingScript)\n      if (!dec?.fields || dec.fields.length < 6) continue\n      const f = await this.decryptProtocolTokenFields(dec.fields)\n      const normalizedDomain = this.normalizeOriginator(f.domainDecoded)\n      if (originFilter != null && normalizedDomain !== originFilter.normalized) continue\n      seen.add(out.outpoint)\n      tokens.push({\n        tx: tx.toBEEF(),\n        txid,\n        outputIndex,\n        outputScript: tx.outputs[outputIndex].lockingScript.toHex(),\n        satoshis: out.satoshis,\n        originator: normalizedDomain,\n        rawOriginator: f.domainDecoded,\n        expiry: f.expiryDecoded,\n        privileged: f.privDecoded,\n        securityLevel: f.secLevelDecoded,\n        protocol: f.protoNameDecoded,\n        counterparty: f.cptyDecoded\n      })\n    }\n  }\n\n  /**\n   * Returns true if the originator already holds a valid unexpired protocol permission.\n   * This calls `ensureProtocolPermission` with `seekPermission=false`, so it won't prompt.\n   */\n  public async hasProtocolPermission(params: {\n    originator: string\n    privileged: boolean\n    protocolID: WalletProtocol\n    counterparty: string\n  }): Promise<boolean> {\n    try {\n      await this.ensureProtocolPermission({\n        ...params,\n        reason: 'hasProtocolPermission',\n        seekPermission: false,\n        usageType: 'generic'\n      })\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  /**\n   * Lists basket permission tokens (DBAP) for a given originator or basket (or for all if not specified).\n   * @param params.originator Optional originator to filter by\n   * @param params.basket Optional basket name to filter by\n   * @returns Array of permission tokens that match the filter criteria\n   */\n  public async listBasketAccess(params: { originator?: string; basket?: string } = {}): Promise<PermissionToken[]> {\n    const basketName = BASKET_MAP.basket\n    const baseTags: string[] = []\n\n    if (params.basket) {\n      baseTags.push(`basket ${params.basket}`)\n    }\n\n    const originFilter = params.originator ? this.prepareOriginator(params.originator) : undefined\n    const originVariants = originFilter == null ? [undefined] : originFilter.lookupValues\n    const seen = new Set<string>()\n    const tokens: PermissionToken[] = []\n\n    for (const originTag of originVariants) {\n      const tags = [...baseTags]\n      if (originTag) {\n        tags.push(`originator ${originTag}`)\n      }\n      const result = await this.underlying.listOutputs(\n        {\n          basket: basketName,\n          tags,\n          tagQueryMode: 'all',\n          include: 'entire transactions',\n          limit: 10000\n        },\n        this.adminOriginator\n      )\n      await this.collectBasketTokens(result, originFilter, seen, tokens)\n    }\n    return tokens\n  }\n\n  /** Decodes and appends basket permission tokens from a listOutputs result. */\n  private async collectBasketTokens(\n    result: Awaited<ReturnType<WalletInterface['listOutputs']>>,\n    originFilter: ReturnType<WalletPermissionsManager['prepareOriginator']> | undefined,\n    seen: Set<string>,\n    tokens: PermissionToken[]\n  ): Promise<void> {\n    for (const out of result.outputs) {\n      if (seen.has(out.outpoint)) continue\n      const [txid, outputIndex] = this.parseOutpoint(out.outpoint)\n      const tx = this.transactionFromResultBeef(result, txid)\n      const dec = PushDrop.decode(tx.outputs[outputIndex].lockingScript)\n      if (!dec?.fields || dec.fields.length < 3) continue\n      const [domainRaw, expiryRaw, basketRaw] = dec.fields\n      const domainDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw))\n      const normalizedDomain = this.normalizeOriginator(domainDecoded)\n      if (originFilter != null && normalizedDomain !== originFilter.normalized) continue\n      const expiryDecoded = Number.parseInt(Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10)\n      const basketDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(basketRaw))\n      seen.add(out.outpoint)\n      tokens.push({\n        tx: tx.toBEEF(),\n        txid,\n        outputIndex,\n        satoshis: out.satoshis,\n        outputScript: tx.outputs[outputIndex].lockingScript.toHex(),\n        originator: normalizedDomain,\n        rawOriginator: domainDecoded,\n        basketName: basketDecoded,\n        expiry: expiryDecoded\n      })\n    }\n  }\n\n  /**\n   * Returns `true` if the originator already holds a valid unexpired basket permission for `basket`.\n   */\n  public async hasBasketAccess(params: { originator: string; basket: string }): Promise<boolean> {\n    try {\n      await this.ensureBasketAccess({\n        originator: params.originator,\n        basket: params.basket,\n        seekPermission: false,\n        usageType: 'insertion'\n      })\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  /**\n   * Lists spending authorization tokens (DSAP) for a given originator (or all).\n   */\n  public async listSpendingAuthorizations(params: { originator?: string }): Promise<PermissionToken[]> {\n    const basketName = BASKET_MAP.spending\n    const tags: string[] = []\n    if (params.originator) {\n      tags.push(`originator ${params.originator}`)\n    }\n    const result = await this.underlying.listOutputs(\n      {\n        basket: basketName,\n        tags,\n        tagQueryMode: 'all',\n        include: 'entire transactions',\n        limit: 10000\n      },\n      this.adminOriginator\n    )\n\n    const tokens: PermissionToken[] = []\n    for (const out of result.outputs) {\n      const [txid, outputIndexStr] = out.outpoint.split('.')\n      const tx = this.transactionFromResultBeef(result, txid)\n      const dec = PushDrop.decode(tx.outputs[Number(outputIndexStr)].lockingScript)\n      if (!dec?.fields || dec.fields.length < 2) continue\n      const [domainRaw, amtRaw] = dec.fields\n      const domainDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw))\n      const amtDecodedStr = Utils.toUTF8(await this.decryptPermissionTokenField(amtRaw))\n      const authorizedAmount = Number.parseInt(amtDecodedStr, 10)\n      tokens.push({\n        tx: tx.toBEEF(),\n        txid: out.outpoint.split('.')[0],\n        outputIndex: Number.parseInt(out.outpoint.split('.')[1], 10),\n        satoshis: out.satoshis,\n        outputScript: tx.outputs[Number(outputIndexStr)].lockingScript.toHex(),\n        originator: domainDecoded,\n        authorizedAmount,\n        expiry: 0\n      })\n    }\n    return tokens\n  }\n\n  /**\n   * Returns `true` if the originator already holds a valid spending authorization token\n   * with enough available monthly spend. We do not prompt (seekPermission=false).\n   */\n  public async hasSpendingAuthorization(params: { originator: string; satoshis: number }): Promise<boolean> {\n    try {\n      await this.ensureSpendingAuthorization({\n        originator: params.originator,\n        satoshis: params.satoshis,\n        seekPermission: false\n      })\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  /**\n   * Lists certificate permission tokens (DCAP) with optional filters.\n   * @param originator Optional originator domain to filter by\n   * @param privileged Optional boolean to filter by privileged status\n   * @param certType Optional certificate type to filter by\n   * @param verifier Optional verifier to filter by\n   * @returns Array of permission tokens that match the filter criteria\n   */\n  public async listCertificateAccess(\n    params: {\n      originator?: string\n      privileged?: boolean\n      certType?: Base64String\n      verifier?: PubKeyHex\n    } = {}\n  ): Promise<PermissionToken[]> {\n    const baseTags: string[] = []\n    if (params.privileged !== undefined) baseTags.push(`privileged ${!!params.privileged}`)\n    if (params.certType) baseTags.push(`type ${params.certType}`)\n    if (params.verifier) baseTags.push(`verifier ${params.verifier}`)\n\n    const originFilter = params.originator ? this.prepareOriginator(params.originator) : undefined\n    const originVariants = originFilter == null ? [undefined] : originFilter.lookupValues\n    const seen = new Set<string>()\n    const tokens: PermissionToken[] = []\n\n    for (const originTag of originVariants) {\n      const tags = originTag != null ? [...baseTags, `originator ${originTag}`] : [...baseTags]\n      const result = await this.underlying.listOutputs(\n        { basket: BASKET_MAP.certificate, tags, tagQueryMode: 'all', include: 'entire transactions', limit: 10000 },\n        this.adminOriginator\n      )\n      await this.collectCertificateTokens(result, originFilter, seen, tokens)\n    }\n    return tokens\n  }\n\n  /** Decodes and appends certificate permission tokens from a listOutputs result. */\n  private async collectCertificateTokens(\n    result: Awaited<ReturnType<WalletInterface['listOutputs']>>,\n    originFilter: ReturnType<WalletPermissionsManager['prepareOriginator']> | undefined,\n    seen: Set<string>,\n    tokens: PermissionToken[]\n  ): Promise<void> {\n    for (const out of result.outputs) {\n      if (seen.has(out.outpoint)) continue\n      const [txid, outputIndex] = this.parseOutpoint(out.outpoint)\n      const tx = this.transactionFromResultBeef(result, txid)\n      const dec = PushDrop.decode(tx.outputs[outputIndex].lockingScript)\n      if (!dec?.fields || dec.fields.length < 6) continue\n      const [domainRaw, expiryRaw, privRaw, typeRaw, fieldsRaw, verifierRaw] = dec.fields\n      const domainDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(domainRaw))\n      const normalizedDomain = this.normalizeOriginator(domainDecoded)\n      if (originFilter != null && normalizedDomain !== originFilter.normalized) continue\n      const expiryDecoded = Number.parseInt(Utils.toUTF8(await this.decryptPermissionTokenField(expiryRaw)), 10)\n      const privDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(privRaw)) === 'true'\n      const typeDecoded = Utils.toUTF8(await this.decryptPermissionTokenField(typeRaw))\n      const verifierDec = Utils.toUTF8(await this.decryptPermissionTokenField(verifierRaw))\n      const allFields = JSON.parse(Utils.toUTF8(await this.decryptPermissionTokenField(fieldsRaw))) as string[]\n      seen.add(out.outpoint)\n      tokens.push({\n        tx: tx.toBEEF(),\n        txid,\n        outputIndex,\n        satoshis: out.satoshis,\n        outputScript: tx.outputs[outputIndex].lockingScript.toHex(),\n        originator: normalizedDomain,\n        rawOriginator: domainDecoded,\n        privileged: privDecoded,\n        certType: typeDecoded,\n        certFields: allFields,\n        verifier: verifierDec,\n        expiry: expiryDecoded\n      })\n    }\n  }\n\n  /**\n   * Returns `true` if the originator already holds a valid unexpired certificate access\n   * for the given certType/fields. Does not prompt the user.\n   */\n  public async hasCertificateAccess(params: {\n    originator: string\n    privileged: boolean\n    verifier: string\n    certType: string\n    fields: string[]\n  }): Promise<boolean> {\n    try {\n      await this.ensureCertificateAccess({\n        originator: params.originator,\n        privileged: params.privileged,\n        verifier: params.verifier,\n        certType: params.certType,\n        fields: params.fields,\n        seekPermission: false,\n        usageType: 'disclosure'\n      })\n      return true\n    } catch {\n      return false\n    }\n  }\n\n  public async revokePermissions(oldTokens: PermissionToken[]): Promise<PermissionToken[]> {\n    return await this.revokePermissionTokensBestEffort(oldTokens)\n  }\n\n  public async revokeAllForOriginator(\n    originator: string,\n    opts?: {\n      protocol?: boolean\n      basket?: boolean\n      certificate?: boolean\n      spending?: boolean\n    }\n  ): Promise<PermissionToken[]> {\n    const preparedOriginator = this.prepareOriginator(originator)\n    const include = {\n      protocol: true,\n      basket: true,\n      certificate: true,\n      spending: true,\n      ...opts\n    }\n\n    const [protocolTokens, basketTokens, certificateTokens, spendingTokens] = await Promise.all([\n      include.protocol ? this.listProtocolPermissions({ originator }) : Promise.resolve([]),\n      include.basket ? this.listBasketAccess({ originator }) : Promise.resolve([]),\n      include.certificate ? this.listCertificateAccess({ originator }) : Promise.resolve([]),\n      include.spending\n        ? this.listSpendingAuthorizations({ originator: preparedOriginator.normalized })\n        : Promise.resolve([])\n    ])\n\n    const spendingTokenList = spendingTokens.length > 0 ? [spendingTokens[0]] : []\n\n    const allTokens = [...protocolTokens, ...basketTokens, ...certificateTokens, ...spendingTokenList]\n    const seen = new Set<string>()\n    const deduped = allTokens.filter(t => {\n      const key = `${t.txid}.${t.outputIndex}`\n      if (seen.has(key)) return false\n      seen.add(key)\n      return true\n    })\n\n    return await this.revokePermissions(deduped)\n  }\n\n  private async revokePermissionTokensBestEffort(items: PermissionToken[]): Promise<PermissionToken[]> {\n    const CHUNK = 15\n    return await this.runBestEffortBatches(items, CHUNK, async chunk => {\n      await this.revokePermissionTokensChunk(chunk)\n      return chunk\n    })\n  }\n\n  private async revokePermissionTokensChunk(oldTokens: PermissionToken[]): Promise<void> {\n    if (oldTokens.length === 0) return\n\n    const inputBeef = new Beef()\n    for (const token of oldTokens) {\n      inputBeef.mergeBeef(Beef.fromBinary(token.tx))\n    }\n\n    const { signableTransaction } = await this.createAction(\n      {\n        description: `Revoke ${oldTokens.length} permissions`,\n        inputBEEF: inputBeef.toBinary(),\n        inputs: oldTokens.map((t, i) => ({\n          outpoint: `${t.txid}.${t.outputIndex}`,\n          unlockingScriptLength: 73,\n          inputDescription: `Consume old permission token #${i + 1}`\n        })),\n        options: {\n          acceptDelayedBroadcast: true,\n          randomizeOutputs: false,\n          signAndProcess: false\n        }\n      },\n      this.adminOriginator\n    )\n\n    if (!signableTransaction?.reference || !signableTransaction.tx) {\n      throw new Error('Failed to create signable transaction')\n    }\n\n    const tx = Transaction.fromAtomicBEEF(signableTransaction.tx)\n\n    const inputsToSign = oldTokens.map(token => {\n      let permInputIndex = this.findInputIndexForToken(tx, token)\n      if (permInputIndex === -1 && tx.inputs.length === 1) {\n        permInputIndex = 0\n      }\n      if (permInputIndex === -1) {\n        throw new Error('Unable to locate permission token input for revocation.')\n      }\n      return { token, permInputIndex }\n    })\n\n    const pushdrop = new PushDrop(this.underlying)\n    const spends: Record<number, { unlockingScript: string }> = {}\n    const signed = await this.mapWithConcurrency(inputsToSign, 8, async ({ token, permInputIndex }) => {\n      const unlocker = pushdrop.unlock(\n        WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n        '1',\n        'self',\n        'all',\n        false,\n        1,\n        LockingScript.fromHex(token.outputScript)\n      )\n      const unlockingScript = await unlocker.sign(tx, permInputIndex)\n      return { permInputIndex, unlockingScriptHex: unlockingScript.toHex() }\n    })\n\n    for (const s of signed) {\n      spends[s.permInputIndex] = { unlockingScript: s.unlockingScriptHex }\n    }\n\n    const { txid } = await this.underlying.signAction({\n      reference: signableTransaction.reference,\n      spends\n    })\n    if (!txid) throw new Error('Failed to finalize revoke transaction')\n  }\n\n  /**\n   * Revokes a permission token by spending it with no replacement output.\n   * The manager builds a BRC-100 transaction that consumes the token, effectively invalidating it.\n   */\n  public async revokePermission(oldToken: PermissionToken): Promise<void> {\n    const oldOutpoint = `${oldToken.txid}.${oldToken.outputIndex}`\n    const { signableTransaction } = await this.createAction(\n      {\n        description: 'Revoke permission',\n        inputBEEF: oldToken.tx,\n        inputs: [\n          {\n            outpoint: oldOutpoint,\n            unlockingScriptLength: 73, // length of signature\n            inputDescription: 'Consume old permission token'\n          }\n        ],\n        options: {\n          acceptDelayedBroadcast: true\n        }\n      },\n      this.adminOriginator\n    )\n    const tx = Transaction.fromBEEF(signableTransaction!.tx)\n\n    let permInputIndex = this.findInputIndexForToken(tx, oldToken)\n\n    if (permInputIndex === -1 && tx.inputs.length === 1) {\n      permInputIndex = 0\n    }\n    if (permInputIndex === -1) {\n      throw new Error('Unable to locate permission token input for revocation.')\n    }\n    const unlocker = new PushDrop(this.underlying).unlock(\n      WalletPermissionsManager.PERM_TOKEN_ENCRYPTION_PROTOCOL,\n      '1',\n      'self',\n      'all',\n      false,\n      1,\n      LockingScript.fromHex(oldToken.outputScript)\n    )\n    const unlockingScript = await unlocker.sign(tx, permInputIndex)\n    await this.underlying.signAction({\n      reference: signableTransaction!.reference,\n      spends: {\n        [permInputIndex]: {\n          unlockingScript: unlockingScript.toHex()\n        }\n      }\n    })\n  }\n\n  /* ---------------------------------------------------------------------\n   *  7) BRC-100 WALLET INTERFACE FORWARDING WITH PERMISSION CHECKS\n   * --------------------------------------------------------------------- */\n\n  public async createAction(\n    args: Parameters<WalletInterface['createAction']>[0],\n    originator?: string\n  ): ReturnType<WalletInterface['createAction']> {\n    // 1) Identify unique P-modules involved (one per schemeID) from both baskets and labels\n    const pModulesByScheme = new Map<string, PermissionsModule>()\n    const nonPBaskets = this.collectNonPBaskets(args.outputs, pModulesByScheme)\n    const nonPLabels = this.splitLabelsByPermissionModule(args.labels, pModulesByScheme)\n\n    // 2) Check permissions for non-P baskets\n    for (const basket of nonPBaskets) {\n      await this.ensureBasketAccess({\n        originator: originator!,\n        basket,\n        reason: args.description,\n        usageType: 'insertion'\n      })\n    }\n    // 3) Check permissions for non-P labels\n    for (const lbl of nonPLabels) {\n      await this.ensureLabelAccess({\n        originator: originator!,\n        label: lbl,\n        reason: args.description,\n        usageType: 'apply'\n      })\n    }\n\n    // 4) Force signAndProcess=false unless the originator is admin and explicitly sets it to true.\n    const modifiedOptions = this.enforceSignAndProcess(args.options, originator)\n\n    // 5) Encrypt transaction metadata, saving originals for spending auth and line items.\n    const originalDescription = args.description\n    const { originalInputDescriptions, originalOutputDescriptions } = await this.encryptActionMetadata(args)\n\n    // 6) Call the underlying wallet's createAction with P-module chaining as needed.\n    const finalArgs = {\n      ...args,\n      options: modifiedOptions,\n      labels: [...(args.labels || []), `admin originator ${originator}`, `admin month ${this.getCurrentMonthYearUTC()}`]\n    }\n    let createResult = await this.callCreateActionWithPModules(finalArgs, pModulesByScheme, originator)\n\n    if (createResult.signableTransaction == null) return createResult\n\n    // 7) Parse the signable tx to determine net spend, then gate on spending authorization.\n    const tx = Transaction.fromAtomicBEEF(createResult.signableTransaction.tx)\n    const reference = createResult.signableTransaction.reference\n\n    // 7a) SECURITY (GHSA-36f9-7rg5-cpf8) defense-in-depth: confirm every\n    // caller-requested output actually appears in the transaction we are about to\n    // authorize and sign. The locking scripts in the signable transaction\n    // originate from storage; a malicious or compromised remote storage provider\n    // could substitute a recipient script, which would then be signed and\n    // broadcast while this manager's caller/UI still shows the requested\n    // recipient. The signer (buildSignableTransaction) rejects this at the\n    // source; this is an independent check at the permissions layer.\n    try {\n      this.verifyRequestedOutputsPresent(tx, args)\n    } catch (err) {\n      await this.underlying.abortAction({ reference })\n      throw err\n    }\n\n    const { netSpent, lineItems } = this.computeNetSpend(\n      tx,\n      args,\n      originalInputDescriptions,\n      originalOutputDescriptions\n    )\n\n    // 8) If netSpent > 0, require spending authorization. Abort if denied.\n    if (netSpent > 0) {\n      try {\n        await this.ensureSpendingAuthorization({\n          originator: originator!,\n          satoshis: netSpent,\n          lineItems,\n          reason: originalDescription\n        })\n      } catch (err) {\n        await this.underlying.abortAction({ reference })\n        throw err\n      }\n    }\n\n    // 9) Finalize or return the signable transaction based on whether more signatures are needed.\n    const vargs = Validation.validateCreateActionArgs(args)\n    if (vargs.isSignAction) return createResult\n\n    const signResult = await this.underlying.signAction({ reference, spends: {}, options: args.options }, originator)\n    return { ...createResult, ...signResult, signableTransaction: undefined }\n  }\n\n  /** Scans outputs to split P-scheme baskets from regular baskets; registers P-modules as a side effect. */\n  private collectNonPBaskets(\n    outputs: Parameters<WalletInterface['createAction']>[0]['outputs'],\n    pModulesByScheme: Map<string, PermissionsModule>\n  ): string[] {\n    const nonPBaskets: string[] = []\n    if (outputs == null) return nonPBaskets\n    for (const out of outputs) {\n      if (!out.basket) continue\n      if (out.basket.startsWith('p ')) {\n        this.addPModuleByScheme(out.basket.split(' ')[1], 'basket', pModulesByScheme)\n      } else {\n        nonPBaskets.push(out.basket)\n      }\n    }\n    return nonPBaskets\n  }\n\n  /** Enforces signAndProcess=false for non-admin originators; throws if admin override is missing. */\n  private enforceSignAndProcess(\n    options: Parameters<WalletInterface['createAction']>[0]['options'],\n    originator?: string\n  ): typeof options {\n    const modifiedOptions = { ...options }\n    if (modifiedOptions.signAndProcess !== true) {\n      modifiedOptions.signAndProcess = false\n    } else if (!this.isAdminOriginator(originator!)) {\n      throw new Error('Only the admin originator can set signAndProcess=true explicitly.')\n    }\n    return modifiedOptions\n  }\n\n  /** Encrypts all description/instruction fields in args in-place; returns original (plaintext) copies. */\n  private async encryptActionMetadata(args: Parameters<WalletInterface['createAction']>[0]): Promise<{\n    originalInputDescriptions: Record<number, string>\n    originalOutputDescriptions: Record<number, string>\n  }> {\n    const originalInputDescriptions: Record<number, string> = {}\n    const originalOutputDescriptions: Record<number, string> = {}\n    const inputEncryptionTasks = (args.inputs || []).map(async (input, i) => {\n      if (!input.inputDescription) return\n      originalInputDescriptions[i] = input.inputDescription\n      input.inputDescription = await this.maybeEncryptMetadata(input.inputDescription)\n    })\n    const outputEncryptionTasks = (args.outputs || []).map(async (output, i) => {\n      if (output.outputDescription) {\n        originalOutputDescriptions[i] = output.outputDescription\n        output.outputDescription = await this.maybeEncryptMetadata(output.outputDescription)\n      }\n      if (output.customInstructions) {\n        output.customInstructions = await this.maybeEncryptMetadata(output.customInstructions)\n      }\n    })\n    await Promise.all([\n      (async () => {\n        args.description = await this.maybeEncryptMetadata(args.description)\n      })(),\n      ...inputEncryptionTasks,\n      ...outputEncryptionTasks\n    ])\n    return { originalInputDescriptions, originalOutputDescriptions }\n  }\n\n  /** Calls underlying createAction, chaining P-module request/response transforms when needed. */\n  private async callCreateActionWithPModules(\n    finalArgs: CreateActionArgs & { labels: string[] },\n    pModulesByScheme: Map<string, PermissionsModule>,\n    originator?: string\n  ): Promise<Awaited<ReturnType<WalletInterface['createAction']>>> {\n    if (pModulesByScheme.size === 0) return await this.underlying.createAction(finalArgs, originator)\n\n    const pModules = Array.from(pModulesByScheme.values())\n    let transformedArgs: object = finalArgs\n    for (const module of pModules) {\n      const transformed = await module.onRequest({\n        method: 'createAction',\n        args: transformedArgs,\n        originator: originator!\n      })\n      transformedArgs = transformed.args\n    }\n    let createResult = await this.underlying.createAction(transformedArgs as CreateActionArgs, originator)\n    for (let i = pModules.length - 1; i >= 0; i--) {\n      createResult = await pModules[i].onResponse(createResult, { method: 'createAction', originator: originator! })\n    }\n    return createResult\n  }\n\n  /**\n   * Computes the net satoshis the originator is spending in a createAction call,\n   * accounting for foreign (originator-provided) inputs and outputs plus the fee.\n   * Also builds the line items list for the spending authorization request.\n   */\n  /**\n   * Defense-in-depth verification that each caller-requested output (locking\n   * script + amount) is present in the transaction returned for signing.\n   *\n   * The scripts in the signable transaction originate from storage. A malicious\n   * or compromised remote storage provider could substitute a different\n   * recipient script for a caller-specified output. The signer\n   * (buildSignableTransaction) rejects this at the source; this is an\n   * independent check at the permissions layer so the substitution is caught\n   * regardless of how the signable transaction was produced.\n   *\n   * Outputs are matched as a multiset on (lockingScript, satoshis): the\n   * transaction also contains change/commission outputs and the output order is\n   * randomized by default, and a caller may legitimately request the same\n   * script+amount more than once.\n   *\n   * @throws Error if any caller-requested output is absent from the transaction.\n   */\n  private verifyRequestedOutputsPresent(tx: Transaction, args: Parameters<WalletInterface['createAction']>[0]): void {\n    const requested = args.outputs || []\n    if (requested.length === 0) return\n\n    // All transaction outputs as (script hex, satoshis); each may satisfy at\n    // most one requested output.\n    const available = tx.outputs.map(o => ({\n      script: o.lockingScript.toHex().toLowerCase(),\n      satoshis: o.satoshis,\n      used: false\n    }))\n\n    for (let i = 0; i < requested.length; i++) {\n      const wantScript = (requested[i].lockingScript ?? '').toLowerCase()\n      const wantSats = requested[i].satoshis\n      const match = available.find(a => !a.used && a.script === wantScript && a.satoshis === wantSats)\n      if (match == null) {\n        throw new Error(\n          `The transaction returned for signing does not contain caller-requested output ${i} ` +\n            `(locking script and amount). The recipient may have been substituted by storage.`\n        )\n      }\n      match.used = true\n    }\n  }\n\n  private computeNetSpend(\n    tx: Transaction,\n    args: Parameters<WalletInterface['createAction']>[0],\n    originalInputDescriptions: Record<number, string>,\n    originalOutputDescriptions: Record<number, string>\n  ): { netSpent: number; lineItems: Array<{ type: LineItemType; description: string; satoshis: number }> } {\n    const lineItems: Array<{ type: LineItemType; description: string; satoshis: number }> = []\n\n    // Sum originator-provided inputs:\n    let totalInputSatoshis = 0\n    for (const input of tx.inputs) {\n      const outpoint = `${input.sourceTXID}.${input.sourceOutputIndex}`\n      const matchingIndex = (args.inputs || []).findIndex(i => i.outpoint === outpoint)\n      if (matchingIndex !== -1) {\n        const satoshis = input.sourceTransaction!.outputs[input.sourceOutputIndex].satoshis!\n        totalInputSatoshis += satoshis\n        lineItems.push({\n          type: 'input',\n          description: originalInputDescriptions[matchingIndex] || 'No input description provided',\n          satoshis\n        })\n      }\n    }\n\n    // Sum originator-requested outputs:\n    const totalOutputSatoshis = (args.outputs || []).reduce((acc, out) => acc + out.satoshis, 0)\n    for (const outIndex in args.outputs || []) {\n      const out = args.outputs![outIndex]\n      lineItems.push({\n        type: 'output',\n        satoshis: out.satoshis,\n        description: originalOutputDescriptions[outIndex] || 'No output description provided'\n      })\n    }\n\n    // Add an entry for the transaction fee:\n    const fee = tx.getFee()\n    lineItems.push({ type: 'fee', satoshis: fee, description: 'Network fee' })\n\n    /**\n     * Net spend = total foreign outflows minus total foreign inflows plus fee.\n     * Domestic wallet inputs/change outputs are not counted — they are internal.\n     */\n    const netSpent = totalOutputSatoshis + fee - totalInputSatoshis\n    return { netSpent, lineItems }\n  }\n\n  public async signAction(\n    ...args: Parameters<WalletInterface['signAction']>\n  ): ReturnType<WalletInterface['signAction']> {\n    return await this.underlying.signAction(...args)\n  }\n\n  public async abortAction(\n    ...args: Parameters<WalletInterface['abortAction']>\n  ): ReturnType<WalletInterface['abortAction']> {\n    return await this.underlying.abortAction(...args)\n  }\n\n  public async listActions(\n    ...args: Parameters<WalletInterface['listActions']>\n  ): ReturnType<WalletInterface['listActions']> {\n    const [requestArgs, originator] = args\n    const { remainingLabels: labelsForPermissionChecks } = parseBrc114ActionTimeLabels(requestArgs.labels)\n\n    // 1) Identify unique P-modules involved (one per schemeID, preserving label order)\n    const pModulesByScheme = new Map<string, PermissionsModule>()\n    const nonPLabels = this.splitLabelsByPermissionModule(labelsForPermissionChecks, pModulesByScheme)\n\n    // 2) Check permissions for non-P labels\n    for (const lbl of nonPLabels) {\n      await this.ensureLabelAccess({\n        originator: originator!,\n        label: lbl,\n        reason: 'listActions',\n        usageType: 'list'\n      })\n    }\n\n    // 3) Call underlying wallet, with P-module transformations if needed\n    let results: ListActionsResult\n\n    if (pModulesByScheme.size > 0) {\n      // P-modules are involved - chain transformations\n      const pModules = Array.from(pModulesByScheme.values())\n\n      // Chain onRequest calls through all modules in order\n      let transformedArgs: object = requestArgs\n      for (const module of pModules) {\n        const transformed = await module.onRequest({\n          method: 'listActions',\n          args: transformedArgs,\n          originator: originator!\n        })\n        transformedArgs = transformed.args\n      }\n\n      // Call underlying wallet with transformed args\n      results = await this.underlying.listActions(transformedArgs as ListActionsArgs, originator)\n\n      // Chain onResponse calls in reverse order\n      for (let i = pModules.length - 1; i >= 0; i--) {\n        results = await pModules[i].onResponse(results, {\n          method: 'listActions',\n          originator: originator!\n        })\n      }\n    } else {\n      // No P-modules - call underlying wallet directly\n      results = await this.underlying.listActions(...args)\n    }\n\n    // 4) Transparently decrypt transaction metadata, if configured to do so.\n    return await this.decryptListActionsMetadata(results)\n  }\n\n  private collectInternalizeActionBaskets(\n    requestArgs: InternalizeActionArgs,\n    pModulesByScheme: Map<string, PermissionsModule>\n  ): Array<{ outIndex: string; basket: string; customInstructions?: string }> {\n    const nonPModuleBaskets: Array<{\n      outIndex: string\n      basket: string\n      customInstructions?: string\n    }> = []\n    for (const outIndex in requestArgs.outputs) {\n      const output = requestArgs.outputs[outIndex]\n      if (output.protocol !== 'basket insertion') continue\n      const { basket, customInstructions } = output.insertionRemittance!\n      if (basket.startsWith('p ')) {\n        this.addPModuleByScheme(basket.split(' ')[1], 'basket', pModulesByScheme)\n      } else {\n        nonPModuleBaskets.push({ outIndex, basket, customInstructions })\n      }\n    }\n    return nonPModuleBaskets\n  }\n\n  private async authorizeInternalizeActionBaskets(\n    requestArgs: InternalizeActionArgs,\n    originator: string,\n    baskets: Array<{ outIndex: string; basket: string; customInstructions?: string }>\n  ): Promise<void> {\n    for (const { outIndex, basket, customInstructions } of baskets) {\n      await this.ensureBasketAccess({\n        originator,\n        basket,\n        reason: requestArgs.description,\n        usageType: 'insertion'\n      })\n      if (customInstructions == null || customInstructions === '') continue\n      requestArgs.outputs[outIndex as unknown as number].insertionRemittance!.customInstructions =\n        await this.maybeEncryptMetadata(customInstructions)\n    }\n  }\n\n  private async authorizeInternalizeActionLabels(\n    requestArgs: InternalizeActionArgs,\n    originator: string,\n    labels: string[]\n  ): Promise<void> {\n    for (const label of labels) {\n      await this.ensureLabelAccess({\n        originator,\n        label,\n        reason: requestArgs.description,\n        usageType: 'apply'\n      })\n    }\n  }\n\n  private async encryptInternalizeActionModuleMetadata(requestArgs: InternalizeActionArgs): Promise<void> {\n    for (const outIndex in requestArgs.outputs) {\n      const output = requestArgs.outputs[outIndex]\n      const customInstructions = output.insertionRemittance?.customInstructions\n      if (output.protocol !== 'basket insertion' || !customInstructions) continue\n      output.insertionRemittance!.customInstructions = await this.maybeEncryptMetadata(customInstructions)\n    }\n  }\n\n  private async runInternalizeActionModules(\n    requestArgs: InternalizeActionArgs,\n    originator: string,\n    modules: PermissionsModule[]\n  ): Promise<Awaited<ReturnType<WalletInterface['internalizeAction']>>> {\n    let transformedArgs: object = requestArgs\n    for (const module of modules) {\n      const transformed = await module.onRequest({\n        method: 'internalizeAction',\n        args: transformedArgs,\n        originator\n      })\n      transformedArgs = transformed.args\n    }\n    await this.encryptInternalizeActionModuleMetadata(transformedArgs as InternalizeActionArgs)\n    let result = await this.underlying.internalizeAction(transformedArgs as InternalizeActionArgs, originator)\n    for (let index = modules.length - 1; index >= 0; index--) {\n      result = await modules[index].onResponse(result, {\n        method: 'internalizeAction',\n        originator\n      })\n    }\n    return result\n  }\n\n  public async internalizeAction(\n    ...args: Parameters<WalletInterface['internalizeAction']>\n  ): ReturnType<WalletInterface['internalizeAction']> {\n    const [requestArgs, originator] = args\n\n    // 1) Identify unique P-modules involved (one per schemeID) from both baskets and labels\n    const pModulesByScheme = new Map<string, PermissionsModule>()\n    const nonPBaskets = this.collectInternalizeActionBaskets(requestArgs, pModulesByScheme)\n    const nonPLabels = this.splitLabelsByPermissionModule(requestArgs.labels, pModulesByScheme)\n    await this.authorizeInternalizeActionBaskets(requestArgs, originator!, nonPBaskets)\n    await this.authorizeInternalizeActionLabels(requestArgs, originator!, nonPLabels)\n\n    // 4) Call underlying wallet, with P-module transformations if needed\n    if (pModulesByScheme.size > 0) {\n      return await this.runInternalizeActionModules(requestArgs, originator!, Array.from(pModulesByScheme.values()))\n    }\n\n    // No P-modules - call underlying wallet directly\n    return await this.underlying.internalizeAction(...args)\n  }\n\n  public async listOutputs(\n    ...args: Parameters<WalletInterface['listOutputs']>\n  ): ReturnType<WalletInterface['listOutputs']> {\n    const [requestArgs, originator] = args\n\n    // Delegate to permission module if needed\n    const pModuleResult = await this.delegateToPModuleIfNeeded(\n      requestArgs.basket,\n      'listOutputs',\n      requestArgs,\n      originator!,\n      async transformedArgs => {\n        const result = await this.underlying.listOutputs(transformedArgs as ListOutputsArgs, originator)\n        // Apply metadata decryption to permission module response\n        return await this.decryptListOutputsMetadata(result)\n      }\n    )\n    if (pModuleResult !== null) {\n      return pModuleResult\n    }\n\n    // Ensure the originator has permission for the basket.\n    await this.ensureBasketAccess({\n      originator: originator!,\n      basket: requestArgs.basket,\n      reason: 'listOutputs',\n      usageType: 'listing'\n    })\n    const results = await this.underlying.listOutputs(...args)\n\n    // Apply metadata decryption to regular response\n    return await this.decryptListOutputsMetadata(results)\n  }\n\n  public async relinquishOutput(\n    ...args: Parameters<WalletInterface['relinquishOutput']>\n  ): ReturnType<WalletInterface['relinquishOutput']> {\n    const [requestArgs, originator] = args\n\n    // Delegate to permission module if needed\n    const pModuleResult = await this.delegateToPModuleIfNeeded(\n      requestArgs.basket,\n      'relinquishOutput',\n      requestArgs,\n      originator!,\n      async transformedArgs => {\n        return await this.underlying.relinquishOutput(transformedArgs as RelinquishOutputArgs, originator)\n      }\n    )\n    if (pModuleResult !== null) {\n      return pModuleResult\n    }\n\n    await this.ensureBasketAccess({\n      originator: originator!,\n      basket: requestArgs.basket,\n      reason: 'relinquishOutput',\n      usageType: 'removal'\n    })\n    return await this.underlying.relinquishOutput(...args)\n  }\n\n  public async getPublicKey(\n    ...args: Parameters<WalletInterface['getPublicKey']>\n  ): ReturnType<WalletInterface['getPublicKey']> {\n    const [requestArgs, originator] = args\n\n    if (requestArgs.protocolID != null) {\n      // Delegate to permission module if needed\n      const pModuleResult = await this.delegateToPModuleIfNeeded(\n        requestArgs.protocolID[1],\n        'getPublicKey',\n        requestArgs,\n        originator!,\n        async transformedArgs => {\n          return await this.underlying.getPublicKey(transformedArgs as GetPublicKeyArgs, originator)\n        }\n      )\n      if (pModuleResult !== null) {\n        return pModuleResult\n      }\n\n      // Not a P-protocol, continue with normal permission flow\n      await this.ensureProtocolPermission({\n        originator: originator!,\n        privileged: requestArgs.privileged!,\n        protocolID: requestArgs.protocolID,\n        counterparty: requestArgs.counterparty || 'self',\n        reason: requestArgs.privilegedReason,\n        seekPermission: requestArgs.seekPermission,\n        usageType: 'publicKey'\n      })\n    }\n\n    if (requestArgs.identityKey) {\n      // We also require a minimal protocol permission to retrieve the user's identity key\n      await this.ensureProtocolPermission({\n        originator: originator!,\n        privileged: requestArgs.privileged!,\n        protocolID: [1, 'identity key retrieval'],\n        counterparty: 'self',\n        reason: requestArgs.privilegedReason,\n        seekPermission: requestArgs.seekPermission,\n        usageType: 'identityKey'\n      })\n    }\n\n    return await this.underlying.getPublicKey(...args)\n  }\n\n  public async revealCounterpartyKeyLinkage(\n    ...args: Parameters<WalletInterface['revealCounterpartyKeyLinkage']>\n  ): ReturnType<WalletInterface['revealCounterpartyKeyLinkage']> {\n    const [requestArgs, originator] = args\n    await this.ensureProtocolPermission({\n      originator: originator!,\n      privileged: requestArgs.privileged!,\n      protocolID: [2, `counterparty key linkage revelation ${requestArgs.counterparty}`],\n      counterparty: requestArgs.verifier,\n      reason: requestArgs.privilegedReason,\n      usageType: 'linkageRevelation'\n    })\n    return await this.underlying.revealCounterpartyKeyLinkage(...args)\n  }\n\n  public async revealSpecificKeyLinkage(\n    ...args: Parameters<WalletInterface['revealSpecificKeyLinkage']>\n  ): ReturnType<WalletInterface['revealSpecificKeyLinkage']> {\n    const [requestArgs, originator] = args\n    await this.ensureProtocolPermission({\n      originator: originator!,\n      privileged: requestArgs.privileged!,\n      protocolID: [\n        2,\n        `specific key linkage revelation ${requestArgs.protocolID[1]} ${requestArgs.protocolID[0] === 2 ? requestArgs.keyID : 'all'}`\n      ],\n      counterparty: requestArgs.verifier,\n      reason: requestArgs.privilegedReason,\n      usageType: 'linkageRevelation'\n    })\n    return await this.underlying.revealSpecificKeyLinkage(...args)\n  }\n\n  public async encrypt(...args: Parameters<WalletInterface['encrypt']>): ReturnType<WalletInterface['encrypt']> {\n    const [requestArgs, originator] = args\n    // Delegate to permission module if needed\n    const pModuleResult = await this.delegateToPModuleIfNeeded(\n      requestArgs.protocolID[1],\n      'encrypt',\n      requestArgs,\n      originator!,\n      async transformedArgs => {\n        return await this.underlying.encrypt(transformedArgs as WalletEncryptArgs, originator)\n      }\n    )\n    if (pModuleResult !== null) {\n      return pModuleResult\n    }\n    await this.ensureProtocolPermission({\n      originator: originator!,\n      protocolID: requestArgs.protocolID,\n      privileged: requestArgs.privileged!,\n      counterparty: requestArgs.counterparty || 'self',\n      reason: requestArgs.privilegedReason,\n      usageType: 'encrypting'\n    })\n    return await this.underlying.encrypt(...args)\n  }\n\n  public async decrypt(...args: Parameters<WalletInterface['decrypt']>): ReturnType<WalletInterface['decrypt']> {\n    const [requestArgs, originator] = args\n    // Delegate to permission module if needed\n    const pModuleResult = await this.delegateToPModuleIfNeeded(\n      requestArgs.protocolID[1],\n      'decrypt',\n      requestArgs,\n      originator!,\n      async transformedArgs => {\n        return await this.underlying.decrypt(transformedArgs as WalletDecryptArgs, originator)\n      }\n    )\n    if (pModuleResult !== null) {\n      return pModuleResult\n    }\n    await this.ensureProtocolPermission({\n      originator: originator!,\n      privileged: requestArgs.privileged!,\n      protocolID: requestArgs.protocolID,\n      counterparty: requestArgs.counterparty || 'self',\n      reason: requestArgs.privilegedReason,\n      usageType: 'encrypting'\n    })\n    return await this.underlying.decrypt(...args)\n  }\n\n  public async createHmac(\n    ...args: Parameters<WalletInterface['createHmac']>\n  ): ReturnType<WalletInterface['createHmac']> {\n    const [requestArgs, originator] = args\n    // Delegate to permission module if needed\n    const pModuleResult = await this.delegateToPModuleIfNeeded(\n      requestArgs.protocolID[1],\n      'createHmac',\n      requestArgs,\n      originator!,\n      async transformedArgs => {\n        return await this.underlying.createHmac(transformedArgs as CreateHmacArgs, originator)\n      }\n    )\n    if (pModuleResult !== null) {\n      return pModuleResult\n    }\n    await this.ensureProtocolPermission({\n      originator: originator!,\n      privileged: requestArgs.privileged!,\n      protocolID: requestArgs.protocolID,\n      counterparty: requestArgs.counterparty || 'self',\n      reason: requestArgs.privilegedReason,\n      usageType: 'hmac'\n    })\n    return await this.underlying.createHmac(...args)\n  }\n\n  public async verifyHmac(\n    ...args: Parameters<WalletInterface['verifyHmac']>\n  ): ReturnType<WalletInterface['verifyHmac']> {\n    const [requestArgs, originator] = args\n    // Delegate to permission module if needed\n    const pModuleResult = await this.delegateToPModuleIfNeeded(\n      requestArgs.protocolID[1],\n      'verifyHmac',\n      requestArgs,\n      originator!,\n      async transformedArgs => {\n        return await this.underlying.verifyHmac(transformedArgs as VerifyHmacArgs, originator)\n      }\n    )\n    if (pModuleResult !== null) {\n      return pModuleResult\n    }\n    await this.ensureProtocolPermission({\n      originator: originator!,\n      privileged: requestArgs.privileged!,\n      protocolID: requestArgs.protocolID,\n      counterparty: requestArgs.counterparty || 'self',\n      reason: requestArgs.privilegedReason,\n      usageType: 'hmac'\n    })\n    return await this.underlying.verifyHmac(...args)\n  }\n\n  public async createSignature(\n    ...args: Parameters<WalletInterface['createSignature']>\n  ): ReturnType<WalletInterface['createSignature']> {\n    const [requestArgs, originator] = args\n    // Delegate to permission module if needed\n    const pModuleResult = await this.delegateToPModuleIfNeeded(\n      requestArgs.protocolID[1],\n      'createSignature',\n      requestArgs,\n      originator!,\n      async transformedArgs => {\n        return await this.underlying.createSignature(transformedArgs as CreateSignatureArgs, originator)\n      }\n    )\n    if (pModuleResult !== null) {\n      return pModuleResult\n    }\n    await this.ensureProtocolPermission({\n      originator: originator!,\n      privileged: requestArgs.privileged!,\n      protocolID: requestArgs.protocolID,\n      counterparty: requestArgs.counterparty || 'self',\n      reason: requestArgs.privilegedReason,\n      usageType: 'signing'\n    })\n    return await this.underlying.createSignature(...args)\n  }\n\n  public async verifySignature(\n    ...args: Parameters<WalletInterface['verifySignature']>\n  ): ReturnType<WalletInterface['verifySignature']> {\n    const [requestArgs, originator] = args\n    // Delegate to permission module if needed\n    const pModuleResult = await this.delegateToPModuleIfNeeded(\n      requestArgs.protocolID[1],\n      'verifySignature',\n      requestArgs,\n      originator!,\n      async transformedArgs => {\n        return await this.underlying.verifySignature(transformedArgs as VerifySignatureArgs, originator)\n      }\n    )\n    if (pModuleResult !== null) {\n      return pModuleResult\n    }\n    await this.ensureProtocolPermission({\n      originator: originator!,\n      privileged: requestArgs.privileged!,\n      protocolID: requestArgs.protocolID,\n      counterparty: requestArgs.counterparty || 'self',\n      reason: requestArgs.privilegedReason,\n      usageType: 'signing'\n    })\n    return await this.underlying.verifySignature(...args)\n  }\n\n  public async acquireCertificate(\n    ...args: Parameters<WalletInterface['acquireCertificate']>\n  ): ReturnType<WalletInterface['acquireCertificate']> {\n    const [requestArgs, originator] = args\n    if (this.config.seekCertificateAcquisitionPermissions) {\n      await this.ensureProtocolPermission({\n        originator: originator!,\n        privileged: requestArgs.privileged!,\n        protocolID: [1, `certificate acquisition ${requestArgs.type}`],\n        counterparty: 'self',\n        reason: requestArgs.privilegedReason,\n        usageType: 'generic'\n      })\n    }\n    return await this.underlying.acquireCertificate(...args)\n  }\n\n  public async listCertificates(\n    ...args: Parameters<WalletInterface['listCertificates']>\n  ): ReturnType<WalletInterface['listCertificates']> {\n    const [requestArgs, originator] = args\n    if (this.config.seekCertificateListingPermissions) {\n      await this.ensureProtocolPermission({\n        originator: originator!,\n        privileged: requestArgs.privileged!,\n        protocolID: [1, 'certificate list'],\n        counterparty: 'self',\n        reason: requestArgs.privilegedReason,\n        usageType: 'generic'\n      })\n    }\n    return await this.underlying.listCertificates(...args)\n  }\n\n  public async proveCertificate(\n    ...args: Parameters<WalletInterface['proveCertificate']>\n  ): ReturnType<WalletInterface['proveCertificate']> {\n    const [requestArgs, originator] = args\n    await this.ensureCertificateAccess({\n      originator: originator!,\n      privileged: requestArgs.privileged!,\n      verifier: requestArgs.verifier,\n      certType: requestArgs.certificate.type!,\n      fields: requestArgs.fieldsToReveal,\n      reason: 'proveCertificate',\n      usageType: 'disclosure'\n    })\n    return await this.underlying.proveCertificate(...args)\n  }\n\n  public async relinquishCertificate(\n    ...args: Parameters<WalletInterface['relinquishCertificate']>\n  ): ReturnType<WalletInterface['relinquishCertificate']> {\n    const [requestArgs, originator] = args\n    if (this.config.seekCertificateRelinquishmentPermissions) {\n      await this.ensureProtocolPermission({\n        originator: originator!,\n        privileged: !!(requestArgs as any).privileged,\n        protocolID: [1, `certificate relinquishment ${requestArgs.type}`],\n        counterparty: 'self',\n        reason: (requestArgs as any).privilegedReason || 'relinquishCertificate',\n        usageType: 'generic'\n      })\n    }\n    return await this.underlying.relinquishCertificate(...args)\n  }\n\n  public async discoverByIdentityKey(\n    ...args: Parameters<WalletInterface['discoverByIdentityKey']>\n  ): ReturnType<WalletInterface['discoverByIdentityKey']> {\n    const [_, originator] = args\n    if (this.config.seekPermissionsForIdentityResolution) {\n      await this.ensureProtocolPermission({\n        originator: originator!,\n        privileged: false,\n        protocolID: [1, 'identity resolution'],\n        counterparty: 'self',\n        reason: 'discoverByIdentityKey',\n        usageType: 'generic'\n      })\n    }\n    return await this.underlying.discoverByIdentityKey(...args)\n  }\n\n  public async discoverByAttributes(\n    ...args: Parameters<WalletInterface['discoverByAttributes']>\n  ): ReturnType<WalletInterface['discoverByAttributes']> {\n    const [_, originator] = args\n    if (this.config.seekPermissionsForIdentityResolution) {\n      await this.ensureProtocolPermission({\n        originator: originator!,\n        privileged: false,\n        protocolID: [1, 'identity resolution'],\n        counterparty: 'self',\n        reason: 'discoverByAttributes',\n        usageType: 'generic'\n      })\n    }\n    return await this.underlying.discoverByAttributes(...args)\n  }\n\n  public async isAuthenticated(\n    ...args: Parameters<WalletInterface['isAuthenticated']>\n  ): ReturnType<WalletInterface['isAuthenticated']> {\n    return await this.underlying.isAuthenticated(...args)\n  }\n\n  public async waitForAuthentication(\n    ...args: Parameters<WalletInterface['waitForAuthentication']>\n  ): ReturnType<WalletInterface['waitForAuthentication']> {\n    const [_, originator] = args\n    if (this.config.seekGroupedPermission && originator) {\n      const { normalized: normalizedOriginator } = this.prepareOriginator(originator)\n      const normalized = normalizedOriginator\n\n      await this.withGroupedPermissionFlowLock(normalized, async () => {\n        // 1. Fetch manifest.json from the originator\n        const groupPermissions = await this.fetchManifestGroupPermissions(normalized)\n        if (groupPermissions != null) {\n          // 2. Filter out already-granted permissions\n          const permissionsToRequest = await this.filterAlreadyGrantedPermissions(normalized, groupPermissions)\n\n          // 3. If any permissions are left to request, start the flow\n          if (this.hasAnyPermissionsToRequest(permissionsToRequest)) {\n            const key = `group:${normalized}`\n            if (this.activeRequests.has(key)) {\n              // Another call is already waiting, piggyback on it\n              await new Promise<boolean>((resolve, reject) => {\n                this.activeRequests.get(key)!.pending.push({ resolve, reject })\n              })\n            } else {\n              // This is the first call, create a new request\n              const promise = new Promise<boolean>((resolve, reject) => {\n                this.activeRequests.set(key, {\n                  request: { originator: normalized, permissions: permissionsToRequest },\n                  pending: [{ resolve, reject }]\n                })\n              })\n\n              // Fire the event outside the executor to avoid async executor (S6544)\n              await this.callEvent('onGroupedPermissionRequested', {\n                requestID: key,\n                originator: normalized,\n                permissions: permissionsToRequest\n              })\n\n              await promise\n            }\n          }\n        }\n      })\n    }\n\n    // Finally, after handling grouped permissions, call the underlying method.\n    return await this.underlying.waitForAuthentication(...args)\n  }\n\n  public async getHeight(...args: Parameters<WalletInterface['getHeight']>): ReturnType<WalletInterface['getHeight']> {\n    return await this.underlying.getHeight(...args)\n  }\n\n  public async getHeaderForHeight(\n    ...args: Parameters<WalletInterface['getHeaderForHeight']>\n  ): ReturnType<WalletInterface['getHeaderForHeight']> {\n    return await this.underlying.getHeaderForHeight(...args)\n  }\n\n  public async getNetwork(\n    ...args: Parameters<WalletInterface['getNetwork']>\n  ): ReturnType<WalletInterface['getNetwork']> {\n    return await this.underlying.getNetwork(...args)\n  }\n\n  public async getVersion(\n    ...args: Parameters<WalletInterface['getVersion']>\n  ): ReturnType<WalletInterface['getVersion']> {\n    return await this.underlying.getVersion(...args)\n  }\n\n  /* ---------------------------------------------------------------------\n   *  8) INTERNAL HELPER UTILITIES\n   * --------------------------------------------------------------------- */\n\n  /** Returns true if the specified origin is the admin originator. */\n  private isAdminOriginator(originator: string): boolean {\n    return this.normalizeOriginator(originator) === this.adminOriginator\n  }\n\n  /**\n   * Checks if the given protocol is admin-reserved per BRC-100 rules:\n   *\n   *  - Must not start with `admin` (admin-reserved)\n   *  - Must not start with `p ` (allows for future specially permissioned protocols)\n   *\n   * If it violates these rules and the caller is not admin, we consider it \"admin-only.\"\n   */\n  private isAdminProtocol(proto: WalletProtocol): boolean {\n    const protocolName = proto[1]\n    if (protocolName.startsWith('admin')) {\n      return true\n    }\n    return false\n  }\n\n  /**\n   * Checks if the given label is admin-reserved per BRC-100 rules:\n   *\n   *  - Must not start with `admin` (admin-reserved)\n   *  - Must not start with `p ` (permissioned labels requiring a permission module)\n   *\n   * If it violates these rules and the caller is not admin, we consider it \"admin-only.\"\n   */\n  private isAdminLabel(label: string): boolean {\n    if (label.startsWith('admin')) {\n      return true\n    }\n    if (label.startsWith('p ')) {\n      return true\n    }\n    return false\n  }\n\n  /**\n   * Checks if the given basket is admin-reserved per BRC-100 rules:\n   *\n   *  - Must not start with `admin`\n   *  - Must not be `default` (some wallets use this for internal operations)\n   *  - Must not start with `p ` (future specially permissioned baskets)\n   */\n  private isAdminBasket(basket: string): boolean {\n    if (basket === 'default') return true\n    if (basket.startsWith('admin')) return true\n    return false\n  }\n\n  /**\n   * Whether the permission is satisfied without consulting on-chain tokens:\n   * cached, recently granted, or — when the user just granted it and its\n   * token is still minting — after the in-flight mint settles. Spares the\n   * user a duplicate prompt for a grant they already made moments ago.\n   */\n  private async hasRecentOrPendingGrant(cacheKey: string): Promise<boolean> {\n    if (!this.telemetry.enabled) return await this.hasRecentOrPendingGrantCore(cacheKey)\n    return await this.telemetry.withSpan(\n      'wallet.permission.cache_check',\n      {\n        component: 'wallet-permissions'\n      },\n      async span => {\n        const result = await this.hasRecentOrPendingGrantCore(cacheKey)\n        span.end({\n          attributes: {\n            'permission.cache_hit': result,\n            'permission.mint_in_flight': this.mintsInFlight.has(cacheKey)\n          }\n        })\n        return result\n      }\n    )\n  }\n\n  private async hasRecentOrPendingGrantCore(cacheKey: string): Promise<boolean> {\n    if (this.isPermissionCached(cacheKey) || this.isRecentlyGranted(cacheKey)) return true\n    const inFlight = this.mintsInFlight.get(cacheKey)\n    if (inFlight == null) return false\n    await inFlight\n    return this.isPermissionCached(cacheKey) || this.isRecentlyGranted(cacheKey)\n  }\n\n  /**\n   * Returns true if we have a cached record that the permission identified by\n   * `key` is valid and unexpired.\n   */\n  private isPermissionCached(key: string): boolean {\n    const entry = this.permissionCache.get(key)\n    if (entry == null) return false\n    if (Date.now() - entry.cachedAt > WalletPermissionsManager.CACHE_TTL_MS) {\n      this.permissionCache.delete(key)\n      return false\n    }\n    if (this.isTokenExpired(entry.expiry)) {\n      this.permissionCache.delete(key)\n      return false\n    }\n    return true\n  }\n\n  /** Caches the fact that the permission for `key` is valid until `expiry`. */\n  private cachePermission(key: string, expiry: number): void {\n    this.permissionCache.set(key, { expiry, cachedAt: Date.now() })\n  }\n\n  /** Records that a non-spending permission was just granted so we can skip re-prompting briefly. */\n  private markRecentGrant(request: PermissionRequest): void {\n    if (request.type === 'spending') return\n    const key = this.buildRequestKey(request)\n    if (!key) return\n    this.recentGrants.set(key, Date.now() + WalletPermissionsManager.RECENT_GRANT_COVER_MS)\n  }\n\n  /** Returns true if we are inside the short \"cover window\" immediately after granting permission. */\n  private isRecentlyGranted(key: string): boolean {\n    const expiry = this.recentGrants.get(key)\n    if (!expiry) return false\n    if (Date.now() > expiry) {\n      this.recentGrants.delete(key)\n      return false\n    }\n    return true\n  }\n\n  /** Normalizes and canonicalizes originator domains (e.g., lowercase + drop default ports). */\n  private normalizeOriginator(originator?: string): string {\n    if (!originator) return ''\n    const trimmed = originator.trim()\n    if (!trimmed) {\n      return ''\n    }\n\n    try {\n      const hasScheme = /^[a-zA-Z][a-zA-Z\\d+\\-.]*:\\/\\//.test(trimmed)\n      const candidate = hasScheme ? trimmed : `https://${trimmed}`\n      const url = new URL(candidate)\n      if (!url.hostname) {\n        return trimmed.toLowerCase()\n      }\n      const hostname = url.hostname.toLowerCase()\n      const needsBrackets = hostname.includes(':')\n      const baseHost = needsBrackets ? `[${hostname}]` : hostname\n      const port = url.port\n      const defaultPort = WalletPermissionsManager.DEFAULT_PORTS[url.protocol]\n      if (port && defaultPort && port === defaultPort) {\n        return baseHost\n      }\n      return port ? `${baseHost}:${port}` : baseHost\n    } catch {\n      // Fall back to a conservative lowercase trim if URL parsing fails.\n      return trimmed.toLowerCase()\n    }\n  }\n\n  private isWhitelistedCounterpartyProtocol(counterparty: string, protocolID: WalletProtocol): boolean {\n    const whitelist = this.config.whitelistedCounterparties\n    if (whitelist == null) return false\n    if (!counterparty || counterparty === 'self' || counterparty === 'anyone') return false\n\n    const protocols =\n      whitelist[counterparty] || whitelist[counterparty.toLowerCase()] || whitelist[counterparty.toUpperCase()]\n    if (!protocols || protocols.length === 0) return false\n\n    const protoName = (protocolID?.[1] ?? '').toString().toLowerCase()\n    if (!protoName) return false\n    return protocols.some(p => (p ?? '').toString().toLowerCase() === protoName)\n  }\n\n  /**\n   * Produces a normalized originator value along with the set of legacy\n   * representations that should be considered when searching for existing\n   * permission tokens (for backwards compatibility).\n   */\n  private prepareOriginator(originator?: string): { normalized: string; lookupValues: string[] } {\n    const trimmed = originator?.trim()\n    if (!trimmed) {\n      throw new Error('Originator is required for permission checks.')\n    }\n    const normalized = this.normalizeOriginator(trimmed) || trimmed.toLowerCase()\n    const lookupValues = Array.from(new Set([trimmed, normalized])).filter(Boolean)\n    return { normalized, lookupValues }\n  }\n\n  /**\n   * Builds a unique list of originator variants that should be searched when\n   * looking up on-chain tokens (e.g., legacy raw + normalized forms).\n   */\n  private buildOriginatorLookupValues(...origins: Array<string | undefined>): string[] {\n    const variants = new Set<string>()\n    for (const origin of origins) {\n      const trimmed = origin?.trim()\n      if (trimmed) {\n        variants.add(trimmed)\n      }\n    }\n    return Array.from(variants)\n  }\n\n  /**\n   * Builds a \"map key\" string so that identical requests (e.g. \"protocol:domain:true:protoName:counterparty\")\n   * do not produce multiple user prompts.\n   */\n  private buildRequestKey(r: PermissionRequest): string {\n    const normalizedOriginator = this.normalizeOriginator(r.originator)\n    switch (r.type) {\n      case 'protocol':\n        return `proto:${normalizedOriginator}:${!!r.privileged}:${r.protocolID?.join(',')}:${r.counterparty}`\n      case 'basket':\n        return `basket:${normalizedOriginator}:${r.basket}`\n      case 'certificate':\n        return `cert:${normalizedOriginator}:${!!r.privileged}:${r.certificate?.verifier}:${r.certificate?.certType}:${r.certificate?.fields.join('|')}`\n      case 'spending':\n        return `spend:${normalizedOriginator}:${r.spending?.satoshis}`\n    }\n  }\n\n  private buildActiveRequestKey(r: PermissionRequest): string {\n    const base = this.buildRequestKey(r)\n    if (r.type === 'protocol' || r.type === 'basket' || r.type === 'certificate') {\n      return `${base}:${r.usageType ?? ''}`\n    }\n    return base\n  }\n}\n"],"mappings":"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ACT;;;;;AAMA,MAAa,uBAA6C;CACxD;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,OAAO;EACP,OAAO;EACP,UAAU;EACV,UAAU;EACV,aAAa;EACb,eAAe;EACf,UAAU;EACV,eAAe;EACf,UAAU;EACV,WAAW;EACX,WAAW;CACb;CACA;EACE,OAAO;EACP,OAAO;EACP,UAAU;EACV,UAAU;EACV,aAAa;EACb,eAAe;EACf,UAAU;EACV,eAAe;EACf,UAAU;EACV,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO;EACP,WAAW;CACb;CACA;EACE,WAAW;EACX,UAAU;EACV,aAAa;EACb,UAAU;EACV,OAAO;EACP,UAAU;EACV,UAAU;EACV,eAAe;EACf,eAAe;EACf,OAAO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"}