UNPKG

wallet-storage

Version:

BRC100 conforming wallet, wallet storage and wallet signer components

1,055 lines (833 loc) 90.4 kB
# API Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) ## Interfaces | | | | --- | --- | | [CommitNewTxResults](#interface-commitnewtxresults) | [PostBeefResultForTxidApi](#interface-postbeefresultfortxidapi) | | [GenerateChangeSdkChangeInput](#interface-generatechangesdkchangeinput) | [PostReqsToNetworkDetails](#interface-postreqstonetworkdetails) | | [GenerateChangeSdkChangeOutput](#interface-generatechangesdkchangeoutput) | [PostReqsToNetworkResult](#interface-postreqstonetworkresult) | | [GenerateChangeSdkInput](#interface-generatechangesdkinput) | [StorageInternalizeActionResult](#interface-storageinternalizeactionresult) | | [GenerateChangeSdkOutput](#interface-generatechangesdkoutput) | [StorageKnexOptions](#interface-storageknexoptions) | | [GenerateChangeSdkParams](#interface-generatechangesdkparams) | [StorageProviderOptions](#interface-storageprovideroptions) | | [GenerateChangeSdkResult](#interface-generatechangesdkresult) | [StorageReaderOptions](#interface-storagereaderoptions) | | [GenerateChangeSdkStorageChange](#interface-generatechangesdkstoragechange) | [StorageReaderWriterOptions](#interface-storagereaderwriteroptions) | | [GetReqsAndBeefDetail](#interface-getreqsandbeefdetail) | [WalletStorageServerOptions](#interface-walletstorageserveroptions) | | [GetReqsAndBeefResult](#interface-getreqsandbeefresult) | [XValidCreateActionOutput](#interface-xvalidcreateactionoutput) | Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: CommitNewTxResults ```ts export interface CommitNewTxResults { req: entity.ProvenTxReq; log?: string; } ``` See also: [log](#variable-log) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: GenerateChangeSdkChangeInput ```ts export interface GenerateChangeSdkChangeInput { outputId: number; satoshis: number; } ``` Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: GenerateChangeSdkChangeOutput ```ts export interface GenerateChangeSdkChangeOutput { satoshis: number; lockingScriptLength: number; } ``` Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: GenerateChangeSdkInput ```ts export interface GenerateChangeSdkInput { satoshis: number; unlockingScriptLength: number; } ``` Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: GenerateChangeSdkOutput ```ts export interface GenerateChangeSdkOutput { satoshis: number; lockingScriptLength: number; } ``` Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: GenerateChangeSdkParams ```ts export interface GenerateChangeSdkParams { fixedInputs: GenerateChangeSdkInput[]; fixedOutputs: GenerateChangeSdkOutput[]; feeModel: sdk.StorageFeeModel; targetNetCount?: number; changeInitialSatoshis: number; changeFirstSatoshis: number; changeLockingScriptLength: number; changeUnlockingScriptLength: number; randomVals?: number[]; noLogging?: boolean; log?: string; } ``` See also: [GenerateChangeSdkInput](#interface-generatechangesdkinput), [GenerateChangeSdkOutput](#interface-generatechangesdkoutput), [StorageFeeModel](#interface-storagefeemodel), [log](#variable-log) <details> <summary>Interface GenerateChangeSdkParams Details</summary> #### Property changeFirstSatoshis Lowest amount value to assign to a change output. Drop the output if unable to satisfy. default 285 ```ts changeFirstSatoshis: number ``` #### Property changeInitialSatoshis Satoshi amount to initialize optional new change outputs. ```ts changeInitialSatoshis: number ``` #### Property changeLockingScriptLength Fixed change locking script length. For P2PKH template, 25 bytes ```ts changeLockingScriptLength: number ``` #### Property changeUnlockingScriptLength Fixed change unlocking script length. For P2PKH template, 107 bytes ```ts changeUnlockingScriptLength: number ``` #### Property targetNetCount Target for number of new change outputs added minus number of funding change outputs consumed. If undefined, only a single change output will be added if excess fees must be recaptured. ```ts targetNetCount?: number ``` </details> Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: GenerateChangeSdkResult ```ts export interface GenerateChangeSdkResult { allocatedChangeInputs: GenerateChangeSdkChangeInput[]; changeOutputs: GenerateChangeSdkChangeOutput[]; size: number; fee: number; satsPerKb: number; } ``` See also: [GenerateChangeSdkChangeInput](#interface-generatechangesdkchangeinput), [GenerateChangeSdkChangeOutput](#interface-generatechangesdkchangeoutput) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: GenerateChangeSdkStorageChange ```ts export interface GenerateChangeSdkStorageChange extends GenerateChangeSdkChangeInput { spendable: boolean; } ``` See also: [GenerateChangeSdkChangeInput](#interface-generatechangesdkchangeinput) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: GetReqsAndBeefDetail ```ts export interface GetReqsAndBeefDetail { txid: string; req?: table.ProvenTxReq; proven?: table.ProvenTx; status: "readyToSend" | "alreadySent" | "error" | "unknown"; error?: string; } ``` Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: GetReqsAndBeefResult ```ts export interface GetReqsAndBeefResult { beef: Beef; details: GetReqsAndBeefDetail[]; } ``` See also: [GetReqsAndBeefDetail](#interface-getreqsandbeefdetail) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: PostBeefResultForTxidApi ```ts export interface PostBeefResultForTxidApi { txid: string; status: "success" | "error"; alreadyKnown?: boolean; blockHash?: string; blockHeight?: number; merklePath?: string; } ``` <details> <summary>Interface PostBeefResultForTxidApi Details</summary> #### Property alreadyKnown if true, the transaction was already known to this service. Usually treat as a success. Potentially stop posting to additional transaction processors. ```ts alreadyKnown?: boolean ``` #### Property status 'success' - The transaction was accepted for processing ```ts status: "success" | "error" ``` </details> Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: PostReqsToNetworkDetails ```ts export interface PostReqsToNetworkDetails { txid: string; req: entity.ProvenTxReq; status: PostReqsToNetworkDetailsStatus; pbrft: sdk.PostTxResultForTxid; data?: string; error?: string; } ``` See also: [PostReqsToNetworkDetailsStatus](#type-postreqstonetworkdetailsstatus), [PostTxResultForTxid](#interface-posttxresultfortxid) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: PostReqsToNetworkResult ```ts export interface PostReqsToNetworkResult { status: "success" | "error"; beef: Beef; details: PostReqsToNetworkDetails[]; pbr?: sdk.PostBeefResult; log: string; } ``` See also: [PostBeefResult](#interface-postbeefresult), [PostReqsToNetworkDetails](#interface-postreqstonetworkdetails), [log](#variable-log) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: StorageInternalizeActionResult ```ts export interface StorageInternalizeActionResult extends InternalizeActionResult { isMerge: boolean; txid: string; satoshis: number; } ``` <details> <summary>Interface StorageInternalizeActionResult Details</summary> #### Property isMerge true if internalizing outputs on an existing storage transaction ```ts isMerge: boolean ``` #### Property satoshis net change in change balance for user due to this internalization ```ts satoshis: number ``` #### Property txid txid of transaction being internalized ```ts txid: string ``` </details> Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: StorageKnexOptions ```ts export interface StorageKnexOptions extends StorageProviderOptions { knex: Knex; } ``` See also: [StorageProviderOptions](#interface-storageprovideroptions) <details> <summary>Interface StorageKnexOptions Details</summary> #### Property knex Knex database interface initialized with valid connection configuration. ```ts knex: Knex ``` </details> Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: StorageProviderOptions ```ts export interface StorageProviderOptions extends StorageReaderWriterOptions { chain: sdk.Chain; feeModel: sdk.StorageFeeModel; commissionSatoshis: number; commissionPubKeyHex?: PubKeyHex; } ``` See also: [Chain](#type-chain), [StorageFeeModel](#interface-storagefeemodel), [StorageReaderWriterOptions](#interface-storagereaderwriteroptions) <details> <summary>Interface StorageProviderOptions Details</summary> #### Property commissionPubKeyHex If commissionSatoshis is greater than zero, must be a valid public key hex string. The actual locking script for each commission will use a public key derived from this key by information stored in the commissions table. ```ts commissionPubKeyHex?: PubKeyHex ``` #### Property commissionSatoshis Transactions created by this Storage can charge a fee per transaction. A value of zero disables commission fees. ```ts commissionSatoshis: number ``` </details> Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: StorageReaderOptions ```ts export interface StorageReaderOptions { chain: sdk.Chain; } ``` See also: [Chain](#type-chain) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: StorageReaderWriterOptions ```ts export interface StorageReaderWriterOptions extends StorageReaderOptions { } ``` See also: [StorageReaderOptions](#interface-storagereaderoptions) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: WalletStorageServerOptions ```ts export interface WalletStorageServerOptions { port: number; wallet: Wallet; monetize: boolean; calculateRequestPrice?: (req: Request) => number | Promise<number>; } ``` See also: [Wallet](#class-wallet) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Interface: XValidCreateActionOutput ```ts export interface XValidCreateActionOutput extends sdk.ValidCreateActionOutput { vout: number; providedBy: sdk.StorageProvidedBy; purpose?: string; derivationSuffix?: string; keyOffset?: string; } ``` See also: [StorageProvidedBy](#type-storageprovidedby), [ValidCreateActionOutput](#interface-validcreateactionoutput) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ## Classes | | | --- | | [KnexMigrations](#class-knexmigrations) | | [StorageClient](#class-storageclient) | | [StorageKnex](#class-storageknex) | | [StorageProvider](#class-storageprovider) | | [StorageReader](#class-storagereader) | | [StorageReaderWriter](#class-storagereaderwriter) | | [StorageServer](#class-storageserver) | | [StorageSyncReader](#class-storagesyncreader) | | [WalletStorageManager](#class-walletstoragemanager) | Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Class: KnexMigrations ```ts export class KnexMigrations implements MigrationSource<string> { migrations: Record<string, Migration> = {}; constructor(public chain: sdk.Chain, public storageName: string, public storageIdentityKey: string, public maxOutputScriptLength: number) async getMigrations(): Promise<string[]> getMigrationName(migration: string) async getMigration(migration: string): Promise<Migration> async getLatestMigration(): Promise<string> static async latestMigration(): Promise<string> setupMigrations(chain: string, storageName: string, storageIdentityKey: string, maxOutputScriptLength: number): Record<string, Migration> static async dbtype(knex: Knex<any, any[]>): Promise<DBType> { try { const q = `SELECT CASE WHEN (SELECT VERSION() LIKE '%MariaDB%') = 1 THEN 'Unknown' WHEN (SELECT VERSION()) IS NOT NULL THEN 'MySQL' ELSE 'Unknown' END AS database_type;`; let r = await knex.raw(q); if (!r[0]["database_type"]) r = r[0]; if (r["rows"]) r = r.rows; const dbtype: "SQLite" | "MySQL" | "Unknown" = r[0].database_type; if (dbtype === "Unknown") throw new sdk.WERR_NOT_IMPLEMENTED(`Attempting to create database on unsuported engine.`); return dbtype; } catch (eu: unknown) { const e = sdk.WalletError.fromUnknown(eu); if (e.code === "SQLITE_ERROR") return "SQLite"; throw new sdk.WERR_NOT_IMPLEMENTED(`Attempting to create database on unsuported engine.`); } } } ``` See also: [Chain](#type-chain), [DBType](#type-dbtype), [WERR_NOT_IMPLEMENTED](#class-werr_not_implemented), [WalletError](#class-walleterror) <details> <summary>Class KnexMigrations Details</summary> #### Constructor ```ts constructor(public chain: sdk.Chain, public storageName: string, public storageIdentityKey: string, public maxOutputScriptLength: number) ``` See also: [Chain](#type-chain) Argument Details + **storageName** + human readable name for this storage instance + **maxOutputScriptLength** + limit for scripts kept in outputs table, longer scripts will be pulled from rawTx #### Method dbtype ```ts static async dbtype(knex: Knex<any, any[]>): Promise<DBType> ``` See also: [DBType](#type-dbtype) Returns connected database engine variant </details> Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Class: StorageClient ```ts export class StorageClient implements sdk.WalletStorageProvider { public settings?: table.Settings; constructor(wallet: WalletInterface, endpointUrl: string) isStorageProvider(): boolean isAvailable(): boolean getSettings(): table.Settings async makeAvailable(): Promise<table.Settings> async destroy(): Promise<void> async migrate(storageName: string, storageIdentityKey: string): Promise<string> getServices(): sdk.WalletServices setServices(v: sdk.WalletServices): void async internalizeAction(auth: sdk.AuthId, args: InternalizeActionArgs): Promise<InternalizeActionResult> async createAction(auth: sdk.AuthId, args: sdk.ValidCreateActionArgs): Promise<sdk.StorageCreateActionResult> async processAction(auth: sdk.AuthId, args: sdk.StorageProcessActionArgs): Promise<sdk.StorageProcessActionResults> async abortAction(auth: sdk.AuthId, args: AbortActionArgs): Promise<AbortActionResult> async findOrInsertUser(identityKey): Promise<{ user: table.User; isNew: boolean; }> async findOrInsertSyncStateAuth(auth: sdk.AuthId, storageIdentityKey: string, storageName: string): Promise<{ syncState: table.SyncState; isNew: boolean; }> async insertCertificateAuth(auth: sdk.AuthId, certificate: table.CertificateX): Promise<number> async listActions(auth: sdk.AuthId, vargs: sdk.ValidListActionsArgs): Promise<ListActionsResult> async listOutputs(auth: sdk.AuthId, vargs: sdk.ValidListOutputsArgs): Promise<ListOutputsResult> async listCertificates(auth: sdk.AuthId, vargs: sdk.ValidListCertificatesArgs): Promise<ListCertificatesResult> async findCertificatesAuth(auth: sdk.AuthId, args: sdk.FindCertificatesArgs): Promise<table.Certificate[]> async findOutputBasketsAuth(auth: sdk.AuthId, args: sdk.FindOutputBasketsArgs): Promise<table.OutputBasket[]> async findOutputsAuth(auth: sdk.AuthId, args: sdk.FindOutputsArgs): Promise<table.Output[]> findProvenTxReqs(args: sdk.FindProvenTxReqsArgs): Promise<table.ProvenTxReq[]> async relinquishCertificate(auth: sdk.AuthId, args: RelinquishCertificateArgs): Promise<number> async relinquishOutput(auth: sdk.AuthId, args: RelinquishOutputArgs): Promise<number> async processSyncChunk(args: sdk.RequestSyncChunkArgs, chunk: sdk.SyncChunk): Promise<sdk.ProcessSyncChunkResult> async getSyncChunk(args: sdk.RequestSyncChunkArgs): Promise<sdk.SyncChunk> async updateProvenTxReqWithNewProvenTx(args: sdk.UpdateProvenTxReqWithNewProvenTxArgs): Promise<sdk.UpdateProvenTxReqWithNewProvenTxResult> async setActive(auth: sdk.AuthId, newActiveStorageIdentityKey: string): Promise<number> } ``` See also: [AuthId](#interface-authid), [FindCertificatesArgs](#interface-findcertificatesargs), [FindOutputBasketsArgs](#interface-findoutputbasketsargs), [FindOutputsArgs](#interface-findoutputsargs), [FindProvenTxReqsArgs](#interface-findproventxreqsargs), [ProcessSyncChunkResult](#interface-processsyncchunkresult), [RequestSyncChunkArgs](#interface-requestsyncchunkargs), [StorageCreateActionResult](#interface-storagecreateactionresult), [StorageProcessActionArgs](#interface-storageprocessactionargs), [StorageProcessActionResults](#interface-storageprocessactionresults), [SyncChunk](#interface-syncchunk), [UpdateProvenTxReqWithNewProvenTxArgs](#interface-updateproventxreqwithnewproventxargs), [UpdateProvenTxReqWithNewProvenTxResult](#interface-updateproventxreqwithnewproventxresult), [ValidCreateActionArgs](#interface-validcreateactionargs), [ValidListActionsArgs](#interface-validlistactionsargs), [ValidListCertificatesArgs](#interface-validlistcertificatesargs), [ValidListOutputsArgs](#interface-validlistoutputsargs), [WalletServices](#interface-walletservices), [WalletStorageProvider](#interface-walletstorageprovider), [createAction](#function-createaction), [getSyncChunk](#function-getsyncchunk), [internalizeAction](#function-internalizeaction), [listActions](#function-listactions), [listCertificates](#function-listcertificates), [listOutputs](#function-listoutputs), [processAction](#function-processaction) Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Class: StorageKnex ```ts export class StorageKnex extends StorageProvider implements sdk.WalletStorageProvider { knex: Knex; constructor(options: StorageKnexOptions) async readSettings(): Promise<table.Settings> override async getProvenOrRawTx(txid: string, trx?: sdk.TrxToken): Promise<sdk.ProvenOrRawTx> dbTypeSubstring(source: string, fromOffset: number, forLength?: number) override async getRawTxOfKnownValidTransaction(txid?: string, offset?: number, length?: number, trx?: sdk.TrxToken): Promise<number[] | undefined> getProvenTxsForUserQuery(args: sdk.FindForUserSincePagedArgs): Knex.QueryBuilder override async getProvenTxsForUser(args: sdk.FindForUserSincePagedArgs): Promise<table.ProvenTx[]> getProvenTxReqsForUserQuery(args: sdk.FindForUserSincePagedArgs): Knex.QueryBuilder override async getProvenTxReqsForUser(args: sdk.FindForUserSincePagedArgs): Promise<table.ProvenTxReq[]> getTxLabelMapsForUserQuery(args: sdk.FindForUserSincePagedArgs): Knex.QueryBuilder override async getTxLabelMapsForUser(args: sdk.FindForUserSincePagedArgs): Promise<table.TxLabelMap[]> getOutputTagMapsForUserQuery(args: sdk.FindForUserSincePagedArgs): Knex.QueryBuilder override async getOutputTagMapsForUser(args: sdk.FindForUserSincePagedArgs): Promise<table.OutputTagMap[]> override async listActions(auth: sdk.AuthId, vargs: sdk.ValidListActionsArgs): Promise<ListActionsResult> override async listOutputs(auth: sdk.AuthId, vargs: sdk.ValidListOutputsArgs): Promise<ListOutputsResult> override async insertProvenTx(tx: table.ProvenTx, trx?: sdk.TrxToken): Promise<number> override async insertProvenTxReq(tx: table.ProvenTxReq, trx?: sdk.TrxToken): Promise<number> override async insertUser(user: table.User, trx?: sdk.TrxToken): Promise<number> override async insertCertificateAuth(auth: sdk.AuthId, certificate: table.CertificateX): Promise<number> override async insertCertificate(certificate: table.CertificateX, trx?: sdk.TrxToken): Promise<number> override async insertCertificateField(certificateField: table.CertificateField, trx?: sdk.TrxToken): Promise<void> override async insertOutputBasket(basket: table.OutputBasket, trx?: sdk.TrxToken): Promise<number> override async insertTransaction(tx: table.Transaction, trx?: sdk.TrxToken): Promise<number> override async insertCommission(commission: table.Commission, trx?: sdk.TrxToken): Promise<number> override async insertOutput(output: table.Output, trx?: sdk.TrxToken): Promise<number> override async insertOutputTag(tag: table.OutputTag, trx?: sdk.TrxToken): Promise<number> override async insertOutputTagMap(tagMap: table.OutputTagMap, trx?: sdk.TrxToken): Promise<void> override async insertTxLabel(label: table.TxLabel, trx?: sdk.TrxToken): Promise<number> override async insertTxLabelMap(labelMap: table.TxLabelMap, trx?: sdk.TrxToken): Promise<void> override async insertMonitorEvent(event: table.MonitorEvent, trx?: sdk.TrxToken): Promise<number> override async insertSyncState(syncState: table.SyncState, trx?: sdk.TrxToken): Promise<number> override async updateCertificateField(certificateId: number, fieldName: string, update: Partial<table.CertificateField>, trx?: sdk.TrxToken): Promise<number> override async updateCertificate(id: number, update: Partial<table.Certificate>, trx?: sdk.TrxToken): Promise<number> override async updateCommission(id: number, update: Partial<table.Commission>, trx?: sdk.TrxToken): Promise<number> override async updateOutputBasket(id: number, update: Partial<table.OutputBasket>, trx?: sdk.TrxToken): Promise<number> override async updateOutput(id: number, update: Partial<table.Output>, trx?: sdk.TrxToken): Promise<number> override async updateOutputTagMap(outputId: number, tagId: number, update: Partial<table.OutputTagMap>, trx?: sdk.TrxToken): Promise<number> override async updateOutputTag(id: number, update: Partial<table.OutputTag>, trx?: sdk.TrxToken): Promise<number> override async updateProvenTxReq(id: number | number[], update: Partial<table.ProvenTxReq>, trx?: sdk.TrxToken): Promise<number> override async updateProvenTx(id: number, update: Partial<table.ProvenTx>, trx?: sdk.TrxToken): Promise<number> override async updateSyncState(id: number, update: Partial<table.SyncState>, trx?: sdk.TrxToken): Promise<number> override async updateTransaction(id: number | number[], update: Partial<table.Transaction>, trx?: sdk.TrxToken): Promise<number> override async updateTxLabelMap(transactionId: number, txLabelId: number, update: Partial<table.TxLabelMap>, trx?: sdk.TrxToken): Promise<number> override async updateTxLabel(id: number, update: Partial<table.TxLabel>, trx?: sdk.TrxToken): Promise<number> override async updateUser(id: number, update: Partial<table.User>, trx?: sdk.TrxToken): Promise<number> override async updateMonitorEvent(id: number, update: Partial<table.MonitorEvent>, trx?: sdk.TrxToken): Promise<number> setupQuery<T extends object>(table: string, args: sdk.FindPartialSincePagedArgs<T>): Knex.QueryBuilder findCertificateFieldsQuery(args: sdk.FindCertificateFieldsArgs): Knex.QueryBuilder findCertificatesQuery(args: sdk.FindCertificatesArgs): Knex.QueryBuilder findCommissionsQuery(args: sdk.FindCommissionsArgs): Knex.QueryBuilder findOutputBasketsQuery(args: sdk.FindOutputBasketsArgs): Knex.QueryBuilder findOutputsQuery(args: sdk.FindOutputsArgs, count?: boolean): Knex.QueryBuilder findOutputTagMapsQuery(args: sdk.FindOutputTagMapsArgs): Knex.QueryBuilder findOutputTagsQuery(args: sdk.FindOutputTagsArgs): Knex.QueryBuilder findProvenTxReqsQuery(args: sdk.FindProvenTxReqsArgs): Knex.QueryBuilder findProvenTxsQuery(args: sdk.FindProvenTxsArgs): Knex.QueryBuilder findSyncStatesQuery(args: sdk.FindSyncStatesArgs): Knex.QueryBuilder findTransactionsQuery(args: sdk.FindTransactionsArgs, count?: boolean): Knex.QueryBuilder findTxLabelMapsQuery(args: sdk.FindTxLabelMapsArgs): Knex.QueryBuilder findTxLabelsQuery(args: sdk.FindTxLabelsArgs): Knex.QueryBuilder findUsersQuery(args: sdk.FindUsersArgs): Knex.QueryBuilder findMonitorEventsQuery(args: sdk.FindMonitorEventsArgs): Knex.QueryBuilder override async findCertificatesAuth(auth: sdk.AuthId, args: sdk.FindCertificatesArgs): Promise<table.Certificate[]> override async findOutputBasketsAuth(auth: sdk.AuthId, args: sdk.FindOutputBasketsArgs): Promise<table.OutputBasket[]> override async findOutputsAuth(auth: sdk.AuthId, args: sdk.FindOutputsArgs): Promise<table.Output[]> override async findCertificateFields(args: sdk.FindCertificateFieldsArgs): Promise<table.CertificateField[]> override async findCertificates(args: sdk.FindCertificatesArgs): Promise<table.Certificate[]> override async findCommissions(args: sdk.FindCommissionsArgs): Promise<table.Commission[]> override async findOutputBaskets(args: sdk.FindOutputBasketsArgs): Promise<table.OutputBasket[]> override async findOutputs(args: sdk.FindOutputsArgs): Promise<table.Output[]> override async findOutputTagMaps(args: sdk.FindOutputTagMapsArgs): Promise<table.OutputTagMap[]> override async findOutputTags(args: sdk.FindOutputTagsArgs): Promise<table.OutputTag[]> override async findProvenTxReqs(args: sdk.FindProvenTxReqsArgs): Promise<table.ProvenTxReq[]> override async findProvenTxs(args: sdk.FindProvenTxsArgs): Promise<table.ProvenTx[]> override async findSyncStates(args: sdk.FindSyncStatesArgs): Promise<table.SyncState[]> override async findTransactions(args: sdk.FindTransactionsArgs): Promise<table.Transaction[]> override async findTxLabelMaps(args: sdk.FindTxLabelMapsArgs): Promise<table.TxLabelMap[]> override async findTxLabels(args: sdk.FindTxLabelsArgs): Promise<table.TxLabel[]> override async findUsers(args: sdk.FindUsersArgs): Promise<table.User[]> override async findMonitorEvents(args: sdk.FindMonitorEventsArgs): Promise<table.MonitorEvent[]> async getCount<T extends object>(q: Knex.QueryBuilder<T, T[]>): Promise<number> override async countCertificateFields(args: sdk.FindCertificateFieldsArgs): Promise<number> override async countCertificates(args: sdk.FindCertificatesArgs): Promise<number> override async countCommissions(args: sdk.FindCommissionsArgs): Promise<number> override async countOutputBaskets(args: sdk.FindOutputBasketsArgs): Promise<number> override async countOutputs(args: sdk.FindOutputsArgs): Promise<number> override async countOutputTagMaps(args: sdk.FindOutputTagMapsArgs): Promise<number> override async countOutputTags(args: sdk.FindOutputTagsArgs): Promise<number> override async countProvenTxReqs(args: sdk.FindProvenTxReqsArgs): Promise<number> override async countProvenTxs(args: sdk.FindProvenTxsArgs): Promise<number> override async countSyncStates(args: sdk.FindSyncStatesArgs): Promise<number> override async countTransactions(args: sdk.FindTransactionsArgs): Promise<number> override async countTxLabelMaps(args: sdk.FindTxLabelMapsArgs): Promise<number> override async countTxLabels(args: sdk.FindTxLabelsArgs): Promise<number> override async countUsers(args: sdk.FindUsersArgs): Promise<number> override async countMonitorEvents(args: sdk.FindMonitorEventsArgs): Promise<number> override async destroy(): Promise<void> override async migrate(storageName: string, storageIdentityKey: string): Promise<string> override async dropAllData(): Promise<void> override async transaction<T>(scope: (trx: sdk.TrxToken) => Promise<T>, trx?: sdk.TrxToken): Promise<T> toDb(trx?: sdk.TrxToken) async validateRawTransaction(t: table.Transaction, trx?: sdk.TrxToken): Promise<void> async validateOutputScript(o: table.Output, trx?: sdk.TrxToken): Promise<void> _verifiedReadyForDatabaseAccess: boolean = false; async verifyReadyForDatabaseAccess(trx?: sdk.TrxToken): Promise<DBType> validatePartialForUpdate<T extends sdk.EntityTimeStamp>(update: Partial<T>, dateFields?: string[], booleanFields?: string[]): Partial<T> async validateEntityForInsert<T extends sdk.EntityTimeStamp>(entity: T, trx?: sdk.TrxToken, dateFields?: string[], booleanFields?: string[]): Promise<any> override async getLabelsForTransactionId(transactionId?: number, trx?: sdk.TrxToken): Promise<table.TxLabel[]> async extendOutput(o: table.Output, includeBasket = false, includeTags = false, trx?: sdk.TrxToken): Promise<table.OutputX> override async getTagsForOutputId(outputId: number, trx?: sdk.TrxToken): Promise<table.OutputTag[]> override async purgeData(params: sdk.PurgeParams, trx?: sdk.TrxToken): Promise<sdk.PurgeResults> override async reviewStatus(args: { agedLimit: Date; trx?: sdk.TrxToken; }): Promise<{ log: string; }> async countChangeInputs(userId: number, basketId: number, excludeSending: boolean): Promise<number> async allocateChangeInput(userId: number, basketId: number, targetSatoshis: number, exactSatoshis: number | undefined, excludeSending: boolean, transactionId: number): Promise<table.Output | undefined> { const status: sdk.TransactionStatus[] = ["completed", "unproven"]; if (!excludeSending) status.push("sending"); const statusText = status.map(s => `'${s}'`).join(","); const r: table.Output | undefined = await this.knex.transaction(async (trx) => { const txStatusCondition = `AND (SELECT status FROM transactions WHERE outputs.transactionId = transactions.transactionId) in (${statusText})`; let outputId: number | undefined; const setOutputId = async (rawQuery: string): Promise<void> => { let oidr = await trx.raw(rawQuery); outputId = undefined; if (!oidr["outputId"] && oidr.length > 0) oidr = oidr[0]; if (!oidr["outputId"] && oidr.length > 0) oidr = oidr[0]; if (oidr["outputId"]) outputId = Number(oidr["outputId"]); }; if (exactSatoshis !== undefined) { await setOutputId(` SELECT outputId FROM outputs WHERE userId = ${userId} AND spendable = 1 AND basketId = ${basketId} ${txStatusCondition} AND satoshis = ${exactSatoshis} LIMIT 1; `); } if (outputId === undefined) { await setOutputId(` SELECT outputId FROM outputs WHERE userId = ${userId} AND spendable = 1 AND basketId = ${basketId} ${txStatusCondition} AND satoshis - ${targetSatoshis} = ( SELECT MIN(satoshis - ${targetSatoshis}) FROM outputs WHERE userId = ${userId} AND spendable = 1 AND basketId = ${basketId} ${txStatusCondition} AND satoshis - ${targetSatoshis} >= 0 ) LIMIT 1; `); } if (outputId === undefined) { await setOutputId(` SELECT outputId FROM outputs WHERE userId = ${userId} AND spendable = 1 AND basketId = ${basketId} ${txStatusCondition} AND satoshis - ${targetSatoshis} = ( SELECT MAX(satoshis - ${targetSatoshis}) FROM outputs WHERE userId = ${userId} AND spendable = 1 AND basketId = ${basketId} ${txStatusCondition} AND satoshis - ${targetSatoshis} < 0 ) LIMIT 1; `); } if (outputId === undefined) return undefined; await this.updateOutput(outputId, { spendable: false, spentBy: transactionId }, trx); const r = verifyTruthy(await this.findOutputById(outputId, trx)); return r; }); return r; } validateEntity<T extends sdk.EntityTimeStamp>(entity: T, dateFields?: string[], booleanFields?: string[]): T validateEntities<T extends sdk.EntityTimeStamp>(entities: T[], dateFields?: string[], booleanFields?: string[]): T[] } ``` See also: [AuthId](#interface-authid), [DBType](#type-dbtype), [EntityTimeStamp](#interface-entitytimestamp), [FindCertificateFieldsArgs](#interface-findcertificatefieldsargs), [FindCertificatesArgs](#interface-findcertificatesargs), [FindCommissionsArgs](#interface-findcommissionsargs), [FindForUserSincePagedArgs](#interface-findforusersincepagedargs), [FindMonitorEventsArgs](#interface-findmonitoreventsargs), [FindOutputBasketsArgs](#interface-findoutputbasketsargs), [FindOutputTagMapsArgs](#interface-findoutputtagmapsargs), [FindOutputTagsArgs](#interface-findoutputtagsargs), [FindOutputsArgs](#interface-findoutputsargs), [FindPartialSincePagedArgs](#interface-findpartialsincepagedargs), [FindProvenTxReqsArgs](#interface-findproventxreqsargs), [FindProvenTxsArgs](#interface-findproventxsargs), [FindSyncStatesArgs](#interface-findsyncstatesargs), [FindTransactionsArgs](#interface-findtransactionsargs), [FindTxLabelMapsArgs](#interface-findtxlabelmapsargs), [FindTxLabelsArgs](#interface-findtxlabelsargs), [FindUsersArgs](#interface-findusersargs), [ProvenOrRawTx](#interface-provenorrawtx), [PurgeParams](#interface-purgeparams), [PurgeResults](#interface-purgeresults), [StorageKnexOptions](#interface-storageknexoptions), [StorageProvider](#class-storageprovider), [TransactionStatus](#type-transactionstatus), [TrxToken](#interface-trxtoken), [ValidListActionsArgs](#interface-validlistactionsargs), [ValidListOutputsArgs](#interface-validlistoutputsargs), [WalletStorageProvider](#interface-walletstorageprovider), [listActions](#function-listactions), [listOutputs](#function-listoutputs), [log](#variable-log), [purgeData](#function-purgedata), [reviewStatus](#function-reviewstatus), [verifyTruthy](#function-verifytruthy) <details> <summary>Class StorageKnex Details</summary> #### Method allocateChangeInput Finds closest matching available change output to use as input for new transaction. Transactionally allocate the output such that ```ts async allocateChangeInput(userId: number, basketId: number, targetSatoshis: number, exactSatoshis: number | undefined, excludeSending: boolean, transactionId: number): Promise<table.Output | undefined> ``` #### Method countChangeInputs Finds closest matching available change output to use as input for new transaction. Transactionally allocate the output such that ```ts async countChangeInputs(userId: number, basketId: number, excludeSending: boolean): Promise<number> ``` #### Method toDb Convert the standard optional `TrxToken` parameter into either a direct knex database instance, or a Knex.Transaction as appropriate. ```ts toDb(trx?: sdk.TrxToken) ``` See also: [TrxToken](#interface-trxtoken) #### Method validateEntities Helper to force uniform behavior across database engines. Use to process all arrays of records with time stamps retreived from database. ```ts validateEntities<T extends sdk.EntityTimeStamp>(entities: T[], dateFields?: string[], booleanFields?: string[]): T[] ``` See also: [EntityTimeStamp](#interface-entitytimestamp) Returns input `entities` array with contained values validated. #### Method validateEntity Helper to force uniform behavior across database engines. Use to process all individual records with time stamps retreived from database. ```ts validateEntity<T extends sdk.EntityTimeStamp>(entity: T, dateFields?: string[], booleanFields?: string[]): T ``` See also: [EntityTimeStamp](#interface-entitytimestamp) #### Method validateEntityForInsert Helper to force uniform behavior across database engines. Use to process new entities being inserted into the database. ```ts async validateEntityForInsert<T extends sdk.EntityTimeStamp>(entity: T, trx?: sdk.TrxToken, dateFields?: string[], booleanFields?: string[]): Promise<any> ``` See also: [EntityTimeStamp](#interface-entitytimestamp), [TrxToken](#interface-trxtoken) #### Method validatePartialForUpdate Helper to force uniform behavior across database engines. Use to process the update template for entities being updated. ```ts validatePartialForUpdate<T extends sdk.EntityTimeStamp>(update: Partial<T>, dateFields?: string[], booleanFields?: string[]): Partial<T> ``` See also: [EntityTimeStamp](#interface-entitytimestamp) #### Method verifyReadyForDatabaseAccess Make sure database is ready for access: - dateScheme is known - foreign key constraints are enabled ```ts async verifyReadyForDatabaseAccess(trx?: sdk.TrxToken): Promise<DBType> ``` See also: [DBType](#type-dbtype), [TrxToken](#interface-trxtoken) </details> Links: [API](#api), [Interfaces](#interfaces), [Classes](#classes), [Functions](#functions), [Types](#types), [Variables](#variables) --- ### Class: StorageProvider ```ts export abstract class StorageProvider extends StorageReaderWriter implements sdk.WalletStorageProvider { isDirty = false; _services?: sdk.WalletServices; feeModel: sdk.StorageFeeModel; commissionSatoshis: number; commissionPubKeyHex?: PubKeyHex; maxRecursionDepth?: number; static defaultOptions() static createStorageBaseOptions(chain: sdk.Chain): StorageProviderOptions constructor(options: StorageProviderOptions) abstract reviewStatus(args: { agedLimit: Date; trx?: sdk.TrxToken; }): Promise<{ log: string; }>; abstract purgeData(params: sdk.PurgeParams, trx?: sdk.TrxToken): Promise<sdk.PurgeResults>; abstract allocateChangeInput(userId: number, basketId: number, targetSatoshis: number, exactSatoshis: number | undefined, excludeSending: boolean, transactionId: number): Promise<table.Output | undefined>; abstract getProvenOrRawTx(txid: string, trx?: sdk.TrxToken): Promise<sdk.ProvenOrRawTx>; abstract getRawTxOfKnownValidTransaction(txid?: string, offset?: number, length?: number, trx?: sdk.TrxToken): Promise<number[] | undefined>; abstract getLabelsForTransactionId(transactionId?: number, trx?: sdk.TrxToken): Promise<table.TxLabel[]>; abstract getTagsForOutputId(outputId: number, trx?: sdk.TrxToken): Promise<table.OutputTag[]>; abstract listActions(auth: sdk.AuthId, args: sdk.ValidListActionsArgs): Promise<ListActionsResult>; abstract listOutputs(auth: sdk.AuthId, args: sdk.ValidListOutputsArgs): Promise<ListOutputsResult>; abstract countChangeInputs(userId: number, basketId: number, excludeSending: boolean): Promise<number>; abstract findCertificatesAuth(auth: sdk.AuthId, args: sdk.FindCertificatesArgs): Promise<table.Certificate[]>; abstract findOutputBasketsAuth(auth: sdk.AuthId, args: sdk.FindOutputBasketsArgs): Promise<table.OutputBasket[]>; abstract findOutputsAuth(auth: sdk.AuthId, args: sdk.FindOutputsArgs): Promise<table.Output[]>; abstract insertCertificateAuth(auth: sdk.AuthId, certificate: table.CertificateX): Promise<number>; override isStorageProvider(): boolean setServices(v: sdk.WalletServices) getServices(): sdk.WalletServices async abortAction(auth: sdk.AuthId, args: Partial<table.Transaction>): Promise<AbortActionResult> async internalizeAction(auth: sdk.AuthId, args: InternalizeActionArgs): Promise<InternalizeActionResult> async getReqsAndBeefToShareWithWorld(txids: string[], knownTxids: string[], trx?: sdk.TrxToken): Promise<GetReqsAndBeefResult> async mergeReqToBeefToShareExternally(req: table.ProvenTxReq, mergeToBeef: Beef, knownTxids: string[], trx?: sdk.TrxToken): Promise<void> async getProvenOrReq(txid: string, newReq?: table.ProvenTxReq, trx?: sdk.TrxToken): Promise<sdk.StorageProvenOrReq> async updateTransactionsStatus(transactionIds: number[], status: sdk.TransactionStatus): Promise<void> async updateTransactionStatus(status: sdk.TransactionStatus, transactionId?: number, userId?: number, reference?: string, trx?: sdk.TrxToken): Promise<void> async createAction(auth: sdk.AuthId, args: sdk.ValidCreateActionArgs): Promise<sdk.StorageCreateActionResult> async processAction(auth: sdk.AuthId, args: sdk.StorageProcessActionArgs): Promise<sdk.StorageProcessActionResults> async attemptToPostReqsToNetwork(reqs: entity.ProvenTxReq[], trx?: sdk.TrxToken): Promise<PostReqsToNetworkResult> async listCertificates(auth: sdk.AuthId, args: sdk.ValidListCertificatesArgs): Promise<ListCertificatesResult> async verifyKnownValidTransaction(txid: string, trx?: sdk.TrxToken): Promise<boolean> async getValidBeefForKnownTxid(txid: string, mergeToBeef?: Beef, trustSelf?: TrustSelf, knownTxids?: string[], trx?: sdk.TrxToken): Promise<Beef> async getValidBeefForTxid(txid: string, mergeToBeef?: Beef, trustSelf?: TrustSelf, knownTxids?: string[], trx?: sdk.TrxToken): Promise<Beef | undefined> async getBeefForTransaction(txid: string, options: sdk.StorageGetBeefOptions): Promise<Beef> async findMonitorEventById(id: number, trx?: sdk.TrxToken): Promise<table.MonitorEvent | undefined> async relinquishCertificate(auth: sdk.AuthId, args: RelinquishCertificateArgs): Promise<number> async relinquishOutput(auth: sdk.AuthId, args: RelinquishOutputArgs): Promise<number> async processSyncChunk(args: sdk.RequestSyncChunkArgs, chunk: sdk.SyncChunk): Promise<sdk.ProcessSyncChunkResult> async updateProvenTxReqWithNewProvenTx(args: sdk.UpdateProvenTxReqWithNewProvenTxArgs): Promise<sdk.UpdateProvenTxReqWithNewProvenTxResult> async confirmSpendableOutputs(): Promise<{ invalidSpendableOutputs: table.Output[]; }> async updateProvenTxReqDynamics(id: number, update: Partial<table.ProvenTxReqDynamics>, trx?: sdk.TrxToken): Promise<number> } ``` See also: [AuthId](#interface-authid), [Chain](#type-chain), [FindCertificatesArgs](#interface-findcertificatesargs), [FindOutputBasketsArgs](#interface-findoutputbasketsargs), [FindOutputsArgs](#interface-findoutputsargs), [GetReqsAndBeefResult](#interface-getreqsandbeefresult), [PostReqsToNetworkResult](#interface-postreqstonetworkresult), [ProcessSyncChunkResult](#interface-processsyncchunkresult), [ProvenOrRawTx](#interface-provenorrawtx), [PurgeParams](#interface-purgeparams), [PurgeResults](#interface-purgeresults), [RequestSyncChunkArgs](#interface-requestsyncchunkargs), [StorageCreateActionResult](#interface-storagecreateactionresult), [StorageFeeModel](#interface-storagefeemodel), [StorageGetBeefOptions](#interface-storagegetbeefoptions), [StorageProcessActionArgs](#interface-storageprocessactionargs), [StorageProcessActionResults](#interface-storageprocessactionresults), [StorageProvenOrReq](#interface-storageprovenorreq), [StorageProviderOptions](#interface-storageprovideroptions), [StorageReaderWriter](#class-storagereaderwriter), [SyncChunk](#interface-syncchunk), [TransactionStatus](#type-transactionstatus), [TrxToken](#interface-trxtoken), [UpdateProvenTxReqWithNewProvenTxArgs](#interface-updateproventxreqwithnewproventxargs), [UpdateProvenTxReqWithNewProvenTxResult](#interface-updateproventxreqwithnewproventxresult), [ValidCreateActionArgs](#interface-validcreateactionargs), [ValidListActionsArgs](#interface-validlistactionsargs), [ValidListCertificatesArgs](#interface-validlistcertificatesargs), [ValidListOutputsArgs](#interface-validlistoutputsargs), [WalletServices](#interface-walletservices), [WalletStorageProvider](#interface-walletstorageprovider), [attemptToPostReqsToNetwork](#function-attempttopostreqstonetwork), [createAction](#function-createaction), [getBeefForTransaction](#function-getbeeffortransaction), [internalizeAction](#function-internalizeaction), [listActions](#function-listactions), [listCertificates](#function-listcertificates), [listOutputs](#function-listoutputs), [log](#variable-log), [processAction](#function-processaction), [purgeData](#function-purgedata), [reviewStatus](#function-reviewstatus) <details> <summary>Class StorageProvider Details</summary> #### Method confirmSpendableOutputs For each spendable output in the 'default' basket of the authenticated user, verify that the output script, satoshis, vout and txid match that of an output still in the mempool of at least one service provider. ```ts async confirmSpendableOutputs(): Promise<{ invalidSpendableOutputs: table.Output[]; }> ``` Returns object with invalidSpendableOutputs array. A good result is an empty array. #### Method getProvenOrReq Checks if txid is a known valid ProvenTx and returns it if found. Next checks if txid is a current ProvenTxReq and returns that if found. If `newReq` is provided and an existing ProvenTxReq isn't found, use `newReq` to create a new ProvenTxReq. This is safe "findOrInsert" operation using retry if unique index constraint is violated by a race condition insert. ```ts async getProvenOrReq(txid: string, newReq?: table.ProvenTxReq, trx?: sdk.TrxToken): Promise<sdk.StorageProvenOrReq> ``` See also: [StorageProvenOrReq](#interface-storageprovenorreq), [TrxToken](#interface-trxtoken) #### Method getReqsAndBeefToShareWithWorld Given an array of transaction txids with current ProvenTxReq ready-to-share status, lookup their DojoProvenTxReqApi req records. For the txids with reqs and status still ready to send construct a single merged beef. ```ts async getReqsAndBeefToShareWithWorld(txids: string[], knownTxids: string[], trx?: sdk.TrxToken): Promise<GetReqsAndBeefResult> ``` See also: [GetReqsAndBeefResult](#interface-getreqsandbeefresult), [TrxToken](#interface-trxtoken) #### Method updateProvenTxReqWithNewProvenTx Handles storage changes when a valid MerklePath and mined block header are found for a ProvenTxReq txid. Performs the following storage updates (typically): 1. Lookup the exising `ProvenTxReq` record for its rawTx 2. Insert a new ProvenTx record using properties from `args` and rawTx, yielding a new provenTxId 3. Update ProvenTxReq record with status 'completed' and new provenTxId value (and history of status changed) 4. Unpack notify transactionIds from req and update each transaction's status to 'completed', provenTxId value. 5. Update ProvenTxReq history again to record that transactions have been notified. 6. Return results... Alterations of "typically" to handle: ```ts async updateProvenTxReqWithNewProvenTx(args: sdk.UpdateProvenTxReqWithNewProvenTxArgs): Promise<sdk.UpdateProvenTxReqWithNewProvenTxResult> ``` See also: [UpdateProvenTxReqWithNewProvenTxArgs](#interface-updateproventxreqwithnewproventxargs), [UpdateProvenTxReqWithNewProvenTxResult](#interface-updateproventxreqwithnewproventxresult) #### Method updateTransactionStatus For all `status` values besides 'failed', just updates the transaction records status property. For 'status' of 'failed', attempts to make outputs previously allocated as inputs to this transaction usable again. ```ts async updateTransactionStatus(status: sdk.TransactionStatus, transactionId?: number, userId?: number, reference?: string, trx?: sdk.TrxToken): Promise<void> ``` See also: [TransactionStatus](#type-transactionstatus), [TrxToken](#interface-trxtoken) Throws ERR_DOJO_COMPLETED_TX if current status is 'comple