@quaivault/sdk 0.1.0
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/LICENSE +21 -0
- package/README.md +387 -0
- package/dist/abi/index.cjs +3349 -0
- package/dist/abi/index.cjs.map +1 -0
- package/dist/abi/index.d.cts +21 -0
- package/dist/abi/index.d.ts +21 -0
- package/dist/abi/index.js +23 -0
- package/dist/abi/index.js.map +1 -0
- package/dist/chunk-Y3PVKON6.js +3334 -0
- package/dist/chunk-Y3PVKON6.js.map +1 -0
- package/dist/index.cjs +7884 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +2271 -0
- package/dist/index.d.ts +2271 -0
- package/dist/index.js +4549 -0
- package/dist/index.js.map +1 -0
- package/package.json +75 -0
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,2271 @@
|
|
|
1
|
+
import * as quais from 'quais';
|
|
2
|
+
import { Provider, Signer, Contract, Interface } from 'quais';
|
|
3
|
+
export { Provider, Signer } from 'quais';
|
|
4
|
+
import * as _supabase_postgrest_js from '@supabase/postgrest-js';
|
|
5
|
+
import { SupabaseClient } from '@supabase/supabase-js';
|
|
6
|
+
import { z } from 'zod';
|
|
7
|
+
export { Erc1155Abi, Erc20Abi, Erc721Abi, MultiSendCallOnlyAbi, QuaiVaultAbi, QuaiVaultFactoryAbi, QuaiVaultProxyAbi, QuaiVaultProxyBytecode, SocialRecoveryModuleAbi } from './abi/index.cjs';
|
|
8
|
+
|
|
9
|
+
declare const mainnet: NetworkConfig;
|
|
10
|
+
declare const testnet: NetworkConfig;
|
|
11
|
+
declare const networks: {
|
|
12
|
+
readonly mainnet: NetworkConfig;
|
|
13
|
+
readonly testnet: NetworkConfig;
|
|
14
|
+
};
|
|
15
|
+
type NetworkName = keyof typeof networks;
|
|
16
|
+
declare function isNetworkName(value: unknown): value is NetworkName;
|
|
17
|
+
|
|
18
|
+
type Address = string;
|
|
19
|
+
type Hex = string;
|
|
20
|
+
type Bytes32 = string;
|
|
21
|
+
|
|
22
|
+
/** Zodiac IAvatar operation type. Mirrors `Enum.Operation` in the contracts. */
|
|
23
|
+
declare enum Operation {
|
|
24
|
+
Call = 0,
|
|
25
|
+
DelegateCall = 1
|
|
26
|
+
}
|
|
27
|
+
interface ContractAddresses {
|
|
28
|
+
implementation: Address;
|
|
29
|
+
factory: Address;
|
|
30
|
+
socialRecovery?: Address;
|
|
31
|
+
multiSendCallOnly?: Address;
|
|
32
|
+
}
|
|
33
|
+
interface IndexerConfig {
|
|
34
|
+
/** Supabase project URL. */
|
|
35
|
+
url: string;
|
|
36
|
+
/** Public anon key. Read-only by RLS policy — safe to distribute. */
|
|
37
|
+
anonKey: string;
|
|
38
|
+
/** Postgres schema for this network (`mainnet`, `testnet`, `dev`). */
|
|
39
|
+
schema: string;
|
|
40
|
+
/** Base URL of the indexer health server, used for lag/liveness checks. */
|
|
41
|
+
healthUrl?: string;
|
|
42
|
+
}
|
|
43
|
+
interface NetworkConfig {
|
|
44
|
+
name: string;
|
|
45
|
+
chainId: number;
|
|
46
|
+
rpcUrl: string;
|
|
47
|
+
explorerUrl?: string;
|
|
48
|
+
contracts: ContractAddresses;
|
|
49
|
+
indexer?: IndexerConfig;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* How reads resolve between the indexer and the chain.
|
|
53
|
+
*
|
|
54
|
+
* - `indexed` — indexer only. Fastest; may be stale; fails if the indexer is down.
|
|
55
|
+
* - `chain` — RPC only. Authoritative; slower; some history queries are unavailable.
|
|
56
|
+
* - `auto` — indexer when it is fresh enough (see {@link ClientOptions.maxIndexerLagBlocks}),
|
|
57
|
+
* otherwise the chain. This is the default.
|
|
58
|
+
*
|
|
59
|
+
* Write paths always re-validate preconditions against the chain regardless of this
|
|
60
|
+
* setting — indexed approval counts can diverge from on-chain reality after an owner
|
|
61
|
+
* is removed (approval epochs), so they must never gate a signature.
|
|
62
|
+
*/
|
|
63
|
+
type Consistency = 'auto' | 'indexed' | 'chain';
|
|
64
|
+
interface ClientOptions {
|
|
65
|
+
network?: NetworkConfig | keyof typeof networks;
|
|
66
|
+
provider?: Provider;
|
|
67
|
+
signer?: Signer;
|
|
68
|
+
/** Private key for a local signer. Prefer the `QUAIVAULT_PRIVATE_KEY` env var. */
|
|
69
|
+
privateKey?: string;
|
|
70
|
+
rpcUrl?: string;
|
|
71
|
+
indexer?: Partial<IndexerConfig>;
|
|
72
|
+
contracts?: Partial<ContractAddresses>;
|
|
73
|
+
consistency?: Consistency;
|
|
74
|
+
/** Beyond this many blocks behind, `auto` reads fall through to the chain. Default 50. */
|
|
75
|
+
maxIndexerLagBlocks?: number;
|
|
76
|
+
/** Read env vars for anything not passed explicitly. Default true. */
|
|
77
|
+
useEnv?: boolean;
|
|
78
|
+
/**
|
|
79
|
+
* Retry policy for transient RPC and indexer failures. Applies to reads only —
|
|
80
|
+
* writes are never retried, since a resubmit risks a double broadcast.
|
|
81
|
+
*/
|
|
82
|
+
retry?: {
|
|
83
|
+
maxAttempts?: number;
|
|
84
|
+
baseDelayMs?: number;
|
|
85
|
+
maxDelayMs?: number;
|
|
86
|
+
onRetry?: (info: {
|
|
87
|
+
attempt: number;
|
|
88
|
+
delayMs: number;
|
|
89
|
+
error: unknown;
|
|
90
|
+
}) => void;
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
interface VaultInfo {
|
|
94
|
+
address: Address;
|
|
95
|
+
owners: Address[];
|
|
96
|
+
threshold: number;
|
|
97
|
+
/** Vault-level minimum timelock for external calls, in seconds. 0 = simple quorum. */
|
|
98
|
+
minExecutionDelay: number;
|
|
99
|
+
nonce: number;
|
|
100
|
+
balance: bigint;
|
|
101
|
+
moduleCount: number;
|
|
102
|
+
}
|
|
103
|
+
type TransactionKind = 'transfer' | 'erc20_transfer' | 'erc721_transfer' | 'erc1155_transfer' | 'wallet_admin' | 'module_config' | 'module_execution' | 'message_signing' | 'recovery_setup' | 'batched_call' | 'external_call' | 'unknown';
|
|
104
|
+
/**
|
|
105
|
+
* Lifecycle state of a vault transaction.
|
|
106
|
+
*
|
|
107
|
+
* `ready` and `timelocked` are SDK-derived refinements of the contract's "pending":
|
|
108
|
+
* both mean not-yet-executed with quorum reached, differing only on whether the
|
|
109
|
+
* execution delay has elapsed.
|
|
110
|
+
*/
|
|
111
|
+
type TransactionStatus = 'pending' | 'timelocked' | 'ready' | 'executed' | 'failed' | 'cancelled' | 'expired';
|
|
112
|
+
interface ApprovalRecord {
|
|
113
|
+
owner: Address;
|
|
114
|
+
/** Whether this approval currently counts toward the threshold. */
|
|
115
|
+
active: boolean;
|
|
116
|
+
}
|
|
117
|
+
interface DecodedCall {
|
|
118
|
+
/** Function name, e.g. `addOwner`. */
|
|
119
|
+
name: string;
|
|
120
|
+
signature: string;
|
|
121
|
+
args: Record<string, unknown>;
|
|
122
|
+
/** Contract the selector was resolved against. */
|
|
123
|
+
target: 'vault' | 'socialRecovery' | 'multiSend' | 'erc20' | 'erc721' | 'erc1155';
|
|
124
|
+
}
|
|
125
|
+
interface VaultTransaction {
|
|
126
|
+
hash: Bytes32;
|
|
127
|
+
vault: Address;
|
|
128
|
+
to: Address;
|
|
129
|
+
value: bigint;
|
|
130
|
+
data: Hex;
|
|
131
|
+
proposer: Address;
|
|
132
|
+
/** Unix seconds when the proposal was recorded on chain. */
|
|
133
|
+
proposedAt: number;
|
|
134
|
+
kind: TransactionKind;
|
|
135
|
+
decoded?: DecodedCall;
|
|
136
|
+
/** One-line human-readable description. */
|
|
137
|
+
summary: string;
|
|
138
|
+
status: TransactionStatus;
|
|
139
|
+
approvals: ApprovalRecord[];
|
|
140
|
+
/** Count of approvals that currently count toward the threshold. */
|
|
141
|
+
approvalCount: number;
|
|
142
|
+
threshold: number;
|
|
143
|
+
/** Unix seconds after which the tx can no longer execute. 0 = never expires. */
|
|
144
|
+
expiration: number;
|
|
145
|
+
/** Seconds of timelock locked in at proposal time. */
|
|
146
|
+
executionDelay: number;
|
|
147
|
+
/** Unix seconds when quorum was first reached. 0 = never reached. */
|
|
148
|
+
approvedAt: number;
|
|
149
|
+
/** `approvedAt + executionDelay`, or 0 if the clock has not started. */
|
|
150
|
+
executableAfter: number;
|
|
151
|
+
/** Raw revert data from a `TransactionFailed` event. */
|
|
152
|
+
failedReturnData?: Hex;
|
|
153
|
+
decodedRevert?: DecodedRevert;
|
|
154
|
+
/** Where this record came from. */
|
|
155
|
+
source: 'indexer' | 'chain';
|
|
156
|
+
/** Indexer head at read time; absent for chain reads. */
|
|
157
|
+
indexedAtBlock?: number;
|
|
158
|
+
}
|
|
159
|
+
interface DecodedRevert {
|
|
160
|
+
/** Custom error name, or `Error` / `Panic` for the builtins. */
|
|
161
|
+
name: string;
|
|
162
|
+
args: unknown[];
|
|
163
|
+
selector: Hex;
|
|
164
|
+
/** Human-readable rendering. */
|
|
165
|
+
message: string;
|
|
166
|
+
}
|
|
167
|
+
interface ProposeOptions {
|
|
168
|
+
/** Unix seconds after which the tx can no longer execute. 0 / omitted = no expiry. */
|
|
169
|
+
expiration?: number;
|
|
170
|
+
/** Extra delay beyond the vault floor, in seconds. */
|
|
171
|
+
executionDelay?: number;
|
|
172
|
+
/** Build and return the call without signing. */
|
|
173
|
+
dryRun?: boolean;
|
|
174
|
+
}
|
|
175
|
+
interface ProposeResult {
|
|
176
|
+
/** The vault-transaction hash (bytes32), not the Quai transaction hash. */
|
|
177
|
+
txHash: Bytes32;
|
|
178
|
+
/** The on-chain Quai transaction hash that carried the proposal. */
|
|
179
|
+
chainTxHash: Hex;
|
|
180
|
+
to: Address;
|
|
181
|
+
value: bigint;
|
|
182
|
+
data: Hex;
|
|
183
|
+
}
|
|
184
|
+
/** Result of a dry-run write: everything needed to inspect or submit later. */
|
|
185
|
+
interface DryRunResult {
|
|
186
|
+
dryRun: true;
|
|
187
|
+
to: Address;
|
|
188
|
+
data: Hex;
|
|
189
|
+
value: bigint;
|
|
190
|
+
/** Estimated gas, or null if estimation reverted. */
|
|
191
|
+
gasEstimate: bigint | null;
|
|
192
|
+
/** Decoded revert if estimation failed. */
|
|
193
|
+
wouldRevert?: DecodedRevert;
|
|
194
|
+
description: string;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Outcome of an execute attempt.
|
|
198
|
+
*
|
|
199
|
+
* A successful Quai transaction receipt does NOT imply the vault transaction ran.
|
|
200
|
+
* See `docs/execution-outcomes.md`.
|
|
201
|
+
*/
|
|
202
|
+
type ExecuteOutcome = 'executed' | 'failed' | 'timelock_started' | 'approved_only';
|
|
203
|
+
interface ExecuteResult {
|
|
204
|
+
outcome: ExecuteOutcome;
|
|
205
|
+
txHash: Bytes32;
|
|
206
|
+
chainTxHash: Hex;
|
|
207
|
+
blockNumber: number;
|
|
208
|
+
gasUsed: bigint;
|
|
209
|
+
/** Set when `outcome === 'failed'`. */
|
|
210
|
+
returnData?: Hex;
|
|
211
|
+
decodedRevert?: DecodedRevert;
|
|
212
|
+
/** Set when `outcome === 'timelock_started'`. Unix seconds. */
|
|
213
|
+
executableAfter?: number;
|
|
214
|
+
/** Set when `outcome === 'approved_only'`. */
|
|
215
|
+
approvalsNeeded?: number;
|
|
216
|
+
/** Human-readable explanation of what happened and what to do next. */
|
|
217
|
+
message: string;
|
|
218
|
+
}
|
|
219
|
+
type VaultAction = 'approve' | 'revokeApproval' | 'execute' | 'approveAndExecute' | 'cancel' | 'expire' | 'proposeCancelByConsensus';
|
|
220
|
+
type AffordanceBlocker = 'not_owner' | 'already_approved' | 'not_approved' | 'threshold' | 'timelock' | 'expired' | 'terminal_state' | 'quorum_locked' | 'not_proposer' | 'no_expiration';
|
|
221
|
+
interface Affordance {
|
|
222
|
+
action: VaultAction;
|
|
223
|
+
allowed: boolean;
|
|
224
|
+
/** Plain-language explanation, suitable for surfacing directly to a user. */
|
|
225
|
+
reason: string;
|
|
226
|
+
/** Unix seconds when a time gate lifts, if the only blocker is time. */
|
|
227
|
+
availableAt?: number;
|
|
228
|
+
blockedBy?: AffordanceBlocker;
|
|
229
|
+
}
|
|
230
|
+
interface CreateVaultParams {
|
|
231
|
+
owners: Address[];
|
|
232
|
+
threshold: number;
|
|
233
|
+
/** Vault-level minimum timelock in seconds. Max 30 days. Default 0. */
|
|
234
|
+
minExecutionDelay?: number;
|
|
235
|
+
/** Modules enabled at deploy time. */
|
|
236
|
+
initialModules?: Address[];
|
|
237
|
+
/** DelegateCall whitelist entries. Empty (default) means DelegateCall is disabled. */
|
|
238
|
+
initialDelegatecallTargets?: Address[];
|
|
239
|
+
/** Pre-mined salt. Omit to mine one automatically. */
|
|
240
|
+
salt?: Bytes32;
|
|
241
|
+
}
|
|
242
|
+
interface MinedSalt {
|
|
243
|
+
salt: Bytes32;
|
|
244
|
+
predictedAddress: Address;
|
|
245
|
+
attempts: number;
|
|
246
|
+
durationMs: number;
|
|
247
|
+
}
|
|
248
|
+
interface CreateVaultResult {
|
|
249
|
+
address: Address;
|
|
250
|
+
chainTxHash: Hex;
|
|
251
|
+
salt: Bytes32;
|
|
252
|
+
/** Whether the deployed address matched the mined prediction. */
|
|
253
|
+
predictionMatched: boolean;
|
|
254
|
+
}
|
|
255
|
+
interface RecoveryConfig {
|
|
256
|
+
guardians: Address[];
|
|
257
|
+
/** Guardian approvals required to execute a recovery. */
|
|
258
|
+
threshold: number;
|
|
259
|
+
/** Delay in seconds between initiation and executability. */
|
|
260
|
+
recoveryPeriod: number;
|
|
261
|
+
/** False when the vault has no recovery configured. */
|
|
262
|
+
configured: boolean;
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Lifecycle state of a recovery request.
|
|
266
|
+
*
|
|
267
|
+
* `cancelled` is only ever reported from the indexer: `cancelRecovery` deletes the
|
|
268
|
+
* on-chain struct, so a chain read cannot distinguish a cancelled recovery from one
|
|
269
|
+
* that never existed.
|
|
270
|
+
*/
|
|
271
|
+
type RecoveryStatus = 'pending' | 'timelocked' | 'ready' | 'executed' | 'cancelled' | 'expired';
|
|
272
|
+
interface RecoveryRequest {
|
|
273
|
+
hash: Bytes32;
|
|
274
|
+
vault: Address;
|
|
275
|
+
newOwners: Address[];
|
|
276
|
+
newThreshold: number;
|
|
277
|
+
approvalCount: number;
|
|
278
|
+
/** Threshold captured at initiation — config changes mid-recovery do not move it. */
|
|
279
|
+
requiredThreshold: number;
|
|
280
|
+
/** Unix seconds after which execution is permitted. */
|
|
281
|
+
executionTime: number;
|
|
282
|
+
/** Unix seconds after which the recovery is dead and can be cleaned up. */
|
|
283
|
+
expiration: number;
|
|
284
|
+
status: RecoveryStatus;
|
|
285
|
+
executed: boolean;
|
|
286
|
+
/** Guardians who have approved. Only populated on indexer reads. */
|
|
287
|
+
approvedBy?: Address[];
|
|
288
|
+
initiator?: Address;
|
|
289
|
+
source: 'indexer' | 'chain';
|
|
290
|
+
}
|
|
291
|
+
type RecoveryAction = 'approve' | 'revokeApproval' | 'execute' | 'cancel' | 'expire';
|
|
292
|
+
interface RecoveryAffordance {
|
|
293
|
+
action: RecoveryAction;
|
|
294
|
+
allowed: boolean;
|
|
295
|
+
reason: string;
|
|
296
|
+
availableAt?: number;
|
|
297
|
+
blockedBy?: 'not_guardian' | 'not_owner' | 'already_approved' | 'not_approved' | 'threshold' | 'timelock' | 'expired' | 'not_expired' | 'terminal_state' | 'module_disabled';
|
|
298
|
+
}
|
|
299
|
+
interface Pagination {
|
|
300
|
+
limit?: number;
|
|
301
|
+
offset?: number;
|
|
302
|
+
}
|
|
303
|
+
interface Page<T> {
|
|
304
|
+
data: T[];
|
|
305
|
+
total: number;
|
|
306
|
+
hasMore: boolean;
|
|
307
|
+
}
|
|
308
|
+
interface IndexerHealth {
|
|
309
|
+
available: boolean;
|
|
310
|
+
lastIndexedBlock: number;
|
|
311
|
+
chainHead?: number;
|
|
312
|
+
blocksBehind?: number;
|
|
313
|
+
isSyncing: boolean;
|
|
314
|
+
/** Reason the indexer was judged unavailable. */
|
|
315
|
+
error?: string;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Retry policy for transient RPC and indexer failures.
|
|
320
|
+
*
|
|
321
|
+
* Scoped deliberately to **reads**. Retrying a write risks broadcasting the same
|
|
322
|
+
* transaction twice — a resubmit that looks like a timeout to the client may already
|
|
323
|
+
* be in the mempool — so every write path in this SDK calls through unretried.
|
|
324
|
+
*/
|
|
325
|
+
interface RetryOptions {
|
|
326
|
+
/** Total attempts including the first. Default 3. */
|
|
327
|
+
maxAttempts?: number;
|
|
328
|
+
/** First backoff delay. Doubles each attempt. Default 250ms. */
|
|
329
|
+
baseDelayMs?: number;
|
|
330
|
+
/** Ceiling on any single backoff. Default 4000ms. */
|
|
331
|
+
maxDelayMs?: number;
|
|
332
|
+
signal?: AbortSignal;
|
|
333
|
+
onRetry?: (info: {
|
|
334
|
+
attempt: number;
|
|
335
|
+
delayMs: number;
|
|
336
|
+
error: unknown;
|
|
337
|
+
}) => void;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* Whether an error is worth retrying.
|
|
341
|
+
*
|
|
342
|
+
* Errs toward *not* retrying: an unrecognised error is treated as permanent, so a
|
|
343
|
+
* genuine bug surfaces immediately instead of being masked by three slow attempts.
|
|
344
|
+
*/
|
|
345
|
+
declare function isTransient(error: unknown): boolean;
|
|
346
|
+
/**
|
|
347
|
+
* Run `fn`, retrying transient failures with exponential backoff and full jitter.
|
|
348
|
+
*
|
|
349
|
+
* Jitter matters more than usual here: several vaults refreshing on the same tick
|
|
350
|
+
* would otherwise retry in lockstep and hammer a rate-limited endpoint in waves.
|
|
351
|
+
*/
|
|
352
|
+
declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
353
|
+
|
|
354
|
+
/**
|
|
355
|
+
* Environment variables read when `useEnv` is not disabled.
|
|
356
|
+
*
|
|
357
|
+
* Explicit `ClientOptions` always win over the environment; the environment always
|
|
358
|
+
* wins over the network preset. Nothing here is read at module load — resolution
|
|
359
|
+
* happens inside `connect()`, so importing the SDK never touches `process.env`.
|
|
360
|
+
*/
|
|
361
|
+
declare const ENV_VARS: {
|
|
362
|
+
readonly network: "QUAIVAULT_NETWORK";
|
|
363
|
+
readonly rpcUrl: "QUAIVAULT_RPC_URL";
|
|
364
|
+
readonly privateKey: "QUAIVAULT_PRIVATE_KEY";
|
|
365
|
+
readonly indexerUrl: "QUAIVAULT_INDEXER_URL";
|
|
366
|
+
readonly indexerAnonKey: "QUAIVAULT_INDEXER_ANON_KEY";
|
|
367
|
+
readonly indexerSchema: "QUAIVAULT_INDEXER_SCHEMA";
|
|
368
|
+
readonly indexerHealthUrl: "QUAIVAULT_INDEXER_HEALTH_URL";
|
|
369
|
+
readonly factory: "QUAIVAULT_FACTORY";
|
|
370
|
+
readonly implementation: "QUAIVAULT_IMPLEMENTATION";
|
|
371
|
+
readonly socialRecovery: "QUAIVAULT_SOCIAL_RECOVERY_MODULE";
|
|
372
|
+
readonly multiSendCallOnly: "QUAIVAULT_MULTISEND_CALL_ONLY";
|
|
373
|
+
readonly consistency: "QUAIVAULT_CONSISTENCY";
|
|
374
|
+
readonly maxIndexerLagBlocks: "QUAIVAULT_MAX_INDEXER_LAG_BLOCKS";
|
|
375
|
+
};
|
|
376
|
+
interface ResolvedConfig {
|
|
377
|
+
network: NetworkConfig;
|
|
378
|
+
contracts: ContractAddresses;
|
|
379
|
+
indexer?: IndexerConfig;
|
|
380
|
+
rpcUrl: string;
|
|
381
|
+
/**
|
|
382
|
+
* ⚠️ Secret. Consumed once to build a signer and never retained afterwards.
|
|
383
|
+
*
|
|
384
|
+
* Never log or serialise a `ResolvedConfig` that still carries this — use
|
|
385
|
+
* {@link redactConfig}, which is what `QuaiVaultClient.config` exposes.
|
|
386
|
+
*/
|
|
387
|
+
privateKey?: string;
|
|
388
|
+
consistency: Consistency;
|
|
389
|
+
maxIndexerLagBlocks: number;
|
|
390
|
+
retry: RetryOptions;
|
|
391
|
+
}
|
|
392
|
+
/** A `ResolvedConfig` with the private key removed. Safe to log. */
|
|
393
|
+
type PublicConfig = Omit<ResolvedConfig, 'privateKey'> & {
|
|
394
|
+
privateKey?: never;
|
|
395
|
+
};
|
|
396
|
+
/**
|
|
397
|
+
* Merge, in order of decreasing precedence: explicit options → environment →
|
|
398
|
+
* network preset defaults.
|
|
399
|
+
*/
|
|
400
|
+
declare function resolveConfig(options?: ClientOptions): ResolvedConfig;
|
|
401
|
+
|
|
402
|
+
/**
|
|
403
|
+
* Owns the provider/signer pair and hands out contract instances.
|
|
404
|
+
*
|
|
405
|
+
* Quai RPC endpoints are shard-pathed (`https://host/cyprus1`), which `quais`
|
|
406
|
+
* handles via `usePathing: true` — the same setting the indexer uses.
|
|
407
|
+
*/
|
|
408
|
+
declare class Connection {
|
|
409
|
+
readonly provider: Provider;
|
|
410
|
+
/** Retry policy for reads. Shared with every contract facade this hands out. */
|
|
411
|
+
readonly retry: RetryOptions;
|
|
412
|
+
private readonly _signer;
|
|
413
|
+
constructor(config: ResolvedConfig, explicit?: {
|
|
414
|
+
provider?: Provider;
|
|
415
|
+
signer?: Signer;
|
|
416
|
+
});
|
|
417
|
+
get signer(): Signer | null;
|
|
418
|
+
hasSigner(): boolean;
|
|
419
|
+
/** The signer, or a typed error naming the operation that needs one. */
|
|
420
|
+
requireSigner(operation: string): Signer;
|
|
421
|
+
address(): Promise<Address>;
|
|
422
|
+
/** Connected address, or null when read-only. */
|
|
423
|
+
addressOrNull(): Promise<Address | null>;
|
|
424
|
+
vault(address: Address, write?: boolean): Contract;
|
|
425
|
+
factory(address: Address, write?: boolean): Contract;
|
|
426
|
+
socialRecovery(address: Address, write?: boolean): Contract;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
interface MineSaltOptions {
|
|
430
|
+
factory: Address;
|
|
431
|
+
implementation: Address;
|
|
432
|
+
/** Address that will call `createWallet`. The mined address lands on its shard. */
|
|
433
|
+
deployer: Address;
|
|
434
|
+
params: CreateVaultParams;
|
|
435
|
+
/** Override the target shard prefix. Defaults to the deployer's. */
|
|
436
|
+
targetPrefix?: string;
|
|
437
|
+
maxAttempts?: number;
|
|
438
|
+
/** Abort after this long. Default 120_000 ms. */
|
|
439
|
+
timeoutMs?: number;
|
|
440
|
+
/** Called roughly every 1000 attempts. */
|
|
441
|
+
onProgress?: (attempts: number) => void;
|
|
442
|
+
signal?: AbortSignal;
|
|
443
|
+
}
|
|
444
|
+
interface MiningStrategy {
|
|
445
|
+
readonly name: string;
|
|
446
|
+
mine(options: Required<Pick<MineSaltOptions, 'factory' | 'deployer'>> & ResolvedMineJob): Promise<MinedSalt>;
|
|
447
|
+
}
|
|
448
|
+
/** Everything the inner loop needs, precomputed once. */
|
|
449
|
+
interface ResolvedMineJob {
|
|
450
|
+
bytecodeHash: Bytes32;
|
|
451
|
+
targetPrefix: string;
|
|
452
|
+
maxAttempts: number;
|
|
453
|
+
timeoutMs: number;
|
|
454
|
+
onProgress?: (attempts: number) => void;
|
|
455
|
+
signal?: AbortSignal;
|
|
456
|
+
}
|
|
457
|
+
/**
|
|
458
|
+
* Chunked single-threaded miner. Yields to the event loop between chunks so it does
|
|
459
|
+
* not block a browser UI thread or a Node server's other work.
|
|
460
|
+
*
|
|
461
|
+
* Works everywhere, which makes it the safe default.
|
|
462
|
+
*/
|
|
463
|
+
declare const syncStrategy: MiningStrategy;
|
|
464
|
+
/**
|
|
465
|
+
* Node-only multi-core miner. Falls back to {@link syncStrategy} when
|
|
466
|
+
* `node:worker_threads` is unavailable (browsers, restricted runtimes).
|
|
467
|
+
*/
|
|
468
|
+
declare const workerThreadsStrategy: MiningStrategy;
|
|
469
|
+
/** Prefer worker_threads on Node; the sync miner degrades gracefully everywhere else. */
|
|
470
|
+
declare function defaultStrategy(): MiningStrategy;
|
|
471
|
+
/**
|
|
472
|
+
* Mine a CREATE2 salt that deploys a vault onto the deployer's Quai shard.
|
|
473
|
+
*
|
|
474
|
+
* The predicted address is a pure function of (factory, implementation, deployer,
|
|
475
|
+
* salt, create params) — so the caller can mine ahead of time, persist the salt,
|
|
476
|
+
* and deploy later, as long as every one of those inputs is unchanged.
|
|
477
|
+
*/
|
|
478
|
+
declare function mineSalt(options: MineSaltOptions, strategy?: MiningStrategy): Promise<MinedSalt>;
|
|
479
|
+
|
|
480
|
+
interface CreateProgress {
|
|
481
|
+
step: 'validating' | 'mining' | 'deploying' | 'confirming' | 'done';
|
|
482
|
+
message: string;
|
|
483
|
+
attempts?: number;
|
|
484
|
+
predictedAddress?: Address;
|
|
485
|
+
chainTxHash?: Hex;
|
|
486
|
+
}
|
|
487
|
+
interface FactoryContext {
|
|
488
|
+
connection: Connection;
|
|
489
|
+
contracts: ContractAddresses;
|
|
490
|
+
}
|
|
491
|
+
/** Deploy and look up vaults through `QuaiVaultFactory`. */
|
|
492
|
+
declare class Factory {
|
|
493
|
+
private readonly ctx;
|
|
494
|
+
constructor(ctx: FactoryContext);
|
|
495
|
+
get address(): Address;
|
|
496
|
+
private contract;
|
|
497
|
+
/** The implementation every proxy from this factory delegates to. */
|
|
498
|
+
implementation(): Promise<Address>;
|
|
499
|
+
/** Whether the factory has this vault in its registry. */
|
|
500
|
+
isRegistered(vault: Address): Promise<boolean>;
|
|
501
|
+
vaultCount(): Promise<number>;
|
|
502
|
+
vaultAt(index: number): Promise<Address>;
|
|
503
|
+
/**
|
|
504
|
+
* Verify the configured implementation address matches what the factory reports.
|
|
505
|
+
*
|
|
506
|
+
* A mismatch means salt mining will predict addresses the factory will not deploy
|
|
507
|
+
* to, so it is worth catching before a deployment rather than after.
|
|
508
|
+
*/
|
|
509
|
+
verify(): Promise<{
|
|
510
|
+
valid: boolean;
|
|
511
|
+
errors: string[];
|
|
512
|
+
}>;
|
|
513
|
+
/** Off-chain CREATE2 prediction. Identical to `factory.predictWalletAddress`. */
|
|
514
|
+
predictAddress(deployer: Address, salt: Bytes32, params: CreateVaultParams): Address;
|
|
515
|
+
/**
|
|
516
|
+
* Mine a CREATE2 salt placing the vault on the deployer's shard.
|
|
517
|
+
*
|
|
518
|
+
* Quai addresses are shard-scoped, so an arbitrary salt usually produces a vault
|
|
519
|
+
* the deployer cannot reach. The mined salt is only valid for these exact create
|
|
520
|
+
* params — changing owners, threshold, delay, modules or delegatecall targets
|
|
521
|
+
* changes the predicted address.
|
|
522
|
+
*/
|
|
523
|
+
mineSalt(params: CreateVaultParams, options?: Partial<Omit<MineSaltOptions, 'factory' | 'implementation' | 'params'>>, strategy?: MiningStrategy): Promise<MinedSalt>;
|
|
524
|
+
/**
|
|
525
|
+
* Deploy a vault, mining a salt first when one is not supplied.
|
|
526
|
+
*
|
|
527
|
+
* Always uses the 6-argument `createWallet` overload so the deployed bytecode
|
|
528
|
+
* matches what mining predicted, whatever combination of modules and delegatecall
|
|
529
|
+
* targets is requested.
|
|
530
|
+
*/
|
|
531
|
+
create(params: CreateVaultParams, options?: {
|
|
532
|
+
onProgress?: (progress: CreateProgress) => void;
|
|
533
|
+
miningStrategy?: MiningStrategy;
|
|
534
|
+
maxAttempts?: number;
|
|
535
|
+
timeoutMs?: number;
|
|
536
|
+
}): Promise<CreateVaultResult>;
|
|
537
|
+
/** Register an externally deployed proxy. Callable only by one of its owners. */
|
|
538
|
+
register(vault: Address): Promise<{
|
|
539
|
+
chainTxHash: Hex;
|
|
540
|
+
}>;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* The indexer uses one Postgres schema per network, chosen at runtime, so the
|
|
545
|
+
* client cannot be pinned to supabase-js's default `"public"` schema generic.
|
|
546
|
+
*/
|
|
547
|
+
type AnySupabaseClient = SupabaseClient<any, any, any, any, any>;
|
|
548
|
+
/**
|
|
549
|
+
* Thin wrapper over the indexer's Supabase project.
|
|
550
|
+
*
|
|
551
|
+
* The anon key is a public read-only credential: the indexer's RLS grants `anon`
|
|
552
|
+
* SELECT on every table and nothing else, with all writes reserved for
|
|
553
|
+
* `service_role`. It carries no authority beyond reading already-public chain data.
|
|
554
|
+
*/
|
|
555
|
+
declare class IndexerClient {
|
|
556
|
+
readonly config: IndexerConfig;
|
|
557
|
+
private readonly client;
|
|
558
|
+
private healthCache;
|
|
559
|
+
private inflightHealth;
|
|
560
|
+
/** Health results are reused for this long to keep read paths cheap. */
|
|
561
|
+
readonly healthCacheMs: number;
|
|
562
|
+
constructor(config: IndexerConfig, options?: {
|
|
563
|
+
healthCacheMs?: number;
|
|
564
|
+
});
|
|
565
|
+
/** Raw Supabase client, for queries the SDK does not wrap. */
|
|
566
|
+
get raw(): AnySupabaseClient;
|
|
567
|
+
from(table: string): _supabase_postgrest_js.PostgrestQueryBuilder<any, any, any, string, unknown>;
|
|
568
|
+
/**
|
|
569
|
+
* Run a query, parse each row, and surface failures as `IndexerQueryError`.
|
|
570
|
+
*
|
|
571
|
+
* No retry wrapper here on purpose. `postgrest-js` already retries GET/HEAD/OPTIONS
|
|
572
|
+
* internally (3 attempts, retryable statuses and fetch errors, honouring
|
|
573
|
+
* `Retry-After`), and it reports failures as a resolved `{ error }` value rather
|
|
574
|
+
* than a rejection — so an outer `withRetry` would be dead code that silently
|
|
575
|
+
* multiplied attempts if it were ever made to work. Chain reads, which do reject,
|
|
576
|
+
* are retried in `src/chain/retry.ts`.
|
|
577
|
+
*/
|
|
578
|
+
select<S extends z.ZodTypeAny>(table: string, schema: S, build: (q: ReturnType<AnySupabaseClient["from"]>) => PromiseLike<{
|
|
579
|
+
data: unknown[] | null;
|
|
580
|
+
error: {
|
|
581
|
+
message: string;
|
|
582
|
+
code?: string;
|
|
583
|
+
} | null;
|
|
584
|
+
}>): Promise<Array<z.infer<S>>>;
|
|
585
|
+
/** Single-row variant. Returns null for PostgREST's "no rows" code. */
|
|
586
|
+
selectOne<S extends z.ZodTypeAny>(table: string, schema: S, build: (q: ReturnType<AnySupabaseClient["from"]>) => PromiseLike<{
|
|
587
|
+
data: unknown | null;
|
|
588
|
+
error: {
|
|
589
|
+
message: string;
|
|
590
|
+
code?: string;
|
|
591
|
+
} | null;
|
|
592
|
+
}>): Promise<z.infer<S> | null>;
|
|
593
|
+
/** The indexer's sync head, straight from the `indexer_state` table. */
|
|
594
|
+
state(): Promise<{
|
|
595
|
+
lastIndexedBlock: number;
|
|
596
|
+
isSyncing: boolean;
|
|
597
|
+
} | null>;
|
|
598
|
+
/**
|
|
599
|
+
* Liveness and lag. Prefers the HTTP health endpoint (which knows the chain head)
|
|
600
|
+
* and falls back to the `indexer_state` table when it is unreachable.
|
|
601
|
+
*/
|
|
602
|
+
health(force?: boolean): Promise<IndexerHealth>;
|
|
603
|
+
/**
|
|
604
|
+
* Block until the indexer has processed `blockNumber`.
|
|
605
|
+
*
|
|
606
|
+
* Closes the write-then-read race: a transaction confirmed at block N is not
|
|
607
|
+
* queryable until the indexer reaches N, so `propose()` immediately followed by
|
|
608
|
+
* `pendingTransactions()` will silently miss it. Await this in between.
|
|
609
|
+
*
|
|
610
|
+
* Resolves immediately when the head is already at or past the target.
|
|
611
|
+
*/
|
|
612
|
+
waitForBlock(blockNumber: number, options?: {
|
|
613
|
+
timeoutMs?: number;
|
|
614
|
+
pollIntervalMs?: number;
|
|
615
|
+
signal?: AbortSignal;
|
|
616
|
+
}): Promise<{
|
|
617
|
+
reached: boolean;
|
|
618
|
+
lastIndexedBlock: number;
|
|
619
|
+
}>;
|
|
620
|
+
private probeHealth;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
declare const WalletSchema: z.ZodObject<{
|
|
624
|
+
address: z.ZodString;
|
|
625
|
+
name: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
626
|
+
threshold: z.ZodNumber;
|
|
627
|
+
owner_count: z.ZodNumber;
|
|
628
|
+
created_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
629
|
+
created_at_tx: z.ZodString;
|
|
630
|
+
min_execution_delay: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
631
|
+
created_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
632
|
+
updated_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
633
|
+
}, "strip", z.ZodTypeAny, {
|
|
634
|
+
address: string;
|
|
635
|
+
threshold: number;
|
|
636
|
+
owner_count: number;
|
|
637
|
+
created_at_block: string | number;
|
|
638
|
+
created_at_tx: string;
|
|
639
|
+
name?: string | null | undefined;
|
|
640
|
+
min_execution_delay?: number | null | undefined;
|
|
641
|
+
created_at?: string | null | undefined;
|
|
642
|
+
updated_at?: string | null | undefined;
|
|
643
|
+
}, {
|
|
644
|
+
address: string;
|
|
645
|
+
threshold: number;
|
|
646
|
+
owner_count: number;
|
|
647
|
+
created_at_block: string | number;
|
|
648
|
+
created_at_tx: string;
|
|
649
|
+
name?: string | null | undefined;
|
|
650
|
+
min_execution_delay?: number | null | undefined;
|
|
651
|
+
created_at?: string | null | undefined;
|
|
652
|
+
updated_at?: string | null | undefined;
|
|
653
|
+
}>;
|
|
654
|
+
type WalletRow = z.infer<typeof WalletSchema>;
|
|
655
|
+
declare const WalletOwnerSchema: z.ZodObject<{
|
|
656
|
+
wallet_address: z.ZodString;
|
|
657
|
+
owner_address: z.ZodString;
|
|
658
|
+
added_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
659
|
+
added_at_tx: z.ZodString;
|
|
660
|
+
removed_at_block: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
661
|
+
removed_at_tx: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
662
|
+
is_active: z.ZodBoolean;
|
|
663
|
+
}, "strip", z.ZodTypeAny, {
|
|
664
|
+
wallet_address: string;
|
|
665
|
+
owner_address: string;
|
|
666
|
+
added_at_block: string | number;
|
|
667
|
+
added_at_tx: string;
|
|
668
|
+
is_active: boolean;
|
|
669
|
+
removed_at_block?: string | number | null | undefined;
|
|
670
|
+
removed_at_tx?: string | null | undefined;
|
|
671
|
+
}, {
|
|
672
|
+
wallet_address: string;
|
|
673
|
+
owner_address: string;
|
|
674
|
+
added_at_block: string | number;
|
|
675
|
+
added_at_tx: string;
|
|
676
|
+
is_active: boolean;
|
|
677
|
+
removed_at_block?: string | number | null | undefined;
|
|
678
|
+
removed_at_tx?: string | null | undefined;
|
|
679
|
+
}>;
|
|
680
|
+
type WalletOwnerRow = z.infer<typeof WalletOwnerSchema>;
|
|
681
|
+
declare const TransactionStatusEnum: z.ZodEnum<["pending", "executed", "cancelled", "expired", "failed"]>;
|
|
682
|
+
declare const TransactionSchema: z.ZodObject<{
|
|
683
|
+
wallet_address: z.ZodString;
|
|
684
|
+
tx_hash: z.ZodString;
|
|
685
|
+
to_address: z.ZodString;
|
|
686
|
+
value: z.ZodString;
|
|
687
|
+
data: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
688
|
+
transaction_type: z.ZodString;
|
|
689
|
+
decoded_params: z.ZodOptional<z.ZodNullable<z.ZodUnknown>>;
|
|
690
|
+
status: z.ZodEnum<["pending", "executed", "cancelled", "expired", "failed"]>;
|
|
691
|
+
confirmation_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
692
|
+
submitted_by: z.ZodString;
|
|
693
|
+
submitted_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
694
|
+
submitted_at_tx: z.ZodString;
|
|
695
|
+
executed_at_block: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
696
|
+
executed_at_tx: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
697
|
+
executed_by: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
698
|
+
cancelled_at_block: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
699
|
+
cancelled_at_tx: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
700
|
+
expiration: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
701
|
+
execution_delay: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
702
|
+
approved_at: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
703
|
+
executable_after: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
704
|
+
is_expired: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
705
|
+
failed_return_data: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
706
|
+
created_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
707
|
+
updated_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
708
|
+
}, "strip", z.ZodTypeAny, {
|
|
709
|
+
value: string;
|
|
710
|
+
status: "executed" | "cancelled" | "pending" | "failed" | "expired";
|
|
711
|
+
wallet_address: string;
|
|
712
|
+
tx_hash: string;
|
|
713
|
+
to_address: string;
|
|
714
|
+
transaction_type: string;
|
|
715
|
+
submitted_by: string;
|
|
716
|
+
submitted_at_block: string | number;
|
|
717
|
+
submitted_at_tx: string;
|
|
718
|
+
data?: string | null | undefined;
|
|
719
|
+
expiration?: string | number | null | undefined;
|
|
720
|
+
created_at?: string | null | undefined;
|
|
721
|
+
updated_at?: string | null | undefined;
|
|
722
|
+
decoded_params?: unknown;
|
|
723
|
+
confirmation_count?: number | null | undefined;
|
|
724
|
+
executed_at_block?: string | number | null | undefined;
|
|
725
|
+
executed_at_tx?: string | null | undefined;
|
|
726
|
+
executed_by?: string | null | undefined;
|
|
727
|
+
cancelled_at_block?: string | number | null | undefined;
|
|
728
|
+
cancelled_at_tx?: string | null | undefined;
|
|
729
|
+
execution_delay?: number | null | undefined;
|
|
730
|
+
approved_at?: string | number | null | undefined;
|
|
731
|
+
executable_after?: string | number | null | undefined;
|
|
732
|
+
is_expired?: boolean | null | undefined;
|
|
733
|
+
failed_return_data?: string | null | undefined;
|
|
734
|
+
}, {
|
|
735
|
+
value: string;
|
|
736
|
+
status: "executed" | "cancelled" | "pending" | "failed" | "expired";
|
|
737
|
+
wallet_address: string;
|
|
738
|
+
tx_hash: string;
|
|
739
|
+
to_address: string;
|
|
740
|
+
transaction_type: string;
|
|
741
|
+
submitted_by: string;
|
|
742
|
+
submitted_at_block: string | number;
|
|
743
|
+
submitted_at_tx: string;
|
|
744
|
+
data?: string | null | undefined;
|
|
745
|
+
expiration?: string | number | null | undefined;
|
|
746
|
+
created_at?: string | null | undefined;
|
|
747
|
+
updated_at?: string | null | undefined;
|
|
748
|
+
decoded_params?: unknown;
|
|
749
|
+
confirmation_count?: number | null | undefined;
|
|
750
|
+
executed_at_block?: string | number | null | undefined;
|
|
751
|
+
executed_at_tx?: string | null | undefined;
|
|
752
|
+
executed_by?: string | null | undefined;
|
|
753
|
+
cancelled_at_block?: string | number | null | undefined;
|
|
754
|
+
cancelled_at_tx?: string | null | undefined;
|
|
755
|
+
execution_delay?: number | null | undefined;
|
|
756
|
+
approved_at?: string | number | null | undefined;
|
|
757
|
+
executable_after?: string | number | null | undefined;
|
|
758
|
+
is_expired?: boolean | null | undefined;
|
|
759
|
+
failed_return_data?: string | null | undefined;
|
|
760
|
+
}>;
|
|
761
|
+
type TransactionRow = z.infer<typeof TransactionSchema>;
|
|
762
|
+
declare const ConfirmationSchema: z.ZodObject<{
|
|
763
|
+
wallet_address: z.ZodString;
|
|
764
|
+
tx_hash: z.ZodString;
|
|
765
|
+
owner_address: z.ZodString;
|
|
766
|
+
confirmed_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
767
|
+
confirmed_at_tx: z.ZodString;
|
|
768
|
+
revoked_at_block: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
769
|
+
revoked_at_tx: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
770
|
+
is_active: z.ZodBoolean;
|
|
771
|
+
}, "strip", z.ZodTypeAny, {
|
|
772
|
+
wallet_address: string;
|
|
773
|
+
owner_address: string;
|
|
774
|
+
is_active: boolean;
|
|
775
|
+
tx_hash: string;
|
|
776
|
+
confirmed_at_block: string | number;
|
|
777
|
+
confirmed_at_tx: string;
|
|
778
|
+
revoked_at_block?: string | number | null | undefined;
|
|
779
|
+
revoked_at_tx?: string | null | undefined;
|
|
780
|
+
}, {
|
|
781
|
+
wallet_address: string;
|
|
782
|
+
owner_address: string;
|
|
783
|
+
is_active: boolean;
|
|
784
|
+
tx_hash: string;
|
|
785
|
+
confirmed_at_block: string | number;
|
|
786
|
+
confirmed_at_tx: string;
|
|
787
|
+
revoked_at_block?: string | number | null | undefined;
|
|
788
|
+
revoked_at_tx?: string | null | undefined;
|
|
789
|
+
}>;
|
|
790
|
+
type ConfirmationRow = z.infer<typeof ConfirmationSchema>;
|
|
791
|
+
declare const WalletModuleSchema: z.ZodObject<{
|
|
792
|
+
wallet_address: z.ZodString;
|
|
793
|
+
module_address: z.ZodString;
|
|
794
|
+
enabled_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
795
|
+
enabled_at_tx: z.ZodString;
|
|
796
|
+
disabled_at_block: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
797
|
+
disabled_at_tx: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
798
|
+
is_active: z.ZodBoolean;
|
|
799
|
+
}, "strip", z.ZodTypeAny, {
|
|
800
|
+
wallet_address: string;
|
|
801
|
+
is_active: boolean;
|
|
802
|
+
module_address: string;
|
|
803
|
+
enabled_at_block: string | number;
|
|
804
|
+
enabled_at_tx: string;
|
|
805
|
+
disabled_at_block?: string | number | null | undefined;
|
|
806
|
+
disabled_at_tx?: string | null | undefined;
|
|
807
|
+
}, {
|
|
808
|
+
wallet_address: string;
|
|
809
|
+
is_active: boolean;
|
|
810
|
+
module_address: string;
|
|
811
|
+
enabled_at_block: string | number;
|
|
812
|
+
enabled_at_tx: string;
|
|
813
|
+
disabled_at_block?: string | number | null | undefined;
|
|
814
|
+
disabled_at_tx?: string | null | undefined;
|
|
815
|
+
}>;
|
|
816
|
+
type WalletModuleRow = z.infer<typeof WalletModuleSchema>;
|
|
817
|
+
declare const DelegatecallTargetSchema: z.ZodObject<{
|
|
818
|
+
wallet_address: z.ZodString;
|
|
819
|
+
target_address: z.ZodString;
|
|
820
|
+
added_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
821
|
+
added_at_tx: z.ZodString;
|
|
822
|
+
removed_at_block: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
823
|
+
removed_at_tx: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
824
|
+
is_active: z.ZodBoolean;
|
|
825
|
+
}, "strip", z.ZodTypeAny, {
|
|
826
|
+
wallet_address: string;
|
|
827
|
+
added_at_block: string | number;
|
|
828
|
+
added_at_tx: string;
|
|
829
|
+
is_active: boolean;
|
|
830
|
+
target_address: string;
|
|
831
|
+
removed_at_block?: string | number | null | undefined;
|
|
832
|
+
removed_at_tx?: string | null | undefined;
|
|
833
|
+
}, {
|
|
834
|
+
wallet_address: string;
|
|
835
|
+
added_at_block: string | number;
|
|
836
|
+
added_at_tx: string;
|
|
837
|
+
is_active: boolean;
|
|
838
|
+
target_address: string;
|
|
839
|
+
removed_at_block?: string | number | null | undefined;
|
|
840
|
+
removed_at_tx?: string | null | undefined;
|
|
841
|
+
}>;
|
|
842
|
+
type DelegatecallTargetRow = z.infer<typeof DelegatecallTargetSchema>;
|
|
843
|
+
declare const DepositSchema: z.ZodObject<{
|
|
844
|
+
wallet_address: z.ZodString;
|
|
845
|
+
sender_address: z.ZodString;
|
|
846
|
+
amount: z.ZodString;
|
|
847
|
+
deposited_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
848
|
+
deposited_at_tx: z.ZodString;
|
|
849
|
+
created_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
850
|
+
}, "strip", z.ZodTypeAny, {
|
|
851
|
+
amount: string;
|
|
852
|
+
wallet_address: string;
|
|
853
|
+
sender_address: string;
|
|
854
|
+
deposited_at_block: string | number;
|
|
855
|
+
deposited_at_tx: string;
|
|
856
|
+
created_at?: string | null | undefined;
|
|
857
|
+
}, {
|
|
858
|
+
amount: string;
|
|
859
|
+
wallet_address: string;
|
|
860
|
+
sender_address: string;
|
|
861
|
+
deposited_at_block: string | number;
|
|
862
|
+
deposited_at_tx: string;
|
|
863
|
+
created_at?: string | null | undefined;
|
|
864
|
+
}>;
|
|
865
|
+
type DepositRow = z.infer<typeof DepositSchema>;
|
|
866
|
+
declare const TokenSchema: z.ZodObject<{
|
|
867
|
+
address: z.ZodString;
|
|
868
|
+
standard: z.ZodEnum<["ERC20", "ERC721", "ERC1155"]>;
|
|
869
|
+
symbol: z.ZodString;
|
|
870
|
+
name: z.ZodString;
|
|
871
|
+
decimals: z.ZodNumber;
|
|
872
|
+
discovered_at_block: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
873
|
+
discovered_via: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
874
|
+
}, "strip", z.ZodTypeAny, {
|
|
875
|
+
symbol: string;
|
|
876
|
+
address: string;
|
|
877
|
+
name: string;
|
|
878
|
+
standard: "ERC20" | "ERC721" | "ERC1155";
|
|
879
|
+
decimals: number;
|
|
880
|
+
discovered_at_block?: string | number | null | undefined;
|
|
881
|
+
discovered_via?: string | null | undefined;
|
|
882
|
+
}, {
|
|
883
|
+
symbol: string;
|
|
884
|
+
address: string;
|
|
885
|
+
name: string;
|
|
886
|
+
standard: "ERC20" | "ERC721" | "ERC1155";
|
|
887
|
+
decimals: number;
|
|
888
|
+
discovered_at_block?: string | number | null | undefined;
|
|
889
|
+
discovered_via?: string | null | undefined;
|
|
890
|
+
}>;
|
|
891
|
+
type TokenRow = z.infer<typeof TokenSchema>;
|
|
892
|
+
declare const TokenTransferSchema: z.ZodObject<{
|
|
893
|
+
token_address: z.ZodString;
|
|
894
|
+
wallet_address: z.ZodString;
|
|
895
|
+
from_address: z.ZodString;
|
|
896
|
+
to_address: z.ZodString;
|
|
897
|
+
value: z.ZodString;
|
|
898
|
+
token_id: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
899
|
+
batch_index: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
900
|
+
direction: z.ZodEnum<["inflow", "outflow"]>;
|
|
901
|
+
block_number: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
902
|
+
transaction_hash: z.ZodString;
|
|
903
|
+
log_index: z.ZodNumber;
|
|
904
|
+
}, "strip", z.ZodTypeAny, {
|
|
905
|
+
value: string;
|
|
906
|
+
wallet_address: string;
|
|
907
|
+
to_address: string;
|
|
908
|
+
token_address: string;
|
|
909
|
+
from_address: string;
|
|
910
|
+
direction: "inflow" | "outflow";
|
|
911
|
+
block_number: string | number;
|
|
912
|
+
transaction_hash: string;
|
|
913
|
+
log_index: number;
|
|
914
|
+
token_id?: string | null | undefined;
|
|
915
|
+
batch_index?: number | null | undefined;
|
|
916
|
+
}, {
|
|
917
|
+
value: string;
|
|
918
|
+
wallet_address: string;
|
|
919
|
+
to_address: string;
|
|
920
|
+
token_address: string;
|
|
921
|
+
from_address: string;
|
|
922
|
+
direction: "inflow" | "outflow";
|
|
923
|
+
block_number: string | number;
|
|
924
|
+
transaction_hash: string;
|
|
925
|
+
log_index: number;
|
|
926
|
+
token_id?: string | null | undefined;
|
|
927
|
+
batch_index?: number | null | undefined;
|
|
928
|
+
}>;
|
|
929
|
+
type TokenTransferRow = z.infer<typeof TokenTransferSchema>;
|
|
930
|
+
declare const SignedMessageSchema: z.ZodObject<{
|
|
931
|
+
wallet_address: z.ZodString;
|
|
932
|
+
msg_hash: z.ZodString;
|
|
933
|
+
data: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
934
|
+
signed_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
935
|
+
signed_at_tx: z.ZodString;
|
|
936
|
+
unsigned_at_block: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
937
|
+
unsigned_at_tx: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
938
|
+
is_active: z.ZodBoolean;
|
|
939
|
+
}, "strip", z.ZodTypeAny, {
|
|
940
|
+
wallet_address: string;
|
|
941
|
+
is_active: boolean;
|
|
942
|
+
msg_hash: string;
|
|
943
|
+
signed_at_block: string | number;
|
|
944
|
+
signed_at_tx: string;
|
|
945
|
+
data?: string | null | undefined;
|
|
946
|
+
unsigned_at_block?: string | number | null | undefined;
|
|
947
|
+
unsigned_at_tx?: string | null | undefined;
|
|
948
|
+
}, {
|
|
949
|
+
wallet_address: string;
|
|
950
|
+
is_active: boolean;
|
|
951
|
+
msg_hash: string;
|
|
952
|
+
signed_at_block: string | number;
|
|
953
|
+
signed_at_tx: string;
|
|
954
|
+
data?: string | null | undefined;
|
|
955
|
+
unsigned_at_block?: string | number | null | undefined;
|
|
956
|
+
unsigned_at_tx?: string | null | undefined;
|
|
957
|
+
}>;
|
|
958
|
+
type SignedMessageRow = z.infer<typeof SignedMessageSchema>;
|
|
959
|
+
declare const IndexerStateSchema: z.ZodObject<{
|
|
960
|
+
id: z.ZodString;
|
|
961
|
+
last_indexed_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
962
|
+
last_block_hash: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
963
|
+
last_indexed_at: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
964
|
+
is_syncing: z.ZodOptional<z.ZodNullable<z.ZodBoolean>>;
|
|
965
|
+
}, "strip", z.ZodTypeAny, {
|
|
966
|
+
id: string;
|
|
967
|
+
last_indexed_block: string | number;
|
|
968
|
+
last_block_hash?: string | null | undefined;
|
|
969
|
+
last_indexed_at?: string | null | undefined;
|
|
970
|
+
is_syncing?: boolean | null | undefined;
|
|
971
|
+
}, {
|
|
972
|
+
id: string;
|
|
973
|
+
last_indexed_block: string | number;
|
|
974
|
+
last_block_hash?: string | null | undefined;
|
|
975
|
+
last_indexed_at?: string | null | undefined;
|
|
976
|
+
is_syncing?: boolean | null | undefined;
|
|
977
|
+
}>;
|
|
978
|
+
type IndexerStateRow = z.infer<typeof IndexerStateSchema>;
|
|
979
|
+
declare const RecoveryConfigSchema: z.ZodObject<{
|
|
980
|
+
wallet_address: z.ZodString;
|
|
981
|
+
threshold: z.ZodNumber;
|
|
982
|
+
recovery_period: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
983
|
+
setup_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
984
|
+
setup_at_tx: z.ZodString;
|
|
985
|
+
is_active: z.ZodBoolean;
|
|
986
|
+
}, "strip", z.ZodTypeAny, {
|
|
987
|
+
threshold: number;
|
|
988
|
+
wallet_address: string;
|
|
989
|
+
is_active: boolean;
|
|
990
|
+
recovery_period: string | number;
|
|
991
|
+
setup_at_block: string | number;
|
|
992
|
+
setup_at_tx: string;
|
|
993
|
+
}, {
|
|
994
|
+
threshold: number;
|
|
995
|
+
wallet_address: string;
|
|
996
|
+
is_active: boolean;
|
|
997
|
+
recovery_period: string | number;
|
|
998
|
+
setup_at_block: string | number;
|
|
999
|
+
setup_at_tx: string;
|
|
1000
|
+
}>;
|
|
1001
|
+
type RecoveryConfigRow = z.infer<typeof RecoveryConfigSchema>;
|
|
1002
|
+
declare const RecoveryGuardianSchema: z.ZodObject<{
|
|
1003
|
+
wallet_address: z.ZodString;
|
|
1004
|
+
guardian_address: z.ZodString;
|
|
1005
|
+
added_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
1006
|
+
added_at_tx: z.ZodString;
|
|
1007
|
+
is_active: z.ZodBoolean;
|
|
1008
|
+
}, "strip", z.ZodTypeAny, {
|
|
1009
|
+
wallet_address: string;
|
|
1010
|
+
added_at_block: string | number;
|
|
1011
|
+
added_at_tx: string;
|
|
1012
|
+
is_active: boolean;
|
|
1013
|
+
guardian_address: string;
|
|
1014
|
+
}, {
|
|
1015
|
+
wallet_address: string;
|
|
1016
|
+
added_at_block: string | number;
|
|
1017
|
+
added_at_tx: string;
|
|
1018
|
+
is_active: boolean;
|
|
1019
|
+
guardian_address: string;
|
|
1020
|
+
}>;
|
|
1021
|
+
type RecoveryGuardianRow = z.infer<typeof RecoveryGuardianSchema>;
|
|
1022
|
+
declare const RecoverySchema: z.ZodObject<{
|
|
1023
|
+
wallet_address: z.ZodString;
|
|
1024
|
+
recovery_hash: z.ZodString;
|
|
1025
|
+
new_owners: z.ZodArray<z.ZodString, "many">;
|
|
1026
|
+
new_threshold: z.ZodNumber;
|
|
1027
|
+
initiator_address: z.ZodString;
|
|
1028
|
+
approval_count: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
1029
|
+
required_threshold: z.ZodNumber;
|
|
1030
|
+
execution_time: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
1031
|
+
status: z.ZodEnum<["pending", "executed", "cancelled", "invalidated", "expired"]>;
|
|
1032
|
+
initiated_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
1033
|
+
initiated_at_tx: z.ZodString;
|
|
1034
|
+
expiration: z.ZodOptional<z.ZodNullable<z.ZodUnion<[z.ZodNumber, z.ZodString]>>>;
|
|
1035
|
+
}, "strip", z.ZodTypeAny, {
|
|
1036
|
+
status: "executed" | "cancelled" | "pending" | "expired" | "invalidated";
|
|
1037
|
+
wallet_address: string;
|
|
1038
|
+
recovery_hash: string;
|
|
1039
|
+
new_owners: string[];
|
|
1040
|
+
new_threshold: number;
|
|
1041
|
+
initiator_address: string;
|
|
1042
|
+
required_threshold: number;
|
|
1043
|
+
execution_time: string | number;
|
|
1044
|
+
initiated_at_block: string | number;
|
|
1045
|
+
initiated_at_tx: string;
|
|
1046
|
+
expiration?: string | number | null | undefined;
|
|
1047
|
+
approval_count?: number | null | undefined;
|
|
1048
|
+
}, {
|
|
1049
|
+
status: "executed" | "cancelled" | "pending" | "expired" | "invalidated";
|
|
1050
|
+
wallet_address: string;
|
|
1051
|
+
recovery_hash: string;
|
|
1052
|
+
new_owners: string[];
|
|
1053
|
+
new_threshold: number;
|
|
1054
|
+
initiator_address: string;
|
|
1055
|
+
required_threshold: number;
|
|
1056
|
+
execution_time: string | number;
|
|
1057
|
+
initiated_at_block: string | number;
|
|
1058
|
+
initiated_at_tx: string;
|
|
1059
|
+
expiration?: string | number | null | undefined;
|
|
1060
|
+
approval_count?: number | null | undefined;
|
|
1061
|
+
}>;
|
|
1062
|
+
type RecoveryRow = z.infer<typeof RecoverySchema>;
|
|
1063
|
+
declare const RecoveryApprovalSchema: z.ZodObject<{
|
|
1064
|
+
wallet_address: z.ZodString;
|
|
1065
|
+
recovery_hash: z.ZodString;
|
|
1066
|
+
guardian_address: z.ZodString;
|
|
1067
|
+
approved_at_block: z.ZodUnion<[z.ZodNumber, z.ZodString]>;
|
|
1068
|
+
approved_at_tx: z.ZodString;
|
|
1069
|
+
is_active: z.ZodBoolean;
|
|
1070
|
+
}, "strip", z.ZodTypeAny, {
|
|
1071
|
+
wallet_address: string;
|
|
1072
|
+
is_active: boolean;
|
|
1073
|
+
guardian_address: string;
|
|
1074
|
+
recovery_hash: string;
|
|
1075
|
+
approved_at_block: string | number;
|
|
1076
|
+
approved_at_tx: string;
|
|
1077
|
+
}, {
|
|
1078
|
+
wallet_address: string;
|
|
1079
|
+
is_active: boolean;
|
|
1080
|
+
guardian_address: string;
|
|
1081
|
+
recovery_hash: string;
|
|
1082
|
+
approved_at_block: string | number;
|
|
1083
|
+
approved_at_tx: string;
|
|
1084
|
+
}>;
|
|
1085
|
+
type RecoveryApprovalRow = z.infer<typeof RecoveryApprovalSchema>;
|
|
1086
|
+
/** Coerce the bigint-ish columns Postgres returns as strings. */
|
|
1087
|
+
declare function toNumber(value: unknown, fallback?: number): number;
|
|
1088
|
+
|
|
1089
|
+
type schemas_ConfirmationRow = ConfirmationRow;
|
|
1090
|
+
declare const schemas_ConfirmationSchema: typeof ConfirmationSchema;
|
|
1091
|
+
type schemas_DelegatecallTargetRow = DelegatecallTargetRow;
|
|
1092
|
+
declare const schemas_DelegatecallTargetSchema: typeof DelegatecallTargetSchema;
|
|
1093
|
+
type schemas_DepositRow = DepositRow;
|
|
1094
|
+
declare const schemas_DepositSchema: typeof DepositSchema;
|
|
1095
|
+
type schemas_IndexerStateRow = IndexerStateRow;
|
|
1096
|
+
declare const schemas_IndexerStateSchema: typeof IndexerStateSchema;
|
|
1097
|
+
type schemas_RecoveryApprovalRow = RecoveryApprovalRow;
|
|
1098
|
+
declare const schemas_RecoveryApprovalSchema: typeof RecoveryApprovalSchema;
|
|
1099
|
+
type schemas_RecoveryConfigRow = RecoveryConfigRow;
|
|
1100
|
+
declare const schemas_RecoveryConfigSchema: typeof RecoveryConfigSchema;
|
|
1101
|
+
type schemas_RecoveryGuardianRow = RecoveryGuardianRow;
|
|
1102
|
+
declare const schemas_RecoveryGuardianSchema: typeof RecoveryGuardianSchema;
|
|
1103
|
+
type schemas_RecoveryRow = RecoveryRow;
|
|
1104
|
+
declare const schemas_RecoverySchema: typeof RecoverySchema;
|
|
1105
|
+
type schemas_SignedMessageRow = SignedMessageRow;
|
|
1106
|
+
declare const schemas_SignedMessageSchema: typeof SignedMessageSchema;
|
|
1107
|
+
type schemas_TokenRow = TokenRow;
|
|
1108
|
+
declare const schemas_TokenSchema: typeof TokenSchema;
|
|
1109
|
+
type schemas_TokenTransferRow = TokenTransferRow;
|
|
1110
|
+
declare const schemas_TokenTransferSchema: typeof TokenTransferSchema;
|
|
1111
|
+
type schemas_TransactionRow = TransactionRow;
|
|
1112
|
+
declare const schemas_TransactionSchema: typeof TransactionSchema;
|
|
1113
|
+
declare const schemas_TransactionStatusEnum: typeof TransactionStatusEnum;
|
|
1114
|
+
type schemas_WalletModuleRow = WalletModuleRow;
|
|
1115
|
+
declare const schemas_WalletModuleSchema: typeof WalletModuleSchema;
|
|
1116
|
+
type schemas_WalletOwnerRow = WalletOwnerRow;
|
|
1117
|
+
declare const schemas_WalletOwnerSchema: typeof WalletOwnerSchema;
|
|
1118
|
+
type schemas_WalletRow = WalletRow;
|
|
1119
|
+
declare const schemas_WalletSchema: typeof WalletSchema;
|
|
1120
|
+
declare const schemas_toNumber: typeof toNumber;
|
|
1121
|
+
declare namespace schemas {
|
|
1122
|
+
export { type schemas_ConfirmationRow as ConfirmationRow, schemas_ConfirmationSchema as ConfirmationSchema, type schemas_DelegatecallTargetRow as DelegatecallTargetRow, schemas_DelegatecallTargetSchema as DelegatecallTargetSchema, type schemas_DepositRow as DepositRow, schemas_DepositSchema as DepositSchema, type schemas_IndexerStateRow as IndexerStateRow, schemas_IndexerStateSchema as IndexerStateSchema, type schemas_RecoveryApprovalRow as RecoveryApprovalRow, schemas_RecoveryApprovalSchema as RecoveryApprovalSchema, type schemas_RecoveryConfigRow as RecoveryConfigRow, schemas_RecoveryConfigSchema as RecoveryConfigSchema, type schemas_RecoveryGuardianRow as RecoveryGuardianRow, schemas_RecoveryGuardianSchema as RecoveryGuardianSchema, type schemas_RecoveryRow as RecoveryRow, schemas_RecoverySchema as RecoverySchema, type schemas_SignedMessageRow as SignedMessageRow, schemas_SignedMessageSchema as SignedMessageSchema, type schemas_TokenRow as TokenRow, schemas_TokenSchema as TokenSchema, type schemas_TokenTransferRow as TokenTransferRow, schemas_TokenTransferSchema as TokenTransferSchema, type schemas_TransactionRow as TransactionRow, schemas_TransactionSchema as TransactionSchema, schemas_TransactionStatusEnum as TransactionStatusEnum, type schemas_WalletModuleRow as WalletModuleRow, schemas_WalletModuleSchema as WalletModuleSchema, type schemas_WalletOwnerRow as WalletOwnerRow, schemas_WalletOwnerSchema as WalletOwnerSchema, type schemas_WalletRow as WalletRow, schemas_WalletSchema as WalletSchema, schemas_toNumber as toNumber };
|
|
1123
|
+
}
|
|
1124
|
+
|
|
1125
|
+
declare class IndexerQueries {
|
|
1126
|
+
private readonly client;
|
|
1127
|
+
constructor(client: IndexerClient);
|
|
1128
|
+
wallet(address: Address): Promise<WalletRow | null>;
|
|
1129
|
+
/** Active owner addresses, lowercased as stored. */
|
|
1130
|
+
owners(address: Address): Promise<string[]>;
|
|
1131
|
+
vaultsForOwner(owner: Address, options?: Pagination): Promise<WalletRow[]>;
|
|
1132
|
+
vaultsForGuardian(guardian: Address, options?: Pagination): Promise<WalletRow[]>;
|
|
1133
|
+
pendingTransactions(vault: Address, options?: Pagination): Promise<TransactionRow[]>;
|
|
1134
|
+
transaction(vault: Address, txHash: string): Promise<TransactionRow | null>;
|
|
1135
|
+
transactionHistory(vault: Address, options?: Pagination & {
|
|
1136
|
+
status?: string[];
|
|
1137
|
+
}): Promise<Page<TransactionRow>>;
|
|
1138
|
+
/** All confirmations for one transaction, including revoked ones. */
|
|
1139
|
+
confirmations(vault: Address, txHash: string): Promise<ConfirmationRow[]>;
|
|
1140
|
+
/**
|
|
1141
|
+
* Active confirmations for many transactions in one round trip.
|
|
1142
|
+
*
|
|
1143
|
+
* "Active" here means not revoked. It does NOT mean the confirming address is
|
|
1144
|
+
* still an owner — the indexer does not deactivate confirmations when an owner is
|
|
1145
|
+
* removed, while the contract invalidates them via approval epochs. Callers must
|
|
1146
|
+
* intersect with the active owner set; `Vault` does this for you.
|
|
1147
|
+
*/
|
|
1148
|
+
activeConfirmationsBatch(vault: Address, txHashes: string[]): Promise<Map<string, ConfirmationRow[]>>;
|
|
1149
|
+
modules(vault: Address): Promise<string[]>;
|
|
1150
|
+
delegatecallTargets(vault: Address): Promise<string[]>;
|
|
1151
|
+
deposits(vault: Address, options?: Pagination): Promise<Page<DepositRow>>;
|
|
1152
|
+
tokenTransfers(vault: Address, options?: Pagination): Promise<Page<TokenTransferRow>>;
|
|
1153
|
+
tokens(addresses: string[]): Promise<TokenRow[]>;
|
|
1154
|
+
signedMessages(vault: Address): Promise<SignedMessageRow[]>;
|
|
1155
|
+
recoveryConfig(vault: Address): Promise<{
|
|
1156
|
+
threshold: number;
|
|
1157
|
+
recoveryPeriod: number;
|
|
1158
|
+
guardians: string[];
|
|
1159
|
+
} | null>;
|
|
1160
|
+
pendingRecoveries(vault: Address): Promise<RecoveryRow[]>;
|
|
1161
|
+
recoveryHistory(vault: Address, options?: Pagination): Promise<RecoveryRow[]>;
|
|
1162
|
+
recoveryApprovals(vault: Address, recoveryHash: string): Promise<RecoveryApprovalRow[]>;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
interface RecoveryModuleContext {
|
|
1166
|
+
connection: Connection;
|
|
1167
|
+
queries: IndexerQueries | null;
|
|
1168
|
+
vaultAddress: Address;
|
|
1169
|
+
moduleAddress: Address | undefined;
|
|
1170
|
+
}
|
|
1171
|
+
/**
|
|
1172
|
+
* Guardian-based recovery for one vault.
|
|
1173
|
+
*
|
|
1174
|
+
* Recovery is an escape hatch that bypasses the owner multisig entirely: enough
|
|
1175
|
+
* guardians can replace the owner set after a delay. Every write here is therefore
|
|
1176
|
+
* gated on the module still being enabled on the vault, which is the vault owners'
|
|
1177
|
+
* only lever once guardians are configured.
|
|
1178
|
+
*/
|
|
1179
|
+
declare class RecoveryModule {
|
|
1180
|
+
private readonly ctx;
|
|
1181
|
+
constructor(ctx: RecoveryModuleContext);
|
|
1182
|
+
/** The module address, or a typed error naming the variable to set. */
|
|
1183
|
+
get address(): Address;
|
|
1184
|
+
private contract;
|
|
1185
|
+
private get vault();
|
|
1186
|
+
/** Whether the module is currently enabled on the vault. */
|
|
1187
|
+
isEnabled(): Promise<boolean>;
|
|
1188
|
+
config(): Promise<RecoveryConfig>;
|
|
1189
|
+
isGuardian(address: Address): Promise<boolean>;
|
|
1190
|
+
/** Hashes of recoveries the module still tracks as pending. */
|
|
1191
|
+
pendingHashes(): Promise<Bytes32[]>;
|
|
1192
|
+
hasPending(): Promise<boolean>;
|
|
1193
|
+
/**
|
|
1194
|
+
* One recovery request, read from chain.
|
|
1195
|
+
*
|
|
1196
|
+
* Throws `NotFoundError` for a hash that was never initiated *or* was cancelled —
|
|
1197
|
+
* `cancelRecovery` deletes the struct, so the two are indistinguishable on chain.
|
|
1198
|
+
* Use {@link history} for cancelled recoveries.
|
|
1199
|
+
*/
|
|
1200
|
+
get(recoveryHash: Bytes32): Promise<RecoveryRequest>;
|
|
1201
|
+
/** Every recovery the module still tracks as pending, hydrated. */
|
|
1202
|
+
pending(): Promise<RecoveryRequest[]>;
|
|
1203
|
+
/**
|
|
1204
|
+
* Full recovery history including executed, cancelled and expired requests.
|
|
1205
|
+
* Indexer-only — the chain retains no record of cancelled recoveries.
|
|
1206
|
+
*/
|
|
1207
|
+
history(options?: {
|
|
1208
|
+
limit?: number;
|
|
1209
|
+
offset?: number;
|
|
1210
|
+
}): Promise<RecoveryRequest[]>;
|
|
1211
|
+
/** Guardians who have an active approval on a recovery. */
|
|
1212
|
+
approvals(recoveryHash: Bytes32): Promise<Address[]>;
|
|
1213
|
+
/** Hash the next `initiate` with these parameters would produce. */
|
|
1214
|
+
predictHash(newOwners: Address[], newThreshold: number): Promise<Bytes32>;
|
|
1215
|
+
/**
|
|
1216
|
+
* Initiate a recovery. Guardians only.
|
|
1217
|
+
*
|
|
1218
|
+
* Returns the recovery hash, read from the `RecoveryInitiated` event — the function's
|
|
1219
|
+
* return value is not recoverable from a receipt.
|
|
1220
|
+
*/
|
|
1221
|
+
initiate(params: {
|
|
1222
|
+
newOwners: Address[];
|
|
1223
|
+
newThreshold: number;
|
|
1224
|
+
}): Promise<{
|
|
1225
|
+
recoveryHash: Bytes32;
|
|
1226
|
+
chainTxHash: Hex;
|
|
1227
|
+
}>;
|
|
1228
|
+
/** Approve a recovery. Guardians only. */
|
|
1229
|
+
approve(recoveryHash: Bytes32): Promise<{
|
|
1230
|
+
chainTxHash: Hex;
|
|
1231
|
+
}>;
|
|
1232
|
+
/** Withdraw a guardian approval before the recovery executes. */
|
|
1233
|
+
revokeApproval(recoveryHash: Bytes32): Promise<{
|
|
1234
|
+
chainTxHash: Hex;
|
|
1235
|
+
}>;
|
|
1236
|
+
/**
|
|
1237
|
+
* Execute a recovery, replacing the vault's owner set. Permissionless once the
|
|
1238
|
+
* guardian threshold is met and the recovery period has elapsed.
|
|
1239
|
+
*/
|
|
1240
|
+
execute(recoveryHash: Bytes32): Promise<{
|
|
1241
|
+
chainTxHash: Hex;
|
|
1242
|
+
}>;
|
|
1243
|
+
/**
|
|
1244
|
+
* Cancel a recovery. Callable by any current vault owner — this is the owners'
|
|
1245
|
+
* defence against a hostile or mistaken guardian action.
|
|
1246
|
+
*/
|
|
1247
|
+
cancel(recoveryHash: Bytes32): Promise<{
|
|
1248
|
+
chainTxHash: Hex;
|
|
1249
|
+
}>;
|
|
1250
|
+
/** Clean up a recovery past its deadline. Permissionless. */
|
|
1251
|
+
expire(recoveryHash: Bytes32): Promise<{
|
|
1252
|
+
chainTxHash: Hex;
|
|
1253
|
+
}>;
|
|
1254
|
+
/** What `caller` may do to a recovery right now, and when blocked actions unlock. */
|
|
1255
|
+
affordances(recoveryHash: Bytes32, caller?: Address): Promise<RecoveryAffordance[]>;
|
|
1256
|
+
private buildFromChain;
|
|
1257
|
+
private validateNewOwners;
|
|
1258
|
+
private assertLive;
|
|
1259
|
+
private assertEnabled;
|
|
1260
|
+
private send;
|
|
1261
|
+
private extractRecoveryHash;
|
|
1262
|
+
private toRevert;
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
interface TokenBalance {
|
|
1266
|
+
token: Address;
|
|
1267
|
+
standard: 'ERC20' | 'ERC721' | 'ERC1155';
|
|
1268
|
+
symbol: string;
|
|
1269
|
+
name: string;
|
|
1270
|
+
decimals: number;
|
|
1271
|
+
/** ERC20: raw units. ERC721: number held. ERC1155: total across ids. */
|
|
1272
|
+
balance: bigint;
|
|
1273
|
+
/** ERC721 / ERC1155 only. */
|
|
1274
|
+
tokenIds?: string[];
|
|
1275
|
+
/** True when the balance came from an on-chain read rather than transfer replay. */
|
|
1276
|
+
verified: boolean;
|
|
1277
|
+
/**
|
|
1278
|
+
* Set when more candidate ids existed than `maxTokenIdChecks` allowed, so
|
|
1279
|
+
* `tokenIds` is a subset. The `balance` is still the authoritative on-chain count.
|
|
1280
|
+
*/
|
|
1281
|
+
tokenIdsTruncated?: boolean;
|
|
1282
|
+
}
|
|
1283
|
+
interface VaultBalances {
|
|
1284
|
+
native: bigint;
|
|
1285
|
+
tokens: TokenBalance[];
|
|
1286
|
+
/**
|
|
1287
|
+
* Set when a scan limit was hit, so the result may be incomplete. Silent
|
|
1288
|
+
* truncation would read as "these are all the holdings" when they are not.
|
|
1289
|
+
*/
|
|
1290
|
+
truncated?: {
|
|
1291
|
+
/** More transfer history existed than `transferScanLimit` scanned. */
|
|
1292
|
+
transfers?: boolean;
|
|
1293
|
+
/** More distinct tokens were discovered than `maxTokens` allowed. */
|
|
1294
|
+
tokens?: boolean;
|
|
1295
|
+
};
|
|
1296
|
+
}
|
|
1297
|
+
interface BalanceOptions {
|
|
1298
|
+
/**
|
|
1299
|
+
* Confirm each candidate balance with an on-chain read. Slower, but authoritative —
|
|
1300
|
+
* a token that moved through a path the indexer does not observe still reports
|
|
1301
|
+
* correctly. Default true.
|
|
1302
|
+
*/
|
|
1303
|
+
verify?: boolean;
|
|
1304
|
+
/** Cap on tokens considered, newest activity first. Default 50. */
|
|
1305
|
+
maxTokens?: number;
|
|
1306
|
+
/**
|
|
1307
|
+
* How many recent transfer rows to scan when discovering tokens. Default 500.
|
|
1308
|
+
*
|
|
1309
|
+
* A vault with more transfers than this may not surface its oldest holdings, so
|
|
1310
|
+
* raise it for long-lived vaults. Reported back in {@link VaultBalances.truncated}.
|
|
1311
|
+
*/
|
|
1312
|
+
transferScanLimit?: number;
|
|
1313
|
+
/** Cap on ERC721 ids ownership-checked per token. Default 100. */
|
|
1314
|
+
maxTokenIdChecks?: number;
|
|
1315
|
+
}
|
|
1316
|
+
/**
|
|
1317
|
+
* Aggregate a vault's holdings.
|
|
1318
|
+
*
|
|
1319
|
+
* Discovery is indexer-driven: `token_transfers` tells us which contracts a vault has
|
|
1320
|
+
* ever touched, which the chain cannot answer without scanning every log. Amounts are
|
|
1321
|
+
* then read on chain by default, because replaying transfers misses anything the
|
|
1322
|
+
* indexer did not observe (a token discovered after the transfer, a rebasing balance,
|
|
1323
|
+
* a direct mint). Set `verify: false` to skip the reads and accept replayed totals.
|
|
1324
|
+
*/
|
|
1325
|
+
declare function loadBalances(connection: Connection, queries: IndexerQueries | null, vault: Address, options?: BalanceOptions): Promise<VaultBalances>;
|
|
1326
|
+
|
|
1327
|
+
/** Indexer tables a vault subscription can follow. */
|
|
1328
|
+
type WatchTopic = 'transactions' | 'confirmations' | 'owners' | 'modules' | 'deposits' | 'tokenTransfers' | 'recoveries' | 'signedMessages';
|
|
1329
|
+
interface WatchEvent {
|
|
1330
|
+
topic: WatchTopic;
|
|
1331
|
+
table: string;
|
|
1332
|
+
/** Postgres operation that produced the event. */
|
|
1333
|
+
type: 'INSERT' | 'UPDATE' | 'DELETE';
|
|
1334
|
+
/** Row after the change. Absent for DELETE. */
|
|
1335
|
+
row: Record<string, unknown> | null;
|
|
1336
|
+
/** Row before the change, when the table's replica identity provides it. */
|
|
1337
|
+
previous: Record<string, unknown> | null;
|
|
1338
|
+
}
|
|
1339
|
+
interface WatchOptions {
|
|
1340
|
+
topics?: WatchTopic[];
|
|
1341
|
+
/** Called on subscription lifecycle changes, so callers can surface reconnects. */
|
|
1342
|
+
onStatus?: (status: string, error?: Error) => void;
|
|
1343
|
+
}
|
|
1344
|
+
/** Handle returned by {@link watchVault}. Call `unsubscribe` to release the channel. */
|
|
1345
|
+
interface Subscription {
|
|
1346
|
+
unsubscribe(): Promise<void>;
|
|
1347
|
+
readonly topics: WatchTopic[];
|
|
1348
|
+
}
|
|
1349
|
+
/**
|
|
1350
|
+
* Follow indexer changes for one vault over Supabase Realtime.
|
|
1351
|
+
*
|
|
1352
|
+
* All topics share a single channel — one WebSocket per vault rather than one per
|
|
1353
|
+
* table, which matters because Realtime caps concurrent channels per client.
|
|
1354
|
+
*
|
|
1355
|
+
* Realtime delivers *indexer* writes, so events arrive only after the indexer has
|
|
1356
|
+
* processed the block. It is a change feed, not a chain subscription: use it to know
|
|
1357
|
+
* when to re-read, and re-read through `Vault` so approval counts stay correct.
|
|
1358
|
+
*/
|
|
1359
|
+
declare function watchVault(client: IndexerClient, vault: Address, handler: (event: WatchEvent) => void, options?: WatchOptions): Subscription;
|
|
1360
|
+
|
|
1361
|
+
interface DecodeContext {
|
|
1362
|
+
/** The vault the transaction belongs to — used to detect self-calls. */
|
|
1363
|
+
vault: Address;
|
|
1364
|
+
to: Address;
|
|
1365
|
+
value: bigint;
|
|
1366
|
+
data: Hex;
|
|
1367
|
+
/** Known module addresses, for classifying `module_config` calls. */
|
|
1368
|
+
socialRecovery?: Address;
|
|
1369
|
+
multiSendCallOnly?: Address;
|
|
1370
|
+
}
|
|
1371
|
+
interface DecodeResult {
|
|
1372
|
+
kind: TransactionKind;
|
|
1373
|
+
decoded?: DecodedCall;
|
|
1374
|
+
summary: string;
|
|
1375
|
+
}
|
|
1376
|
+
/**
|
|
1377
|
+
* Classify and describe a proposed vault transaction from its calldata.
|
|
1378
|
+
*
|
|
1379
|
+
* Resolution order matters: self-calls are checked against the vault ABI first,
|
|
1380
|
+
* because several vault selectors would otherwise be ambiguous with token calls.
|
|
1381
|
+
*/
|
|
1382
|
+
declare function decodeCall(ctx: DecodeContext): DecodeResult;
|
|
1383
|
+
interface DecodedBatchCall {
|
|
1384
|
+
operation: number;
|
|
1385
|
+
to: Address;
|
|
1386
|
+
value: bigint;
|
|
1387
|
+
data: Hex;
|
|
1388
|
+
}
|
|
1389
|
+
/**
|
|
1390
|
+
* Unpack a MultiSend payload into its constituent calls.
|
|
1391
|
+
* Layout per call: `operation(1) ‖ to(20) ‖ value(32) ‖ dataLength(32) ‖ data`.
|
|
1392
|
+
*/
|
|
1393
|
+
declare function decodeMultiSendPayload(payload: Hex): DecodedBatchCall[];
|
|
1394
|
+
|
|
1395
|
+
declare const interfaces: {
|
|
1396
|
+
vault: Interface;
|
|
1397
|
+
recovery: Interface;
|
|
1398
|
+
multiSend: Interface;
|
|
1399
|
+
erc20: Interface;
|
|
1400
|
+
erc721: Interface;
|
|
1401
|
+
erc1155: Interface;
|
|
1402
|
+
};
|
|
1403
|
+
/** Max value the contracts accept for `minExecutionDelay` / `requestedDelay` (30 days). */
|
|
1404
|
+
declare const MAX_EXECUTION_DELAY: number;
|
|
1405
|
+
declare const MAX_OWNERS = 20;
|
|
1406
|
+
declare const MAX_MODULES = 50;
|
|
1407
|
+
/** Head of the Zodiac module linked list. */
|
|
1408
|
+
declare const SENTINEL_MODULES = "0x0000000000000000000000000000000000000001";
|
|
1409
|
+
declare const selfCall: {
|
|
1410
|
+
addOwner: (owner: Address) => Hex;
|
|
1411
|
+
removeOwner: (owner: Address) => Hex;
|
|
1412
|
+
changeThreshold: (threshold: number) => Hex;
|
|
1413
|
+
enableModule: (module: Address) => Hex;
|
|
1414
|
+
/**
|
|
1415
|
+
* Disable a module.
|
|
1416
|
+
*
|
|
1417
|
+
* `prevModule` is the predecessor in the Zodiac linked list and must be resolved
|
|
1418
|
+
* against the live list — a proposal built against a stale list can never execute.
|
|
1419
|
+
* Prefer `Vault.propose.disableModule`, which resolves it for you.
|
|
1420
|
+
*/
|
|
1421
|
+
disableModule: (prevModule: Address, module: Address) => Hex;
|
|
1422
|
+
setMinExecutionDelay: (seconds: number) => Hex;
|
|
1423
|
+
addDelegatecallTarget: (target: Address) => Hex;
|
|
1424
|
+
removeDelegatecallTarget: (target: Address) => Hex;
|
|
1425
|
+
cancelByConsensus: (txHash: Hex) => Hex;
|
|
1426
|
+
/** Sign arbitrary bytes. For EIP-1271 hash pre-approval use {@link approveHashForEip1271}. */
|
|
1427
|
+
signMessage: (data: Hex) => Hex;
|
|
1428
|
+
unsignMessage: (data: Hex) => Hex;
|
|
1429
|
+
/**
|
|
1430
|
+
* Pre-approve a hash so `isValidSignature(hash, …)` returns the EIP-1271 magic value.
|
|
1431
|
+
*
|
|
1432
|
+
* `isValidSignature(h)` checks `signedMessages[getMessageHash(abi.encode(h))]`, while
|
|
1433
|
+
* `signMessage(data)` stores `getMessageHash(data)`. Because `abi.encode` of a static
|
|
1434
|
+
* `bytes32` is the identity on its 32 bytes, this produces calldata identical to
|
|
1435
|
+
* `signMessage(hash)` — the encoding step is a no-op for a well-formed hash.
|
|
1436
|
+
*
|
|
1437
|
+
* It is a separate helper because the *length* is what matters: signing an
|
|
1438
|
+
* arbitrary-length message `M` does NOT make `isValidSignature(keccak256(M))`
|
|
1439
|
+
* validate, since EIP-1271 hashes the 32-byte dataHash, not `M`. This entry point
|
|
1440
|
+
* enforces the 32-byte precondition and states the intent, so that mistake is
|
|
1441
|
+
* caught here rather than discovered when a counterparty's check silently fails.
|
|
1442
|
+
*/
|
|
1443
|
+
approveHashForEip1271: (hash: Hex) => Hex;
|
|
1444
|
+
/** Revoke a hash previously approved via {@link approveHashForEip1271}. */
|
|
1445
|
+
revokeHashForEip1271: (hash: Hex) => Hex;
|
|
1446
|
+
};
|
|
1447
|
+
declare const token: {
|
|
1448
|
+
erc20Transfer: (to: Address, amount: bigint) => Hex;
|
|
1449
|
+
erc20Approve: (spender: Address, amount: bigint) => Hex;
|
|
1450
|
+
erc721Transfer: (from: Address, to: Address, tokenId: bigint) => Hex;
|
|
1451
|
+
erc1155Transfer: (from: Address, to: Address, id: bigint, amount: bigint, data?: Hex) => Hex;
|
|
1452
|
+
erc1155BatchTransfer: (from: Address, to: Address, ids: bigint[], amounts: bigint[], data?: Hex) => Hex;
|
|
1453
|
+
};
|
|
1454
|
+
declare const recoveryCall: {
|
|
1455
|
+
/** Encoded for a vault-proposed call to the module (not a self-call). */
|
|
1456
|
+
setupRecovery: (vaultAddress: Address, guardians: Address[], threshold: number, recoveryPeriodSeconds: number) => Hex;
|
|
1457
|
+
};
|
|
1458
|
+
interface BatchCall {
|
|
1459
|
+
to: Address;
|
|
1460
|
+
value?: bigint;
|
|
1461
|
+
data?: Hex;
|
|
1462
|
+
}
|
|
1463
|
+
/**
|
|
1464
|
+
* Pack calls into MultiSendCallOnly's transaction blob:
|
|
1465
|
+
* `operation(1) ‖ to(20) ‖ value(32) ‖ dataLength(32) ‖ data`, concatenated.
|
|
1466
|
+
*
|
|
1467
|
+
* `MultiSendCallOnly` rejects nested DelegateCall, so operation is always 0.
|
|
1468
|
+
*/
|
|
1469
|
+
declare function encodeMultiSendPayload(calls: BatchCall[]): Hex;
|
|
1470
|
+
/** Full `multiSend(bytes)` calldata for a batch of calls. */
|
|
1471
|
+
declare function encodeMultiSend(calls: BatchCall[]): Hex;
|
|
1472
|
+
/**
|
|
1473
|
+
* Smallest expiration the contract will accept for a given delay.
|
|
1474
|
+
*
|
|
1475
|
+
* `_proposeTransaction` rejects `expiration <= block.timestamp + effectiveDelay` with
|
|
1476
|
+
* `ExpirationTooSoon`, so a proposal must leave at least one execution opportunity
|
|
1477
|
+
* after the timelock elapses. The margin absorbs the gap between building the
|
|
1478
|
+
* proposal and it being mined.
|
|
1479
|
+
*/
|
|
1480
|
+
declare function minimumExpiration(effectiveDelaySeconds: number, marginSeconds?: number, at?: number): number;
|
|
1481
|
+
|
|
1482
|
+
interface VaultContext {
|
|
1483
|
+
connection: Connection;
|
|
1484
|
+
indexer: IndexerClient | null;
|
|
1485
|
+
queries: IndexerQueries | null;
|
|
1486
|
+
contracts: ContractAddresses;
|
|
1487
|
+
consistency: Consistency;
|
|
1488
|
+
maxIndexerLagBlocks: number;
|
|
1489
|
+
}
|
|
1490
|
+
/** A handle to one deployed vault. Cheap to construct; performs no I/O until used. */
|
|
1491
|
+
declare class Vault {
|
|
1492
|
+
readonly address: Address;
|
|
1493
|
+
/** Guardian-based recovery for this vault. */
|
|
1494
|
+
readonly recovery: RecoveryModule;
|
|
1495
|
+
private readonly ctx;
|
|
1496
|
+
constructor(address: Address, ctx: VaultContext);
|
|
1497
|
+
/**
|
|
1498
|
+
* Whether an indexer read is acceptable right now.
|
|
1499
|
+
*
|
|
1500
|
+
* `auto` uses the indexer only while it is live and within the configured lag
|
|
1501
|
+
* budget, so a stalled indexer silently degrades to chain reads instead of
|
|
1502
|
+
* serving stale state.
|
|
1503
|
+
*/
|
|
1504
|
+
private useIndexer;
|
|
1505
|
+
private requireQueries;
|
|
1506
|
+
private contract;
|
|
1507
|
+
/** Owners, threshold, timelock floor, nonce and balance. Always read from chain. */
|
|
1508
|
+
info(): Promise<VaultInfo>;
|
|
1509
|
+
/** Active owners. Prefers the indexer, falls back to chain. */
|
|
1510
|
+
owners(): Promise<Address[]>;
|
|
1511
|
+
isOwner(address: Address): Promise<boolean>;
|
|
1512
|
+
threshold(): Promise<number>;
|
|
1513
|
+
balance(): Promise<bigint>;
|
|
1514
|
+
/**
|
|
1515
|
+
* Enabled modules, in linked-list order.
|
|
1516
|
+
*
|
|
1517
|
+
* Order matters: `disableModule` needs each module's predecessor, so this always
|
|
1518
|
+
* reads the chain rather than the indexer (which stores an unordered set).
|
|
1519
|
+
*/
|
|
1520
|
+
modules(): Promise<Address[]>;
|
|
1521
|
+
isModuleEnabled(module: Address): Promise<boolean>;
|
|
1522
|
+
/** Addresses permitted as DelegateCall targets. Empty means DelegateCall is disabled. */
|
|
1523
|
+
delegatecallTargets(): Promise<Address[]>;
|
|
1524
|
+
isDelegatecallAllowed(target: Address): Promise<boolean>;
|
|
1525
|
+
/** Whether a hash has been pre-approved for EIP-1271 validation. */
|
|
1526
|
+
isValidSignature(hash: Bytes32): Promise<boolean>;
|
|
1527
|
+
/** The vault-transaction hash for a given call, at a given nonce. */
|
|
1528
|
+
transactionHash(to: Address, value: bigint, data: Hex, nonce?: number): Promise<Bytes32>;
|
|
1529
|
+
transaction(txHash: Bytes32): Promise<VaultTransaction>;
|
|
1530
|
+
pendingTransactions(options?: Pagination): Promise<VaultTransaction[]>;
|
|
1531
|
+
transactionHistory(options?: Pagination & {
|
|
1532
|
+
status?: string[];
|
|
1533
|
+
}): Promise<Page<VaultTransaction>>;
|
|
1534
|
+
private hydrateRows;
|
|
1535
|
+
private fromIndexer;
|
|
1536
|
+
/**
|
|
1537
|
+
* Build a `VaultTransaction` from an indexed row.
|
|
1538
|
+
*
|
|
1539
|
+
* Approval counting intersects the indexer's confirmations with the current owner
|
|
1540
|
+
* set. The indexer marks a confirmation inactive only on an explicit
|
|
1541
|
+
* `ApprovalRevoked`; it does not react to `OwnerRemoved`. On chain, removing an
|
|
1542
|
+
* owner bumps `ownerVersions` and invalidates every approval that address made, so
|
|
1543
|
+
* the stored `confirmation_count` over-reports after any removal. Intersecting here
|
|
1544
|
+
* reproduces the contract's `_countValidApprovals`.
|
|
1545
|
+
*/
|
|
1546
|
+
private buildTransaction;
|
|
1547
|
+
/** Authoritative read: the struct plus a `hasApproved` probe per current owner. */
|
|
1548
|
+
private fromChain;
|
|
1549
|
+
/**
|
|
1550
|
+
* What `caller` may legally do to `txHash` right now, and when blocked actions
|
|
1551
|
+
* become available. Defaults to the connected signer's address.
|
|
1552
|
+
*/
|
|
1553
|
+
affordances(txHash: Bytes32, caller?: Address): Promise<Affordance[]>;
|
|
1554
|
+
/**
|
|
1555
|
+
* Proposal builders.
|
|
1556
|
+
*
|
|
1557
|
+
* Every method here is async, including the ones whose work is purely local. Mixing
|
|
1558
|
+
* synchronous throws with rejected promises is a footgun: `propose.addOwner(bad)`
|
|
1559
|
+
* would throw before `.catch()` could attach. Validation failures are always
|
|
1560
|
+
* rejections.
|
|
1561
|
+
*/
|
|
1562
|
+
readonly propose: {
|
|
1563
|
+
/** Propose an arbitrary call. Every other `propose.*` helper routes through this. */
|
|
1564
|
+
call: (params: {
|
|
1565
|
+
to: Address;
|
|
1566
|
+
value?: bigint;
|
|
1567
|
+
data?: Hex;
|
|
1568
|
+
} & ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1569
|
+
/** Send native QUAI. */
|
|
1570
|
+
transfer: (params: {
|
|
1571
|
+
to: Address;
|
|
1572
|
+
amount: bigint;
|
|
1573
|
+
} & ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1574
|
+
erc20Transfer: (params: {
|
|
1575
|
+
token: Address;
|
|
1576
|
+
to: Address;
|
|
1577
|
+
amount: bigint;
|
|
1578
|
+
} & ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1579
|
+
erc721Transfer: (params: {
|
|
1580
|
+
token: Address;
|
|
1581
|
+
to: Address;
|
|
1582
|
+
tokenId: bigint;
|
|
1583
|
+
} & ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1584
|
+
erc1155Transfer: (params: {
|
|
1585
|
+
token: Address;
|
|
1586
|
+
to: Address;
|
|
1587
|
+
id: bigint;
|
|
1588
|
+
amount: bigint;
|
|
1589
|
+
data?: Hex;
|
|
1590
|
+
} & ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1591
|
+
/**
|
|
1592
|
+
* Batch several calls through MultiSendCallOnly.
|
|
1593
|
+
*
|
|
1594
|
+
* Requires MultiSendCallOnly to be on this vault's DelegateCall whitelist, which
|
|
1595
|
+
* is empty by default. The precondition is checked before signing so the failure
|
|
1596
|
+
* names the missing `addDelegatecallTarget` proposal instead of reverting.
|
|
1597
|
+
*/
|
|
1598
|
+
batch: (calls: BatchCall[], options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1599
|
+
addOwner: (owner: Address, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1600
|
+
removeOwner: (owner: Address, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1601
|
+
changeThreshold: (threshold: number, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1602
|
+
setMinExecutionDelay: (seconds: number, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1603
|
+
enableModule: (module: Address, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1604
|
+
/**
|
|
1605
|
+
* Disable a module, resolving its predecessor in the Zodiac linked list.
|
|
1606
|
+
*
|
|
1607
|
+
* The predecessor is baked into the proposal, so any module added or removed
|
|
1608
|
+
* before this executes invalidates it. `execute` re-checks and raises
|
|
1609
|
+
* `StaleProposalError` rather than letting it revert on chain.
|
|
1610
|
+
*/
|
|
1611
|
+
disableModule: (module: Address, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1612
|
+
addDelegatecallTarget: (target: Address, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1613
|
+
removeDelegatecallTarget: (target: Address, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1614
|
+
/** Cancel a transaction that has already reached quorum. Needs full consensus. */
|
|
1615
|
+
cancelByConsensus: (txHash: Bytes32, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1616
|
+
/** Sign arbitrary bytes. For EIP-1271 hash approval use `approveHashForEip1271`. */
|
|
1617
|
+
signMessage: (message: Hex, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1618
|
+
unsignMessage: (message: Hex, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1619
|
+
/**
|
|
1620
|
+
* Make `isValidSignature(hash, …)` return the EIP-1271 magic value.
|
|
1621
|
+
*
|
|
1622
|
+
* Enforces the 32-byte precondition: signing an arbitrary-length message `M`
|
|
1623
|
+
* does not make `isValidSignature(keccak256(M))` validate, because EIP-1271
|
|
1624
|
+
* hashes the dataHash itself, not `M`.
|
|
1625
|
+
*/
|
|
1626
|
+
approveHashForEip1271: (hash: Bytes32, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1627
|
+
revokeHashForEip1271: (hash: Bytes32, options?: ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1628
|
+
/** Configure social recovery. A call to the module, not a self-call. */
|
|
1629
|
+
setupRecovery: (params: {
|
|
1630
|
+
guardians: Address[];
|
|
1631
|
+
threshold: number;
|
|
1632
|
+
recoveryPeriodSeconds: number;
|
|
1633
|
+
} & ProposeOptions) => Promise<ProposeResult | DryRunResult>;
|
|
1634
|
+
};
|
|
1635
|
+
/** Predecessor of `module` in the Zodiac linked list, for `disableModule`. */
|
|
1636
|
+
previousModule(module: Address): Promise<Address>;
|
|
1637
|
+
private proposeSelfCall;
|
|
1638
|
+
private proposeCall;
|
|
1639
|
+
private minExecutionDelay;
|
|
1640
|
+
approve(txHash: Bytes32): Promise<{
|
|
1641
|
+
chainTxHash: Hex;
|
|
1642
|
+
}>;
|
|
1643
|
+
revokeApproval(txHash: Bytes32): Promise<{
|
|
1644
|
+
chainTxHash: Hex;
|
|
1645
|
+
}>;
|
|
1646
|
+
/**
|
|
1647
|
+
* Execute a transaction that has reached quorum.
|
|
1648
|
+
*
|
|
1649
|
+
* The returned {@link ExecuteResult} says what actually happened. A successful
|
|
1650
|
+
* receipt does not imply execution — see {@link classifyExecution}.
|
|
1651
|
+
*/
|
|
1652
|
+
execute(txHash: Bytes32): Promise<ExecuteResult>;
|
|
1653
|
+
/** Approve and, if that meets quorum and the timelock allows, execute in one call. */
|
|
1654
|
+
approveAndExecute(txHash: Bytes32): Promise<ExecuteResult>;
|
|
1655
|
+
/** Cancel a transaction you proposed, before it ever reaches quorum. */
|
|
1656
|
+
cancel(txHash: Bytes32): Promise<{
|
|
1657
|
+
chainTxHash: Hex;
|
|
1658
|
+
}>;
|
|
1659
|
+
/** Close out an expired transaction. Permissionless — no ownership required. */
|
|
1660
|
+
expire(txHash: Bytes32): Promise<{
|
|
1661
|
+
chainTxHash: Hex;
|
|
1662
|
+
}>;
|
|
1663
|
+
private assertCallerIsOwner;
|
|
1664
|
+
/**
|
|
1665
|
+
* Re-validate on chain immediately before signing an execute.
|
|
1666
|
+
*
|
|
1667
|
+
* Reads always go through the chain here, never the indexer: indexed approval
|
|
1668
|
+
* counts can over-report after an owner removal, and a stale count must never gate
|
|
1669
|
+
* a signature.
|
|
1670
|
+
*/
|
|
1671
|
+
private assertExecutable;
|
|
1672
|
+
/**
|
|
1673
|
+
* Native and token holdings.
|
|
1674
|
+
*
|
|
1675
|
+
* Token discovery needs the indexer — the chain cannot answer "which contracts has
|
|
1676
|
+
* this address touched" without scanning every log. Amounts are verified on chain
|
|
1677
|
+
* by default; pass `{ verify: false }` to accept replayed transfer totals instead.
|
|
1678
|
+
*/
|
|
1679
|
+
balances(options?: BalanceOptions): Promise<VaultBalances>;
|
|
1680
|
+
/** Native QUAI received by the vault. Indexer-only. */
|
|
1681
|
+
deposits(options?: Pagination): Promise<Page<{
|
|
1682
|
+
amount: string;
|
|
1683
|
+
wallet_address: string;
|
|
1684
|
+
sender_address: string;
|
|
1685
|
+
deposited_at_block: string | number;
|
|
1686
|
+
deposited_at_tx: string;
|
|
1687
|
+
created_at?: string | null | undefined;
|
|
1688
|
+
}>>;
|
|
1689
|
+
/** ERC20/721/1155 transfers involving this vault. Indexer-only. */
|
|
1690
|
+
tokenTransfers(options?: Pagination): Promise<Page<{
|
|
1691
|
+
value: string;
|
|
1692
|
+
wallet_address: string;
|
|
1693
|
+
to_address: string;
|
|
1694
|
+
token_address: string;
|
|
1695
|
+
from_address: string;
|
|
1696
|
+
direction: "inflow" | "outflow";
|
|
1697
|
+
block_number: string | number;
|
|
1698
|
+
transaction_hash: string;
|
|
1699
|
+
log_index: number;
|
|
1700
|
+
token_id?: string | null | undefined;
|
|
1701
|
+
batch_index?: number | null | undefined;
|
|
1702
|
+
}>>;
|
|
1703
|
+
/** Message hashes currently signed by the vault for EIP-1271. Indexer-only. */
|
|
1704
|
+
signedMessages(): Promise<{
|
|
1705
|
+
wallet_address: string;
|
|
1706
|
+
is_active: boolean;
|
|
1707
|
+
msg_hash: string;
|
|
1708
|
+
signed_at_block: string | number;
|
|
1709
|
+
signed_at_tx: string;
|
|
1710
|
+
data?: string | null | undefined;
|
|
1711
|
+
unsigned_at_block?: string | number | null | undefined;
|
|
1712
|
+
unsigned_at_tx?: string | null | undefined;
|
|
1713
|
+
}[]>;
|
|
1714
|
+
/**
|
|
1715
|
+
* Follow indexer changes for this vault over Supabase Realtime.
|
|
1716
|
+
*
|
|
1717
|
+
* Events fire after the indexer processes a block, so treat them as a signal to
|
|
1718
|
+
* re-read rather than as state themselves — re-read through this handle so approval
|
|
1719
|
+
* counts stay intersected with the current owner set.
|
|
1720
|
+
*
|
|
1721
|
+
* ```ts
|
|
1722
|
+
* const sub = vault.watch((e) => console.log(e.topic, e.type));
|
|
1723
|
+
* // …later
|
|
1724
|
+
* await sub.unsubscribe();
|
|
1725
|
+
* ```
|
|
1726
|
+
*/
|
|
1727
|
+
watch(handler: (event: WatchEvent) => void, options?: WatchOptions): Subscription;
|
|
1728
|
+
/**
|
|
1729
|
+
* Block until the indexer has caught up to `blockNumber` (or to the chain head
|
|
1730
|
+
* when omitted), so a subsequent indexed read reflects a write you just made.
|
|
1731
|
+
*
|
|
1732
|
+
* Returns `reached: false` on timeout rather than throwing — a lagging indexer is
|
|
1733
|
+
* an expected operating condition, and the caller may reasonably fall back to a
|
|
1734
|
+
* chain read. Requires an indexer; without one there is nothing to wait for.
|
|
1735
|
+
*/
|
|
1736
|
+
waitForIndexer(blockNumber?: number, options?: {
|
|
1737
|
+
timeoutMs?: number;
|
|
1738
|
+
pollIntervalMs?: number;
|
|
1739
|
+
signal?: AbortSignal;
|
|
1740
|
+
}): Promise<{
|
|
1741
|
+
reached: boolean;
|
|
1742
|
+
lastIndexedBlock: number;
|
|
1743
|
+
}>;
|
|
1744
|
+
/**
|
|
1745
|
+
* Poll until a transaction is executable, then resolve with its current state.
|
|
1746
|
+
*
|
|
1747
|
+
* Lets a caller express "run this when it can run" instead of reimplementing the
|
|
1748
|
+
* timelock arithmetic. Resolves as soon as the status reaches `ready`; rejects if
|
|
1749
|
+
* the transaction reaches a terminal state first, or if the deadline passes.
|
|
1750
|
+
*
|
|
1751
|
+
* Reads go through the chain so the answer is authoritative — a `ready` verdict
|
|
1752
|
+
* here is immediately actionable.
|
|
1753
|
+
*/
|
|
1754
|
+
waitForExecutable(txHash: Bytes32, options?: {
|
|
1755
|
+
/** Give up after this long. Default 1 hour. */
|
|
1756
|
+
timeoutMs?: number;
|
|
1757
|
+
/** Poll interval. Default 15s, roughly three Quai blocks. */
|
|
1758
|
+
pollIntervalMs?: number;
|
|
1759
|
+
signal?: AbortSignal;
|
|
1760
|
+
onPoll?: (tx: VaultTransaction) => void;
|
|
1761
|
+
}): Promise<VaultTransaction>;
|
|
1762
|
+
/** Compact human-readable summary of a transaction's state. */
|
|
1763
|
+
describe(txHash: Bytes32, caller?: Address): Promise<string>;
|
|
1764
|
+
}
|
|
1765
|
+
|
|
1766
|
+
/**
|
|
1767
|
+
* Entry point to the SDK.
|
|
1768
|
+
*
|
|
1769
|
+
* Construct with {@link connect}. Nothing here performs I/O until a method is
|
|
1770
|
+
* called, so building a client is cheap and safe at module scope.
|
|
1771
|
+
*/
|
|
1772
|
+
declare class QuaiVaultClient {
|
|
1773
|
+
/**
|
|
1774
|
+
* Resolved configuration, with the private key stripped and the indexer key
|
|
1775
|
+
* masked — safe to log. The key itself is consumed once when building the signer.
|
|
1776
|
+
*/
|
|
1777
|
+
readonly config: PublicConfig;
|
|
1778
|
+
readonly connection: Connection;
|
|
1779
|
+
readonly factory: Factory;
|
|
1780
|
+
readonly indexer: IndexerClient | null;
|
|
1781
|
+
readonly queries: IndexerQueries | null;
|
|
1782
|
+
constructor(options?: ClientOptions);
|
|
1783
|
+
get network(): NetworkConfig;
|
|
1784
|
+
get provider(): Provider;
|
|
1785
|
+
get signer(): Signer | null;
|
|
1786
|
+
/** The connected address, or null when read-only. */
|
|
1787
|
+
address(): Promise<Address | null>;
|
|
1788
|
+
/** A handle to one vault. No I/O. */
|
|
1789
|
+
vault(address: Address): Vault;
|
|
1790
|
+
private vaultContext;
|
|
1791
|
+
/** Vault discovery. Requires the indexer — there is no on-chain reverse index. */
|
|
1792
|
+
readonly vaults: {
|
|
1793
|
+
/**
|
|
1794
|
+
* Vaults where `owner` is an active owner.
|
|
1795
|
+
*
|
|
1796
|
+
* Indexer-only: `factory.getWalletsByCreator` was removed from the contracts for
|
|
1797
|
+
* gas reasons, and the factory registry is not indexed by owner.
|
|
1798
|
+
*/
|
|
1799
|
+
forOwner: (owner: Address, options?: Pagination) => Promise<Address[]>;
|
|
1800
|
+
/** Vaults where `guardian` is an active social-recovery guardian. */
|
|
1801
|
+
forGuardian: (guardian: Address, options?: Pagination) => Promise<Address[]>;
|
|
1802
|
+
/** Whether an address is a vault this factory deployed or registered. */
|
|
1803
|
+
exists: (address: Address) => Promise<boolean>;
|
|
1804
|
+
get: (address: Address) => Vault;
|
|
1805
|
+
};
|
|
1806
|
+
private requireQueries;
|
|
1807
|
+
/** Indexer liveness and lag. Reports unavailable when no indexer is configured. */
|
|
1808
|
+
indexerHealth(): Promise<IndexerHealth>;
|
|
1809
|
+
}
|
|
1810
|
+
/**
|
|
1811
|
+
* Create a client.
|
|
1812
|
+
*
|
|
1813
|
+
* Configuration resolves in order of decreasing precedence: explicit options,
|
|
1814
|
+
* environment variables, then the network preset. With nothing supplied it targets
|
|
1815
|
+
* mainnet over the public RPC in read-only mode.
|
|
1816
|
+
*
|
|
1817
|
+
* ```ts
|
|
1818
|
+
* // read-only, from env (QUAIVAULT_NETWORK, QUAIVAULT_INDEXER_ANON_KEY, …)
|
|
1819
|
+
* const qv = connect();
|
|
1820
|
+
*
|
|
1821
|
+
* // read-write against testnet
|
|
1822
|
+
* const qv = connect({ network: 'testnet', privateKey: process.env.KEY });
|
|
1823
|
+
* ```
|
|
1824
|
+
*/
|
|
1825
|
+
declare function connect(options?: ClientOptions): QuaiVaultClient;
|
|
1826
|
+
/** Namespace form, for callers who prefer `QuaiVault.connect(…)`. */
|
|
1827
|
+
declare const QuaiVault: {
|
|
1828
|
+
connect: typeof connect;
|
|
1829
|
+
};
|
|
1830
|
+
|
|
1831
|
+
/**
|
|
1832
|
+
* Raw `Transaction` struct as returned by `QuaiVault.transactions(bytes32)`.
|
|
1833
|
+
* Field names match the Solidity struct.
|
|
1834
|
+
*/
|
|
1835
|
+
interface RawTransactionStruct {
|
|
1836
|
+
to: string;
|
|
1837
|
+
timestamp: bigint;
|
|
1838
|
+
expiration: bigint;
|
|
1839
|
+
proposer: string;
|
|
1840
|
+
executed: boolean;
|
|
1841
|
+
cancelled: boolean;
|
|
1842
|
+
approvedAt: bigint;
|
|
1843
|
+
executionDelay: bigint;
|
|
1844
|
+
value: bigint;
|
|
1845
|
+
data: string;
|
|
1846
|
+
}
|
|
1847
|
+
/**
|
|
1848
|
+
* Typed facade over the generated `Contract`.
|
|
1849
|
+
*
|
|
1850
|
+
* `quais` types its dynamic method accessor as possibly-undefined and cannot
|
|
1851
|
+
* disambiguate overloads by arity, so every call here goes through `getFunction`
|
|
1852
|
+
* with an explicit signature. Keeping that in one place means callers get real
|
|
1853
|
+
* types and overload selection is stated once, next to the ABI it depends on.
|
|
1854
|
+
*/
|
|
1855
|
+
declare class VaultContract {
|
|
1856
|
+
readonly contract: Contract;
|
|
1857
|
+
private readonly retry;
|
|
1858
|
+
constructor(contract: Contract, retry?: RetryOptions);
|
|
1859
|
+
private fn;
|
|
1860
|
+
/**
|
|
1861
|
+
* Reads retry transient RPC failures (see {@link withRetry}); writes never do,
|
|
1862
|
+
* because a resubmit that looks like a timeout may already be in the mempool.
|
|
1863
|
+
*/
|
|
1864
|
+
private read;
|
|
1865
|
+
get interface(): quais.Interface;
|
|
1866
|
+
getOwners(): Promise<string[]>;
|
|
1867
|
+
isOwner(address: Address): Promise<boolean>;
|
|
1868
|
+
threshold(): Promise<bigint>;
|
|
1869
|
+
nonce(): Promise<bigint>;
|
|
1870
|
+
minExecutionDelay(): Promise<bigint>;
|
|
1871
|
+
moduleCount(): Promise<bigint>;
|
|
1872
|
+
getModules(): Promise<string[]>;
|
|
1873
|
+
isModuleEnabled(module: Address): Promise<boolean>;
|
|
1874
|
+
delegatecallAllowed(target: Address): Promise<boolean>;
|
|
1875
|
+
transactions(txHash: Bytes32): Promise<RawTransactionStruct>;
|
|
1876
|
+
/**
|
|
1877
|
+
* Whether an owner's approval currently counts toward the threshold.
|
|
1878
|
+
* Accounts for approval-epoch invalidation from owner removal.
|
|
1879
|
+
*/
|
|
1880
|
+
hasApproved(txHash: Bytes32, owner: Address): Promise<boolean>;
|
|
1881
|
+
/** True when the transaction was closed by `expireTransaction`, not cancelled. */
|
|
1882
|
+
expiredTxs(txHash: Bytes32): Promise<boolean>;
|
|
1883
|
+
getTransactionHash(to: Address, value: bigint, data: Hex, nonce: number | bigint): Promise<Bytes32>;
|
|
1884
|
+
isValidSignature(hash: Bytes32, signature: Hex): Promise<string>;
|
|
1885
|
+
/**
|
|
1886
|
+
* Overload with expiration and delay. The 3-argument overload is used when
|
|
1887
|
+
* neither is supplied, so a caller that wants no expiry never has to pass 0.
|
|
1888
|
+
*/
|
|
1889
|
+
proposeTransactionFull(to: Address, value: bigint, data: Hex, expiration: number, executionDelay: number): Promise<ContractTransactionResponse>;
|
|
1890
|
+
proposeTransactionSimple(to: Address, value: bigint, data: Hex): Promise<ContractTransactionResponse>;
|
|
1891
|
+
approveTransaction(txHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1892
|
+
approveAndExecute(txHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1893
|
+
executeTransaction(txHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1894
|
+
revokeApproval(txHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1895
|
+
cancelTransaction(txHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1896
|
+
expireTransaction(txHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1897
|
+
encode(signature: string, args: unknown[]): Hex;
|
|
1898
|
+
}
|
|
1899
|
+
/** Minimal shape of a sent transaction — enough to await a receipt. */
|
|
1900
|
+
interface ContractTransactionResponse {
|
|
1901
|
+
hash: string;
|
|
1902
|
+
wait(confirmations?: number): Promise<unknown>;
|
|
1903
|
+
}
|
|
1904
|
+
/** Typed facade over `QuaiVaultFactory`. */
|
|
1905
|
+
declare class FactoryContract {
|
|
1906
|
+
readonly contract: Contract;
|
|
1907
|
+
private readonly retry;
|
|
1908
|
+
constructor(contract: Contract, retry?: RetryOptions);
|
|
1909
|
+
private fn;
|
|
1910
|
+
/**
|
|
1911
|
+
* Reads retry transient RPC failures (see {@link withRetry}); writes never do,
|
|
1912
|
+
* because a resubmit that looks like a timeout may already be in the mempool.
|
|
1913
|
+
*/
|
|
1914
|
+
private read;
|
|
1915
|
+
get interface(): quais.Interface;
|
|
1916
|
+
implementation(): Promise<string>;
|
|
1917
|
+
isWallet(address: Address): Promise<boolean>;
|
|
1918
|
+
getWalletCount(): Promise<bigint>;
|
|
1919
|
+
deployedWallets(index: number | bigint): Promise<string>;
|
|
1920
|
+
predictWalletAddress(deployer: Address, salt: Bytes32, owners: Address[], threshold: number, minExecutionDelay: number, initialModules: Address[], initialDelegatecallTargets: Address[]): Promise<string>;
|
|
1921
|
+
/** Full 6-argument overload. The SDK always uses it so mining stays consistent. */
|
|
1922
|
+
createWallet(owners: Address[], threshold: number, salt: Bytes32, minExecutionDelay: number, initialModules: Address[], initialDelegatecallTargets: Address[]): Promise<ContractTransactionResponse>;
|
|
1923
|
+
registerWallet(wallet: Address): Promise<ContractTransactionResponse>;
|
|
1924
|
+
}
|
|
1925
|
+
|
|
1926
|
+
/** Raw `RecoveryConfig` struct from `getRecoveryConfig(address)`. */
|
|
1927
|
+
interface RawRecoveryConfig {
|
|
1928
|
+
guardians: string[];
|
|
1929
|
+
threshold: bigint;
|
|
1930
|
+
recoveryPeriod: bigint;
|
|
1931
|
+
}
|
|
1932
|
+
/** Raw `Recovery` struct from `getRecovery(address,bytes32)`. */
|
|
1933
|
+
interface RawRecovery {
|
|
1934
|
+
newOwners: string[];
|
|
1935
|
+
newThreshold: bigint;
|
|
1936
|
+
approvalCount: bigint;
|
|
1937
|
+
executionTime: bigint;
|
|
1938
|
+
expiration: bigint;
|
|
1939
|
+
requiredThreshold: bigint;
|
|
1940
|
+
executed: boolean;
|
|
1941
|
+
}
|
|
1942
|
+
/**
|
|
1943
|
+
* Typed facade over `SocialRecoveryModule`.
|
|
1944
|
+
*
|
|
1945
|
+
* Every function is wallet-scoped: one module deployment serves every vault, so the
|
|
1946
|
+
* vault address is always the first argument.
|
|
1947
|
+
*/
|
|
1948
|
+
declare class RecoveryContract {
|
|
1949
|
+
readonly contract: Contract;
|
|
1950
|
+
private readonly retry;
|
|
1951
|
+
constructor(contract: Contract, retry?: RetryOptions);
|
|
1952
|
+
private fn;
|
|
1953
|
+
/**
|
|
1954
|
+
* Reads retry transient RPC failures (see {@link withRetry}); writes never do,
|
|
1955
|
+
* because a resubmit that looks like a timeout may already be in the mempool.
|
|
1956
|
+
*/
|
|
1957
|
+
private read;
|
|
1958
|
+
get interface(): quais.Interface;
|
|
1959
|
+
getRecoveryConfig(vault: Address): Promise<RawRecoveryConfig>;
|
|
1960
|
+
getRecovery(vault: Address, recoveryHash: Bytes32): Promise<RawRecovery>;
|
|
1961
|
+
isGuardian(vault: Address, guardian: Address): Promise<boolean>;
|
|
1962
|
+
getPendingRecoveryHashes(vault: Address): Promise<string[]>;
|
|
1963
|
+
hasPendingRecoveries(vault: Address): Promise<boolean>;
|
|
1964
|
+
recoveryApprovals(vault: Address, recoveryHash: Bytes32, guardian: Address): Promise<boolean>;
|
|
1965
|
+
recoveryNonces(vault: Address): Promise<bigint>;
|
|
1966
|
+
maxGuardians(): Promise<bigint>;
|
|
1967
|
+
/** Hash for an explicit nonce. Use {@link predictNextRecoveryHash} for the next one. */
|
|
1968
|
+
getRecoveryHash(vault: Address, newOwners: Address[], newThreshold: number, nonce: bigint | number): Promise<Bytes32>;
|
|
1969
|
+
/** Hash the next `initiateRecovery` would produce, at the current nonce. */
|
|
1970
|
+
predictNextRecoveryHash(vault: Address, newOwners: Address[], newThreshold: number): Promise<Bytes32>;
|
|
1971
|
+
initiateRecovery(vault: Address, newOwners: Address[], newThreshold: number): Promise<ContractTransactionResponse>;
|
|
1972
|
+
approveRecovery(vault: Address, recoveryHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1973
|
+
revokeRecoveryApproval(vault: Address, recoveryHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1974
|
+
executeRecovery(vault: Address, recoveryHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1975
|
+
cancelRecovery(vault: Address, recoveryHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1976
|
+
expireRecovery(vault: Address, recoveryHash: Bytes32): Promise<ContractTransactionResponse>;
|
|
1977
|
+
}
|
|
1978
|
+
|
|
1979
|
+
interface ReceiptLike {
|
|
1980
|
+
hash?: string;
|
|
1981
|
+
transactionHash?: string;
|
|
1982
|
+
blockNumber?: number | bigint | null;
|
|
1983
|
+
gasUsed?: bigint | number | null;
|
|
1984
|
+
status?: number | null;
|
|
1985
|
+
logs: ReadonlyArray<{
|
|
1986
|
+
topics: ReadonlyArray<string>;
|
|
1987
|
+
data: string;
|
|
1988
|
+
address?: string;
|
|
1989
|
+
}>;
|
|
1990
|
+
}
|
|
1991
|
+
/**
|
|
1992
|
+
* Classify what actually happened to a vault transaction, from the receipt of the
|
|
1993
|
+
* Quai transaction that carried `execute` / `approveAndExecute`.
|
|
1994
|
+
*
|
|
1995
|
+
* This exists because `receipt.status === 1` does NOT mean the vault transaction ran.
|
|
1996
|
+
* Three cases produce a successful receipt with no execution:
|
|
1997
|
+
*
|
|
1998
|
+
* 1. **Lazy timelock clock** — `executeTransaction` on a timelocked transaction whose
|
|
1999
|
+
* `approvedAt` was never set (e.g. the threshold was lowered after owners approved)
|
|
2000
|
+
* sets `approvedAt`, emits `ThresholdReached`, and returns without executing. It
|
|
2001
|
+
* deliberately does not revert, because a revert would roll back the clock start.
|
|
2002
|
+
* 2. **`approveAndExecute` returned false** — the threshold is unmet, or the timelock
|
|
2003
|
+
* has not elapsed. A boolean return value is invisible in a receipt.
|
|
2004
|
+
* 3. **External call failure (Option B)** — the vault marks the transaction `executed`
|
|
2005
|
+
* permanently and emits `TransactionFailed` instead of reverting. The vault
|
|
2006
|
+
* transaction is dead; the receipt says success.
|
|
2007
|
+
*/
|
|
2008
|
+
declare function classifyExecution(receipt: ReceiptLike, vault: string, txHash: Bytes32): ExecuteResult;
|
|
2009
|
+
/**
|
|
2010
|
+
* Pull the vault-transaction hash out of a `proposeTransaction` receipt.
|
|
2011
|
+
* The `TransactionProposed` event is the only reliable source — `proposeTransaction`
|
|
2012
|
+
* returns the hash, but return values are not available from a receipt.
|
|
2013
|
+
*/
|
|
2014
|
+
declare function extractProposedTxHash(receipt: ReceiptLike, vault: string): Bytes32 | null;
|
|
2015
|
+
|
|
2016
|
+
interface RawTransactionState {
|
|
2017
|
+
executed: boolean;
|
|
2018
|
+
cancelled: boolean;
|
|
2019
|
+
/** From `expiredTxs[txHash]` — distinguishes expiry from voluntary cancellation. */
|
|
2020
|
+
isExpired?: boolean;
|
|
2021
|
+
expiration: number;
|
|
2022
|
+
executionDelay: number;
|
|
2023
|
+
approvedAt: number;
|
|
2024
|
+
approvalCount: number;
|
|
2025
|
+
threshold: number;
|
|
2026
|
+
/** Set when a TransactionFailed event was indexed. */
|
|
2027
|
+
failed?: boolean;
|
|
2028
|
+
}
|
|
2029
|
+
declare function nowSeconds(): number;
|
|
2030
|
+
/**
|
|
2031
|
+
* `approvedAt + executionDelay`, or 0 when the timelock clock has not started.
|
|
2032
|
+
*
|
|
2033
|
+
* `approvedAt` is written once, on the first threshold crossing, and is never
|
|
2034
|
+
* cleared — revoking approvals below the threshold does not reset the clock.
|
|
2035
|
+
*/
|
|
2036
|
+
declare function executableAfterOf(approvedAt: number, executionDelay: number): number;
|
|
2037
|
+
/**
|
|
2038
|
+
* Derive the lifecycle status from raw contract state.
|
|
2039
|
+
*
|
|
2040
|
+
* `ready` and `timelocked` refine the contract's "pending": both mean not yet
|
|
2041
|
+
* executed with quorum reached, differing only on whether the delay has elapsed.
|
|
2042
|
+
* The contract has no such distinction — it is computed here so callers do not
|
|
2043
|
+
* have to reimplement the timelock arithmetic.
|
|
2044
|
+
*/
|
|
2045
|
+
declare function deriveStatus(state: RawTransactionState, at?: number): TransactionStatus;
|
|
2046
|
+
/** Whether the status admits no further state transitions. */
|
|
2047
|
+
declare function isTerminal(status: TransactionStatus): boolean;
|
|
2048
|
+
interface RawRecoveryState {
|
|
2049
|
+
executed: boolean;
|
|
2050
|
+
approvalCount: number;
|
|
2051
|
+
/** Threshold captured at initiation, not the current config. */
|
|
2052
|
+
requiredThreshold: number;
|
|
2053
|
+
executionTime: number;
|
|
2054
|
+
expiration: number;
|
|
2055
|
+
}
|
|
2056
|
+
/**
|
|
2057
|
+
* Derive a recovery's lifecycle status from raw module state.
|
|
2058
|
+
*
|
|
2059
|
+
* Expiry is computed from `expiration` rather than taken from a stored flag, because
|
|
2060
|
+
* nothing transitions a recovery to expired on its own — `expireRecovery` is a
|
|
2061
|
+
* permissionless cleanup call somebody has to make. The indexer only writes an
|
|
2062
|
+
* expired status when it sees `RecoveryExpiredEvent`, so an un-cleaned recovery reads
|
|
2063
|
+
* as `pending` there long after it died. Computing it here keeps the SDK honest
|
|
2064
|
+
* regardless of which side the data came from.
|
|
2065
|
+
*
|
|
2066
|
+
* `cancelled` is never returned: `cancelRecovery` deletes the on-chain struct, so it
|
|
2067
|
+
* is only observable through indexed history.
|
|
2068
|
+
*/
|
|
2069
|
+
declare function deriveRecoveryStatus(state: RawRecoveryState, at?: number): Exclude<RecoveryStatus, 'cancelled'>;
|
|
2070
|
+
|
|
2071
|
+
interface AffordanceContext {
|
|
2072
|
+
tx: VaultTransaction;
|
|
2073
|
+
caller: Address;
|
|
2074
|
+
isOwner: boolean;
|
|
2075
|
+
/** Whether `caller` currently has a threshold-counting approval. */
|
|
2076
|
+
hasApproved: boolean;
|
|
2077
|
+
at?: number;
|
|
2078
|
+
}
|
|
2079
|
+
/**
|
|
2080
|
+
* Enumerate which actions `caller` may legally take on `tx` right now, and when a
|
|
2081
|
+
* blocked action becomes available.
|
|
2082
|
+
*
|
|
2083
|
+
* Every rule here mirrors an on-chain check, so callers can plan instead of
|
|
2084
|
+
* discovering constraints through reverted transactions:
|
|
2085
|
+
*
|
|
2086
|
+
* - `onlyOwner` on approve / revoke / execute / cancel
|
|
2087
|
+
* - epoch-based approvals (`_approvalValid`) for already-approved / not-approved
|
|
2088
|
+
* - `approvedAt != 0` permanently locking proposer-cancel, even after revocations
|
|
2089
|
+
* - the timelock on external calls (self-calls bypass it)
|
|
2090
|
+
* - expiration, and the permissionless `expireTransaction` cleanup path
|
|
2091
|
+
*/
|
|
2092
|
+
declare function computeAffordances(ctx: AffordanceContext): Affordance[];
|
|
2093
|
+
/** The subset of actions currently allowed. */
|
|
2094
|
+
declare function allowedActions(affordances: Affordance[]): Affordance[];
|
|
2095
|
+
|
|
2096
|
+
/**
|
|
2097
|
+
* Encode the `initialize` call the factory delegatecalls from the proxy constructor.
|
|
2098
|
+
*
|
|
2099
|
+
* This MUST match `QuaiVaultFactory._createWallet` exactly — including the module and
|
|
2100
|
+
* delegatecall-target arrays. Encoding `[]` for those while deploying with a non-empty
|
|
2101
|
+
* array yields a different bytecode hash, so the mined address will not be the address
|
|
2102
|
+
* the factory actually deploys to.
|
|
2103
|
+
*/
|
|
2104
|
+
declare function encodeInitData(params: {
|
|
2105
|
+
owners: Address[];
|
|
2106
|
+
threshold: number;
|
|
2107
|
+
minExecutionDelay?: number;
|
|
2108
|
+
initialModules?: Address[];
|
|
2109
|
+
initialDelegatecallTargets?: Address[];
|
|
2110
|
+
}): string;
|
|
2111
|
+
/**
|
|
2112
|
+
* keccak256 of the full proxy creation bytecode (creation code + ABI-encoded
|
|
2113
|
+
* constructor args), which is the third input to CREATE2.
|
|
2114
|
+
*
|
|
2115
|
+
* Constant for a given set of create params, so it is computed once and reused
|
|
2116
|
+
* across every mining attempt.
|
|
2117
|
+
*/
|
|
2118
|
+
declare function computeBytecodeHash(implementation: Address, initData: string): Bytes32;
|
|
2119
|
+
/**
|
|
2120
|
+
* The factory namespaces user salts by caller:
|
|
2121
|
+
* `fullSalt = keccak256(abi.encodePacked(msg.sender, userSalt))`.
|
|
2122
|
+
* Two deployers using the same user salt therefore get different addresses.
|
|
2123
|
+
*/
|
|
2124
|
+
declare function computeFullSalt(deployer: Address, userSalt: Bytes32): Bytes32;
|
|
2125
|
+
/**
|
|
2126
|
+
* Reproduce `QuaiVaultFactory.predictWalletAddress` off-chain — no RPC needed.
|
|
2127
|
+
*/
|
|
2128
|
+
declare function predictVaultAddress(args: {
|
|
2129
|
+
factory: Address;
|
|
2130
|
+
implementation: Address;
|
|
2131
|
+
deployer: Address;
|
|
2132
|
+
salt: Bytes32;
|
|
2133
|
+
params: CreateVaultParams;
|
|
2134
|
+
}): Address;
|
|
2135
|
+
/**
|
|
2136
|
+
* The shard prefix of a Quai address: `0x` plus the leading byte.
|
|
2137
|
+
*
|
|
2138
|
+
* Quai addresses are shard-scoped. A vault deployed outside the deployer's shard is
|
|
2139
|
+
* unreachable from it, which is why deployment requires mining a salt rather than
|
|
2140
|
+
* picking one at random.
|
|
2141
|
+
*/
|
|
2142
|
+
declare function shardPrefixOf(address: Address): string;
|
|
2143
|
+
|
|
2144
|
+
/**
|
|
2145
|
+
* Address validation for Quai's dual-ledger, sharded address space.
|
|
2146
|
+
*
|
|
2147
|
+
* Two independent properties are encoded in a Quai address:
|
|
2148
|
+
*
|
|
2149
|
+
* - **Zone** — the first byte (`0x00`–`0x02`, `0x10`–`0x12`, `0x20`–`0x22`). An address
|
|
2150
|
+
* outside those ranges belongs to no shard and cannot hold state.
|
|
2151
|
+
* - **Ledger** — the 9th bit, i.e. the high bit of the *second* byte. Set means Qi (the
|
|
2152
|
+
* UTXO ledger); clear means Quai (the EVM account ledger).
|
|
2153
|
+
*
|
|
2154
|
+
* They are genuinely orthogonal: `0x008111…` sits in zone `0x00` yet is a Qi address, so
|
|
2155
|
+
* a zone check alone is not enough.
|
|
2156
|
+
*
|
|
2157
|
+
* **Qi addresses cannot interact with smart contracts.** A Qi owner could never sign a
|
|
2158
|
+
* vault transaction, a Qi guardian could never approve a recovery, and native value sent
|
|
2159
|
+
* to one leaves the Quai ledger. The contracts do not check for this — `_addOwner` only
|
|
2160
|
+
* rejects the zero address, the vault itself and the module sentinel — so admitting one
|
|
2161
|
+
* permanently reduces the number of addresses able to reach the threshold, and enough of
|
|
2162
|
+
* them bricks the vault. The SDK therefore rejects Qi addresses wherever an address is
|
|
2163
|
+
* committed to a role or receives value.
|
|
2164
|
+
*/
|
|
2165
|
+
type AddressLedger = 'quai' | 'qi';
|
|
2166
|
+
interface AddressCheck {
|
|
2167
|
+
valid: boolean;
|
|
2168
|
+
checksummed?: Address;
|
|
2169
|
+
/** Zone prefix, e.g. `0x00`. Absent when the address belongs to no shard. */
|
|
2170
|
+
zone?: string;
|
|
2171
|
+
ledger?: AddressLedger;
|
|
2172
|
+
reason?: string;
|
|
2173
|
+
}
|
|
2174
|
+
/** Inspect an address without throwing. */
|
|
2175
|
+
declare function inspectAddress(value: unknown): AddressCheck;
|
|
2176
|
+
/** Whether an address is shard-valid and on the Quai ledger. */
|
|
2177
|
+
declare function isUsableQuaiAddress(value: unknown): boolean;
|
|
2178
|
+
/**
|
|
2179
|
+
* Assert an address can participate in Quai smart-contract calls, returning it
|
|
2180
|
+
* checksummed.
|
|
2181
|
+
*
|
|
2182
|
+
* Use for any address being committed to a role (owner, guardian, module, delegatecall
|
|
2183
|
+
* target) or receiving value. Do **not** use it for addresses being *removed* — a Qi
|
|
2184
|
+
* address that predates this check must still be removable — nor for read-only lookups,
|
|
2185
|
+
* where rejecting the query is less useful than answering it.
|
|
2186
|
+
*/
|
|
2187
|
+
declare function assertQuaiAddress(value: unknown, label?: string): Address;
|
|
2188
|
+
/** Assert every address in a list, reporting the offending index. */
|
|
2189
|
+
declare function assertQuaiAddresses(values: readonly unknown[], label: string): Address[];
|
|
2190
|
+
|
|
2191
|
+
/** Machine-readable error codes. Stable across releases. */
|
|
2192
|
+
type QuaiVaultErrorCode = 'CONFIG' | 'NOT_CONNECTED' | 'NO_SIGNER' | 'NO_INDEXER' | 'INDEXER_QUERY' | 'INDEXER_STALE' | 'VALIDATION' | 'NOT_FOUND' | 'PRECONDITION' | 'REVERT' | 'SALT_MINING' | 'STALE_PROPOSAL' | 'UNSUPPORTED';
|
|
2193
|
+
declare class QuaiVaultError extends Error {
|
|
2194
|
+
readonly code: QuaiVaultErrorCode;
|
|
2195
|
+
/** What the caller can do about it, in plain language. */
|
|
2196
|
+
readonly remediation?: string;
|
|
2197
|
+
/** Unix seconds after which retrying could succeed. */
|
|
2198
|
+
readonly retryableAt?: number;
|
|
2199
|
+
readonly cause?: unknown;
|
|
2200
|
+
constructor(code: QuaiVaultErrorCode, message: string, options?: {
|
|
2201
|
+
remediation?: string;
|
|
2202
|
+
retryableAt?: number;
|
|
2203
|
+
cause?: unknown;
|
|
2204
|
+
});
|
|
2205
|
+
/** Structured form, for logs and machine consumers. */
|
|
2206
|
+
toJSON(): Record<string, unknown>;
|
|
2207
|
+
}
|
|
2208
|
+
declare class ConfigError extends QuaiVaultError {
|
|
2209
|
+
constructor(message: string, remediation?: string);
|
|
2210
|
+
}
|
|
2211
|
+
declare class NoSignerError extends QuaiVaultError {
|
|
2212
|
+
constructor(operation: string);
|
|
2213
|
+
}
|
|
2214
|
+
declare class NoIndexerError extends QuaiVaultError {
|
|
2215
|
+
constructor(operation: string);
|
|
2216
|
+
}
|
|
2217
|
+
declare class IndexerQueryError extends QuaiVaultError {
|
|
2218
|
+
constructor(message: string, cause?: unknown);
|
|
2219
|
+
}
|
|
2220
|
+
declare class ValidationError extends QuaiVaultError {
|
|
2221
|
+
constructor(message: string, remediation?: string);
|
|
2222
|
+
}
|
|
2223
|
+
declare class NotFoundError extends QuaiVaultError {
|
|
2224
|
+
constructor(message: string);
|
|
2225
|
+
}
|
|
2226
|
+
/** A precondition the contract enforces would fail — checked before signing. */
|
|
2227
|
+
declare class PreconditionError extends QuaiVaultError {
|
|
2228
|
+
constructor(message: string, options?: {
|
|
2229
|
+
remediation?: string;
|
|
2230
|
+
retryableAt?: number;
|
|
2231
|
+
});
|
|
2232
|
+
}
|
|
2233
|
+
/** A contract call reverted. Carries the decoded custom error when resolvable. */
|
|
2234
|
+
declare class RevertError extends QuaiVaultError {
|
|
2235
|
+
readonly revert?: DecodedRevert;
|
|
2236
|
+
constructor(message: string, revert?: DecodedRevert, options?: {
|
|
2237
|
+
remediation?: string;
|
|
2238
|
+
cause?: unknown;
|
|
2239
|
+
});
|
|
2240
|
+
toJSON(): Record<string, unknown>;
|
|
2241
|
+
}
|
|
2242
|
+
declare class SaltMiningError extends QuaiVaultError {
|
|
2243
|
+
constructor(message: string, remediation?: string);
|
|
2244
|
+
}
|
|
2245
|
+
/**
|
|
2246
|
+
* A `disableModule` proposal whose baked-in `prevModule` no longer matches the
|
|
2247
|
+
* live linked list. The proposal can never execute and must be replaced.
|
|
2248
|
+
*/
|
|
2249
|
+
declare class StaleProposalError extends QuaiVaultError {
|
|
2250
|
+
constructor(message: string);
|
|
2251
|
+
}
|
|
2252
|
+
|
|
2253
|
+
/**
|
|
2254
|
+
* Decode revert data against every QuaiVault ABI, plus the two Solidity builtins.
|
|
2255
|
+
* Returns `undefined` for empty data or an unrecognised selector.
|
|
2256
|
+
*/
|
|
2257
|
+
declare function decodeRevert(data: unknown): DecodedRevert | undefined;
|
|
2258
|
+
/** Remediation text for a custom error name, if the SDK knows one. */
|
|
2259
|
+
declare function remediationFor(errorName: string): string | undefined;
|
|
2260
|
+
/**
|
|
2261
|
+
* Pull revert data out of the many shapes providers use, then decode it.
|
|
2262
|
+
* Handles quais/ethers `CALL_EXCEPTION` errors, raw RPC error bodies and nested causes.
|
|
2263
|
+
*/
|
|
2264
|
+
declare function decodeRevertFromError(error: unknown): DecodedRevert | undefined;
|
|
2265
|
+
/** All known custom error selectors. Exposed for tooling and tests. */
|
|
2266
|
+
declare function knownErrorSelectors(): Array<{
|
|
2267
|
+
selector: Hex;
|
|
2268
|
+
signature: string;
|
|
2269
|
+
}>;
|
|
2270
|
+
|
|
2271
|
+
export { type Address, type AddressCheck, type AddressLedger, type Affordance, type AffordanceBlocker, type AffordanceContext, type ApprovalRecord, type BalanceOptions, type BatchCall, type Bytes32, type ClientOptions, ConfigError, Connection, type Consistency, type ContractAddresses, type CreateProgress, type CreateVaultParams, type CreateVaultResult, type DecodeContext, type DecodeResult, type DecodedBatchCall, type DecodedCall, type DecodedRevert, type DryRunResult, ENV_VARS, type ExecuteOutcome, type ExecuteResult, Factory, type FactoryContext, FactoryContract, type Hex, IndexerClient, type IndexerConfig, type IndexerHealth, IndexerQueries, IndexerQueryError, MAX_EXECUTION_DELAY, MAX_MODULES, MAX_OWNERS, type MineSaltOptions, type MinedSalt, type MiningStrategy, type NetworkConfig, type NetworkName, NoIndexerError, NoSignerError, NotFoundError, Operation, type Page, type Pagination, PreconditionError, type ProposeOptions, type ProposeResult, QuaiVault, QuaiVaultClient, QuaiVaultError, type QuaiVaultErrorCode, type RawRecovery, type RawRecoveryConfig, type RawRecoveryState, type RawTransactionState, type RawTransactionStruct, type ReceiptLike, type RecoveryAction, type RecoveryAffordance, type RecoveryConfig, RecoveryContract, RecoveryModule, type RecoveryModuleContext, type RecoveryRequest, type RecoveryStatus, type ResolvedConfig, type RetryOptions, RevertError, SENTINEL_MODULES, SaltMiningError, StaleProposalError, type Subscription, type TokenBalance, type TransactionKind, type TransactionStatus, ValidationError, Vault, type VaultAction, type VaultBalances, type VaultContext, VaultContract, type VaultInfo, type VaultTransaction, type WatchEvent, type WatchOptions, type WatchTopic, allowedActions, assertQuaiAddress, assertQuaiAddresses, classifyExecution, computeAffordances, computeBytecodeHash, computeFullSalt, connect, decodeCall, decodeMultiSendPayload, decodeRevert, decodeRevertFromError, defaultStrategy, deriveRecoveryStatus, deriveStatus, encodeInitData, encodeMultiSend, encodeMultiSendPayload, executableAfterOf, extractProposedTxHash, schemas as indexerSchemas, inspectAddress, interfaces, isNetworkName, isTerminal, isTransient, isUsableQuaiAddress, knownErrorSelectors, loadBalances, mainnet, mineSalt, minimumExpiration, networks, nowSeconds, predictVaultAddress, recoveryCall, remediationFor, resolveConfig, selfCall, shardPrefixOf, syncStrategy, testnet, token as tokenCalls, watchVault, withRetry, workerThreadsStrategy };
|