@blockula/sdk 0.3.0 → 1.0.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/dist/index.d.ts CHANGED
@@ -1,10 +1,276 @@
1
- import { type Action, type Tx, type UnsignedTx } from "./tx.js";
1
+ import { type SeanceClaimRef, type Action, type BaseFee, type ProposalKind, type ProgramPolicy, type Tx, type UnsignedTx } from "./tx.js";
2
+ import { type ProofResponse, type ProvenRecord } from "./proof.js";
3
+ import { type ProgramCodeInfo, type ProgramCost, type ProgramFuel, type ProgramInfo, type ProgramInterfaceInfo, type ProgramParams, type ProgramReceipt, type ProgramViewResult } from "./programs.js";
4
+ import { type NetworkName } from "./networks.js";
2
5
  export * from "./tx.js";
6
+ export * from "./proof.js";
7
+ export * from "./distribution.js";
8
+ export * from "./release.js";
9
+ export * from "./describe.js";
10
+ export * from "./networks.js";
11
+ export * from "./payments.js";
12
+ export * from "./programs.js";
3
13
  export declare const DEFAULT_RPC = "http://localhost:7070";
4
- export declare function addressFromPublicKey(publicKey: Uint8Array): string;
14
+ /** Address prefixes: `boo` on mainnet (and dev chains), `tboo` on public testnets. */
15
+ export declare const KNOWN_PREFIXES: readonly ["boo", "tboo"];
16
+ export declare const DEFAULT_PREFIX = "boo";
17
+ /** Mainnet's chain id (node/src/chain.rs `MAINNET_CHAIN_ID`). */
18
+ export declare const MAINNET_CHAIN_ID = "blockula-1";
19
+ /** How long a transaction stays valid by default: 600 blocks (10 minutes at 1 s blocks). */
20
+ export declare const DEFAULT_VALID_FOR_BLOCKS = 600;
21
+ /** The address of a public key: bech32m(prefix, BLAKE3(public key)). */
22
+ export declare function addressFromPublicKey(publicKey: Uint8Array, prefix?: string): string;
5
23
  /** A key's id: BLAKE3(public key) as hex. Same 32 bytes as inside the `boo1…` address it derives. */
6
24
  export declare function keyId(publicKey: Uint8Array): string;
7
- export declare function isAddress(s: string): boolean;
25
+ /** The prefix of a canonical address (`boo`, `tboo`), or `undefined` if `s` isn't one. */
26
+ export declare function addressPrefix(s: string): string | undefined;
27
+ /** Whether `s` is an address: with any known prefix, or exactly `prefix` when given. */
28
+ export declare function isAddress(s: string, prefix?: string): boolean;
29
+ /**
30
+ * An amount of FANG: a decimal string ("1.5") or bigint drops (1 FANG = 10⁹ drops).
31
+ * A JS number is still accepted, but that form is deprecated and will be dropped: floats can't
32
+ * hold most decimal amounts exactly (`0.1 + 0.2`). Pass a string.
33
+ */
34
+ export type Amount = string | number | bigint;
35
+ /** A `.boo` name as the chain stores it (node/src/types.rs `normalize_name`): lowercase, without the suffix. */
36
+ export declare function bareName(name: string): string;
37
+ /**
38
+ * The most `Wallet.propose` bonds by default without being told (audit gap-7-5): mainnet's genesis
39
+ * `proposal_deposit` (node/src/params.rs). A node reporting more is refused; pass `deposit`.
40
+ */
41
+ export declare const DEFAULT_MAX_PROPOSAL_DEPOSIT: bigint;
42
+ /** Highest vote conviction (node/src/params.rs `MAX_CONVICTION`). */
43
+ export declare const MAX_CONVICTION = 6;
44
+ /** Lock periods a vote at each conviction locks its amount for (params.rs `CONVICTION_PERIODS`) … */
45
+ export declare const CONVICTION_PERIODS: readonly [0, 1, 2, 4, 8, 16, 32];
46
+ /** … and its weight in tenths of the amount (`CONVICTION_TENTHS`): 0.1× with no lock, then 1×–6×. */
47
+ export declare const CONVICTION_TENTHS: readonly [1, 10, 20, 30, 40, 50, 60];
48
+ /** A vote's weight in drops: `amount` × the conviction multiplier (params.rs `vote_weight`). */
49
+ export declare function convictionWeight(amount: Amount, conviction: number): bigint;
50
+ /**
51
+ * Builders for `Wallet.propose` kinds (node/src/types.rs `ProposalKind`). Amounts are FANG (or
52
+ * bigint drops), Soul is in Soul ("2.5"); names in `to`/`account` are resolved when proposing.
53
+ */
54
+ export declare const proposal: {
55
+ /** Set a governance parameter (a key of `/api/params`, e.g. "max_validators") to a raw value (drops, blocks, bps …), within its bounds. */
56
+ paramChange(key: string, value: bigint | number | string): ProposalKind;
57
+ /** Pay from the treasury (spends above a share of the treasury need a supermajority). */
58
+ treasurySpend(to: string, amount: Amount): ProposalKind;
59
+ /**
60
+ * Open a community distribution of `total`, claimable with Merkle proofs against `merkleRoot` until block `claimUntil`.
61
+ * `distributionId` is the id the tree was built for (`buildDistribution(id, …)`): one no distribution has yet,
62
+ * at most 1,000 past the next proposal id (`client.proposals()`'s `next_distribution_id` is free, and
63
+ * `max_distribution_id` is the largest allowed; the range only grows). Other proposals landing first don't change
64
+ * it, so a multisig can take its time approving; if a distribution with that id opens first, the node refuses this
65
+ * one (nothing is escrowed), or it fails when it runs. Claims close at most 730 days after the proposal's vote ends.
66
+ */
67
+ distribution(distributionId: number, merkleRoot: string, total: Amount, claimUntil: number): ProposalKind;
68
+ /** Put a repo in the contribution pool (weight 1–100; 0 removes it). */
69
+ setRepo(repo: string, weight: number): ProposalKind;
70
+ /** Grant Soul (in Soul, "2.5"; at most 100 per grant). */
71
+ grantSoul(to: string, soul: string | number, reason: string): ProposalKind;
72
+ flagSybil(account: string, reason: string): ProposalKind;
73
+ /** Lift a sybil flag: the appeal path for `flagSybil` (nothing the flag took comes back). */
74
+ unflagSybil(account: string, reason: string): ProposalKind;
75
+ rejectClaim(claimId: number, reason: string): ProposalKind;
76
+ clawback(account: string, reason: string): ProposalKind;
77
+ unlinkGithub(handle: string): ProposalKind;
78
+ /** Refund every funder of a hunt (escrow can be refunded, never redirected). */
79
+ refundHunt(huntId: number): ProposalKind;
80
+ /**
81
+ * Switch to protocol `version` at block `activationHeight` (needs a supermajority). The version is newer than
82
+ * every one scheduled or withdrawn (`client.upgrade()`'s `withdrawn.highest_version`) and at most 16 past the
83
+ * newest scheduled, withdrawn or superseded (`next_version` is the number to use); the activation is at most
84
+ * 365 days after the proposal's vote ends.
85
+ */
86
+ scheduleUpgrade(version: number, activationHeight: number): ProposalKind;
87
+ /**
88
+ * Withdraw the upgrade to protocol `version` scheduled at block `activationHeight` (see
89
+ * `client.upgrade()`), and any scheduled after it, before it activates. Needs a supermajority;
90
+ * there's no timelock (it runs the block after its vote), and it must run at least 64 blocks
91
+ * before the activation height, so propose it at least `voting_blocks + 65` blocks ahead.
92
+ */
93
+ cancelUpgrade(version: number, activationHeight: number): ProposalKind;
94
+ /** Turn on a feature flag (e.g. "ghost"). */
95
+ activateFeature(feature: string): ProposalKind;
96
+ deactivateFeature(feature: string): ProposalKind;
97
+ /** A signal with no on-chain effect. */
98
+ text(): ProposalKind;
99
+ };
100
+ /** One pool an account has stake in (`/api/staking/{account}` `delegations[]`). */
101
+ export interface StakeDelegation {
102
+ validator: string;
103
+ validator_name: string | null;
104
+ /** Pool shares held (what `undelegate` takes). */
105
+ shares: string;
106
+ /** Their current value, in drops. */
107
+ value: string;
108
+ /** What went in, less what sales and slashes took (value above it is earnings). */
109
+ principal: string;
110
+ /** This is the validator's owner's self-bond. */
111
+ self_bond: boolean;
112
+ }
113
+ /** Stake on its way out (`entries[]` of type `unbonding`): paid out by `withdrawUnbonded` from `completes_at`. */
114
+ export interface StakeUnbonding {
115
+ id: number;
116
+ validator: string;
117
+ amount: string;
118
+ started_at: number;
119
+ completes_at: number;
120
+ ready: boolean;
121
+ }
122
+ /** Stake moved between pools (`entries[]` of type `redelegation`): slashable by `from` until `completes_at`. */
123
+ export interface StakeRedelegation {
124
+ id: number;
125
+ from: string;
126
+ to: string;
127
+ amount: string;
128
+ completes_at: number;
129
+ }
130
+ /** An account's stake, from `/api/staking/{account}`. */
131
+ export interface StakeSummary {
132
+ delegations: StakeDelegation[];
133
+ unbonding: StakeUnbonding[];
134
+ redelegations: StakeRedelegation[];
135
+ /** Total value staked, in drops. */
136
+ bonded: string;
137
+ /** Total unbonding, in drops. */
138
+ unbonding_total: string;
139
+ /** Unbonding that has finished (what `withdrawUnbonded` pays now), in drops. */
140
+ withdrawable: string;
141
+ /** The node's plain-English summary. */
142
+ summary: string;
143
+ }
144
+ export declare function stakeSummary(raw: unknown): StakeSummary;
145
+ /**
146
+ * Shares worth about `value` drops in a delegation (rounded down, at most all of them), at the
147
+ * value the delegation reports. That's a node's word: to unbond an amount, pass
148
+ * `wallet.undelegate(validator, { amount })`, which the chain converts itself (audit gap-7-5).
149
+ */
150
+ export declare function sharesFor(d: StakeDelegation, value: Amount): bigint;
151
+ /** `/api/params`' governance parameters as a key → value map (values as strings: amounts can exceed 2^53). */
152
+ export declare function paramsOf(raw: unknown): Record<string, string>;
153
+ /** A proposal, from `/api/proposals` (`proposals[]`) or `/api/proposal/{id}`. Amounts are in drops. */
154
+ export interface ProposalSummary {
155
+ id: number;
156
+ title: string;
157
+ url: string;
158
+ /**
159
+ * The node's own summary text. No digest covers it, so a lying node can make it say anything
160
+ * (audit gap-7-6): show `does` instead, and never present this as what the proposal does.
161
+ */
162
+ summary: string;
163
+ /** What it does, rendered here from `kind` (`describeKind`): what a vote on it binds. */
164
+ does: string;
165
+ kind: ProposalKind | null;
166
+ /**
167
+ * `proposalDigest(kind, title, url)`: what a vote binds. `null` when this client can't compute
168
+ * it exactly (`digest_error` says why, e.g. a number past 2^53): it can't vote on it either.
169
+ */
170
+ digest: string | null;
171
+ digest_error?: string;
172
+ proposer: string | null;
173
+ proposer_name: string | null;
174
+ /** `voting`, `queued`, `rejected`, `executed` or `failed`. */
175
+ status: string;
176
+ deposit: string;
177
+ /** Conviction-weighted ayes and nays (what the majority counts) … */
178
+ aye: string;
179
+ nay: string;
180
+ /** … and the raw FANG behind them (what quorum counts). */
181
+ aye_amount: string;
182
+ nay_amount: string;
183
+ /** aye_amount + nay_amount. */
184
+ turnout: string;
185
+ voters: number;
186
+ /** The quorum it had to reach and whether it did: known once voting closed. */
187
+ quorum?: string;
188
+ quorum_reached?: boolean;
189
+ /** Bootstrap-council votes so far (one per validator); `of` is the set's size at the close. */
190
+ council: {
191
+ ayes: number;
192
+ nays: number;
193
+ of?: number;
194
+ };
195
+ /** Whether it needs `supermajority_bps` of the weight (upgrades, feature activations, issuance parameters, large spends). */
196
+ supermajority: boolean;
197
+ /** Last block votes count in, and when a passed proposal runs (after the timelock). */
198
+ voting_ends_at: number;
199
+ executes_at?: number;
200
+ /** Why it was rejected or failed, or what it did. */
201
+ outcome: string;
202
+ /** With `rules` (`/api/proposals`' `params`): the share of the weight its ayes need, in basis points. */
203
+ threshold_bps?: number;
204
+ }
205
+ export declare function proposalSummary(raw: unknown, rules?: {
206
+ supermajority_bps?: number;
207
+ }): ProposalSummary;
208
+ /** Per-transaction options. */
209
+ export interface TxOptions {
210
+ /** Paid to the block's proposer on top of the base fee: FANG ("0.001") or bigint drops. Default: the wallet's `tip` (0). At most `tip_cap_multiple` (20) × the base fee (`maxTip`), from transferable FANG. */
211
+ tip?: string | number | bigint;
212
+ /** Blocks from now the tx stays valid (at most the chain's `max_tx_validity_blocks`, an hour of blocks). Default: the wallet's `validForBlocks` (600). */
213
+ validForBlocks?: number;
214
+ /**
215
+ * Room for the base fee to rise before the tx is included (TR-6): its `fee` becomes this many
216
+ * times the base fee `/api/fees` fixes for the next 17 blocks (`suggested`), plus the tip. Only
217
+ * the including block's base fee and the tip are charged, so headroom costs nothing; without it a
218
+ * tx queued behind full blocks for longer than that can stop covering the base fee and be
219
+ * dropped (with every later tx from the account). 1 to 100; default the wallet's `feeHeadroom` (1).
220
+ */
221
+ feeHeadroom?: number;
222
+ /**
223
+ * The tx's `fee` outright (FANG, or bigint drops): the most it may be charged, base fee plus tip.
224
+ * At least what it costs at `suggested` now. Overrides `feeHeadroom`.
225
+ */
226
+ maxFee?: Amount;
227
+ }
228
+ /** `Wallet.send`'s options. */
229
+ export interface SendOptions extends TxOptions {
230
+ /** Public, up to 256 bytes, written by the payer: an order or user id you issued. */
231
+ memo?: string;
232
+ /** Wait for it to finalize (default true); `false` returns as soon as a node admitted it. */
233
+ wait?: boolean;
234
+ /**
235
+ * Called with the signed tx and its id before it's submitted, in the wallet's queue (so parallel
236
+ * sends still get one nonce each): store both here, and every outcome is recoverable by
237
+ * resubmitting the same bytes (`client.post(tx)`). If it throws, nothing is submitted, the
238
+ * error is passed on, and the next tx takes the nonce.
239
+ */
240
+ onSigned?: (tx: Tx, id: string) => void | Promise<void>;
241
+ }
242
+ /** The most `feeHeadroom` a tx may ask for: 100 × the base fee. */
243
+ export declare const MAX_FEE_HEADROOM = 100;
244
+ /** The least a payment that opens an account must carry: 0.01 FANG (node/src/types.rs `MIN_NEW_ACCOUNT`). */
245
+ export declare const MIN_NEW_ACCOUNT = 10000000n;
246
+ /** `Wallet.build`'s options: a tx's, plus the resolutions of names it carries as addresses. */
247
+ export interface BuildOptions extends TxOptions {
248
+ /** `Client.resolution`s of names in `action`'s address fields (refused on mainnet unless proven). */
249
+ resolutions?: Resolution[];
250
+ }
251
+ /**
252
+ * A key's consent to being added to one account (audit gap-7-2): its public key and its
253
+ * signature over `keyPopMessage(chain_id, genesis_hash, account, key_id)` (context
254
+ * `KEY_POP_CONTEXT`). The key's holder makes it (`Wallet.keyGrant`) and hands it to the account's
255
+ * owner (`encodeKeyGrant`: a grant code to paste), who adds the key with it (`addOwnerKey`,
256
+ * `addSessionKey`). Nobody can put a key on an account without it, so `/api/key` lists only
257
+ * accounts the key agreed to.
258
+ */
259
+ export interface KeyGrant {
260
+ /** The account the key agrees to join. */
261
+ account: string;
262
+ key_id: string;
263
+ /** Hex ML-DSA-65 public key. */
264
+ public_key: string;
265
+ /** Hex proof of possession. */
266
+ pop: string;
267
+ }
268
+ /** A grant as one pasteable string: `bkgrant1.<account>.<base64url(public key ‖ pop)>`. */
269
+ export declare function encodeKeyGrant(g: KeyGrant): string;
270
+ /** Parses a grant code (`encodeKeyGrant`). Whitespace is ignored, so a wrapped paste works. */
271
+ export declare function decodeKeyGrant(code: string): KeyGrant;
272
+ /** Whether `g` is a valid consent by its key to join `g.account` on the chain `(chainId, genesisHash)`. */
273
+ export declare function verifyKeyGrant(g: KeyGrant, chainId: string, genesisHash: string): boolean;
8
274
  /**
9
275
  * Wallet = one ML-DSA-65 key (from a 32-byte seed, FIPS 204 ξ) acting for one account.
10
276
  * By default the account is the key's own address. Call `actAs(account)` to use a key that
@@ -14,16 +280,39 @@ export declare class Wallet {
14
280
  readonly seed: Uint8Array;
15
281
  client: Client;
16
282
  readonly publicKey: Uint8Array;
17
- /** This key's own address. */
18
- readonly address: string;
19
- /** The account this wallet acts for (defaults to `address`). */
20
- account: string;
21
283
  /** WebAuthn credential id, when the wallet was unlocked by a passkey. Not secret. */
