@arkade-os/sdk 0.5.0-rc.2 → 0.5.0-rc.21
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 +90 -83
- package/dist/adapters/expo.cjs +5 -6
- package/dist/adapters/expo.d.cts +4 -4
- package/dist/adapters/expo.d.ts +4 -4
- package/dist/adapters/expo.js +3 -4
- package/dist/{asyncStorageTaskQueue-C5rBYlru.d.ts → asyncStorageTaskQueue-aL7K14e4.d.ts} +2 -2
- package/dist/{asyncStorageTaskQueue-BuDvgWh6.d.cts → asyncStorageTaskQueue-x8ok3tJy.d.cts} +2 -2
- package/dist/{chunk-ISO4TI5J.js → chunk-4FDNOLBO.js} +566 -459
- package/dist/chunk-4FDNOLBO.js.map +1 -0
- package/dist/{chunk-JZWLXNHV.cjs → chunk-5XBH5SAL.cjs} +574 -464
- package/dist/chunk-5XBH5SAL.cjs.map +1 -0
- package/dist/{chunk-3R476TDV.js → chunk-CXHJGED6.js} +293 -1071
- package/dist/chunk-CXHJGED6.js.map +1 -0
- package/dist/{chunk-ZRNQV6HV.js → chunk-EXFU6MTA.js} +4578 -4396
- package/dist/chunk-EXFU6MTA.js.map +1 -0
- package/dist/{chunk-43FKNLX4.cjs → chunk-GVF4OCTL.cjs} +357 -1114
- package/dist/chunk-GVF4OCTL.cjs.map +1 -0
- package/dist/{chunk-HLCGYOIH.cjs → chunk-HIZNPHB2.cjs} +37 -36
- package/dist/chunk-HIZNPHB2.cjs.map +1 -0
- package/dist/{chunk-4PKLULWT.js → chunk-JZAEFOE4.js} +109 -246
- package/dist/chunk-JZAEFOE4.js.map +1 -0
- package/dist/{chunk-ZOTXDOS5.js → chunk-LNJPVLIC.js} +30 -29
- package/dist/chunk-LNJPVLIC.js.map +1 -0
- package/dist/{chunk-NVZJSKZS.cjs → chunk-Q7PC3NHX.cjs} +121 -257
- package/dist/chunk-Q7PC3NHX.cjs.map +1 -0
- package/dist/{chunk-GMZZQXV5.cjs → chunk-R5OFJ23O.cjs} +4961 -4767
- package/dist/chunk-R5OFJ23O.cjs.map +1 -0
- package/dist/{chunk-6DNR46C7.js → chunk-S2WWOVFC.js} +7 -5
- package/dist/chunk-S2WWOVFC.js.map +1 -0
- package/dist/{chunk-D25O4EGY.cjs → chunk-VZMLADXQ.cjs} +12 -10
- package/dist/chunk-VZMLADXQ.cjs.map +1 -0
- package/dist/contracts/handlers/index.cjs +9 -10
- package/dist/contracts/handlers/index.d.cts +5 -5
- package/dist/contracts/handlers/index.d.ts +5 -5
- package/dist/contracts/handlers/index.js +2 -3
- package/dist/{delegate-BAX5QftB.d.ts → delegate-BT5iON1T.d.ts} +1 -1
- package/dist/{delegate-1yp1HyP7.d.cts → delegate-u6kXTtWY.d.cts} +1 -1
- package/dist/index-BCnhItOQ.d.cts +639 -0
- package/dist/{index-DUxufw76.d.cts → index-CK5QbTmZ.d.cts} +1387 -2404
- package/dist/{index-DUxufw76.d.ts → index-CK5QbTmZ.d.ts} +1387 -2404
- package/dist/index-D1D4cR-G.d.ts +639 -0
- package/dist/index.cjs +375 -340
- package/dist/index.d.cts +784 -1197
- package/dist/index.d.ts +784 -1197
- package/dist/index.js +4 -5
- package/dist/repositories/realm/index.cjs +201 -106
- package/dist/repositories/realm/index.cjs.map +1 -1
- package/dist/repositories/realm/index.d.cts +28 -16
- package/dist/repositories/realm/index.d.ts +28 -16
- package/dist/repositories/realm/index.js +190 -95
- package/dist/repositories/realm/index.js.map +1 -1
- package/dist/repositories/sqlite/index.cjs +301 -189
- package/dist/repositories/sqlite/index.cjs.map +1 -1
- package/dist/repositories/sqlite/index.d.cts +32 -21
- package/dist/repositories/sqlite/index.d.ts +32 -21
- package/dist/repositories/sqlite/index.js +294 -182
- package/dist/repositories/sqlite/index.js.map +1 -1
- package/dist/{taskRunner-D_iPiZIi.d.ts → taskRunner-BeYR6NpQ.d.ts} +2 -2
- package/dist/{taskRunner-Dr3NStc0.d.cts → taskRunner-Csey3EYJ.d.cts} +2 -2
- package/dist/wallet/expo/background.cjs +14 -15
- package/dist/wallet/expo/background.cjs.map +1 -1
- package/dist/wallet/expo/background.d.cts +10 -16
- package/dist/wallet/expo/background.d.ts +10 -16
- package/dist/wallet/expo/background.js +6 -7
- package/dist/wallet/expo/background.js.map +1 -1
- package/dist/wallet/expo/index.cjs +16 -23
- package/dist/wallet/expo/index.cjs.map +1 -1
- package/dist/wallet/expo/index.d.cts +6 -9
- package/dist/wallet/expo/index.d.ts +6 -9
- package/dist/wallet/expo/index.js +8 -15
- package/dist/wallet/expo/index.js.map +1 -1
- package/dist/wallet-DG3Qmbmt.d.cts +1848 -0
- package/dist/wallet-DzSLMxBZ.d.ts +1848 -0
- package/dist/worker/expo/index.cjs +9 -10
- package/dist/worker/expo/index.cjs.map +1 -1
- package/dist/worker/expo/index.d.cts +6 -6
- package/dist/worker/expo/index.d.ts +6 -6
- package/dist/worker/expo/index.js +5 -6
- package/dist/worker/expo/index.js.map +1 -1
- package/package.json +12 -51
- package/dist/adapters/asyncStorage.cjs +0 -48
- package/dist/adapters/asyncStorage.cjs.map +0 -1
- package/dist/adapters/asyncStorage.d.cts +0 -16
- package/dist/adapters/asyncStorage.d.ts +0 -16
- package/dist/adapters/asyncStorage.js +0 -46
- package/dist/adapters/asyncStorage.js.map +0 -1
- package/dist/adapters/fileSystem.cjs +0 -116
- package/dist/adapters/fileSystem.cjs.map +0 -1
- package/dist/adapters/fileSystem.d.cts +0 -17
- package/dist/adapters/fileSystem.d.ts +0 -17
- package/dist/adapters/fileSystem.js +0 -93
- package/dist/adapters/fileSystem.js.map +0 -1
- package/dist/adapters/indexedDB.cjs +0 -103
- package/dist/adapters/indexedDB.cjs.map +0 -1
- package/dist/adapters/indexedDB.d.cts +0 -18
- package/dist/adapters/indexedDB.d.ts +0 -18
- package/dist/adapters/indexedDB.js +0 -101
- package/dist/adapters/indexedDB.js.map +0 -1
- package/dist/adapters/localStorage.cjs +0 -50
- package/dist/adapters/localStorage.cjs.map +0 -1
- package/dist/adapters/localStorage.d.cts +0 -14
- package/dist/adapters/localStorage.d.ts +0 -14
- package/dist/adapters/localStorage.js +0 -48
- package/dist/adapters/localStorage.js.map +0 -1
- package/dist/chunk-3R476TDV.js.map +0 -1
- package/dist/chunk-43FKNLX4.cjs.map +0 -1
- package/dist/chunk-4PKLULWT.js.map +0 -1
- package/dist/chunk-5BLDMQED.cjs +0 -18
- package/dist/chunk-5BLDMQED.cjs.map +0 -1
- package/dist/chunk-6DNR46C7.js.map +0 -1
- package/dist/chunk-D25O4EGY.cjs.map +0 -1
- package/dist/chunk-GMZZQXV5.cjs.map +0 -1
- package/dist/chunk-HLCGYOIH.cjs.map +0 -1
- package/dist/chunk-ISO4TI5J.js.map +0 -1
- package/dist/chunk-JZWLXNHV.cjs.map +0 -1
- package/dist/chunk-NSBPE2FW.js +0 -15
- package/dist/chunk-NSBPE2FW.js.map +0 -1
- package/dist/chunk-NVZJSKZS.cjs.map +0 -1
- package/dist/chunk-ZOTXDOS5.js.map +0 -1
- package/dist/chunk-ZRNQV6HV.js.map +0 -1
- package/dist/hdWalletCapable-CmEU0NP1.d.ts +0 -2232
- package/dist/hdWalletCapable-eJgaT-ec.d.cts +0 -2232
- package/dist/index-Bem5vKzX.d.ts +0 -850
- package/dist/index-C0IanN1m.d.cts +0 -11
- package/dist/index-C0IanN1m.d.ts +0 -11
- package/dist/index-W_oMcOmG.d.cts +0 -850
|
@@ -1,2232 +0,0 @@
|
|
|
1
|
-
import { w as RelativeTimelock, X as Network, Y as CSVMultisigTapscript, Z as BatchStartedEvent, _ as TreeSigningStartedEvent, $ as TxTree, a0 as TreeNoncesEvent, a1 as BatchFinalizationEvent, a2 as BatchFinalizedEvent, a3 as BatchFailedEvent, a4 as TreeTxEvent, a5 as TreeSignatureEvent, o as SettlementEvent, b as WalletConfig, W as WalletRepository, C as ContractRepository, a6 as DescriptorProvider, j as IContractManager, a7 as IReadonlyWallet, a8 as ReadonlyIdentity, a9 as OnchainProvider, u as ArkProvider, v as IndexerProvider, aa as DelegateProvider, ab as ReadonlyWalletConfig, J as IntentRepository, M as VirtualTxRepository, ac as ExitCaptureMode, ad as ExitDataSource, h as ActivityRegistry, ae as IReadonlyAssetManager, af as ContractSyncState, ag as RecipientArkadeAddressContext, G as GetArkadeInfoOptions, A as ArkadeInfo, c as ArkadeReader, ah as NetworkName, ai as ArkAddress, e as WalletBalance, f as GetVtxosFilter, N as NormalizedExtendedVirtualCoin, aj as ContractWithVtxos, ak as selectPendingRecoveryOutpoints, g as ArkTransaction, i as Activity, E as ExtendedCoin, al as Coin, B as ExtendedVirtualCoin, am as ContractManager, an as ContractManagerConfig, I as IWallet, a as Identity, k as GetNewAddressesOptions, l as NewAddress, ao as SettlementConfig, d as ArkadeBroadcaster, q as IAssetManager, ap as VtxoManager, m as IDelegateManager, S as SendBitcoinParams, n as SettleParams, R as Recipient, aq as SignerSession, ar as SignedIntent, as as Intent, p as SendParams, at as TimeHeight } from './index-DUxufw76.cjs';
|
|
2
|
-
import { Transaction } from '@scure/btc-signer';
|
|
3
|
-
import { TransactionOutput } from '@scure/btc-signer/psbt.js';
|
|
4
|
-
import { Bytes } from '@scure/btc-signer/utils.js';
|
|
5
|
-
import { D as DefaultVtxo, a as DelegateVtxo } from './delegate-1yp1HyP7.cjs';
|
|
6
|
-
|
|
7
|
-
/** Wall-clock floor for `batchExpiry` outside regtest. */
|
|
8
|
-
declare const DEFAULT_MIN_BATCH_EXPIRY_SECONDS = 86400n;
|
|
9
|
-
/** Wall-clock floor for `batchExpiry` on regtest (~10 blocks). */
|
|
10
|
-
declare const REGTEST_MIN_BATCH_EXPIRY_SECONDS = 6000n;
|
|
11
|
-
/** Bounds applied to a server-supplied `BatchStartedEvent.batchExpiry`. */
|
|
12
|
-
type BatchExpiryPolicy = {
|
|
13
|
-
/** Minimum wall-clock delay in seconds, after normalization. */
|
|
14
|
-
minSeconds: bigint;
|
|
15
|
-
/**
|
|
16
|
-
* Reject block-typed timelocks. Mirrors arkd, which allows a block-typed
|
|
17
|
-
* vtxo tree expiry only on regtest.
|
|
18
|
-
*/
|
|
19
|
-
requireSeconds: boolean;
|
|
20
|
-
/** When advertised by the operator, `batchExpiry` must equal it exactly. */
|
|
21
|
-
advertisedVtxoTreeExpiry?: bigint;
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Default policy for a network.
|
|
25
|
-
*
|
|
26
|
-
* Derive it from the locally held {@link Network} — pinned at wallet setup —
|
|
27
|
-
* rather than from a per-round server field, so the permissive regtest branch
|
|
28
|
-
* can't be selected by the operator at event time.
|
|
29
|
-
*/
|
|
30
|
-
declare function defaultBatchExpiryPolicy(network: Network): BatchExpiryPolicy;
|
|
31
|
-
/** Resolve a policy for `network`, applying any caller overrides on top. */
|
|
32
|
-
declare function resolveBatchExpiryPolicy(network: Network, overrides?: Partial<BatchExpiryPolicy>): BatchExpiryPolicy;
|
|
33
|
-
/**
|
|
34
|
-
* Check a server-supplied batch expiry against `policy` and return the timelock
|
|
35
|
-
* to commit to.
|
|
36
|
-
*
|
|
37
|
-
* The sweep leaf of the shared batch output is derived from this value, so it
|
|
38
|
-
* is never reconstructible from anything else the server sends: validating the
|
|
39
|
-
* tree only proves it is consistent with whatever value was chosen. Callers
|
|
40
|
-
* must encode the returned timelock rather than re-deriving their own.
|
|
41
|
-
*
|
|
42
|
-
* @throws {ServerResponseMismatchError} if the value is out of policy.
|
|
43
|
-
*/
|
|
44
|
-
declare function assertValidBatchExpiry(batchExpiry: bigint, policy: BatchExpiryPolicy): RelativeTimelock;
|
|
45
|
-
|
|
46
|
-
/** Wall-clock floor for the checkpoint exit delay outside regtest. Matches arkd's own default. */
|
|
47
|
-
declare const DEFAULT_MIN_CHECKPOINT_EXIT_DELAY_SECONDS = 86400n;
|
|
48
|
-
/**
|
|
49
|
-
* Wall-clock floor for the checkpoint exit delay on regtest (~2 blocks nominal).
|
|
50
|
-
*
|
|
51
|
-
* Deliberately lower than {@link REGTEST_MIN_BATCH_EXPIRY_SECONDS "../wallet/batchExpiry"} — it
|
|
52
|
-
* was sized to clear an `ARKD_CHECKPOINT_EXIT_DELAY` of 5 blocks while still rejecting a 1-block
|
|
53
|
-
* attack. No env in this repo goes below 20 any more (the 5-block one shipped with the removed
|
|
54
|
-
* boltz-swap package), so there is room to tighten this; left as-is until someone confirms no
|
|
55
|
-
* external regtest deployment relies on the lower bound.
|
|
56
|
-
*/
|
|
57
|
-
declare const REGTEST_MIN_CHECKPOINT_EXIT_DELAY_SECONDS = 1200n;
|
|
58
|
-
/**
|
|
59
|
-
* Wall-clock floor for the checkpoint exit delay on mutinynet.
|
|
60
|
-
*
|
|
61
|
-
* The hosted mutinynet Arkade Service advertises exactly this: its
|
|
62
|
-
* `checkpointTapscript` decodes to a 4096s (8 * 512) CSV, sized for a chain
|
|
63
|
-
* that mines ~30s blocks. {@link DEFAULT_MIN_CHECKPOINT_EXIT_DELAY_SECONDS}
|
|
64
|
-
* rejects it, which left mutinynet unusable until the caller went and found
|
|
65
|
-
* `minCheckpointExitDelaySeconds` and then this number.
|
|
66
|
-
*/
|
|
67
|
-
declare const MUTINYNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS = 4096n;
|
|
68
|
-
/**
|
|
69
|
-
* Wall-clock floor for the checkpoint exit delay on signet.
|
|
70
|
-
*
|
|
71
|
-
* The hosted signet Arkade Service advertises 86016s (168 * 512): a 24h
|
|
72
|
-
* setting rounded down to BIP-68's 512s granularity, since 86400 is not a
|
|
73
|
-
* multiple of 512 and so cannot be encoded in a seconds-typed timelock at all.
|
|
74
|
-
* That lands 384s under {@link DEFAULT_MIN_CHECKPOINT_EXIT_DELAY_SECONDS} and
|
|
75
|
-
* is rejected by it, so signet needs its own floor for the same reason
|
|
76
|
-
* mutinynet does.
|
|
77
|
-
*/
|
|
78
|
-
declare const SIGNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS = 86016n;
|
|
79
|
-
/** Bounds applied to a server-supplied `ArkadeInfo.checkpointTapscript`. */
|
|
80
|
-
type CheckpointExitDelayPolicy = {
|
|
81
|
-
/** Minimum wall-clock delay in seconds, after normalization. */
|
|
82
|
-
minSeconds: bigint;
|
|
83
|
-
/**
|
|
84
|
-
* Reject block-typed timelocks. Mirrors arkd, which allows a block-typed
|
|
85
|
-
* checkpoint exit delay only on regtest.
|
|
86
|
-
*/
|
|
87
|
-
requireSeconds: boolean;
|
|
88
|
-
/**
|
|
89
|
-
* When set, the script's embedded pubkey must equal this x-only key.
|
|
90
|
-
*
|
|
91
|
-
* arkd always builds the checkpoint tapscript from its own `forfeitPubkey`
|
|
92
|
-
* (`internal/core/application/service.go`), so this should be the
|
|
93
|
-
* `forfeitPubkey` the caller already trusts — pinned wallet state where one
|
|
94
|
-
* exists, otherwise the same `ArkadeInfo` response's own `forfeitPubkey` field
|
|
95
|
-
* as a self-consistency check.
|
|
96
|
-
*/
|
|
97
|
-
advertisedForfeitPubkey?: Bytes;
|
|
98
|
-
};
|
|
99
|
-
/**
|
|
100
|
-
* Default policy for a network.
|
|
101
|
-
*
|
|
102
|
-
* Derive it from the locally held {@link Network} — pinned at wallet setup —
|
|
103
|
-
* rather than from server data, so the permissive regtest branch can't be
|
|
104
|
-
* selected by the operator.
|
|
105
|
-
*/
|
|
106
|
-
declare function defaultCheckpointExitDelayPolicy(network: Network): CheckpointExitDelayPolicy;
|
|
107
|
-
/** Resolve a policy for `network`, applying any caller overrides on top. */
|
|
108
|
-
declare function resolveCheckpointExitDelayPolicy(network: Network, overrides?: Partial<CheckpointExitDelayPolicy>): CheckpointExitDelayPolicy;
|
|
109
|
-
/**
|
|
110
|
-
* Decode and validate a server-supplied `checkpointTapscript` against `policy`.
|
|
111
|
-
*
|
|
112
|
-
* Every offchain send/claim builds its checkpoint outputs' server-claim leaf
|
|
113
|
-
* straight from this script — undecodable, sub-floor or wrong-pubkey values
|
|
114
|
-
* let the operator sweep an in-flight checkpoint before it settles. This is
|
|
115
|
-
* the sole gate: callers must use the returned script rather than decoding
|
|
116
|
-
* their own copy.
|
|
117
|
-
*
|
|
118
|
-
* @throws {ServerResponseMismatchError} if the script fails to decode, its
|
|
119
|
-
* timelock is out of policy, or its pubkey does not match
|
|
120
|
-
* `policy.advertisedForfeitPubkey` (when set).
|
|
121
|
-
*/
|
|
122
|
-
declare function assertValidServerUnrollScript(checkpointTapscript: string, policy: CheckpointExitDelayPolicy): CSVMultisigTapscript.Type;
|
|
123
|
-
|
|
124
|
-
declare class ArkError extends Error {
|
|
125
|
-
readonly code: number;
|
|
126
|
-
readonly message: string;
|
|
127
|
-
readonly name: string;
|
|
128
|
-
readonly metadata?: Record<string, string> | undefined;
|
|
129
|
-
constructor(code: number, message: string, name: string, metadata?: Record<string, string> | undefined);
|
|
130
|
-
}
|
|
131
|
-
/**
|
|
132
|
-
* Structured arkd error `name`s the SDK branches on, centralized so call sites don't
|
|
133
|
-
* hardcode string literals. Not an exhaustive mirror of the server's codes — only the
|
|
134
|
-
* ones the SDK acts on.
|
|
135
|
-
*/
|
|
136
|
-
declare const ArkErrorName: {
|
|
137
|
-
readonly DIGEST_MISMATCH: "DIGEST_MISMATCH";
|
|
138
|
-
readonly VTXO_ALREADY_SPENT: "VTXO_ALREADY_SPENT";
|
|
139
|
-
readonly INVALID_TX_FILTER: "INVALID_TX_FILTER";
|
|
140
|
-
readonly TX_FILTERS_LIMIT_EXCEEDED: "TX_FILTERS_LIMIT_EXCEEDED";
|
|
141
|
-
/**
|
|
142
|
-
* A CLTV closure was spent before its absolute locktime matured. Raised only by
|
|
143
|
-
* `submitTx` (never `finalizeTx`), with metadata
|
|
144
|
-
* `{ locktime, current_locktime, type: "height" | "time" }`.
|
|
145
|
-
*
|
|
146
|
-
* Self-healing, so defer and retry rather than fail: the server matures a
|
|
147
|
-
* seconds-locktime against the **chain tip block's timestamp**, not its wall clock,
|
|
148
|
-
* so a spend attempted promptly at maturity is rejected until a later block lands.
|
|
149
|
-
*/
|
|
150
|
-
readonly FORFEIT_CLOSURE_LOCKED: "FORFEIT_CLOSURE_LOCKED";
|
|
151
|
-
};
|
|
152
|
-
type ArkErrorName = (typeof ArkErrorName)[keyof typeof ArkErrorName];
|
|
153
|
-
/**
|
|
154
|
-
* Type guard for a structured {@link ArkError}, optionally narrowing to a specific
|
|
155
|
-
* `name`. Prefer it over comparing `err.name` literals.
|
|
156
|
-
*
|
|
157
|
-
* `name` accepts only cataloged {@link ArkErrorName} values; to branch on a name the
|
|
158
|
-
* catalog does not cover, either add it there or compare `err.name` after guarding
|
|
159
|
-
* with the one-argument form.
|
|
160
|
-
*
|
|
161
|
-
* @example
|
|
162
|
-
* if (isArkError(maybeArkError(err), ArkErrorName.DIGEST_MISMATCH)) { ... }
|
|
163
|
-
*/
|
|
164
|
-
declare function isArkError(error: unknown, name?: ArkErrorName): error is ArkError;
|
|
165
|
-
/**
|
|
166
|
-
* Which remote dependency an availability failure refers to. Used to label the
|
|
167
|
-
* {@link ProviderUnavailableError} message and the wallet's
|
|
168
|
-
* `ProviderConnectionState`; it is deliberately *not* carried as a structured
|
|
169
|
-
* field on the error, since custom `Error` own-properties do not survive the
|
|
170
|
-
* service-worker `postMessage` boundary. Structured clone keeps `message`,
|
|
171
|
-
* `stack` and `cause`, drops own-properties, and normalizes a custom `name` to
|
|
172
|
-
* `"Error"` — only the built-in error names survive it.
|
|
173
|
-
*/
|
|
174
|
-
type ProviderKind = "arkade" | "indexer";
|
|
175
|
-
/**
|
|
176
|
-
* A remote provider (Arkade operator or its indexer) is temporarily
|
|
177
|
-
* unreachable. This is a *retryable* condition — transport failure, request
|
|
178
|
-
* timeout, or a 5xx/429-style temporary HTTP response — as opposed to a
|
|
179
|
-
* terminal configuration/authorization/schema error, which stays a plain
|
|
180
|
-
* `Error`/{@link ArkError}. The original low-level error is preserved as
|
|
181
|
-
* {@link Error.cause}.
|
|
182
|
-
*/
|
|
183
|
-
declare class ProviderUnavailableError extends Error {
|
|
184
|
-
/** Always `true`: this error type only ever wraps retryable conditions. */
|
|
185
|
-
readonly retryable = true;
|
|
186
|
-
constructor(message: string, options?: {
|
|
187
|
-
cause?: unknown;
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
/**
|
|
191
|
-
* A response does not reconcile with what the SDK submitted or already
|
|
192
|
-
* validated — a checkpoint tx whose txid is not among those submitted, a
|
|
193
|
-
* commitment tx that differs from the one validated at tree signing. Terminal
|
|
194
|
-
* rather than retryable: the two are equal by construction in a well-formed
|
|
195
|
-
* exchange, so the same request would produce the same outcome.
|
|
196
|
-
*
|
|
197
|
-
* Neither own-properties nor a custom `name` cross the service-worker
|
|
198
|
-
* `postMessage` boundary (see {@link ProviderKind}), so `retryable` and `name`
|
|
199
|
-
* are in-process conveniences and every distinguishing detail belongs in
|
|
200
|
-
* `message` — the one field a consumer past the boundary can still branch on.
|
|
201
|
-
*/
|
|
202
|
-
declare class ServerResponseMismatchError extends Error {
|
|
203
|
-
readonly retryable = false;
|
|
204
|
-
constructor(message: string, options?: {
|
|
205
|
-
cause?: unknown;
|
|
206
|
-
});
|
|
207
|
-
}
|
|
208
|
-
/**
|
|
209
|
-
* Try to convert an error to an ArkError class, returning undefined if the error is not an ArkError
|
|
210
|
-
* @param error - The error to parse
|
|
211
|
-
* @returns The parsed ArkError, or undefined if the error is not an ArkError
|
|
212
|
-
*/
|
|
213
|
-
declare function maybeArkError(error: any): ArkError | undefined;
|
|
214
|
-
|
|
215
|
-
/** Where the {@link ArkadeInfo} used to construct a wallet came from. */
|
|
216
|
-
type ServerInfoSource = "live" | "cache";
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* Batch namespace provides utilities for joining and processing batch session.
|
|
220
|
-
* The batch settlement process involves multiple events, this namespace provides abstractions and types to handle them.
|
|
221
|
-
* @see https://docs.arkadeos.com/learn/pillars/batch-swaps
|
|
222
|
-
* @example
|
|
223
|
-
* ```typescript
|
|
224
|
-
* // use wallet handler or create a custom one
|
|
225
|
-
* const handler = wallet.createBatchHandler(intentId, inputs, expectedRecipients, musig2session);
|
|
226
|
-
*
|
|
227
|
-
* const abortController = new AbortController();
|
|
228
|
-
* // Get event stream from the Arkade provider
|
|
229
|
-
* const eventStream = arkProvider.getEventStream(
|
|
230
|
-
* abortController.signal,
|
|
231
|
-
* ['your-topic-1', 'your-topic-2']
|
|
232
|
-
* );
|
|
233
|
-
*
|
|
234
|
-
* // Join the batch and process events
|
|
235
|
-
* try {
|
|
236
|
-
* const commitmentTxid = await Batch.join(eventStream, handler);
|
|
237
|
-
* console.log('Batch completed with commitment:', commitmentTxid);
|
|
238
|
-
* } catch (error) {
|
|
239
|
-
* console.error('Batch processing failed:', error);
|
|
240
|
-
* } finally {
|
|
241
|
-
* abortController.abort();
|
|
242
|
-
* }
|
|
243
|
-
* ```
|
|
244
|
-
*/
|
|
245
|
-
declare namespace Batch {
|
|
246
|
-
interface Handler {
|
|
247
|
-
/**
|
|
248
|
-
* Called on BatchStarted event.
|
|
249
|
-
* @returns { skip: boolean } indicating whether the batch should be skipped or not.
|
|
250
|
-
*/
|
|
251
|
-
onBatchStarted(event: BatchStartedEvent): Promise<{
|
|
252
|
-
skip: boolean;
|
|
253
|
-
}>;
|
|
254
|
-
/**
|
|
255
|
-
* Called when tree signing starts.
|
|
256
|
-
* @param event The tree signing started event.
|
|
257
|
-
* @param vtxoTree The unsigned virtual output tree, reconstructed from the TreeTxEvent events.
|
|
258
|
-
* @returns Promise resolving to a boolean indicating whether to continue processing.
|
|
259
|
-
*/
|
|
260
|
-
onTreeSigningStarted(event: TreeSigningStartedEvent, vtxoTree: TxTree): Promise<{
|
|
261
|
-
skip: boolean;
|
|
262
|
-
}>;
|
|
263
|
-
/**
|
|
264
|
-
* Called when tree nonces are received.
|
|
265
|
-
* @param event The tree nonces event.
|
|
266
|
-
* @returns Promise resolving to a boolean indicating whether signing is complete.
|
|
267
|
-
*/
|
|
268
|
-
onTreeNonces(event: TreeNoncesEvent): Promise<{
|
|
269
|
-
fullySigned: boolean;
|
|
270
|
-
}>;
|
|
271
|
-
/**
|
|
272
|
-
* Called during batch finalization.
|
|
273
|
-
* @param event The batch finalization event.
|
|
274
|
-
* @param vtxoTree The signed virtual output tree, reconstructed from the TreeTxEvent events.
|
|
275
|
-
* @param connectorTree The connector transaction tree, reconstructed from the TreeTxEvent events.
|
|
276
|
-
*/
|
|
277
|
-
onBatchFinalization(event: BatchFinalizationEvent, vtxoTree?: TxTree, connectorTree?: TxTree): Promise<void>;
|
|
278
|
-
/**
|
|
279
|
-
* Called when batch finalization completes successfully.
|
|
280
|
-
*
|
|
281
|
-
* @param event - Batch finalized event
|
|
282
|
-
*/
|
|
283
|
-
onBatchFinalized?(event: BatchFinalizedEvent): Promise<void>;
|
|
284
|
-
/**
|
|
285
|
-
* Called when batch processing fails.
|
|
286
|
-
*
|
|
287
|
-
* @param event - Batch failed event
|
|
288
|
-
*/
|
|
289
|
-
onBatchFailed?(event: BatchFailedEvent): Promise<void>;
|
|
290
|
-
/**
|
|
291
|
-
* Called for each virtual output tree transaction chunk received during batch processing.
|
|
292
|
-
*
|
|
293
|
-
* @param event - Tree transaction event
|
|
294
|
-
*/
|
|
295
|
-
onTreeTxEvent?(event: TreeTxEvent): Promise<void>;
|
|
296
|
-
/**
|
|
297
|
-
* Called for each tree signature event received during batch processing.
|
|
298
|
-
*
|
|
299
|
-
* @param event - Tree signature event
|
|
300
|
-
*/
|
|
301
|
-
onTreeSignatureEvent?(event: TreeSignatureEvent): Promise<void>;
|
|
302
|
-
}
|
|
303
|
-
/**
|
|
304
|
-
* Options for the join function.
|
|
305
|
-
*
|
|
306
|
-
* @property abortController - Abort controller used to cancel batch processing.
|
|
307
|
-
* @property skipVtxoTreeSigning - Ignore events related to the virtual output tree musig2 signing session.
|
|
308
|
-
* @property eventCallback - Callback invoked for each settlement event received while joining the batch.
|
|
309
|
-
*/
|
|
310
|
-
type JoinOptions = Partial<{
|
|
311
|
-
abortController: AbortController;
|
|
312
|
-
skipVtxoTreeSigning: boolean;
|
|
313
|
-
eventCallback: (event: SettlementEvent) => Promise<void>;
|
|
314
|
-
}>;
|
|
315
|
-
/**
|
|
316
|
-
* Start the state machine that will process the batch events and join a batch.
|
|
317
|
-
* @param eventIterator - The events stream to process.
|
|
318
|
-
* @param handler - How to react to events.
|
|
319
|
-
* @param options - Options.
|
|
320
|
-
*/
|
|
321
|
-
function join(eventIterator: AsyncIterableIterator<SettlementEvent>, handler: Handler, options?: JoinOptions): Promise<string>;
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
/**
|
|
325
|
-
* Inputs the wallet hands to a {@link ReceiveRotatorFactory} when
|
|
326
|
-
* asking it to construct the rotator at boot. The factory uses these
|
|
327
|
-
* to look up the wallet's current display contract (or allocate a
|
|
328
|
-
* fresh receive descriptor). Note: no `offchainTapscript` here — the
|
|
329
|
-
* factory's job is allocation, not script construction. The wallet's
|
|
330
|
-
* orchestrator (`WalletReceiveRotator.resolveBoot`) handles the
|
|
331
|
-
* tapscript rebuild on top of the factory's result.
|
|
332
|
-
*/
|
|
333
|
-
interface ReceiveRotatorBootOpts {
|
|
334
|
-
walletRepository: WalletRepository;
|
|
335
|
-
contractRepository: ContractRepository;
|
|
336
|
-
serverPubKey: Uint8Array;
|
|
337
|
-
/**
|
|
338
|
-
* Expected contract family ("default" or "delegate"). When provided,
|
|
339
|
-
* boot will only consider contracts of this type when looking up the
|
|
340
|
-
* wallet's current display contract, preventing a default wallet from
|
|
341
|
-
* accidentally picking up a delegate contract or vice versa.
|
|
342
|
-
*/
|
|
343
|
-
expectedContractType?: "default" | "delegate";
|
|
344
|
-
/**
|
|
345
|
-
* The wallet's baseline (index-0) receive pubkey — the x-only key the
|
|
346
|
-
* initial offchain tapscript is built from. Used by {@link
|
|
347
|
-
* WalletReceiveRotator.defaultBoot} as the no-tagged-row fallback:
|
|
348
|
-
* because boarding shares the single HD index stream, the raw watermark
|
|
349
|
-
* may have been advanced by a boarding-only allocation, so the boot must
|
|
350
|
-
* NOT derive the receive pubkey from it. A wallet with no tagged receive
|
|
351
|
-
* row has never rotated L2, so its correct current receive *is* the
|
|
352
|
-
* baseline index-0 key (plan §6-II.5).
|
|
353
|
-
*/
|
|
354
|
-
baselineReceivePubKey?: Uint8Array;
|
|
355
|
-
/**
|
|
356
|
-
* Logger to receive rotation-failure + backoff diagnostics. Defaults
|
|
357
|
-
* to `console` when omitted. Any object implementing
|
|
358
|
-
* {@link Logger.error} works (winston, pino, Sentry breadcrumbs,
|
|
359
|
-
* the runtime's own logger).
|
|
360
|
-
*/
|
|
361
|
-
logger?: Logger;
|
|
362
|
-
}
|
|
363
|
-
/**
|
|
364
|
-
* Output of {@link ReceiveRotatorFactory.createReceiveRotator}: the
|
|
365
|
-
* constructed rotator paired with the receive pubkey it resolved at
|
|
366
|
-
* boot (either the existing tagged display contract's pubkey, or a
|
|
367
|
-
* freshly allocated one).
|
|
368
|
-
*/
|
|
369
|
-
interface ReceiveRotatorBoot {
|
|
370
|
-
rotator: WalletReceiveRotator;
|
|
371
|
-
receivePubkey: Uint8Array;
|
|
372
|
-
}
|
|
373
|
-
/**
|
|
374
|
-
* Result returned by {@link WalletReceiveRotator.resolveBoot} to the
|
|
375
|
-
* wallet: the rotator plus the offchain tapscript the wallet should
|
|
376
|
-
* actually use (rebuilt to the resolved boot pubkey when it differs
|
|
377
|
-
* from the identity's static pubkey), plus the {@link DescriptorProvider}
|
|
378
|
-
* the rotator was built around. The wallet retains the provider so
|
|
379
|
-
* spending paths can route per-input signing through
|
|
380
|
-
* {@link DescriptorProvider.signWithDescriptor} instead of the
|
|
381
|
-
* identity's index-0 key.
|
|
382
|
-
*/
|
|
383
|
-
interface ReceiveRotatorBootResult {
|
|
384
|
-
rotator: WalletReceiveRotator;
|
|
385
|
-
offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script;
|
|
386
|
-
provider: DescriptorProvider;
|
|
387
|
-
}
|
|
388
|
-
/**
|
|
389
|
-
* Opt-in extension to {@link DescriptorProvider} for providers that
|
|
390
|
-
* drive HD receive rotation. Implemented by {@link HDDescriptorProvider}
|
|
391
|
-
* out of the box; custom providers (HSMs, external signers, …) can also
|
|
392
|
-
* implement it when they want to participate.
|
|
393
|
-
*
|
|
394
|
-
* Kept out of the core `DescriptorProvider` interface so providers that
|
|
395
|
-
* only do allocation + signing don't have to know about the wallet's
|
|
396
|
-
* receive lifecycle. The wallet detects support via
|
|
397
|
-
* {@link hasReceiveRotatorFactory} (a duck-typed `instanceof`-style
|
|
398
|
-
* check) and falls back to {@link WalletReceiveRotator.defaultBoot}
|
|
399
|
-
* when the provider doesn't implement the extension.
|
|
400
|
-
*/
|
|
401
|
-
interface ReceiveRotatorFactory {
|
|
402
|
-
createReceiveRotator(opts: ReceiveRotatorBootOpts): Promise<ReceiveRotatorBoot | undefined>;
|
|
403
|
-
}
|
|
404
|
-
/**
|
|
405
|
-
* Parse the trailing HD child index from a materialized signing
|
|
406
|
-
* descriptor (`tr(...xpub.../0/<index>)`). Returns 0 when the
|
|
407
|
-
* descriptor is absent or carries no parseable child index — restore
|
|
408
|
-
* registers the index-0 baseline untagged, so a missing descriptor
|
|
409
|
-
* legitimately maps to 0.
|
|
410
|
-
*/
|
|
411
|
-
declare function signingDescriptorIndex(descriptor: unknown): number;
|
|
412
|
-
/**
|
|
413
|
-
* Strict sibling of {@link signingDescriptorIndex}: `undefined` instead of
|
|
414
|
-
* the 0 fallback, for callers that must tell "no parseable index" apart from
|
|
415
|
-
* index 0 — a watermark move mapped to 0 would move nothing while reporting
|
|
416
|
-
* success.
|
|
417
|
-
*/
|
|
418
|
-
declare function strictSigningDescriptorIndex(descriptor: string): number | undefined;
|
|
419
|
-
/**
|
|
420
|
-
* Minimal logging surface the rotator needs. `console` satisfies it
|
|
421
|
-
* out of the box; SDK consumers can pass a structured logger
|
|
422
|
-
* (winston / pino / Sentry adapter) via {@link ReceiveRotatorBootOpts}
|
|
423
|
-
* to capture rotation failures + backoff diagnostics through their
|
|
424
|
-
* own pipeline.
|
|
425
|
-
*/
|
|
426
|
-
interface Logger {
|
|
427
|
-
error(message: string, ...args: unknown[]): void;
|
|
428
|
-
}
|
|
429
|
-
/**
|
|
430
|
-
* Narrow surface the rotator needs from the wallet at runtime: the
|
|
431
|
-
* mutable display tapscript, the display contract's script hex, the
|
|
432
|
-
* contract manager (for subscribing + registering rotated contracts),
|
|
433
|
-
* and the display address (for the contract's `address` field).
|
|
434
|
-
*
|
|
435
|
-
* Kept as an interface so the rotator module avoids a circular
|
|
436
|
-
* dependency on `wallet.ts`. `Wallet` implements this surface
|
|
437
|
-
* structurally — no `implements` clause is required.
|
|
438
|
-
*/
|
|
439
|
-
interface RotatableWallet {
|
|
440
|
-
readonly defaultContractScript: string;
|
|
441
|
-
readonly network: {
|
|
442
|
-
hrp: string;
|
|
443
|
-
};
|
|
444
|
-
readonly arkServerPublicKey: Uint8Array;
|
|
445
|
-
readonly offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script;
|
|
446
|
-
/**
|
|
447
|
-
* @internal Sole sanctioned write path for `offchainTapscript`
|
|
448
|
-
* after construction. The rotator calls this once per rotation
|
|
449
|
-
* after persisting the new display contract.
|
|
450
|
-
*/
|
|
451
|
-
setOffchainTapscriptForRotation(tapscript: DefaultVtxo.Script | DelegateVtxo.Script): void;
|
|
452
|
-
getContractManager(): Promise<IContractManager>;
|
|
453
|
-
getAddress(): Promise<string>;
|
|
454
|
-
}
|
|
455
|
-
/**
|
|
456
|
-
* Owns the wallet's HD receive-rotation lifecycle.
|
|
457
|
-
*
|
|
458
|
-
* The rotator is constructed only when the wallet's `walletMode`
|
|
459
|
-
* resolves to a {@link DescriptorProvider}; static wallets and
|
|
460
|
-
* non-HD-capable wallets under `'auto'` never see one.
|
|
461
|
-
*
|
|
462
|
-
* Lifecycle:
|
|
463
|
-
* 1. `resolveBoot()` — pre-Wallet-construction. Resolves the provider
|
|
464
|
-
* from `walletMode`, then either reuses the existing display
|
|
465
|
-
* contract's pubkey (if any) or allocates the first descriptor.
|
|
466
|
-
* Returns the rotator paired with the boot pubkey.
|
|
467
|
-
* 2. `install(wallet)` — post-`getVtxoManager()`. Subscribes to
|
|
468
|
-
* `vtxo_received` on the contract manager and routes matching events
|
|
469
|
-
* through the rotation chain.
|
|
470
|
-
* 3. `dispose()` — tears down the subscription and drains any in-flight
|
|
471
|
-
* rotation so the contract manager can be disposed cleanly.
|
|
472
|
-
*
|
|
473
|
-
* This class follows the dotnet-sdk's split of responsibilities: the
|
|
474
|
-
* provider is a pure rotating allocator; "what address am I currently
|
|
475
|
-
* bound to?" is answered by querying the contract repository, not by
|
|
476
|
-
* asking the provider.
|
|
477
|
-
*/
|
|
478
|
-
declare class WalletReceiveRotator {
|
|
479
|
-
private readonly provider;
|
|
480
|
-
private unsubscribe?;
|
|
481
|
-
private chain;
|
|
482
|
-
/**
|
|
483
|
-
* Script of the most-recent tagged display contract — populated
|
|
484
|
-
* either from the boot-time repo lookup or from the previous
|
|
485
|
-
* `rotate()` call within this session. The next `rotate()` marks
|
|
486
|
-
* this contract `inactive` once the new tagged contract is in
|
|
487
|
-
* place. `undefined` means the wallet's current display is the
|
|
488
|
-
* untagged index-0 baseline (no rotation has happened yet on this
|
|
489
|
-
* repo), and the baseline must NOT be deactivated.
|
|
490
|
-
*/
|
|
491
|
-
private currentTaggedScript;
|
|
492
|
-
/**
|
|
493
|
-
* Consecutive rotation failures since the last successful rotate.
|
|
494
|
-
* Drives an exponential backoff (capped at
|
|
495
|
-
* {@link ROTATION_MAX_BACKOFF_MS}) so a broken provider can't make
|
|
496
|
-
* the rotator hammer `getNextSigningDescriptor` + `createContract`
|
|
497
|
-
* on every inbound VTXO. Reset to zero on a successful rotate.
|
|
498
|
-
*/
|
|
499
|
-
private consecutiveFailures;
|
|
500
|
-
/**
|
|
501
|
-
* Unix-ms timestamp before which incoming `vtxo_received` events
|
|
502
|
-
* skip the rotation attempt entirely. Zero means "no backoff
|
|
503
|
-
* active" — the next event can rotate immediately.
|
|
504
|
-
*/
|
|
505
|
-
private nextRotationAllowedAt;
|
|
506
|
-
private readonly logger;
|
|
507
|
-
private constructor();
|
|
508
|
-
/**
|
|
509
|
-
* Phase 1 — pre-Wallet-construction. Resolves `walletMode` to a
|
|
510
|
-
* {@link DescriptorProvider}, then asks that provider to construct
|
|
511
|
-
* the rotator (delegated through
|
|
512
|
-
* {@link DescriptorProvider.createReceiveRotator}, which falls back
|
|
513
|
-
* to {@link defaultBoot} when the provider doesn't override it).
|
|
514
|
-
*
|
|
515
|
-
* Returns the rotator paired with the offchain tapscript the wallet
|
|
516
|
-
* should actually install (rebuilt to the resolved receive pubkey
|
|
517
|
-
* when it differs from the identity's static pubkey), or
|
|
518
|
-
* `undefined` when the wallet should stay on the static path.
|
|
519
|
-
*
|
|
520
|
-
* Errors during pubkey resolution propagate when:
|
|
521
|
-
* - `walletMode === 'hd'` (caller asked for HD; loud failure expected).
|
|
522
|
-
* - `walletMode` is a {@link DescriptorProvider} (caller supplied an
|
|
523
|
-
* explicit allocator; silently degrading would hide misconfig).
|
|
524
|
-
*
|
|
525
|
-
* Errors are silently swallowed (returning `undefined`) only under
|
|
526
|
-
* `walletMode: 'auto'` with the built-in HD provider, to preserve
|
|
527
|
-
* backwards compatibility with wallets whose identity descriptor
|
|
528
|
-
* isn't actually rangeable.
|
|
529
|
-
*/
|
|
530
|
-
static resolveBoot(config: WalletConfig, setup: ReceiveRotatorBootOpts & {
|
|
531
|
-
offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script;
|
|
532
|
-
}): Promise<ReceiveRotatorBootResult | undefined>;
|
|
533
|
-
/**
|
|
534
|
-
* Default factory-shaped boot any
|
|
535
|
-
* {@link ReceiveRotatorFactory.createReceiveRotator} implementation
|
|
536
|
-
* can delegate to. Pulls the wallet's current display contract from
|
|
537
|
-
* the contract repository (or allocates a fresh receive descriptor
|
|
538
|
-
* via the provider when no tagged display contract exists), and
|
|
539
|
-
* returns the rotator paired with the resolved receive pubkey.
|
|
540
|
-
*
|
|
541
|
-
* Used internally by `resolveBoot` when the provider doesn't
|
|
542
|
-
* implement {@link ReceiveRotatorFactory}. Exported so providers
|
|
543
|
-
* that *do* override can still invoke the default work for the
|
|
544
|
-
* parts of the boot path they don't want to customise. Tapscript
|
|
545
|
-
* construction is intentionally NOT in here — that's the
|
|
546
|
-
* orchestrator's job.
|
|
547
|
-
*/
|
|
548
|
-
static defaultBoot(provider: DescriptorProvider, opts: ReceiveRotatorBootOpts): Promise<ReceiveRotatorBoot>;
|
|
549
|
-
/**
|
|
550
|
-
* Phase 2 — post-`getVtxoManager()`. Subscribe to `vtxo_received`
|
|
551
|
-
* and trigger a rotation whenever the currently-active display
|
|
552
|
-
* contract receives funds. Old display contracts remain `active`
|
|
553
|
-
* in the repo so earlier shared addresses keep crediting this
|
|
554
|
-
* wallet.
|
|
555
|
-
*/
|
|
556
|
-
install(wallet: RotatableWallet): Promise<void>;
|
|
557
|
-
/**
|
|
558
|
-
* Run a single rotation attempt, applying exponential backoff on
|
|
559
|
-
* failure. Public-shaped behavior:
|
|
560
|
-
* - During a backoff window: log + skip (no `rotate()` call).
|
|
561
|
-
* - On success: reset failure count and backoff.
|
|
562
|
-
* - On failure: increment counter, schedule next attempt at
|
|
563
|
-
* `min(2^consecutiveFailures * 1s, ROTATION_MAX_BACKOFF_MS)`.
|
|
564
|
-
*
|
|
565
|
-
* Errors are deliberately swallowed (logged, not rethrown) so the
|
|
566
|
-
* surrounding `chain` Promise never settles to rejected — the next
|
|
567
|
-
* `vtxo_received` event must still get a chance to run.
|
|
568
|
-
*/
|
|
569
|
-
private runRotateWithBackoff;
|
|
570
|
-
/**
|
|
571
|
-
* Wait for any in-flight rotation to complete. Useful in tests
|
|
572
|
-
* that need to observe the post-rotation state after dispatching
|
|
573
|
-
* a `vtxo_received` event synchronously; production code rarely
|
|
574
|
-
* needs to call this directly.
|
|
575
|
-
*/
|
|
576
|
-
drain(): Promise<void>;
|
|
577
|
-
/**
|
|
578
|
-
* Run `fn` on the rotator's serialization chain, so it cannot interleave
|
|
579
|
-
* with a receive `rotate()`. Used by {@link Wallet.rotateServerSigner} to
|
|
580
|
-
* serialize server-signer rotation against HD receive rotation: both
|
|
581
|
-
* rebuild and swap `offchainTapscript`, so running them concurrently could
|
|
582
|
-
* tear the wallet's visible receive state. The chain keeps advancing even
|
|
583
|
-
* if `fn` rejects (its own caller still sees the rejection).
|
|
584
|
-
*/
|
|
585
|
-
runExclusive<T>(fn: () => Promise<T>): Promise<T>;
|
|
586
|
-
/**
|
|
587
|
-
* Tear down the subscription first so no late `vtxo_received` event
|
|
588
|
-
* can queue work on a disposing wallet, then drain any in-flight
|
|
589
|
-
* rotation so its `createContract` finishes before the contract
|
|
590
|
-
* manager itself disposes.
|
|
591
|
-
*/
|
|
592
|
-
dispose(): Promise<void>;
|
|
593
|
-
/**
|
|
594
|
-
* Allocate the next descriptor, swap it into the wallet's active
|
|
595
|
-
* offchain tapscript, register the new tagged contract, and retire
|
|
596
|
-
* the previous tagged contract (if any) by setting its state to
|
|
597
|
-
* `inactive`. The contract watcher keeps watching inactive
|
|
598
|
-
* contracts until their VTXOs are spent, so funds in flight at the
|
|
599
|
-
* old display address are not lost — only the address stops being
|
|
600
|
-
* advertised.
|
|
601
|
-
*
|
|
602
|
-
* Contract type matches the wallet's tapscript shape: a default
|
|
603
|
-
* wallet rotates to a new `default` contract, a delegate wallet to
|
|
604
|
-
* a new `delegate` contract.
|
|
605
|
-
*
|
|
606
|
-
* The first rotation on a fresh wallet does NOT deactivate
|
|
607
|
-
* anything: `currentTaggedScript` is `undefined` because the wallet
|
|
608
|
-
* was displaying the untagged index-0 baseline, which must stay
|
|
609
|
-
* active forever.
|
|
610
|
-
*/
|
|
611
|
-
private rotate;
|
|
612
|
-
}
|
|
613
|
-
|
|
614
|
-
/**
|
|
615
|
-
* Maximum caller-requested HD descriptors materialized past the watermark by
|
|
616
|
-
* getUsedSigningDescriptors(). Bounds plugin/restore probes without changing
|
|
617
|
-
* the wallet's actual allocation watermark.
|
|
618
|
-
*/
|
|
619
|
-
declare const MAX_USED_SIGNING_DESCRIPTORS_LOOK_AHEAD = 1000;
|
|
620
|
-
type IncomingFunds = {
|
|
621
|
-
type: "utxo";
|
|
622
|
-
coins: Coin[];
|
|
623
|
-
} | {
|
|
624
|
-
type: "vtxo";
|
|
625
|
-
newVtxos: ExtendedVirtualCoin[];
|
|
626
|
-
spentVtxos: ExtendedVirtualCoin[];
|
|
627
|
-
};
|
|
628
|
-
|
|
629
|
-
/**
|
|
630
|
-
* What signer classification needs of a snapshot: contract params and the coins
|
|
631
|
-
* under them. Structural rather than {@link ContractWithVtxos} so a repository-
|
|
632
|
-
* built snapshot — the worker's, whose VTXOs carry no `contractScript` — can be
|
|
633
|
-
* classified without allocating a parallel array to satisfy the nominal type.
|
|
634
|
-
*/
|
|
635
|
-
type PendingRecoverySnapshot = Parameters<typeof selectPendingRecoveryOutpoints>[0];
|
|
636
|
-
/**
|
|
637
|
-
* Boarding UTXOs grouped by the boarding address they sit on, carrying that
|
|
638
|
-
* address's signer association explicitly. Returned by
|
|
639
|
-
* {@link ReadonlyWallet.getBoardingUtxosForSigners} because a flat
|
|
640
|
-
* {@link ExtendedCoin} cannot carry the signer: it retains only the encoded
|
|
641
|
-
* leaves/tapTree the spend needs, not the owning `DefaultVtxo.Script` (and so
|
|
642
|
-
* not its `serverPubKey` or CSV delay). The deprecated-signer boarding
|
|
643
|
-
* classification reads both back from this group (Section 7).
|
|
644
|
-
*/
|
|
645
|
-
interface BoardingUtxoGroup {
|
|
646
|
-
/** Tapscript of the boarding address the coins sit on. */
|
|
647
|
-
tapscript: DefaultVtxo.Script;
|
|
648
|
-
/** Server key of that address, normalized x-only hex. */
|
|
649
|
-
serverPubKey: string;
|
|
650
|
-
/** CSV exit timelock decoded from THIS tapscript's exit leaf. */
|
|
651
|
-
csvTimelock: RelativeTimelock;
|
|
652
|
-
coins: ExtendedCoin[];
|
|
653
|
-
}
|
|
654
|
-
/**
|
|
655
|
-
* Why a VTXO at an arkadeCash address could not be swept by {@link Wallet.claimCash}.
|
|
656
|
-
*
|
|
657
|
-
* - `swept` — the server swept the batch at expiry. Recoverable in principle,
|
|
658
|
-
* but only through a settlement, which the thin sweep cannot do.
|
|
659
|
-
* - `subdust` — below dust, so it sits at an OP_RETURN script with no spendable
|
|
660
|
-
* leaf. Unspendable as cash; `createCash` prevents minting these.
|
|
661
|
-
* - `already-spent` — someone else claimed it first.
|
|
662
|
-
* - `exited` — unilaterally exited onchain, so the offchain sweep cannot reach it;
|
|
663
|
-
* `Unroll.completeUnroll` is the remedy.
|
|
664
|
-
* - `has-assets` — asset-bearing; the BTC-only sweep would burn the assets.
|
|
665
|
-
* - `sweep-failed` — spendable, but its own sweep was rejected.
|
|
666
|
-
*/
|
|
667
|
-
type ArkadeCashUnclaimedReason = "swept" | "subdust" | "already-spent" | "exited" | "has-assets" | "sweep-failed";
|
|
668
|
-
/** A VTXO {@link Wallet.claimCash} left behind, with the reason why. */
|
|
669
|
-
interface ArkadeCashUnclaimedVtxo {
|
|
670
|
-
txid: string;
|
|
671
|
-
vout: number;
|
|
672
|
-
/** Value in satoshis. */
|
|
673
|
-
value: number;
|
|
674
|
-
reason: ArkadeCashUnclaimedReason;
|
|
675
|
-
}
|
|
676
|
-
/**
|
|
677
|
-
* Outcome of {@link Wallet.claimCash}: what was swept, and what was not.
|
|
678
|
-
*
|
|
679
|
-
* The shape is open — further buckets may be added alongside `unclaimed` as
|
|
680
|
-
* more of the non-sweepable states become claimable.
|
|
681
|
-
*/
|
|
682
|
-
interface ArkadeCashClaimResult {
|
|
683
|
-
/** Satoshis swept to this wallet. */
|
|
684
|
-
swept: number;
|
|
685
|
-
unclaimed: {
|
|
686
|
-
/** Satoshis left behind. */
|
|
687
|
-
amount: number;
|
|
688
|
-
vtxos: ArkadeCashUnclaimedVtxo[];
|
|
689
|
-
};
|
|
690
|
-
}
|
|
691
|
-
/**
|
|
692
|
-
* Thrown when {@link Wallet.createCash} funds the note but its `send` call
|
|
693
|
-
* fails after the transaction may already have been submitted.
|
|
694
|
-
*
|
|
695
|
-
* The whole value of the note lives in `cash`: it carries the private key that
|
|
696
|
-
* controls the funded output. If `send` committed and this error is discarded,
|
|
697
|
-
* the sats are stranded at an address only this token can reach. Callers that
|
|
698
|
-
* cannot rule out a post-submit failure must persist `cash` — passing it to
|
|
699
|
-
* {@link Wallet.claimCash} recovers the funds whether or not the send landed.
|
|
700
|
-
*/
|
|
701
|
-
declare class ArkadeCashCreateError extends Error {
|
|
702
|
-
/** The encoded arkadeCash token controlling the funded output. */
|
|
703
|
-
readonly cash: string;
|
|
704
|
-
/** The original failure from `send`. */
|
|
705
|
-
readonly cause: unknown;
|
|
706
|
-
constructor(
|
|
707
|
-
/** The encoded arkadeCash token controlling the funded output. */
|
|
708
|
-
cash: string,
|
|
709
|
-
/** The original failure from `send`. */
|
|
710
|
-
cause: unknown);
|
|
711
|
-
}
|
|
712
|
-
/**
|
|
713
|
-
* Freshness of the wallet's provider-backed sync, composed from the boot
|
|
714
|
-
* server-info source and the contract-manager's indexer-sync health. It
|
|
715
|
-
* describes only how fresh provider data is — never the wallet balances/VTXOs
|
|
716
|
-
* themselves, which are always served from the repository (system of record).
|
|
717
|
-
*/
|
|
718
|
-
type ProviderConnectionState = {
|
|
719
|
-
mode: "online";
|
|
720
|
-
source: "live";
|
|
721
|
-
lastOnlineAt: number;
|
|
722
|
-
} | {
|
|
723
|
-
mode: "degraded";
|
|
724
|
-
source: "cache" | "repository";
|
|
725
|
-
provider: ProviderKind;
|
|
726
|
-
reason: string;
|
|
727
|
-
lastOnlineAt?: number;
|
|
728
|
-
};
|
|
729
|
-
declare class ReadonlyWallet implements IReadonlyWallet {
|
|
730
|
-
readonly identity: ReadonlyIdentity;
|
|
731
|
-
readonly network: Network;
|
|
732
|
-
readonly onchainProvider: OnchainProvider;
|
|
733
|
-
/**
|
|
734
|
-
* Narrowed to what a readonly wallet legitimately needs — the only use
|
|
735
|
-
* here is {@link getArkadeInfo}. `protected` stops an outside caller
|
|
736
|
-
* reaching it; the `Pick` stops this class growing a use for
|
|
737
|
-
* `submitTx`. `Wallet` re-widens both below.
|
|
738
|
-
*/
|
|
739
|
-
protected readonly arkProvider: Pick<ArkProvider, "getInfo">;
|
|
740
|
-
readonly indexerProvider: IndexerProvider;
|
|
741
|
-
readonly dustAmount: bigint;
|
|
742
|
-
readonly walletRepository: WalletRepository;
|
|
743
|
-
readonly contractRepository: ContractRepository;
|
|
744
|
-
readonly delegateProvider?: DelegateProvider | undefined;
|
|
745
|
-
private _contractManager?;
|
|
746
|
-
private _contractManagerInitializing?;
|
|
747
|
-
protected readonly watcherConfig?: ReadonlyWalletConfig["watcherConfig"];
|
|
748
|
-
/**
|
|
749
|
-
* Opt-in intent-lifecycle repository. Assigned by the `create()`
|
|
750
|
-
* factories from `config.storage.intentRepository`; `undefined` ⇒ all
|
|
751
|
-
* intent-persistence code paths are no-ops (default behaviour unchanged).
|
|
752
|
-
*/
|
|
753
|
-
intentRepository?: IntentRepository;
|
|
754
|
-
/**
|
|
755
|
-
* **Experimental / inert.** Opt-in virtual-tx / exit-branch repository,
|
|
756
|
-
* exposed so callers can pass it to {@link Unroll.Session.create} as a
|
|
757
|
-
* best-effort raw-tx cache. Assigned by `create()` from
|
|
758
|
-
* `config.storage.virtualTxRepository`. Normal sync never writes it
|
|
759
|
-
* (ContractManager isn't given it); `undefined` ⇒ no-op.
|
|
760
|
-
*/
|
|
761
|
-
virtualTxRepository?: VirtualTxRepository;
|
|
762
|
-
/** Opt-in exit-data capture settings; see {@link StorageConfig.exitDataCapture}. */
|
|
763
|
-
exitDataCapture?: {
|
|
764
|
-
mode?: ExitCaptureMode;
|
|
765
|
-
minExitWorthSats?: number;
|
|
766
|
-
sources?: ExitDataSource[];
|
|
767
|
-
};
|
|
768
|
-
private readonly _assetManager;
|
|
769
|
-
readonly walletContractTimelocks: RelativeTimelock[];
|
|
770
|
-
protected _pendingSpendOutpoints: Set<string>;
|
|
771
|
-
/** Activity resolvers consumed by {@link getActivityHistory}. */
|
|
772
|
-
readonly activity: ActivityRegistry;
|
|
773
|
-
get assetManager(): IReadonlyAssetManager;
|
|
774
|
-
/**
|
|
775
|
-
* Backing field for the active receive tapscript. Read via the
|
|
776
|
-
* public `offchainTapscript` getter; written only by
|
|
777
|
-
* {@link Wallet.setOffchainTapscriptForRotation}, which
|
|
778
|
-
* {@link WalletReceiveRotator.rotate} is the sole intended caller of.
|
|
779
|
-
*/
|
|
780
|
-
protected _offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script;
|
|
781
|
-
/**
|
|
782
|
-
* Backing field for the current boarding tapscript (the QR / onboarding
|
|
783
|
-
* target). Read via the public `boardingTapscript` getter; written only
|
|
784
|
-
* by {@link Wallet.setBoardingTapscriptForRotation}, the sanctioned
|
|
785
|
-
* boarding-rotation write path (analogue of `_offchainTapscript`). It is
|
|
786
|
-
* a *current value*, not a fixed setup constant, because per-derivation
|
|
787
|
-
* boarding rotation (plan §6-II) swaps it when a fresh boarding address
|
|
788
|
-
* is explicitly allocated. Static / `auto` wallets never rotate it, so
|
|
789
|
-
* it stays the index-0 baseline for their lifetime.
|
|
790
|
-
*/
|
|
791
|
-
protected _boardingTapscript: DefaultVtxo.Script;
|
|
792
|
-
/**
|
|
793
|
-
* Backing field for the active server signer (x-only, 32 bytes). Read via
|
|
794
|
-
* the public {@link arkServerPublicKey} getter; written only by
|
|
795
|
-
* {@link Wallet.setArkServerPublicKeyForRotation}, the sanctioned
|
|
796
|
-
* server-signer rotation write path (analogue of `_offchainTapscript`). It
|
|
797
|
-
* is a *current value*, not a fixed constructor constant, because
|
|
798
|
-
* mid-session server-signer rotation (plan §4) swaps it when arkd rotates
|
|
799
|
-
* its active signer. Wallets that never span a rotation keep their
|
|
800
|
-
* construction-time snapshot for their lifetime.
|
|
801
|
-
*/
|
|
802
|
-
protected _arkServerPublicKey: Bytes;
|
|
803
|
-
/**
|
|
804
|
-
* Whether the LATEST server-info resolution answered live (`"live"`) or
|
|
805
|
-
* from the cached snapshot because the operator was unreachable
|
|
806
|
-
* (`"cache"`). Seeded at construction and updated by every
|
|
807
|
-
* {@link getArkadeInfo} read, so a wallet that booted offline and
|
|
808
|
-
* recovered stops reporting degraded — and one that just fell back stops
|
|
809
|
-
* claiming online. Freshness signal for
|
|
810
|
-
* {@link getProviderConnectionState}.
|
|
811
|
-
*/
|
|
812
|
-
protected _serverInfoSource: ServerInfoSource;
|
|
813
|
-
/**
|
|
814
|
-
* Epoch-ms of the last known live operator contact: the most recent live
|
|
815
|
-
* resolution (construction or a later {@link getArkadeInfo}), or the
|
|
816
|
-
* cached snapshot's `savedAt` when the latest resolution fell back.
|
|
817
|
-
*/
|
|
818
|
-
protected _serverInfoLastOnlineAt?: number;
|
|
819
|
-
/** @see {@link _serverInfoSource} */
|
|
820
|
-
get serverInfoSource(): ServerInfoSource;
|
|
821
|
-
/**
|
|
822
|
-
* Composed provider-connection freshness: the LATEST server-info
|
|
823
|
-
* resolution (boot, or any later {@link getArkadeInfo} read) combined with
|
|
824
|
-
* the contract-manager's indexer-sync health, if the manager has been
|
|
825
|
-
* initialized. Reads no live provider state — it never forces a
|
|
826
|
-
* `ContractManager` to construct — so it is safe for readonly callers
|
|
827
|
-
* that only use address/balance APIs.
|
|
828
|
-
*
|
|
829
|
-
* - Latest resolution fell back to the cached snapshot → degraded on
|
|
830
|
-
* `arkade` (`cache`).
|
|
831
|
-
* - Otherwise, if the contract manager has degraded to repository data →
|
|
832
|
-
* degraded on `indexer` (`repository`).
|
|
833
|
-
* - Otherwise online.
|
|
834
|
-
*
|
|
835
|
-
* This only describes sync freshness; wallet balances/VTXOs are always read
|
|
836
|
-
* from the repository regardless of this state.
|
|
837
|
-
*/
|
|
838
|
-
getProviderConnectionState(): ProviderConnectionState;
|
|
839
|
-
/**
|
|
840
|
-
* The contract-manager's current provider-sync health **without forcing it
|
|
841
|
-
* to initialize** — reads the already-constructed manager, or reports
|
|
842
|
-
* `online` when none exists yet. Unlike {@link getContractManager}, this
|
|
843
|
-
* never triggers a remote sync, so it is safe on a pure diagnostics path
|
|
844
|
-
* (e.g. the service-worker sync-state message).
|
|
845
|
-
*/
|
|
846
|
-
getContractSyncState(): ContractSyncState;
|
|
847
|
-
protected constructor(identity: ReadonlyIdentity, network: Network, onchainProvider: OnchainProvider,
|
|
848
|
-
/**
|
|
849
|
-
* Narrowed to what a readonly wallet legitimately needs — the only use
|
|
850
|
-
* here is {@link getArkadeInfo}. `protected` stops an outside caller
|
|
851
|
-
* reaching it; the `Pick` stops this class growing a use for
|
|
852
|
-
* `submitTx`. `Wallet` re-widens both below.
|
|
853
|
-
*/
|
|
854
|
-
arkProvider: Pick<ArkProvider, "getInfo">, indexerProvider: IndexerProvider, arkServerPublicKey: Bytes, offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script, boardingTapscript: DefaultVtxo.Script, dustAmount: bigint, walletRepository: WalletRepository, contractRepository: ContractRepository, delegateProvider?: DelegateProvider | undefined, watcherConfig?: ReadonlyWalletConfig["watcherConfig"], walletContractTimelocks?: RelativeTimelock[]);
|
|
855
|
-
/**
|
|
856
|
-
* x-only hex of the operator's deprecated signer keys (from
|
|
857
|
-
* `ArkadeInfo.deprecatedSigners`), cached for the OFFLINE read/watch paths.
|
|
858
|
-
* The boarding watch/history surfaces ({@link getBoardingAddresses},
|
|
859
|
-
* {@link getBoardingTxs}) fan out over {current} ∪ this set so a deposit at
|
|
860
|
-
* a boarding address minted under a now-rotated operator signer keeps being
|
|
861
|
-
* watched. Refreshed from the server-info snapshot at construction (via the
|
|
862
|
-
* create() factories) and on a detected signer change. Deliberately NOT
|
|
863
|
-
* consulted by the spend path — {@link getBoardingUtxos} stays
|
|
864
|
-
* current-signer-only (a deprecated-signer input in a plain settle() is
|
|
865
|
-
* rejected; old-signer recovery goes through the migration API).
|
|
866
|
-
*/
|
|
867
|
-
protected _deprecatedSigners: Map<string, bigint>;
|
|
868
|
-
/**
|
|
869
|
-
* Refresh the cached deprecated-signer set from a fresh server-info
|
|
870
|
-
* snapshot. Called by the create() factories at construction, by the
|
|
871
|
-
* server-info-change handler mid-session, and by the deprecated-signer
|
|
872
|
-
* migration pass (`VtxoManager.migrateDeprecatedSignerVtxos`). This set feeds
|
|
873
|
-
* {@link pendingRecoveryOutpoints}, which drops EXPIRED (past-cutoff)
|
|
874
|
-
* deprecated-signer VTXOs from the wallet's own coin selection. Lenient: a
|
|
875
|
-
* malformed deprecated entry is skipped, never fatal to wallet creation.
|
|
876
|
-
*/
|
|
877
|
-
refreshDeprecatedSigners(info: {
|
|
878
|
-
deprecatedSigners?: readonly {
|
|
879
|
-
pubkey?: string;
|
|
880
|
-
cutoffDate?: bigint;
|
|
881
|
-
}[];
|
|
882
|
-
}): void;
|
|
883
|
-
/**
|
|
884
|
-
* The signer set the boarding WATCH/HISTORY paths fan out over: the wallet's
|
|
885
|
-
* current signer plus every cached deprecated signer. Distinct from the
|
|
886
|
-
* spend path, which is current-signer-only.
|
|
887
|
-
*/
|
|
888
|
-
protected watchedBoardingSigners(): Set<string>;
|
|
889
|
-
/**
|
|
890
|
-
* `serverPubKey` defaults to the live key; spend paths that snapshot it
|
|
891
|
-
* against mid-flight rotation pass their snapshot, so the check reads from
|
|
892
|
-
* one rotation epoch.
|
|
893
|
-
*/
|
|
894
|
-
protected recipientAddressContext(serverPubKey?: Bytes): RecipientArkadeAddressContext;
|
|
895
|
-
/**
|
|
896
|
-
* Currently-active receive tapscript. Read-only from the outside;
|
|
897
|
-
* mutated only via {@link Wallet.setOffchainTapscriptForRotation}
|
|
898
|
-
* by {@link WalletReceiveRotator.rotate}.
|
|
899
|
-
*/
|
|
900
|
-
get offchainTapscript(): DefaultVtxo.Script | DelegateVtxo.Script;
|
|
901
|
-
/**
|
|
902
|
-
* The wallet's current active server signer (x-only, 32 bytes). Read-only
|
|
903
|
-
* from the outside; mutated only via
|
|
904
|
-
* {@link Wallet.setArkServerPublicKeyForRotation} during mid-session
|
|
905
|
-
* server-signer rotation (plan §4). Single-valued for wallets that never
|
|
906
|
-
* span a rotation.
|
|
907
|
-
*/
|
|
908
|
-
get arkServerPublicKey(): Bytes;
|
|
909
|
-
/**
|
|
910
|
-
* Server info for the Arkade server this wallet is connected to, resolved
|
|
911
|
-
* exactly as construction resolves it: live wins, a retryable failure
|
|
912
|
-
* falls back to the snapshot persisted at boot, a terminal one propagates.
|
|
913
|
-
*
|
|
914
|
-
* Live rather than the pinned boot snapshot because the fields callers
|
|
915
|
-
* come here for — `signerPubkey`, `checkpointTapscript`, `fees` — are the
|
|
916
|
-
* ones a mid-session rotation moves, and a covenant built against a
|
|
917
|
-
* superseded signer is unspendable.
|
|
918
|
-
*
|
|
919
|
-
* One rotation caveat: reading does NOT re-pin the wallet —
|
|
920
|
-
* {@link arkServerPublicKey}, {@link dustAmount} and the tapscripts move
|
|
921
|
-
* only through `handleServerInfoChanged`/`rotateServerSigner` — so inside
|
|
922
|
-
* a rotation window this can report epoch N+1 while the wallet still
|
|
923
|
-
* spends on N. The window closes on its own: a read that observes a moved
|
|
924
|
-
* digest makes the provider emit `onServerInfoChanged`, which is what
|
|
925
|
-
* drives that rotation. A caller about to bind the answer into a covenant
|
|
926
|
-
* passes `{ requireLive: true }` and fails closed instead of receiving
|
|
927
|
-
* the boot snapshot.
|
|
928
|
-
*
|
|
929
|
-
* @returns The Arkade server's info
|
|
930
|
-
* @see ArkadeInfo
|
|
931
|
-
*/
|
|
932
|
-
getArkadeInfo(opts?: GetArkadeInfoOptions): Promise<ArkadeInfo>;
|
|
933
|
-
/**
|
|
934
|
-
* Chain reads against this wallet's server for scripts it does not own.
|
|
935
|
-
*
|
|
936
|
-
* Binds the wallet's own `indexerProvider` — which may be an Expo or
|
|
937
|
-
* injected one that a caller's hand-built `RestIndexerProvider` would
|
|
938
|
-
* silently bypass. `getVtxos` goes through
|
|
939
|
-
* {@link getNormalizedVtxos}, which is what makes every VTXO leaving the
|
|
940
|
-
* seam carry its canonical facts.
|
|
941
|
-
*
|
|
942
|
-
* A bound object rather than the provider itself, so an `IReadonlyWallet`
|
|
943
|
-
* holder gets `getVtxos`/`getVirtualTxs` and nothing else at runtime.
|
|
944
|
-
* (`indexerProvider` is still public on the concrete classes, unlike
|
|
945
|
-
* `arkProvider`, so this narrows the interface rather than the field.)
|
|
946
|
-
*/
|
|
947
|
-
getArkadeReader(): Promise<ArkadeReader>;
|
|
948
|
-
/**
|
|
949
|
-
* The wallet's current boarding tapscript (the on-chain onboarding
|
|
950
|
-
* target). Read-only from the outside; mutated only via
|
|
951
|
-
* {@link Wallet.setBoardingTapscriptForRotation} when a fresh boarding
|
|
952
|
-
* address is explicitly allocated. Single-valued for static / `auto`
|
|
953
|
-
* wallets.
|
|
954
|
-
*/
|
|
955
|
-
get boardingTapscript(): DefaultVtxo.Script;
|
|
956
|
-
/**
|
|
957
|
-
* Listeners fired after the boarding tapscript rotates to a fresh index
|
|
958
|
-
* (see {@link Wallet.setBoardingTapscriptForRotation}). A live
|
|
959
|
-
* {@link notifyIncomingFunds} onchain watcher registers one so it can
|
|
960
|
-
* re-subscribe to include the newly allocated boarding address within the
|
|
961
|
-
* same session — without it, a deposit to the fresh address wouldn't fire
|
|
962
|
-
* a notification until the watcher's next re-init. Always empty for
|
|
963
|
-
* readonly / static / `auto` wallets, which never rotate boarding.
|
|
964
|
-
*/
|
|
965
|
-
private readonly _boardingRotationListeners;
|
|
966
|
-
/**
|
|
967
|
-
* Register a listener invoked synchronously after each boarding rotation.
|
|
968
|
-
* Returns an unsubscribe function. Protected: only internal subscribers
|
|
969
|
-
* (the incoming-funds watcher) participate.
|
|
970
|
-
*/
|
|
971
|
-
protected onBoardingRotation(listener: () => void): () => void;
|
|
972
|
-
/**
|
|
973
|
-
* Notify boarding-rotation listeners. Called by the boarding-rotation
|
|
974
|
-
* write path ({@link Wallet.setBoardingTapscriptForRotation}) once the new
|
|
975
|
-
* tapscript is in place. A throwing listener is isolated so it can neither
|
|
976
|
-
* break the rotation nor starve sibling listeners.
|
|
977
|
-
*/
|
|
978
|
-
protected notifyBoardingRotation(): void;
|
|
979
|
-
/**
|
|
980
|
-
* Protected helper to set up shared wallet configuration.
|
|
981
|
-
* Extracts common logic used by both ReadonlyWallet.create() and Wallet.create().
|
|
982
|
-
*/
|
|
983
|
-
protected static setupWalletConfig(config: ReadonlyWalletConfig, pubKey: Uint8Array): Promise<{
|
|
984
|
-
arkProvider: ArkProvider;
|
|
985
|
-
indexerProvider: IndexerProvider;
|
|
986
|
-
onchainProvider: OnchainProvider;
|
|
987
|
-
network: Network;
|
|
988
|
-
networkName: NetworkName;
|
|
989
|
-
serverPubKey: Uint8Array<ArrayBufferLike>;
|
|
990
|
-
offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script;
|
|
991
|
-
boardingTapscript: DefaultVtxo.Script;
|
|
992
|
-
dustAmount: bigint;
|
|
993
|
-
walletRepository: WalletRepository;
|
|
994
|
-
contractRepository: ContractRepository;
|
|
995
|
-
info: ArkadeInfo;
|
|
996
|
-
serverInfoSource: ServerInfoSource;
|
|
997
|
-
serverInfoLastOnlineAt: number | undefined;
|
|
998
|
-
delegateProvider: DelegateProvider | undefined;
|
|
999
|
-
/** @deprecated alias for `delegateProvider` */
|
|
1000
|
-
delegatorProvider: DelegateProvider | undefined;
|
|
1001
|
-
walletContractTimelocks: RelativeTimelock[];
|
|
1002
|
-
}>;
|
|
1003
|
-
/**
|
|
1004
|
-
* Create a readonly wallet for querying balances, addresses, and history.
|
|
1005
|
-
*
|
|
1006
|
-
* @param config - Readonly wallet configuration
|
|
1007
|
-
* @returns A readonly wallet instance
|
|
1008
|
-
*/
|
|
1009
|
-
static create(config: ReadonlyWalletConfig): Promise<ReadonlyWallet>;
|
|
1010
|
-
get arkAddress(): ArkAddress;
|
|
1011
|
-
/**
|
|
1012
|
-
* Get the pkScript hex for the wallet's primary offchain address.
|
|
1013
|
-
* For the full wallet-owned script set registered in ContractManager, use getWalletScripts().
|
|
1014
|
-
*/
|
|
1015
|
-
get defaultContractScript(): string;
|
|
1016
|
-
/** Returns the wallet's Arkade address. */
|
|
1017
|
-
getAddress(): Promise<string>;
|
|
1018
|
-
/** Returns the onchain boarding address used to move funds into Arkade. */
|
|
1019
|
-
getBoardingAddress(): Promise<string>;
|
|
1020
|
-
/**
|
|
1021
|
-
* Return the wallet's combined onchain and offchain balances.
|
|
1022
|
-
*/
|
|
1023
|
-
getBalance(): Promise<WalletBalance>;
|
|
1024
|
-
/**
|
|
1025
|
-
* Return virtual outputs tracked by the wallet.
|
|
1026
|
-
*
|
|
1027
|
-
* The raw reporting/recovery read: escrowed, locked and awaiting-recovery
|
|
1028
|
-
* funds are all present. Coin selection must use
|
|
1029
|
-
* {@link getSpendableVtxos} instead — feeding this straight into
|
|
1030
|
-
* `settle({ inputs })` or `sendBitcoin({ selectedVtxos })` bypasses the
|
|
1031
|
-
* generic-spending gate.
|
|
1032
|
-
*
|
|
1033
|
-
* @param filter - Optional flags controlling whether recoverable or unrolled VTXOs are included
|
|
1034
|
-
*/
|
|
1035
|
-
getVtxos(filter?: GetVtxosFilter): Promise<NormalizedExtendedVirtualCoin[]>;
|
|
1036
|
-
/** @inheritdoc */
|
|
1037
|
-
getSpendableVtxos(filter?: GetVtxosFilter): Promise<NormalizedExtendedVirtualCoin[]>;
|
|
1038
|
-
/**
|
|
1039
|
-
* Debug-log any explicit input generic selection would have excluded, for
|
|
1040
|
-
* each of the three reasons it excludes on. Explicit-input APIs stay ungated
|
|
1041
|
-
* on purpose (naming an outpoint *is* the intent the gate protects, and it
|
|
1042
|
-
* is how an escrowed deposit is recovered once generic selection stops
|
|
1043
|
-
* covering it), so this only makes the crossing visible — notably
|
|
1044
|
-
* `settle({ inputs: await wallet.getVtxos() })`, which launders the raw read
|
|
1045
|
-
* into a spend. Never throws into a spend path.
|
|
1046
|
-
*
|
|
1047
|
-
* Public so the worker handler and plugins can report their own
|
|
1048
|
-
* explicit-input crossings through the same three checks.
|
|
1049
|
-
*/
|
|
1050
|
-
logUngatedInputs(source: string, inputs: readonly {
|
|
1051
|
-
txid: string;
|
|
1052
|
-
vout: number;
|
|
1053
|
-
script?: string;
|
|
1054
|
-
}[]): Promise<void>;
|
|
1055
|
-
/**
|
|
1056
|
-
* Contracts whose operator signer is past its rotation cutoff, as an
|
|
1057
|
-
* exclusion over scripts. The outpoint-level `pendingRecovery` set needs a
|
|
1058
|
-
* synced VTXO snapshot to also drop already-swept coins; this answers the
|
|
1059
|
-
* same question about a caller-supplied input without one, and a swept
|
|
1060
|
-
* outpoint is unspendable regardless.
|
|
1061
|
-
*/
|
|
1062
|
-
private expiredSignerExclusion;
|
|
1063
|
-
/** The intent store's lock set. Fails open, like every other read of it. */
|
|
1064
|
-
private lockedOutpoints;
|
|
1065
|
-
/**
|
|
1066
|
-
* One contract+VTXO read. `getContractsWithVtxos` opportunistically syncs
|
|
1067
|
-
* against the indexer, so every caller that needs more than one view of the
|
|
1068
|
-
* wallet's coins takes a single snapshot and derives them all from it —
|
|
1069
|
-
* otherwise the gate and the pending-recovery set answer about two different
|
|
1070
|
-
* points in time, and each read costs another sync.
|
|
1071
|
-
*/
|
|
1072
|
-
protected contractSnapshot(): Promise<ContractWithVtxos[]>;
|
|
1073
|
-
/**
|
|
1074
|
-
* The two exclusion sets the gate is made of, derived from one snapshot so
|
|
1075
|
-
* {@link getSpendableVtxos} and the balance answer about the same instant.
|
|
1076
|
-
*/
|
|
1077
|
-
private spendabilityView;
|
|
1078
|
-
/** The capability probes {@link computeOffchainBalance} needs, over one snapshot. */
|
|
1079
|
-
private balanceCapabilities;
|
|
1080
|
-
/**
|
|
1081
|
-
* Outpoints of VTXOs whose deprecated signer is past its cutoff (EXPIRED) and
|
|
1082
|
-
* which have not yet been swept — unspendable until they recover. Offline:
|
|
1083
|
-
* classifies the repo's contracts against the cached signer set (active +
|
|
1084
|
-
* {@link _deprecatedSigners}, cutoffs included). Empty fast-path when no
|
|
1085
|
-
* signer is deprecated. Consumed by {@link getBalance} (the `pendingRecovery`
|
|
1086
|
-
* bucket) and by {@link getSpendableVtxos} so neither counts nor spends them.
|
|
1087
|
-
*
|
|
1088
|
-
* Takes a fresh {@link contractSnapshot}, which syncs against the indexer.
|
|
1089
|
-
* Callers that already hold a snapshot — or that must not sync at all, like
|
|
1090
|
-
* the worker's balance read — pass it to
|
|
1091
|
-
* {@link pendingRecoveryOutpointsIn} instead.
|
|
1092
|
-
*/
|
|
1093
|
-
pendingRecoveryOutpoints(): Promise<Set<string>>;
|
|
1094
|
-
/**
|
|
1095
|
-
* {@link pendingRecoveryOutpoints} over a snapshot the caller already has:
|
|
1096
|
-
* pure classification against the cached signer set, no repository or
|
|
1097
|
-
* network read of its own.
|
|
1098
|
-
*/
|
|
1099
|
-
pendingRecoveryOutpointsIn(snapshot: PendingRecoverySnapshot): Set<string>;
|
|
1100
|
-
private selectPendingRecovery;
|
|
1101
|
-
/**
|
|
1102
|
-
* Return wallet transaction history derived from Arkade state and boarding transactions.
|
|
1103
|
-
*/
|
|
1104
|
-
getTransactionHistory(): Promise<ArkTransaction[]>;
|
|
1105
|
-
/**
|
|
1106
|
-
* Wallet history grouped by registered activity resolvers. With no resolver match,
|
|
1107
|
-
* rows bucket by transaction key so send/change pairs stay together.
|
|
1108
|
-
*/
|
|
1109
|
-
getActivityHistory(): Promise<Activity[]>;
|
|
1110
|
-
/**
|
|
1111
|
-
* Clear the global VTXO sync cursor, forcing a full re-bootstrap on next sync.
|
|
1112
|
-
* Useful for recovery after indexer reprocessing or debugging.
|
|
1113
|
-
*/
|
|
1114
|
-
clearSyncCursor(): Promise<void>;
|
|
1115
|
-
/**
|
|
1116
|
-
* Wipe all locally persisted wallet data (VTXOs, UTXOs, history, sync
|
|
1117
|
-
* cursor, contracts). Create a fresh wallet instance afterward.
|
|
1118
|
-
*/
|
|
1119
|
-
clear(): Promise<void>;
|
|
1120
|
-
/**
|
|
1121
|
-
* The on-chain (P2TR) addresses of every boarding tapscript this wallet
|
|
1122
|
-
* uses — the current address plus any historical rotated boarding
|
|
1123
|
-
* addresses. The aggregating boarding readers (history, notifications) fan
|
|
1124
|
-
* out over this set so deposits at previous boarding addresses are still
|
|
1125
|
-
* surfaced (plan §6-IV); {@link getBoardingAddress} stays single-valued.
|
|
1126
|
-
*/
|
|
1127
|
-
getBoardingAddresses(): Promise<string[]>;
|
|
1128
|
-
/**
|
|
1129
|
-
* Build a transaction history view across the wallet's boarding addresses
|
|
1130
|
-
* (current + historical rotated; plan §6-IV.1).
|
|
1131
|
-
*/
|
|
1132
|
-
getBoardingTxs(): Promise<{
|
|
1133
|
-
boardingTxs: ArkTransaction[];
|
|
1134
|
-
commitmentsToIgnore: Set<string>;
|
|
1135
|
-
}>;
|
|
1136
|
-
/**
|
|
1137
|
-
* The set of boarding tapscripts whose on-chain UTXOs belong to this
|
|
1138
|
-
* wallet — the current display tapscript plus every historical boarding
|
|
1139
|
-
* address it has used. Under per-derivation rotation (plan §6-II) a wallet
|
|
1140
|
-
* can hold unspent boarding UTXOs at several addresses at once, so fund
|
|
1141
|
-
* discovery / spending must enumerate them all, not just the current one
|
|
1142
|
-
* (plan §6-III.1). Deduplicated by scriptPubKey.
|
|
1143
|
-
*
|
|
1144
|
-
* Always includes the index-0 baseline (identity x-only key), which covers
|
|
1145
|
-
* the degenerate equal-delay case where the index-0 boarding row is
|
|
1146
|
-
* coalesced onto a `default` row and so isn't a `boarding`-typed contract.
|
|
1147
|
-
*
|
|
1148
|
-
* @param allowedSigners - Optional set of x-only-hex server keys whose
|
|
1149
|
-
* persisted boarding rows are included. Defaults to `{current x-only
|
|
1150
|
-
* signer}`, preserving today's current-signer-only discovery (and the
|
|
1151
|
-
* foreign-ASP guard). The deprecated-signer migration path widens this to
|
|
1152
|
-
* reach old-signer boarding addresses. The index-0 baseline and the
|
|
1153
|
-
* current display tapscript are always included regardless of the set.
|
|
1154
|
-
*/
|
|
1155
|
-
protected getBoardingTapscripts(allowedSigners?: Set<string>): Promise<DefaultVtxo.Script[]>;
|
|
1156
|
-
/**
|
|
1157
|
-
* Fetch and cache onchain inputs (UTXOs) received at the boarding addresses
|
|
1158
|
-
* of the given signer set, grouped per boarding address so the caller keeps
|
|
1159
|
-
* the address↔signer association that {@link ExtendedCoin} cannot carry
|
|
1160
|
-
* (it retains only the encoded leaves/tapTree the spend needs, not the
|
|
1161
|
-
* `DefaultVtxo.Script` and its `serverPubKey`/CSV delay).
|
|
1162
|
-
*
|
|
1163
|
-
* Per group it does exactly what {@link getBoardingUtxos} does per tapscript:
|
|
1164
|
-
* `getCoins` → {@link extendCoinWithTapscript} → `saveUtxos`. Offline-first:
|
|
1165
|
-
* it does not call `getInfo()`; the caller supplies the allowed signer set,
|
|
1166
|
-
* so the only network calls are the per-address `getCoins`.
|
|
1167
|
-
*
|
|
1168
|
-
* @param allowedSigners - x-only-hex server keys whose boarding addresses to
|
|
1169
|
-
* fetch (passed through to {@link getBoardingTapscripts}).
|
|
1170
|
-
*/
|
|
1171
|
-
getBoardingUtxosForSigners(allowedSigners: Set<string>): Promise<BoardingUtxoGroup[]>;
|
|
1172
|
-
/**
|
|
1173
|
-
* Fetch and cache onchain inputs (UTXOs) received at the wallet's boarding
|
|
1174
|
-
* addresses — the current address plus any historical rotated boarding
|
|
1175
|
-
* addresses that still hold unspent UTXOs (plan §6-III.1). Each UTXO is
|
|
1176
|
-
* annotated with the tapscript of the address it actually sits on, so the
|
|
1177
|
-
* spending path forfeits / exits it with the correct per-index leaves.
|
|
1178
|
-
*
|
|
1179
|
-
* Current-signer only: a flatten of {@link getBoardingUtxosForSigners} over
|
|
1180
|
-
* the wallet's current signer, so the two paths cannot drift. Old-signer
|
|
1181
|
-
* boarding recovery goes through the deprecated-signer migration API
|
|
1182
|
-
* instead (it would otherwise pull EXPIRED-signer inputs into a plain
|
|
1183
|
-
* `settle()` that the server must reject).
|
|
1184
|
-
*/
|
|
1185
|
-
getBoardingUtxos(): Promise<ExtendedCoin[]>;
|
|
1186
|
-
/**
|
|
1187
|
-
* Subscribe to onchain and offchain notifications for newly received funds.
|
|
1188
|
-
*
|
|
1189
|
-
* The onchain watcher tracks the full boarding-address set (current +
|
|
1190
|
-
* historical rotated). When boarding rotates *after* subscribing — e.g.
|
|
1191
|
-
* rotate-on-board allocates a fresh address via
|
|
1192
|
-
* {@link getNewBoardingAddress} — the watcher automatically re-subscribes
|
|
1193
|
-
* to widen its set, so a deposit to the new address fires a notification
|
|
1194
|
-
* within the same session (no watcher re-init required). The re-subscribe
|
|
1195
|
-
* is driven by {@link onBoardingRotation}; static / `auto` / readonly
|
|
1196
|
-
* wallets never rotate boarding, so it never fires for them.
|
|
1197
|
-
*
|
|
1198
|
-
* @param eventCallback - Callback invoked when matching funds are detected
|
|
1199
|
-
* @returns A function that stops the subscriptions
|
|
1200
|
-
*/
|
|
1201
|
-
notifyIncomingFunds(eventCallback: (coins: IncomingFunds) => void): Promise<() => void>;
|
|
1202
|
-
/** Fetch Arkade transaction ids that are still pending final settlement. */
|
|
1203
|
-
fetchPendingTxs(): Promise<string[]>;
|
|
1204
|
-
/**
|
|
1205
|
-
* Get all pkScript hex strings for the wallet's own addresses
|
|
1206
|
-
* (both delegate and non-delegate, current and historical).
|
|
1207
|
-
*/
|
|
1208
|
-
getWalletScripts(): Promise<string[]>;
|
|
1209
|
-
/**
|
|
1210
|
-
* Build a map of scriptHex → VtxoScript for all wallet contracts,
|
|
1211
|
-
* so virtual outputs can be extended with the correct tapscript per contract.
|
|
1212
|
-
*/
|
|
1213
|
-
getScriptMap(): Promise<Map<string, DefaultVtxo.Script | DelegateVtxo.Script>>;
|
|
1214
|
-
/**
|
|
1215
|
-
* Get the ContractManager for managing contracts including the wallet's default address.
|
|
1216
|
-
*
|
|
1217
|
-
* The ContractManager handles:
|
|
1218
|
-
* - The wallet's default receiving address (as a "default" contract)
|
|
1219
|
-
* - External contracts (Boltz swaps, HTLCs, etc.)
|
|
1220
|
-
* - Multi-contract watching with resilient connections
|
|
1221
|
-
*
|
|
1222
|
-
* @example
|
|
1223
|
-
* ```typescript
|
|
1224
|
-
* const manager = await wallet.getContractManager();
|
|
1225
|
-
*
|
|
1226
|
-
* // Create a contract for a Boltz swap
|
|
1227
|
-
* const contract = await manager.createContract({
|
|
1228
|
-
* label: "Boltz Swap",
|
|
1229
|
-
* type: "vhtlc",
|
|
1230
|
-
* params: { ... },
|
|
1231
|
-
* script: swapScript,
|
|
1232
|
-
* address: swapAddress,
|
|
1233
|
-
* });
|
|
1234
|
-
*
|
|
1235
|
-
* // Start watching for events (includes wallet's default address)
|
|
1236
|
-
* const stop = await manager.onContractEvent((event) => {
|
|
1237
|
-
* console.log(`${event.type} on ${event.contractScript}`);
|
|
1238
|
-
* });
|
|
1239
|
-
* ```
|
|
1240
|
-
*/
|
|
1241
|
-
getContractManager(): Promise<ContractManager>;
|
|
1242
|
-
/**
|
|
1243
|
-
* HD look-ahead configuration for the contract manager. Readonly wallets
|
|
1244
|
-
* have no descriptor provider, hence no watermark to look ahead of.
|
|
1245
|
-
* @see Wallet.lookAheadConfig
|
|
1246
|
-
*/
|
|
1247
|
-
protected lookAheadConfig(): ContractManagerConfig["lookAhead"];
|
|
1248
|
-
private initializeContractManager;
|
|
1249
|
-
/** Dispose wallet-owned managers and release background resources. */
|
|
1250
|
-
dispose(): Promise<void>;
|
|
1251
|
-
/** Async-dispose hook that forwards to `dispose()`. */
|
|
1252
|
-
[Symbol.asyncDispose](): Promise<void>;
|
|
1253
|
-
}
|
|
1254
|
-
/**
|
|
1255
|
-
* Main wallet implementation for Bitcoin transactions with Arkade protocol support.
|
|
1256
|
-
* The wallet does not store any data locally and relies on Arkade and onchain
|
|
1257
|
-
* providers to fetch onchain and virtual outputs.
|
|
1258
|
-
*
|
|
1259
|
-
* @example
|
|
1260
|
-
* ```typescript
|
|
1261
|
-
* // Create a wallet with providers
|
|
1262
|
-
* const wallet = await Wallet.create({
|
|
1263
|
-
* identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
1264
|
-
* arkProvider: new RestArkProvider(),
|
|
1265
|
-
* onchainProvider: new EsploraProvider()
|
|
1266
|
-
* });
|
|
1267
|
-
*
|
|
1268
|
-
* // Use custom providers and/or URLs (e.g., for Expo/React Native)
|
|
1269
|
-
* const wallet = await Wallet.create({
|
|
1270
|
-
* identity: MnemonicIdentity.fromMnemonic('abandon abandon...'),
|
|
1271
|
-
* arkProvider: new ExpoArkProvider('https://arkade.computer'),
|
|
1272
|
-
* indexerProvider: new ExpoIndexerProvider('https://arkade.computer'),
|
|
1273
|
-
* onchainProvider: new EsploraProvider('https://mempool.space/api')
|
|
1274
|
-
* });
|
|
1275
|
-
*
|
|
1276
|
-
* // Get addresses
|
|
1277
|
-
* const arkAddress = await wallet.getAddress();
|
|
1278
|
-
* const boardingAddress = await wallet.getBoardingAddress();
|
|
1279
|
-
*
|
|
1280
|
-
* // Send bitcoin
|
|
1281
|
-
* const txid = await wallet.send({
|
|
1282
|
-
* address: 'ark1q...',
|
|
1283
|
-
* amount: 50000,
|
|
1284
|
-
* });
|
|
1285
|
-
* ```
|
|
1286
|
-
*/
|
|
1287
|
-
declare class Wallet extends ReadonlyWallet implements IWallet, HDWalletCapable, AddressAllocationCapable {
|
|
1288
|
-
readonly forfeitOutputScript: Bytes;
|
|
1289
|
-
readonly forfeitPubkey: Bytes;
|
|
1290
|
-
/** Overrides for the `batchExpiry` bounds; defaults derive from `network`. */
|
|
1291
|
-
protected readonly batchExpiryPolicy?: Partial<BatchExpiryPolicy> | undefined;
|
|
1292
|
-
/** Overrides for the checkpoint exit delay bounds; defaults derive from `network`. */
|
|
1293
|
-
protected readonly checkpointExitDelayPolicy?: Partial<CheckpointExitDelayPolicy> | undefined;
|
|
1294
|
-
static MIN_FEE_RATE: number;
|
|
1295
|
-
readonly identity: Identity;
|
|
1296
|
-
private readonly _delegateManager?;
|
|
1297
|
-
private _vtxoManager?;
|
|
1298
|
-
private _vtxoManagerInitializing?;
|
|
1299
|
-
private _walletAssetManager?;
|
|
1300
|
-
/**
|
|
1301
|
-
* HD receive rotator. Owns the {@link DescriptorProvider}, the
|
|
1302
|
-
* `vtxo_received` subscription, and the rotate-and-register
|
|
1303
|
-
* lifecycle. Absent in `walletMode: 'static'` and for SingleKey
|
|
1304
|
-
* wallets under `'auto'`. Wired in via the constructor; the actual
|
|
1305
|
-
* subscription is installed lazily on first `getVtxoManager()` so
|
|
1306
|
-
* the contract manager is up first.
|
|
1307
|
-
*/
|
|
1308
|
-
private _receiveRotator?;
|
|
1309
|
-
/**
|
|
1310
|
-
* Unsubscribe handle for the arkProvider's `onServerInfoChanged` stream
|
|
1311
|
-
* (mid-session signer-rotation detection). Torn down in {@link dispose}.
|
|
1312
|
-
*/
|
|
1313
|
-
private _serverInfoUnsub?;
|
|
1314
|
-
/**
|
|
1315
|
-
* Tail of the serialized {@link handleServerInfoChanged} chain. Each
|
|
1316
|
-
* `onServerInfoChanged` event chains onto it so handlers run one at a time,
|
|
1317
|
-
* and {@link dispose} awaits it so an in-flight re-derive/rotation settles
|
|
1318
|
-
* before the contract manager is torn down underneath it.
|
|
1319
|
-
*/
|
|
1320
|
-
private _serverInfoInFlight;
|
|
1321
|
-
/**
|
|
1322
|
-
* React to a mid-session server-info change (driven by the arkProvider's
|
|
1323
|
-
* `DIGEST_MISMATCH` detection). First refresh the cached deprecated-signer
|
|
1324
|
-
* set so the boarding WATCH path immediately widens to the just-deprecated
|
|
1325
|
-
* signer, then — only if the active signer actually changed — rotate the
|
|
1326
|
-
* wallet onto it via {@link rotateServerSigner} (re-deriving the offchain +
|
|
1327
|
-
* boarding display tapscripts and registering the current-signer rows).
|
|
1328
|
-
* Old-signer rows stay active, so existing funds remain watched. Failures
|
|
1329
|
-
* are logged, never thrown back into the provider's emit loop.
|
|
1330
|
-
*/
|
|
1331
|
-
private handleServerInfoChanged;
|
|
1332
|
-
/**
|
|
1333
|
-
* Await an `onServerInfoChanged` handler still applying a rotation.
|
|
1334
|
-
*
|
|
1335
|
-
* The provider emits synchronously but {@link handleServerInfoChanged} runs
|
|
1336
|
-
* off the emit, so between the two a caller can observe a half-applied
|
|
1337
|
-
* rotation: {@link rotateServerSigner} persists the active signer's contract
|
|
1338
|
-
* rows *before* committing the tapscripts, so `arkServerPublicKey` still
|
|
1339
|
-
* reads the old key while the new key's rows are already in the repository.
|
|
1340
|
-
* A path that refreshes server info and then reads signer-derived state must
|
|
1341
|
-
* drain the chain first, or it both reads that torn state and races the
|
|
1342
|
-
* handler for the rotation itself.
|
|
1343
|
-
*
|
|
1344
|
-
* Resolves once the chain is idle; a handler that threw already logged, and
|
|
1345
|
-
* its rejection is swallowed here.
|
|
1346
|
-
*
|
|
1347
|
-
* @internal Invoked by {@link dispose} and the {@link VtxoManager} migration
|
|
1348
|
-
* pass; not part of the stable public API.
|
|
1349
|
-
*/
|
|
1350
|
-
settleServerInfoChanges(): Promise<void>;
|
|
1351
|
-
private _receiveRotatorInstalled;
|
|
1352
|
-
/**
|
|
1353
|
-
* Descriptor-aware signer used by {@link _signerRouter} to sign
|
|
1354
|
-
* inputs locked by rotated pubkeys. Same instance the rotator owns;
|
|
1355
|
-
* stashed here so the spending paths don't have to reach inside the
|
|
1356
|
-
* rotator. Undefined for static / non-HD-capable wallets — those
|
|
1357
|
-
* paths only ever take the identity-sign branch.
|
|
1358
|
-
*/
|
|
1359
|
-
private readonly _descriptorProvider?;
|
|
1360
|
-
/** Per-side width of the HD look-ahead band. @see WalletConfig.lookAheadWindow */
|
|
1361
|
-
private readonly _lookAheadWindow;
|
|
1362
|
-
/**
|
|
1363
|
-
* Watch a band of missing offchain receive scripts around the HD watermark
|
|
1364
|
-
* so payments to an externally-issued address land without a `restore()`.
|
|
1365
|
-
* Only HD wallets have a watermark to look ahead of; static / `auto`
|
|
1366
|
-
* wallets keep a single index-0 receive address, so the feature stays off.
|
|
1367
|
-
*
|
|
1368
|
-
* `candidateDeps` is read at refill time, so a band rebuilt after
|
|
1369
|
-
* {@link rotateServerSigner} fans the active signer set (persisted
|
|
1370
|
-
* old-signer rows stay watched through the repository).
|
|
1371
|
-
*/
|
|
1372
|
-
protected lookAheadConfig(): ContractManagerConfig["lookAhead"];
|
|
1373
|
-
/**
|
|
1374
|
-
* Every axis an externally issued receive script could be anchored to, not
|
|
1375
|
-
* just the wallet's own current shape: an issuer sharing the seed (NArk, a
|
|
1376
|
-
* merchant backend) picks its own contract type, and a band derived from one
|
|
1377
|
-
* variant silently misses the rest until a `restore()`.
|
|
1378
|
-
*
|
|
1379
|
-
* Read from cached state, not a fresh `getInfo`, to stay synchronous and
|
|
1380
|
-
* offline-safe; {@link refreshDeprecatedSigners} and
|
|
1381
|
-
* {@link rotateServerSigner} keep it current and re-trigger a refill.
|
|
1382
|
-
*/
|
|
1383
|
-
private receiveCandidateDeps;
|
|
1384
|
-
private readonly _signerRouter;
|
|
1385
|
-
/**
|
|
1386
|
-
* @internal Sole write path for `offchainTapscript` after construction.
|
|
1387
|
-
* Called by {@link WalletReceiveRotator.rotate} once the rotated
|
|
1388
|
-
* display contract has been persisted. External code must treat
|
|
1389
|
-
* `offchainTapscript` as read-only.
|
|
1390
|
-
*/
|
|
1391
|
-
setOffchainTapscriptForRotation(tapscript: DefaultVtxo.Script | DelegateVtxo.Script): void;
|
|
1392
|
-
/**
|
|
1393
|
-
* @internal Sole write path for `boardingTapscript` after construction.
|
|
1394
|
-
* Called by {@link Wallet.getNewBoardingAddress} once the rotated
|
|
1395
|
-
* boarding contract has been persisted. External code must treat
|
|
1396
|
-
* `boardingTapscript` as read-only.
|
|
1397
|
-
*/
|
|
1398
|
-
setBoardingTapscriptForRotation(tapscript: DefaultVtxo.Script): void;
|
|
1399
|
-
/**
|
|
1400
|
-
* @internal Sole write path for `arkServerPublicKey` after construction.
|
|
1401
|
-
* Called by {@link Wallet.rotateServerSigner} once the rotated offchain and
|
|
1402
|
-
* boarding contract rows have been persisted. External code must treat
|
|
1403
|
-
* `arkServerPublicKey` as read-only.
|
|
1404
|
-
*/
|
|
1405
|
-
setArkServerPublicKeyForRotation(serverPubKey: Bytes): void;
|
|
1406
|
-
/**
|
|
1407
|
-
* Output script for checkpoint transactions, decoded from the server's
|
|
1408
|
-
* `checkpointTapscript`. Server-controlled state: pinned at construction
|
|
1409
|
-
* and re-sourced from a fresh `ArkadeInfo` on server-signer rotation. Read it
|
|
1410
|
-
* through {@link serverUnrollScript}; write it only through
|
|
1411
|
-
* {@link setServerUnrollScriptForRotation}.
|
|
1412
|
-
*/
|
|
1413
|
-
protected _serverUnrollScript: CSVMultisigTapscript.Type;
|
|
1414
|
-
get serverUnrollScript(): CSVMultisigTapscript.Type;
|
|
1415
|
-
/**
|
|
1416
|
-
* @internal Sole write path for `serverUnrollScript` after construction.
|
|
1417
|
-
* Called by {@link Wallet._doRotateServerSigner} with the checkpoint script
|
|
1418
|
-
* sourced from the fresh `ArkadeInfo` that triggered the rotation, so the send
|
|
1419
|
-
* path builds checkpoints against the new server epoch. External code must
|
|
1420
|
-
* treat `serverUnrollScript` as read-only.
|
|
1421
|
-
*/
|
|
1422
|
-
setServerUnrollScriptForRotation(script: CSVMultisigTapscript.Type): void;
|
|
1423
|
-
/**
|
|
1424
|
-
* Serializes {@link rotateServerSigner} for static / non-HD wallets (which
|
|
1425
|
-
* have no {@link WalletReceiveRotator} chain to ride). Coalesces concurrent
|
|
1426
|
-
* migration passes so two callers cannot both rebuild and swap the
|
|
1427
|
-
* tapscripts. HD wallets serialize on the rotator's chain instead, via
|
|
1428
|
-
* {@link WalletReceiveRotator.runExclusive}.
|
|
1429
|
-
*/
|
|
1430
|
-
private _serverRotationChain;
|
|
1431
|
-
/**
|
|
1432
|
-
* Allocate and return a *fresh* on-chain boarding address, rotating the
|
|
1433
|
-
* wallet's current boarding tapscript to a new HD index.
|
|
1434
|
-
*
|
|
1435
|
-
* This is the explicit boarding allocator — the analogue of dotnet's
|
|
1436
|
-
* `GetNextContract(NextContractPurpose.Boarding)`. Unlike
|
|
1437
|
-
* {@link getBoardingAddress} (a stable read of the current display
|
|
1438
|
-
* address that never burns an index), each call here:
|
|
1439
|
-
*
|
|
1440
|
-
* - allocates the next index from the shared HD stream (so boarding and
|
|
1441
|
-
* L2 receive interleave on one monotonic index);
|
|
1442
|
-
* - builds the boarding tapscript at that index with the boarding-exit
|
|
1443
|
-
* CSV;
|
|
1444
|
-
* - persists an `active` `boarding` contract tagged
|
|
1445
|
-
* {@link WALLET_RECEIVE_SOURCE} (with its `signingDescriptor`) so the
|
|
1446
|
-
* ContractWatcher monitors it, boot can restore it as the current
|
|
1447
|
-
* boarding address, and descriptor-aware signing can recover the
|
|
1448
|
-
* per-index key;
|
|
1449
|
-
* - swaps the wallet's current `boardingTapscript`.
|
|
1450
|
-
*
|
|
1451
|
-
* Gated by `walletMode`: a static / `auto` wallet has no descriptor
|
|
1452
|
-
* provider and keeps a single index-0 boarding address for its lifetime,
|
|
1453
|
-
* so this returns the existing {@link getBoardingAddress} unchanged
|
|
1454
|
-
* (no rotation, no index burned).
|
|
1455
|
-
*
|
|
1456
|
-
* **Behaviour change.** A wallet configured with a custom
|
|
1457
|
-
* {@link DescriptorProvider} (`walletMode: <provider>`) now rotates here.
|
|
1458
|
-
* It previously did not: allocation went through the contract manager,
|
|
1459
|
-
* which only wires an `allocate` hook for {@link HDDescriptorProvider}, so
|
|
1460
|
-
* such a wallet read as "declined to allocate" and silently kept its
|
|
1461
|
-
* index-0 boarding address forever. Those wallets now burn an index per
|
|
1462
|
-
* call — including via {@link maybeRotateBoardingAfterBoard}, which fires
|
|
1463
|
-
* on every settle that consumes a boarding UTXO. Funds at retired
|
|
1464
|
-
* addresses stay reachable: each rotation persists its `boarding` contract
|
|
1465
|
-
* before swapping, and {@link getBoardingUtxos} fans out over the full
|
|
1466
|
-
* historical set.
|
|
1467
|
-
*
|
|
1468
|
-
* @deprecated Use {@link getNewAddresses} — it mints any combination of
|
|
1469
|
-
* address types at one shared index, and reports the contract row behind
|
|
1470
|
-
* each. Note the difference in display behaviour: this method *swaps* the
|
|
1471
|
-
* advertised boarding address, where `getNewAddresses` mints side
|
|
1472
|
-
* addresses and leaves {@link getBoardingAddress} alone. To keep this
|
|
1473
|
-
* method's behaviour, keep calling this method.
|
|
1474
|
-
*/
|
|
1475
|
-
getNewBoardingAddress(): Promise<string>;
|
|
1476
|
-
/**
|
|
1477
|
-
* Allocate a *fresh* address of each requested type, all derived from one
|
|
1478
|
-
* newly allocated HD index.
|
|
1479
|
-
*
|
|
1480
|
-
* This is the explicit allocator the receive path otherwise lacks:
|
|
1481
|
-
* {@link getAddress} and {@link getBoardingAddress} are stable reads of the
|
|
1482
|
-
* wallet's display addresses, and the display receive address only advances
|
|
1483
|
-
* when a payment arrives ({@link WalletReceiveRotator} rotates on
|
|
1484
|
-
* `vtxo_received`). Issuing a second address before the first is paid — one
|
|
1485
|
-
* invoice for Alice, another for Bob — has to go through here.
|
|
1486
|
-
*
|
|
1487
|
-
* Each call:
|
|
1488
|
-
*
|
|
1489
|
-
* - allocates **one** index from the shared HD stream, however many types
|
|
1490
|
-
* were asked for, so a `default` + `boarding` pair are siblings rather
|
|
1491
|
-
* than two burnt indices;
|
|
1492
|
-
* - builds each requested script at that index, preserving every other
|
|
1493
|
-
* option of the wallet's current script for that flavour (including a
|
|
1494
|
-
* delegate wallet's `delegate` shape);
|
|
1495
|
-
* - persists each as an `active` contract carrying its `signingDescriptor`,
|
|
1496
|
-
* so the ContractWatcher monitors it, the balance counts it, and
|
|
1497
|
-
* {@link signerForDescriptor} can recover the key;
|
|
1498
|
-
* - slides the look-ahead band, since the watermark moved past indices an
|
|
1499
|
-
* external issuer may still be handing out.
|
|
1500
|
-
*
|
|
1501
|
-
* The minted rows are deliberately left **untagged**: the boot lookups
|
|
1502
|
-
* adopt the newest {@link WALLET_RECEIVE_SOURCE}-tagged row as the display
|
|
1503
|
-
* address, and a side address issued to one counterparty must not become
|
|
1504
|
-
* the address the wallet advertises to everyone else. {@link getAddress}
|
|
1505
|
-
* and {@link getBoardingAddress} are unchanged by this call.
|
|
1506
|
-
*
|
|
1507
|
-
* A wallet with no HD stream (`walletMode: 'static'` / `'auto'`) has one
|
|
1508
|
-
* address per flavour for its lifetime. Without `forceNew` it returns those
|
|
1509
|
-
* — the real persisted rows, no index burned; with `forceNew` it throws
|
|
1510
|
-
* {@link WalletCannotAllocateAddressError} rather than hand back an address
|
|
1511
|
-
* that is not in fact fresh.
|
|
1512
|
-
*
|
|
1513
|
-
* @example
|
|
1514
|
-
* ```typescript
|
|
1515
|
-
* const [invoice] = await wallet.getNewAddresses({ forceNew: true });
|
|
1516
|
-
* // hand `invoice.address` to Alice, keep the descriptor with the invoice
|
|
1517
|
-
* const signer = await wallet.signerForDescriptor(invoice.signingDescriptor);
|
|
1518
|
-
* ```
|
|
1519
|
-
*/
|
|
1520
|
-
getNewAddresses(opts?: GetNewAddressesOptions): Promise<NewAddress[]>;
|
|
1521
|
-
/**
|
|
1522
|
-
* Shared allocation core behind {@link getNewAddresses} and the deprecated
|
|
1523
|
-
* {@link getNewBoardingAddress}, so the two cannot drift on what an
|
|
1524
|
-
* allocation costs or what gets persisted.
|
|
1525
|
-
*
|
|
1526
|
-
* @param tagSource - Tag the persisted rows {@link WALLET_RECEIVE_SOURCE},
|
|
1527
|
-
* making the next boot adopt them as the display address. Only the
|
|
1528
|
-
* deprecated boarding allocator passes `true`; `getNewAddresses` mints side
|
|
1529
|
-
* addresses and must not hijack what the wallet advertises.
|
|
1530
|
-
*/
|
|
1531
|
-
private allocateAddresses;
|
|
1532
|
-
/**
|
|
1533
|
-
* The wallet's existing display addresses, as persisted contract rows —
|
|
1534
|
-
* the honest answer for a wallet with no index to burn.
|
|
1535
|
-
*
|
|
1536
|
-
* Each type is minted from the descriptor that already owns its display
|
|
1537
|
-
* script ({@link displayDescriptor}), not from the identity key, so the
|
|
1538
|
-
* returned `signingDescriptor` is the one that signs for the returned
|
|
1539
|
-
* `address` even on a wallet that has rotated.
|
|
1540
|
-
*/
|
|
1541
|
-
private currentAddresses;
|
|
1542
|
-
/**
|
|
1543
|
-
* The descriptor that owns the wallet's current display script for `type`,
|
|
1544
|
-
* read off the row the wallet persisted when it adopted that script.
|
|
1545
|
-
*
|
|
1546
|
-
* Deriving it from the identity instead is only correct for a wallet that
|
|
1547
|
-
* never rotates. On one that has — an HD wallet whose provider later
|
|
1548
|
-
* declines to allocate — the display script belongs to an HD child, and
|
|
1549
|
-
* pairing its address with the identity descriptor hands the caller a
|
|
1550
|
-
* {@link NewAddress} whose `signingDescriptor` resolves, via
|
|
1551
|
-
* {@link signerForDescriptor}, to a signer holding the wrong key.
|
|
1552
|
-
*
|
|
1553
|
-
* Falls back to the identity's pathless `tr(pubkey)` when no row carries a
|
|
1554
|
-
* descriptor: the static / `auto` case, where the identity key genuinely
|
|
1555
|
-
* owns the display script and this is what `getNextSigningDescriptor`
|
|
1556
|
-
* answers too. (The index-0 baselines registered at construction carry no
|
|
1557
|
-
* `signingDescriptor` metadata, so those wallets take this path.)
|
|
1558
|
-
*/
|
|
1559
|
-
private displayDescriptor;
|
|
1560
|
-
/**
|
|
1561
|
-
* Build, persist and shape one address of `type` owned by `descriptor` —
|
|
1562
|
-
* the single build-and-register path behind both {@link allocateAddresses}
|
|
1563
|
-
* and {@link currentAddresses}, so a freshly allocated address and a
|
|
1564
|
-
* re-registered display address cannot disagree on what gets written.
|
|
1565
|
-
*
|
|
1566
|
-
* The descriptor is the sole source of the script's owner key in both
|
|
1567
|
-
* branches. Deriving one flavour from the descriptor and the other from a
|
|
1568
|
-
* tapscript field is what lets `address` and `signingDescriptor` drift
|
|
1569
|
-
* apart.
|
|
1570
|
-
*/
|
|
1571
|
-
private mintAddress;
|
|
1572
|
-
/**
|
|
1573
|
-
* Build the boarding contract owned by `pubKey`, keeping every other option
|
|
1574
|
-
* of the wallet's current boarding tapscript (notably the boarding-exit
|
|
1575
|
-
* CSV, which is index-independent). The offchain analogue lives in
|
|
1576
|
-
* {@link buildReceiveContract}.
|
|
1577
|
-
*/
|
|
1578
|
-
private buildBoardingContract;
|
|
1579
|
-
/**
|
|
1580
|
-
* @see HDWalletCapable.getCurrentSigningDescriptor
|
|
1581
|
-
*/
|
|
1582
|
-
getCurrentSigningDescriptor(): Promise<string | undefined>;
|
|
1583
|
-
/**
|
|
1584
|
-
* @see HDAllocationCapable.getNextSigningDescriptor
|
|
1585
|
-
*
|
|
1586
|
-
* Every `Wallet` answers — this is where the wallet's key-provisioning
|
|
1587
|
-
* policy lives, so consumers never have to branch on wallet shape:
|
|
1588
|
-
* - HD: allocate a fresh index through the contract manager (which owns
|
|
1589
|
-
* cross-context serialization and the look-ahead band).
|
|
1590
|
-
* - custom provider: whatever the provider allocates.
|
|
1591
|
-
* - static / `auto`: the identity key as a bare `tr(pubkey)` descriptor —
|
|
1592
|
-
* the same answer every call, because that IS the static policy.
|
|
1593
|
-
*/
|
|
1594
|
-
getNextSigningDescriptor(): Promise<string | undefined>;
|
|
1595
|
-
/**
|
|
1596
|
-
* @see HDAllocationCapable.advanceSigningDescriptorWatermark
|
|
1597
|
-
*/
|
|
1598
|
-
advanceSigningDescriptorWatermark(descriptor: string): Promise<void>;
|
|
1599
|
-
/**
|
|
1600
|
-
* @see HDWalletCapable.getUsedSigningDescriptors
|
|
1601
|
-
*
|
|
1602
|
-
* Union of the watermark band and the descriptors persisted on contracts:
|
|
1603
|
-
* the band alone would miss rows a restore scan wrote, and the contracts
|
|
1604
|
-
* alone would miss indices allocated for something the wallet never
|
|
1605
|
-
* persisted (a swap, an externally issued invoice).
|
|
1606
|
-
*/
|
|
1607
|
-
getUsedSigningDescriptors(opts?: {
|
|
1608
|
-
lookAhead?: number;
|
|
1609
|
-
}): Promise<string[]>;
|
|
1610
|
-
/**
|
|
1611
|
-
* @see HDWalletCapable.signerForDescriptor
|
|
1612
|
-
*
|
|
1613
|
-
* Fail-loud contract: the returned identity is always the descriptor's
|
|
1614
|
-
* own key. A descriptor this wallet cannot sign for throws
|
|
1615
|
-
* {@link ForeignDescriptorError} instead of silently substituting the
|
|
1616
|
-
* baseline identity — that identity would sign happily with the wrong
|
|
1617
|
-
* key, and the failure would only surface as a rejected transaction or a
|
|
1618
|
-
* dead script, far from the call that caused it.
|
|
1619
|
-
*/
|
|
1620
|
-
signerForDescriptor(descriptor: string): Promise<Identity>;
|
|
1621
|
-
/**
|
|
1622
|
-
* Mid-session server-signer rotation (plan §4). When arkd rotates its
|
|
1623
|
-
* active signer mid-session — the case the long-lived service worker and
|
|
1624
|
-
* Expo background processes that own automatic migration must handle — a
|
|
1625
|
-
* wallet constructed before the rotation keeps deriving old-signer receive
|
|
1626
|
-
* addresses. Building a migration output to such an address would produce a
|
|
1627
|
-
* VTXO the server must reject, so the wallet must first re-derive its own
|
|
1628
|
-
* receive state under the new active signer.
|
|
1629
|
-
*
|
|
1630
|
-
* Follows the {@link WalletReceiveRotator.rotate} write-path pattern with
|
|
1631
|
-
* the server key swapped instead of the user key: build the new offchain
|
|
1632
|
-
* and boarding tapscripts locally (preserving every other option),
|
|
1633
|
-
* register the matching `default`/`delegate` and `boarding` contract rows
|
|
1634
|
-
* through {@link ContractManager.createContract}, and only then commit the
|
|
1635
|
-
* new tapscripts and server key to the wallet's visible state. The signing
|
|
1636
|
-
* metadata of the current receive/boarding rows is carried onto the new
|
|
1637
|
-
* rows so a rotated (descriptor-backed) receive pubkey can still sign.
|
|
1638
|
-
*
|
|
1639
|
-
* The old-signer contract rows are intentionally left `active` and watched
|
|
1640
|
-
* — they are exactly the deprecated-signer contracts the migration pass
|
|
1641
|
-
* drains. Idempotent: a no-op when the wallet already tracks `xonly`.
|
|
1642
|
-
*
|
|
1643
|
-
* Serialized against HD receive rotation so the two paths (both of which
|
|
1644
|
-
* rebuild and swap `offchainTapscript`) cannot interleave.
|
|
1645
|
-
*
|
|
1646
|
-
* @internal Invoked by the {@link VtxoManager} migration pass; not part of
|
|
1647
|
-
* the stable public API.
|
|
1648
|
-
*/
|
|
1649
|
-
rotateServerSigner(newServerPubKey: Bytes, checkpointTapscript: string): Promise<void>;
|
|
1650
|
-
private _doRotateServerSigner;
|
|
1651
|
-
/**
|
|
1652
|
-
* Async mutex that serializes all operations submitting VTXOs to the Arkade
|
|
1653
|
-
* server (`settle`, `send`, `sendBitcoin`). This prevents VtxoManager's
|
|
1654
|
-
* background renewal from racing with user-initiated transactions for the
|
|
1655
|
-
* same VTXO inputs.
|
|
1656
|
-
*/
|
|
1657
|
-
private _txLock;
|
|
1658
|
-
/**
|
|
1659
|
-
* In-flight guard for {@link restore}. A second `restore()` while one
|
|
1660
|
-
* is running returns the same promise so concurrent callers coalesce
|
|
1661
|
-
* into a single scan (spec §3.E). Cleared on settle so a later
|
|
1662
|
-
* explicit `restore()` re-runs.
|
|
1663
|
-
*/
|
|
1664
|
-
private _restoreInFlight?;
|
|
1665
|
-
private _addPendingSpends;
|
|
1666
|
-
private _removePendingSpends;
|
|
1667
|
-
private _withTxLock;
|
|
1668
|
-
/**
|
|
1669
|
-
* Explicitly recover this wallet's contracts and balance on a fresh
|
|
1670
|
-
* repo. HD wallets run a gap-limit scan across the index range;
|
|
1671
|
-
* static / non-HD wallets restore based on the single default
|
|
1672
|
-
* pubkey. Never throws because of identity/mode (a static identity
|
|
1673
|
-
* is a valid, narrower restore); throws on operational failure (so a
|
|
1674
|
-
* truncated restore is loud, not silent — the gap window may have
|
|
1675
|
-
* closed early). Idempotent and safe to call concurrently (calls
|
|
1676
|
-
* coalesce into one scan).
|
|
1677
|
-
*
|
|
1678
|
-
* Ordering is deliberate (spec §3.B / §4): scan → advance the HD
|
|
1679
|
-
* watermark → inline VTXO pull → only THEN surface aggregated
|
|
1680
|
-
* handler errors, so safely-discovered funds are always recovered
|
|
1681
|
-
* even when one discovery handler failed.
|
|
1682
|
-
*
|
|
1683
|
-
* @param opts.gapLimit - Consecutive-unused-index window. Default
|
|
1684
|
-
* 20. A non-positive / non-integer value is a programmer error and
|
|
1685
|
-
* throws synchronously (distinct from operational failure).
|
|
1686
|
-
*
|
|
1687
|
-
* @note Concurrent calls coalesce: if a restore is already in flight,
|
|
1688
|
-
* subsequent callers receive the same promise and their `gapLimit` is
|
|
1689
|
-
* ignored — the first caller's value governs the running scan.
|
|
1690
|
-
*/
|
|
1691
|
-
restore(opts?: {
|
|
1692
|
-
gapLimit?: number;
|
|
1693
|
-
}): Promise<void>;
|
|
1694
|
-
private _runRestore;
|
|
1695
|
-
/** @deprecated Use settlementConfig instead */
|
|
1696
|
-
readonly renewalConfig: Required<Omit<WalletConfig["renewalConfig"], "enabled">> & {
|
|
1697
|
-
enabled: boolean;
|
|
1698
|
-
thresholdMs: number;
|
|
1699
|
-
};
|
|
1700
|
-
readonly settlementConfig: SettlementConfig | false;
|
|
1701
|
-
/**
|
|
1702
|
-
* Re-widened to public: a full wallet's provider is part of its API
|
|
1703
|
-
* (`ExpoWallet` and the delegate manager read it), while `ReadonlyWallet`
|
|
1704
|
-
* keeps it protected so a readonly view cannot hand out `submitTx`.
|
|
1705
|
-
*/
|
|
1706
|
-
readonly arkProvider: ArkProvider;
|
|
1707
|
-
/**
|
|
1708
|
-
* Broadcast access bound to this wallet's server, so a plugin needs only
|
|
1709
|
-
* the wallet.
|
|
1710
|
-
*
|
|
1711
|
-
* Defined here and not on {@link ReadonlyWallet} for the same reason
|
|
1712
|
-
* `arkProvider` is protected there: a readonly wallet, and every
|
|
1713
|
-
* `toReadonly()` view, must not be able to submit.
|
|
1714
|
-
*/
|
|
1715
|
-
getArkadeBroadcaster(): Promise<ArkadeBroadcaster>;
|
|
1716
|
-
protected constructor(identity: Identity, network: Network, onchainProvider: OnchainProvider, arkProvider: ArkProvider, indexerProvider: IndexerProvider, arkServerPublicKey: Bytes, offchainTapscript: DefaultVtxo.Script | DelegateVtxo.Script, boardingTapscript: DefaultVtxo.Script, serverUnrollScript: CSVMultisigTapscript.Type, forfeitOutputScript: Bytes, forfeitPubkey: Bytes, dustAmount: bigint, walletRepository: WalletRepository, contractRepository: ContractRepository,
|
|
1717
|
-
/** @deprecated Use settlementConfig */
|
|
1718
|
-
renewalConfig?: WalletConfig["renewalConfig"], delegateProvider?: DelegateProvider, watcherConfig?: WalletConfig["watcherConfig"], settlementConfig?: WalletConfig["settlementConfig"], walletContractTimelocks?: RelativeTimelock[], receiveRotator?: WalletReceiveRotator, descriptorProvider?: DescriptorProvider, lookAheadWindow?: number,
|
|
1719
|
-
/** Overrides for the `batchExpiry` bounds; defaults derive from `network`. */
|
|
1720
|
-
batchExpiryPolicy?: Partial<BatchExpiryPolicy> | undefined,
|
|
1721
|
-
/** Overrides for the checkpoint exit delay bounds; defaults derive from `network`. */
|
|
1722
|
-
checkpointExitDelayPolicy?: Partial<CheckpointExitDelayPolicy> | undefined);
|
|
1723
|
-
get assetManager(): IAssetManager;
|
|
1724
|
-
getVtxoManager(): Promise<VtxoManager>;
|
|
1725
|
-
dispose(): Promise<void>;
|
|
1726
|
-
/**
|
|
1727
|
-
* Create a full wallet and initialize its background managers.
|
|
1728
|
-
*
|
|
1729
|
-
* @param config - Wallet configuration
|
|
1730
|
-
* @returns A wallet ready to query balances and send transactions
|
|
1731
|
-
* @example
|
|
1732
|
-
* ```typescript
|
|
1733
|
-
* const wallet = await Wallet.create({
|
|
1734
|
-
* identity,
|
|
1735
|
-
* arkProvider: new RestArkProvider(),
|
|
1736
|
-
* });
|
|
1737
|
-
* ```
|
|
1738
|
-
*/
|
|
1739
|
-
static create(config: WalletConfig): Promise<Wallet>;
|
|
1740
|
-
/**
|
|
1741
|
-
* Convert this wallet to a readonly wallet.
|
|
1742
|
-
*
|
|
1743
|
-
* @returns A readonly wallet with the same configuration but readonly identity
|
|
1744
|
-
* @example
|
|
1745
|
-
* ```typescript
|
|
1746
|
-
* const wallet = await Wallet.create({ identity: MnemonicIdentity.fromMnemonic('abandon abandon...'), ... });
|
|
1747
|
-
* const readonlyWallet = await wallet.toReadonly();
|
|
1748
|
-
*
|
|
1749
|
-
* // Can query balance and addresses
|
|
1750
|
-
* const balance = await readonlyWallet.getBalance();
|
|
1751
|
-
* const address = await readonlyWallet.getAddress();
|
|
1752
|
-
*
|
|
1753
|
-
* // But cannot send transactions (type error)
|
|
1754
|
-
* // readonlyWallet.send(...); // TypeScript error
|
|
1755
|
-
* ```
|
|
1756
|
-
*/
|
|
1757
|
-
toReadonly(): Promise<ReadonlyWallet>;
|
|
1758
|
-
/** Returns the delegate manager when delegation support is configured. */
|
|
1759
|
-
getDelegateManager(): Promise<IDelegateManager | undefined>;
|
|
1760
|
-
/** @deprecated alias for @see Wallet.getDelegateManager */
|
|
1761
|
-
getDelegatorManager(): Promise<IDelegateManager | undefined>;
|
|
1762
|
-
/**
|
|
1763
|
-
* Send bitcoin to an Arkade address.
|
|
1764
|
-
*
|
|
1765
|
-
* @deprecated Use `send`.
|
|
1766
|
-
* @param params - Send parameters
|
|
1767
|
-
*/
|
|
1768
|
-
sendBitcoin(params: SendBitcoinParams): Promise<string>;
|
|
1769
|
-
/**
|
|
1770
|
-
* Settle boarding inputs and/or virtual outputs into a finalized mainnet transaction.
|
|
1771
|
-
*
|
|
1772
|
-
* `params.inputs` is **ungated**: whatever the caller names is settled,
|
|
1773
|
-
* including VTXOs generic selection would skip. That is what makes an
|
|
1774
|
-
* escrowed or otherwise gated deposit recoverable by hand — but it also
|
|
1775
|
-
* means `settle({ inputs: await wallet.getVtxos() })` silently bypasses the
|
|
1776
|
-
* gate. Pass {@link getSpendableVtxos} instead when the intent is "settle
|
|
1777
|
-
* whatever is spendable".
|
|
1778
|
-
*
|
|
1779
|
-
* @param params - Optional settlement inputs and outputs. When omitted, the wallet settles all eligible funds.
|
|
1780
|
-
* @param eventCallback - Optional callback invoked for settlement stream events.
|
|
1781
|
-
* @returns The finalized Arkade transaction id
|
|
1782
|
-
*/
|
|
1783
|
-
settle(params?: SettleParams, eventCallback?: (event: SettlementEvent) => void): Promise<string>;
|
|
1784
|
-
private _settleImpl;
|
|
1785
|
-
/**
|
|
1786
|
-
* Rotate the boarding address after a board (rotate-on-board trigger).
|
|
1787
|
-
*
|
|
1788
|
-
* Mirrors {@link WalletReceiveRotator}'s L2 rotation, but driven by a
|
|
1789
|
-
* board instead of a `vtxo_received` event: when a settle consumes at
|
|
1790
|
-
* least one boarding (on-chain) UTXO, the current boarding address has
|
|
1791
|
-
* served its purpose, so we allocate a fresh one via
|
|
1792
|
-
* {@link getNewBoardingAddress}. A settle that consumed only VTXOs (a
|
|
1793
|
-
* renewal / offboard) is not a board and leaves the boarding address
|
|
1794
|
-
* untouched.
|
|
1795
|
-
*
|
|
1796
|
-
* Boarding inputs are the non-VTXO coins (no `script`), the same
|
|
1797
|
-
* discriminator {@link handleSettlementFinalizationEvent} uses; the
|
|
1798
|
-
* `typeof` guard skips the arknote strings settle also accepts.
|
|
1799
|
-
*
|
|
1800
|
-
* No-ops for static / `auto` wallets (no descriptor provider — boarding
|
|
1801
|
-
* stays on its fixed index-0 address). Wallets on a custom
|
|
1802
|
-
* {@link DescriptorProvider} DO rotate here now, where they previously
|
|
1803
|
-
* no-opped — see the behaviour-change note on {@link
|
|
1804
|
-
* getNewBoardingAddress}. Best-effort and non-fatal: the
|
|
1805
|
-
* settle has already committed and its txid must be returned, so a
|
|
1806
|
-
* rotation failure is logged and swallowed rather than thrown. Funds at
|
|
1807
|
-
* the retired boarding address remain discoverable — the old `boarding`
|
|
1808
|
-
* contract stays active and {@link getBoardingUtxos} fans out over the
|
|
1809
|
-
* full historical boarding set.
|
|
1810
|
-
*/
|
|
1811
|
-
private maybeRotateBoardingAfterBoard;
|
|
1812
|
-
private handleSettlementFinalizationEvent;
|
|
1813
|
-
private unsignableBoardingInputError;
|
|
1814
|
-
/**
|
|
1815
|
-
* Create a batch event handler for settlement flows.
|
|
1816
|
-
*
|
|
1817
|
-
* @param intentId - The intent ID.
|
|
1818
|
-
* @param inputs - Inputs used by the intent.
|
|
1819
|
-
* @param expectedRecipients - Expected recipients to validate in the virtual output tree.
|
|
1820
|
-
* @param session - Optional musig2 signing session. When omitted, signing steps are skipped.
|
|
1821
|
-
*/
|
|
1822
|
-
createBatchHandler(intentId: string, inputs: ExtendedCoin[], expectedRecipients: Recipient[], session?: SignerSession): Batch.Handler;
|
|
1823
|
-
/**
|
|
1824
|
-
* Build {@link InputSigningJob}s for a tx whose signable inputs can be
|
|
1825
|
-
* resolved from their own `witnessUtxo.script`. Inputs without a
|
|
1826
|
-
* `witnessUtxo` are silently omitted, mirroring the wallet's
|
|
1827
|
-
* historical silent-skip behaviour for cosigner/connector inputs.
|
|
1828
|
-
*/
|
|
1829
|
-
private inputSigningJobsFromWitnessUtxos;
|
|
1830
|
-
/**
|
|
1831
|
-
* Best-effort upsert of the current settlement intent into the optional
|
|
1832
|
-
* {@link intentRepository}. Never throws into the settle path — intent
|
|
1833
|
-
* persistence is observational and must not break money flow. Preserves
|
|
1834
|
-
* fields already written by the event reducer (state-event ordering).
|
|
1835
|
-
*/
|
|
1836
|
-
private persistIntentSnapshot;
|
|
1837
|
-
/**
|
|
1838
|
-
* @internal Sign an on-chain boarding exit / sweep transaction, routing
|
|
1839
|
-
* each input to the correct key by its `witnessUtxo.script`: the identity
|
|
1840
|
-
* for index-0 / static boarding, the per-index descriptor for a rotated
|
|
1841
|
-
* boarding UTXO (plan §6-III.3). Used by
|
|
1842
|
-
* {@link VtxoManager.sweepExpiredBoardingUtxos}; without it, the
|
|
1843
|
-
* unilateral exit of a rotated boarding UTXO would be signed with the
|
|
1844
|
-
* wrong (index-0) key and rejected.
|
|
1845
|
-
*/
|
|
1846
|
-
signOnchainBoardingTx(tx: Transaction): Promise<Transaction>;
|
|
1847
|
-
safeRegisterIntent(intent: SignedIntent<Intent.RegisterMessage>, inputs: ExtendedCoin[]): Promise<string>;
|
|
1848
|
-
makeRegisterIntentSignature(coins: ExtendedCoin[], outputs: TransactionOutput[], onchainOutputsIndexes: number[], cosignerPubKeys: string[], validAt?: number): Promise<SignedIntent<Intent.RegisterMessage>>;
|
|
1849
|
-
makeDeleteIntentSignature(coins: ExtendedCoin[]): Promise<SignedIntent<Intent.DeleteMessage>>;
|
|
1850
|
-
makeGetPendingTxIntentSignature(coins: ExtendedVirtualCoin[]): Promise<SignedIntent<Intent.GetPendingTxMessage>>;
|
|
1851
|
-
/**
|
|
1852
|
-
* Finalizes pending transactions by retrieving them from the server and finalizing each one.
|
|
1853
|
-
* Skips the server check entirely when no send was interrupted (no pending tx flag set).
|
|
1854
|
-
* @param vtxos - Optional list of virtual outputs to use instead of retrieving them from the server
|
|
1855
|
-
* @returns Array of transaction IDs that were finalized
|
|
1856
|
-
*/
|
|
1857
|
-
finalizePendingTxs(vtxos?: ExtendedVirtualCoin[]): Promise<{
|
|
1858
|
-
finalized: string[];
|
|
1859
|
-
pending: string[];
|
|
1860
|
-
}>;
|
|
1861
|
-
/**
|
|
1862
|
-
* The server unroll scripts a pending checkpoint may legitimately have been
|
|
1863
|
-
* built under: this wallet's configured one, the server's current one, and
|
|
1864
|
-
* one per deprecated signer (same closure, deprecated key). A tx submitted
|
|
1865
|
-
* before a signer rotation was built under the old key, so rebuilding
|
|
1866
|
-
* against the current key alone would leave it pending forever.
|
|
1867
|
-
*/
|
|
1868
|
-
private checkpointUnrollCandidates;
|
|
1869
|
-
private hasPendingTxFlag;
|
|
1870
|
-
private setPendingTxFlag;
|
|
1871
|
-
/**
|
|
1872
|
-
* Create an ArkadeCash bearer instrument.
|
|
1873
|
-
*
|
|
1874
|
-
* Generates a fresh keypair, sends the specified amount to a DefaultVtxo
|
|
1875
|
-
* controlled by the new key, and returns the encoded arkadeCash string.
|
|
1876
|
-
* The receiver can claim the funds using `claimCash()` without ever
|
|
1877
|
-
* sharing their address.
|
|
1878
|
-
*
|
|
1879
|
-
* ArkadeCash is a short-lived instrument: it carries a private key, so it is
|
|
1880
|
-
* meant to be handed over and claimed promptly, not held. A note left
|
|
1881
|
-
* unclaimed past its batch expiry is swept by the server and `claimCash`
|
|
1882
|
-
* can only report it, not move it.
|
|
1883
|
-
*
|
|
1884
|
-
* @param amount - Amount in satoshis to send. Must be a whole number of
|
|
1885
|
-
* sats at or above the dust threshold — a below-dust amount would mint an
|
|
1886
|
-
* OP_RETURN output that is unspendable as cash.
|
|
1887
|
-
* @returns The encoded arkadeCash string (e.g., "arkadecash1...")
|
|
1888
|
-
*/
|
|
1889
|
-
createCash(amount: number): Promise<string>;
|
|
1890
|
-
/**
|
|
1891
|
-
* Claim an ArkadeCash bearer instrument: sweep what can be swept, report the
|
|
1892
|
-
* rest.
|
|
1893
|
-
*
|
|
1894
|
-
* Every spendable VTXO at the arkadeCash address is swept to this wallet in
|
|
1895
|
-
* its own offchain transaction, signed with the key carried by the arkadeCash
|
|
1896
|
-
* string. Nothing is ever persisted: no contract is imported, and the
|
|
1897
|
-
* arkadeCash key is not stored. Anything that cannot be swept — server-swept,
|
|
1898
|
-
* subdust, already claimed, or asset-bearing — is returned in `unclaimed`
|
|
1899
|
-
* with a per-VTXO reason and otherwise ignored.
|
|
1900
|
-
*
|
|
1901
|
-
* The arkadeCash string is the recovery token: a claim interrupted between
|
|
1902
|
-
* submit and finalize is completed by simply re-running `claimCash`, which
|
|
1903
|
-
* drains any pending arkadeCash transaction on the server before sweeping.
|
|
1904
|
-
*
|
|
1905
|
-
* @param cashStr - The encoded arkadeCash string (e.g., "arkadecash1...")
|
|
1906
|
-
* @returns The swept total and the report of what was left behind. The
|
|
1907
|
-
* shape is open: further buckets may be added alongside `unclaimed`.
|
|
1908
|
-
*/
|
|
1909
|
-
claimCash(cashStr: string): Promise<ArkadeCashClaimResult>;
|
|
1910
|
-
/**
|
|
1911
|
-
* Split the VTXOs at an arkadeCash address into the ones the thin sweep can
|
|
1912
|
-
* move and the ones it can only report.
|
|
1913
|
-
*/
|
|
1914
|
-
private classifyCashVtxos;
|
|
1915
|
-
/** Read every page of an unfiltered VTXO query for the given scripts. */
|
|
1916
|
-
private fetchAllVtxos;
|
|
1917
|
-
/**
|
|
1918
|
-
* Complete any sweep a previous `claimCash` registered but never finalized.
|
|
1919
|
-
* A thin variant of {@link finalizePendingTxs}, scoped to the arkadeCash key:
|
|
1920
|
-
* the intent is signed with it, and so are the returned checkpoints.
|
|
1921
|
-
*
|
|
1922
|
-
* A drained sweep is not automatically *ours*. Whoever registered it chose
|
|
1923
|
-
* the destination, so a tx a different claimer left half-finished pays that
|
|
1924
|
-
* claimer — finalizing it is still right (the input is spent either way, and
|
|
1925
|
-
* completing it unsticks the funds), but only the value it actually pays to
|
|
1926
|
-
* `myPkScript` may be counted as claimed here.
|
|
1927
|
-
*
|
|
1928
|
-
* @param vtxos - VTXOs at the arkadeCash contract's own pkScript, spent ones
|
|
1929
|
-
* included (a registered sweep marks its input spent). Any other outpoint —
|
|
1930
|
-
* subdust above all — would make the proof invalid, since it describes every
|
|
1931
|
-
* input by that pkScript.
|
|
1932
|
-
* @returns The number of pending txs finalized, the sats among them paid to
|
|
1933
|
-
* this wallet, and the outpoints those txs consumed to pay it.
|
|
1934
|
-
*/
|
|
1935
|
-
private finalizePendingCashTxs;
|
|
1936
|
-
/** Sum the outputs of an ark tx PSBT that pay the given scriptPubKey. */
|
|
1937
|
-
private arkTxAmountPaidTo;
|
|
1938
|
-
/**
|
|
1939
|
-
* Send BTC and/or assets to one or more recipients, passed either as
|
|
1940
|
-
* variadic `Recipient`s or as a single `SendParams` object — the latter
|
|
1941
|
-
* also carries the virtual outputs to spend.
|
|
1942
|
-
*
|
|
1943
|
-
* @param args - Recipients, or a `SendParams` object
|
|
1944
|
-
* @returns Promise resolving to the Arkade transaction ID
|
|
1945
|
-
* @see SendParams
|
|
1946
|
-
*
|
|
1947
|
-
* @example
|
|
1948
|
-
* ```typescript
|
|
1949
|
-
* const txid = await wallet.send({
|
|
1950
|
-
* address: 'ark1q...',
|
|
1951
|
-
* amount: 1000, // (optional, default to dust) btc amount to send to the output
|
|
1952
|
-
* assets: [{ assetId: 'abc123...', amount: 50n }] // (optional) list of assets to send
|
|
1953
|
-
* });
|
|
1954
|
-
*
|
|
1955
|
-
* // choosing the inputs as well as the outputs
|
|
1956
|
-
* const txid = await wallet.send({
|
|
1957
|
-
* recipients: [{ address: 'ark1q...', amount: 1000 }],
|
|
1958
|
-
* selectedVtxos: mine, // spent as given, nothing added
|
|
1959
|
-
* });
|
|
1960
|
-
* ```
|
|
1961
|
-
*/
|
|
1962
|
-
send(...args: [SendParams] | [Recipient, ...Recipient[]]): Promise<string>;
|
|
1963
|
-
private _sendImpl;
|
|
1964
|
-
/**
|
|
1965
|
-
* Shared tail of every Ark-transaction spend path (`send`, selected-VTXO
|
|
1966
|
-
* `sendBitcoin`, and {@link sendSelectedVtxosToSelf}): hide the inputs from
|
|
1967
|
-
* concurrent `getVtxos()`, build+submit the offchain tx, persist the spent
|
|
1968
|
-
* inputs and any wallet-owned (change / self) output, then release the
|
|
1969
|
-
* pending-spend hold. Callers own coin selection, output construction, and
|
|
1970
|
-
* the synchronous epoch snapshot; this owns the submit/persist sequence.
|
|
1971
|
-
*/
|
|
1972
|
-
private _submitOffchainSpend;
|
|
1973
|
-
/**
|
|
1974
|
-
* @internal Migration primitive (deprecated-signer plan, step 1). Spend an
|
|
1975
|
-
* explicit set of the wallet's own deprecated-signer VTXOs into a single
|
|
1976
|
-
* full-value output on the wallet's *active* signer, through the Ark send
|
|
1977
|
-
* path (not `settle`) so arkd builds checkpoints against the active server
|
|
1978
|
-
* epoch. Consumed in-process by {@link VtxoManager}'s migration pass; not
|
|
1979
|
-
* part of the public `IWallet` API and never accepts boarding `ExtendedCoin`
|
|
1980
|
-
* inputs.
|
|
1981
|
-
*
|
|
1982
|
-
* The caller (`migrateCore`) must have already moved the wallet onto the
|
|
1983
|
-
* active signer (`ensureReceiveOnActiveSigner`) and sized the batch (caps +
|
|
1984
|
-
* dust floor); this method validates the inputs, preserves all input assets
|
|
1985
|
-
* on the self output, and persists the new active-signer VTXO even though
|
|
1986
|
-
* there is no separate change output. It records no `TxSent` history — the
|
|
1987
|
-
* funds never leave the wallet.
|
|
1988
|
-
*/
|
|
1989
|
-
sendSelectedVtxosToSelf(inputs: ExtendedVirtualCoin[], now?: TimeHeight): Promise<string>;
|
|
1990
|
-
/**
|
|
1991
|
-
* Build an offchain transaction from the given inputs and outputs,
|
|
1992
|
-
* sign it, submit to the Arkade provider, and finalize.
|
|
1993
|
-
*
|
|
1994
|
-
* Signs whatever it is handed, ungated — see {@link settle} for the trade.
|
|
1995
|
-
*
|
|
1996
|
-
* @returns The Arkade transaction id and server-signed checkpoint PSBTs (for bookkeeping)
|
|
1997
|
-
*/
|
|
1998
|
-
buildAndSubmitOffchainTx(inputs: ExtendedVirtualCoin[], outputs: TransactionOutput[], serverUnrollScript?: CSVMultisigTapscript.Type): Promise<{
|
|
1999
|
-
arkTxid: string;
|
|
2000
|
-
signedCheckpointTxs: string[];
|
|
2001
|
-
}>;
|
|
2002
|
-
private updateDbAfterOffchainTx;
|
|
2003
|
-
private updateDbAfterSettle;
|
|
2004
|
-
}
|
|
2005
|
-
/**
|
|
2006
|
-
* Select virtual outputs to reach a target amount, prioritizing those closer to expiry
|
|
2007
|
-
* @param coins List of virtual outputs to select from
|
|
2008
|
-
* @param targetAmount Target amount to reach in satoshis
|
|
2009
|
-
* @returns Selected virtual outputs and change amount
|
|
2010
|
-
*/
|
|
2011
|
-
declare function selectVirtualCoins(coins: ExtendedVirtualCoin[], targetAmount: number): {
|
|
2012
|
-
inputs: ExtendedVirtualCoin[];
|
|
2013
|
-
changeAmount: bigint;
|
|
2014
|
-
};
|
|
2015
|
-
/**
|
|
2016
|
-
* Raised when a wait is cancelled through its `AbortSignal` or `timeoutMs`.
|
|
2017
|
-
*
|
|
2018
|
-
* `name` is `"AbortError"`, matching both the platform convention and the
|
|
2019
|
-
* `error.name === "AbortError"` checks the provider layer already makes, so a
|
|
2020
|
-
* caller can treat DOM and SDK aborts identically.
|
|
2021
|
-
*/
|
|
2022
|
-
declare class AbortError extends Error {
|
|
2023
|
-
constructor(message?: string);
|
|
2024
|
-
}
|
|
2025
|
-
/** Options for {@link waitForIncomingFunds}. */
|
|
2026
|
-
interface WaitForIncomingFundsOptions {
|
|
2027
|
-
/**
|
|
2028
|
-
* Cancels the wait. On abort the underlying subscription is stopped and
|
|
2029
|
-
* the returned promise rejects — with the signal's `reason` when the
|
|
2030
|
-
* caller supplied an `Error`, otherwise an {@link AbortError}.
|
|
2031
|
-
*/
|
|
2032
|
-
signal?: AbortSignal;
|
|
2033
|
-
/**
|
|
2034
|
-
* Cancels the wait after this many milliseconds, rejecting with an
|
|
2035
|
-
* {@link AbortError}. Equivalent to passing an `AbortSignal.timeout`
|
|
2036
|
-
* signal, without requiring that API on the target platform.
|
|
2037
|
-
*/
|
|
2038
|
-
timeoutMs?: number;
|
|
2039
|
-
}
|
|
2040
|
-
/**
|
|
2041
|
-
* Wait for incoming funds to the wallet.
|
|
2042
|
-
*
|
|
2043
|
-
* This opens live network watchers (an onchain address subscription plus the
|
|
2044
|
-
* wallet's indexer stream) and keeps them open until it settles. **Cancel it
|
|
2045
|
-
* if you are not going to await it to completion** — pass a `signal` or a
|
|
2046
|
-
* `timeoutMs`. Racing an uncancelled call against a timer (`Promise.race`)
|
|
2047
|
-
* abandons the loser without stopping its watchers, and repeating that in a
|
|
2048
|
-
* loop stacks subscriptions until the process exits.
|
|
2049
|
-
*
|
|
2050
|
-
* @param wallet - The wallet to wait for incoming funds
|
|
2051
|
-
* @param options - Cancellation options; see {@link WaitForIncomingFundsOptions}
|
|
2052
|
-
* @returns A promise that resolves the next new coins received by the wallet's address
|
|
2053
|
-
* @throws {AbortError} If cancelled via `signal` or `timeoutMs`
|
|
2054
|
-
* @example
|
|
2055
|
-
* ```typescript
|
|
2056
|
-
* // Wake early on a deposit, but give up after 30s and release the watchers.
|
|
2057
|
-
* try {
|
|
2058
|
-
* const funds = await waitForIncomingFunds(wallet, { timeoutMs: 30_000 })
|
|
2059
|
-
* } catch (e) {
|
|
2060
|
-
* if ((e as Error).name !== "AbortError") throw e
|
|
2061
|
-
* }
|
|
2062
|
-
* ```
|
|
2063
|
-
*/
|
|
2064
|
-
declare function waitForIncomingFunds(wallet: Wallet, options?: WaitForIncomingFundsOptions): Promise<IncomingFunds>;
|
|
2065
|
-
|
|
2066
|
-
/**
|
|
2067
|
-
* Capability a wallet exposes so descriptor-blind consumers — Boltz swaps and
|
|
2068
|
-
* other plugins — can bind the artifacts they create to the wallet's current
|
|
2069
|
-
* HD index and later enumerate every index that has been used.
|
|
2070
|
-
*
|
|
2071
|
-
* Probed structurally ({@link isHDWalletCapable}) rather than widening
|
|
2072
|
-
* `IWallet`: plugins must keep working against wallets that predate it, and a
|
|
2073
|
-
* static wallet answers "no HD state" through the same three methods.
|
|
2074
|
-
*/
|
|
2075
|
-
interface HDWalletCapable {
|
|
2076
|
-
/**
|
|
2077
|
-
* The descriptor at the wallet's current receive index, or `undefined` for
|
|
2078
|
-
* static / `auto` wallets and HD wallets that have never rotated. Callers
|
|
2079
|
-
* fall back to the identity key.
|
|
2080
|
-
*/
|
|
2081
|
-
getCurrentSigningDescriptor(): Promise<string | undefined>;
|
|
2082
|
-
/**
|
|
2083
|
-
* Every descriptor the wallet may hold keys under, ascending by index:
|
|
2084
|
-
* the allocation watermark's band plus any descriptor persisted on a
|
|
2085
|
-
* contract. Empty for static wallets.
|
|
2086
|
-
*
|
|
2087
|
-
* `lookAhead` appends that many descriptors past the watermark without
|
|
2088
|
-
* advancing it, for a restore that must probe indices no local state
|
|
2089
|
-
* mentions yet.
|
|
2090
|
-
*/
|
|
2091
|
-
getUsedSigningDescriptors(opts?: {
|
|
2092
|
-
lookAhead?: number;
|
|
2093
|
-
}): Promise<string[]>;
|
|
2094
|
-
/**
|
|
2095
|
-
* An {@link Identity} whose keys and signatures are those of `descriptor`.
|
|
2096
|
-
* Returns the wallet identity itself when `descriptor` is the identity's
|
|
2097
|
-
* own key (a static wallet's descriptor, or an HD wallet's baseline key).
|
|
2098
|
-
*
|
|
2099
|
-
* Throws {@link ForeignDescriptorError} for a descriptor this wallet
|
|
2100
|
-
* cannot sign for. Never silently substitutes another key: an identity
|
|
2101
|
-
* handed out for a foreign descriptor signs happily with the wrong key,
|
|
2102
|
-
* and that surfaces only as a rejected transaction or a dead script —
|
|
2103
|
-
* far from the call that caused it.
|
|
2104
|
-
*
|
|
2105
|
-
* The returned identity must actually sign — `sign`, `signMessage` and
|
|
2106
|
-
* `signerSession`, not just `xOnlyPublicKey`. A watch-only identity
|
|
2107
|
-
* carrying the right key is not a signer, and `contractSigner` refuses it
|
|
2108
|
-
* as `WalletCannotSignError`: returning one here would otherwise pass
|
|
2109
|
-
* every check and throw at push time, after the contract is funded.
|
|
2110
|
-
*/
|
|
2111
|
-
signerForDescriptor(descriptor: string): Promise<Identity>;
|
|
2112
|
-
}
|
|
2113
|
-
/**
|
|
2114
|
-
* Thrown by {@link HDWalletCapable.signerForDescriptor} when the wallet holds
|
|
2115
|
-
* no key for the requested descriptor — it belongs to another seed, or to an
|
|
2116
|
-
* identity this wallet does not carry. A typed refusal so callers can tell
|
|
2117
|
-
* "not my key" from transient signing failures.
|
|
2118
|
-
*/
|
|
2119
|
-
declare class ForeignDescriptorError extends Error {
|
|
2120
|
-
readonly descriptor: string;
|
|
2121
|
-
readonly name = "ForeignDescriptorError";
|
|
2122
|
-
constructor(descriptor: string, options?: {
|
|
2123
|
-
cause?: unknown;
|
|
2124
|
-
});
|
|
2125
|
-
}
|
|
2126
|
-
/**
|
|
2127
|
-
* Thrown by `Wallet.getNewAddresses({ forceNew: true })` when the wallet has
|
|
2128
|
-
* no HD stream to advance — `walletMode: 'static'` / `'auto'`, or a
|
|
2129
|
-
* {@link DescriptorProvider} that declined to allocate.
|
|
2130
|
-
*
|
|
2131
|
-
* A typed refusal rather than a silent repeat: a caller that asked for a
|
|
2132
|
-
* *fresh* address is issuing one per counterparty, and quietly returning the
|
|
2133
|
-
* address it already handed out surfaces only as two payers sharing a script.
|
|
2134
|
-
*/
|
|
2135
|
-
declare class WalletCannotAllocateAddressError extends Error {
|
|
2136
|
-
readonly name = "WalletCannotAllocateAddressError";
|
|
2137
|
-
constructor(reason: string, options?: {
|
|
2138
|
-
cause?: unknown;
|
|
2139
|
-
});
|
|
2140
|
-
}
|
|
2141
|
-
/** Anything that can derive and sign for a descriptor it claims. */
|
|
2142
|
-
type DescriptorOwner = Pick<DescriptorProvider, "isOurs" | "signWithDescriptor" | "signMessageWithDescriptor">;
|
|
2143
|
-
/**
|
|
2144
|
-
* The identity that signs `descriptor`, or {@link ForeignDescriptorError}.
|
|
2145
|
-
*
|
|
2146
|
-
* Shared by every {@link HDWalletCapable.signerForDescriptor} implementation
|
|
2147
|
-
* so they cannot drift: the page-side and worker-side wallets answering
|
|
2148
|
-
* differently for one descriptor is a signer that passes a public-key check
|
|
2149
|
-
* and then throws on every signature — after the artifact is funded.
|
|
2150
|
-
*/
|
|
2151
|
-
declare function resolveDescriptorSigner(descriptor: string, identity: Identity, provider?: DescriptorOwner): Promise<Identity>;
|
|
2152
|
-
/** Structural type guard for {@link HDWalletCapable}. */
|
|
2153
|
-
declare function isHDWalletCapable(value: unknown): value is HDWalletCapable;
|
|
2154
|
-
/**
|
|
2155
|
-
* Allocating a *fresh* index, which is strictly more than
|
|
2156
|
-
* {@link HDWalletCapable}'s descriptor awareness.
|
|
2157
|
-
*
|
|
2158
|
-
* Deliberately a separate probe rather than three more methods on
|
|
2159
|
-
* `HDWalletCapable`: widening that guard would silently demote every wallet
|
|
2160
|
-
* implementing only its original surface — including one built by an older
|
|
2161
|
-
* SDK — from HD-capable to static, which is exactly the breakage it documents
|
|
2162
|
-
* itself as avoiding. Consumers that only read descriptors keep the narrow
|
|
2163
|
-
* probe; anything deriving per-artifact secrets asks for this one.
|
|
2164
|
-
*/
|
|
2165
|
-
interface HDAllocationCapable {
|
|
2166
|
-
/**
|
|
2167
|
-
* The signing descriptor a new artifact (a swap, an invoice, a contract)
|
|
2168
|
-
* should bind to. **The wallet decides what that means**: an HD wallet
|
|
2169
|
-
* allocates a fresh index, advancing the watermark; a static wallet
|
|
2170
|
-
* answers with its one `tr(pubkey)` descriptor every time. Consumers must
|
|
2171
|
-
* not probe the wallet's shape or mint key material of their own — they
|
|
2172
|
-
* ask, and use what comes back with
|
|
2173
|
-
* {@link HDWalletCapable.signerForDescriptor}.
|
|
2174
|
-
*
|
|
2175
|
-
* `undefined` only for implementations that genuinely cannot answer;
|
|
2176
|
-
* `Wallet` always answers. Callers that must work against such wallets
|
|
2177
|
-
* fall back to the identity key — never to a random one.
|
|
2178
|
-
*
|
|
2179
|
-
* Distinct from {@link HDWalletCapable.getCurrentSigningDescriptor}, which
|
|
2180
|
-
* peeks: on an HD wallet, two artifacts bound to a peek share a key.
|
|
2181
|
-
* Whether the returned descriptor is unique per call is a property of the
|
|
2182
|
-
* wallet, not of this method — anything deriving per-artifact secrets
|
|
2183
|
-
* from the descriptor must check the descriptor's shape, not the wallet's.
|
|
2184
|
-
*/
|
|
2185
|
-
getNextSigningDescriptor(): Promise<string | undefined>;
|
|
2186
|
-
/**
|
|
2187
|
-
* Move the allocation watermark to `descriptor`'s index so later
|
|
2188
|
-
* allocations cannot reissue it. Monotonic — a lower index is a no-op.
|
|
2189
|
-
* On a static wallet there is no watermark: the wallet's own descriptor
|
|
2190
|
-
* is accepted as a no-op.
|
|
2191
|
-
*
|
|
2192
|
-
* Throws on a descriptor this wallet cannot derive, or an HD descriptor
|
|
2193
|
-
* with no parseable trailing child index: silently mapping those to index
|
|
2194
|
-
* 0 would move the watermark nowhere and let a restored artifact's index
|
|
2195
|
-
* be handed out again.
|
|
2196
|
-
*/
|
|
2197
|
-
advanceSigningDescriptorWatermark(descriptor: string): Promise<void>;
|
|
2198
|
-
}
|
|
2199
|
-
/** Structural type guard for {@link HDAllocationCapable}. */
|
|
2200
|
-
declare function isHDAllocationCapable(value: unknown): value is HDAllocationCapable;
|
|
2201
|
-
/**
|
|
2202
|
-
* Minting addresses to hand out, which is strictly more than
|
|
2203
|
-
* {@link HDAllocationCapable}'s bare index allocation: the wallet also builds
|
|
2204
|
-
* the scripts at that index, persists them as watched contracts, and reports
|
|
2205
|
-
* the rows.
|
|
2206
|
-
*
|
|
2207
|
-
* A third probe rather than another method on `HDAllocationCapable`, for the
|
|
2208
|
-
* same reason that interface exists separately from {@link HDWalletCapable}:
|
|
2209
|
-
* widening an existing guard silently demotes every wallet implementing only
|
|
2210
|
-
* its older surface.
|
|
2211
|
-
*/
|
|
2212
|
-
interface AddressAllocationCapable {
|
|
2213
|
-
/**
|
|
2214
|
-
* Fresh addresses of each requested type, all derived from one newly
|
|
2215
|
-
* allocated HD index, persisted and watched. **The wallet decides what
|
|
2216
|
-
* "fresh" means**: an HD wallet burns an index, a wallet with no stream
|
|
2217
|
-
* answers with its existing display addresses — or, under
|
|
2218
|
-
* `forceNew`, refuses with {@link WalletCannotAllocateAddressError}
|
|
2219
|
-
* rather than repeat an address it already handed out.
|
|
2220
|
-
*
|
|
2221
|
-
* Distinct from {@link HDAllocationCapable.getNextSigningDescriptor},
|
|
2222
|
-
* which yields only an index and leaves the caller to build and register
|
|
2223
|
-
* the script — two steps that must not be split across a process
|
|
2224
|
-
* boundary, since a page that allocated an index and then failed to
|
|
2225
|
-
* register the script holds a burnt index and an unwatched address.
|
|
2226
|
-
*/
|
|
2227
|
-
getNewAddresses(opts?: GetNewAddressesOptions): Promise<NewAddress[]>;
|
|
2228
|
-
}
|
|
2229
|
-
/** Structural type guard for {@link AddressAllocationCapable}. */
|
|
2230
|
-
declare function isAddressAllocationCapable(value: unknown): value is AddressAllocationCapable;
|
|
2231
|
-
|
|
2232
|
-
export { type AddressAllocationCapable as A, type BatchExpiryPolicy as B, type CheckpointExitDelayPolicy as C, DEFAULT_MIN_BATCH_EXPIRY_SECONDS as D, defaultCheckpointExitDelayPolicy as E, ForeignDescriptorError as F, isAddressAllocationCapable as G, type HDWalletCapable as H, type IncomingFunds as I, isArkError as J, isHDAllocationCapable as K, isHDWalletCapable as L, MAX_USED_SIGNING_DESCRIPTORS_LOOK_AHEAD as M, maybeArkError as N, resolveBatchExpiryPolicy as O, type ProviderConnectionState as P, resolveCheckpointExitDelayPolicy as Q, ReadonlyWallet as R, SIGNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS as S, resolveDescriptorSigner as T, selectVirtualCoins as U, signingDescriptorIndex as V, Wallet as W, strictSigningDescriptorIndex as X, waitForIncomingFunds as Y, type HDAllocationCapable as a, type ReceiveRotatorFactory as b, type ReceiveRotatorBootOpts as c, type ReceiveRotatorBoot as d, Batch as e, AbortError as f, ArkError as g, ArkErrorName as h, type ArkadeCashClaimResult as i, ArkadeCashCreateError as j, type ArkadeCashUnclaimedReason as k, type ArkadeCashUnclaimedVtxo as l, type BoardingUtxoGroup as m, DEFAULT_MIN_CHECKPOINT_EXIT_DELAY_SECONDS as n, MUTINYNET_MIN_CHECKPOINT_EXIT_DELAY_SECONDS as o, type ProviderKind as p, ProviderUnavailableError as q, REGTEST_MIN_BATCH_EXPIRY_SECONDS as r, REGTEST_MIN_CHECKPOINT_EXIT_DELAY_SECONDS as s, type ServerInfoSource as t, ServerResponseMismatchError as u, type WaitForIncomingFundsOptions as v, WalletCannotAllocateAddressError as w, assertValidBatchExpiry as x, assertValidServerUnrollScript as y, defaultBatchExpiryPolicy as z };
|