@ar.io/sdk 3.24.0 → 4.0.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +682 -600
- package/lib/esm/cli/cli.js +188 -152
- package/lib/esm/cli/commands/antCommands.js +23 -58
- package/lib/esm/cli/commands/arnsPurchaseCommands.js +48 -30
- package/lib/esm/cli/commands/escrowCommands.js +221 -0
- package/lib/esm/cli/commands/gatewayWriteCommands.js +142 -23
- package/lib/esm/cli/commands/pruneCommands.js +150 -0
- package/lib/esm/cli/commands/readCommands.js +22 -3
- package/lib/esm/cli/commands/transfer.js +6 -6
- package/lib/esm/cli/options.js +124 -58
- package/lib/esm/cli/utils.js +280 -174
- package/lib/esm/common/ant-registry.js +17 -143
- package/lib/esm/common/ant.js +44 -1167
- package/lib/esm/common/faucet.js +11 -6
- package/lib/esm/common/index.js +0 -4
- package/lib/esm/common/io.js +25 -1412
- package/lib/esm/constants.js +13 -19
- package/lib/esm/solana/ant-readable.js +724 -0
- package/lib/esm/solana/ant-registry-readable.js +133 -0
- package/lib/esm/solana/ant-registry-writeable.js +472 -0
- package/lib/esm/solana/ant-writeable.js +384 -0
- package/lib/esm/solana/ata.js +70 -0
- package/lib/esm/solana/canonical-message.js +128 -0
- package/lib/esm/solana/clusters.js +111 -0
- package/lib/esm/solana/constants.js +146 -0
- package/lib/esm/solana/delegation-math.js +112 -0
- package/lib/esm/solana/deserialize.js +711 -0
- package/lib/esm/solana/escrow.js +839 -0
- package/lib/{cjs/utils/json.js → esm/solana/events.js} +15 -10
- package/lib/esm/solana/funding-plan.js +699 -0
- package/lib/esm/solana/index.js +126 -0
- package/lib/esm/solana/instruction.js +39 -0
- package/lib/esm/solana/io-readable.js +2182 -0
- package/lib/esm/solana/io-writeable.js +3196 -0
- package/lib/esm/solana/json-rpc.js +90 -0
- package/lib/esm/solana/metadata.js +81 -0
- package/lib/esm/solana/mpl-core.js +192 -0
- package/lib/esm/solana/pda.js +332 -0
- package/lib/esm/solana/predict-prescribed-observers.js +110 -0
- package/lib/esm/solana/retry.js +117 -0
- package/lib/esm/solana/rpc-circuit-breaker.js +258 -0
- package/lib/esm/solana/send.js +372 -0
- package/lib/esm/solana/spawn-ant.js +224 -0
- package/lib/esm/solana/types.js +1 -0
- package/lib/esm/types/ant.js +27 -15
- package/lib/esm/types/io.js +8 -11
- package/lib/esm/utils/ant.js +0 -63
- package/lib/esm/utils/index.js +0 -3
- package/lib/esm/version.js +1 -1
- package/lib/types/cli/commands/antCommands.d.ts +5 -13
- package/lib/types/cli/commands/arnsPurchaseCommands.d.ts +33 -7
- package/lib/types/cli/commands/escrowCommands.d.ts +68 -0
- package/lib/types/cli/commands/gatewayWriteCommands.d.ts +12 -11
- package/lib/types/cli/commands/pruneCommands.d.ts +31 -0
- package/lib/types/cli/commands/readCommands.d.ts +27 -22
- package/lib/types/cli/commands/transfer.d.ts +9 -9
- package/lib/types/cli/options.d.ts +76 -21
- package/lib/types/cli/types.d.ts +11 -13
- package/lib/types/cli/utils.d.ts +71 -31
- package/lib/types/common/ant-registry.d.ts +49 -47
- package/lib/types/common/ant.d.ts +54 -539
- package/lib/types/common/faucet.d.ts +20 -8
- package/lib/types/common/index.d.ts +0 -3
- package/lib/types/common/io.d.ts +51 -263
- package/lib/types/constants.d.ts +11 -18
- package/lib/types/solana/ant-readable.d.ts +180 -0
- package/lib/types/solana/ant-registry-readable.d.ts +105 -0
- package/lib/types/solana/ant-registry-writeable.d.ts +249 -0
- package/lib/types/solana/ant-writeable.d.ts +177 -0
- package/lib/types/solana/ata.d.ts +44 -0
- package/lib/types/solana/canonical-message.d.ts +121 -0
- package/lib/types/solana/clusters.d.ts +109 -0
- package/lib/types/solana/constants.d.ts +119 -0
- package/lib/types/solana/delegation-math.d.ts +45 -0
- package/lib/types/solana/deserialize.d.ts +262 -0
- package/lib/types/solana/escrow.d.ts +480 -0
- package/lib/types/solana/events.d.ts +38 -0
- package/lib/types/solana/funding-plan.d.ts +225 -0
- package/lib/types/solana/index.d.ts +87 -0
- package/lib/types/solana/instruction.d.ts +39 -0
- package/lib/types/solana/io-readable.d.ts +499 -0
- package/lib/types/solana/io-writeable.d.ts +893 -0
- package/lib/types/solana/json-rpc.d.ts +47 -0
- package/lib/types/solana/metadata.d.ts +84 -0
- package/lib/types/solana/mpl-core.d.ts +120 -0
- package/lib/types/solana/pda.d.ts +95 -0
- package/lib/types/solana/predict-prescribed-observers.d.ts +28 -0
- package/lib/types/solana/retry.d.ts +62 -0
- package/lib/types/solana/rpc-circuit-breaker.d.ts +78 -0
- package/lib/types/solana/send.d.ts +94 -0
- package/lib/types/solana/spawn-ant.d.ts +145 -0
- package/lib/types/solana/types.d.ts +82 -0
- package/lib/types/types/ant-registry.d.ts +43 -4
- package/lib/types/types/ant.d.ts +114 -96
- package/lib/types/types/common.d.ts +18 -74
- package/lib/types/types/faucet.d.ts +2 -2
- package/lib/types/types/io.d.ts +244 -158
- package/lib/types/types/token.d.ts +0 -12
- package/lib/types/utils/ant.d.ts +1 -12
- package/lib/types/utils/index.d.ts +0 -3
- package/lib/types/version.d.ts +1 -1
- package/package.json +36 -33
- package/lib/cjs/cli/cli.js +0 -822
- package/lib/cjs/cli/commands/antCommands.js +0 -113
- package/lib/cjs/cli/commands/arnsPurchaseCommands.js +0 -212
- package/lib/cjs/cli/commands/gatewayWriteCommands.js +0 -210
- package/lib/cjs/cli/commands/readCommands.js +0 -215
- package/lib/cjs/cli/commands/transfer.js +0 -159
- package/lib/cjs/cli/options.js +0 -470
- package/lib/cjs/cli/types.js +0 -2
- package/lib/cjs/cli/utils.js +0 -639
- package/lib/cjs/common/ant-registry.js +0 -155
- package/lib/cjs/common/ant-versions.js +0 -93
- package/lib/cjs/common/ant.js +0 -1182
- package/lib/cjs/common/arweave.js +0 -27
- package/lib/cjs/common/contracts/ao-process.js +0 -224
- package/lib/cjs/common/error.js +0 -64
- package/lib/cjs/common/faucet.js +0 -150
- package/lib/cjs/common/hyperbeam/hb.js +0 -173
- package/lib/cjs/common/index.js +0 -42
- package/lib/cjs/common/io.js +0 -1423
- package/lib/cjs/common/logger.js +0 -83
- package/lib/cjs/common/loggers/winston.js +0 -68
- package/lib/cjs/common/marketplace.js +0 -731
- package/lib/cjs/common/turbo.js +0 -223
- package/lib/cjs/constants.js +0 -41
- package/lib/cjs/node/index.js +0 -39
- package/lib/cjs/package.json +0 -1
- package/lib/cjs/types/ant-registry.js +0 -2
- package/lib/cjs/types/ant.js +0 -168
- package/lib/cjs/types/common.js +0 -2
- package/lib/cjs/types/faucet.js +0 -2
- package/lib/cjs/types/index.js +0 -37
- package/lib/cjs/types/io.js +0 -51
- package/lib/cjs/types/token.js +0 -116
- package/lib/cjs/utils/ant.js +0 -108
- package/lib/cjs/utils/ao.js +0 -432
- package/lib/cjs/utils/arweave.js +0 -285
- package/lib/cjs/utils/base64.js +0 -62
- package/lib/cjs/utils/hash.js +0 -56
- package/lib/cjs/utils/index.js +0 -38
- package/lib/cjs/utils/processes.js +0 -173
- package/lib/cjs/utils/random.js +0 -30
- package/lib/cjs/utils/schema.js +0 -15
- package/lib/cjs/utils/url.js +0 -37
- package/lib/cjs/version.js +0 -20
- package/lib/cjs/web/index.js +0 -41
- package/lib/esm/common/ant-versions.js +0 -87
- package/lib/esm/common/arweave.js +0 -21
- package/lib/esm/common/contracts/ao-process.js +0 -220
- package/lib/esm/common/hyperbeam/hb.js +0 -169
- package/lib/esm/common/marketplace.js +0 -724
- package/lib/esm/common/turbo.js +0 -215
- package/lib/esm/node/index.js +0 -20
- package/lib/esm/utils/ao.js +0 -420
- package/lib/esm/utils/arweave.js +0 -271
- package/lib/esm/utils/processes.js +0 -167
- package/lib/esm/web/index.js +0 -20
- package/lib/types/common/ant-versions.d.ts +0 -39
- package/lib/types/common/arweave.d.ts +0 -17
- package/lib/types/common/contracts/ao-process.d.ts +0 -47
- package/lib/types/common/hyperbeam/hb.d.ts +0 -88
- package/lib/types/common/marketplace.d.ts +0 -568
- package/lib/types/common/turbo.d.ts +0 -61
- package/lib/types/node/index.d.ts +0 -20
- package/lib/types/utils/ao.d.ts +0 -80
- package/lib/types/utils/arweave.d.ts +0 -79
- package/lib/types/utils/processes.d.ts +0 -39
- package/lib/types/web/index.d.ts +0 -20
|
@@ -0,0 +1,893 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
/**
|
|
17
|
+
* Solana implementation of ARIOWrite interface.
|
|
18
|
+
*
|
|
19
|
+
* Extends SolanaARIOReadable with write operations that build and send
|
|
20
|
+
* Solana transactions via Codama-generated instruction builders.
|
|
21
|
+
*
|
|
22
|
+
* All instruction encoding (discriminators, account ordering, Borsh codecs,
|
|
23
|
+
* default value resolution for token/system programs) is delegated to the
|
|
24
|
+
* generated builders in `./generated/{core,gar,arns}/instructions/`. The
|
|
25
|
+
* builders are derived from the on-chain IDL and stay in sync via codegen.
|
|
26
|
+
*
|
|
27
|
+
* This file's job is just to:
|
|
28
|
+
* 1. Translate the AO-style SDK params into the builder's input shape.
|
|
29
|
+
* 2. Pre-derive the PDAs that the *Async builders can't infer (the ones
|
|
30
|
+
* whose seeds depend on runtime state — e.g. the next withdrawal id
|
|
31
|
+
* from the on-chain counter, or the buyer's ATA from a runtime mint).
|
|
32
|
+
* 3. Append remaining_accounts (gateway PDAs, name registry) for the
|
|
33
|
+
* epoch crank instructions, since Codama doesn't generate a typed
|
|
34
|
+
* surface for them.
|
|
35
|
+
*/
|
|
36
|
+
import { type Address, type Instruction } from '@solana/kit';
|
|
37
|
+
import type { ILogger } from '../common/logger.js';
|
|
38
|
+
import type { MessageResult, WriteOptions } from '../types/common.js';
|
|
39
|
+
import type { ArNSPurchaseParams, BuyRecordParams, CreateVaultParams, DelegateStakeParams, ExtendLeaseParams, ExtendVaultParams, IncreaseUndernameLimitParams, IncreaseVaultParams, JoinNetworkParams, RedelegateStakeParams, RevokeVaultParams, UpdateGatewaySettingsParams, VaultedTransferParams } from '../types/io.js';
|
|
40
|
+
import type { mARIOToken } from '../types/token.js';
|
|
41
|
+
import { deserializeEpochSettingsFull } from './deserialize.js';
|
|
42
|
+
import { SolanaARIOReadable } from './io-readable.js';
|
|
43
|
+
import type { SolanaRpcSubscriptions, SolanaSigner, SolanaWriteConfig } from './types.js';
|
|
44
|
+
/**
|
|
45
|
+
* Pick the swapped-gateway operator that `finalize_gone` needs as a writable
|
|
46
|
+
* `remaining_accounts[0]`.
|
|
47
|
+
*
|
|
48
|
+
* `finalize_gone` reclaims a gateway's slot from the compact GatewayRegistry by
|
|
49
|
+
* moving the LAST active slot into it and rewriting that swapped gateway's
|
|
50
|
+
* stored `registry_index`. When the finalized gateway is NOT already the last
|
|
51
|
+
* slot, the on-chain handler requires the swapped Gateway PDA (writable) at
|
|
52
|
+
* `remaining_accounts[0]`; when it IS the last slot, no swap occurs and no
|
|
53
|
+
* extra account is needed. See
|
|
54
|
+
* `programs/ario-gar/src/instructions/gateway.rs::finalize_gone`.
|
|
55
|
+
*
|
|
56
|
+
* `registryAddresses` MUST be the active registry operator addresses in slot
|
|
57
|
+
* order (`getRegistryGatewayAddresses()` — length === on-chain
|
|
58
|
+
* `registry.count`), so `registryAddresses[length - 1]` is exactly the
|
|
59
|
+
* `registry.gateways[count - 1].address` the on-chain swap reads.
|
|
60
|
+
*
|
|
61
|
+
* @returns the swapped gateway's operator address, or `null` when the finalized
|
|
62
|
+
* gateway already occupies the last slot.
|
|
63
|
+
* @throws if `registryIndex` is outside the active registry count (mirrors the
|
|
64
|
+
* on-chain `index < registry.count` guard, surfacing a stale index early).
|
|
65
|
+
*/
|
|
66
|
+
export declare function selectFinalizeGoneSwapOperator(registryIndex: number, registryAddresses: string[]): string | null;
|
|
67
|
+
/**
|
|
68
|
+
* Split a primary name into its undername + base parts using the same rule
|
|
69
|
+
* as the on-chain `splitn(2, '_')` in `programs/ario-core/src/instructions/primary_name.rs`:
|
|
70
|
+
* everything before the first '_' is the undername, the rest is the base.
|
|
71
|
+
*
|
|
72
|
+
* Exposed as a top-level helper so it can be unit-tested without spinning up
|
|
73
|
+
* an `SolanaARIOWriteable`. Lowercases the input to match contract behavior.
|
|
74
|
+
*/
|
|
75
|
+
export declare function splitPrimaryName(name: string): {
|
|
76
|
+
isUndername: boolean;
|
|
77
|
+
baseName: string;
|
|
78
|
+
undername: string | null;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Solana-backed read-write client for the AR.IO protocol.
|
|
82
|
+
*
|
|
83
|
+
* Usage:
|
|
84
|
+
* ```ts
|
|
85
|
+
* import {
|
|
86
|
+
* createSolanaRpc,
|
|
87
|
+
* createSolanaRpcSubscriptions,
|
|
88
|
+
* generateKeyPairSigner,
|
|
89
|
+
* } from '@solana/kit';
|
|
90
|
+
* import { SolanaARIOWriteable } from '@ar.io/sdk/solana';
|
|
91
|
+
*
|
|
92
|
+
* const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
|
|
93
|
+
* const rpcSubscriptions = createSolanaRpcSubscriptions('wss://api.mainnet-beta.solana.com');
|
|
94
|
+
* const signer = await generateKeyPairSigner();
|
|
95
|
+
* const ario = new SolanaARIOWriteable({ rpc, rpcSubscriptions, signer });
|
|
96
|
+
*
|
|
97
|
+
* await ario.transfer({ target: 'RecipientPubkey...', qty: 100_000_000 });
|
|
98
|
+
* ```
|
|
99
|
+
*/
|
|
100
|
+
/** Build the gateway_results bitmap for save_observations.
|
|
101
|
+
* All bits start as 1 (pass) for the first `registryAddresses.length`
|
|
102
|
+
* positions; positions named in `failedGateways` get cleared to 0; all
|
|
103
|
+
* positions beyond `registryAddresses.length` are 0. */
|
|
104
|
+
export declare function buildObservationBitmap(registryAddresses: string[], failedGateways: string[]): Buffer;
|
|
105
|
+
/** Encode an Arweave TX ID into the on-chain `[u8; 32]` slot.
|
|
106
|
+
*
|
|
107
|
+
* An Arweave TX ID **is** a 32-byte SHA-256 hash; the 43-char base64url
|
|
108
|
+
* string is just its presentation encoding. We decode here so the
|
|
109
|
+
* on-chain bytes are the raw hash — lossless and trivially reversible
|
|
110
|
+
* via base64url-encode on the consumer side. Without this, on-chain
|
|
111
|
+
* bytes alone couldn't be used to look up the original report bundle
|
|
112
|
+
* on permaweb (the whole point of recording the txid for auditability).
|
|
113
|
+
*
|
|
114
|
+
* Empty / undefined input → 32 zero bytes ("no permaweb archive
|
|
115
|
+
* configured for this submission" — the report still lives off-chain
|
|
116
|
+
* in the observer's local sinks but isn't anchored on Arweave).
|
|
117
|
+
*
|
|
118
|
+
* Throws on malformed input: the base64url string must be exactly 43
|
|
119
|
+
* chars and decode to 32 bytes. Strict validation here is desirable —
|
|
120
|
+
* silently truncating or accepting bad input would erode the
|
|
121
|
+
* auditability that the field exists for.
|
|
122
|
+
*/
|
|
123
|
+
export declare function encodeReportTxId(reportTxId: string | undefined): Buffer;
|
|
124
|
+
/** The single on-chain action a {@link SolanaARIOWriteable.crankEpochStep} call performed. */
|
|
125
|
+
export type CrankAction = 'create' | 'tally' | 'prescribe' | 'distribute' | 'compound' | 'update_demand_factor' | 'prune_returned_names' | 'close_observation' | 'close' | 'idle';
|
|
126
|
+
/** Options for {@link SolanaARIOWriteable.crankEpochStep}. */
|
|
127
|
+
export interface CrankEpochStepOptions {
|
|
128
|
+
/** Gateways per tally/distribute batch. Default 30. */
|
|
129
|
+
batchSize?: number;
|
|
130
|
+
/**
|
|
131
|
+
* NameRegistry account for the name-prescription leg. Defaults to the
|
|
132
|
+
* registry derived from the configured ArNS program. Pass `null` to disable
|
|
133
|
+
* name prescription entirely.
|
|
134
|
+
*/
|
|
135
|
+
nameRegistryAccount?: Address | null;
|
|
136
|
+
/** Close fully-distributed epochs older than `epochRetention`. Default true. */
|
|
137
|
+
enableClose?: boolean;
|
|
138
|
+
/** Epochs of retention before an epoch may be closed (GAR-006). Default 7. */
|
|
139
|
+
epochRetention?: number;
|
|
140
|
+
/**
|
|
141
|
+
* Compound pending delegate rewards (settle the reward-per-share accumulator
|
|
142
|
+
* into delegated stake) once the live epoch is fully distributed, so the next
|
|
143
|
+
* epoch's tally weights the compounded stake. Default true. The delegate
|
|
144
|
+
* rewards are correct in the accumulator regardless — this only materializes
|
|
145
|
+
* them on-chain. Each step compounds one batch; runs only in the otherwise-
|
|
146
|
+
* idle tail (never during tally/distribute).
|
|
147
|
+
*/
|
|
148
|
+
enableCompound?: boolean;
|
|
149
|
+
/**
|
|
150
|
+
* Skip compounding delegations whose pending reward is at/below this (mARIO).
|
|
151
|
+
* Avoids dust compounds that only advance `reward_debt`. Default 0.
|
|
152
|
+
*/
|
|
153
|
+
compoundMinPendingRewards?: number;
|
|
154
|
+
/**
|
|
155
|
+
* Roll the demand factor forward when its (wall-clock) period has elapsed.
|
|
156
|
+
* Idempotent — only sends a tx when the stored period is behind. Pricing is
|
|
157
|
+
* always lazily correct without this; it keeps the STORED factor (and reads
|
|
158
|
+
* between buys) current. Default true. Runs only in the idle tail.
|
|
159
|
+
*/
|
|
160
|
+
enableDemandFactorRoll?: boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Prune expired ReturnedName PDAs (auction window elapsed) as part of the
|
|
163
|
+
* crank. Default true. Runs whenever the epoch lifecycle is otherwise idle
|
|
164
|
+
* (the live observation window AND the post-distribution tail), one batch per
|
|
165
|
+
* step. It scans the ReturnedName PDAs DIRECTLY (via getExpiredReturnedNames)
|
|
166
|
+
* and does NOT consult `config.next_returned_names_prune_timestamp` — that
|
|
167
|
+
* hint is only set for on-chain returns and is never updated for imported
|
|
168
|
+
* returned names, so trusting it strands imported auctions forever.
|
|
169
|
+
*/
|
|
170
|
+
enablePrune?: boolean;
|
|
171
|
+
/** ReturnedName PDAs to prune per tx (u8, max 255). Default 15. */
|
|
172
|
+
pruneBatchSize?: number;
|
|
173
|
+
/**
|
|
174
|
+
* Minimum wall-clock gap between returned-name prune SCANS (ms). The scan is a
|
|
175
|
+
* `getProgramAccounts` over ReturnedName PDAs, so this throttles it below the
|
|
176
|
+
* crank poll rate. Default 60_000 (1 min). Set 0 to scan every step (tests).
|
|
177
|
+
*/
|
|
178
|
+
pruneScanIntervalMs?: number;
|
|
179
|
+
/** Unix seconds; defaults to the wall clock. Injectable for testing. */
|
|
180
|
+
now?: number;
|
|
181
|
+
}
|
|
182
|
+
/** Result of a single {@link SolanaARIOWriteable.crankEpochStep} call. */
|
|
183
|
+
export interface CrankEpochStepResult {
|
|
184
|
+
/** The action performed (or `'idle'` when nothing was due). */
|
|
185
|
+
action: CrankAction;
|
|
186
|
+
/** The epoch the action targeted (absent for `'idle'`). */
|
|
187
|
+
epochIndex?: number;
|
|
188
|
+
/** Confirmed transaction signature, when an action was submitted. */
|
|
189
|
+
txId?: string;
|
|
190
|
+
/** Batch progress for `'tally'` / `'distribute'`. */
|
|
191
|
+
progress?: {
|
|
192
|
+
index: number;
|
|
193
|
+
total: number;
|
|
194
|
+
};
|
|
195
|
+
/** For `action: 'idle'`, why nothing was done. */
|
|
196
|
+
reason?: 'epochs_disabled' | 'waiting_for_genesis' | 'waiting_for_epoch' | 'waiting_for_observations' | 'epoch_complete';
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Detect the GAR `InvalidGatewayAccount` error by Anchor error name/message
|
|
200
|
+
* (walking the cause chain + `context.logs`), NOT by numeric code — codes are
|
|
201
|
+
* `6000 + enum-index` and shift across program versions, but the name and
|
|
202
|
+
* message are stable. `prescribe_epoch` raises this when a supplied observer
|
|
203
|
+
* Gateway PDA is missing/spoofed (e.g. a predicted observer left the registry
|
|
204
|
+
* between prediction and tx landing).
|
|
205
|
+
*/
|
|
206
|
+
export declare function isInvalidGatewayAccountError(error: unknown): boolean;
|
|
207
|
+
export declare class SolanaARIOWriteable extends SolanaARIOReadable {
|
|
208
|
+
protected readonly signer: SolanaSigner;
|
|
209
|
+
protected readonly rpcSubscriptions: SolanaRpcSubscriptions;
|
|
210
|
+
constructor(config: SolanaWriteConfig & {
|
|
211
|
+
logger?: ILogger;
|
|
212
|
+
coreProgramId?: Address;
|
|
213
|
+
garProgramId?: Address;
|
|
214
|
+
arnsProgramId?: Address;
|
|
215
|
+
antProgramId?: Address;
|
|
216
|
+
});
|
|
217
|
+
/** The signer's on-chain address. */
|
|
218
|
+
protected get signerAddress(): Address;
|
|
219
|
+
protected sendTransaction(instructions: Instruction[], computeUnitLimit?: number): Promise<string>;
|
|
220
|
+
/** Helper to get the ARIO mint and treasury from ArioConfig */
|
|
221
|
+
private getCoreConfig;
|
|
222
|
+
private getMint;
|
|
223
|
+
/** Helper to get ArNS config fields (mint and treasury) */
|
|
224
|
+
private getArnsConfig;
|
|
225
|
+
/** Helper to get GAR config fields (mint, stake pool, protocol pool) */
|
|
226
|
+
private getGarConfig;
|
|
227
|
+
/**
|
|
228
|
+
* Inject ARNS default PDAs (config, demandFactor, nameRegistry).
|
|
229
|
+
*
|
|
230
|
+
* Extra fields not consumed by a given builder are harmlessly ignored
|
|
231
|
+
* (codama only reads the named keys from `input`).
|
|
232
|
+
*/
|
|
233
|
+
private withArnsDefaults;
|
|
234
|
+
/**
|
|
235
|
+
* If the on-chain ArnsRecord for `name` hasn't been migrated to the
|
|
236
|
+
* current schema (name_hash at offset 8 doesn't match the expected
|
|
237
|
+
* hash), return a `migrate_arns_record` instruction that must be
|
|
238
|
+
* prepended to any operation referencing the record with PDA seed
|
|
239
|
+
* verification.
|
|
240
|
+
*
|
|
241
|
+
* Returns an empty array when the record is already up-to-date or
|
|
242
|
+
* doesn't exist.
|
|
243
|
+
*/
|
|
244
|
+
private _buildMigrateArnsRecordIxIfNeeded;
|
|
245
|
+
/** Inject ARIO core default PDAs (config). */
|
|
246
|
+
private withCoreDefaults;
|
|
247
|
+
/** Inject GAR default PDAs (settings, epochSettings, registry). */
|
|
248
|
+
private withGarDefaults;
|
|
249
|
+
/** Read WithdrawalCounter's next_id (returns 0n if not yet created) */
|
|
250
|
+
private getNextWithdrawalId;
|
|
251
|
+
transfer(params: {
|
|
252
|
+
target: string;
|
|
253
|
+
qty: number | mARIOToken;
|
|
254
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
255
|
+
vaultedTransfer(params: VaultedTransferParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
256
|
+
createVault(params: CreateVaultParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
257
|
+
/** Read VaultCounter's next_id (returns 0n if not yet created). */
|
|
258
|
+
private getNextVaultId;
|
|
259
|
+
extendVault(params: ExtendVaultParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
260
|
+
increaseVault(params: IncreaseVaultParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
261
|
+
revokeVault(params: RevokeVaultParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
262
|
+
joinNetwork(params: JoinNetworkParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
263
|
+
leaveNetwork(_options?: WriteOptions): Promise<MessageResult>;
|
|
264
|
+
updateGatewaySettings(params: UpdateGatewaySettingsParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
265
|
+
increaseOperatorStake(params: {
|
|
266
|
+
increaseQty: number | mARIOToken;
|
|
267
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
268
|
+
decreaseOperatorStake(params: {
|
|
269
|
+
decreaseQty: number | mARIOToken;
|
|
270
|
+
instant?: boolean;
|
|
271
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
272
|
+
delegateStake(params: DelegateStakeParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
273
|
+
decreaseDelegateStake(params: {
|
|
274
|
+
target: string;
|
|
275
|
+
decreaseQty: number | mARIOToken;
|
|
276
|
+
instant?: boolean;
|
|
277
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
278
|
+
instantWithdrawal(params: {
|
|
279
|
+
gatewayAddress?: string;
|
|
280
|
+
vaultId: string;
|
|
281
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
282
|
+
cancelWithdrawal(params: {
|
|
283
|
+
gatewayAddress?: string;
|
|
284
|
+
vaultId: string;
|
|
285
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
286
|
+
saveObservations(params: {
|
|
287
|
+
reportTxId: string;
|
|
288
|
+
failedGateways: string[];
|
|
289
|
+
epochIndex?: number;
|
|
290
|
+
/** Raw 256-byte gateway results bitfield (if provided, overrides failedGateways) */
|
|
291
|
+
gatewayResults?: Uint8Array;
|
|
292
|
+
gatewayCount?: number;
|
|
293
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
294
|
+
redelegateStake(params: RedelegateStakeParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
295
|
+
buyRecord(params: BuyRecordParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
296
|
+
/**
|
|
297
|
+
* Resolve a `FundingPlan` for a fee-paying ArNS ix. When `params.sources`
|
|
298
|
+
* is set, use it verbatim (caller-supplied plan); otherwise discover the
|
|
299
|
+
* user's sources and build a plan via the Lua-faithful planner.
|
|
300
|
+
*
|
|
301
|
+
* Throws `InsufficientFundingError` (as a thrown Error with the structured
|
|
302
|
+
* payload as `cause`) when no plan covers `amountNeeded`.
|
|
303
|
+
*/
|
|
304
|
+
private _resolveFundingPlan;
|
|
305
|
+
/**
|
|
306
|
+
* Build a `buy_name_from_funding_plan` ix using the funding-plan module.
|
|
307
|
+
* Resolves per-source PDAs (Delegation, Withdrawal) and the residue-vault
|
|
308
|
+
* PDA prediction in one shot.
|
|
309
|
+
*/
|
|
310
|
+
private _buildBuyNameFromFundingPlanIx;
|
|
311
|
+
/**
|
|
312
|
+
* For an explicit caller-supplied plan, detect which Delegation sources
|
|
313
|
+
* will trigger an on-chain residue auto-vault. Reads each (Delegation,
|
|
314
|
+
* Gateway) pair in parallel; computes post-drain; flags `(0, min)`.
|
|
315
|
+
*
|
|
316
|
+
* Hard-fails on RPC error or missing PDA — silently skipping would let
|
|
317
|
+
* the on-chain handler reject the tx with `MissingResidueVault` and
|
|
318
|
+
* burn fees. The error message points at remediation.
|
|
319
|
+
*/
|
|
320
|
+
private _detectResidueIndexes;
|
|
321
|
+
/**
|
|
322
|
+
* Materialize a `FundingPlan` into the on-chain ix's per-source remaining
|
|
323
|
+
* accounts, residue-vault PDAs, and the withdrawal_counter slot. Shared
|
|
324
|
+
* across all 5 ArNS funding-plan ix dispatches and the 2 ario-core
|
|
325
|
+
* primary-name funding-plan dispatches.
|
|
326
|
+
*
|
|
327
|
+
* Throws when the plan has Withdrawal sources whose ids cannot be
|
|
328
|
+
* resolved from either `spec.withdrawalId` (preferred) or
|
|
329
|
+
* `params.withdrawalId` (single-withdrawal back-compat).
|
|
330
|
+
*/
|
|
331
|
+
private _materializeFundingPlan;
|
|
332
|
+
/**
|
|
333
|
+
* Simulate the on-chain `get_token_cost` instruction and return the exact
|
|
334
|
+
* cost as a `bigint` (mARIO). This guarantees byte-exact agreement with the
|
|
335
|
+
* on-chain pricing math, avoiding integer-division rounding divergences
|
|
336
|
+
* that plagued the previous client-side reimplementation.
|
|
337
|
+
*
|
|
338
|
+
* The program writes a LE-u64 cost into the transaction's return data;
|
|
339
|
+
* we parse it from the simulation result.
|
|
340
|
+
*/
|
|
341
|
+
private _simulateTokenCost;
|
|
342
|
+
private arnsConfigPda;
|
|
343
|
+
private demandFactorPda;
|
|
344
|
+
private nameRegistryPda;
|
|
345
|
+
upgradeRecord(params: ArNSPurchaseParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
346
|
+
syncAttributes(params: {
|
|
347
|
+
name: string;
|
|
348
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
349
|
+
/**
|
|
350
|
+
* Build a `sync_attributes` instruction for `name` IFF the signer is
|
|
351
|
+
* the current MPL Core asset owner. Returns `null` otherwise.
|
|
352
|
+
*
|
|
353
|
+
* Sprint 4 / ADR-016: bundle helper for `buyRecord`, `upgradeRecord`,
|
|
354
|
+
* `increaseUndernameLimit`, `reassignName`, and `buyReturnedName`.
|
|
355
|
+
* Returning `null` lets the caller send the arns ix alone — preserves
|
|
356
|
+
* BD-095 (non-holder ArNS lease management) and BD-096 (deferred
|
|
357
|
+
* trait sync for non-holder buyers). The actual ANT owner reconciles
|
|
358
|
+
* state later via the public `syncAttributes()`.
|
|
359
|
+
*
|
|
360
|
+
* `extendLease` is NOT a caller of this helper — extend_lease changes
|
|
361
|
+
* only `end_timestamp`, which isn't mirrored in any Attributes-plugin
|
|
362
|
+
* trait (BD-095 last row). `releaseName` is also excluded — release_name
|
|
363
|
+
* closes the ArnsRecord PDA, so a follow-up `sync_attributes` would
|
|
364
|
+
* fail the PDA-existence check.
|
|
365
|
+
*
|
|
366
|
+
* `assetOverride` MUST be set when the bundling ix mutates
|
|
367
|
+
* `record.ant` mid-tx (i.e. `reassign_name`). The on-chain record
|
|
368
|
+
* still points at the OLD asset at SDK build time, so without the
|
|
369
|
+
* override the bundled sync would target the wrong asset and fail
|
|
370
|
+
* the post-reassign `record.ant == asset.key()` check. The owner
|
|
371
|
+
* check runs against the supplied asset (= new ANT for reassign),
|
|
372
|
+
* matching the pre-reshape "new owner reconciles later" semantic.
|
|
373
|
+
*/
|
|
374
|
+
private _buildSyncAttributesIxIfOwner;
|
|
375
|
+
/**
|
|
376
|
+
* Build a `sync_attributes` instruction unconditionally (no owner
|
|
377
|
+
* check). Used by the public `syncAttributes()` method, where the
|
|
378
|
+
* caller is asking explicitly — if they aren't the owner the chain
|
|
379
|
+
* returns NotNftHolder.
|
|
380
|
+
*/
|
|
381
|
+
private _buildSyncAttributesIxUnconditional;
|
|
382
|
+
/** Pure builder; no RPC. Used by both gated + unconditional helpers. */
|
|
383
|
+
private _buildSyncAttributesIxFor;
|
|
384
|
+
extendLease(params: ExtendLeaseParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
385
|
+
increaseUndernameLimit(params: IncreaseUndernameLimitParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
386
|
+
/**
|
|
387
|
+
* Shared dispatch helper for the 3 manage variants (upgrade / extend /
|
|
388
|
+
* increaseUndername). They share the same account shape per the
|
|
389
|
+
* `manage_from_delegation_accounts!` / `manage_from_operator_stake_accounts!`
|
|
390
|
+
* macros in `programs/ario-arns/src/instructions/manage_from_stake.rs`.
|
|
391
|
+
* Only the operation-specific extra args differ (years for extend,
|
|
392
|
+
* quantity for increaseUndername).
|
|
393
|
+
*/
|
|
394
|
+
private _buildManageStakeIx;
|
|
395
|
+
/**
|
|
396
|
+
* If the signer already has a primary name set, build the instruction(s)
|
|
397
|
+
* needed to remove it so they can be prepended to a request/set tx —
|
|
398
|
+
* enabling single-tx "change primary name" flows.
|
|
399
|
+
*
|
|
400
|
+
* Returns an empty array when the signer has no existing primary name.
|
|
401
|
+
*
|
|
402
|
+
* Throws when the signer has a legacy primary-name state (forward
|
|
403
|
+
* `PrimaryName` PDA exists but its paired `PrimaryNameReverse` PDA does
|
|
404
|
+
* NOT). Both `remove_primary_name` AND `request_and_set_primary_name`
|
|
405
|
+
* require the reverse PDA on-chain — the latter rejects with
|
|
406
|
+
* `MustRemoveExistingPrimaryName` (0x1786, code 6022) any time a
|
|
407
|
+
* forward record already exists for the signer, regardless of reverse
|
|
408
|
+
* state. Silently skipping the remove would queue a tx guaranteed to
|
|
409
|
+
* fail with that opaque error. Surfacing it at the client with a clear
|
|
410
|
+
* remediation pointer is the only safe behavior.
|
|
411
|
+
*
|
|
412
|
+
* The legacy state should not exist on any cluster post-snapshot/import
|
|
413
|
+
* PR #159 (which emits PrimaryNameReverse in lockstep with PrimaryName)
|
|
414
|
+
* — it's a relic of pre-#159 imports. Operators on affected clusters
|
|
415
|
+
* must run `yarn workspace @ar-io/migration-import backfill:primary-name-reverse`
|
|
416
|
+
* (in the solana-ar-io repo) before this method can succeed.
|
|
417
|
+
*/
|
|
418
|
+
private _buildRemoveExistingPrimaryNameIxs;
|
|
419
|
+
/**
|
|
420
|
+
* Build the `remaining_accounts` slice + the `antProgramId` arg the
|
|
421
|
+
* four ario-core primary-name instructions consume. Sprint 2/5
|
|
422
|
+
* reshape (ADR-016): ario-core no longer reads MPL Core asset bytes.
|
|
423
|
+
* Authorization is "caller is the effective AntRecord owner for this
|
|
424
|
+
* name", resolved from the `AntRecord` + `AntConfig` PDAs (freshness-
|
|
425
|
+
* gated against `AntConfig.last_known_owner` — see ario-core BD-097 /
|
|
426
|
+
* BD-109). Both are program-PDA-pinned lookups.
|
|
427
|
+
*
|
|
428
|
+
* Layouts the on-chain handlers expect:
|
|
429
|
+
* request_primary_name: [arnsRecord, demandFactor]
|
|
430
|
+
* request_and_set_primary_name: [arnsRecord, demandFactor, antRecord, antConfig]
|
|
431
|
+
* approve_primary_name: [arnsRecord, antRecord, antConfig]
|
|
432
|
+
* remove_primary_name_for_base_name: [arnsRecord, antRecord(@), antConfig]
|
|
433
|
+
*
|
|
434
|
+
* `antRecord` keys off the undername part for undernames (e.g.
|
|
435
|
+
* "blog_arweave" → AntRecord at "blog") or the canonical "@" sentinel
|
|
436
|
+
* for base names. `removeForBaseName` is special — it always uses "@"
|
|
437
|
+
* regardless of whether the primary name being removed is an undername,
|
|
438
|
+
* since the *base* name owner is the one revoking it.
|
|
439
|
+
*
|
|
440
|
+
* `antProgram` honors ADR-016 / BD-100 pluggability: the asset's
|
|
441
|
+
* `ANT Program` Attributes-plugin trait selects which program owns the
|
|
442
|
+
* AntRecord PDA. Absent / unparseable → canonical fallback. The detected
|
|
443
|
+
* trait is untrusted asset/RPC data, so it is honored only when it matches
|
|
444
|
+
* the canonical program or this client's explicitly-configured
|
|
445
|
+
* `this.antProgram`; any other value falls back to the configured program
|
|
446
|
+
* (see the SECURITY note in the body). Both the PDA derivation here and the
|
|
447
|
+
* `ant_program_id` arg the caller passes to the on-chain ix MUST agree (the
|
|
448
|
+
* handler re-derives and rejects mismatches).
|
|
449
|
+
*/
|
|
450
|
+
private _buildPrimaryNameValidationAccounts;
|
|
451
|
+
requestPrimaryName(params: ArNSPurchaseParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
452
|
+
setPrimaryName(params: ArNSPurchaseParams, _options?: WriteOptions): Promise<MessageResult>;
|
|
453
|
+
/**
|
|
454
|
+
* Build a `request_primary_name_from_funding_plan` or
|
|
455
|
+
* `request_and_set_primary_name_from_funding_plan` ix. Forwards both:
|
|
456
|
+
* - validation accounts (ArnsRecord + DemandFactor [+ ant_asset
|
|
457
|
+
* [+ AntRecord]]) — passed via remaining_accounts at indices
|
|
458
|
+
* [0..validation_account_count)
|
|
459
|
+
* - per-source PDAs from the funding plan — passed at indices
|
|
460
|
+
* [validation_account_count..)
|
|
461
|
+
*
|
|
462
|
+
* The on-chain handler (programs/ario-core/src/instructions/primary_name.rs)
|
|
463
|
+
* splits remaining_accounts at `validation_account_count` and forwards the
|
|
464
|
+
* funding-source slice to ario-gar's pay_from_funding_plan via CPI.
|
|
465
|
+
*/
|
|
466
|
+
private _buildPrimaryNameFromFundingPlanIx;
|
|
467
|
+
private _coreConfigPda;
|
|
468
|
+
/**
|
|
469
|
+
* Approve a previously-created primary name request. The signer must be
|
|
470
|
+
* the AntRecord.owner for the requested name (undername part for
|
|
471
|
+
* undernames, "@" for base names) — Sprint 2 / ADR-016 reshape.
|
|
472
|
+
*
|
|
473
|
+
* Mirrors the on-chain `approve_primary_name` instruction
|
|
474
|
+
* (`programs/ario-core/src/instructions/primary_name.rs`).
|
|
475
|
+
* remaining_accounts: [arns_record(base), ant_record(undername | @), ant_config].
|
|
476
|
+
*/
|
|
477
|
+
approvePrimaryName(params: {
|
|
478
|
+
initiator: Address;
|
|
479
|
+
name: string;
|
|
480
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
481
|
+
/** Release tokens from an unlocked vault back to the owner. */
|
|
482
|
+
releaseVault(params: {
|
|
483
|
+
vaultId: string;
|
|
484
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
485
|
+
/** Close an expired primary name request (permissionless — anyone can call). */
|
|
486
|
+
closeExpiredRequest(params: {
|
|
487
|
+
initiator: string;
|
|
488
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
489
|
+
/** Claim tokens from a completed withdrawal (after lock period). */
|
|
490
|
+
claimWithdrawal(params: {
|
|
491
|
+
withdrawalId: string;
|
|
492
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
493
|
+
/** Claim delegated stake from a gateway that is leaving the network. */
|
|
494
|
+
claimDelegateFromLeavingGateway(params: {
|
|
495
|
+
gatewayAddress: string;
|
|
496
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
497
|
+
/**
|
|
498
|
+
* Claim a delegate's stake out of a gateway that has DISABLED delegation
|
|
499
|
+
* (`allow_delegated_staking == false`), moving it into the delegate's own
|
|
500
|
+
* withdrawal vault (WP §6.3 / Fix #6). This is the disabled-gateway analog of
|
|
501
|
+
* {@link claimDelegateFromLeavingGateway}: the on-chain instruction is
|
|
502
|
+
* permissionless, so a cranker can sweep delegates out (the operator cannot
|
|
503
|
+
* re-enable delegation until `total_delegated_stake == 0` and the cooldown
|
|
504
|
+
* elapses). The withdrawal-counter and withdrawal PDAs are seeded by the
|
|
505
|
+
* DELEGATOR, so a cranker must pass that delegate's `delegatorAddress`.
|
|
506
|
+
*
|
|
507
|
+
* @param params.gatewayAddress The gateway whose delegation was disabled.
|
|
508
|
+
* @param params.delegatorAddress The delegate to claim for. Defaults to the
|
|
509
|
+
* signer (self-claim). Pass another address to crank on a delegate's behalf;
|
|
510
|
+
* the signer covers rent (`payer`) but stake still routes to the delegate's
|
|
511
|
+
* own vault (the delegator key is bound by the delegation PDA seeds).
|
|
512
|
+
*/
|
|
513
|
+
claimDelegateFromDisabledGateway(params: {
|
|
514
|
+
gatewayAddress: string;
|
|
515
|
+
delegatorAddress?: string;
|
|
516
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
517
|
+
/** Add an address to the gateway's delegation allowlist. */
|
|
518
|
+
allowDelegate(params: {
|
|
519
|
+
delegate: string;
|
|
520
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
521
|
+
/** Remove an address from the gateway's delegation allowlist. */
|
|
522
|
+
disallowDelegate(params: {
|
|
523
|
+
delegate: string;
|
|
524
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
525
|
+
/** Enable or disable the delegation allowlist for the gateway. */
|
|
526
|
+
setAllowlistEnabled(params: {
|
|
527
|
+
enabled: boolean;
|
|
528
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
529
|
+
/**
|
|
530
|
+
* Buy a name from the returned name auction (Dutch auction with premium).
|
|
531
|
+
*
|
|
532
|
+
* Phase 4: now dispatches on `params.fundFrom`. Note that for
|
|
533
|
+
* `buyReturnedName`, only the protocol share funds from the chosen source;
|
|
534
|
+
* the initiator share is always a direct buyer-ATA → initiator-ATA SPL
|
|
535
|
+
* transfer (matches the on-chain `_from_*` variant behavior).
|
|
536
|
+
*/
|
|
537
|
+
buyReturnedName(params: {
|
|
538
|
+
name: string;
|
|
539
|
+
type: 'lease' | 'permabuy';
|
|
540
|
+
years?: number;
|
|
541
|
+
processId: string;
|
|
542
|
+
} & Partial<ArNSPurchaseParams>, _options?: WriteOptions): Promise<MessageResult>;
|
|
543
|
+
/**
|
|
544
|
+
* Pick a single stake-derived funding source that can cover a returned-name
|
|
545
|
+
* purchase, for the single-source `buy_returned_name_from_*` paths.
|
|
546
|
+
*
|
|
547
|
+
* Returned-name prices decay per slot, so the multi-source funding plan
|
|
548
|
+
* (which pre-commits exact amounts) can't match the execution-time cost. The
|
|
549
|
+
* single-source paths carry no amount — the program draws the live cost — so
|
|
550
|
+
* we only need to pick ONE source with enough stake. We size the pick against
|
|
551
|
+
* the premium-inclusive estimate (an upper bound, since the price only falls
|
|
552
|
+
* from now) and choose the largest matching source. Returns `null` when no
|
|
553
|
+
* single source covers the estimate.
|
|
554
|
+
*/
|
|
555
|
+
private _autoPickReturnedNameStakeSource;
|
|
556
|
+
/** Reassign an ArNS name to a different ANT. */
|
|
557
|
+
reassignName(params: {
|
|
558
|
+
name: string;
|
|
559
|
+
processId: string;
|
|
560
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
561
|
+
/** Release a permabuy name back to the registry (creates a returned name auction). */
|
|
562
|
+
releaseName(params: {
|
|
563
|
+
name: string;
|
|
564
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
565
|
+
/**
|
|
566
|
+
* Roll the demand factor forward to the current period. Permissionless and
|
|
567
|
+
* idempotent — a no-op within the same period. Pricing already rolls the
|
|
568
|
+
* factor inline on every buy/extend, so this only refreshes the STORED
|
|
569
|
+
* factor that `getDemandFactor` and between-buy price previews read; a
|
|
570
|
+
* periodic crank (~once per 24h `PERIOD_LENGTH_SECONDS`) keeps it current.
|
|
571
|
+
*/
|
|
572
|
+
updateDemandFactor(_options?: WriteOptions): Promise<MessageResult>;
|
|
573
|
+
/**
|
|
574
|
+
* Materialize a single delegate's pending rewards into their delegated
|
|
575
|
+
* stake by settling the gateway's reward-per-share accumulator.
|
|
576
|
+
* Permissionless — there is no signer beyond the fee payer; `delegator` is
|
|
577
|
+
* only a PDA-derivation seed. Rewards always accrue correctly in the
|
|
578
|
+
* accumulator regardless of this call; compounding makes the on-chain
|
|
579
|
+
* `delegatedStake` reflect them (and earn compound interest in the next
|
|
580
|
+
* epoch's weighting). Idempotent — a no-op once already settled.
|
|
581
|
+
*/
|
|
582
|
+
compoundDelegationRewards(params: {
|
|
583
|
+
gateway: string;
|
|
584
|
+
delegator: string;
|
|
585
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
586
|
+
/**
|
|
587
|
+
* Compound many delegates' rewards in a SINGLE transaction — one
|
|
588
|
+
* `compound_delegation_rewards` instruction per entry. Idempotent and
|
|
589
|
+
* permissionless, so partial batches are safe to retry. Keep each batch
|
|
590
|
+
* within the per-tx account/CU budget; grouping entries that share a gateway
|
|
591
|
+
* lowers the unique-account count (the gateway account is reused across
|
|
592
|
+
* instructions). Typical cranker usage: enumerate with
|
|
593
|
+
* `SolanaARIOReadable.getDelegationsToCompound`, chunk, then call this.
|
|
594
|
+
*/
|
|
595
|
+
compoundDelegationRewardsBatch(delegations: Array<{
|
|
596
|
+
gateway: string;
|
|
597
|
+
delegator: string;
|
|
598
|
+
}>, _options?: WriteOptions): Promise<MessageResult>;
|
|
599
|
+
/**
|
|
600
|
+
* Build a single `compound_delegation_rewards` instruction (shared by the
|
|
601
|
+
* single + batch methods). PDAs are derived under the configured gar program
|
|
602
|
+
* so the program-id override always targets the right cluster.
|
|
603
|
+
*/
|
|
604
|
+
private buildCompoundDelegationRewardsInstruction;
|
|
605
|
+
/**
|
|
606
|
+
* Create a new epoch. Permissionless — anyone can call when the next
|
|
607
|
+
* epoch's start time has arrived.
|
|
608
|
+
*/
|
|
609
|
+
createEpoch(_options?: WriteOptions): Promise<MessageResult>;
|
|
610
|
+
/**
|
|
611
|
+
* Tally weights for a batch of gateways. Permissionless — call repeatedly
|
|
612
|
+
* until all gateways are processed. Pass gateway PDAs as
|
|
613
|
+
* `gatewayAccounts`; they're appended as `remaining_accounts`.
|
|
614
|
+
*/
|
|
615
|
+
tallyWeights(params: {
|
|
616
|
+
epochIndex: number;
|
|
617
|
+
gatewayAccounts: Address[];
|
|
618
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
619
|
+
/**
|
|
620
|
+
* Prescribe observers and names for an epoch. Permissionless — call after
|
|
621
|
+
* weights are tallied.
|
|
622
|
+
*
|
|
623
|
+
* `gatewayAccounts` MUST be the Gateway PDAs of the SELECTED observers only
|
|
624
|
+
* — at most `epoch_settings.prescribed_observer_count` (≤50), NOT the whole
|
|
625
|
+
* registry. The selection is computed on-chain; mirror it off-chain with
|
|
626
|
+
* {@link predictPrescribedObservers} / {@link getPredictedObserverPDAs} to
|
|
627
|
+
* learn the set. Passing every registry gateway (e.g. via
|
|
628
|
+
* {@link getAllRegistryGatewayPDAs}) hits Solana's `MAX_TX_ACCOUNT_LOCKS = 64`
|
|
629
|
+
* on large registries and the tx fails at pre-flight.
|
|
630
|
+
*
|
|
631
|
+
* The selected PDAs are appended as `remaining_accounts`, followed by the
|
|
632
|
+
* optional `nameRegistryAccount` (must be LAST) which enables the name
|
|
633
|
+
* prescription leg.
|
|
634
|
+
*
|
|
635
|
+
* If a selected gateway leaves between prediction and tx landing, the tx
|
|
636
|
+
* fails with `InvalidGatewayAccount` — retry once with a fresh prediction.
|
|
637
|
+
*/
|
|
638
|
+
prescribeEpoch(params: {
|
|
639
|
+
epochIndex: number;
|
|
640
|
+
gatewayAccounts: Address[];
|
|
641
|
+
/** Optional NameRegistry account — pass to enable name prescription */
|
|
642
|
+
nameRegistryAccount?: Address;
|
|
643
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
644
|
+
/**
|
|
645
|
+
* Distribute rewards for a completed epoch in batches. Permissionless —
|
|
646
|
+
* call after epoch ends. Gateway PDAs appended as `remaining_accounts`.
|
|
647
|
+
*/
|
|
648
|
+
distributeEpoch(params: {
|
|
649
|
+
epochIndex: number;
|
|
650
|
+
gatewayAccounts: Address[];
|
|
651
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
652
|
+
/**
|
|
653
|
+
* Close an old epoch account and reclaim rent. Permissionless — call after
|
|
654
|
+
* the epoch is distributed and at least 7 epochs have passed.
|
|
655
|
+
*/
|
|
656
|
+
closeEpoch(params: {
|
|
657
|
+
epochIndex: number;
|
|
658
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
659
|
+
/**
|
|
660
|
+
* Get gateway PDAs for a batch starting at registryIndex.
|
|
661
|
+
* Reads the GatewayRegistry and derives PDAs for the next `batchSize`
|
|
662
|
+
* active gateways.
|
|
663
|
+
*/
|
|
664
|
+
getRegistryGatewayPDAs(startIndex: number, batchSize: number): Promise<Address[]>;
|
|
665
|
+
/** Get ALL active gateway PDAs from the registry. */
|
|
666
|
+
getAllRegistryGatewayPDAs(): Promise<Address[]>;
|
|
667
|
+
/**
|
|
668
|
+
* Predict the Gateway PDAs that `prescribe_epoch` will select as observers
|
|
669
|
+
* for `epochIndex`, mirroring the on-chain weighted-roulette selection.
|
|
670
|
+
*
|
|
671
|
+
* Returns at most `epoch_settings.prescribed_observer_count` (≤50) PDAs
|
|
672
|
+
* regardless of registry size — the set to pass as `gatewayAccounts` to
|
|
673
|
+
* {@link prescribeEpoch}. This is the size-safe replacement for
|
|
674
|
+
* {@link getAllRegistryGatewayPDAs} on the prescribe path (which oversupplies
|
|
675
|
+
* and trips `MAX_TX_ACCOUNT_LOCKS = 64` on large registries).
|
|
676
|
+
*
|
|
677
|
+
* Reads three accounts (epoch, registry, epoch settings) at the configured
|
|
678
|
+
* commitment so the prediction reflects live registry weights. If a selected
|
|
679
|
+
* gateway races out before the tx lands, `prescribeEpoch` throws
|
|
680
|
+
* `InvalidGatewayAccount` — re-call this and retry once.
|
|
681
|
+
*/
|
|
682
|
+
getPredictedObserverPDAs(epochIndex: number): Promise<Address[]>;
|
|
683
|
+
/**
|
|
684
|
+
* Reclaim rent from the ephemeral Address Lookup Tables this signer created
|
|
685
|
+
* for `prescribe_epoch` (see {@link sendWithEphemeralLookupTable}). Each
|
|
686
|
+
* prescribe leaves a single-use table allocated (~0.0126 SOL); reclaiming
|
|
687
|
+
* needs a deactivate → ~513-slot cooldown → close sequence, so it can't run
|
|
688
|
+
* inline. Call this from a throttled/permissionless cleanup pass (cranker /
|
|
689
|
+
* observer) to deactivate active tables and close cooled-down ones, refunding
|
|
690
|
+
* the rent to the signer.
|
|
691
|
+
*
|
|
692
|
+
* Discovery reads the signer's transaction history (RPC-portable; the ALT
|
|
693
|
+
* program can't be enumerated via `getProgramAccounts`). The GAR + ArNS
|
|
694
|
+
* program IDs are passed as the entry-ownership fingerprint so only genuine
|
|
695
|
+
* prescribe tables are touched. Best-effort: at most `maxTables` submissions
|
|
696
|
+
* per call, scanning at most `scanLimit` recent signatures.
|
|
697
|
+
*/
|
|
698
|
+
reclaimLookupTableRent(opts?: {
|
|
699
|
+
maxTables?: number;
|
|
700
|
+
scanLimit?: number;
|
|
701
|
+
}): Promise<{
|
|
702
|
+
deactivated: number;
|
|
703
|
+
closed: number;
|
|
704
|
+
candidates: number;
|
|
705
|
+
scannedSignatures: number;
|
|
706
|
+
}>;
|
|
707
|
+
/** Read and deserialize the full EpochSettings account. */
|
|
708
|
+
getEpochSettingsFull(): Promise<ReturnType<typeof deserializeEpochSettingsFull>>;
|
|
709
|
+
/**
|
|
710
|
+
* Submit `prescribe_epoch` using the off-chain-predicted observer set, with a
|
|
711
|
+
* single re-predict-and-retry on `InvalidGatewayAccount` (covers a gateway
|
|
712
|
+
* leaving the registry between the prediction read and the tx landing).
|
|
713
|
+
*/
|
|
714
|
+
protected prescribeWithPrediction(epochIndex: number, nameRegistryAccount?: Address): Promise<MessageResult>;
|
|
715
|
+
/**
|
|
716
|
+
* Advance the epoch lifecycle by ONE on-chain action and return what it did.
|
|
717
|
+
*
|
|
718
|
+
* Stateless and idempotent: it reads `EpochSettings` + the current `Epoch`,
|
|
719
|
+
* determines the single next required step
|
|
720
|
+
* (`create` → `tally` → `prescribe` → `distribute` → `close`), submits it,
|
|
721
|
+
* and returns a {@link CrankEpochStepResult}. Call it repeatedly on your own
|
|
722
|
+
* schedule — it owns *which* on-chain action is correct and *which accounts*
|
|
723
|
+
* it needs; you own scheduling, logging, error classification, and any
|
|
724
|
+
* permissionless cleanup.
|
|
725
|
+
*
|
|
726
|
+
* Crucially, the `prescribe` leg uses {@link getPredictedObserverPDAs} (only
|
|
727
|
+
* the ~`prescribed_observer_count` selected Gateway PDAs), so it never trips
|
|
728
|
+
* `MAX_TX_ACCOUNT_LOCKS = 64` on large registries — and it re-predicts and
|
|
729
|
+
* retries once on `InvalidGatewayAccount`.
|
|
730
|
+
*
|
|
731
|
+
* Errors propagate to the caller (classify/retry as you see fit); the only
|
|
732
|
+
* internally-handled error is the prescribe `InvalidGatewayAccount` retry.
|
|
733
|
+
*/
|
|
734
|
+
crankEpochStep(opts?: CrankEpochStepOptions): Promise<CrankEpochStepResult>;
|
|
735
|
+
/**
|
|
736
|
+
* One compound batch over delegations with pending rewards (≤
|
|
737
|
+
* {@link MAX_COMPOUND_BATCH} per tx), or `null` when none are due. Settling
|
|
738
|
+
* is idempotent, so this converges over a few crank steps then no-ops until
|
|
739
|
+
* the next epoch's distribution advances the accumulator again.
|
|
740
|
+
*/
|
|
741
|
+
private maybeCompoundStep;
|
|
742
|
+
/**
|
|
743
|
+
* Roll the demand factor forward if its (wall-clock) period elapsed since the
|
|
744
|
+
* last stored roll, else `null`. Mirrors the on-chain period math; the roll
|
|
745
|
+
* itself is idempotent.
|
|
746
|
+
*/
|
|
747
|
+
private maybeRollDemandFactorStep;
|
|
748
|
+
/** Wall-clock (ms) of the last returned-name prune scan; throttles the
|
|
749
|
+
* getProgramAccounts scan below the crank poll rate. */
|
|
750
|
+
private lastReturnedNamePruneScanMs;
|
|
751
|
+
/**
|
|
752
|
+
* One prune batch over ReturnedName PDAs whose 14-day auction window has
|
|
753
|
+
* elapsed (≤ {@link CrankEpochStepOptions.pruneBatchSize} per tx), or `null`
|
|
754
|
+
* when none are due / the scan is throttled. Scans the PDAs directly — it does
|
|
755
|
+
* NOT gate on `config.next_returned_names_prune_timestamp`, which is never set
|
|
756
|
+
* for imported returned names and would strand them. The contract re-checks
|
|
757
|
+
* each account's window, so a slightly-skewed client clock is safe.
|
|
758
|
+
*/
|
|
759
|
+
private maybePruneReturnedNamesStep;
|
|
760
|
+
/**
|
|
761
|
+
* The DemandFactor account's stored period + period-zero start (seconds) —
|
|
762
|
+
* the gate for {@link maybeRollDemandFactorStep}. `null` if the account
|
|
763
|
+
* doesn't exist (pre-genesis).
|
|
764
|
+
*/
|
|
765
|
+
getDemandFactorPeriodState(): Promise<{
|
|
766
|
+
currentPeriod: number;
|
|
767
|
+
periodZeroStartTimestamp: number;
|
|
768
|
+
} | null>;
|
|
769
|
+
/**
|
|
770
|
+
* Read the raw epoch account data for cranker state inspection.
|
|
771
|
+
* Returns null if the epoch account doesn't exist yet.
|
|
772
|
+
*/
|
|
773
|
+
getEpochRaw(epochIndex: number): Promise<{
|
|
774
|
+
tallyIndex: number;
|
|
775
|
+
distributionIndex: number;
|
|
776
|
+
weightsTallied: number;
|
|
777
|
+
prescriptionsDone: number;
|
|
778
|
+
rewardsDistributed: number;
|
|
779
|
+
observationsSubmitted: number;
|
|
780
|
+
observationsClosed: number;
|
|
781
|
+
activeGatewayCount: number;
|
|
782
|
+
endTimestamp: number;
|
|
783
|
+
} | null>;
|
|
784
|
+
/**
|
|
785
|
+
* Parse raw epoch account data for cranker-relevant fields.
|
|
786
|
+
* Offsets match the Rust Epoch zero-copy struct (repr(C)).
|
|
787
|
+
*
|
|
788
|
+
* Layout after 8-byte discriminator:
|
|
789
|
+
* [8 epoch_index][8 start_ts][8 end_ts][8 total_eligible][8 per_gw]
|
|
790
|
+
* [8 per_obs][8 reward_rate][8 weight_lo][8 weight_hi][32 hashchain]
|
|
791
|
+
* [4 active_gw_count][4 dist_idx][4 tally_idx]
|
|
792
|
+
* [1 observer_count][1 name_count][1 obs_submitted][1 rewards_dist]
|
|
793
|
+
* [1 weights_tallied][1 prescriptions_done][1 bump][1 obs_closed]
|
|
794
|
+
* [6000 failure_counts][1600 prescribed_observers]
|
|
795
|
+
* [1600 prescribed_observer_gateways][64 prescribed_names]
|
|
796
|
+
* [7 has_observed][5 _pad2]
|
|
797
|
+
*
|
|
798
|
+
* NOTE: byte +123 is `observations_closed` (NOT padding) — `close_epoch`
|
|
799
|
+
* reverts with EpochObservationsNotClosed until it equals obs_submitted.
|
|
800
|
+
*/
|
|
801
|
+
private fetchEpochRawFields;
|
|
802
|
+
/**
|
|
803
|
+
* Batch-prune expired ArnsRecord PDAs from the NameRegistry. The caller
|
|
804
|
+
* supplies the eligible records as `arnsRecords` — they're appended as
|
|
805
|
+
* `remaining_accounts` and the on-chain handler verifies each is past
|
|
806
|
+
* `end_timestamp + grace_period + return_auction_duration` before closing.
|
|
807
|
+
* `maxNames` caps the per-tx work (u8). Submit in batches of ~10-15.
|
|
808
|
+
*/
|
|
809
|
+
pruneExpiredNames(params: {
|
|
810
|
+
maxNames: number;
|
|
811
|
+
arnsRecords: string[];
|
|
812
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
813
|
+
/**
|
|
814
|
+
* Convert a single expired-but-not-yet-returned lease into a `ReturnedName`
|
|
815
|
+
* (kicks off the Dutch auction). Permissionless.
|
|
816
|
+
*/
|
|
817
|
+
pruneNameToReturned(params: {
|
|
818
|
+
name: string;
|
|
819
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
820
|
+
/**
|
|
821
|
+
* Batch-prune expired ReturnedName PDAs (auction window elapsed). Caller
|
|
822
|
+
* supplies the eligible PDAs as `returnedNames`; they're appended as
|
|
823
|
+
* `remaining_accounts`. `maxNames` caps per-tx work (u8).
|
|
824
|
+
*/
|
|
825
|
+
pruneReturnedNames(params: {
|
|
826
|
+
maxNames: number;
|
|
827
|
+
returnedNames: string[];
|
|
828
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
829
|
+
/**
|
|
830
|
+
* Close a single expired ReservedName PDA. Permissionless after
|
|
831
|
+
* `expires_at`.
|
|
832
|
+
*/
|
|
833
|
+
pruneExpiredReservation(params: {
|
|
834
|
+
name: string;
|
|
835
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
836
|
+
/**
|
|
837
|
+
* Slash and remove a deficient gateway (`stats.failed_consecutive >=
|
|
838
|
+
* max_consecutive_failures`). Builds the protected exit vault for the
|
|
839
|
+
* post-slash min portion plus the optional excess vault for any surplus.
|
|
840
|
+
* The contract's `excess_withdrawal: Option<UncheckedAccount>` slot is
|
|
841
|
+
* always passed (PDA derived from `next_id + 1`); the handler consumes
|
|
842
|
+
* it only when the post-slash stake exceeds `min_operator_stake`.
|
|
843
|
+
* Permissionless.
|
|
844
|
+
*/
|
|
845
|
+
pruneGateway(params: {
|
|
846
|
+
gateway: string;
|
|
847
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
848
|
+
/**
|
|
849
|
+
* GC a `Leaving`/`Gone` gateway whose leave window has fully elapsed.
|
|
850
|
+
* Closes the Gateway PDA and refunds rent to the caller. Permissionless.
|
|
851
|
+
*/
|
|
852
|
+
finalizeGone(params: {
|
|
853
|
+
gateway: string;
|
|
854
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
855
|
+
/**
|
|
856
|
+
* Reclaim rent from an Observation PDA whose epoch has been distributed.
|
|
857
|
+
* Permissionless. Pass `epochIndex` and the `observer` address used as
|
|
858
|
+
* the Observation seed.
|
|
859
|
+
*/
|
|
860
|
+
closeObservation(params: {
|
|
861
|
+
epochIndex: number;
|
|
862
|
+
observer: string;
|
|
863
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
864
|
+
/**
|
|
865
|
+
* Close multiple Observation PDAs for one epoch in a single tx (each
|
|
866
|
+
* `close_observation` increments the parent Epoch's `observations_closed`).
|
|
867
|
+
* Permissionless; rent is refunded to the payer. Used by the crank to satisfy
|
|
868
|
+
* `close_epoch`'s `observations_closed == observations_submitted` precondition
|
|
869
|
+
* before closing a retention-aged epoch. Keep the batch small — each ix carries
|
|
870
|
+
* the Epoch + Observation + payer + system accounts.
|
|
871
|
+
*/
|
|
872
|
+
closeObservations(params: {
|
|
873
|
+
epochIndex: number;
|
|
874
|
+
observers: string[];
|
|
875
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
876
|
+
/**
|
|
877
|
+
* Close an empty Delegation PDA (`amount == 0`) and refund rent to the
|
|
878
|
+
* original delegator (NOT the caller — see GAR-016, prevents griefing).
|
|
879
|
+
* Permissionless.
|
|
880
|
+
*/
|
|
881
|
+
closeEmptyDelegation(params: {
|
|
882
|
+
gateway: string;
|
|
883
|
+
delegator: string;
|
|
884
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
885
|
+
/**
|
|
886
|
+
* Close a drained Withdrawal PDA (`amount == 0`) and refund rent to the
|
|
887
|
+
* original owner (NOT the caller). Permissionless.
|
|
888
|
+
*/
|
|
889
|
+
closeDrainedWithdrawal(params: {
|
|
890
|
+
owner: string;
|
|
891
|
+
withdrawalId: number | bigint;
|
|
892
|
+
}, _options?: WriteOptions): Promise<MessageResult>;
|
|
893
|
+
}
|