@ar.io/sdk 3.24.0 → 4.0.0-alpha.2

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.
Files changed (169) hide show
  1. package/README.md +757 -589
  2. package/lib/esm/cli/cli.js +188 -152
  3. package/lib/esm/cli/commands/antCommands.js +23 -58
  4. package/lib/esm/cli/commands/arnsPurchaseCommands.js +48 -30
  5. package/lib/esm/cli/commands/escrowCommands.js +227 -0
  6. package/lib/esm/cli/commands/gatewayWriteCommands.js +140 -23
  7. package/lib/esm/cli/commands/pruneCommands.js +154 -0
  8. package/lib/esm/cli/commands/readCommands.js +22 -3
  9. package/lib/esm/cli/commands/transfer.js +6 -6
  10. package/lib/esm/cli/options.js +124 -58
  11. package/lib/esm/cli/utils.js +303 -175
  12. package/lib/esm/common/ant-registry.js +17 -143
  13. package/lib/esm/common/ant.js +44 -1167
  14. package/lib/esm/common/faucet.js +17 -6
  15. package/lib/esm/common/index.js +0 -4
  16. package/lib/esm/common/io.js +25 -1412
  17. package/lib/esm/constants.js +13 -19
  18. package/lib/esm/solana/ant-readable.js +724 -0
  19. package/lib/esm/solana/ant-registry-readable.js +133 -0
  20. package/lib/esm/solana/ant-registry-writeable.js +472 -0
  21. package/lib/esm/solana/ant-writeable.js +384 -0
  22. package/lib/esm/solana/ata.js +70 -0
  23. package/lib/esm/solana/canonical-message.js +128 -0
  24. package/lib/esm/solana/clusters.js +111 -0
  25. package/lib/esm/solana/constants.js +146 -0
  26. package/lib/esm/solana/delegation-math.js +112 -0
  27. package/lib/esm/solana/deserialize.js +711 -0
  28. package/lib/esm/solana/escrow.js +839 -0
  29. package/lib/{cjs/utils/json.js → esm/solana/events.js} +15 -10
  30. package/lib/esm/solana/funding-plan.js +699 -0
  31. package/lib/esm/solana/index.js +126 -0
  32. package/lib/esm/solana/instruction.js +39 -0
  33. package/lib/esm/solana/io-readable.js +2182 -0
  34. package/lib/esm/solana/io-writeable.js +3196 -0
  35. package/lib/esm/solana/json-rpc.js +90 -0
  36. package/lib/esm/solana/metadata.js +81 -0
  37. package/lib/esm/solana/mpl-core.js +192 -0
  38. package/lib/esm/solana/pda.js +332 -0
  39. package/lib/esm/solana/predict-prescribed-observers.js +110 -0
  40. package/lib/esm/solana/retry.js +117 -0
  41. package/lib/esm/solana/rpc-circuit-breaker.js +258 -0
  42. package/lib/esm/solana/send.js +372 -0
  43. package/lib/esm/solana/spawn-ant.js +224 -0
  44. package/lib/esm/solana/types.js +1 -0
  45. package/lib/esm/types/ant.js +27 -15
  46. package/lib/esm/types/io.js +8 -11
  47. package/lib/esm/utils/ant.js +0 -63
  48. package/lib/esm/utils/index.js +0 -3
  49. package/lib/esm/version.js +1 -1
  50. package/lib/types/cli/commands/antCommands.d.ts +5 -13
  51. package/lib/types/cli/commands/arnsPurchaseCommands.d.ts +33 -7
  52. package/lib/types/cli/commands/escrowCommands.d.ts +68 -0
  53. package/lib/types/cli/commands/gatewayWriteCommands.d.ts +12 -11
  54. package/lib/types/cli/commands/pruneCommands.d.ts +31 -0
  55. package/lib/types/cli/commands/readCommands.d.ts +27 -22
  56. package/lib/types/cli/commands/transfer.d.ts +9 -9
  57. package/lib/types/cli/options.d.ts +76 -21
  58. package/lib/types/cli/types.d.ts +11 -13
  59. package/lib/types/cli/utils.d.ts +71 -31
  60. package/lib/types/common/ant-registry.d.ts +49 -47
  61. package/lib/types/common/ant.d.ts +54 -539
  62. package/lib/types/common/faucet.d.ts +20 -8
  63. package/lib/types/common/index.d.ts +0 -3
  64. package/lib/types/common/io.d.ts +66 -258
  65. package/lib/types/constants.d.ts +11 -18
  66. package/lib/types/solana/ant-readable.d.ts +180 -0
  67. package/lib/types/solana/ant-registry-readable.d.ts +105 -0
  68. package/lib/types/solana/ant-registry-writeable.d.ts +249 -0
  69. package/lib/types/solana/ant-writeable.d.ts +177 -0
  70. package/lib/types/solana/ata.d.ts +44 -0
  71. package/lib/types/solana/canonical-message.d.ts +121 -0
  72. package/lib/types/solana/clusters.d.ts +109 -0
  73. package/lib/types/solana/constants.d.ts +119 -0
  74. package/lib/types/solana/delegation-math.d.ts +45 -0
  75. package/lib/types/solana/deserialize.d.ts +262 -0
  76. package/lib/types/solana/escrow.d.ts +480 -0
  77. package/lib/types/solana/events.d.ts +38 -0
  78. package/lib/types/solana/funding-plan.d.ts +225 -0
  79. package/lib/types/solana/index.d.ts +87 -0
  80. package/lib/types/solana/instruction.d.ts +39 -0
  81. package/lib/types/solana/io-readable.d.ts +499 -0
  82. package/lib/types/solana/io-writeable.d.ts +893 -0
  83. package/lib/types/solana/json-rpc.d.ts +47 -0
  84. package/lib/types/solana/metadata.d.ts +84 -0
  85. package/lib/types/solana/mpl-core.d.ts +120 -0
  86. package/lib/types/solana/pda.d.ts +95 -0
  87. package/lib/types/solana/predict-prescribed-observers.d.ts +28 -0
  88. package/lib/types/solana/retry.d.ts +62 -0
  89. package/lib/types/solana/rpc-circuit-breaker.d.ts +78 -0
  90. package/lib/types/solana/send.d.ts +94 -0
  91. package/lib/types/solana/spawn-ant.d.ts +145 -0
  92. package/lib/types/solana/types.d.ts +82 -0
  93. package/lib/types/types/ant-registry.d.ts +43 -4
  94. package/lib/types/types/ant.d.ts +114 -96
  95. package/lib/types/types/common.d.ts +18 -74
  96. package/lib/types/types/faucet.d.ts +2 -2
  97. package/lib/types/types/io.d.ts +244 -158
  98. package/lib/types/types/token.d.ts +0 -12
  99. package/lib/types/utils/ant.d.ts +1 -12
  100. package/lib/types/utils/index.d.ts +0 -3
  101. package/lib/types/version.d.ts +1 -1
  102. package/package.json +36 -33
  103. package/lib/cjs/cli/cli.js +0 -822
  104. package/lib/cjs/cli/commands/antCommands.js +0 -113
  105. package/lib/cjs/cli/commands/arnsPurchaseCommands.js +0 -212
  106. package/lib/cjs/cli/commands/gatewayWriteCommands.js +0 -210
  107. package/lib/cjs/cli/commands/readCommands.js +0 -215
  108. package/lib/cjs/cli/commands/transfer.js +0 -159
  109. package/lib/cjs/cli/options.js +0 -470
  110. package/lib/cjs/cli/types.js +0 -2
  111. package/lib/cjs/cli/utils.js +0 -639
  112. package/lib/cjs/common/ant-registry.js +0 -155
  113. package/lib/cjs/common/ant-versions.js +0 -93
  114. package/lib/cjs/common/ant.js +0 -1182
  115. package/lib/cjs/common/arweave.js +0 -27
  116. package/lib/cjs/common/contracts/ao-process.js +0 -224
  117. package/lib/cjs/common/error.js +0 -64
  118. package/lib/cjs/common/faucet.js +0 -150
  119. package/lib/cjs/common/hyperbeam/hb.js +0 -173
  120. package/lib/cjs/common/index.js +0 -42
  121. package/lib/cjs/common/io.js +0 -1423
  122. package/lib/cjs/common/logger.js +0 -83
  123. package/lib/cjs/common/loggers/winston.js +0 -68
  124. package/lib/cjs/common/marketplace.js +0 -731
  125. package/lib/cjs/common/turbo.js +0 -223
  126. package/lib/cjs/constants.js +0 -41
  127. package/lib/cjs/node/index.js +0 -39
  128. package/lib/cjs/package.json +0 -1
  129. package/lib/cjs/types/ant-registry.js +0 -2
  130. package/lib/cjs/types/ant.js +0 -168
  131. package/lib/cjs/types/common.js +0 -2
  132. package/lib/cjs/types/faucet.js +0 -2
  133. package/lib/cjs/types/index.js +0 -37
  134. package/lib/cjs/types/io.js +0 -51
  135. package/lib/cjs/types/token.js +0 -116
  136. package/lib/cjs/utils/ant.js +0 -108
  137. package/lib/cjs/utils/ao.js +0 -432
  138. package/lib/cjs/utils/arweave.js +0 -285
  139. package/lib/cjs/utils/base64.js +0 -62
  140. package/lib/cjs/utils/hash.js +0 -56
  141. package/lib/cjs/utils/index.js +0 -38
  142. package/lib/cjs/utils/processes.js +0 -173
  143. package/lib/cjs/utils/random.js +0 -30
  144. package/lib/cjs/utils/schema.js +0 -15
  145. package/lib/cjs/utils/url.js +0 -37
  146. package/lib/cjs/version.js +0 -20
  147. package/lib/cjs/web/index.js +0 -41
  148. package/lib/esm/common/ant-versions.js +0 -87
  149. package/lib/esm/common/arweave.js +0 -21
  150. package/lib/esm/common/contracts/ao-process.js +0 -220
  151. package/lib/esm/common/hyperbeam/hb.js +0 -169
  152. package/lib/esm/common/marketplace.js +0 -724
  153. package/lib/esm/common/turbo.js +0 -215
  154. package/lib/esm/node/index.js +0 -20
  155. package/lib/esm/utils/ao.js +0 -420
  156. package/lib/esm/utils/arweave.js +0 -271
  157. package/lib/esm/utils/processes.js +0 -167
  158. package/lib/esm/web/index.js +0 -20
  159. package/lib/types/common/ant-versions.d.ts +0 -39
  160. package/lib/types/common/arweave.d.ts +0 -17
  161. package/lib/types/common/contracts/ao-process.d.ts +0 -47
  162. package/lib/types/common/hyperbeam/hb.d.ts +0 -88
  163. package/lib/types/common/marketplace.d.ts +0 -568
  164. package/lib/types/common/turbo.d.ts +0 -61
  165. package/lib/types/node/index.d.ts +0 -20
  166. package/lib/types/utils/ao.d.ts +0 -80
  167. package/lib/types/utils/arweave.d.ts +0 -79
  168. package/lib/types/utils/processes.d.ts +0 -39
  169. package/lib/types/web/index.d.ts +0 -20
package/README.md CHANGED
@@ -2,7 +2,11 @@
2
2
 