22
284
  credentialId?: Uint8Array;
285
+ /** Default tip (drops) for this wallet's transactions. */
286
+ tip: bigint;
287
+ /** Default validity (blocks from now) for this wallet's transactions. */
288
+ validForBlocks: number;
289
+ /** Default `feeHeadroom` for this wallet's transactions (1: none). See `TxOptions.feeHeadroom`. */
290
+ feeHeadroom: number;
23
291
  private readonly secretKey;
292
+ /**
293
+ * This wallet's txs are signed and submitted one at a time, in nonce order (DEV-3): parallel
294
+ * `send`s from one wallet would otherwise read the same next nonce and all but one be refused.
295
+ */
296
+ private queue;
297
+ /** The nonce after the last tx this wallet submitted, for one chain and account, and that tx. */
298
+ private cursor?;
299
+ private acting?;
300
+ /** How `actAs` found the account, when that was one node's unproven word (checked when signing on mainnet). */
301
+ private actingUnproven?;
24
302
  private constructor();
303
+ /** This key's own address, with the chain's prefix once the client knows it (`await client.addressPrefix()`). */
304
+ get address(): string;
305
+ /** The account this wallet acts for (defaults to `address`). */
306
+ get account(): string;
307
+ set account(account: string);
25
308
  get keyId(): string;
26
- /** Act for another account this key has been authorized on. Accepts a name or address. */
309
+ /**
310
+ * Act for another account this key has been authorized on. Accepts a name or address. A name
311
+ * needs an address here (every tx names the account it acts for), so it's resolved: proven with
312
+ * the client's witnesses. Without them it's one node's word, and on mainnet nothing is signed
313
+ * for an account found that way (`UnprovenNameError`): check the address and pass it instead
314
+ * (audit gap-7-1).
315
+ */
27
316
  actAs(account: string): Promise<this>;
28
317
  static generate(client?: Client): Wallet;
29
318
  static fromSeed(seed: string | Uint8Array, client?: Client): Wallet;
