@arkade-os/sdk 0.4.23 → 0.4.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -1
- package/dist/cjs/contracts/contractManager.js +66 -5
- package/dist/cjs/contracts/contractWatcher.js +9 -3
- package/dist/cjs/contracts/handlers/default.js +3 -2
- package/dist/cjs/contracts/handlers/delegate.js +3 -2
- package/dist/cjs/contracts/handlers/helpers.js +2 -58
- package/dist/cjs/contracts/handlers/vhtlc.js +7 -6
- package/dist/cjs/contracts/vtxoOwnership.js +78 -0
- package/dist/cjs/index.js +3 -3
- package/dist/cjs/repositories/inMemory/walletRepository.js +35 -0
- package/dist/cjs/repositories/indexedDB/walletRepository.js +117 -0
- package/dist/cjs/repositories/realm/walletRepository.js +28 -0
- package/dist/cjs/repositories/sqlite/walletRepository.js +23 -0
- package/dist/cjs/script/base.js +12 -47
- package/dist/cjs/script/tapscript.js +97 -73
- package/dist/cjs/utils/timelock.js +59 -0
- package/dist/cjs/utils/unknownFields.js +2 -39
- package/dist/cjs/wallet/serviceWorker/wallet-message-handler.js +71 -10
- package/dist/cjs/wallet/serviceWorker/wallet.js +10 -0
- package/dist/cjs/wallet/unroll.js +79 -67
- package/dist/cjs/wallet/vtxo-manager.js +112 -16
- package/dist/cjs/wallet/wallet.js +64 -8
- package/dist/cjs/worker/expo/processors/contractPollProcessor.js +7 -2
- package/dist/esm/contracts/contractManager.js +66 -5
- package/dist/esm/contracts/contractWatcher.js +9 -3
- package/dist/esm/contracts/handlers/default.js +2 -1
- package/dist/esm/contracts/handlers/delegate.js +2 -1
- package/dist/esm/contracts/handlers/helpers.js +1 -22
- package/dist/esm/contracts/handlers/vhtlc.js +2 -1
- package/dist/esm/contracts/vtxoOwnership.js +69 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/repositories/inMemory/walletRepository.js +35 -0
- package/dist/esm/repositories/indexedDB/walletRepository.js +117 -0
- package/dist/esm/repositories/realm/walletRepository.js +28 -0
- package/dist/esm/repositories/sqlite/walletRepository.js +23 -0
- package/dist/esm/script/base.js +12 -14
- package/dist/esm/script/tapscript.js +97 -40
- package/dist/esm/utils/timelock.js +22 -0
- package/dist/esm/utils/unknownFields.js +2 -6
- package/dist/esm/wallet/serviceWorker/wallet-message-handler.js +71 -10
- package/dist/esm/wallet/serviceWorker/wallet.js +10 -0
- package/dist/esm/wallet/unroll.js +78 -67
- package/dist/esm/wallet/vtxo-manager.js +112 -16
- package/dist/esm/wallet/wallet.js +62 -6
- package/dist/esm/worker/expo/processors/contractPollProcessor.js +7 -2
- package/dist/types/contracts/contractManager.d.ts +17 -1
- package/dist/types/contracts/handlers/helpers.d.ts +0 -9
- package/dist/types/contracts/vtxoOwnership.d.ts +33 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/repositories/inMemory/walletRepository.d.ts +4 -1
- package/dist/types/repositories/indexedDB/walletRepository.d.ts +4 -1
- package/dist/types/repositories/realm/walletRepository.d.ts +4 -1
- package/dist/types/repositories/sqlite/walletRepository.d.ts +4 -1
- package/dist/types/repositories/walletRepository.d.ts +21 -0
- package/dist/types/script/tapscript.d.ts +4 -0
- package/dist/types/utils/timelock.d.ts +9 -0
- package/dist/types/wallet/serviceWorker/wallet-message-handler.d.ts +14 -2
- package/dist/types/wallet/unroll.d.ts +10 -0
- package/dist/types/wallet/vtxo-manager.d.ts +32 -5
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { warnAndFilterVtxosForScript, saveVtxosForContract, } from '../../../contracts/vtxoOwnership.js';
|
|
1
2
|
export const CONTRACT_POLL_TASK_TYPE = "contract-poll";
|
|
2
3
|
/**
|
|
3
4
|
* Polls the indexer for the latest VTXO state of every contract and
|
|
@@ -40,8 +41,12 @@ export const contractPollProcessor = {
|
|
|
40
41
|
hasMore = page ? vtxos.length === pageSize : false;
|
|
41
42
|
pageIndex++;
|
|
42
43
|
}
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
// Skip wrong-script rows (legacy duplicates or indexer drift)
|
|
45
|
+
// before persisting; the loop must keep going for the remaining
|
|
46
|
+
// contracts even when one row is rejected.
|
|
47
|
+
const filtered = warnAndFilterVtxosForScript(allVtxos, contract.script, "contractPollProcessor");
|
|
48
|
+
await saveVtxosForContract(walletRepository, contract, filtered);
|
|
49
|
+
vtxosSaved += filtered.length;
|
|
45
50
|
contractsProcessed++;
|
|
46
51
|
}
|
|
47
52
|
return {
|
|
@@ -2,7 +2,7 @@ import { IndexerProvider } from "../providers/indexer";
|
|
|
2
2
|
import { WalletRepository } from "../repositories/walletRepository";
|
|
3
3
|
import { Contract, ContractEventCallback, ContractState, ContractWithVtxos, GetContractsFilter, PathSelection } from "./types";
|
|
4
4
|
import { ContractWatcherConfig } from "./contractWatcher";
|
|
5
|
-
import { ExtendedVirtualCoin, VirtualCoin } from "../wallet";
|
|
5
|
+
import { ExtendedVirtualCoin, Outpoint, VirtualCoin } from "../wallet";
|
|
6
6
|
import { ContractRepository } from "../repositories";
|
|
7
7
|
export type RefreshVtxosOptions = {
|
|
8
8
|
scripts?: string[];
|
|
@@ -88,6 +88,21 @@ export interface IContractManager extends Disposable {
|
|
|
88
88
|
* With options, narrows the refresh to specific scripts and/or a time window.
|
|
89
89
|
*/
|
|
90
90
|
refreshVtxos(opts?: RefreshVtxosOptions): Promise<void>;
|
|
91
|
+
/**
|
|
92
|
+
* Reconcile specific outpoints with the indexer's authoritative state and
|
|
93
|
+
* upsert the result into the wallet repository.
|
|
94
|
+
*
|
|
95
|
+
* The cursor-derived delta sync filters by `created_at`, so a VTXO that
|
|
96
|
+
* was created before the cursor but spent recently won't surface in a
|
|
97
|
+
* standard `refreshVtxos()` call. This method is the surgical recovery
|
|
98
|
+
* path for that case: when something hands us a stale outpoint (e.g. the
|
|
99
|
+
* server returns `VTXO_ALREADY_SPENT` with a `vtxo_outpoint` in its
|
|
100
|
+
* error metadata), call this to pull the latest state and unblock the
|
|
101
|
+
* caller — no full re-scan, no cursor change.
|
|
102
|
+
*
|
|
103
|
+
* Outpoints not owned by any tracked contract are silently dropped.
|
|
104
|
+
*/
|
|
105
|
+
refreshOutpoints(outpoints: Outpoint[]): Promise<void>;
|
|
91
106
|
/**
|
|
92
107
|
* Whether the underlying watcher is currently active.
|
|
93
108
|
*/
|
|
@@ -310,6 +325,7 @@ export declare class ContractManager implements IContractManager {
|
|
|
310
325
|
* Subset refreshes (scripts filter) intentionally do not advance the cursor.
|
|
311
326
|
*/
|
|
312
327
|
refreshVtxos(opts?: RefreshVtxosOptions): Promise<void>;
|
|
328
|
+
refreshOutpoints(outpoints: Outpoint[]): Promise<void>;
|
|
313
329
|
/**
|
|
314
330
|
* Check if currently watching.
|
|
315
331
|
*/
|
|
@@ -1,13 +1,4 @@
|
|
|
1
|
-
import { RelativeTimelock } from "../../script/tapscript";
|
|
2
1
|
import { Contract, PathContext } from "../types";
|
|
3
|
-
/**
|
|
4
|
-
* Convert RelativeTimelock to BIP68 sequence number.
|
|
5
|
-
*/
|
|
6
|
-
export declare function timelockToSequence(timelock: RelativeTimelock): number;
|
|
7
|
-
/**
|
|
8
|
-
* Convert BIP68 sequence number back to RelativeTimelock.
|
|
9
|
-
*/
|
|
10
|
-
export declare function sequenceToTimelock(sequence: number): RelativeTimelock;
|
|
11
2
|
/**
|
|
12
3
|
* Resolve wallet's role from explicit role or by matching descriptor/pubkey.
|
|
13
4
|
*/
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { ExtendedVirtualCoin, VirtualCoin } from "../wallet";
|
|
2
|
+
import type { WalletRepository } from "../repositories/walletRepository";
|
|
3
|
+
import type { Contract } from "./types";
|
|
4
|
+
/**
|
|
5
|
+
* Tier 1 helpers that enforce VTXO ownership at call sites that already know
|
|
6
|
+
* the intended contract script. Address-keyed repositories may still hand back
|
|
7
|
+
* legacy duplicate rows under the wrong bucket; these helpers gate reads and
|
|
8
|
+
* writes so a wrong-script row never wins.
|
|
9
|
+
*
|
|
10
|
+
* `script` is the authoritative ownership key. Equality is strict: a missing
|
|
11
|
+
* or empty `vtxo.script` never matches.
|
|
12
|
+
*/
|
|
13
|
+
export declare function vtxoOutpoint(vtxo: Pick<VirtualCoin, "txid" | "vout">): string;
|
|
14
|
+
export declare function isVtxoForScript(vtxo: Pick<VirtualCoin, "script">, script: string): boolean;
|
|
15
|
+
export declare function filterVtxosForScript<T extends Pick<VirtualCoin, "script">>(vtxos: T[], script: string): T[];
|
|
16
|
+
/**
|
|
17
|
+
* Background/indexer sync flavour: drop wrong-script rows and log enough
|
|
18
|
+
* context to identify each rejection. Returns only matching rows so the
|
|
19
|
+
* caller can keep going.
|
|
20
|
+
*/
|
|
21
|
+
export declare function warnAndFilterVtxosForScript<T extends Pick<VirtualCoin, "txid" | "vout" | "script">>(vtxos: T[], script: string, context: string): T[];
|
|
22
|
+
/**
|
|
23
|
+
* User-initiated transaction/signing flavour: throw before persisting or
|
|
24
|
+
* signing inconsistent ownership state. Silently skipping here would hide a
|
|
25
|
+
* serious bug in the wallet's spend path.
|
|
26
|
+
*/
|
|
27
|
+
export declare function validateVtxosForScript(vtxos: Array<Pick<VirtualCoin, "txid" | "vout" | "script">>, script: string, context: string): void;
|
|
28
|
+
/**
|
|
29
|
+
* Tier 2 dispatch helpers: route to script-scoped repository methods when
|
|
30
|
+
* available, falling back to Tier 1 address-based filtering otherwise.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getVtxosForContract(repo: WalletRepository, contract: Pick<Contract, "script" | "address">): Promise<ExtendedVirtualCoin[]>;
|
|
33
|
+
export declare function saveVtxosForContract(repo: WalletRepository, contract: Pick<Contract, "script" | "address">, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -51,7 +51,7 @@ export * as asset from "./extension/asset";
|
|
|
51
51
|
import { ContractManager, ContractWatcher, contractHandlers, DefaultContractHandler, DelegateContractHandler, VHTLCContractHandler, encodeArkContract, decodeArkContract, contractFromArkContract, contractFromArkContractWithAddress, isArkContract } from "./contracts";
|
|
52
52
|
import type { Contract, ContractVtxo, ContractState, ContractEvent, ContractEventCallback, ContractBalance, ContractWithVtxos, ContractHandler, PathSelection, PathContext, ContractManagerConfig, CreateContractParams, ContractWatcherConfig, ParsedArkContract, DefaultContractParams, DelegateContractParams, VHTLCContractParams } from "./contracts";
|
|
53
53
|
import { IContractManager } from "./contracts/contractManager";
|
|
54
|
-
import { timelockToSequence, sequenceToTimelock } from "./
|
|
54
|
+
import { timelockToSequence, sequenceToTimelock } from "./utils/timelock";
|
|
55
55
|
import { closeDatabase, openDatabase } from "./repositories/indexedDB/manager";
|
|
56
56
|
import { WalletMessageHandler, WalletNotInitializedError, ReadonlyWalletError, DelegatorNotConfiguredError } from "./wallet/serviceWorker/wallet-message-handler";
|
|
57
57
|
import { MESSAGE_BUS_NOT_INITIALIZED, MessageBusNotInitializedError, ServiceWorkerTimeoutError } from "./worker/errors";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArkTransaction, ExtendedCoin, ExtendedVirtualCoin } from "../../wallet";
|
|
2
|
-
import { WalletRepository, WalletState } from "../walletRepository";
|
|
2
|
+
import { WalletRepository, WalletState, VtxoRepositoryKey } from "../walletRepository";
|
|
3
3
|
/**
|
|
4
4
|
* In-memory implementation of WalletRepository.
|
|
5
5
|
* Data is ephemeral and scoped to the instance.
|
|
@@ -13,6 +13,9 @@ export declare class InMemoryWalletRepository implements WalletRepository {
|
|
|
13
13
|
getVtxos(address: string): Promise<ExtendedVirtualCoin[]>;
|
|
14
14
|
saveVtxos(address: string, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
15
15
|
deleteVtxos(address: string): Promise<void>;
|
|
16
|
+
getVtxosForScript(script: string): Promise<ExtendedVirtualCoin[]>;
|
|
17
|
+
saveVtxosForScript(key: VtxoRepositoryKey, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
18
|
+
deleteVtxosForScript(script: string): Promise<void>;
|
|
16
19
|
getUtxos(address: string): Promise<ExtendedCoin[]>;
|
|
17
20
|
saveUtxos(address: string, utxos: ExtendedCoin[]): Promise<void>;
|
|
18
21
|
deleteUtxos(address: string): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ExtendedCoin, ExtendedVirtualCoin, ArkTransaction } from "../../wallet";
|
|
2
|
-
import { WalletRepository, WalletState } from "../walletRepository";
|
|
2
|
+
import { WalletRepository, WalletState, VtxoRepositoryKey } from "../walletRepository";
|
|
3
3
|
/**
|
|
4
4
|
* IndexedDB-based implementation of WalletRepository.
|
|
5
5
|
*/
|
|
@@ -13,6 +13,9 @@ export declare class IndexedDBWalletRepository implements WalletRepository {
|
|
|
13
13
|
getVtxos(address: string): Promise<ExtendedVirtualCoin[]>;
|
|
14
14
|
saveVtxos(address: string, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
15
15
|
deleteVtxos(address: string): Promise<void>;
|
|
16
|
+
getVtxosForScript(script: string): Promise<ExtendedVirtualCoin[]>;
|
|
17
|
+
saveVtxosForScript(key: VtxoRepositoryKey, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
18
|
+
deleteVtxosForScript(script: string): Promise<void>;
|
|
16
19
|
getUtxos(address: string): Promise<ExtendedCoin[]>;
|
|
17
20
|
saveUtxos(address: string, utxos: ExtendedCoin[]): Promise<void>;
|
|
18
21
|
deleteUtxos(address: string): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArkTransaction, ExtendedCoin, ExtendedVirtualCoin } from "../../wallet";
|
|
2
|
-
import { WalletRepository, WalletState } from "../walletRepository";
|
|
2
|
+
import { WalletRepository, WalletState, VtxoRepositoryKey } from "../walletRepository";
|
|
3
3
|
import { RealmLike } from "./types";
|
|
4
4
|
/**
|
|
5
5
|
* Realm-based implementation of WalletRepository.
|
|
@@ -20,6 +20,9 @@ export declare class RealmWalletRepository implements WalletRepository {
|
|
|
20
20
|
getVtxos(address: string): Promise<ExtendedVirtualCoin[]>;
|
|
21
21
|
saveVtxos(address: string, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
22
22
|
deleteVtxos(address: string): Promise<void>;
|
|
23
|
+
getVtxosForScript(script: string): Promise<ExtendedVirtualCoin[]>;
|
|
24
|
+
saveVtxosForScript(key: VtxoRepositoryKey, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
25
|
+
deleteVtxosForScript(script: string): Promise<void>;
|
|
23
26
|
getUtxos(address: string): Promise<ExtendedCoin[]>;
|
|
24
27
|
saveUtxos(address: string, utxos: ExtendedCoin[]): Promise<void>;
|
|
25
28
|
deleteUtxos(address: string): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ArkTransaction, ExtendedCoin, ExtendedVirtualCoin } from "../../wallet";
|
|
2
|
-
import { WalletRepository, WalletState } from "../walletRepository";
|
|
2
|
+
import { WalletRepository, WalletState, VtxoRepositoryKey } from "../walletRepository";
|
|
3
3
|
import { SQLExecutor } from "./types";
|
|
4
4
|
interface SQLiteWalletRepositoryOptions {
|
|
5
5
|
/** Table name prefix (default: "ark_") */
|
|
@@ -50,6 +50,9 @@ export declare class SQLiteWalletRepository implements WalletRepository {
|
|
|
50
50
|
getVtxos(address: string): Promise<ExtendedVirtualCoin[]>;
|
|
51
51
|
saveVtxos(address: string, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
52
52
|
deleteVtxos(address: string): Promise<void>;
|
|
53
|
+
getVtxosForScript(script: string): Promise<ExtendedVirtualCoin[]>;
|
|
54
|
+
saveVtxosForScript(key: VtxoRepositoryKey, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
55
|
+
deleteVtxosForScript(script: string): Promise<void>;
|
|
53
56
|
getUtxos(address: string): Promise<ExtendedCoin[]>;
|
|
54
57
|
saveUtxos(address: string, utxos: ExtendedCoin[]): Promise<void>;
|
|
55
58
|
deleteUtxos(address: string): Promise<void>;
|
|
@@ -20,6 +20,12 @@ export type CommitmentTxRecord = {
|
|
|
20
20
|
/** Creation timestamp in milliseconds. */
|
|
21
21
|
createdAt: number;
|
|
22
22
|
};
|
|
23
|
+
export interface VtxoRepositoryKey {
|
|
24
|
+
/** Authoritative ownership key. */
|
|
25
|
+
script: string;
|
|
26
|
+
/** Legacy storage bucket. Required by all current backends; throw if absent. */
|
|
27
|
+
address?: string;
|
|
28
|
+
}
|
|
23
29
|
export interface WalletRepository extends AsyncDisposable {
|
|
24
30
|
readonly version: 1;
|
|
25
31
|
/**
|
|
@@ -32,6 +38,21 @@ export interface WalletRepository extends AsyncDisposable {
|
|
|
32
38
|
saveVtxos(address: string, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
33
39
|
/** Delete stored virtual outputs for an address. */
|
|
34
40
|
deleteVtxos(address: string): Promise<void>;
|
|
41
|
+
/**
|
|
42
|
+
* Fetch stored virtual outputs for a script.
|
|
43
|
+
* @optional SDK backends implement this; custom backends fall back to Tier 1.
|
|
44
|
+
*/
|
|
45
|
+
getVtxosForScript?(script: string): Promise<ExtendedVirtualCoin[]>;
|
|
46
|
+
/**
|
|
47
|
+
* Save virtual outputs for a script.
|
|
48
|
+
* @optional SDK backends implement this; custom backends fall back to Tier 1.
|
|
49
|
+
*/
|
|
50
|
+
saveVtxosForScript?(key: VtxoRepositoryKey, vtxos: ExtendedVirtualCoin[]): Promise<void>;
|
|
51
|
+
/**
|
|
52
|
+
* Delete stored virtual outputs for a script.
|
|
53
|
+
* @optional SDK backends implement this; custom backends fall back to Tier 1.
|
|
54
|
+
*/
|
|
55
|
+
deleteVtxosForScript?(script: string): Promise<void>;
|
|
35
56
|
/** Fetch stored boarding inputs for an address. */
|
|
36
57
|
getUtxos(address: string): Promise<ExtendedCoin[]>;
|
|
37
58
|
/** Save boarding inputs for an address. */
|
|
@@ -90,6 +90,7 @@ export declare namespace CSVMultisigTapscript {
|
|
|
90
90
|
function decode(script: Uint8Array): Type;
|
|
91
91
|
/** Return true when the tapscript is a CSV multisig tapscript. */
|
|
92
92
|
function is(tapscript: ArkTapscript<any, any>): tapscript is Type;
|
|
93
|
+
function isScriptValid(script: Uint8Array): true | Error;
|
|
93
94
|
}
|
|
94
95
|
/**
|
|
95
96
|
* Combines a condition script with an exit closure. The resulting script requires
|
|
@@ -114,6 +115,7 @@ export declare namespace ConditionCSVMultisigTapscript {
|
|
|
114
115
|
function decode(script: Uint8Array): Type;
|
|
115
116
|
/** Return true when the tapscript is a condition + CSV multisig tapscript. */
|
|
116
117
|
function is(tapscript: ArkTapscript<any, any>): tapscript is Type;
|
|
118
|
+
function isScriptValid(script: Uint8Array): true | Error;
|
|
117
119
|
}
|
|
118
120
|
/**
|
|
119
121
|
* Combines a condition script with a forfeit closure. The resulting script requires
|
|
@@ -138,6 +140,7 @@ export declare namespace ConditionMultisigTapscript {
|
|
|
138
140
|
function decode(script: Uint8Array): Type;
|
|
139
141
|
/** Return true when the tapscript is a condition + multisig tapscript. */
|
|
140
142
|
function is(tapscript: ArkTapscript<any, any>): tapscript is Type;
|
|
143
|
+
function isScriptValid(script: Uint8Array): true | Error;
|
|
141
144
|
}
|
|
142
145
|
/**
|
|
143
146
|
* Implements an absolute timelock (CLTV) script combined with a forfeit closure.
|
|
@@ -162,4 +165,5 @@ export declare namespace CLTVMultisigTapscript {
|
|
|
162
165
|
function decode(script: Uint8Array): Type;
|
|
163
166
|
/** Return true when the tapscript is a CLTV multisig tapscript. */
|
|
164
167
|
function is(tapscript: ArkTapscript<any, any>): tapscript is Type;
|
|
168
|
+
function isScriptValid(script: Uint8Array): true | Error;
|
|
165
169
|
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { RelativeTimelock } from "../script/tapscript";
|
|
2
|
+
/**
|
|
3
|
+
* Convert RelativeTimelock to BIP68 sequence number.
|
|
4
|
+
*/
|
|
5
|
+
export declare function timelockToSequence(timelock: RelativeTimelock): number;
|
|
6
|
+
/**
|
|
7
|
+
* Convert BIP68 sequence number back to RelativeTimelock.
|
|
8
|
+
*/
|
|
9
|
+
export declare function sequenceToTimelock(sequence: number): RelativeTimelock;
|
|
@@ -259,6 +259,18 @@ export type RequestRefreshVtxos = RequestEnvelope & {
|
|
|
259
259
|
export type ResponseRefreshVtxos = ResponseEnvelope & {
|
|
260
260
|
type: "REFRESH_VTXOS_SUCCESS";
|
|
261
261
|
};
|
|
262
|
+
export type RequestRefreshOutpoints = RequestEnvelope & {
|
|
263
|
+
type: "REFRESH_OUTPOINTS";
|
|
264
|
+
payload: {
|
|
265
|
+
outpoints: {
|
|
266
|
+
txid: string;
|
|
267
|
+
vout: number;
|
|
268
|
+
}[];
|
|
269
|
+
};
|
|
270
|
+
};
|
|
271
|
+
export type ResponseRefreshOutpoints = ResponseEnvelope & {
|
|
272
|
+
type: "REFRESH_OUTPOINTS_SUCCESS";
|
|
273
|
+
};
|
|
262
274
|
export type RequestGetAllSpendingPaths = RequestEnvelope & {
|
|
263
275
|
type: "GET_ALL_SPENDING_PATHS";
|
|
264
276
|
payload: {
|
|
@@ -463,8 +475,8 @@ export type ResponseSweepExpiredBoardingUtxos = ResponseEnvelope & {
|
|
|
463
475
|
txid: string;
|
|
464
476
|
};
|
|
465
477
|
};
|
|
466
|
-
export type WalletUpdaterRequest = RequestInitWallet | RequestSettle | RequestSendBitcoin | RequestGetAddress | RequestGetBoardingAddress | RequestGetBalance | RequestGetVtxos | RequestGetBoardingUtxos | RequestGetTransactionHistory | RequestGetStatus | RequestClear | RequestReloadWallet | RequestSignTransaction | RequestCreateContract | RequestGetContracts | RequestGetContractsWithVtxos | RequestAnnotateVtxos | RequestUpdateContract | RequestDeleteContract | RequestGetSpendablePaths | RequestGetAllSpendingPaths | RequestIsContractManagerWatching | RequestRefreshVtxos | RequestSend | RequestGetAssetDetails | RequestIssue | RequestReissue | RequestBurn | RequestDelegate | RequestGetDelegateInfo | RequestRecoverVtxos | RequestGetRecoverableBalance | RequestGetExpiringVtxos | RequestRenewVtxos | RequestGetExpiredBoardingUtxos | RequestSweepExpiredBoardingUtxos;
|
|
467
|
-
export type WalletUpdaterResponse = ResponseEnvelope & (ResponseInitWallet | ResponseSettle | ResponseSettleEvent | ResponseSendBitcoin | ResponseGetAddress | ResponseGetBoardingAddress | ResponseGetBalance | ResponseGetVtxos | ResponseGetBoardingUtxos | ResponseGetTransactionHistory | ResponseGetStatus | ResponseClear | ResponseReloadWallet | ResponseUtxoUpdate | ResponseVtxoUpdate | ResponseSignTransaction | ResponseCreateContract | ResponseGetContracts | ResponseGetContractsWithVtxos | ResponseAnnotateVtxos | ResponseUpdateContract | ResponseDeleteContract | ResponseGetSpendablePaths | ResponseGetAllSpendingPaths | ResponseIsContractManagerWatching | ResponseRefreshVtxos | ResponseContractEvent | ResponseSend | ResponseGetAssetDetails | ResponseIssue | ResponseReissue | ResponseBurn | ResponseDelegate | ResponseGetDelegateInfo | ResponseRecoverVtxos | ResponseRecoverVtxosEvent | ResponseGetRecoverableBalance | ResponseGetExpiringVtxos | ResponseRenewVtxos | ResponseRenewVtxosEvent | ResponseGetExpiredBoardingUtxos | ResponseSweepExpiredBoardingUtxos);
|
|
478
|
+
export type WalletUpdaterRequest = RequestInitWallet | RequestSettle | RequestSendBitcoin | RequestGetAddress | RequestGetBoardingAddress | RequestGetBalance | RequestGetVtxos | RequestGetBoardingUtxos | RequestGetTransactionHistory | RequestGetStatus | RequestClear | RequestReloadWallet | RequestSignTransaction | RequestCreateContract | RequestGetContracts | RequestGetContractsWithVtxos | RequestAnnotateVtxos | RequestUpdateContract | RequestDeleteContract | RequestGetSpendablePaths | RequestGetAllSpendingPaths | RequestIsContractManagerWatching | RequestRefreshVtxos | RequestRefreshOutpoints | RequestSend | RequestGetAssetDetails | RequestIssue | RequestReissue | RequestBurn | RequestDelegate | RequestGetDelegateInfo | RequestRecoverVtxos | RequestGetRecoverableBalance | RequestGetExpiringVtxos | RequestRenewVtxos | RequestGetExpiredBoardingUtxos | RequestSweepExpiredBoardingUtxos;
|
|
479
|
+
export type WalletUpdaterResponse = ResponseEnvelope & (ResponseInitWallet | ResponseSettle | ResponseSettleEvent | ResponseSendBitcoin | ResponseGetAddress | ResponseGetBoardingAddress | ResponseGetBalance | ResponseGetVtxos | ResponseGetBoardingUtxos | ResponseGetTransactionHistory | ResponseGetStatus | ResponseClear | ResponseReloadWallet | ResponseUtxoUpdate | ResponseVtxoUpdate | ResponseSignTransaction | ResponseCreateContract | ResponseGetContracts | ResponseGetContractsWithVtxos | ResponseAnnotateVtxos | ResponseUpdateContract | ResponseDeleteContract | ResponseGetSpendablePaths | ResponseGetAllSpendingPaths | ResponseIsContractManagerWatching | ResponseRefreshVtxos | ResponseRefreshOutpoints | ResponseContractEvent | ResponseSend | ResponseGetAssetDetails | ResponseIssue | ResponseReissue | ResponseBurn | ResponseDelegate | ResponseGetDelegateInfo | ResponseRecoverVtxos | ResponseRecoverVtxosEvent | ResponseGetRecoverableBalance | ResponseGetExpiringVtxos | ResponseRenewVtxos | ResponseRenewVtxosEvent | ResponseGetExpiredBoardingUtxos | ResponseSweepExpiredBoardingUtxos);
|
|
468
480
|
export declare class WalletMessageHandler implements MessageHandler<WalletUpdaterRequest, WalletUpdaterResponse> {
|
|
469
481
|
readonly messageTag: string;
|
|
470
482
|
private wallet;
|
|
@@ -15,6 +15,7 @@ export declare namespace Unroll {
|
|
|
15
15
|
*/
|
|
16
16
|
type UnrollStep = {
|
|
17
17
|
tx: Transaction;
|
|
18
|
+
pkg: [parent: string, child: string];
|
|
18
19
|
};
|
|
19
20
|
/**
|
|
20
21
|
* Wait step where the transaction has to be confirmed onchain
|
|
@@ -102,3 +103,12 @@ export declare namespace Unroll {
|
|
|
102
103
|
*/
|
|
103
104
|
function completeUnroll(wallet: Wallet, vtxoTxids: string[], outputAddress: string): Promise<string>;
|
|
104
105
|
}
|
|
106
|
+
/**
|
|
107
|
+
* Prepares the transaction that spends the CSV path to complete unrolling a VTXO.
|
|
108
|
+
* @param wallet the wallet owning the VTXO(s)
|
|
109
|
+
* @param vtxoTxIds the txids of the VTXO(s) to complete unroll
|
|
110
|
+
* @param outputAddress the address to send the unrolled funds to
|
|
111
|
+
* @throws if the VTXO(s) are not fully unrolled, if the txids are not found, if the tx is not confirmed, if no exit path is found or not available
|
|
112
|
+
* @returns the transaction spending the unrolled funds
|
|
113
|
+
*/
|
|
114
|
+
export declare function prepareUnrollTransaction(wallet: Wallet, vtxoTxIds: string[], outputAddress: string): Promise<Transaction>;
|
|
@@ -410,13 +410,40 @@ export declare class VtxoManager implements AsyncDisposable, IVtxoManager {
|
|
|
410
410
|
/**
|
|
411
411
|
* VTXO_ALREADY_SPENT means the server's authoritative view of VTXO state
|
|
412
412
|
* is ahead of ours — cross-instance race, pre-lock snapshot drift, or an
|
|
413
|
-
* SSE gap left stale data in the local cache. Silent-swallowing
|
|
414
|
-
* the same error on the next cycle because nothing
|
|
415
|
-
*
|
|
416
|
-
*
|
|
417
|
-
*
|
|
413
|
+
* SSE gap left stale data in the local cache. Silent-swallowing
|
|
414
|
+
* guarantees the same error on the next cycle because nothing
|
|
415
|
+
* reconciles the cache.
|
|
416
|
+
*
|
|
417
|
+
* The cursor-derived delta sync filters by `created_at`, so a VTXO that
|
|
418
|
+
* was created before the cursor but spent recently can never be
|
|
419
|
+
* reconciled by `refreshVtxos()`. Use `refreshOutpoints` for surgical
|
|
420
|
+
* recovery: query the indexer for the specific stale outpoint and
|
|
421
|
+
* upsert its authoritative state into the wallet repository.
|
|
422
|
+
*
|
|
423
|
+
* Throttled because the same VTXO can fire repeatedly before the
|
|
424
|
+
* upsert observably propagates through the renewal selector.
|
|
418
425
|
*/
|
|
419
426
|
private maybeRefreshAfterVtxoSpent;
|
|
427
|
+
/**
|
|
428
|
+
* Extract the offending VTXO outpoint from a `VTXO_ALREADY_SPENT` error,
|
|
429
|
+
* if the server attached one in `metadata.vtxo_outpoint`. Returns
|
|
430
|
+
* `undefined` when the error isn't a parsed ArkError, isn't this code,
|
|
431
|
+
* or doesn't carry the metadata.
|
|
432
|
+
*/
|
|
433
|
+
private extractSpentOutpoint;
|
|
434
|
+
/**
|
|
435
|
+
* Reconcile the chosen VTXOs with the indexer's authoritative state
|
|
436
|
+
* before submitting a settle intent. Pulls the canonical record for
|
|
437
|
+
* each candidate outpoint via {@link IContractManager.refreshOutpoints}
|
|
438
|
+
* (which upserts the result into the wallet repository), then
|
|
439
|
+
* re-selects through the standard expiring-vtxo filter so anything
|
|
440
|
+
* the refresh flagged as spent is dropped.
|
|
441
|
+
*
|
|
442
|
+
* Best-effort: a failed refresh just falls back to the original
|
|
443
|
+
* candidates and lets the post-submit `VTXO_ALREADY_SPENT` recovery
|
|
444
|
+
* handle whatever slipped through.
|
|
445
|
+
*/
|
|
446
|
+
private revalidateBeforeSettle;
|
|
420
447
|
/** Computes the next poll delay, applying exponential backoff on failures. */
|
|
421
448
|
private getNextPollDelay;
|
|
422
449
|
/**
|