3
3
  [![codecov](https://codecov.io/gh/ar-io/ar-io-sdk/graph/badge.svg?token=7dXKcT7dJy)](https://codecov.io/gh/ar-io/ar-io-sdk)
4
4
 
5
- This is the home of the ar.io SDK. This SDK provides functionality for interacting with the ar.io ecosystem of services (e.g. gateways and observers) and protocols (e.g. ArNS and AO). It is available for both NodeJS and Web environments.
5
+ The Solana-native SDK for the AR.IO network. Provides typed
6
+ client classes (`ARIO`, `ANT`, `ANTRegistry`), PDA helpers,
7
+ deserializers, and escrow primitives for the AR.IO protocol on Solana.
8
+ Codama-generated instruction builders and account decoders are
9
+ supplied by [`@ar.io/solana-contracts`](https://www.npmjs.com/package/@ar.io/solana-contracts).
6
10
 
7
11
  ## Table of Contents
8
12
 
@@ -14,9 +18,11 @@ This is the home of the ar.io SDK. This SDK provides functionality for interacti
14
18
  - [Usage](#usage)
15
19
  - [ARIO Contract](#ario-contract)
16
20
  - [ANT Contracts](#ant-contracts)
21
+ - [Escrow](#escrow)
17
22
  - [Token Conversion](#token-conversion)
18
23
  - [Logging](#logging)
19
24
  - [Pagination](#pagination)
25
+ - [Advanced](#advanced)
20
26
  - [Resources](#resources)
21
27
  - [Developers](#developers)
22
28
 
@@ -24,7 +30,7 @@ This is the home of the ar.io SDK. This SDK provides functionality for interacti
24
30
 
25
31
  ## Installation
26
32
 
27
- Requires `node>=v18.0.0`
33
+ Requires `node>=v18.0.0`.
28
34
 
29
35
  ```shell
30
36
  npm install @ar.io/sdk
@@ -33,21 +39,49 @@ npm install @ar.io/sdk
33
39
  or
34
40
 
35
41
  ```shell
36
- yarn add @ar.io/sdk --ignore-engines
42
+ yarn add @ar.io/sdk
37
43
  ```
38
44
 
39
- > [!NOTE]
40
- > The `--ignore-engines` flag is required when using yarn, as [permaweb/aoconnect] recommends only the use of npm. Alternatively, you can add a `.yarnrc.yml` file to your project containing `ignore-engines true` to ignore the engines check.
41
-
42
45
  ## Quick Start
43
46
 
44
47
  ```typescript
45
- import { ARIO } from "@ar.io/sdk";
48
+ import { ARIO } from '@ar.io/sdk';
49
+ import { createSolanaRpc } from '@solana/kit';
46
50
 
47
- const ario = ARIO.mainnet(); // defaults to mainnet
51
+ const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
52
+ const ario = ARIO.init({ rpc });
48
53
  const gateways = await ario.getGateways();
49
54
  ```
50
55
 
56
+ Write operations need a `@solana/kit` signer plus an `rpcSubscriptions`
57
+ client (used by kit's `sendAndConfirmTransaction`):
58
+
59
+ ```typescript
60
+ import { ARIO } from '@ar.io/sdk';
61
+ import {
62
+ createSolanaRpc,
63
+ createSolanaRpcSubscriptions,
64
+ createKeyPairSignerFromBytes,
65
+ } from '@solana/kit';
66
+ import { readFileSync } from 'node:fs';
67
+
68
+ const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
69
+ const rpcSubscriptions = createSolanaRpcSubscriptions(
70
+ 'wss://api.mainnet-beta.solana.com',
71
+ );
72
+ const signer = await createKeyPairSignerFromBytes(
73
+ new Uint8Array(JSON.parse(readFileSync('keypair.json', 'utf8'))),
74
+ );
75
+
76
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
77
+ await ario.buyRecord({
78
+ name: 'foo',
79
+ type: 'lease',
80
+ years: 1,
81
+ processId: '<ANT mint pubkey>',
82
+ });
83
+ ```
84
+
51
85
  <details>
52
86
  <summary>Output</summary>
53
87
 
@@ -58,7 +92,13 @@ const gateways = await ario.getGateways();
58
92
  "gatewayAddress": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
59
93
  "observerAddress": "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs",
60
94
  "operatorStake": 250000000000,
95
+ "totalDelegatedStake": 0,
61
96
  "settings": {
97
+ "allowDelegatedStaking": true,
98
+ "allowedDelegates": [],
99
+ "autoStake": false,
100
+ "delegateRewardShareRatio": 10,
101
+ "minDelegatedStake": 100000000,
62
102
  "fqdn": "ar-io.dev",
63
103
  "label": "ar.io Test",
64
104
  "note": "Test Gateway operated by PDS for the ar.io ecosystem.",
@@ -67,28 +107,33 @@ const gateways = await ario.getGateways();
67
107
  "protocol": "https"
68
108
  },
69
109
  "startTimestamp": 1720720621424,
110
+ "endTimestamp": 0,
70
111
  "stats": {
112
+ "passedConsecutiveEpochs": 30,
71
113
  "failedConsecutiveEpochs": 0,
72
- "passedEpochCount": 30,
73
- "submittedEpochCount": 30,
74
114
  "totalEpochCount": 31,
75
- "totalEpochsPrescribedCount": 31
115
+ "passedEpochCount": 30,
116
+ "failedEpochCount": 1,
117
+ "observedEpochCount": 30,
118
+ "prescribedEpochCount": 31
76
119
  },
77
120
  "status": "joined",
78
- "vaults": {},
79
121
  "weights": {
80
- "compositeWeight": 0.97688888893556,
81
- "gatewayPerformanceRatio": 1,
122
+ "stakeWeight": 5.02400000024,
82
123
  "tenureWeight": 0.19444444444444,
124
+ "gatewayPerformanceRatio": 1,
125
+ "observerPerformanceRatio": 1,
126
+ "gatewayRewardRatioWeight": 1,
83
127
  "observerRewardRatioWeight": 1,
84
- "normalizedCompositeWeight": 0.19247316211083,
85
- "stakeWeight": 5.02400000024
128
+ "compositeWeight": 0.97688888893556,
129
+ "normalizedCompositeWeight": 0.19247316211083
86
130
  }
87
131
  }
88
132
  ],
89
133
  "hasMore": true,
90
134
  "nextCursor": "-4xgjroXENKYhTWqrBo57HQwvDL51mMdfsdsxJy6Y2Z_sA",
91
135
  "totalItems": 316,
136
+ "limit": 100,
92
137
  "sortBy": "startTimestamp",
93
138
  "sortOrder": "desc"
94
139
  }
@@ -98,88 +143,92 @@ const gateways = await ario.getGateways();
98
143
 
99
144
  ## Usage
100
145
 
101
- The SDK is provided in both CommonJS and ESM formats and is compatible with bundlers such as Webpack, Rollup, and ESbuild. Utilize the appropriately named exports provided by this SDK's [package.json] based on your project's configuration. Refer to the [examples] directory to see how to use the SDK in various environments.
146
+ The SDK is published as an ES module (`"type": "module"`) and is
147
+ compatible with modern bundlers such as Webpack, Rollup, ESbuild, and
148
+ Vite. CommonJS consumers should migrate to ESM (Node 18+ supports ESM
149
+ natively). Refer to the [examples] directory to see how to use the SDK
150
+ in various environments.
151
+
152
+ ### Subpath exports
153
+
154
+ - `@ar.io/sdk` — main entry. `ARIO`, `ANT`, `ANTRegistry`, Solana
155
+ client classes, PDA helpers, deserializers, escrow primitives.
156
+ - `@ar.io/sdk/solana` — alias of the main entry (kept for one release
157
+ while consumers migrate from the previous subpath layout).
102
158
 
103
159
  ### Web
104
160
 
105
161
  > [!WARNING]
106
- > Polyfills are not provided by default for bundled web projects (Vite, ESBuild, Webpack, Rollup, etc.) . Depending on your apps bundler configuration and plugins, you will need to provide polyfills for various imports including `crypto`, `process` and `buffer`. Refer to [examples/webpack] and [examples/vite] for examples. For other project configurations, refer to your bundler's documentation for more information on how to provide the necessary polyfills.
107
-
108
- #### Bundlers (Webpack, Rollup, ESbuild, etc.)
162
+ > Polyfills are not provided by default for bundled web projects (Vite,
163
+ > ESBuild, Webpack, Rollup, etc.). Depending on your bundler config, you
164
+ > will need polyfills for `crypto`, `process` and `buffer`. Refer to
165
+ > [examples/webpack] and [examples/vite] for examples.
109
166
 
110
167
  ```javascript
111
- import { ARIO } from "@ar.io/sdk/web";
168
+ import { ARIO } from '@ar.io/sdk';
169
+ import { createSolanaRpc } from '@solana/kit';
112
170
 
113
- // set up client
114
- const ario = ARIO.mainnet();
115
- // fetch gateways
171
+ const ario = ARIO.init({
172
+ rpc: createSolanaRpc('https://api.mainnet-beta.solana.com'),
173
+ });
116
174
  const gateways = await ario.getGateways();
117
175
  ```
118
176
 
119
- #### Browser
177
+ ### Browser bundle
120
178
 
121
179
  ```html
122
180
  <script type="module">
123
- // replace <version> with a release version (e.g. 3.8.4)
124
- import { ARIO } from "https://github.com/ar-io/ar-io-sdk/releases/download/v<version>/web.bundle.min.js";
181
+ // replace <version> with a release version
182
+ import { ARIO } from 'https://github.com/ar-io/ar-io-sdk/releases/download/v<version>/web.bundle.min.js';
183
+ import { createSolanaRpc } from 'https://esm.sh/@solana/kit@6';
125
184
 
126
- // set up client
127
- const ario = ARIO.mainnet();
128
- // fetch gateways
185
+ const ario = ARIO.init({
186
+ rpc: createSolanaRpc('https://api.mainnet-beta.solana.com'),
187
+ });
129
188
  const gateways = await ario.getGateways();
130
189
  </script>
131
190
  ```
132
191
 
133
- ### Node
134
-
135
- #### ESM (NodeNext)
136
-
137
- ```javascript
138
- import { ARIO } from "@ar.io/sdk/node";
139
-
140
- // set up client
141
- const ario = ARIO.mainnet();
142
- // fetch gateways
143
- const gateways = await ario.getGateways();
144
- ```
145
-
146
- #### CJS
147
-
148
- ```javascript
149
- import { ARIO } from "@ar.io/sdk";
150
-
151
- // set up client
152
- const ario = ARIO.mainnet();
153
- // fetch gateways
154
- const gateways = await ario.getGateways();
155
- ```
156
-
157
- ### Typescript
192
+ ### TypeScript
158
193
 
159
- The SDK provides TypeScript types. When you import the SDK in a TypeScript project types are exported from `./lib/types/[node/web]/index.d.ts` and should be automatically recognized by package managers, offering benefits such as type-checking and autocompletion.
194
+ The SDK ships TypeScript types alongside the JS output. Types are
195
+ exported from `./lib/types/solana/index.d.ts` and resolve automatically
196
+ for ESM consumers.
160
197
 
161
198
  > [!NOTE]
162
- > Typescript version 5.3 or higher is recommended.
199
+ > TypeScript 5.3+ is recommended (the SDK uses `nodenext` module
200
+ > resolution with `.js` extensions in relative imports).
163
201
 
164
202
  ## ARIO Contract
165
203
 
166
204
  ### General
167
205
 
168
- #### `init({ signer })`
206
+ #### `init({ rpc, rpcSubscriptions?, signer? })`
169
207
 
170
- Factory function to that creates a read-only or writeable client. By providing a `signer` additional write APIs that require signing, like `joinNetwork` and `delegateStake` are available. By default, a read-only client is returned and no write APIs are available.
208
+ Factory function that creates a read-only or writeable ARIO client.
209
+ Providing `signer` plus `rpcSubscriptions` enables write methods
210
+ (`joinNetwork`, `delegateStake`, `buyRecord`, etc.). Without a signer,
211
+ the client is read-only.
171
212
 
172
213
  ```typescript
173
- // read-only client
174
- const ario = ARIO.init();
214
+ import { ARIO } from '@ar.io/sdk';
215
+ import {
216
+ createSolanaRpc,
217
+ createSolanaRpcSubscriptions,
218
+ createKeyPairSignerFromBytes,
219
+ } from '@solana/kit';
175
220
 
176
- // read-write client for browser environments
177
- const ario = ARIO.init({
178
- signer: new ArConnectSigner(window.arweaveWallet, Arweave.init({})),
179
- });
221
+ const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
180
222
 
181
- // read-write client for node environments
182
- const ario = ARIO.init({ signer: new ArweaveSigner(JWK) });
223
+ // read-only client
224
+ const ario = ARIO.init({ rpc });
225
+
226
+ // read-write client (needs rpcSubscriptions for sendAndConfirm)
227
+ const rpcSubscriptions = createSolanaRpcSubscriptions(
228
+ 'wss://api.mainnet-beta.solana.com',
229
+ );
230
+ const signer = await createKeyPairSignerFromBytes(/* 64-byte secret key */);
231
+ const arioWrite = ARIO.init({ rpc, rpcSubscriptions, signer });
183
232
  ```
184
233
 
185
234
  #### `getInfo()`
@@ -187,7 +236,7 @@ const ario = ARIO.init({ signer: new ArweaveSigner(JWK) });
187
236
  Retrieves the information of the ARIO process.
188
237
 
189
238
  ```typescript
190
- const ario = ARIO.mainnet();
239
+ const ario = ARIO.init({ rpc });
191
240
  const info = await ario.getInfo();
192
241
  ```
193
242
 
@@ -196,16 +245,29 @@ const info = await ario.getInfo();
196
245
 
197
246
  ```json
198
247
  {
199
- "Name": "ARIO",
248
+ "Name": "AR.IO",
200
249
  "Ticker": "ARIO",
201
- "Owner": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
250
+ "Logo": "",
202
251
  "Denomination": 6,
203
- "Handlers": ["_eval", "_default_"], // full list of handlers, useful for debugging
204
- "LastCreatedEpochIndex": 31, // epoch index of the last tick
205
- "LastDistributedEpochIndex": 31 // epoch index of the last distribution
252
+ "Handlers": [],
253
+ "LastCreatedEpochIndex": 0,
254
+ "LastDistributedEpochIndex": 0,
255
+ "totalSupply": 1000000000000000,
256
+ "protocolBalance": 0,
257
+ "epochSettings": {
258
+ "durationMs": 86400000,
259
+ "prescribedNameCount": 25,
260
+ "maxObservers": 50
261
+ }
206
262
  }
207
263
  ```
208
264
 
265
+ > **Note**: `Handlers`, `LastCreatedEpochIndex`, and `LastDistributedEpochIndex`
266
+ > are placeholders on Solana (returned for backwards-compatible field shape
267
+ > with consumer code). `totalSupply` / `protocolBalance` are live reads from
268
+ > the `ArioConfig` PDA; `epochSettings` is live from the `EpochSettings`
269
+ > PDA. See `src/solana/io-readable.ts` for the exact projection.
270
+
209
271
  </details>
210
272
 
211
273
  #### `getTokenSupply()`
@@ -221,7 +283,7 @@ Retrieves the total supply of tokens, returned in mARIO. The total supply includ
221
283
  - `protocolBalance` - tokens that are held in the protocol's treasury. This is included in the circulating supply.
222
284
 
223
285
  ```typescript
224
- const ario = ARIO.mainnet();
286
+ const ario = ARIO.init({ rpc });
225
287
  const supply = await ario.getTokenSupply();
226
288
  ```
227
289
 
@@ -247,7 +309,7 @@ const supply = await ario.getTokenSupply();
247
309
  Retrieves the balance of the specified wallet address.
248
310
 
249
311
  ```typescript
250
- const ario = ARIO.mainnet();
312
+ const ario = ARIO.init({ rpc });
251
313
  // the balance will be returned in mARIO as a value
252
314
  const balance = await ario
253
315
  .getBalance({
@@ -270,7 +332,7 @@ const balance = await ario
270
332
  Retrieves the balances of the ARIO process in `mARIO`, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last wallet address from the previous request.
271
333
 
272
334
  ```typescript
273
- const ario = ARIO.mainnet();
335
+ const ario = ARIO.init({ rpc });
274
336
  const balances = await ario.getBalances({
275
337
  cursor: "-4xgjroXENKYhTWqrBo57HQwvDL51mMdfsdsxJy6Y2Z_sA",
276
338
  limit: 100,
@@ -312,59 +374,49 @@ Transfers `mARIO` to the designated `target` recipient address. Requires `signer
312
374
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
313
375
 
314
376
  ```typescript
315
- const ario = ARIO.mainnet({
316
- signer: new ArweaveSigner(jwk),
377
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
378
+ const { id: txId } = await ario.transfer({
379
+ target: 'RecipientSolanaPubkeyBase58',
380
+ qty: new ARIOToken(1000).toMARIO(),
317
381
  });
318
- const { id: txId } = await ario.transfer(
319
- {
320
- target: "-5dV7nk7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5",
321
- qty: new ARIOToken(1000).toMARIO(),
322
- },
323
- // optional additional tags
324
- { tags: [{ name: "App-Name", value: "My-Awesome-App" }] },
325
- );
326
382
  ```
327
383
 
328
384
  ### Networks
329
385
 
330
- The SDK provides the following process IDs for the mainnet and testnet environments:
331
-
332
- - `ARIO_MAINNET_PROCESS_ID` - Mainnet ARIO process ID (production)
333
- - `ARIO_TESTNET_PROCESS_ID` - Testnet ARIO process ID (testing and development)
334
- - `ARIO_DEVNET_PROCESS_ID` - Devnet ARIO process ID (development)
335
-
336
- As of `v3.8.1` the SDK defaults all API interactions to **mainnet**. To use the **testnet** or **devnet** provide the appropriate `ARIO_TESTNET_PROCESS_ID` or `ARIO_DEVNET_PROCESS_ID` when initializing the client.
337
-
338
- #### Mainnet
339
-
340
- As of `v3.8.1` the SDK defaults all API interactions to **mainnet**. To use the **testnet** or **devnet** provide the appropriate `ARIO_TESTNET_PROCESS_ID` or `ARIO_DEVNET_PROCESS_ID` when initializing the client.
386
+ The SDK talks to whatever cluster your `@solana/kit` RPC client points
387
+ at — mainnet-beta by default. For devnet or a local validator, override
388
+ the RPC URL and (on any non-mainnet cluster) the per-program addresses:
341
389
 
342
390
  ```typescript
343
- import { ARIO } from "@ar.io/sdk";
391
+ import { ARIO } from '@ar.io/sdk';
392
+ import { createSolanaRpc, address } from '@solana/kit';
344
393
 
345
- const ario = ARIO.mainnet(); // or ARIO.init()
394
+ const ario = ARIO.init({
395
+ rpc: createSolanaRpc('https://api.devnet.solana.com'),
396
+ coreProgramId: address('<ARIO_CORE_PROGRAM_ID>'),
397
+ garProgramId: address('<ARIO_GAR_PROGRAM_ID>'),
398
+ arnsProgramId: address('<ARIO_ARNS_PROGRAM_ID>'),
399
+ antProgramId: address('<ARIO_ANT_PROGRAM_ID>'),
400
+ });
346
401
  ```
347
402
 
348
- #### Testnet
349
-
350
- ```typescript
351
- import { ARIO } from "@ar.io/sdk";
352
-
353
- const testnet = ARIO.testnet(); // or ARIO.init({ processId: ARIO_TESTNET_PROCESS_ID })
354
- ```
403
+ On localnet (Surfpool) source program IDs from
404
+ `migration/localnet/out/localnet.env` in the `solana-ar-io` monorepo.
355
405
 
356
406
  ##### Faucet
357
407
 
358
- The SDK provides APIs for claiming tokens via a faucet on the ar.io Testnet process (`tARIO`) via the [ar-io-testnet-faucet] service. All token requests require a captcha to be solved, and the faucet is rate limited to prevent abuse.
359
-
360
- To claim testnet tokens from the testnet token faucet, you can use one of the following methods:
361
-
362
- 1. Visit [faucet.ar.io](https://faucet.ar.io) - the easiest way to quickly get tokens for testing for a single address.
408
+ The SDK exposes a `createFaucet` HTTP wrapper around the ar.io faucet
409
+ service ([faucet.ar.io](https://faucet.ar.io)). The faucet backend has
410
+ not yet been ported to issue Solana-mint transfers the SDK surface is
411
+ documented here for forward-compatibility once it lands:
363
412
 
364
- 2. Programmatically via the SDK - useful if you need to claim tokens for multiple addresses or dynamically within your application.
365
- - `ARIO.testnet().faucet.captchaUrl()` - returns the captcha URL for the testnet faucet. Open this URL in a new browser window and listen for the `ario-jwt-success` event to be emitted.
366
- - `ARIO.testnet().faucet.claimWithAuthToken({ authToken, recipient, quantity })` - claims tokens for the specified recipient address using the provided auth token.
367
- - `ARIO.testnet().faucet.verifyAuthToken({ authToken })` - verifies if the provided auth token is still valid.
413
+ - `createFaucet({ arioInstance, processId }).captchaUrl()` returns
414
+ the captcha URL.
415
+ - `createFaucet({ arioInstance, processId }).claimWithAuthToken({ authToken, recipient, quantity })`
416
+ claim tokens for `recipient` using an auth token returned by the
417
+ captcha flow.
418
+ - `createFaucet({ arioInstance, processId }).verifyAuthToken({ authToken })` —
419
+ check whether an auth token is still valid.
368
420
 
369
421
  <details>
370
422
  <summary><i>Example client-side code for claiming tokens</i></summary>
@@ -372,7 +424,7 @@ To claim testnet tokens from the testnet token faucet, you can use one of the fo
372
424
  ```typescript
373
425
  import { ARIO } from "@ar.io/sdk";
374
426
 
375
- const testnet = ARIO.testnet();
427
+ const ario = ARIO.init({ rpc });
376
428
  const captchaUrl = await ario.faucet.captchaUrl();
377
429
 
378
430
  // open the captcha URL in the browser, and listen for the auth token event
@@ -433,7 +485,7 @@ if (
433
485
  Retrieves the locked-balance user vault of the ARIO process by the specified wallet address and vault ID.
434
486
 
435
487
  ```typescript
436
- const ario = ARIO.mainnet();
488
+ const ario = ARIO.init({ rpc });
437
489
  const vault = await ario.getVault({
438
490
  address: "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
439
491
  vaultId: "vaultIdOne",
@@ -458,7 +510,7 @@ const vault = await ario.getVault({
458
510
  Retrieves all locked-balance user vaults of the ARIO process, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last wallet address from the previous request.
459
511
 
460
512
  ```typescript
461
- const ario = ARIO.mainnet();
513
+ const ario = ARIO.init({ rpc });
462
514
  const vaults = await ario.getVaults({
463
515
  cursor: "0",
464
516
  limit: 100,
@@ -506,7 +558,7 @@ Transfers `mARIO` to the designated `recipient` address and locks the balance fo
506
558
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
507
559
 
508
560
  ```typescript
509
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
561
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
510
562
  const { id: txId } = await ario.vaultedTransfer(
511
563
  {
512
564
  recipient: "-5dV7nk7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5",
@@ -526,7 +578,7 @@ Revokes a vaulted transfer by the recipient address and vault ID. Only the sende
526
578
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
527
579
 
528
580
  ```typescript
529
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
581
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
530
582
  const { id: txId } = await ario.revokeVault({
531
583
  recipient: "-5dV7nk7waR8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5",
532
584
  vaultId: "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs",
@@ -538,7 +590,7 @@ const { id: txId } = await ario.revokeVault({
538
590
  Creates a vault for the specified `quantity` of mARIO from the signer's balance and locks it for the specified `lockLengthMs` milliseconds.
539
591
 
540
592
  ```typescript
541
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
593
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
542
594
 
543
595
  const { id: txId } = await ario.createVault({
544
596
  lockLengthMs: 1000 * 60 * 60 * 24 * 365, // 1 year
@@ -551,7 +603,7 @@ const { id: txId } = await ario.createVault({
551
603
  Extends the lock length of a signer's vault by the specified `extendLengthMs` milliseconds.
552
604
 
553
605
  ```typescript
554
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
606
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
555
607
 
556
608
  const { id: txId } = await ario.extendVault({
557
609
  vaultId: "vaultIdOne",
@@ -564,7 +616,7 @@ const { id: txId } = await ario.extendVault({
564
616
  Increases the balance of a signer's vault by the specified `quantity` of mARIO.
565
617
 
566
618
  ```typescript
567
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
619
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
568
620
  const { id: txId } = await ario.increaseVault({
569
621
  vaultId: "vaultIdOne",
570
622
  quantity: new ARIOToken(1000).toMARIO(),
@@ -578,7 +630,7 @@ const { id: txId } = await ario.increaseVault({
578
630
  Retrieves a gateway's info by its staking wallet address.
579
631
 
580
632
  ```typescript
581
- const ario = ARIO.mainnet();
633
+ const ario = ARIO.init({ rpc });
582
634
  const gateway = await ario.getGateway({
583
635
  address: "-7vXsQZQDk8TMDlpiSLy3CnLi5PDPlAaN2DaynORpck",
584
636
  });
@@ -591,7 +643,13 @@ const gateway = await ario.getGateway({
591
643
  {
592
644
  "observerAddress": "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs",
593
645
  "operatorStake": 250000000000,
646
+ "totalDelegatedStake": 0,
594
647
  "settings": {
648
+ "allowDelegatedStaking": true,
649
+ "allowedDelegates": [],
650
+ "autoStake": false,
651
+ "delegateRewardShareRatio": 10,
652
+ "minDelegatedStake": 100000000,
595
653
  "fqdn": "ar-io.dev",
596
654
  "label": "ar.io Test",
597
655
  "note": "Test Gateway operated by PDS for the ar.io ecosystem.",
@@ -600,22 +658,26 @@ const gateway = await ario.getGateway({
600
658
  "protocol": "https"
601
659
  },
602
660
  "startTimestamp": 1720720620813,
661
+ "endTimestamp": 0,
603
662
  "stats": {
663
+ "passedConsecutiveEpochs": 30,
604
664
  "failedConsecutiveEpochs": 0,
605
- "passedEpochCount": 30,
606
- "submittedEpochCount": 30,
607
665
  "totalEpochCount": 31,
608
- "totalEpochsPrescribedCount": 31
666
+ "passedEpochCount": 30,
667
+ "failedEpochCount": 1,
668
+ "observedEpochCount": 30,
669
+ "prescribedEpochCount": 31
609
670
  },
610
671
  "status": "joined",
611
- "vaults": {},
612
672
  "weights": {
613
- "compositeWeight": 0.97688888893556,
614
- "gatewayPerformanceRatio": 1,
673
+ "stakeWeight": 5.02400000024,
615
674
  "tenureWeight": 0.19444444444444,
675
+ "gatewayPerformanceRatio": 1,
676
+ "observerPerformanceRatio": 1,
677
+ "gatewayRewardRatioWeight": 1,
616
678
  "observerRewardRatioWeight": 1,
617
- "normalizedCompositeWeight": 0.19247316211083,
618
- "stakeWeight": 5.02400000024
679
+ "compositeWeight": 0.97688888893556,
680
+ "normalizedCompositeWeight": 0.19247316211083
619
681
  }
620
682
  }
621
683
  ```
@@ -627,7 +689,7 @@ const gateway = await ario.getGateway({
627
689
  Retrieves registered gateways of the ARIO process, using pagination and sorting by the specified criteria. The `cursor` used for pagination is the last gateway address from the previous request.
628
690
 
629
691
  ```typescript
630
- const ario = ARIO.mainnet();
692
+ const ario = ARIO.init({ rpc });
631
693
  const gateways = await ario.getGateways({
632
694
  limit: 100,
633
695
  sortOrder: "desc",
@@ -647,7 +709,13 @@ Available `sortBy` options are any of the keys on the gateway object, e.g. `oper
647
709
  "gatewayAddress": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
648
710
  "observerAddress": "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs",
649
711
  "operatorStake": 250000000000,
712
+ "totalDelegatedStake": 0,
650
713
  "settings": {
714
+ "allowDelegatedStaking": true,
715
+ "allowedDelegates": [],
716
+ "autoStake": false,
717
+ "delegateRewardShareRatio": 10,
718
+ "minDelegatedStake": 100000000,
651
719
  "fqdn": "ar-io.dev",
652
720
  "label": "ar.io Test",
653
721
  "note": "Test Gateway operated by PDS for the ar.io ecosystem.",
@@ -656,28 +724,33 @@ Available `sortBy` options are any of the keys on the gateway object, e.g. `oper
656
724
  "protocol": "https"
657
725
  },
658
726
  "startTimestamp": 1720720620813,
727
+ "endTimestamp": 0,
659
728
  "stats": {
729
+ "passedConsecutiveEpochs": 30,
660
730
  "failedConsecutiveEpochs": 0,
661
- "passedEpochCount": 30,
662
- "submittedEpochCount": 30,
663
731
  "totalEpochCount": 31,
664
- "totalEpochsPrescribedCount": 31
732
+ "passedEpochCount": 30,
733
+ "failedEpochCount": 1,
734
+ "observedEpochCount": 30,
735
+ "prescribedEpochCount": 31
665
736
  },
666
737
  "status": "joined",
667
- "vaults": {},
668
738
  "weights": {
669
- "compositeWeight": 0.97688888893556,
670
- "gatewayPerformanceRatio": 1,
739
+ "stakeWeight": 5.02400000024,
671
740
  "tenureWeight": 0.19444444444444,
741
+ "gatewayPerformanceRatio": 1,
742
+ "observerPerformanceRatio": 1,
743
+ "gatewayRewardRatioWeight": 1,
672
744
  "observerRewardRatioWeight": 1,
673
- "normalizedCompositeWeight": 0.19247316211083,
674
- "stakeWeight": 5.02400000024
745
+ "compositeWeight": 0.97688888893556,
746
+ "normalizedCompositeWeight": 0.19247316211083
675
747
  }
676
748
  }
677
749
  ],
678
750
  "hasMore": true,
679
751
  "nextCursor": "-4xgjroXENKYhTWqrBo57HQwvDL51mMdfsdsxJy6Y2Z_sA",
680
752
  "totalItems": 316,
753
+ "limit": 100,
681
754
  "sortBy": "operatorStake",
682
755
  "sortOrder": "desc"
683
756
  }
@@ -690,7 +763,7 @@ Available `sortBy` options are any of the keys on the gateway object, e.g. `oper
690
763
  Retrieves all delegates for a specific gateway, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last delegate address from the previous request.
691
764
 
692
765
  ```typescript
693
- const ario = ARIO.mainnet();
766
+ const ario = ARIO.init({ rpc });
694
767
  const delegates = await ario.getGatewayDelegates({
695
768
  address: "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
696
769
  limit: 3,
@@ -739,7 +812,7 @@ Joins a gateway to the ar.io network via its associated wallet.
739
812
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
740
813
 
741
814
  ```typescript
742
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
815
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
743
816
  const { id: txId } = await ario.joinNetwork(
744
817
  {
745
818
  qty: new ARIOToken(10_000).toMARIO(), // minimum operator stake allowed
@@ -767,7 +840,7 @@ Sets the gateway as `leaving` on the ar.io network. Requires `signer` to be prov
767
840
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
768
841
 
769
842
  ```typescript
770
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
843
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
771
844
 
772
845
  const { id: txId } = await ario.leaveNetwork(
773
846
  // optional additional tags
@@ -782,7 +855,7 @@ Writes new gateway settings to the callers gateway configuration.
782
855
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
783
856
 
784
857
  ```typescript
785
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
858
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
786
859
  const { id: txId } = await ario.updateGatewaySettings(
787
860
  {
788
861
  // any other settings you want to update
@@ -800,7 +873,7 @@ Increases the callers stake on the target gateway.
800
873
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
801
874
 
802
875
  ```typescript
803
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
876
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
804
877
  const { id: txId } = await ario.increaseDelegateStake(
805
878
  {
806
879
  target: "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
@@ -818,7 +891,7 @@ Decreases the callers stake on the target gateway. Can instantly decrease stake
818
891
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
819
892
 
820
893
  ```typescript
821
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
894
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
822
895
  const { id: txId } = await ario.decreaseDelegateStake(
823
896
  {
824
897
  target: "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
@@ -833,7 +906,7 @@ const { id: txId } = await ario.decreaseDelegateStake(
833
906
  Pay the early withdrawal fee and withdraw instantly.
834
907
 
835
908
  ```typescript
836
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
909
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
837
910
  const { id: txId } = await ario.decreaseDelegateStake({
838
911
  target: "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
839
912
  qty: new ARIOToken(100).toMARIO(),
@@ -846,7 +919,7 @@ const { id: txId } = await ario.decreaseDelegateStake({
846
919
  Retrieves all active and vaulted stakes across all gateways for a specific address, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last delegationId (concatenated gateway and startTimestamp of the delgation) from the previous request.
847
920
 
848
921
  ```typescript
849
- const ario = ARIO.mainnet();
922
+ const ario = ARIO.init({ rpc });
850
923
  const vaults = await ario.getDelegations({
851
924
  address: "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
852
925
  cursor: "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ_123456789",
@@ -897,7 +970,7 @@ Instantly withdraws an existing vault on a gateway. If no `gatewayAddress` is pr
897
970
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
898
971
 
899
972
  ```typescript
900
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
973
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
901
974
  // removes a delegated vault from a gateway
902
975
  const { id: txId } = await ario.instantWithdrawal(
903
976
  {
@@ -924,7 +997,7 @@ Cancels an existing vault on a gateway. The vaulted stake will be returned to th
924
997
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
925
998
 
926
999
  ```typescript
927
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
1000
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
928
1001
  // cancels a delegated vault from a gateway
929
1002
  const { id: txId } = await ario.cancelWithdrawal(
930
1003
  {
@@ -948,7 +1021,7 @@ const { id: txId } = await ario.cancelWithdrawal({
948
1021
  Retrieves all allowed delegates for a specific address. The `cursor` used for pagination is the last address from the previous request.
949
1022
 
950
1023
  ```typescript
951
- const ario = ARIO.mainnet();
1024
+ const ario = ARIO.init({ rpc });
952
1025
  const allowedDelegates = await ario.getAllowedDelegates({
953
1026
  address: "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
954
1027
  });
@@ -979,7 +1052,7 @@ const allowedDelegates = await ario.getAllowedDelegates({
979
1052
  Retrieves all vaults across all gateways for a specific address, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last vaultId from the previous request.
980
1053
 
981
1054
  ```typescript
982
- const ario = ARIO.mainnet();
1055
+ const ario = ARIO.init({ rpc });
983
1056
  const vaults = await ario.getGatewayVaults({
984
1057
  address: '"PZ5vIhHf8VY969TxBPQN-rYY9CNFP9ggNsMBqlWUzWM',
985
1058
  });
@@ -1014,7 +1087,7 @@ const vaults = await ario.getGatewayVaults({
1014
1087
  Retrieves all vaults across all gateways, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last vaultId from the previous request.
1015
1088
 
1016
1089
  ```typescript
1017
- const ario = ARIO.mainnet();
1090
+ const ario = ARIO.init({ rpc });
1018
1091
  const vaults = await ario.getAllGatewayVaults({
1019
1092
  limit: 1,
1020
1093
  sortBy: "endTimestamp",
@@ -1048,6 +1121,57 @@ const vaults = await ario.getAllGatewayVaults({
1048
1121
 
1049
1122
  </details>
1050
1123
 
1124
+ #### `getWithdrawals({ address, cursor, limit, sortBy, sortOrder })`
1125
+
1126
+ Returns every pending stake withdrawal owned by `address` — covering both operator-stake decreases (`isDelegate: false`) and delegate-stake decreases (`isDelegate: true`). A withdrawal is claimable when `Date.now() >= endTimestamp`; call `claimWithdrawal({ withdrawalId: item.vaultId })` to release the tokens.
1127
+
1128
+ This is the per-owner read needed to drive "you have X claimable withdrawals" UIs without fanning out across every gateway the wallet has interacted with.
1129
+
1130
+ ```typescript
1131
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1132
+
1133
+ const withdrawals = await ario.getWithdrawals({
1134
+ address: "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",
1135
+ });
1136
+
1137
+ const claimable = withdrawals.items.filter(
1138
+ (w) => Date.now() >= w.endTimestamp,
1139
+ );
1140
+ ```
1141
+
1142
+ <details>
1143
+ <summary>Output</summary>
1144
+
1145
+ ```json
1146
+ {
1147
+ "hasMore": false,
1148
+ "totalItems": 2,
1149
+ "limit": 100,
1150
+ "items": [
1151
+ {
1152
+ "cursorId": "8CSdSjf7gXqQ5p1U2qfdwHzVw9sZRYHJpDpV87dnvb4d",
1153
+ "vaultId": "0",
1154
+ "gatewayAddress": "Bxz7Q2tWfqr9Q5T6cZjUnVxRk9CnHwShfgUaW5fY1Mvr",
1155
+ "balance": 50000000000,
1156
+ "startTimestamp": 1735843635857,
1157
+ "endTimestamp": 1738435635857,
1158
+ "isDelegate": true
1159
+ },
1160
+ {
1161
+ "cursorId": "FmWUz4w7vSdLcz1nN8H1n2KkjJgrQQXR1n4kV3WqJ7Hf",
1162
+ "vaultId": "1",
1163
+ "gatewayAddress": "9xQeWvG816bUx9EPjHmaT23yvVM2ZWbrrpZb9PusVFin",
1164
+ "balance": 10000000000,
1165
+ "startTimestamp": 1735843835857,
1166
+ "endTimestamp": 1738435835857,
1167
+ "isDelegate": false
1168
+ }
1169
+ ]
1170
+ }
1171
+ ```
1172
+
1173
+ </details>
1174
+
1051
1175
  #### `increaseOperatorStake({ qty })`
1052
1176
 
1053
1177
  Increases the callers operator stake. Must be executed with a wallet registered as a gateway operator.
@@ -1055,7 +1179,7 @@ Increases the callers operator stake. Must be executed with a wallet registered
1055
1179
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
1056
1180
 
1057
1181
  ```typescript
1058
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
1182
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1059
1183
  const { id: txId } = await ario.increaseOperatorStake(
1060
1184
  {
1061
1185
  qty: new ARIOToken(100).toMARIO(),
@@ -1073,7 +1197,7 @@ Decreases the callers operator stake. Must be executed with a wallet registered
1073
1197
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
1074
1198
 
1075
1199
  ```typescript
1076
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
1200
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1077
1201
  const { id: txId } = await ario.decreaseOperatorStake(
1078
1202
  {
1079
1203
  qty: new ARIOToken(100).toMARIO(),
@@ -1091,7 +1215,7 @@ Redelegates the stake of a specific address to a new gateway. Vault ID may be op
1091
1215
  e.g: If 1000 mARIO is redelegated and the fee rate is 10%, the fee will be 100 mARIO. Resulting in 900 mARIO being redelegated to the new gateway and 100 mARIO being deducted back to the protocol balance.
1092
1216
 
1093
1217
  ```typescript
1094
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
1218
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1095
1219
 
1096
1220
  const { id: txId } = await ario.redelegateStake({
1097
1221
  target: "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
@@ -1106,7 +1230,7 @@ const { id: txId } = await ario.redelegateStake({
1106
1230
  Retrieves the fee rate as percentage required to redelegate the stake of a specific address. Fee rate ranges from 0% to 60% based on the number of redelegations since the last fee reset.
1107
1231
 
1108
1232
  ```typescript
1109
- const ario = ARIO.mainnet();
1233
+ const ario = ARIO.init({ rpc });
1110
1234
 
1111
1235
  const fee = await ario.getRedelegationFee({
1112
1236
  address: "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
@@ -1130,7 +1254,7 @@ const fee = await ario.getRedelegationFee({
1130
1254
  Retrieves all delegates across all gateways, paginated and sorted by the specified criteria. The `cursor` used for pagination is a `cursorId` derived from delegate address and the gatewayAddress from the previous request. e.g `address_gatewayAddress`.
1131
1255
 
1132
1256
  ```typescript
1133
- const ario = ARIO.mainnet();
1257
+ const ario = ARIO.init({ rpc });
1134
1258
  const delegates = await ario.getAllDelegates({
1135
1259
  limit: 2,
1136
1260
  sortBy: "startTimestamp",
@@ -1181,7 +1305,7 @@ Resolves an ArNS name to the underlying data id stored on the names correspondin
1181
1305
  ##### Resolving a base name
1182
1306
 
1183
1307
  ```typescript
1184
- const ario = ARIO.mainnet();
1308
+ const ario = ARIO.init({ rpc });
1185
1309
  const record = await ario.resolveArNSName({ name: "ardrive" });
1186
1310
  ```
1187
1311
 
@@ -1190,13 +1314,12 @@ const record = await ario.resolveArNSName({ name: "ardrive" });
1190
1314
 
1191
1315
  ```json
1192
1316
  {
1317
+ "name": "ardrive",
1193
1318
  "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
1194
1319
  "txId": "kvhEUsIY5bXe0Wu2-YUFz20O078uYFzmQIO-7brv8qw",
1195
1320
  "type": "lease",
1196
- "recordIndex": 0,
1197
- "undernameLimit": 100,
1198
- "owner": "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
1199
- "name": "ardrive"
1321
+ "ttlSeconds": 3600,
1322
+ "undernameLimit": 100
1200
1323
  }
1201
1324
  ```
1202
1325
 
@@ -1205,7 +1328,7 @@ const record = await ario.resolveArNSName({ name: "ardrive" });
1205
1328
  ##### Resolving an undername
1206
1329
 
1207
1330
  ```typescript
1208
- const ario = ARIO.mainnet();
1331
+ const ario = ARIO.init({ rpc });
1209
1332
  const record = await ario.resolveArNSName({ name: "logo_ardrive" });
1210
1333
  ```
1211
1334
 
@@ -1214,13 +1337,12 @@ const record = await ario.resolveArNSName({ name: "logo_ardrive" });
1214
1337
 
1215
1338
  ```json
1216
1339
  {
1340
+ "name": "ardrive",
1217
1341
  "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
1218
1342
  "txId": "kvhEUsIY5bXe0Wu2-YUFz20O078uYFzmQIO-7brv8qw",
1219
1343
  "type": "lease",
1220
- "recordIndex": 1,
1221
- "undernameLimit": 100,
1222
- "owner": "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
1223
- "name": "ardrive"
1344
+ "ttlSeconds": 3600,
1345
+ "undernameLimit": 100
1224
1346
  }
1225
1347
  ```
1226
1348
 
@@ -1241,7 +1363,7 @@ _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
1241
1363
  - `referrer` - _optional_: track purchase referrals for analytics (e.g. `my-app.com`)
1242
1364
 
1243
1365
  ```typescript
1244
- const ario = ARIO.mainnet({ signer });
1366
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1245
1367
  const record = await ario.buyRecord(
1246
1368
  {
1247
1369
  name: "ardrive",
@@ -1279,7 +1401,7 @@ Upgrades an existing leased ArNS record to a permanent ownership. The record mus
1279
1401
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
1280
1402
 
1281
1403
  ```typescript
1282
- const ario = ARIO.mainnet({ signer });
1404
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1283
1405
  const record = await ario.upgradeRecord(
1284
1406
  {
1285
1407
  name: "ardrive",
@@ -1297,7 +1419,7 @@ const record = await ario.upgradeRecord(
1297
1419
  Retrieves the record info of the specified ArNS name.
1298
1420
 
1299
1421
  ```typescript
1300
- const ario = ARIO.mainnet();
1422
+ const ario = ARIO.init({ rpc });
1301
1423
  const record = await ario.getArNSRecord({ name: "ardrive" });
1302
1424
  ```
1303
1425
 
@@ -1307,10 +1429,11 @@ const record = await ario.getArNSRecord({ name: "ardrive" });
1307
1429
  ```json
1308
1430
  {
1309
1431
  "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
1310
- "endTimestamp": 1752256702026,
1311
1432
  "startTimestamp": 1720720819969,
1433
+ "endTimestamp": 1752256702026,
1312
1434
  "type": "lease",
1313
- "undernameLimit": 100
1435
+ "undernameLimit": 100,
1436
+ "purchasePrice": 75541282285
1314
1437
  }
1315
1438
  ```
1316
1439
 
@@ -1321,7 +1444,7 @@ const record = await ario.getArNSRecord({ name: "ardrive" });
1321
1444
  Retrieves all registered ArNS records of the ARIO process, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last ArNS name from the previous request.
1322
1445
 
1323
1446
  ```typescript
1324
- const ario = ARIO.mainnet();
1447
+ const ario = ARIO.init({ rpc });
1325
1448
  // get the newest 100 names
1326
1449
  const records = await ario.getArNSRecords({
1327
1450
  limit: 100,
@@ -1395,12 +1518,12 @@ Available `sortBy` options are any of the keys on the record object, e.g. `name`
1395
1518
 
1396
1519
  </details>
1397
1520
 
1398
- #### `getArNSRecordsForAddress({ address, antRegistryProcessId, cursor, limit, sortBy, sortOrder })`
1521
+ #### `getArNSRecordsForAddress({ address, cursor, limit, sortBy, sortOrder })`
1399
1522
 
1400
1523
  Retrieves all registered ArNS records of the specified address according to the `ANTRegistry` access control list, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last ArNS name from the previous request.
1401
1524
 
1402
1525
  ```typescript
1403
- const ario = ARIO.mainnet();
1526
+ const ario = ARIO.init({ rpc });
1404
1527
  const records = await ario.getArNSRecordsForAddress({
1405
1528
  address: "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
1406
1529
  limit: 100,
@@ -1445,7 +1568,7 @@ Increases the undername support of a domain up to a maximum of 10k. Domains, by
1445
1568
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
1446
1569
 
1447
1570
  ```typescript
1448
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
1571
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1449
1572
  const { id: txId } = await ario.increaseUndernameLimit(
1450
1573
  {
1451
1574
  name: "ar-io",
@@ -1462,7 +1585,7 @@ const { id: txId } = await ario.increaseUndernameLimit(
1462
1585
  Extends the lease of a registered ArNS domain, with an extension of 1-5 years depending on grace period status. Permanently registered domains cannot be extended.
1463
1586
 
1464
1587
  ```typescript
1465
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
1588
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1466
1589
  const { id: txId } = await ario.extendLease(
1467
1590
  {
1468
1591
  name: "ar-io",
@@ -1516,19 +1639,14 @@ const costDetails = await ario.getCostDetails({
1516
1639
 
1517
1640
  ```json
1518
1641
  {
1519
- "tokenCost": 2384252273,
1520
- "fundingPlan": {
1521
- "address": "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
1522
- "balance": 0,
1523
- "stakes": {
1524
- "Rc80LG6h27Y3p9TN6J5hwDeG5M51cu671YwZpU9uAVE": {
1525
- "vaults": [],
1526
- "delegatedStake": 2384252273
1527
- }
1528
- },
1529
- "shortfall": 0
1530
- },
1531
- "discounts": []
1642
+ "tokenCost": 1907401818,
1643
+ "discounts": [
1644
+ {
1645
+ "name": "Gateway Operator",
1646
+ "discountTotal": 476850455,
1647
+ "multiplier": 0.8
1648
+ }
1649
+ ]
1532
1650
  }
1533
1651
  ```
1534
1652
 
@@ -1539,7 +1657,7 @@ const costDetails = await ario.getCostDetails({
1539
1657
  Retrieves the current demand factor of the network. The demand factor is a multiplier applied to the cost of ArNS interactions based on the current network demand.
1540
1658
 
1541
1659
  ```typescript
1542
- const ario = ARIO.mainnet();
1660
+ const ario = ARIO.init({ rpc });
1543
1661
  const demandFactor = await ario.getDemandFactor();
1544
1662
  ```
1545
1663
 
@@ -1557,7 +1675,7 @@ const demandFactor = await ario.getDemandFactor();
1557
1675
  Retrieves all active returned names of the ARIO process, paginated and sorted by the specified criteria. The `cursor` used for pagination is the last returned name from the previous request.
1558
1676
 
1559
1677
  ```typescript
1560
- const ario = ARIO.mainnet();
1678
+ const ario = ARIO.init({ rpc });
1561
1679
  const returnedNames = await ario.getArNSReturnedNames({
1562
1680
  limit: 100,
1563
1681
  sortBy: "endTimestamp",
@@ -1573,21 +1691,15 @@ const returnedNames = await ario.getArNSReturnedNames({
1573
1691
  "items": [
1574
1692
  {
1575
1693
  "name": "permalink",
1576
- "endTimestamp": 1730985241349,
1577
1694
  "startTimestamp": 1729775641349,
1578
- "baseFee": 250000000,
1579
- "demandFactor": 1.05256,
1695
+ "endTimestamp": 1730985241349,
1580
1696
  "initiator": "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc",
1581
- "settings": {
1582
- "durationMs": 1209600000,
1583
- "decayRate": 0.000000000016847809193121693,
1584
- "scalingExponent": 190,
1585
- "startPriceMultiplier": 50
1586
- }
1697
+ "premiumMultiplier": 50
1587
1698
  }
1588
1699
  ],
1589
1700
  "hasMore": false,
1590
1701
  "totalItems": 1,
1702
+ "limit": 100,
1591
1703
  "sortBy": "endTimestamp",
1592
1704
  "sortOrder": "asc"
1593
1705
  }
@@ -1600,7 +1712,7 @@ const returnedNames = await ario.getArNSReturnedNames({
1600
1712
  Retrieves the returned name data for the specified returned name.
1601
1713
 
1602
1714
  ```typescript
1603
- const ario = ARIO.mainnet();
1715
+ const ario = ARIO.init({ rpc });
1604
1716
  const returnedName = await ario.getArNSReturnedName({ name: "permalink" });
1605
1717
  ```
1606
1718
 
@@ -1610,17 +1722,10 @@ const returnedName = await ario.getArNSReturnedName({ name: "permalink" });
1610
1722
  ```json
1611
1723
  {
1612
1724
  "name": "permalink",
1613
- "endTimestamp": 1730985241349,
1614
1725
  "startTimestamp": 1729775641349,
1615
- "baseFee": 250000000,
1616
- "demandFactor": 1.05256,
1726
+ "endTimestamp": 1730985241349,
1617
1727
  "initiator": "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc",
1618
- "settings": {
1619
- "durationMs": 1209600000,
1620
- "decayRate": 0.000000000016847809193121693,
1621
- "scalingExponent": 190,
1622
- "startPriceMultiplier": 50
1623
- }
1728
+ "premiumMultiplier": 50
1624
1729
  }
1625
1730
  ```
1626
1731
 
@@ -1633,7 +1738,7 @@ const returnedName = await ario.getArNSReturnedName({ name: "permalink" });
1633
1738
  Returns the current epoch data.
1634
1739
 
1635
1740
  ```typescript
1636
- const ario = ARIO.mainnet();
1741
+ const ario = ARIO.init({ rpc });
1637
1742
  const epoch = await ario.getCurrentEpoch();
1638
1743
  ```
1639
1744
 
@@ -1643,10 +1748,10 @@ const epoch = await ario.getCurrentEpoch();
1643
1748
  ```json
1644
1749
  {
1645
1750
  "epochIndex": 0,
1751
+ "startHeight": 0,
1646
1752
  "startTimestamp": 1720720621424,
1647
1753
  "endTimestamp": 1752256702026,
1648
- "startHeight": 1350700,
1649
- "distributionTimestamp": 1711122739,
1754
+ "distributionTimestamp": 1752256702026,
1650
1755
  "observations": {
1651
1756
  "failureSummaries": {
1652
1757
  "-Tk2DDk8k4zkwtppp_XFKKI5oUgh6IEHygAoN7mD-w8": [
@@ -1663,21 +1768,28 @@ const epoch = await ario.getCurrentEpoch();
1663
1768
  "gatewayAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
1664
1769
  "observerAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
1665
1770
  "stake": 10000000000,
1666
- "start": 1292450,
1771
+ "startTimestamp": 1720720621424,
1667
1772
  "stakeWeight": 1,
1668
1773
  "tenureWeight": 0.4494598765432099,
1669
1774
  "gatewayPerformanceRatio": 1,
1775
+ "observerPerformanceRatio": 1,
1776
+ "gatewayRewardRatioWeight": 1,
1670
1777
  "observerRewardRatioWeight": 1,
1671
1778
  "compositeWeight": 0.4494598765432099,
1672
1779
  "normalizedCompositeWeight": 0.002057032496835938
1673
1780
  }
1674
1781
  ],
1675
1782
  "distributions": {
1676
- "distributedTimestamp": 1711122739,
1783
+ "totalEligibleGateways": 1,
1677
1784
  "totalEligibleRewards": 100000000,
1678
- "rewards": {
1679
- "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": 100000000
1680
- }
1785
+ "totalEligibleObserverReward": 100000000,
1786
+ "totalEligibleGatewayReward": 100000000
1787
+ },
1788
+ "arnsStats": {
1789
+ "totalReturnedNames": 0,
1790
+ "totalActiveNames": 0,
1791
+ "totalGracePeriodNames": 0,
1792
+ "totalReservedNames": 0
1681
1793
  }
1682
1794
  }
1683
1795
  ```
@@ -1689,7 +1801,7 @@ const epoch = await ario.getCurrentEpoch();
1689
1801
  Returns the epoch data for the specified block height. If no epoch index is provided, the current epoch is used.
1690
1802
 
1691
1803
  ```typescript
1692
- const ario = ARIO.mainnet();
1804
+ const ario = ARIO.init({ rpc });
1693
1805
  const epoch = await ario.getEpoch({ epochIndex: 0 });
1694
1806
  ```
1695
1807
 
@@ -1699,9 +1811,9 @@ const epoch = await ario.getEpoch({ epochIndex: 0 });
1699
1811
  ```json
1700
1812
  {
1701
1813
  "epochIndex": 0,
1814
+ "startHeight": 0,
1702
1815
  "startTimestamp": 1720720620813,
1703
1816
  "endTimestamp": 1752256702026,
1704
- "startHeight": 1350700,
1705
1817
  "distributionTimestamp": 1752256702026,
1706
1818
  "observations": {
1707
1819
  "failureSummaries": {
@@ -1718,11 +1830,13 @@ const epoch = await ario.getEpoch({ epochIndex: 0 });
1718
1830
  {
1719
1831
  "gatewayAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
1720
1832
  "observerAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
1721
- "stake": 10000000000, // value in mARIO
1833
+ "stake": 10000000000,
1722
1834
  "startTimestamp": 1720720620813,
1723
1835
  "stakeWeight": 1,
1724
1836
  "tenureWeight": 0.4494598765432099,
1725
1837
  "gatewayPerformanceRatio": 1,
1838
+ "observerPerformanceRatio": 1,
1839
+ "gatewayRewardRatioWeight": 1,
1726
1840
  "observerRewardRatioWeight": 1,
1727
1841
  "compositeWeight": 0.4494598765432099,
1728
1842
  "normalizedCompositeWeight": 0.002057032496835938
@@ -1732,14 +1846,13 @@ const epoch = await ario.getEpoch({ epochIndex: 0 });
1732
1846
  "totalEligibleGateways": 1,
1733
1847
  "totalEligibleRewards": 100000000,
1734
1848
  "totalEligibleObserverReward": 100000000,
1735
- "totalEligibleGatewayReward": 100000000,
1736
- "totalDistributedRewards": 100000000,
1737
- "distributedTimestamp": 1720720621424,
1738
- "rewards": {
1739
- "distributed": {
1740
- "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": 100000000
1741
- }
1742
- }
1849
+ "totalEligibleGatewayReward": 100000000
1850
+ },
1851
+ "arnsStats": {
1852
+ "totalReturnedNames": 0,
1853
+ "totalActiveNames": 0,
1854
+ "totalGracePeriodNames": 0,
1855
+ "totalReservedNames": 0
1743
1856
  }
1744
1857
  }
1745
1858
  ```
@@ -1751,7 +1864,7 @@ const epoch = await ario.getEpoch({ epochIndex: 0 });
1751
1864
  Returns the eligible epoch rewards for the specified block height. If no epoch index is provided, the current epoch is used.
1752
1865
 
1753
1866
  ```typescript
1754
- const ario = ARIO.mainnet();
1867
+ const ario = ARIO.init({ rpc });
1755
1868
  const rewards = await ario.getEligibleEpochRewards({ epochIndex: 0 });
1756
1869
  ```
1757
1870
 
@@ -1784,7 +1897,7 @@ const rewards = await ario.getEligibleEpochRewards({ epochIndex: 0 });
1784
1897
  Returns the epoch-indexed observation list. If no epoch index is provided, the current epoch is used.
1785
1898
 
1786
1899
  ```typescript
1787
- const ario = ARIO.mainnet();
1900
+ const ario = ARIO.init({ rpc });
1788
1901
  const observations = await ario.getObservations();
1789
1902
  ```
1790
1903
 
@@ -1793,19 +1906,16 @@ const observations = await ario.getObservations();
1793
1906
 
1794
1907
  ```json
1795
1908
  {
1796
- "0": {
1797
- "failureSummaries": {
1798
- "-Tk2DDk8k4zkwtppp_XFKKI5oUgh6IEHygAoN7mD-w8": [
1799
- "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA",
1800
- "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA"
1801
- ]
1802
- },
1803
- "reports": {
1804
- "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": "B6UUjKWjjEWDBvDSMXWNmymfwvgR9EN27z5FTkEVlX4",
1805
- "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA": "7tKsiQ2fxv0D8ZVN_QEv29fZ8hwFIgHoEDrpeEG0DIs",
1806
- "osZP4D9cqeDvbVFBaEfjIxwc1QLIvRxUBRAxDIX9je8": "aatgznEvC_UPcxp1v0uw_RqydhIfKm4wtt1KCpONBB0",
1807
- "qZ90I67XG68BYIAFVNfm9PUdM7v1XtFTn7u-EOZFAtk": "Bd8SmFK9-ktJRmwIungS8ur6JM-JtpxrvMtjt5JkB1M"
1808
- }
1909
+ "failureSummaries": {
1910
+ "-Tk2DDk8k4zkwtppp_XFKKI5oUgh6IEHygAoN7mD-w8": [
1911
+ "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA"
1912
+ ]
1913
+ },
1914
+ "reports": {
1915
+ "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": "B6UUjKWjjEWDBvDSMXWNmymfwvgR9EN27z5FTkEVlX4",
1916
+ "Ie2wEEUDKoU26c7IuckHNn3vMFdNQnMvfPBrFzAb3NA": "7tKsiQ2fxv0D8ZVN_QEv29fZ8hwFIgHoEDrpeEG0DIs",
1917
+ "osZP4D9cqeDvbVFBaEfjIxwc1QLIvRxUBRAxDIX9je8": "aatgznEvC_UPcxp1v0uw_RqydhIfKm4wtt1KCpONBB0",
1918
+ "qZ90I67XG68BYIAFVNfm9PUdM7v1XtFTn7u-EOZFAtk": "Bd8SmFK9-ktJRmwIungS8ur6JM-JtpxrvMtjt5JkB1M"
1809
1919
  }
1810
1920
  }
1811
1921
  ```
@@ -1817,7 +1927,7 @@ const observations = await ario.getObservations();
1817
1927
  Returns the current rewards distribution information. If no epoch index is provided, the current epoch is used.
1818
1928
 
1819
1929
  ```typescript
1820
- const ario = ARIO.mainnet();
1930
+ const ario = ARIO.init({ rpc });
1821
1931
  const distributions = await ario.getDistributions({ epochIndex: 0 });
1822
1932
  ```
1823
1933
 
@@ -1829,20 +1939,7 @@ const distributions = await ario.getDistributions({ epochIndex: 0 });
1829
1939
  "totalEligibleGateways": 1,
1830
1940
  "totalEligibleRewards": 100000000,
1831
1941
  "totalEligibleObserverReward": 100000000,
1832
- "totalEligibleGatewayReward": 100000000,
1833
- "totalDistributedRewards": 100000000,
1834
- "distributedTimestamp": 1720720621424,
1835
- "rewards": {
1836
- "eligible": {
1837
- "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": {
1838
- "operatorReward": 100000000,
1839
- "delegateRewards": {}
1840
- }
1841
- },
1842
- "distributed": {
1843
- "IPdwa3Mb_9pDD8c2IaJx6aad51Ss-_TfStVwBuhtXMs": 100000000
1844
- }
1845
- }
1942
+ "totalEligibleGatewayReward": 100000000
1846
1943
  }
1847
1944
  ```
1848
1945
 
@@ -1853,7 +1950,7 @@ Saves the observations of the current epoch. Requires `signer` to be provided on
1853
1950
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
1854
1951
 
1855
1952
  ```typescript
1856
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
1953
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1857
1954
  const { id: txId } = await ario.saveObservations(
1858
1955
  {
1859
1956
  reportTxId: "fDrr0_J4Iurt7caNST02cMotaz2FIbWQ4Kcj616RHl3",
@@ -1872,7 +1969,7 @@ const { id: txId } = await ario.saveObservations(
1872
1969
  Retrieves the prescribed observers of the ARIO process. To fetch prescribed observers for a previous epoch set the `epochIndex` to the desired epoch index.
1873
1970
 
1874
1971
  ```typescript
1875
- const ario = ARIO.mainnet();
1972
+ const ario = ARIO.init({ rpc });
1876
1973
  const observers = await ario.getPrescribedObservers({ epochIndex: 0 });
1877
1974
  ```
1878
1975
 
@@ -1884,11 +1981,13 @@ const observers = await ario.getPrescribedObservers({ epochIndex: 0 });
1884
1981
  {
1885
1982
  "gatewayAddress": "BpQlyhREz4lNGS-y3rSS1WxADfxPpAuing9Lgfdrj2U",
1886
1983
  "observerAddress": "2Fk8lCmDegPg6jjprl57-UCpKmNgYiKwyhkU4vMNDnE",
1887
- "stake": 10000000000, // value in mARIO
1888
- "start": 1296976,
1984
+ "stake": 10000000000,
1985
+ "startTimestamp": 1720720620813,
1889
1986
  "stakeWeight": 1,
1890
1987
  "tenureWeight": 0.41453703703703704,
1891
1988
  "gatewayPerformanceRatio": 1,
1989
+ "observerPerformanceRatio": 1,
1990
+ "gatewayRewardRatioWeight": 1,
1892
1991
  "observerRewardRatioWeight": 1,
1893
1992
  "compositeWeight": 0.41453703703703704,
1894
1993
  "normalizedCompositeWeight": 0.0018972019546783507
@@ -1898,6 +1997,40 @@ const observers = await ario.getPrescribedObservers({ epochIndex: 0 });
1898
1997
 
1899
1998
  </details>
1900
1999
 
2000
+ #### `crankEpochStep(options?)`
2001
+
2002
+ High-level, permissionless epoch crank. Advances the epoch lifecycle by **one
2003
+ step per call** and returns the action it took — run it on a loop (this is what
2004
+ the standalone cranker and the observer-embedded cranker do). It owns the whole
2005
+ sequence so you don't orchestrate the individual instructions yourself:
2006
+
2007
+ `create` → `tally` → `prescribe` → `distribute` → `close` — closing an epoch's
2008
+ observation PDAs first (`close_observation`) so `close_epoch` doesn't revert —
2009
+ plus an idle-tail of permissionless maintenance: `compound` delegate rewards,
2010
+ `update_demand_factor`, and `prune_returned_names`. The close path is
2011
+ non-wedging: a cleanup failure never blocks creation of the next epoch.
2012
+
2013
+ ```typescript
2014
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
2015
+
2016
+ // one step
2017
+ const result = await ario.crankEpochStep();
2018
+ // → { action, epochIndex?, txId?, progress? }
2019
+ // action ∈ create | tally | prescribe | distribute | close
2020
+ // | close_observation | compound | update_demand_factor
2021
+ // | prune_returned_names | idle
2022
+
2023
+ // or drive it on an interval
2024
+ setInterval(async () => {
2025
+ const r = await ario.crankEpochStep();
2026
+ if (r.action !== 'idle') console.log(r.action, r.epochIndex, r.txId);
2027
+ }, 60_000);
2028
+ ```
2029
+
2030
+ All options are optional: `batchSize`, `enableClose`, `epochRetention`,
2031
+ `enableCompound`, `compoundMinPendingRewards`, `enableDemandFactorRoll`,
2032
+ `enablePrune`, `pruneBatchSize`, `nameRegistryAccount`.
2033
+
1901
2034
  ### Primary Names
1902
2035
 
1903
2036
  #### `getPrimaryNames({ cursor, limit, sortBy, sortOrder })`
@@ -1905,7 +2038,7 @@ const observers = await ario.getPrescribedObservers({ epochIndex: 0 });
1905
2038
  Retrieves all primary names paginated and sorted by the specified criteria. The `cursor` used for pagination is the last name from the previous request.
1906
2039
 
1907
2040
  ```typescript
1908
- const ario = ARIO.mainnet();
2041
+ const ario = ARIO.init({ rpc });
1909
2042
  const names = await ario.getPrimaryNames({
1910
2043
  cursor: "ao", // this is the last name from the previous request
1911
2044
  limit: 1,
@@ -1924,12 +2057,13 @@ const names = await ario.getPrimaryNames({
1924
2057
  "totalItems": 100,
1925
2058
  "limit": 1,
1926
2059
  "sortBy": "startTimestamp",
1927
- "cursor": "arns",
2060
+ "nextCursor": "arns",
1928
2061
  "items": [
1929
2062
  {
2063
+ "name": "arns",
1930
2064
  "owner": "HwFceQaMQnOBgKDpnFqCqgwKwEU5LBme1oXRuQOWSRA",
1931
- "startTimestamp": 1719356032297,
1932
- "name": "arns"
2065
+ "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
2066
+ "startTimestamp": 1719356032297
1933
2067
  }
1934
2068
  ]
1935
2069
  }
@@ -1942,7 +2076,7 @@ const names = await ario.getPrimaryNames({
1942
2076
  Retrieves the primary name for a given name or address.
1943
2077
 
1944
2078
  ```typescript
1945
- const ario = ARIO.mainnet();
2079
+ const ario = ARIO.init({ rpc });
1946
2080
  const name = await ario.getPrimaryName({
1947
2081
  name: "arns",
1948
2082
  });
@@ -1957,9 +2091,10 @@ const name = await ario.getPrimaryName({
1957
2091
 
1958
2092
  ```json
1959
2093
  {
2094
+ "name": "arns",
1960
2095
  "owner": "HwFceQaMQnOBgKDpnFqCqgwKwEU5LBme1oXRuQOWSRA",
1961
- "startTimestamp": 1719356032297,
1962
- "name": "arns"
2096
+ "processId": "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
2097
+ "startTimestamp": 1719356032297
1963
2098
  }
1964
2099
  ```
1965
2100
 
@@ -1972,9 +2107,8 @@ Sets an ArNS name already owned by the `signer` as their primary name. Note: `si
1972
2107
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
1973
2108
 
1974
2109
  ```typescript
1975
- const signer = new ArweaveSigner(jwk);
1976
- const ario = ARIO.mainnet({ signer });
1977
- await ario.setPrimaryName({ name: "my-arns-name" }); // the caller must already have purchased the name my-arns-name and be assigned as the owner of the processId that is assigned to the name
2110
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
2111
+ await ario.setPrimaryName({ name: 'my-arns-name' });
1978
2112
  ```
1979
2113
 
1980
2114
  #### `requestPrimaryName({ name })`
@@ -1984,7 +2118,7 @@ Requests a primary name for the `signer`'s address. The request must be approved
1984
2118
  _Note: Requires `signer` to be provided on `ARIO.init` to sign the transaction._
1985
2119
 
1986
2120
  ```typescript
1987
- const ario = ARIO.mainnet({ signer: new ArweaveSigner(jwk) });
2121
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
1988
2122
  const { id: txId } = await ario.requestPrimaryName({
1989
2123
  name: "arns",
1990
2124
  });
@@ -1995,7 +2129,7 @@ const { id: txId } = await ario.requestPrimaryName({
1995
2129
  Retrieves the primary name request for a a wallet address.
1996
2130
 
1997
2131
  ```typescript
1998
- const ario = ARIO.mainnet();
2132
+ const ario = ARIO.init({ rpc });
1999
2133
  const request = await ario.getPrimaryNameRequest({
2000
2134
  initiator: "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3",
2001
2135
  });
@@ -2017,80 +2151,71 @@ const request = await ario.getPrimaryNameRequest({
2017
2151
 
2018
2152
  ### Configuration
2019
2153
 
2020
- The ARIO client class exposes APIs relevant to the ar.io process. It can be configured to use any AO Process ID that adheres to the [ARIO Network Spec]. By default, it will use the current [ARIO Testnet Process]. Refer to [AO Connect] for more information on how to configure an ARIO process to use specific AO infrastructure.
2021
-
2022
- ```typescript
2023
- import { ARIO , AOProcess } from '@ar.io/sdk';
2024
- import { connect } from '@permaweb/aoconnect';
2025
-
2026
- // provide a custom ao infrastructure and process id
2027
- const ario = ARIO.mainnet({
2028
- process: new AOProcess({
2029
- processId: 'ARIO_PROCESS_ID'
2030
- ao: connect({
2031
- MODE: 'legacy',
2032
- MU_URL: 'https://mu-testnet.xyz',
2033
- CU_URL: 'https://cu-testnet.xyz',
2034
- GRAPHQL_URL: 'https://arweave.net/graphql',
2035
- GATEWAY_URL: 'https://arweave.net',
2036
- })
2037
- })
2038
- });
2039
- ```
2154
+ `ARIO.init` accepts a `@solana/kit` RPC client plus optional program ID
2155
+ overrides for non-mainnet clusters. See [Networks](#networks) above for
2156
+ the full shape.
2040
2157
 
2041
2158
  ## ANT Contracts
2042
2159
 
2043
- The ANT client class exposes APIs relevant to compliant Arweave Name Token processes. It can be configured to use any process ID that adheres to the ANT process spec. You must provide either a custom process data provider or a processId to the ANT class constructor to use.
2160
+ The ANT client class exposes APIs for Arweave Name Tokens. On Solana an
2161
+ ANT is a Metaplex Core asset; its `processId` is the asset's mint
2162
+ pubkey. The `ario-ant` program owns the on-chain records / controllers
2163
+ state attached to the asset.
2044
2164
 
2045
2165
  ### Initialize
2046
2166
 
2047
- #### `init({ processId, signer })`
2167
+ #### `init({ processId, rpc, rpcSubscriptions?, signer? })`
2048
2168
 
2049
- Factory function to that creates a read-only or writeable client. By providing a `signer` additional write APIs that require signing, like `setRecord` and `transfer` are available. By default, a read-only client is returned and no write APIs are available.
2169
+ Factory that creates a read-only or writeable ANT client. Providing
2170
+ `signer` and `rpcSubscriptions` enables write methods (`setRecord`,
2171
+ `transfer`, `addController`, etc.).
2050
2172
 
2051
2173
  ```typescript
2052
- // in a browser environment with ArConnect
2053
- const ant = ANT.init({
2054
- signer: new ArConnectSigner(window.arweaveWallet, Arweave.init({})),
2055
- processId: "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
2174
+ import { ANT } from '@ar.io/sdk';
2175
+ import {
2176
+ createSolanaRpc,
2177
+ createSolanaRpcSubscriptions,
2178
+ } from '@solana/kit';
2179
+
2180
+ const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
2181
+
2182
+ // Read-only
2183
+ const ant = await ANT.init({
2184
+ processId: '<MPL Core asset pubkey>',
2185
+ rpc,
2056
2186
  });
2057
2187
 
2058
- // in a node environment
2059
- const ant = ANT.init({
2060
- signer: new ArweaveSigner(JWK),
2061
- processId: "bh9l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
2188
+ // Read + write
2189
+ const antWrite = await ANT.init({
2190
+ processId: '<MPL Core asset pubkey>',
2191
+ rpc,
2192
+ rpcSubscriptions: createSolanaRpcSubscriptions(
2193
+ 'wss://api.mainnet-beta.solana.com',
2194
+ ),
2195
+ signer,
2062
2196
  });
2063
2197
  ```
2064
2198
 
2065
2199
  ### Spawn
2066
2200
 
2067
- #### `spawn({ signer, module?, ao?, scheduler?, state?, antRegistryId?, logger?, authority? })`
2068
-
2069
- Spawns a new ANT (Arweave Name Token) process. This static function creates a new ANT process on the AO network and returns the process ID.
2201
+ #### `ANT.spawn({ rpc, rpcSubscriptions, signer, state })`
2070
2202
 
2071
- _Note: Requires `signer` to be provided to sign the spawn transaction._
2203
+ Static factory that mints a new MPL Core asset and initializes the
2204
+ `ario-ant` PDAs in a single transaction. Returns
2205
+ `{ processId, mint, signature }`.
2072
2206
 
2073
2207
  ```typescript
2074
- import { ANT } from "@ar.io/sdk";
2075
- import { ArweaveSigner } from "@ar.io/sdk/node";
2076
-
2077
- const processId = await ANT.spawn({
2078
- signer: new ArweaveSigner(jwk),
2079
- state: {
2080
- name: "My ANT",
2081
- ticker: "MYANT",
2082
- description: "My custom ANT token",
2083
- },
2084
- });
2208
+ import { ANT } from '@ar.io/sdk';
2085
2209
 
2086
- // Using a custom module ID
2087
- const processId = await ANT.spawn({
2088
- signer: new ArweaveSigner(jwk),
2089
- module: "FKtQtOOtlcWCW2pXrwWFiCSlnuewMZOHCzhulVkyqBE", // Custom module ID
2210
+ const { processId, signature } = await ANT.spawn({
2211
+ rpc,
2212
+ rpcSubscriptions,
2213
+ signer,
2090
2214
  state: {
2091
- name: "My Custom Module ANT",
2092
- ticker: "CUSTOM",
2093
- description: "ANT using a specific module version",
2215
+ name: 'My ANT',
2216
+ ticker: 'MYANT',
2217
+ description: 'My ANT token',
2218
+ uri: 'ar://<metadata-tx-id>',
2094
2219
  },
2095
2220
  });
2096
2221
  ```
@@ -2098,25 +2223,34 @@ const processId = await ANT.spawn({
2098
2223
  **CLI Usage:**
2099
2224
 
2100
2225
  ```bash
2101
- # Spawn ANT with default (latest) module
2102
- ar.io spawn-ant --wallet-file wallet.json --name "My ANT" --ticker "MYANT"
2103
-
2104
- # Spawn ANT with custom module ID
2105
- ar.io spawn-ant --wallet-file wallet.json --module FKtQtOOtlcWCW2pXrwWFiCSlnuewMZOHCzhulVkyqBE --name "My Custom ANT" --ticker "CUSTOM"
2226
+ ar.io spawn-ant \
2227
+ --wallet-file wallet.json \
2228
+ --name "My ANT" \
2229
+ --ticker "MYANT" \
2230
+ --metadata-uri "ar://<metadata-tx-id>"
2106
2231
  ```
2107
2232
 
2108
2233
  **Parameters:**
2109
2234
 
2110
- - `signer: AoSigner` - The signer used to authenticate the spawn transaction
2111
- - `module?: string` - Optional module ID to use; if not provided, gets latest from ANT registry
2112
- - `ao?: AoClient` - Optional AO client instance (defaults to legacy mode connection)
2113
- - `scheduler?: string` - Optional scheduler ID
2114
- - `state?: SpawnANTState` - Optional initial state for the ANT including name, ticker, description, etc.
2115
- - `antRegistryId?: string` - Optional ANT registry ID
2116
- - `logger?: Logger` - Optional logger instance
2117
- - `authority?: string` - Optional authority
2235
+ - `state.name: string` display name of the ANT
2236
+ - `state.ticker?: string` ticker symbol
2237
+ - `state.description?: string` short description
2238
+ - `state.uri: string` `ar://` URI of the Metaplex Core asset's JSON
2239
+ metadata. Build via `buildAntMetadata` from `@ar.io/sdk` and upload
2240
+ to Arweave (e.g. via `@ardrive/turbo-sdk`).
2241
+ - `state.keywords?: string[]`
2242
+ - `state.logo?: string` Arweave TX ID of the logo
2243
+ - `state.transactionId?: string` — initial `@` record target
2118
2244
 
2119
- **Returns:** `Promise<ProcessId>` - The process ID of the newly spawned ANT
2245
+ **Returns:**
2246
+
2247
+ ```ts
2248
+ {
2249
+ processId: string; // the MPL Core asset mint pubkey
2250
+ mint: Address;
2251
+ signature: string; // the Solana tx signature
2252
+ }
2253
+ ```
2120
2254
 
2121
2255
  ### Versions
2122
2256
 
@@ -2187,61 +2321,6 @@ true
2187
2321
 
2188
2322
  </details>
2189
2323
 
2190
- #### `getANTVersions`
2191
-
2192
- Static method that returns the full array of available ANT versions and the latest version from the ANT registry.
2193
-
2194
- ```typescript
2195
- import { ANT } from "@ar.io/sdk";
2196
-
2197
- // Get all available ANT versions
2198
- const antVersions = ANT.versions;
2199
- const versions = await antVersions.getANTVersions();
2200
- ```
2201
-
2202
- Result:
2203
-
2204
- ```json
2205
- {
2206
- [
2207
- {
2208
- "moduleId": "FKtQtOOtlcWCW2pXrwWFiCSlnuewMZOHCzhulVkyqBE",
2209
- "version": "23",
2210
- "releaseNotes": "Initial release of the ANT module.",
2211
- "releaseDate": 1700000000000
2212
- }
2213
- // ...other versions
2214
- ],
2215
- }
2216
- ```
2217
-
2218
- #### `getLatestANTVersion()`
2219
-
2220
- Static method that returns the latest ANT version from the ANT registry.
2221
-
2222
- ```typescript
2223
- import { ANT } from "@ar.io/sdk";
2224
-
2225
- // Get the latest ANT version
2226
- import { ANT } from "@ar.io/sdk";
2227
-
2228
- // Get all available ANT versions
2229
- const antVersions = ANT.versions;
2230
- const versions = await antVersions.getANTVersions();
2231
- const latestVersion = await antVersions.getLatestANTVersion();
2232
- ```
2233
-
2234
- Result:
2235
-
2236
- ```json
2237
- {
2238
- "moduleId": "FKtQtOOtlcWCW2pXrwWFiCSlnuewMZOHCzhulVkyqBE",
2239
- "version": "23",
2240
- "releaseNotes": "Initial release of the ANT module.",
2241
- "releaseDate": 1700000000000
2242
- }
2243
- ```
2244
-
2245
2324
  ### State
2246
2325
 
2247
2326
  #### `getInfo()`
@@ -2257,11 +2336,42 @@ const info = await ant.getInfo();
2257
2336
 
2258
2337
  ```json
2259
2338
  {
2260
- "name": "ArDrive",
2261
- "ticker": "ANT-ARDRIVE",
2262
- "description": "This is the ANT for the ArDrive decentralized web app.",
2263
- "keywords": ["File-sharing", "Publishing", "dApp"],
2264
- "owner": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ"
2339
+ "Name": "ArDrive",
2340
+ "Owner": "QGWqtJdLLgm2ehFWiiPzMaoFLD50CnGuzZIPEdoDRGQ",
2341
+ "Ticker": "ANT-ARDRIVE",
2342
+ "Total-Supply": "1",
2343
+ "Description": "This is the ANT for the ArDrive decentralized web app.",
2344
+ "Keywords": ["File-sharing", "Publishing", "dApp"],
2345
+ "Logo": "Sie_26dvgyok0PZD_-iQAFOhOd5YxDTkczOLoqTTL_A",
2346
+ "Denomination": "0",
2347
+ "Handlers": [
2348
+ "balance",
2349
+ "balances",
2350
+ "totalSupply",
2351
+ "info",
2352
+ "controllers",
2353
+ "record",
2354
+ "records",
2355
+ "state",
2356
+ "transfer",
2357
+ "addController",
2358
+ "removeController",
2359
+ "setRecord",
2360
+ "removeRecord",
2361
+ "setName",
2362
+ "setTicker",
2363
+ "setDescription",
2364
+ "setKeywords",
2365
+ "setLogo",
2366
+ "initializeState",
2367
+ "releaseName",
2368
+ "reassignName",
2369
+ "approvePrimaryName",
2370
+ "removePrimaryNames",
2371
+ "transferRecordOwnership",
2372
+ "_eval",
2373
+ "_default"
2374
+ ]
2265
2375
  }
2266
2376
  ```
2267
2377
 
@@ -2280,24 +2390,32 @@ const handlers = await ant.getHandlers();
2280
2390
 
2281
2391
  ```json
2282
2392
  [
2283
- "_eval",
2284
- "_default",
2285
- "transfer",
2286
2393
  "balance",
2287
2394
  "balances",
2288
2395
  "totalSupply",
2289
2396
  "info",
2397
+ "controllers",
2398
+ "record",
2399
+ "records",
2400
+ "state",
2401
+ "transfer",
2290
2402
  "addController",
2291
2403
  "removeController",
2292
- "controllers",
2293
2404
  "setRecord",
2294
2405
  "removeRecord",
2295
- "record",
2296
- "records",
2297
2406
  "setName",
2298
2407
  "setTicker",
2408
+ "setDescription",
2409
+ "setKeywords",
2410
+ "setLogo",
2299
2411
  "initializeState",
2300
- "state"
2412
+ "releaseName",
2413
+ "reassignName",
2414
+ "approvePrimaryName",
2415
+ "removePrimaryNames",
2416
+ "transferRecordOwnership",
2417
+ "_eval",
2418
+ "_default"
2301
2419
  ]
2302
2420
  ```
2303
2421
 
@@ -2316,23 +2434,28 @@ const state = await ant.getState();
2316
2434
 
2317
2435
  ```json
2318
2436
  {
2319
- "TotalSupply": 1,
2320
- "Balances": {
2321
- "98O1_xqDLrBKRfQPWjF5p7xZ4Jx6GM8P5PeJn26xwUY": 1
2322
- },
2437
+ "Name": "ar.io Foundation",
2438
+ "Ticker": "ANT-AR-IO",
2439
+ "Description": "A friendly description for this ANT.",
2440
+ "Keywords": ["keyword1", "keyword2", "keyword3"],
2441
+ "Denomination": 0,
2442
+ "Owner": "98O1_xqDLrBKRfQPWjF5p7xZ4Jx6GM8P5PeJn26xwUY",
2323
2443
  "Controllers": [],
2324
2444
  "Records": {
2325
2445
  "v1-0-0_whitepaper": {
2326
2446
  "transactionId": "lNjWn3LpyhKC95Kqe-x8X2qgju0j98MhucdDKK85vc4",
2327
- "ttlSeconds": 900
2447
+ "ttlSeconds": 900,
2448
+ "targetProtocol": 0
2328
2449
  },
2329
2450
  "@": {
2330
2451
  "transactionId": "2rMLb2uHAyEt7jSu6bXtKx8e-jOfIf7E-DOgQnm8EtU",
2331
- "ttlSeconds": 3600
2452
+ "ttlSeconds": 3600,
2453
+ "targetProtocol": 0
2332
2454
  },
2333
2455
  "alice": {
2334
2456
  "transactionId": "kMk95k_3R8x_7d3wB9tEOiL5v6n8QhR_VnFCh3aeE3f",
2335
2457
  "ttlSeconds": 900,
2458
+ "targetProtocol": 0,
2336
2459
  "owner": "alice-wallet-address-123...",
2337
2460
  "displayName": "Alice's Portfolio",
2338
2461
  "logo": "avatar-tx-id-456...",
@@ -2341,17 +2464,16 @@ const state = await ant.getState();
2341
2464
  },
2342
2465
  "whitepaper": {
2343
2466
  "transactionId": "lNjWn3LpyhKC95Kqe-x8X2qgju0j98MhucdDKK85vc4",
2344
- "ttlSeconds": 900
2467
+ "ttlSeconds": 900,
2468
+ "targetProtocol": 0
2345
2469
  }
2346
2470
  },
2347
- "Initialized": true,
2348
- "Ticker": "ANT-AR-IO",
2349
- "Description": "A friendly description for this ANT.",
2350
- "Keywords": ["keyword1", "keyword2", "keyword3"],
2471
+ "Balances": {
2472
+ "98O1_xqDLrBKRfQPWjF5p7xZ4Jx6GM8P5PeJn26xwUY": 1
2473
+ },
2351
2474
  "Logo": "Sie_26dvgyok0PZD_-iQAFOhOd5YxDTkczOLoqTTL_A",
2352
- "Denomination": 0,
2353
- "Name": "ar.io Foundation",
2354
- "Owner": "98O1_xqDLrBKRfQPWjF5p7xZ4Jx6GM8P5PeJn26xwUY"
2475
+ "TotalSupply": 1,
2476
+ "Initialized": true
2355
2477
  }
2356
2478
  ```
2357
2479
 
@@ -2440,24 +2562,32 @@ const records = await ant.getRecords();
2440
2562
  {
2441
2563
  "@": {
2442
2564
  "transactionId": "UyC5P5qKPZaltMmmZAWdakhlDXsBF6qmyrbWYFchRTk",
2443
- "ttlSeconds": 3600
2565
+ "ttlSeconds": 3600,
2566
+ "targetProtocol": 0,
2567
+ "index": 0
2444
2568
  },
2445
2569
  "alice": {
2446
2570
  "transactionId": "kMk95k_3R8x_7d3wB9tEOiL5v6n8QhR_VnFCh3aeE3f",
2447
2571
  "ttlSeconds": 900,
2572
+ "targetProtocol": 0,
2448
2573
  "owner": "alice-wallet-address-123...",
2449
2574
  "displayName": "Alice's Portfolio",
2450
2575
  "logo": "avatar-tx-id-456...",
2451
2576
  "description": "Personal portfolio and blog",
2452
- "keywords": ["portfolio", "personal", "blog"]
2577
+ "keywords": ["portfolio", "personal", "blog"],
2578
+ "index": 1
2453
2579
  },
2454
2580
  "zed": {
2455
2581
  "transactionId": "-k7t8xMoB8hW482609Z9F4bTFMC3MnuW8bTvTyT8pFI",
2456
- "ttlSeconds": 900
2582
+ "ttlSeconds": 900,
2583
+ "targetProtocol": 0,
2584
+ "index": 2
2457
2585
  },
2458
2586
  "ardrive": {
2459
2587
  "transactionId": "-cucucachoodwedwedoiwepodiwpodiwpoidpwoiedp",
2460
- "ttlSeconds": 900
2588
+ "ttlSeconds": 900,
2589
+ "targetProtocol": 0,
2590
+ "index": 3
2461
2591
  }
2462
2592
  }
2463
2593
  ```
@@ -2479,6 +2609,7 @@ const record = await ant.getRecord({ undername: "dapp" });
2479
2609
  {
2480
2610
  "transactionId": "432l1cy0aksiL_x9M359faGzM_yjralacHIUo8_nQXM",
2481
2611
  "ttlSeconds": 900,
2612
+ "targetProtocol": 0,
2482
2613
  "owner": "alice-wallet-address-123...",
2483
2614
  "displayName": "Alice's Site",
2484
2615
  "logo": "avatar-tx-id-456...",
@@ -2793,115 +2924,28 @@ const { id: txId } = await ant.setLogo(
2793
2924
 
2794
2925
  ### ARIO Integrations
2795
2926
 
2796
- #### `releaseName({ name, arioProcessId })`
2797
-
2798
- Releases a name from the current owner and makes it available for purchase on the ARIO contract. The name must be permanently owned by the releasing wallet. If purchased within the recently returned name period (14 epochs), 50% of the purchase amount will be distributed to the ANT owner at the time of release. If no purchases in the recently returned name period, the name can be reregistered by anyone for the normal fee.
2799
-
2800
- _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._
2801
-
2802
- ```typescript
2803
- const { id: txId } = await ant.releaseName({
2804
- name: "permalink",
2805
- arioProcessId: ARIO_MAINNET_PROCESS_ID, // releases the name owned by the ANT and sends it to recently returned names on the ARIO contract
2806
- });
2807
- ```
2808
-
2809
- #### `reassignName({ name, arioProcessId, antProcessId })`
2810
-
2811
- Reassigns a name to a new ANT. This can only be done by the current owner of the ANT.
2812
-
2813
- _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._
2814
-
2815
- ```typescript
2816
- const { id: txId } = await ant.reassignName({
2817
- name: "ardrive",
2818
- arioProcessId: ARIO_MAINNET_PROCESS_ID,
2819
- antProcessId: NEW_ANT_PROCESS_ID, // the new ANT process id that will take over ownership of the name
2820
- });
2821
- ```
2822
-
2823
- #### `approvePrimaryNameRequest({ name, address, arioProcessId })`
2824
-
2825
- Approves a primary name request for a given name or address.
2826
-
2827
- _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._
2828
-
2829
- ```typescript
2830
- const { id: txId } = await ant.approvePrimaryNameRequest({
2831
- name: "arns",
2832
- address: "t4Xr0_J4Iurt7caNST02cMotaz2FIbWQ4Kbj616RHl3", // must match the request initiator address
2833
- arioProcessId: ARIO_MAINNET_PROCESS_ID, // the ARIO process id to use for the request
2834
- });
2835
- ```
2836
-
2837
- #### `removePrimaryNames({ names, arioProcessId, notifyOwners })`
2838
-
2839
- Removes primary names from the ANT process.
2840
-
2841
- _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._
2842
-
2843
- ```typescript
2844
- const { id: txId } = await ant.removePrimaryNames({
2845
- names: ["arns", "test_arns"], // any primary names associated with a base name controlled by this ANT will be removed
2846
- arioProcessId: ARIO_MAINNET_PROCESS_ID,
2847
- notifyOwners: true, // if true, the owners of the removed names will be send AO messages to notify them of the removal
2848
- });
2849
- ```
2927
+ `releaseName`, `reassignName`, `approvePrimaryNameRequest`, and
2928
+ `removePrimaryNames` were AO-only orchestration helpers and have been
2929
+ removed. Their on-chain equivalents on Solana live on the `ario-arns`
2930
+ program and are exposed through the `ARIO` write client
2931
+ (`upgradeRecord`, `setPrimaryName`, etc.) or for permissionless
2932
+ maintenance — through `SolanaARIOWriteable`'s prune helpers.
2850
2933
 
2851
2934
  ### Upgrade
2852
2935
 
2853
- #### `upgrade({ reassignAffiliatedNames?, names?, arioProcessId?, antRegistryId?, skipVersionCheck?, onSigningProgress? })`
2854
-
2855
- Upgrades an ANT by forking it to the latest version from the ANT registry and optionally reassigning ArNS names to the new process. This function first checks the version of the existing ANT, creates a new ANT using `.fork()` to the latest version, and then reassigns the ArNS names affiliated with this process to the new process.
2936
+ #### `upgrade()`
2856
2937
 
2857
- _Note: Requires `signer` to be provided on `ANT.init` to sign the transaction._
2938
+ Migrates this ANT's on-chain state to the latest schema version (per-
2939
+ ANT data migration on Solana — no process forking, no name
2940
+ reassignment). Returns `{ id, needsMigration }`.
2858
2941
 
2859
2942
  ```typescript
2860
- // Upgrade ANT and reassign all affiliated ArNS names to the new process
2861
2943
  const result = await ant.upgrade();
2862
-
2863
- // Upgrade ANT and reassign specific ArNS names to the new process
2864
- const result = await ant.upgrade({
2865
- names: ["ardrive", "example"],
2866
- });
2867
-
2868
- // with callbacks
2869
- const result = await ant.upgrade({
2870
- names: ["ardrive", "example"],
2871
- onSigningProgress: (event, payload) => {
2872
- console.log(`${event}:`, payload);
2873
- if (event === "checking-version") {
2874
- console.log(`Checking version: ${payload.antProcessId}`);
2875
- }
2876
- if (event === "fetching-affiliated-names") {
2877
- console.log(`Fetching affiliated names: ${payload.arioProcessId}`);
2878
- }
2879
- if (event === "reassigning-name") {
2880
- console.log(`Reassigning name: ${payload.name}`);
2881
- }
2882
- if (event === "validating-names") {
2883
- console.log(`Validating names: ${payload.names}`);
2884
- }
2885
- // other callback events...
2886
- },
2887
- });
2888
-
2889
- console.log(`Upgraded to process: ${result.forkedProcessId}`);
2890
- console.log(`Successfully reassigned names: ${result.reassignedNames}`);
2891
- console.log(`Failed to reassign names: ${result.failedReassignedNames}`);
2944
+ if (result.needsMigration) {
2945
+ console.log(`Migrated: ${result.id}`);
2946
+ }
2892
2947
  ```
2893
2948
 
2894
- **Parameters:**
2895
-
2896
- - `reassignAffiliatedNames?: boolean` - If true, reassigns all names associated with this process to the new forked process (defaults to true when names is empty)
2897
- - `names?: string[]` - Optional array of specific names to reassign (cannot be used with `reassignAffiliatedNames: true`). These names must be affiliated with this ANT on the provided ARIO process.
2898
- - `arioProcessId?: string` - Optional ARIO process ID (defaults to mainnet)
2899
- - `antRegistryId?: string` - Optional ANT registry process ID used to resolve the latest version (defaults to mainnet registry)
2900
- - `skipVersionCheck?: boolean` - Skip checking if ANT is already latest version (defaults to false)
2901
- - `onSigningProgress?: Function` - Optional progress callback for tracking upgrade steps
2902
-
2903
- **Returns:** `Promise<{ forkedProcessId: string, reassignedNames: Record<string, AoMessageResult>, failedReassignedNames: Record<string, { id?: string; error: Error }> }>`
2904
-
2905
2949
  ### Undername Ownership
2906
2950
 
2907
2951
  NTs support ownership of undernames:
@@ -2954,9 +2998,11 @@ console.log(`Transaction ID: ${record.transactionId}`);
2954
2998
 
2955
2999
  ```typescript
2956
3000
  // Alice (record owner) updating her own record
2957
- const aliceAnt = ANT.init({
2958
- processId: "ANT_PROCESS_ID",
2959
- signer: new ArweaveSigner(aliceJwk), // Alice's wallet
3001
+ const aliceAnt = await ANT.init({
3002
+ processId: 'ANT_MINT_PUBKEY',
3003
+ rpc,
3004
+ rpcSubscriptions,
3005
+ signer: aliceSigner, // Alice's @solana/kit signer
2960
3006
  });
2961
3007
 
2962
3008
  // ✅ CORRECT: Alice includes her own address as owner
@@ -3010,55 +3056,62 @@ console.log(recordAfter.owner); // undefined (controlled by ANT owner again)
3010
3056
 
3011
3057
  ### Static Methods
3012
3058
 
3013
- #### `ANT.fork({ signer, antProcessId, module?, scheduler?, state?, ao?, antRegistryId?, onSigningProgress? })`
3014
-
3015
- Forks an existing ANT process to create a new one with the same state but potentially a different module. This is used for upgrading ANTs to new versions.
3059
+ `ANT.fork()` and the static `ANT.upgrade()` were AO-only (process
3060
+ forking + name reassignment). On Solana, schema migration is a
3061
+ per-asset CPI exposed as the instance method `ant.upgrade()` documented
3062
+ above; new ANTs are created with `ANT.spawn()`.
3016
3063
 
3017
- ```typescript
3018
- const newProcessId = await ANT.fork({
3019
- signer: new ArweaveSigner(jwk),
3020
- antProcessId: "existing-ant-process-id",
3021
- // Optional: specify a specific module ID, defaults to latest from registry
3022
- module: "new-module-id",
3023
- onSigningProgress: (event, payload) => {
3024
- console.log(`Fork progress: ${event}`);
3025
- },
3026
- });
3064
+ ## Escrow
3027
3065
 
3028
- console.log(`Forked ANT to new process: ${newProcessId}`);
3029
- ```
3066
+ Trustless, multi-protocol escrow for handing an asset to a recipient identified by
3067
+ an **Arweave** or **Ethereum** address, claimable once they hold a Solana wallet.
3068
+ Backed by the `ario-ant-escrow` program. Two clients:
3030
3069
 
3031
- #### `ANT.upgrade({ signer, antProcessId, reassignAffiliatedNames?, names?, arioProcessId?, antRegistryId?, ao?, logger?, skipVersionCheck?, onSigningProgress?, hyperbeamUrl? })`
3070
+ - `TokenEscrow` escrow liquid **ARIO** (SPL) or a **time-locked vault**.
3071
+ - `ANTEscrow` — escrow an **ANT** (Metaplex Core NFT).
3032
3072
 
3033
- Static method to upgrade an ANT by forking it to the latest version and reassigning names.
3073
+ Each supports **deposit claim cancel/refund update-recipient**. Claims work
3074
+ three ways: **Arweave-attested** (an off-chain attestor re-signs the canonical
3075
+ claim with Ed25519, verified on-chain), **Ethereum** (on-chain `secp256k1_recover`
3076
+ + EIP-191), and **vault** (instruction introspection that preserves the remaining
3077
+ lock).
3034
3078
 
3035
3079
  ```typescript
3036
- // Upgrade and reassign all affiliated names
3037
- const result = await ANT.upgrade({
3038
- signer: new ArweaveSigner(jwk),
3039
- antProcessId: "existing-ant-process-id",
3040
- reassignAffiliatedNames: true,
3041
- arioProcessId: ARIO_MAINNET_PROCESS_ID,
3080
+ import { TokenEscrow, canonicalMessageV2 } from '@ar.io/sdk';
3081
+
3082
+ const escrow = new TokenEscrow({
3083
+ rpc,
3084
+ rpcSubscriptions,
3085
+ signer,
3086
+ programId,
3087
+ coreProgram,
3042
3088
  });
3043
3089
 
3044
- // Upgrade and reassign specific names
3045
- const result = await ANT.upgrade({
3046
- signer: new ArweaveSigner(jwk),
3047
- antProcessId: "existing-ant-process-id",
3048
- names: ["ardrive", "example"],
3049
- reassignAffiliatedNames: false,
3050
- arioProcessId: ARIO_MAINNET_PROCESS_ID,
3090
+ // deposit 50 ARIO to an Ethereum recipient
3091
+ await escrow.depositTokens({
3092
+ assetId, // 32-byte client-supplied id
3093
+ amount: 50_000_000n,
3094
+ arioMint,
3095
+ depositorTokenAccount,
3096
+ recipient: { protocol: 'ethereum', publicKey: ethAddress20 },
3051
3097
  });
3052
3098
 
3053
- console.log(`Upgraded to process: ${result.forkedProcessId}`);
3054
- console.log(
3055
- `Successfully reassigned names: ${Object.keys(result.reassignedNames)}`,
3056
- );
3057
- console.log(
3058
- `Failed reassignments: ${Object.keys(result.failedReassignedNames)}`,
3059
- );
3099
+ // the recipient claims (Ethereum path) once they have a Solana wallet
3100
+ await escrow.claimTokensEthereum({
3101
+ depositor,
3102
+ assetId,
3103
+ claimant,
3104
+ claimantTokenAccount,
3105
+ escrowTokenAccount,
3106
+ signature, // recipient's EIP-191 signature over canonicalMessageV2(...)
3107
+ });
3060
3108
  ```
3061
3109
 
3110
+ Build the exact bytes a recipient signs with `canonicalMessage` /
3111
+ `canonicalMessageV2` — byte-identical to the on-chain program (and the off-chain
3112
+ attestor). See the contracts repo's escrow design + protocol spec for the full
3113
+ flow and the cross-language canonical-message vectors.
3114
+
3062
3115
  ## Token Conversion
3063
3116
 
3064
3117
  The ARIO process stores all values as mARIO (micro-ARIO) to avoid floating-point arithmetic issues. The SDK provides an `ARIOToken` and `mARIOToken` classes to handle the conversion between ARIO and mARIO, along with rounding logic for precision.
@@ -3111,10 +3164,9 @@ const customLogger: ILogger = {
3111
3164
  },
3112
3165
  };
3113
3166
 
3114
- // Use custom logger with any class
3115
- const ario = ARIO.mainnet({ logger: customLogger });
3116
-
3117
- // or set it as the default logger in the entire SDK
3167
+ // Set it as the default logger across the entire SDK — every class
3168
+ // (ARIO, ANT, ANTRegistry, etc.) will route logs through it. `ARIO.init`
3169
+ // does not accept a per-instance logger.
3118
3170
  Logger.default = customLogger;
3119
3171
  ```
3120
3172
 
@@ -3170,6 +3222,136 @@ In the example above, the query will return ArNS records where:
3170
3222
  - The type is "lease" AND
3171
3223
  - The processId is EITHER "ZkgLfyHALs5koxzojpcsEFAKA8fbpzP7l-tbM7wmQNM" OR "r61rbOjyXx3u644nGl9bkwLWlWmArMEzQgxBo2R-Vu0"
3172
3224
 
3225
+ ## Advanced
3226
+
3227
+ ### RPC Configuration
3228
+
3229
+ The SDK accepts any `@solana/kit` RPC client. For read-only usage, only
3230
+ `rpc` is required. Write operations additionally need `rpcSubscriptions`
3231
+ (WebSocket) for transaction confirmation and a `signer`.
3232
+
3233
+ #### Basic (read-only)
3234
+
3235
+ ```ts
3236
+ import { ARIO } from '@ar.io/sdk';
3237
+ import { createSolanaRpc } from '@solana/kit';
3238
+
3239
+ const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
3240
+ const ario = ARIO.init({ rpc });
3241
+ ```
3242
+
3243
+ #### With writes (signer + WebSocket subscriptions)
3244
+
3245
+ ```ts
3246
+ import { ARIO } from '@ar.io/sdk';
3247
+ import {
3248
+ createSolanaRpc,
3249
+ createSolanaRpcSubscriptions,
3250
+ createKeyPairSignerFromBytes,
3251
+ } from '@solana/kit';
3252
+
3253
+ const rpc = createSolanaRpc('https://api.mainnet-beta.solana.com');
3254
+ const rpcSubscriptions = createSolanaRpcSubscriptions(
3255
+ 'wss://api.mainnet-beta.solana.com',
3256
+ );
3257
+ const signer = await createKeyPairSignerFromBytes(/* ... */);
3258
+
3259
+ const ario = ARIO.init({ rpc, rpcSubscriptions, signer });
3260
+ ```
3261
+
3262
+ > **Note:** `rpcSubscriptions` opens a WebSocket connection and is only
3263
+ > needed for writes. If your RPC provider doesn't expose a WebSocket
3264
+ > endpoint, omit it and use the SDK in read-only mode.
3265
+
3266
+ ### Circuit Breaker
3267
+
3268
+ The SDK ships an [opossum]-backed circuit breaker that wraps the RPC
3269
+ transport. When the primary endpoint starts failing (429 rate-limits,
3270
+ 5xx errors, network timeouts) the circuit opens and subsequent calls
3271
+ route transparently to a fallback RPC until the primary recovers.
3272
+
3273
+ ```ts
3274
+ import { ARIO, createCircuitBreakerRpc } from '@ar.io/sdk';
3275
+
3276
+ const rpc = createCircuitBreakerRpc({
3277
+ primaryUrl: 'https://my-premium-rpc.example.com',
3278
+ fallbackUrl: 'https://api.mainnet-beta.solana.com',
3279
+ });
3280
+
3281
+ const ario = ARIO.init({ rpc });
3282
+ ```
3283
+
3284
+ Use `defaultFallbackUrl()` to auto-pick mainnet or devnet based on the
3285
+ primary URL:
3286
+
3287
+ ```ts
3288
+ import {
3289
+ createCircuitBreakerRpc,
3290
+ defaultFallbackUrl,
3291
+ } from '@ar.io/sdk';
3292
+
3293
+ const primaryUrl = 'https://my-premium-rpc.example.com';
3294
+ const rpc = createCircuitBreakerRpc({
3295
+ primaryUrl,
3296
+ fallbackUrl: defaultFallbackUrl(primaryUrl), // → mainnet public RPC
3297
+ });
3298
+ ```
3299
+
3300
+ Tuning knobs (all optional):
3301
+
3302
+ | Option | Default | Description |
3303
+ |---|---|---|
3304
+ | `timeout` | `10000` | ms before a single request is timed out (`false` to disable) |
3305
+ | `errorThresholdPercentage` | `50` | error % at which to open the circuit |
3306
+ | `resetTimeout` | `30000` | ms to wait before probing the primary again (half-open) |
3307
+ | `volumeThreshold` | `5` | minimum requests in the rolling window before the circuit can trip |
3308
+
3309
+ ### Automatic Retries
3310
+
3311
+ All RPC **read** calls (account fetches, `getProgramAccounts`, etc.)
3312
+ automatically retry on transient transport errors with exponential
3313
+ back-off. Writes are **not** retried (to avoid double-sends).
3314
+
3315
+ Retried errors: HTTP 429/5xx, `fetch failed`, `ECONNRESET`,
3316
+ `ETIMEDOUT`, `AbortError` / timeouts. Non-retryable errors (account
3317
+ not found, invalid params, deserialization) throw immediately.
3318
+
3319
+ Defaults: **6 attempts**, 500 ms base delay, 5 s max delay. Override
3320
+ per-call with the exported `withRetry` helper:
3321
+
3322
+ ```ts
3323
+ import { withRetry } from '@ar.io/sdk';
3324
+
3325
+ const result = await withRetry(() => rpc.getAccountInfo(addr).send(), {
3326
+ maxAttempts: 3,
3327
+ baseDelayMs: 1000,
3328
+ });
3329
+ ```
3330
+
3331
+ ### Generated instruction builders
3332
+
3333
+ For custom transaction building, import Codama-generated typed clients
3334
+ from [`@ar.io/solana-contracts`](https://www.npmjs.com/package/@ar.io/solana-contracts):
3335
+
3336
+ ```ts
3337
+ import {
3338
+ getBuyNameInstructionAsync,
3339
+ ARIO_ARNS_PROGRAM_ADDRESS,
3340
+ } from '@ar.io/solana-contracts/arns';
3341
+ ```
3342
+
3343
+ ### Networks
3344
+
3345
+ | Network | RPC | Programs |
3346
+ |---|---|---|
3347
+ | Mainnet | `https://api.mainnet-beta.solana.com` (mainnet-beta, default) | Not yet deployed — placeholder IDs in `src/solana/constants.ts` |
3348
+ | Devnet | `https://api.devnet.solana.com` | See `src/solana/constants.ts` for current devnet program IDs |
3349
+ | Localnet | Surfpool — `https://github.com/solana-foundation/surfpool` | Localnet harness in `solana-ar-io` monorepo |
3350
+
3351
+ The migration tooling (snapshot exporter, batch importer, claim app)
3352
+ lives in the [`solana-ar-io`](https://github.com/ar-io/solana-ar-io)
3353
+ monorepo until cutover.
3354
+
3173
3355
  ## Resources
3174
3356
 
3175
3357
  ### Bundling
@@ -3187,12 +3369,6 @@ To run your own ar.io gateway, you can refer to the following resources:
3187
3369
 
3188
3370
  Running your own gateway allows you to participate in the ar.io network, serve Arweave data, and potentially earn rewards. Make sure to follow the official documentation for the most up-to-date and accurate information on gateway operation.
3189
3371
 
3190
- ### AO
3191
-
3192
- This library integrates with [AO], a decentralized compute platform built on Arweave. We utilize [AO Connect] to interact with AO processes and messages. This integration allows for seamless communication with the AO network, enabling developers to leverage decentralized computation and storage capabilities in their applications.
3193
-
3194
- For more information on how to use AO and AO Connect within this library, please refer to our documentation and examples.
3195
-
3196
3372
  ## Developers
3197
3373
 
3198
3374
  ### Requirements
@@ -3213,7 +3389,6 @@ For more information on how to use AO and AO Connect within this library, please
3213
3389
  - `yarn test:e2e` - runs e2e tests
3214
3390
  - `yarn test:unit` - runs unit tests
3215
3391
  - `yarn example:web` - opens up the example web page
3216
- - `yarn example:cjs` - runs example CJS node script
3217
3392
  - `yarn example:esm` - runs example ESM node script
3218
3393
  - `yarn example:vite` - runs example Vite web page
3219
3394
 
@@ -3236,21 +3411,14 @@ For more information on how to contribute, please see [CONTRIBUTING.md].
3236
3411
  <!-- ADD ALL LINK REFERENCES BELOW -->
3237
3412
 
3238
3413
  [ar.io]: https://ar.io
3239
- [permaweb/aoconnect]: https://github.com/permaweb/aoconnect
3240
- [package.json]: ./package.json
3241
3414
  [examples]: ./examples
3242
3415
  [examples/webpack]: ./examples/webpack
3243
3416
  [examples/vite]: ./examples/vite
3244
3417
  [CONTRIBUTING.md]: ./CONTRIBUTING.md
3245
- [AO Connect]: https://github.com/permaweb/ao/tree/main/connect
3246
- [ARIO Testnet Process]: https://www.ao.link/#/entity/agYcCFJtrMG6cqMuZfskIkFTGvUPddICmtQSBIoPdiA
3247
- [ARIO Network Spec]: https://github.com/ar-io/ar-io-network-process?tab=readme-ov-file#contract-spec
3248
- [Winston]: https://www.npmjs.com/package/winston
3249
- [AO]: https://github.com/permaweb/ao
3250
3418
  [ar-io-node repository]: https://github.com/ar-io/ar-io-node
3251
3419
  [ar.io Gateway Documentation]: https://docs.ar.io/gateways/ar-io-node/overview/
3252
3420
  [ANS-104]: https://github.com/ArweaveTeam/arweave-standards/blob/master/ans/ANS-104.md
3253
- [ar-io-testnet-faucet]: https://github.com/ar-io/ar-io-testnet-faucet?tab=readme-ov-file#asynchronous-workflow
3421
+ [opossum]: https://nodeshift.dev/opossum/
3254
3422
 
3255
3423
  ```
3256
3424