@@ -34,30 +323,170 @@ export declare class Wallet {
34
323
  static fromPasskeyPrf(prfOutput: Uint8Array, client?: Client): Wallet;
35
324
  get seedHex(): string;
36
325
  sign(tx: UnsignedTx): Tx;
37
- build(action: Action, memo?: string): Promise<Tx>;
38
- /** Send FANG to a `.boo` name or `boo1…` address. `amount` is in FANG ("1.5") or bigint drops. */
39
- send(to: string, amount: string | number | bigint, opts?: {
326
+ /**
327
+ * This key's consent to being added to `account` (an address, or a name resolved by the
328
+ * client: proven when it has witnesses; on mainnet an unproven name is refused, pass the address)
329
+ * on the client's chain: hand `encodeKeyGrant(grant)` to the account's owner, who adds the key
330
+ * with it. Pass `chain` to sign offline.
331
+ */
332
+ keyGrant(account: string | Resolution, chain?: {
333
+ chainId: string;
334
+ genesisHash: string;
335
+ }): Promise<KeyGrant>;
336
+ /**
337
+ * The `add_key` action for a grant (an object or its code): it must be for this account and
338
+ * verify on the client's chain, so a wrong or damaged code fails here, before anything is signed.
339
+ */
340
+ private grantAction;
341
+ /**
342
+ * Builds and signs a tx: `fee` = the highest base fee already fixed for the next blocks
343
+ * (`/api/fees` `suggested`) + `tip`, `valid_until` = the current height + `validForBlocks`, and
344
+ * the chain's id and genesis hash from `/api/status`. Only the base fee of the block that
345
+ * includes it (+ the tip) is charged. A tip above `tip_cap_multiple` × the lowest upcoming base
346
+ * fee (`/api/fees` `lowest`, see `maxTip`) is refused here, as nodes would refuse it. To sign
347
+ * offline, build an `UnsignedTx` yourself (with the chain's `genesis_hash`) and `sign` it.
348
+ *
349
+ * `action` may be a function of the height `valid_until` is counted from, for actions that
350
+ * carry an absolute block height of their own (a session key's or a hunt's expiry): computed
351
+ * from the same status read, a node that lies about the height can stretch them by at most
352
+ * `max_tx_validity_blocks`, since validators refuse a `valid_until` further ahead than that
353
+ * (audit gap-7-3).
354
+ *
355
+ * That height is checked first (`Client.checkSigningHeight`: against the witnesses' heads and,
356
+ * when the client knows its genesis clock, the clock), since a node reporting one the chain
357
+ * hasn't reached gets a tx it can hold and release later.
358
+ *
359
+ * `opts.resolutions`: how names in fields that need an address got into `action` (their
360
+ * `Client.resolution`s). On mainnet a tx carrying one that only one node vouched for isn't
361
+ * signed (`UnprovenNameError`), checked against the very status the tx is signed for, as the
362
+ * helpers do (audit gap-7-1). Fields the chain resolves itself take `Client.recipient(x).signed`.
363
+ */
364
+ build(action: Action | ((height: number) => Action), memo?: string, opts?: BuildOptions): Promise<Tx>;
365
+ /**
366
+ * `build`, refusing on mainnet a tx that carries an address only one node vouched for: `unproven`
367
+ * (the helpers' resolutions of names in fields that need an address) or the account `actAs`
368
+ * found that way (audit gap-7-1). Checked against the very status the tx is signed for.
369
+ */
370
+ private buildChecked;
371
+ /**
372
+ * A tx's `fee`: the base fee at `suggested` for its size (and, for a program transaction, its
373
+ * fuel fee at the suggested rate: `fuelFee`), times the headroom, plus the tip; or `maxFee`
374
+ * outright, which must cover at least that base fee plus the tip.
375
+ */
376
+ private feeFor;
377
+ /**
378
+ * The nonce for this wallet's next tx on chain/account `key`: the node's `next_nonce` (which
379
+ * counts the txs it holds), or one past the last tx this wallet submitted when that's higher
380
+ * and the tx may still run: still pending on its way through the network, or not yet counted
381
+ * by a node writing a block (DEV-3). A tx that was dropped, or can't run any more
382
+ * (`valid_until` passed), gives its nonce back: the node's word is used again. A nonce handed to
383
+ * a tx a node admitted is never handed out again while that tx may run.
384
+ */
385
+ private nonceFor;
386
+ /** Runs `job` after every job queued before it (its outcome doesn't stop the next one). */
387
+ private enqueue;
388
+ /**
389
+ * Builds, signs and submits one tx in this wallet's queue (`enqueue`): one at a time, so each
390
+ * is admitted before the next is signed, in nonce order (DEV-3). Waits for it after leaving the
391
+ * queue, so parallel calls are only serialized for the moment it takes to sign and submit.
392
+ *
393
+ * What a failure does to the next nonce: refused by the node (a 4xx answer: it wasn't admitted),
394
+ * the nonce is used for the next tx, which can't be paid twice since only one tx per nonce ever
395
+ * runs; on "bad nonce" the same signed bytes are tried again once (a node writing a block can
396
+ * misjudge a correct nonce for a moment), then the node's next nonce is used. Anything else
397
+ * (a timeout, a 5xx, a broken connection) may have been admitted, so its nonce isn't reused.
398
+ */
399
+ private submitQueued;
400
+ /**
401
+ * Send FANG to a `.boo` name or an address. `amount` is in FANG ("1.5") or bigint drops. A name
402
+ * is signed as its proven owner's address when the client has witnesses (who you checked is who
403
+ * gets paid, even if the name changes hands before the tx runs), and as the name itself when it
404
+ * doesn't: the chain then pays whoever owns it when the tx runs. A lying node can't point it at
405
+ * another account now, but it can hold the signed tx until its validity window, which counts
406
+ * from the height the node reported, and release it later, by when the name may have lapsed
407
+ * and been registered again (audit gap-7-1, review-r3-clients-2). See `Client.recipient`.
408
+ */
409
+ send(to: string, amount: Amount, opts?: SendOptions): Promise<any>;
410
+ /**
411
+ * `send`, with the batch's retry policy. An amount of 0 is refused before anything is signed
412
+ * (DEV-14): it moves nothing and only pays a fee. A payment that opens an account must carry at
413
+ * least 0.01 FANG and burns `creation_fee` (0.1 FANG) from this account on top; the result of a
414
+ * finalized payment that did says so (`opened_account`, `creation_fee`), since its `summary` and
415
+ * `fee` don't (DEV-7).
416
+ */
417
+ private pay;
418
+ /**
419
+ * Whether a payment to `address` would open its account, and what that burns from the payer
420
+ * (`/api/account`'s `exists` and `creation_fee`; on nodes without them, an account with no
421
+ * balance and no nonce counts as new). `undefined` when the node didn't say.
422
+ */
423
+ private openingCost;
424
+ /**
425
+ * Whether finalized payment `tx` opened `address`'s account (it had none when the payment was
426
+ * signed): no other finalized tx naming it ran before this one. From its newest history, so a
427
+ * flood of more than 25 txs to a brand-new account within seconds can hide an earlier one.
428
+ */
429
+ private opened;
430
+ /**
431
+ * What paying `amount` to `to` would cost this account, before anything is signed (DEV-7):
432
+ * - `fee`: the base fee for this payment's size at what `/api/fees` fixes for the next 17 blocks
433
+ * (`suggested`), plus the tip. On a chain that isn't busy, what it's charged;
434
+ * - `maxFee`: the most it can be charged (`fee`, or more with `feeHeadroom` / `maxFee`);
435
+ * - `creationFee`: burned from this account when the payment opens the recipient's account
436
+ * (0.1 FANG on chains with genesis defaults), on top of `amount`;
437
+ * - `total`: `amount + fee + creationFee`;
438
+ * - `transferableAfter`: what this account could still move afterwards, counting `maxFee`
439
+ * (negative: it can't pay this). Amounts are bigint drops; `display` has them as FANG text.
440
+ * `recipient` is how `to` gets signed (`Client.recipient`): show `recipient.how` before paying.
441
+ * Refuses (throws) a 0 amount, and less than 0.01 FANG to an account that doesn't exist yet.
442
+ */
443
+ quote(to: string, amount: Amount, opts?: {
40
444
  memo?: string;
445
+ } & TxOptions): Promise<Quote>;
446
+ /**
447
+ * Many payments from this account (TR-5), with at most `concurrency` (default 16, at most 64,
448
+ * the chain's limit of pending txs per sender) waiting to finalize at once. They're signed in
449
+ * turn, one nonce after the other. A node that answers 429 (rate limited) or "too many pending
450
+ * transactions" gets the same signed bytes again once it says to retry (`Retry-After`), for up
451
+ * to `patienceMs` (default 2 minutes); resubmitting the same bytes can't pay twice.
452
+ *
453
+ * Every payment gets a result, in order: `{ ok: true, tx }` or `{ ok: false, error }`. A refused
454
+ * payment (the node said no: insufficient balance, a bad name) used no nonce, and the rest go on.
455
+ * A payment that failed for another reason (`TxPendingError`, `TxFailedError` with `dropped`, a
456
+ * timeout) may still run: check it (`client.tx`) before paying it again, and note that when the
457
+ * chain drops a tx it drops every later one from the account too. `onSigned` is called with
458
+ * each signed tx before it's submitted, as with `send`.
459
+ */
460
+ sendMany(payments: PaymentOrder[], opts?: {
461
+ concurrency?: number;
41
462
  wait?: boolean;
42
- }): Promise<any>;
463
+ patienceMs?: number;
464
+ onSigned?: SendOptions["onSigned"];
465
+ } & TxOptions): Promise<PaymentResult[]>;
43
466
  registerName(name: string, opts?: {
44
467
  wait?: boolean;
45
- }): Promise<any>;
46
- /** Authorize another device's key (e.g. a second passkey) with full control. */
47
- addOwnerKey(keyIdHex: string, label: string): Promise<any>;
468
+ } & TxOptions): Promise<any>;
48
469
  /**
49
- * Let an agent/app key spend from this account, transfers only, within a limit.
50
- * Example: `addSessionKey(agentKeyId, "claude", { limit: "10", periodBlocks: 86_400, expiresInBlocks: 30 * 86_400 })`.
470
+ * Authorize another device's key (e.g. a second passkey) with full control. `grant` is the
471
+ * key's consent to this account (`keyGrant` on that device, or its grant code).
51
472
  */
52
- addSessionKey(keyIdHex: string, label: string, opts: {
473
+ addOwnerKey(grant: KeyGrant | string, label: string): Promise<any>;
474
+ /**
475
+ * Let an agent/app key spend from this account, transfers only, within a limit. `grant` is the
476
+ * key's consent to this account (the agent's grant code).
477
+ * Example: `addSessionKey(grantCode, "claude", { limit: "10", periodBlocks: 86_400, expiresInBlocks: 30 * 86_400 })`.
478
+ */
479
+ addSessionKey(grant: KeyGrant | string, label: string, opts: {
53
480
  limit: string | number | bigint;
54
481
  periodBlocks: number;
55
482
  expiresInBlocks: number;
56
483
  }): Promise<any>;
57
484
  removeKey(keyIdHex: string): Promise<any>;
58
485
  /**
59
- * Offer a validator: bonds `bond` FANG from this account. `consensusKeyHex` is the validator
60
- * node's ML-DSA-65 public key (see `blockula validator init`). Pending until an admin approves.
486
+ * Register a validator owned by this account, self-bonding `bond` FANG into its stake pool (at
487
+ * least the chain's `min_self_bond`). `consensusKey` is the validator node's ML-DSA-65 public
488
+ * key and `pop` its proof of possession (see `blockula validator init`). It's a candidate: at
489
+ * each epoch boundary the top `max_validators` pools by stake form the next active set.
61
490
  */
62
491
  registerValidator(opts: {
63
492
  consensusKey: string;
@@ -66,9 +495,9 @@ export declare class Wallet {
66
495
  bond: string | number | bigint;
67
496
  pop: string;
68
497
  }): Promise<any>;
69
- /** Season 0 admins only. */
498
+ /** Dev and test chains with admins only: pin a validator into the set ahead of stake. */
70
499
  approveValidator(validator: string): Promise<any>;
71
- /** Season 0 admins only. */
500
+ /** Dev and test chains with admins only: take a validator out of the set for good. */
72
501
  removeValidator(validator: string): Promise<any>;
73
502
  /** Claim a GitHub handle. Verify it by creating a public gist (as that user) containing this account's address. */
74
503
  linkGithub(handle: string, gistId: string): Promise<any>;
@@ -82,51 +511,1059 @@ export declare class Wallet {
82
511
  expiresInBlocks: number;
83
512
  }): Promise<any>;
84
513
  fundHunt(huntId: number, amount: string | number | bigint): Promise<any>;
85
- /** Pay a hunt's bounty (creator or admin). `to` may be a .boo name; it's resolved and the address is signed. */
514
+ /** Pay a hunt's bounty (creator or admin). `to` may be a .boo name: signed as `Client.recipient` says (the proven address, or the name for the chain to resolve). */
86
515
  awardHunt(huntId: number, to: string, pr: number, familiarKey?: string): Promise<any>;
87
516
  cancelHunt(huntId: number): Promise<any>;
88
517
  /** Mark one of this account's session keys (an agent) as a Familiar. */
89
518
  registerFamiliar(keyIdHex: string, label: string): Promise<any>;
519
+ /** Claim a merged PR (authored by this account's linked GitHub handle) for the contribution pool. Bonded; validators check it on GitHub. */
520
+ submitClaim(repo: string, pr: number, familiarKey?: string): Promise<any>;
521
+ /** Stake 10 FANG on a newcomer being a real, distinct person (needs 10 Soul). */
522
+ vouch(account: string): Promise<any>;
523
+ /** Withdraw your vouch for `account` (after the lock), or pass your own account to decline one. */
524
+ unvouch(account: string): Promise<any>;
525
+ /** Join (or top up) the Séance juror pool. Needs 5 Soul; owner keys only. */
526
+ joinJury(bond?: string | number | bigint): Promise<any>;
527
+ leaveJury(): Promise<any>;
528
+ /**
529
+ * Seal a Séance judgment: one of "a", "b" or "=" per assigned pair (see `client.seance(id)`),
530
+ * plus claim ids you think are spam. Keep the returned `salt`: `revealVotes` needs it.
531
+ *
532
+ * The judgment binds the pairs it was made on (audit gap-7-6): pass `pairs`, the claims (id,
533
+ * repo, PR) you showed the juror in order, or they're read from the client (`seancePairs`). A
534
+ * node that showed other pairs or PRs makes the commitment fail instead of misdirecting it.
535
+ */
536
+ sealVotes(seanceId: number, votes: string, spam?: number[], salt?: string, opts?: {
537
+ pairs?: [SeanceClaimRef, SeanceClaimRef][];
538
+ }): Promise<{
539
+ tx: any;
540
+ salt: string;
541
+ votes: string;
542
+ spam: number[];
543
+ }>;
544
+ revealVotes(seanceId: number, votes: string, spam: number[], salt: string): Promise<any>;
545
+ fundPool(amount: string | number | bigint): Promise<any>;
546
+ /** Withdraw every contribution reward that has vested so far. */
547
+ withdrawVested(): Promise<any>;
548
+ /** Admins of dev and test chains only (elsewhere: a governance proposal). Weight 1–100; 0 removes the repo. */
549
+ setRepo(repo: string, weight: number): Promise<any>;
550
+ /** Admins of dev and test chains only (elsewhere: a governance proposal). `soul` in Soul ("2.5"), up to 100 per grant. */
551
+ grantSoul(to: string, soul: string | number, reason: string): Promise<any>;
552
+ /** Admins of dev and test chains only (elsewhere: a governance proposal). */
553
+ rejectClaim(claimId: number, reason: string): Promise<any>;
554
+ /** Admins of dev and test chains only (elsewhere: a governance proposal). */
555
+ flagSybil(account: string, reason: string): Promise<any>;
556
+ /** Admins of dev and test chains only (elsewhere: a governance proposal). */
557
+ clawback(account: string, reason: string): Promise<any>;
90
558
  /** Reclaim the bond of a removed validator this account owns. */
91
559
  unbond(validator: string): Promise<any>;
560
+ /** Submits one action (the shared tail of the helpers below); `unproven`: see `buildChecked`. */
561
+ private act;
562
+ /**
563
+ * A validator by address, or by a `.boo` name its account holds. Staking needs the address, so
564
+ * a name is resolved (proven with the client's witnesses); on mainnet a tx with an unproven one
565
+ * isn't signed (audit gap-7-1): pass the validator's address.
566
+ */
567
+ private validatorAddress;
568
+ /** `r`, unless it's an unproven name on mainnet (`UnprovenNameError`); `buildChecked` checks again against the signing status. */
569
+ private addressNeeded;
570
+ /** Stake `amount` (FANG, or bigint drops) in a validator's pool. Your stake earns its share of issuance and is slashed with the pool. */
571
+ delegate(validator: string, amount: Amount, opts?: TxOptions): Promise<any>;
572
+ /**
573
+ * Start unbonding stake in a validator's pool: `{ amount }` (FANG, or bigint drops), `shares`,
574
+ * or `"all"` (every share you hold there, read from `/api/staking`). An amount is signed as an
575
+ * amount and the chain converts it at the pool's price when the tx runs, so no node's report of
576
+ * the stake decides how much unbonds (audit gap-7-5); prefer it to `sharesFor`. It stops
577
+ * earning now and can be withdrawn with `withdrawUnbonded` once the unbonding period (21 days
578
+ * on mainnet) is over.
579
+ */
580
+ undelegate(validator: string, shares: bigint | string | "all" | {
581
+ amount: Amount;
582
+ }, opts?: TxOptions): Promise<any>;
583
+ /** Move `shares` (or `"all"`) from one pool to another without waiting out the unbonding period. */
584
+ redelegate(fromValidator: string, toValidator: string, shares: bigint | string | "all", opts?: TxOptions): Promise<any>;
585
+ /** Pay out every unbonding entry that has finished unbonding. */
586
+ withdrawUnbonded(opts?: TxOptions): Promise<any>;
587
+ /** A validator's owner: set the pool's commission (basis points, 0–10000; it moves a little per epoch at most) and, optionally, new addresses. */
588
+ updateValidator(opts: {
589
+ commissionBps: number;
590
+ p2pAddr?: string;
591
+ httpAddr?: string;
592
+ } & TxOptions): Promise<any>;
593
+ /** Bring a jailed validator back (its owner, after the jail period). */
594
+ unjail(validator: string, opts?: TxOptions): Promise<any>;
595
+ /** Low-level (nodes do this automatically): two conflicting signed votes, hex-encoded as the node's evidence reporter emits them. */
596
+ reportEquivocation(evidenceHex: string, opts?: TxOptions): Promise<any>;
597
+ /** Low-level (validator nodes do this automatically): commit to a beacon secret for `epoch`. */
598
+ beaconCommit(epoch: number, commitmentHex: string, opts?: TxOptions): Promise<any>;
599
+ /** Low-level (validator nodes do this automatically): reveal the beacon secret committed for `epoch`. */
600
+ beaconReveal(epoch: number, secretHex: string, opts?: TxOptions): Promise<any>;
601
+ /**
602
+ * A member of a set of one or two, signing with its consensus key: admit candidate `validator`
603
+ * into the set at the end of `epoch` (default: the epoch the next block is in; the tx fails in
604
+ * any other). The newcomer will be needed for every quorum, so this is the operator's decision,
605
+ * once an epoch per member; it joins once a quorum of the members admitted it and its node
606
+ * showed up (`validatorReady`).
607
+ */
608
+ admitValidator(validator: string, opts?: {
609
+ epoch?: number;
610
+ } & TxOptions): Promise<any>;
611
+ /** Low-level (candidate nodes do this automatically, in the epoch's last tenth, once a set of one or two admitted them): a candidate's consensus key signals its node is running in `epoch`. */
612
+ validatorReady(epoch: number, opts?: TxOptions): Promise<any>;
613
+ /**
614
+ * Put a proposal to a vote (build `kind` with `proposal.*`). Bonds `deposit` (default: the
615
+ * chain's `proposal_deposit`), refunded once the proposal reaches quorum and burned if it
616
+ * doesn't. Names in the kind (`to`, `account`) are signed as `Client.recipient` says: the proven
617
+ * address with witnesses, else the name, which the chain resolves when the proposal is made
618
+ * (it stores the address, which voters then see and bind).
619
+ *
620
+ * The default deposit is what the node reports, and a node can report anything, so it's
621
+ * bounded (audit gap-7-5): every witness of the client must report the same value, and it may
622
+ * be at most `maxDeposit` (default `DEFAULT_MAX_PROPOSAL_DEPOSIT`, mainnet's 1,000 FANG).
623
+ * Pass `deposit` to bond an amount you checked yourself.
624
+ */
625
+ propose(kind: ProposalKind, opts: {
626
+ title: string;
627
+ url?: string;
628
+ deposit?: Amount;
629
+ maxDeposit?: Amount;
630
+ } & TxOptions): Promise<any>;
631
+ /**
632
+ * Vote on a proposal with `amount` of your unlocked holdings (liquid, staked or unbonding;
633
+ * unvested tokens can't vote). `conviction` 0–6 locks `amount` for 0, 1, 2, 4, 8, 16 or 32 lock
634
+ * periods after the vote ends, for 0.1×, 1×, 2× … 6× the weight (see `convictionWeight`).
635
+ * Voting again replaces your vote. A validator's consensus key or owner voting before the
636
+ * bootstrap council ends also casts that validator's council vote.
637
+ *
638
+ * The vote binds the proposal's content (audit gap-7-6): pass `proposal`, the kind, title and
639
+ * link you showed the voter (e.g. the `client.proposal(id)` object you rendered, described with
640
+ * `describeKind`), or it's read from the client. A node that showed another proposal's content
641
+ * makes the vote fail. If you showed it earlier and only kept its digest
642
+ * (`proposalSummary(raw).digest`), pass `digest`: a proposal that reads differently now is
643
+ * refused before anything is signed.
644
+ */
645
+ vote(proposalId: number, aye: boolean, amount: Amount, conviction?: number, opts?: TxOptions & {
646
+ proposal?: {
647
+ kind: ProposalKind;
648
+ title: string;
649
+ url?: string;
650
+ };
651
+ digest?: string;
652
+ }): Promise<any>;
653
+ /** Release every vote lock that has expired. */
654
+ unlock(opts?: TxOptions): Promise<any>;
655
+ /**
656
+ * Make this account an M-of-N multisig of its owner keys (`ownerKeyIds`): owner-only actions
657
+ * then need `multisigPropose` plus approvals up to `threshold`. Session keys keep working
658
+ * within their limits.
659
+ */
660
+ multisigCreate(ownerKeyIds: string[], threshold: number, opts?: TxOptions): Promise<any>;
661
+ /** Propose an action for this multisig account; it runs once enough owners approve. */
662
+ multisigPropose(action: Action, opts?: TxOptions): Promise<any>;
663
+ /**
664
+ * Approve open multisig proposal `id`. The approval binds the action (audit gap-7-6): pass
665
+ * `action`, the one you showed the approver (decode it and describe it with `describeAction`,
666
+ * don't trust a summary), or it's read from `client.multisig(account)`. A node that showed
667
+ * another action makes the approval fail. `digest`: the `actionDigest` of what you showed, if
668
+ * that's all you kept; an action that reads differently now is refused before anything is signed.
669
+ * A `vote` binds its proposal by digest, not by id: show it with `reviewAction(action, {
670
+ * proposal: await client.proposal(action.proposal_id) })`, which describes the proposal only if
671
+ * its content has that digest, and don't offer the approval unless it's `readable` (gap-7-6).
672
+ * Pass that proposal read as `proposal` here: approving a vote is refused, before anything is
673
+ * signed, unless the proposal shown (else one read now) has exactly the content the vote binds.
674
+ * The approval counts on this wallet's account (`actAs`), which the digest doesn't bind: on
675
+ * mainnet act for an address you checked, not a name one node resolved.
676
+ */
677
+ multisigApprove(id: number, opts?: TxOptions & {
678
+ action?: Action;
679
+ digest?: string;
680
+ proposal?: unknown;
681
+ }): Promise<any>;
682
+ /** Extend a name you own by `years` (1–10), at the chain's renewal price per year. */
683
+ renewName(name: string, years?: number, opts?: TxOptions): Promise<any>;
684
+ /**
685
+ * Offer a name you own to another account (a `.boo` name or address, signed as `Client.recipient` says). It
686
+ * stays yours until they accept it (`acceptName`); offering it again replaces the offer, and
687
+ * `withdrawNameOffer` withdraws it. Nobody can be given a name without saying yes.
688
+ */
689
+ transferName(name: string, to: string, opts?: TxOptions): Promise<any>;
690
+ /** Accept a name offered to the account you act for (`client.name(n).offered_to`): it becomes yours. */
691
+ acceptName(name: string, opts?: TxOptions): Promise<any>;
692
+ /** Withdraw your offer of a name you own (the same tx as `acceptName`: the chain tells them apart by who owns the name). */
693
+ withdrawNameOffer(name: string, opts?: TxOptions): Promise<any>;
694
+ /** Give up a name you own; anyone can register it afterwards. */
695
+ releaseName(name: string, opts?: TxOptions): Promise<any>;
696
+ /** Claim your share of a community distribution with the Merkle proof published alongside it (hex hashes). */
697
+ claimDistribution(distributionId: number, amount: Amount, proof: string[], opts?: TxOptions): Promise<any>;
698
+ /** Low-level (validator nodes do this automatically): a matured claim's PR was reverted by commit `revertSha`. */
699
+ attestRevert(claimId: number, revertSha: string, opts?: TxOptions): Promise<any>;
700
+ /** The chain's fuel prices, with programs required to be on (`ProgramsOffError`) and to admit this kind of transaction now. */
701
+ private programsFor;
702
+ /** Waits (up to `waitMs`) for the node's head to pass `height`: what block `height` stored is usable from the next one (§2.1). */
703
+ private waitPast;
704
+ /**
705
+ * Runs what follows a transaction that was submitted and is final, saying so if it fails: `what` names
706
+ * the transaction (its id, and what it made), which was sent and ran, so the failure is of the receipt,
707
+ * the wait or the read after it, and the transaction must not be sent again. The typed error stays
708
+ * as `cause`; its reason is quoted stripped of hidden characters (it may hold a node's text). `what` may be a function
709
+ * so the name can grow as `run` learns more (the address a create made).
710
+ */
711
+ private finalThen;
712
+ /**
713
+ * Waits (up to `waitMs`) until `read` finds what it names (`null`: not there yet) stored in a block
714
+ * before the node's head, which is when it's usable (§2.1: a create, or a call, signed earlier is
715
+ * refused by the mempool). Says what was waited for if it never is.
716
+ */
717
+ private waitUsable;
718
+ /** A program as a call needs it: usable (stored in an earlier block), its digest recomputed from its own record, and proven against the client's witnesses when it has some. */
719
+ private programForCall;
720
+ /**
721
+ * The bindings of a transaction (`ProgramBindingInput`s): each program read (usable, checked, proven
722
+ * with witnesses), its version digest filled with the version in force now when none is given (never
723
+ * "any version", 64 zeros, unless asked: `ANY_PROGRAM_VERSION`), and its code added to `declared`,
724
+ * which load fuel is counted on.
725
+ */
726
+ private resolveBindings;
727
+ /**
728
+ * Signs and submits a program transaction (reserving `reservation` fuel: its fee is priced with it),
729
+ * waits for it, checks its receipt (programs.ts `checkReceipt`) and returns it with what it cost.
730
+ * One that ran and failed throws `ProgramFailedError` (its fee was charged; `storageLimit` names
731
+ * the limit it signed, for the hint a `storage_limit` trap needs).
732
+ *
733
+ * Once the transaction is submitted and the node reports it final, **every failure says so**
734
+ * (`finalThen`): a receipt or answer that doesn't check isn't "nothing happened, ask another node",
735
+ * since the transaction ran, and a payable call sent again pays twice. The typed error is the `cause`.
736
+ */
737
+ private sendProgram;
738
+ /**
739
+ * Uploads a program's code (WebAssembly 1.0) and its interface (format 1: `blockula program interface
740
+ * encode`, or the `.iface` files beside the guests), bonding a storage deposit for each that isn't
741
+ * stored yet: the deposit at today's price (`programUploadDeposit`), which v0 never gives back. `storageLimit`
742
+ * (FANG, default that deposit plus 10%) is the most the upload may bond; below the deposit it's
743
+ * refused before signing, as the upload would fail and still be charged. Fuel is priced at the
744
+ * node's suggested rate. Resolves once the upload is final **and the block after it has been sealed**,
745
+ * when the code is usable (a create signed sooner is refused, §2.1), with its receipt and what it
746
+ * cost: the fee, and the deposit, which `receipt.facts.outside_vm` holds apart from the VM's diff.
747
+ */
748
+ uploadCode(wasm: Uint8Array | string, iface: Uint8Array | string, opts?: ProgramTxOptions & {
749
+ storageLimit?: Amount;
750
+ }): Promise<UploadedCode>;
751
+ /**
752
+ * Creates a program from stored code and interface (`uploadCode`'s hashes), at the address made from
753
+ * this account and the transaction's nonce, which is returned **only once the create has applied**
754
+ * and the block after it has been sealed (the program is then usable), never predicted ahead of it:
755
+ * FANG sent to a program's address before its create is final is stranded for good if the create
756
+ * fails (§2.3). It first waits for the code and interface to be usable (an upload a block ago).
757
+ *
758
+ * `init` runs the interface's `Init` method with its `input` and `value`, present exactly when the
759
+ * interface declares one; it runs under `fuelLimit` (default `program_max_tx_fuel`, 0 without `init`).
760
+ * `storageLimit` (FANG) is the most the record's deposit and what the initializer's writes bond may
761
+ * be: default the record's deposit plus 10%, which a program whose initializer writes needs more than.
762
+ * `authority` (an address, never a name) may upgrade it once a protocol version adds upgrades, with
763
+ * `delayBlocks` of notice (default and least: `program_min_upgrade_delay_blocks`) and an upgrade
764
+ * `policy`; without one the program is immutable. `bindings` are programs the initializer may reach.
765
+ * The receipt's `outside_vm` holds the record deposit and the account creation fee the create burns
766
+ * when the program's address held no account yet.
767
+ */
768
+ createProgram(opts: CreateProgramOptions): Promise<CreatedProgram>;
769
+ /**
770
+ * Calls programs: 1 to 8 calls run in order, all or nothing, sharing `fuelLimit` (default
771
+ * `program_max_tx_fuel`) and `storageLimit` (FANG): **the default is 0, which consents to no new
772
+ * storage**, so a call whose writes bond a deposit traps `storage_limit` and still pays its fee
773
+ * (`ProgramFailedError` says so): pass a limit for any method that writes.
774
+ *
775
+ * Each call binds the `versionDigest` of the program it's calling: when you pass the digest you
776
+ * showed the user (`ProgramCallInput.versionDigest`) the call is refused if the program's code,
777
+ * interface or version isn't the one that digest names; without it, it's recomputed from the
778
+ * program's record (proven against the client's witnesses when it has any), never taken from the
779
+ * node's `version_digest`. Fuel is priced at the node's suggested rate on what's reserved (fuel to
780
+ * run, plus the load of the code the calls and `bindings` declare) and refused when no block
781
+ * could carry it (`FuelReservationError`). Waits for each program to be usable (created a block ago).
782
+ * The receipt's `claims` are what the programs say happened: the chain checks none of it.
783
+ */
784
+ callProgram(calls: ProgramCallInput[], opts?: ProgramCallOptions): Promise<ProgramTxResult>;
785
+ /**
786
+ * One call: `program`'s `method` (a `call` method of its interface; read a `view` with
787
+ * `client.view`) with `input` (bytes, or lowercase hex) and `value` FANG attached (only to a
788
+ * payable method). It reads the program first, so a method its interface doesn't have, a view,
789
+ * an initializer, or FANG sent to a method that isn't payable is refused before anything is signed
790
+ * (the chain refuses them too, and charges the fee), and signs its `version_digest`: see `callProgram`,
791
+ * whose options it takes, including the 0 default of `storageLimit`.
792
+ */
793
+ call(program: string, method: string, input?: Uint8Array | string, opts?: ProgramCallOptions & {
794
+ value?: Amount;
795
+ versionDigest?: string;
796
+ }): Promise<ProgramTxResult>;
797
+ /**
798
+ * For a validator: signs a vote to pause programs (tag 69), from the validator's own account with
799
+ * its key (build the wallet from `validator.key`'s seed and `actAs` nothing: it signs as itself).
800
+ * Programs pause from the block after f + 1 of the epoch's validators have signed, for days, with
801
+ * no undo, so check `client.params()`' `programs` section (the live `votes`, `pause_signed` and
802
+ * `fix_pending`) first, or use `blockula program pause`, which does.
803
+ *
804
+ * It signs and lets the chain's admission decide: a signature the chain refuses (this validator
805
+ * signed one recently, or has a live vote of its own, or isn't in the active set) is an `ApiError`
806
+ * 400 and is never charged. It reserves no fuel and prices none, so its fee is a plain
807
+ * transaction's; it only needs programs to have been switched on (`/api/fees` has a `fuel` section:
808
+ * `ProgramsOffError` otherwise), not any fuel schedule this SDK knows, since a pause must not depend on one.
809
+ */
810
+ programsPause(opts?: TxOptions & {
811
+ onSigned?: SendOptions["onSigned"];
812
+ }): Promise<any>;
813
+ /** This account's shares in a validator's pool, for `"all"`; anything else is parsed and checked. */
814
+ private sharesOf;
815
+ /** A proposal kind with its accounts as `Client.recipient` signs them (the chain resolves names when the proposal is made). */
816
+ private resolveKind;
817
+ /**
818
+ * Everything this account holds, as FANG text ("12.5 FANG"), locked or not: `balances()` says
819
+ * what it can pay. "0 FANG" only for an account that doesn't exist yet; anything else that goes
820
+ * wrong (the node is down or rate limited, a timeout, another chain) throws (DEV-2), so a
821
+ * failure never reads as an empty account.
822
+ */
92
823
  balance(): Promise<string>;
824
+ /**
825
+ * This account's balances, in bigint drops (DEV-2):
826
+ * - `balance`: everything it holds;
827
+ * - `transferable`: what it can pay or send now, fees and tips included: the "can pay" number;
828
+ * - `locked`: what vesting and vote locks hold (their `until` is in `client.account(…).locks`).
829
+ * Staked FANG isn't in `balance` (see `client.staking`). `exists` is false for an account the
830
+ * chain hasn't opened yet (all zeros). Errors propagate, like `balance()`.
831
+ */
832
+ balances(): Promise<Balances>;
93
833
  /** Dev/test chains only: drip 100 FANG to this wallet. */
94
834
  faucet(wait?: boolean): Promise<any>;
95
835
  }
96
- /** An error response from a Blockula node. `status` is the HTTP status (429 = rate limited). */
836
+ /**
837
+ * An error response from a Blockula node. `status` is the HTTP status (429 = rate limited);
838
+ * `retryAfterMs`, when the node said how long to wait (`Retry-After`, or "try again in N minutes").
839
+ */
97
840
  export declare class ApiError extends Error {
98
841
  readonly status: number;
99
- constructor(status: number, message: string);
842
+ readonly retryAfterMs?: number | undefined;
843
+ constructor(status: number, message: string, retryAfterMs?: number | undefined);
844
+ }
845
+ /**
846
+ * The node says it's on blockula-1, and this client isn't pinned to that chain (DEV-1). Nothing
847
+ * was signed. A client signs there only with a `chainId: "blockula-1"` pin.
848
+ */
849
+ export declare class MainnetNotAllowedError extends Error {
850
+ readonly rpc: string;
851
+ constructor(rpc: string);
852
+ }
853
+ /** The most txs a node holds pending from one sender (node/src/chain.rs `MAX_PENDING_PER_SENDER`). */
854
+ export declare const MAX_PENDING_PER_SENDER = 64;
855
+ /** `Wallet.balances()`: an account's balances in bigint drops, and as FANG text. */
856
+ export interface Balances {
857
+ /** Everything the account holds (staked FANG isn't in it). */
858
+ balance: bigint;
859
+ /** What it can pay or send now, fees included: the "can pay" number. */
860
+ transferable: bigint;
861
+ /** What vesting and vote locks hold. */
862
+ locked: bigint;
863
+ /** Whether the chain has opened this account yet. */
864
+ exists: boolean;
865
+ display: {
866
+ balance: string;
867
+ transferable: string;
868
+ locked: string;
869
+ };
100
870
  }
101
- /** A transaction that was rejected at execution (fee charged) or dropped from the mempool. */
871
+ /** `Wallet.quote()`: what a payment would cost, in bigint drops (see `quote`). */
872
+ export interface Quote {
873
+ amount: bigint;
874
+ /** The base fee at `suggested` for its size, plus the tip. */
875
+ fee: bigint;
876
+ /** The most it can be charged (its `fee` field). */
877
+ maxFee: bigint;
878
+ /** Burned from the payer when the payment opens the recipient's account; 0 otherwise. */
879
+ creationFee: bigint;
880
+ /** amount + fee + creationFee. */
881
+ total: bigint;
882
+ /** What the payer could still move afterwards, counting `maxFee`; negative when it can't pay. */
883
+ transferableAfter: bigint;
884
+ enough: boolean;
885
+ /** The recipient has no account yet: this payment opens it. */
886
+ opensAccount: boolean;
887
+ /** How the recipient gets signed: show `how` before paying. */
888
+ recipient: Recipient;
889
+ display: {
890
+ amount: string;
891
+ fee: string;
892
+ maxFee: string;
893
+ creationFee: string;
894
+ total: string;
895
+ transferableAfter: string;
896
+ };
897
+ }
898
+ /** One payment for `Wallet.sendMany`. */
899
+ export type PaymentOrder = {
900
+ to: string;
901
+ amount: Amount;
902
+ memo?: string;
903
+ } & Omit<TxOptions, "maxFee">;
904
+ /** What happened to one payment of `Wallet.sendMany`. */
905
+ export type PaymentResult = {
906
+ ok: true;
907
+ to: string;
908
+ amount: Amount;
909
+ tx: any;
910
+ } | {
911
+ ok: false;
912
+ to: string;
913
+ amount: Amount;
914
+ error: unknown;
915
+ };
916
+ /**
917
+ * The node reports a transaction as failed. Two different things (audit review-fix-clients-2):
918
+ * - `dropped` false: it executed in block `tx.height` and failed there. Its fee was charged; it
919
+ * can't execute again.
920
+ * - `dropped` true: this node dropped it from its mempool without running it (evicted by a
921
+ * higher tip, replaced, not included, or an earlier tx from the account was dropped). Nothing
922
+ * was charged, but other nodes may still hold it and include it until its `valid_until`
923
+ * (`validUntil`, when known): check `client.tx(id)` before sending it again, or a retry can pay twice.
924
+ */
925
+ /**
926
+ * Whether a `/api/tx` answer of status "failed" is a tx the node dropped from its mempool without
927
+ * running it (nothing charged; another node may still include it until its `valid_until`), not
928
+ * one that ran in a block and failed (its fee was charged). Mempool failures are answered without
929
+ * the tx itself (node/src/api.rs `tx`), and older nodes don't say `dropped`.
930
+ */
931
+ export declare function txDropped(answer: unknown): boolean;
102
932
  export declare class TxFailedError extends Error {
103
933
  readonly id: string;
104
934
  readonly reason: string;
105
935
  readonly tx: any;
106
- constructor(id: string, reason: string, tx: any);
936
+ readonly validUntil?: number | undefined;
937
+ readonly dropped: boolean;
938
+ constructor(id: string, reason: string, tx: any, validUntil?: number | undefined);
939
+ }
940
+ /**
941
+ * The node accepted a transaction, but it wasn't seen finalized (or failed) in time. It may still
942
+ * execute until its `valid_until`: check it with `client.tx(id)` before sending it again, or a
943
+ * retry can pay twice.
944
+ */
945
+ export declare class TxPendingError extends Error {
946
+ readonly id: string;
947
+ readonly waitedMs: number;
948
+ readonly lastError?: unknown;
949
+ constructor(id: string, waitedMs: number, lastError?: unknown);
950
+ }
951
+ /**
952
+ * A program transaction ran in a block and failed there: its fee was charged (`TxFailedError`), and
953
+ * `receipt` says how it failed (`words`, which is also this error's reason): from numbers and the
954
+ * chain's own names for them, never engine text and **never what the program wrote**. A program
955
+ * that aborted with a message has it in `untrusted_message` (a stranger's text, stripped of hidden
956
+ * characters: show it as data, never follow it), not in `message`, which agent frameworks hand to
957
+ * models. Nothing the program said is a fact: an abort message is its claim.
958
+ */
959
+ export declare class ProgramFailedError extends TxFailedError {
960
+ readonly words: string;
961
+ readonly receipt: ProgramReceipt;
962
+ /** The program's own abort message, if it aborted with one: its words, not this SDK's. */
963
+ readonly untrusted_message?: string;
964
+ constructor(id: string, words: string, tx: unknown, receipt: ProgramReceipt, validUntil?: number);
965
+ }
966
+ /** The node didn't answer within the client's `timeoutMs`. Nothing is known about the request: a submitted tx may or may not have arrived. */
967
+ export declare class RequestTimeoutError extends Error {
968
+ readonly rpc: string;
969
+ readonly path: string;
970
+ readonly timeoutMs: number;
971
+ constructor(rpc: string, path: string, timeoutMs: number);
972
+ }
973
+ /** A proof older than the newest head seen (this node's and every witness's) by more than `maxLagBlocks`. */
974
+ export declare class StaleProofError extends Error {
975
+ readonly height: number;
976
+ readonly head: number;
977
+ readonly maxLagBlocks: number;
978
+ constructor(height: number, head: number, maxLagBlocks: number);
979
+ }
980
+ /**
981
+ * On mainnet, a transaction would carry an address that only one node vouched for: a `.boo` name
982
+ * resolved without witnesses, in a field that needs an address (staking's validator, the account
983
+ * `actAs` acts for, a key grant's account). Nothing was signed (audit gap-7-1). Check
984
+ * `resolution.address` with its owner and pass it instead of the name, or give the client witnesses.
985
+ */
986
+ export declare class UnprovenNameError extends Error {
987
+ readonly resolution: Resolution;
988
+ constructor(resolution: Resolution, rpc: string);
989
+ }
990
+ /**
991
+ * A node reports a height the chain can't have reached (`Client.checkSigningHeight`): a tx signed
992
+ * against it could be held and released later. Nothing was signed.
993
+ */
994
+ export declare class HeightAheadError extends Error {
995
+ readonly rpc: string;
996
+ readonly height: number;
997
+ readonly limit: number;
998
+ constructor(rpc: string, height: number, limit: number, by: string);
999
+ }
1000
+ /**
1001
+ * How far ahead of the lowest head a client's witnesses report a tx's height may be, by default
1002
+ * (`ClientOptions.maxHeadLeadBlocks`): 30 blocks, room for propagation between nodes.
1003
+ */
1004
+ export declare const DEFAULT_MAX_HEAD_LEAD_BLOCKS = 30;
1005
+ /**
1006
+ * How far behind the network's clocks this machine's may be before `heightLimit` refuses an honest
1007
+ * node: 15 minutes (the CLI uses the same, node/src/cli_net.rs `HEIGHT_CLOCK_TOLERANCE_MS`).
1008
+ */
1009
+ export declare const HEIGHT_CLOCK_TOLERANCE_MS: number;
1010
+ /**
1011
+ * The highest height a chain can have reached at `nowMs` (node/src/cli_net.rs `height_limit`):
1012
+ * every block's timestamp is at least its parent's plus the block time, and validators refuse one
1013
+ * more than a second ahead of their clocks, so block h is stamped no earlier than genesis + h ×
1014
+ * block time. A chain that ran slower than its block time is below this by that much, so it
1015
+ * refuses only heights the chain can't have, not every lie.
1016
+ */
1017
+ export declare function heightLimit(createdAtMs: number, blockTimeMs: number, nowMs: number): number;
1018
+ /** The node reports a different chain than the client is pinned to (`ClientOptions`). */
1019
+ export declare class ChainMismatchError extends Error {
1020
+ readonly rpc: string;
1021
+ readonly field: "chain_id" | "genesis_hash" | "address_prefix";
1022
+ readonly expected: string;
1023
+ readonly reported: string | undefined;
1024
+ constructor(rpc: string, field: "chain_id" | "genesis_hash" | "address_prefix", expected: string, reported: string | undefined);
1025
+ }
1026
+ /** What a `Client` requires of the node. Every `/api/status` (including the one `Wallet.build` signs against) is checked. */
1027
+ export interface ClientOptions {
1028
+ /**
1029
+ * A network this SDK knows (`NETWORKS`): its public RPC (when no URL is given) and every pin it
1030
+ * has (chain id, genesis hash, address prefix, genesis clock), set up front. Pins you pass too
1031
+ * must agree with it.
1032
+ */
1033
+ network?: NetworkName;
1034
+ /**
1035
+ * Submit txs in their wire form (`txBytes`, `application/octet-stream`): about half the bytes
1036
+ * of JSON. Off by default: the JSON form is refused outright when it has a field the node doesn't
1037
+ * know (422), where the wire form leaves such a field out.
1038
+ */
1039
+ wireTxs?: boolean;
1040
+ /** The address prefix you expect (`boo` or `tboo`). */
1041
+ prefix?: string;
1042
+ /**
1043
+ * The chain id the node must report (e.g. `blockula-testnet-2`). Wallets sign on `blockula-1`
1044
+ * only through a client pinned to it (`MainnetNotAllowedError`).
1045
+ */
1046
+ chainId?: string;
1047
+ /** The genesis hash (hex) the node must report. */
1048
+ genesisHash?: string;
1049
+ /** How long one request may take before it fails with `RequestTimeoutError` (default 15 s, at most `MAX_TIMEOUT_MS`). */
1050
+ timeoutMs?: number;
1051
+ /**
1052
+ * Clients for independent nodes of the same chain. With witnesses, every name this client
1053
+ * resolves for a signature is a proven read (`provenName`): the record's Merkle proof must check
1054
+ * out against a state root each witness reports for that block, and be fresh. Without them
1055
+ * (audit gap-7-1):
1056
+ * - where the chain resolves names itself (`Wallet.send`, `awardHunt`, `vouch`/`unvouch`,
1057
+ * `grantSoul`, `flagSybil`, `clawback`, `transferName`, proposal targets), the name is signed
1058
+ * as the name (`recipient`): the chain pays whoever owns it when the tx runs, so a lying node
1059
+ * can't point it at another account now, only hold it within its validity window;
1060
+ * - where an address is needed (`delegate`/`undelegate`/`redelegate`/`unjail`, `actAs`,
1061
+ * `keyGrant`), a name is one node's unproven answer, and on mainnet nothing is signed with it
1062
+ * (`UnprovenNameError`): pass the address.
1063
+ */
1064
+ witnesses?: Client[];
1065
+ /** Refuse to resolve a `.boo` name for a signature unless it's proven (needs `witnesses`). */
1066
+ requireProvenNames?: boolean;
1067
+ /**
1068
+ * With witnesses: how far ahead of the lowest head they report the height a tx is signed
1069
+ * against may be (default `DEFAULT_MAX_HEAD_LEAD_BLOCKS`). See `Client.checkSigningHeight`.
1070
+ */
1071
+ maxHeadLeadBlocks?: number;
1072
+ /**
1073
+ * The chain's genesis time and block time (`created_at_ms` and `block_time_ms` of the
1074
+ * genesis.json that hashes to `genesisHash`, as published with it), as pins: with them, a
1075
+ * status claiming a height the chain can't have reached by this machine's clock is refused
1076
+ * before anything is signed (`Client.checkSigningHeight`). Not the node's word, so don't take
1077
+ * them from it.
1078
+ */
1079
+ genesisClock?: {
1080
+ createdAtMs: number;
1081
+ blockTimeMs: number;
1082
+ };
1083
+ }
1084
+ /** Where a recipient (a `.boo` name or an address) goes, and how sure that is (`Client.resolution`). */
1085
+ export interface Resolution {
1086
+ /** What was asked for. */
1087
+ input: string;
1088
+ /** The address that gets signed. */
1089
+ address: string;
1090
+ /** The bare name, when `input` was one. */
1091
+ name: string | null;
1092
+ /** An address as given, or a name proven against the client's witnesses; `false`: one node's word. */
1093
+ proven: boolean;
1094
+ /** How it was resolved, in plain English (show it with the address before signing). */
1095
+ how: string;
1096
+ /** The block a proven name was read at. */
1097
+ height?: number;
1098
+ }
1099
+ /** A recipient in a field the chain resolves itself, as it gets signed (`Client.recipient`). */
1100
+ export interface Recipient extends Resolution {
1101
+ /**
1102
+ * What goes into the action: an address as given, a name's proven owner (with witnesses), or
1103
+ * the name itself (`alice.boo`) when nothing proved it.
1104
+ */
1105
+ signed: string;
1106
+ /**
1107
+ * `signed` is the name: the chain resolves it to whoever owns it when the tx runs, so no node
1108
+ * can point it at another account now (one holding the signed tx can still release it later,
1109
+ * by when the name may have changed hands: see `recipient`). `address` is then just the node's
1110
+ * current answer, for display.
1111
+ */
1112
+ byChain: boolean;
1113
+ }
1114
+ /** Default per-request timeout of a `Client`. */
1115
+ export declare const DEFAULT_TIMEOUT_MS = 15000;
1116
+ /**
1117
+ * The longest timeout a `Client` takes: 2^31 − 1 ms (about 24.8 days). Timers store their delay
1118
+ * as a signed 32-bit number, and a longer one fires at once (audit review-fix-clients-1).
1119
+ */
1120
+ export declare const MAX_TIMEOUT_MS = 2147483647;
1121
+ /** `ms` as a timeout: a whole number of milliseconds from 1 to `MAX_TIMEOUT_MS`, or an error naming `what`. */
1122
+ export declare function checkTimeoutMs(ms: number, what?: string): number;
1123
+ /**
1124
+ * How far behind the newest head (the node's own and each witness's `/api/status` height) a
1125
+ * proven read's proof may be, by default: 10 blocks (10 s at 1 s blocks), room for propagation
1126
+ * between nodes. Older proofs are refused (`StaleProofError`), so a node can't answer with a
1127
+ * genuine but outdated record (a name's previous owner, a balance before a spend, a removed key).
1128
+ */
1129
+ export declare const DEFAULT_MAX_PROOF_LAG_BLOCKS = 10;
1130
+ /** Options of the proven reads (`provenRecord`, `provenAccount`, `provenName`). */
1131
+ export interface ProvenOptions {
1132
+ /** Clients for independent nodes: each must report the same state root for the proof's block, and its head bounds how old the proof may be. */
1133
+ witnesses?: Client[];
1134
+ /** How long to wait for a witness that hasn't reached the proof's block yet (default 5 s). */
1135
+ waitMs?: number;
1136
+ /** How many blocks the proof may be behind the newest head seen (default `DEFAULT_MAX_PROOF_LAG_BLOCKS`). */
1137
+ maxLagBlocks?: number;
1138
+ }
1139
+ /** Options of a program transaction (`Wallet.uploadCode`, `createProgram`, `callProgram`, `call`): a tx's, and how long to wait. */
1140
+ export interface ProgramTxOptions extends TxOptions {
1141
+ /** Called with the signed tx and its id before it's submitted (as `SendOptions.onSigned`): store them, and every outcome is recoverable. */
1142
+ onSigned?: SendOptions["onSigned"];
1143
+ /** How long to wait (ms) for what the transaction needs to be usable, and for the block after its own (default 60 s). */
1144
+ waitMs?: number;
1145
+ }
1146
+ /** What `callProgram` and `call` take beyond a tx's options. */
1147
+ export interface ProgramCallOptions extends ProgramTxOptions {
1148
+ /** Fuel to run the calls, at most `program_max_tx_fuel` (default that). Reserved fuel is paid for and never refunded. */
1149
+ fuelLimit?: number;
1150
+ /** The most the calls' storage deposits may bond (FANG). Default 0: no new storage; a method that writes needs a limit. */
1151
+ storageLimit?: Amount;
1152
+ /** Programs the calls may reach besides their own. */
1153
+ bindings?: ProgramBindingInput[];
1154
+ }
1155
+ /** A program the transaction may reach: by address, at the version digest given, or the version in force now when none is (`ANY_PROGRAM_VERSION` for any). */
1156
+ export interface ProgramBindingInput {
1157
+ program: string;
1158
+ versionDigest?: string;
1159
+ }
1160
+ /** One call of `callProgram`. */
1161
+ export interface ProgramCallInput {
1162
+ /** The program's address, never a name. */
1163
+ program: string;
1164
+ /** A `call` method of its interface. */
1165
+ method: string;
1166
+ /** What the method reads: bytes, or lowercase hex. Default none. */
1167
+ input?: Uint8Array | string;
1168
+ /** FANG sent with the call (only to a payable method). */
1169
+ value?: Amount;
1170
+ /** The version digest the user was shown for this program: the call is refused if the program isn't the one it names. */
1171
+ versionDigest?: string;
1172
+ }
1173
+ /** What a finalized program transaction gave: the node's answer, its checked receipt, and what it cost its signer. */
1174
+ export interface ProgramTxResult {
1175
+ tx: any;
1176
+ receipt: ProgramReceipt;
1177
+ cost: ProgramCost;
1178
+ }
1179
+ /** `Wallet.uploadCode`'s result. */
1180
+ export interface UploadedCode extends ProgramTxResult {
1181
+ wasmHash: string;
1182
+ interfaceHash: string;
1183
+ /** What this upload bonded (drops): 0 when both were stored already. */
1184
+ deposit: bigint;
1185
+ }
1186
+ /** What `Wallet.createProgram` takes. */
1187
+ export interface CreateProgramOptions extends ProgramTxOptions {
1188
+ /** The stored code's hash and the stored interface's (`uploadCode` returns them). */
1189
+ wasmHash: string;
1190
+ interfaceHash: string;
1191
+ /** Run the interface's `Init` method as the program is created (present exactly when the interface has one). */
1192
+ init?: {
1193
+ method: string;
1194
+ input?: Uint8Array | string;
1195
+ value?: Amount;
1196
+ };
1197
+ /** Fuel for the initializer, at most `program_max_tx_fuel` (default that). */
1198
+ fuelLimit?: number;
1199
+ /** The most the record's deposit and the initializer's writes may bond (FANG; default the record's deposit plus 10%). */
1200
+ storageLimit?: Amount;
1201
+ bindings?: ProgramBindingInput[];
1202
+ /** An account (an address) that may upgrade the program once upgrades exist; without it the program is immutable. */
1203
+ authority?: string;
1204
+ delayBlocks?: number;
1205
+ policy?: ProgramPolicy;
1206
+ /** The program takes plain transfers to its address. */
1207
+ acceptsTransfers?: boolean;
1208
+ }
1209
+ /** `Wallet.createProgram`'s result: the program's address, only once the create has applied. */
1210
+ export interface CreatedProgram extends ProgramTxResult {
1211
+ address: string;
1212
+ /** The program as the node reads it a block after the create. */
1213
+ program: ProgramInfo;
1214
+ }
1215
+ /** A record proven against a state root, and the newest head height that root was checked against. */
1216
+ export type ProvenRead = ProvenRecord & {
1217
+ head: number;
1218
+ };
1219
+ /** A page of an account's history (`Client.history`), newest first. */
1220
+ export interface HistoryPage {
1221
+ /**
1222
+ * Finalized txs sent by the account or naming it, as `/api/tx` shows them (`to` is
1223
+ * `{ address, name }`). Pending ones are in `client.account(id).recent_txs`.
1224
+ */
1225
+ txs: any[];
1226
+ /** The cursor of the next (older) page, for `before`; `null` at the end. */
1227
+ next: string | null;
1228
+ /** The first block the node holds: nothing older is in its history. */
1229
+ history_from?: number;
1230
+ /**
1231
+ * False on a node without paged history (`/api/account/{id}/txs`): `txs` is then `/api/account`'s
1232
+ * `recent_txs` (its pending txs and the newest 25 finalized ones), and there's no `next`.
1233
+ */
1234
+ paged: boolean;
107
1235
  }
108
1236
  export declare class Client {
1237
+ /** The chain's address prefix: given, learned from `/api/status`, or `boo` until then. */
1238
+ prefix: string;
1239
+ private prefixKnown;
1240
+ private readonly pinnedPrefix?;
1241
+ private readonly pinnedChainId?;
1242
+ private readonly pinnedGenesis?;
1243
+ /** Per-request timeout (ms). */
1244
+ readonly timeoutMs: number;
1245
+ /** Independent nodes names are proven against (`ClientOptions.witnesses`). */
1246
+ readonly witnesses: Client[];
1247
+ readonly requireProvenNames: boolean;
1248
+ /** See `ClientOptions.maxHeadLeadBlocks`. */
1249
+ readonly maxHeadLeadBlocks: number;
1250
+ /** See `ClientOptions.genesisClock`. */
1251
+ readonly genesisClock?: {
1252
+ createdAtMs: number;
1253
+ blockTimeMs: number;
1254
+ };
1255
+ /** The node's URL. */
109
1256
  readonly rpc: string;
110
- constructor(rpc?: string);
1257
+ /** The network this client was made for (`ClientOptions.network`), if any. */
1258
+ readonly network?: NetworkName;
1259
+ /** See `ClientOptions.wireTxs`. */
1260
+ readonly wireTxs: boolean;
1261
+ /** The public testnet (`NETWORKS.testnet`), every pin set: `Client.testnet({ witnesses })`, or pass your own node's URL as `rpc`. */
1262
+ static testnet(opts?: Omit<ClientOptions, "network"> & {
1263
+ rpc?: string;
1264
+ }): Client;
1265
+ /** A `blockula dev` chain on this machine (`NETWORKS.local`). */
1266
+ static local(opts?: Omit<ClientOptions, "network"> & {
1267
+ rpc?: string;
1268
+ }): Client;
1269
+ /**
1270
+ * `new Client(rpc, opts)`, `new Client({ network: "testnet" })` (the network's public RPC), or
1271
+ * `new Client(rpc, { network })` (your own node, held to that network's pins). The pins
1272
+ * (`opts`, and the network's) are checked on every status: a node reporting another prefix,
1273
+ * chain id or genesis hash is refused with `ChainMismatchError`.
1274
+ */
1275
+ constructor(rpc?: string | ClientOptions, options?: ClientOptions);
1276
+ /**
1277
+ * Refuses (`HeightAheadError`, before anything is signed) a height a tx's validity window would
1278
+ * count from that this client has reason to think the chain hasn't reached: more than
1279
+ * `maxHeadLeadBlocks` past the lowest head its witnesses report, or, with a `genesisClock`, past
1280
+ * what the chain can have reached by this machine's clock (`heightLimit`). A node reporting a
1281
+ * future height gets a tx it can hold and release later, when the window it picked opens; with
1282
+ * a name signed in it, after the name may have changed hands (audit review-r3-clients-2).
1283
+ * Every witness must report its height, as every witness must confirm a proof: one honest
1284
+ * witness is enough to refuse a height the chain hasn't reached, whatever the others say.
1285
+ * Without witnesses or a genesis clock, the height is the node's word.
1286
+ */
1287
+ checkSigningHeight(height: number): Promise<void>;
1288
+ /**
1289
+ * Refuses (`HeightAheadError`) a height the chain can't have reached by this machine's clock and
1290
+ * the `genesisClock` this client was given: the clock half of `checkSigningHeight`, for heights a
1291
+ * node reports that aren't signed against (a read's, a wait's). Without a `genesisClock` the
1292
+ * height is the node's word.
1293
+ */
1294
+ checkHeightClock(height: number): void;
1295
+ /** The chain's address prefix, asking the node once if it isn't known yet. */
1296
+ addressPrefix(): Promise<string>;
1297
+ /**
1298
+ * Throws `MainnetNotAllowedError` for a status on blockula-1 unless this client is pinned to that
1299
+ * chain (`chainPin`). Wallets call it with the very status each tx is signed for (DEV-1).
1300
+ */
1301
+ checkMainnetPin(chainId: unknown): void;
1302
+ /** The chain id this client is pinned to (`ClientOptions.chainId`), if any. A client that pins the chain itself reports its own pin. */
1303
+ protected chainPin(): string | undefined;
1304
+ /** One request, bounded by `timeoutMs` (headers and body): a node that never answers fails with `RequestTimeoutError` instead of hanging. */
111
1305
  private call;
112
1306
  status(): Promise<any>;
113
- blocks(limit?: number): Promise<any>;
1307
+ /**
1308
+ * Block headers, newest first: `{ height, hash, timestamp_ms, proposer, state_root, tx_count, … }`.
1309
+ * Up to `limit` (at most 100) below height `before` (default: from the head), so a page's
1310
+ * last height is the next page's `before`. Nothing older than the node's `history_from`.
1311
+ * `blocks(20)` still works.
1312
+ */
1313
+ blocks(page?: number | {
1314
+ limit?: number;
1315
+ before?: number;
1316
+ }): Promise<any[]>;
1317
+ /**
1318
+ * An account's history, newest first, a page at a time (TR-3): pass the previous page's `next`
1319
+ * as `before` until it's `null`. Each tx is shown as `/api/tx` shows it. On nodes without paged
1320
+ * history it's the newest 25 and the pending ones, with `paged: false` (see `HistoryPage`).
1321
+ */
1322
+ history(account: string, page?: {
1323
+ before?: string;
1324
+ limit?: number;
1325
+ }): Promise<HistoryPage>;
114
1326
  block(heightOrHash: number | string): Promise<any>;
115
1327
  tx(id: string): Promise<any>;
116
1328
  account(addressOrName: string): Promise<any>;
1329
+ /** A name: `status` (`active`, `grace` (expired; only its owner can renew it), `reserved` or `available`), owner, `expires_at`, `offered_to` (if its owner offered it to an account: theirs once they accept), prices. */
117
1330
  name(name: string): Promise<any>;
1331
+ /** The base fee: each upcoming block's (`slots`) and `suggested`, which covers any of the next 17 blocks. */
1332
+ fees(): Promise<{
1333
+ height: number;
1334
+ lag: number;
1335
+ slots: ({
1336
+ height: number;
1337
+ max_block_bytes: number;
1338
+ } & BaseFee)[];
1339
+ suggested: BaseFee;
1340
+ lowest?: BaseFee;
1341
+ tip_cap_multiple?: number;
1342
+ account_creation_fee: string;
1343
+ [k: string]: unknown;
1344
+ }>;
1345
+ /** The governance parameters (node/src/params.rs `ChainParams`; amounts as strings) under `params`, genesis constants under `genesis`, and the issuance year. `paramsOf` flattens it. */
1346
+ params(): Promise<any>;
1347
+ /** The chain's genesis.json as this node serves it: the node's word (nothing here checks it against the genesis hash). */
1348
+ genesis(): Promise<any>;
1349
+ /** Upgrades: the protocol version in force, what the node's binary supports, the `schedule` (`[{ version, activation_height, active }]`, what `proposal.cancelUpgrade` names), halts and each validator's readiness signal. */
1350
+ upgrade(): Promise<any>;
118
1351
  /** Accounts a key is authorized on (its own address, plus any it was added to). */
119
- keyAccounts(keyIdHex: string): Promise<any>;
1352
+ /**
1353
+ * Accounts a key is on (`{ key_id, accounts, next }`), a page at a time: pass the previous page's
1354
+ * `next` as `after`. Only accounts the key agreed to join (its grant) can list it (audit gap-7-2).
1355
+ */
1356
+ keyAccounts(keyIdHex: string, page?: {
1357
+ after?: string;
1358
+ limit?: number;
1359
+ }): Promise<any>;
120
1360
  search(q: string): Promise<any>;
121
- /** Active set for the current epoch, pending/approved validators, next-epoch set, epoch timing. */
1361
+ /** The validator set: `active` this epoch, `next_epoch` (with `joining`/`leaving`), `candidates`, `jailed`, `tombstoned` and `removed`, each with stake, self-bond, commission, jail and liveness; epoch timing; the churn limit and slashing parameters. */
122
1362
  validators(): Promise<any>;
123
1363
  /** Hunts (bounties on GitHub issues), biggest first. */
124
1364
  hunts(status?: "open" | "awarded" | "cancelled" | "expired"): Promise<any>;
125
1365
  hunt(id: number): Promise<any>;
126
1366
  /** Off-chain check of a GitHub link (gist owned by the handle containing the address). */
127
1367
  github(handle: string): Promise<any>;
1368
+ /** The contribution pool: balance, repos, rules, the open Séance and recent results. */
1369
+ contributions(): Promise<any>;
1370
+ claims(opts?: {
1371
+ status?: "pending" | "verified" | "in_seance" | "scored" | "spam" | "rejected";
1372
+ account?: string;
1373
+ }): Promise<any>;
1374
+ claim(id: number): Promise<any>;
1375
+ /** A Séance, with each juror's assigned pairs (what they must judge). */
1376
+ seance(id: number): Promise<any>;
1377
+ /** A juror's assigned pairs in Séance `id`, in order, with each claim's repo and PR (what `sealVotes` binds). */
1378
+ seancePairs(id: number, juror: string): Promise<[SeanceClaimRef, SeanceClaimRef][]>;
1379
+ /** Soul leaderboard. */
1380
+ souls(limit?: number): Promise<any>;
1381
+ /** An account's stake: `delegations` (shares, value, principal), `entries` (unbonding and redelegations, with `release_at`), `bonded`, `unbonding` and `withdrawable` totals, the `validators` it runs, a `summary`. */
1382
+ staking(account: string): Promise<any>;
1383
+ /** Governance proposals, newest first (`status`: `voting`, `queued`, `rejected`, `executed`, `failed`), the rules (`params`), treasury and community balances. */
1384
+ proposals(opts?: {
1385
+ status?: string;
1386
+ limit?: number;
1387
+ }): Promise<any>;
1388
+ /** One proposal with its votes. */
1389
+ proposal(id: number): Promise<any>;
1390
+ /** A community distribution: Merkle root, total, claimed so far, claim deadline. */
1391
+ distribution(id: number): Promise<any>;
1392
+ /** A multisig account: owners, threshold, open proposals and their approvals. */
1393
+ multisig(account: string): Promise<any>;
1394
+ /**
1395
+ * The chain's fuel prices and program bounds now (`/api/fees`' `fuel` section), checked.
1396
+ * `ProgramsOffError` when programs have never been switched on there (the section is absent).
1397
+ */
1398
+ programFuel(): Promise<ProgramFuel>;
1399
+ /** The programs parameters a deposit is priced with (`/api/params`' `programs` section), checked. */
1400
+ programParams(): Promise<ProgramParams>;
1401
+ /**
1402
+ * A program by its address (never a name): its record, the version digest a call binds (recomputed
1403
+ * from its code, interface and version: a node whose digest isn't what those compute is refused),
1404
+ * who could upgrade it, what it holds and its methods, whose names are the deployer's
1405
+ * (`untrusted_name`). One node's word (`proven: false`): `provenProgram` proves the record itself.
1406
+ */
1407
+ program(address: string): Promise<ProgramInfo>;
1408
+ /**
1409
+ * A stored code by its hash: its size, who uploaded it and for what deposit, how many programs use
1410
+ * it, when it was stored (usable from the block after) and its exported methods (`untrusted_exports`).
1411
+ * With `wasm`, the code itself too, checked to hash to what was asked for.
1412
+ */
1413
+ code(hash: string, opts?: {
1414
+ wasm?: boolean;
1415
+ }): Promise<ProgramCodeInfo>;
1416
+ /**
1417
+ * A stored interface by its hash: its format-1 bytes (checked to hash to what was asked for) and
1418
+ * the node's JSON reading of them (`untrusted_interface`, every name the deployer's, not checked
1419
+ * against the bytes: this SDK has no interface decoder yet).
1420
+ */
1421
+ interface(hash: string): Promise<ProgramInterfaceInfo>;
1422
+ /**
1423
+ * Runs a program's `view` method on the node, as of its newest block: nothing is signed or paid.
1424
+ * `input` is what the method reads (bytes, or lowercase hex); `bindings` name the other programs
1425
+ * it may reach (a program's address, and the version digest it must be at, or none for "any
1426
+ * version", which a read may take); `fuel` caps the run (the node caps it too). The answer's
1427
+ * `return_data` is the program's own claim, which the chain checks nothing of. Refused views
1428
+ * (`ApiError`: 403 when the node serves none, 429 with `retryAfterMs`, 400/404/422 for a request
1429
+ * the node won't run) never ran.
1430
+ */
1431
+ view(address: string, method: string, input?: Uint8Array | string, opts?: {
1432
+ bindings?: {
1433
+ program: string;
1434
+ versionDigest?: string;
1435
+ }[];
1436
+ fuel?: number;
1437
+ }): Promise<ProgramViewResult>;
1438
+ /**
1439
+ * A program's record, proven: its Merkle proof (namespace 66) checked against the state root the
1440
+ * node reports, which each of `witnesses` must report too, and fresh (see `provenRecord`).
1441
+ * The record is decoded here and its `version_digest` recomputed from its own fields, so a call
1442
+ * built from it binds the code the chain holds. `null` if the program provably doesn't exist.
1443
+ * Without witnesses it's only as sure as this node (it can't be called proven).
1444
+ */
1445
+ provenProgram(address: string, opts?: ProvenOptions): Promise<{
1446
+ creator: string;
1447
+ created_at: number;
1448
+ wasm_hash: string;
1449
+ interface_hash: string;
1450
+ version: number;
1451
+ authority: string | null;
1452
+ upgrade_delay_blocks: number;
1453
+ policy: "open" | "additive";
1454
+ accepts_transfers: boolean;
1455
+ storage: {
1456
+ items: number;
1457
+ bytes: number;
1458
+ deposit: string;
1459
+ };
1460
+ sponsored: string;
1461
+ record_deposit: string;
1462
+ record_payer: string;
1463
+ address: string;
1464
+ version_digest: string;
1465
+ witnesses: number;
1466
+ height: number;
1467
+ root: string;
1468
+ head: number;
1469
+ } | null>;
1470
+ /** `/api/proof/{namespace}/{key}`, unchecked. Prefer `provenRecord`. */
1471
+ proof(namespace: number, key: string | Uint8Array): Promise<ProofResponse>;
1472
+ /**
1473
+ * A record with its Merkle proof checked against the state root the node reports. On its own
1474
+ * that only shows the node is consistent; `witnesses` (clients for independent nodes) must
1475
+ * each report the same state root for that block, so a single lying node can't fake balances,
1476
+ * names or keys. A witness that hasn't reached the block yet is retried for `waitMs`.
1477
+ *
1478
+ * The proof must also be fresh: its block may be at most `maxLagBlocks` behind the newest head
1479
+ * this node and the witnesses report (`StaleProofError` otherwise). Witnesses confirm any
1480
+ * genuine root, old ones included, so without this a lying node could serve a real but outdated
1481
+ * record (a name's previous owner, a balance before a spend, a key since removed). `head` is
1482
+ * the newest head seen. Without witnesses only this node's own head is compared, which a lying
1483
+ * node controls: pass witnesses for anything that matters.
1484
+ */
1485
+ provenRecord(namespace: number, key: string | Uint8Array, opts?: ProvenOptions): Promise<ProvenRead>;
1486
+ /** Throws unless this node's block `height` has state root `root` (waiting up to `waitMs` for it to get there). */
1487
+ confirmStateRoot(height: number, root: string, waitMs?: number): Promise<void>;
1488
+ /** An address's balance, nonce and keys, proven and fresh (see `provenRecord`). `null` if the account provably doesn't exist. */
1489
+ provenAccount(address: string, opts?: ProvenOptions): Promise<{
1490
+ balance: bigint;
1491
+ nonce: number;
1492
+ keys: import("./proof.js").ProvenKey[];
1493
+ address: string;
1494
+ height: number;
1495
+ root: string;
1496
+ head: number;
1497
+ } | null>;
1498
+ /**
1499
+ * Who a `.boo` name resolves to, proven and fresh (see `provenRecord`). `null` if it provably
1500
+ * doesn't resolve: never registered, or expired (`expires_at` passed; in its grace period only
1501
+ * the owner can renew it, and after that anyone can register it). `includeExpired` returns an
1502
+ * expired record too, with `active: false`: never pay its `owner`.
1503
+ */
1504
+ provenName(name: string, opts?: ProvenOptions & {
1505
+ includeExpired?: boolean;
1506
+ }): Promise<{
1507
+ name: string;
1508
+ owner: string;
1509
+ registered_at: number;
1510
+ expires_at: number;
1511
+ offered_to?: string;
1512
+ grace_blocks?: number;
1513
+ active: boolean;
1514
+ height: number;
1515
+ root: string;
1516
+ head: number;
1517
+ } | null>;
1518
+ /**
1519
+ * The address a name or address resolves to, for fields that need an address (see
1520
+ * `resolution`): proven with witnesses, else one node's word. Where the chain resolves names
1521
+ * itself (payments, vouches, name offers…), use `recipient` instead, which signs the name.
1522
+ */
128
1523
  resolve(nameOrAddress: string): Promise<string>;
1524
+ /**
1525
+ * How to sign a recipient in a field the chain resolves itself (`transfer.to`, `award_hunt.to`,
1526
+ * `vouch`/`unvouch`/`flag_sybil`/`clawback.account`, `grant_soul.to`, `transfer_name.to`, and
1527
+ * proposal targets): an address as given; with witnesses a name's proven owner; without them
1528
+ * the name itself, which the chain resolves to its owner when the tx runs, so a lying node
1529
+ * can't point it at another account now (audit gap-7-1). It can still hold the signed tx and
1530
+ * release it later within its validity window, which counts from the height that node reported
1531
+ * (bounded by `checkSigningHeight` only with witnesses or a `genesisClock`): whoever owns the
1532
+ * name then is paid, so a name that lapses in between pays its next owner (review-r3-clients-2).
1533
+ * Show `how` before signing.
1534
+ */
1535
+ recipient(nameOrAddress: string): Promise<Recipient>;
1536
+ /**
1537
+ * Where a recipient goes and how sure that is: show `address` and `how` before signing. With the
1538
+ * client's `witnesses` a name is a proven, fresh read (`provenName`), so a lying node can't
1539
+ * point it elsewhere; without them it's this node's answer alone (`proven: false`), which a
1540
+ * lying node controls (audit gap-7-1).
1541
+ */
1542
+ resolution(nameOrAddress: string): Promise<Resolution>;
1543
+ /**
1544
+ * Submits a signed tx, then (with `wait`) waits for it. What a failure means:
1545
+ * - `ApiError`: the node refused the tx; it wasn't admitted.
1546
+ * - `RequestTimeoutError` or a network error: unknown; the tx may have arrived.
1547
+ * - `TxFailedError`: it executed and failed (`dropped` false: its fee was charged), or this node
1548
+ * dropped it unrun (`dropped` true: nothing charged, but it may still execute elsewhere until
1549
+ * its `valid_until`).
1550
+ * - `TxPendingError`: it was admitted and may still execute. Don't send it again blindly.
1551
+ */
129
1552
  submit(tx: Tx, wait?: boolean): Promise<any>;
1553
+ /**
1554
+ * Submits a signed tx and returns its id, without reading it back or waiting (`submit` does
1555
+ * both). The same bytes can be posted again safely: a node answers with the same id, and the tx
1556
+ * runs at most once. As JSON, or in its wire form with `wireTxs`. Errors as `submit`'s.
1557
+ */
1558
+ post(tx: Tx): Promise<{
1559
+ id: string;
1560
+ }>;
130
1561
  faucet(to: string, wait?: boolean): Promise<any>;
131
- waitForTx(id: string, timeoutMs?: number): Promise<any>;
1562
+ /**
1563
+ * Polls a tx until it's finalized (returns it) or failed (`TxFailedError`, which says whether it
1564
+ * executed or was dropped unrun). A poll that fails (rate limited, a node error, a timeout, not
1565
+ * visible yet) is retried; after `timeoutMs` it throws `TxPendingError`, since the tx may still
1566
+ * execute. `validUntil` (the tx's, when the caller has it) goes into a dropped tx's error.
1567
+ */
1568
+ waitForTx(id: string, timeoutMs?: number, validUntil?: number): Promise<any>;
132
1569
  }