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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +682 -600
  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 +221 -0
  6. package/lib/esm/cli/commands/gatewayWriteCommands.js +142 -23
  7. package/lib/esm/cli/commands/pruneCommands.js +150 -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 +280 -174
  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 +11 -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 +51 -263
  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
@@ -1,1417 +1,30 @@
1
- /**
2
- * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
3
- *
4
- * Licensed under the Apache License, Version 2.0 (the "License");
5
- * you may not use this file except in compliance with the License.
6
- * You may obtain a copy of the License at
7
- *
8
- * http://www.apache.org/licenses/LICENSE-2.0
9
- *
10
- * Unless required by applicable law or agreed to in writing, software
11
- * distributed under the License is distributed on an "AS IS" BASIS,
12
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
- * See the License for the specific language governing permissions and
14
- * limitations under the License.
15
- */
16
- import { connect } from '@permaweb/aoconnect';
17
- import { ANT_REGISTRY_ID, ARIO_MAINNET_PROCESS_ID, ARIO_TESTNET_PROCESS_ID, } from '../constants.js';
18
- import { isProcessConfiguration, isProcessIdConfiguration, } from '../types/index.js';
19
- import { createAoSigner } from '../utils/ao.js';
20
- import { getEpochDataFromGqlWithCUFallback, paginationParamsToTags, pruneTags, removeEligibleRewardsFromEpochData, sortAndPaginateEpochDataIntoEligibleDistributions, } from '../utils/arweave.js';
21
- import { ANTRegistry } from './ant-registry.js';
22
- import { ANT } from './ant.js';
23
- import { defaultArweave } from './arweave.js';
24
- import { AOProcess } from './contracts/ao-process.js';
25
- import { InvalidContractConfigurationError } from './error.js';
26
- import { createFaucet } from './faucet.js';
27
- import { HB } from './hyperbeam/hb.js';
28
- import { Logger } from './logger.js';
29
- import { TurboArNSPaymentFactory, TurboArNSPaymentProviderAuthenticated, isTurboArNSSigner, } from './turbo.js';
1
+ import { SolanaARIOReadable } from '../solana/io-readable.js';
2
+ import { SolanaARIOWriteable } from '../solana/io-writeable.js';
3
+ export const DEFAULT_SOLANA_RPC_URL = 'https://api.mainnet-beta.solana.com';
30
4
  export class ARIO {
31
- // Implementation
32
5
  static init(config) {
33
- if (config !== undefined && 'signer' in config) {
34
- return new ARIOWriteable(config);
35
- }
36
- return new ARIOReadable(config);
37
- }
38
- static mainnet(config) {
39
- if (config !== undefined && 'signer' in config) {
40
- return new ARIOWriteable({
41
- ...config,
42
- process: new AOProcess({
43
- processId: ARIO_MAINNET_PROCESS_ID,
44
- ao: connect({
45
- MODE: 'legacy',
46
- CU_URL: 'https://cu.ardrive.io',
47
- ...config?.process?.ao,
48
- }),
49
- }),
50
- });
51
- }
52
- return new ARIOReadable({
53
- ...config,
54
- process: new AOProcess({
55
- processId: ARIO_MAINNET_PROCESS_ID,
56
- ao: connect({
57
- CU_URL: 'https://cu.ardrive.io',
58
- MODE: 'legacy',
59
- ...config?.process?.ao,
60
- }),
61
- }),
62
- });
63
- }
64
- static testnet(config) {
65
- if (config !== undefined && 'signer' in config) {
66
- return createFaucet({
67
- arioInstance: new ARIOWriteable({
68
- ...config,
69
- process: new AOProcess({
70
- processId: ARIO_TESTNET_PROCESS_ID,
71
- ao: connect({
72
- MODE: 'legacy',
73
- CU_URL: 'https://cu.ardrive.io',
74
- ...config?.process?.ao,
75
- }),
76
- }),
77
- }),
78
- faucetApiUrl: config?.faucetUrl,
79
- });
80
- }
81
- return createFaucet({
82
- arioInstance: new ARIOReadable({
83
- ...config,
84
- process: new AOProcess({
85
- processId: ARIO_TESTNET_PROCESS_ID,
86
- ao: connect({
87
- MODE: 'legacy',
88
- CU_URL: 'https://cu.ardrive.io',
89
- ...config?.process?.ao,
90
- }),
91
- }),
92
- }),
93
- faucetApiUrl: config?.faucetUrl,
94
- });
95
- }
96
- }
97
- export class ARIOReadable {
98
- process;
99
- epochSettings;
100
- arweave;
101
- hyperbeamUrl;
102
- paymentProvider; // TODO: this could be an array/map of payment providers
103
- logger = Logger.default;
104
- hb;
105
- constructor(config) {
106
- this.arweave = config?.arweave ?? defaultArweave;
107
- if (config === undefined || Object.keys(config).length === 0) {
108
- this.process = new AOProcess({
109
- processId: ARIO_MAINNET_PROCESS_ID,
110
- });
111
- }
112
- else if (isProcessConfiguration(config)) {
113
- this.process = config.process;
114
- }
115
- else if (isProcessIdConfiguration(config)) {
116
- this.process = new AOProcess({
117
- processId: config.processId,
118
- });
119
- }
120
- else {
121
- throw new InvalidContractConfigurationError();
122
- }
123
- // only use hyperbeam if the client has provided a hyperbeamUrl
124
- // this will avoid overwhelming the HyperBeam node with requests
125
- // as we shift using HyperBEAM for all ANT operations
126
- if (config?.hyperbeamUrl !== undefined) {
127
- this.hyperbeamUrl = config.hyperbeamUrl;
128
- this.hb = new HB({
129
- url: this.hyperbeamUrl,
130
- processId: this.process.processId,
131
- });
132
- this.logger.debug(`Using HyperBEAM node for process ${this.process.processId}`, {
133
- hyperbeamUrl: this.hyperbeamUrl,
134
- });
135
- }
136
- this.paymentProvider = TurboArNSPaymentFactory.init({
137
- paymentUrl: config?.paymentUrl,
138
- });
139
- }
140
- async getInfo() {
141
- return this.process.read({
142
- tags: [{ name: 'Action', value: 'Info' }],
143
- });
144
- }
145
- async getTokenSupply() {
146
- return this.process.read({
147
- tags: [{ name: 'Action', value: 'Total-Token-Supply' }],
148
- });
149
- }
150
- async computeEpochIndexForTimestamp(timestamp) {
151
- const epochSettings = await this.getEpochSettings();
152
- const epochZeroStartTimestamp = epochSettings.epochZeroStartTimestamp;
153
- const epochLengthMs = epochSettings.durationMs;
154
- return Math.floor((timestamp - epochZeroStartTimestamp) / epochLengthMs);
155
- }
156
- async computeCurrentEpochIndex() {
157
- return this.computeEpochIndexForTimestamp(Date.now());
158
- }
159
- async computeEpochIndex(params) {
160
- const epochIndex = params?.epochIndex;
161
- if (epochIndex !== undefined) {
162
- return epochIndex;
163
- }
164
- const timestamp = params?.timestamp;
165
- if (timestamp !== undefined) {
166
- return this.computeEpochIndexForTimestamp(timestamp);
167
- }
168
- return undefined;
169
- }
170
- async getEpochSettings() {
171
- return (this.epochSettings ??= await this.process.read({
172
- tags: [{ name: 'Action', value: 'Epoch-Settings' }],
173
- }));
174
- }
175
- async getEpoch(epoch) {
176
- const epochIndex = await this.computeEpochIndex(epoch);
177
- const currentIndex = await this.computeCurrentEpochIndex();
178
- if (epochIndex !== undefined && epochIndex < currentIndex) {
179
- const epochData = await getEpochDataFromGqlWithCUFallback({
180
- arweave: this.arweave,
181
- epochIndex: epochIndex,
182
- processId: this.process.processId,
183
- ao: this.process.ao,
184
- });
185
- if (!epochData) {
186
- throw new Error('Epoch data not found for epoch index ' + epochIndex);
187
- }
188
- return removeEligibleRewardsFromEpochData(epochData);
189
- }
190
- // go to the process epoch and fetch the epoch data
191
- const allTags = [
192
- { name: 'Action', value: 'Epoch' },
193
- {
194
- name: 'Epoch-Index',
195
- value: currentIndex.toString(),
196
- },
197
- ];
198
- return this.process.read({
199
- tags: pruneTags(allTags),
200
- });
201
- }
202
- async getArNSRecord({ name }) {
203
- return this.process.read({
204
- tags: [
205
- { name: 'Action', value: 'Record' },
206
- { name: 'Name', value: name },
207
- ],
208
- });
209
- }
210
- async getArNSRecords(params) {
211
- return this.process.read({
212
- tags: [
213
- { name: 'Action', value: 'Paginated-Records' },
214
- ...paginationParamsToTags(params),
215
- ],
216
- });
217
- }
218
- async getArNSReservedNames(params) {
219
- return this.process.read({
220
- tags: [
221
- { name: 'Action', value: 'Reserved-Names' },
222
- ...paginationParamsToTags(params),
223
- ],
224
- });
225
- }
226
- async getArNSReservedName({ name, }) {
227
- return this.process.read({
228
- tags: [
229
- { name: 'Action', value: 'Reserved-Name' },
230
- { name: 'Name', value: name },
231
- ],
232
- });
233
- }
234
- async getBalance({ address }) {
235
- if (this.hb && (await this.hb.checkHyperBeamCompatibility())) {
236
- this.logger.debug('Getting balance from HyperBEAM', { address });
237
- const res = await this.hb
238
- .compute({
239
- path: `balances/${address}`,
240
- })
241
- .then((res) => Number(res))
242
- .catch((error) => {
243
- this.logger.error('Failed to get balance from HyperBEAM', {
244
- cause: error,
245
- });
246
- return null;
247
- });
248
- if (res !== null)
249
- return res;
250
- // else fall through to CU read
251
- this.logger.info('Failed to get balance from HyperBEAM, failing over to to CU read', { address });
252
- }
253
- return this.process.read({
254
- tags: [
255
- { name: 'Action', value: 'Balance' },
256
- { name: 'Address', value: address },
257
- ],
258
- });
259
- }
260
- async getBalances(params) {
261
- return this.process.read({
262
- tags: [
263
- { name: 'Action', value: 'Paginated-Balances' },
264
- ...paginationParamsToTags(params),
265
- ],
266
- });
267
- }
268
- async getVault({ address, vaultId, }) {
269
- return this.process.read({
270
- tags: [
271
- { name: 'Action', value: 'Vault' },
272
- { name: 'Address', value: address },
273
- { name: 'Vault-Id', value: vaultId },
274
- ],
275
- });
276
- }
277
- async getVaults(params) {
278
- return this.process.read({
279
- tags: [
280
- { name: 'Action', value: 'Paginated-Vaults' },
281
- ...paginationParamsToTags(params),
282
- ],
283
- });
284
- }
285
- async getGateway({ address, }) {
286
- return this.process.read({
287
- tags: [
288
- { name: 'Action', value: 'Gateway' },
289
- { name: 'Address', value: address },
290
- ],
291
- });
292
- }
293
- async getGatewayDelegates({ address, ...pageParams }) {
294
- return this.process.read({
295
- tags: [
296
- { name: 'Action', value: 'Paginated-Delegates' },
297
- { name: 'Address', value: address },
298
- ...paginationParamsToTags(pageParams),
299
- ],
300
- });
301
- }
302
- async getGatewayDelegateAllowList({ address, ...pageParams }) {
303
- return this.process.read({
304
- tags: [
305
- { name: 'Action', value: 'Paginated-Allowed-Delegates' },
306
- { name: 'Address', value: address },
307
- ...paginationParamsToTags(pageParams),
308
- ],
309
- });
310
- }
311
- async getGateways(pageParams) {
312
- return this.process.read({
313
- tags: [
314
- { name: 'Action', value: 'Paginated-Gateways' },
315
- ...paginationParamsToTags(pageParams),
316
- ],
317
- });
318
- }
319
- async getCurrentEpoch() {
320
- return this.process.read({
321
- tags: [{ name: 'Action', value: 'Epoch' }],
322
- });
323
- }
324
- async getPrescribedObservers(epoch) {
325
- const epochIndex = await this.computeEpochIndex(epoch);
326
- const currentIndex = await this.computeCurrentEpochIndex();
327
- if (epochIndex !== undefined && epochIndex < currentIndex) {
328
- const epochData = await getEpochDataFromGqlWithCUFallback({
329
- ao: this.process.ao,
330
- arweave: this.arweave,
331
- epochIndex: epochIndex,
332
- processId: this.process.processId,
333
- });
334
- if (!epochData) {
335
- throw new Error('Epoch data not found for epoch index ' + epochIndex);
336
- }
337
- return epochData.prescribedObservers;
338
- }
339
- const allTags = [
340
- { name: 'Action', value: 'Epoch-Prescribed-Observers' },
341
- {
342
- name: 'Epoch-Index',
343
- value: currentIndex.toString(),
344
- },
345
- ];
346
- return this.process.read({
347
- tags: pruneTags(allTags),
348
- });
349
- }
350
- async getPrescribedNames(epoch) {
351
- const epochIndex = await this.computeEpochIndex(epoch);
352
- const currentIndex = await this.computeCurrentEpochIndex();
353
- if (epochIndex !== undefined && epochIndex < currentIndex) {
354
- const epochData = await getEpochDataFromGqlWithCUFallback({
355
- arweave: this.arweave,
356
- epochIndex: epochIndex,
357
- processId: this.process.processId,
358
- ao: this.process.ao,
359
- });
360
- if (!epochData) {
361
- throw new Error('Epoch data not found for epoch index ' + epochIndex);
362
- }
363
- return epochData.prescribedNames;
364
- }
365
- const allTags = [
366
- { name: 'Action', value: 'Epoch-Prescribed-Names' },
367
- {
368
- name: 'Epoch-Index',
369
- value: currentIndex.toString(),
370
- },
371
- ];
372
- return this.process.read({
373
- tags: pruneTags(allTags),
374
- });
375
- }
376
- // we need to find the epoch index for the epoch that is currently being distributed and fetch it from gql
377
- async getObservations(epoch) {
378
- const epochIndex = await this.computeEpochIndex(epoch);
379
- const currentIndex = await this.computeCurrentEpochIndex();
380
- if (epochIndex !== undefined && epochIndex < currentIndex) {
381
- const epochData = await getEpochDataFromGqlWithCUFallback({
382
- arweave: this.arweave,
383
- epochIndex: epochIndex,
384
- processId: this.process.processId,
385
- ao: this.process.ao,
386
- });
387
- if (!epochData) {
388
- throw new Error('Epoch data not found for epoch index ' + epochIndex);
389
- }
390
- return epochData.observations;
391
- }
392
- // go to the process epoch and fetch the observations
393
- const allTags = [
394
- { name: 'Action', value: 'Epoch-Observations' },
395
- {
396
- name: 'Epoch-Index',
397
- value: currentIndex.toString(),
398
- },
399
- ];
400
- return this.process.read({
401
- tags: pruneTags(allTags),
402
- });
403
- }
404
- async getDistributions(epoch) {
405
- const epochIndex = await this.computeEpochIndex(epoch);
406
- const currentIndex = await this.computeCurrentEpochIndex();
407
- if (epochIndex !== undefined && epochIndex < currentIndex) {
408
- const epochData = await getEpochDataFromGqlWithCUFallback({
409
- arweave: this.arweave,
410
- epochIndex: epochIndex,
411
- processId: this.process.processId,
412
- ao: this.process.ao,
413
- });
414
- if (epochData === undefined) {
415
- throw new Error('Epoch data not found for epoch index ' + epochIndex);
416
- }
417
- return epochData.distributions;
418
- }
419
- // go to the process epoch and fetch the distributions
420
- const allTags = [
421
- { name: 'Action', value: 'Epoch-Distributions' },
422
- {
423
- name: 'Epoch-Index',
424
- value: currentIndex.toString(),
425
- },
426
- ];
427
- return this.process.read({
428
- tags: pruneTags(allTags),
429
- });
430
- }
431
- async getEligibleEpochRewards(epoch, params) {
432
- const epochIndex = await this.computeEpochIndex(epoch);
433
- const currentIndex = await this.computeCurrentEpochIndex();
434
- if (epochIndex !== undefined && epochIndex < currentIndex) {
435
- const epochData = await getEpochDataFromGqlWithCUFallback({
436
- arweave: this.arweave,
437
- epochIndex: epochIndex,
438
- processId: this.process.processId,
439
- ao: this.process.ao,
440
- });
441
- if (!epochData) {
442
- throw new Error('Epoch data not found for epoch index ' + epochIndex);
443
- }
444
- return sortAndPaginateEpochDataIntoEligibleDistributions(epochData, params);
445
- }
446
- // on current epoch, go to process and fetch the distributions
447
- const allTags = [
448
- { name: 'Action', value: 'Epoch-Eligible-Rewards' },
449
- ...paginationParamsToTags(params),
450
- ];
451
- return this.process.read({
452
- tags: pruneTags(allTags),
453
- });
454
- }
455
- async getTokenCost({ intent, type, years, name, quantity, fromAddress, }) {
456
- const replacedBuyRecordWithBuyName = intent === 'Buy-Record' ? 'Buy-Name' : intent;
457
- const allTags = [
458
- { name: 'Action', value: 'Token-Cost' },
459
- {
460
- name: 'Intent',
461
- value: replacedBuyRecordWithBuyName,
462
- },
463
- {
464
- name: 'Name',
465
- value: name,
466
- },
467
- {
468
- name: 'Years',
469
- value: years?.toString(),
470
- },
471
- {
472
- name: 'Quantity',
473
- value: quantity?.toString(),
474
- },
475
- {
476
- name: 'Purchase-Type',
477
- value: type,
478
- },
479
- ];
480
- return this.process.read({
481
- tags: pruneTags(allTags),
482
- fromAddress,
483
- });
484
- }
485
- // TODO: Can overload this function to refine different types of cost details params
486
- async getCostDetails({ intent, type, years, name, quantity, fromAddress, fundFrom, }) {
487
- const replacedBuyRecordWithBuyName = intent === 'Buy-Record' ? 'Buy-Name' : intent;
488
- if (fundFrom === 'turbo') {
489
- const { mARIO, winc } = await this.paymentProvider.getArNSPriceDetails({
490
- intent: replacedBuyRecordWithBuyName,
491
- name,
492
- quantity,
493
- type,
494
- years,
495
- });
496
- return {
497
- tokenCost: mARIO.valueOf(),
498
- wincQty: winc,
499
- discounts: [],
500
- };
501
- }
502
- const allTags = [
503
- { name: 'Action', value: 'Cost-Details' },
504
- {
505
- name: 'Intent',
506
- value: replacedBuyRecordWithBuyName,
507
- },
508
- {
509
- name: 'Name',
510
- value: name,
511
- },
512
- {
513
- name: 'Years',
514
- value: years?.toString(),
515
- },
516
- {
517
- name: 'Quantity',
518
- value: quantity?.toString(),
519
- },
520
- {
521
- name: 'Purchase-Type',
522
- value: type,
523
- },
524
- {
525
- name: 'Fund-From',
526
- value: fundFrom,
527
- },
528
- ];
529
- return this.process.read({
530
- tags: pruneTags(allTags),
531
- fromAddress,
532
- });
533
- }
534
- async getRegistrationFees() {
535
- return this.process.read({
536
- tags: [{ name: 'Action', value: 'Registration-Fees' }],
537
- });
538
- }
539
- async getDemandFactor() {
540
- return this.process.read({
541
- tags: [{ name: 'Action', value: 'Demand-Factor' }],
542
- });
543
- }
544
- async getDemandFactorSettings() {
545
- return this.process.read({
546
- tags: [{ name: 'Action', value: 'Demand-Factor-Settings' }],
547
- });
548
- }
549
- async getArNSReturnedNames(params) {
550
- return this.process.read({
551
- tags: [
552
- { name: 'Action', value: 'Returned-Names' },
553
- ...paginationParamsToTags(params),
554
- ],
555
- });
556
- }
557
- async getArNSReturnedName({ name, }) {
558
- const allTags = [
559
- { name: 'Action', value: 'Returned-Name' },
560
- { name: 'Name', value: name },
561
- ];
562
- return this.process.read({
563
- tags: allTags,
564
- });
565
- }
566
- async getDelegations(params) {
567
- const allTags = [
568
- { name: 'Action', value: 'Paginated-Delegations' },
569
- { name: 'Address', value: params.address },
570
- ...paginationParamsToTags(params),
571
- ];
572
- return this.process.read({
573
- tags: pruneTags(allTags),
574
- });
575
- }
576
- async getAllowedDelegates(params) {
577
- return this.getGatewayDelegateAllowList(params);
578
- }
579
- async getGatewayVaults(params) {
580
- return this.process.read({
581
- tags: [
582
- { name: 'Action', value: 'Paginated-Gateway-Vaults' },
583
- { name: 'Address', value: params.address },
584
- ...paginationParamsToTags(params),
585
- ],
586
- });
587
- }
588
- async getPrimaryNameRequest(params) {
589
- if (this.hb && (await this.hb.checkHyperBeamCompatibility())) {
590
- this.logger.debug('Getting primary name request from HyperBEAM', {
591
- initiator: params.initiator,
592
- });
593
- const res = await this.hb
594
- .compute({
595
- path: `/primary-names/requests/${params.initiator}`,
596
- })
597
- .catch((error) => {
598
- this.logger.error('Failed to get primary name request from HyperBEAM', {
599
- cause: error,
600
- });
601
- return null;
602
- });
603
- if (res !== null) {
604
- // Ensure initiator is included in the result
605
- return {
606
- ...res,
607
- initiator: params.initiator,
608
- };
609
- }
610
- // else fall through to CU read
611
- this.logger.info('Failed to get primary name request from HyperBEAM, failing over to CU read', { initiator: params.initiator });
612
- }
613
- const allTags = [
614
- { name: 'Action', value: 'Primary-Name-Request' },
615
- {
616
- name: 'Initiator',
617
- value: params.initiator,
618
- },
619
- ];
620
- return this.process.read({
621
- tags: allTags,
622
- });
623
- }
624
- async getPrimaryNameRequests(params) {
625
- return this.process.read({
626
- tags: [
627
- { name: 'Action', value: 'Primary-Name-Requests' },
628
- ...paginationParamsToTags(params),
629
- ],
630
- });
631
- }
632
- async getPrimaryName(params) {
633
- if (this.hb && (await this.hb.checkHyperBeamCompatibility())) {
634
- this.logger.debug('Getting primary name from HyperBEAM', { params });
635
- try {
636
- let owner;
637
- if ('name' in params) {
638
- // Step 1: Get owner from /primary-names/names/<name>
639
- owner = await this.hb.compute({
640
- path: `/primary-names/names/${params.name}`,
641
- });
642
- }
643
- else {
644
- // If given address, skip the /names/name query
645
- owner = params.address;
646
- }
647
- // Step 2: Get {name, startTimestamp} from /primary-names/owners/<owner>
648
- const ownerData = await this.hb.compute({
649
- path: `/primary-names/owners/${owner}`,
650
- });
651
- const name = ownerData.name;
652
- const startTimestamp = ownerData.startTimestamp;
653
- // Step 3: Get processId from getArNSRecord
654
- const record = await this.getArNSRecord({ name });
655
- const processId = record.processId;
656
- // Combine all data
657
- const result = {
658
- owner,
659
- name,
660
- startTimestamp,
661
- processId,
662
- };
663
- return result;
664
- }
665
- catch (error) {
666
- this.logger.error('Failed to get primary name from HyperBEAM', {
667
- cause: error,
668
- });
669
- // Fall through to CU read
670
- this.logger.info('Failed to get primary name from HyperBEAM, failing over to CU read', { params });
671
- }
672
- }
673
- const allTags = [
674
- { name: 'Action', value: 'Primary-Name' },
675
- {
676
- name: 'Address',
677
- value: params?.address,
678
- },
679
- { name: 'Name', value: params?.name },
680
- ];
681
- return this.process.read({
682
- tags: pruneTags(allTags),
683
- });
684
- }
685
- async getPrimaryNames(params) {
686
- return this.process.read({
687
- tags: [
688
- { name: 'Action', value: 'Primary-Names' },
689
- ...paginationParamsToTags(params),
690
- ],
691
- });
692
- }
693
- /**
694
- * Get current redelegation fee percentage for address
695
- *
696
- * @param {Object} params - The parameters for fetching redelegation fee
697
- * @param {string} params.address - The address to fetch the fee for
698
- * @returns {Promise<AoMessageResult>} The redelegation fee result
699
- */
700
- async getRedelegationFee(params) {
701
- return this.process.read({
702
- tags: [
703
- { name: 'Action', value: 'Redelegation-Fee' },
704
- { name: 'Address', value: params.address },
705
- ],
706
- });
707
- }
708
- async getGatewayRegistrySettings() {
709
- return this.process.read({
710
- tags: [{ name: 'Action', value: 'Gateway-Registry-Settings' }],
711
- });
712
- }
713
- async getAllDelegates(params) {
714
- return this.process.read({
715
- tags: [
716
- { name: 'Action', value: 'All-Paginated-Delegates' },
717
- ...paginationParamsToTags(params),
718
- ],
719
- });
720
- }
721
- async getAllGatewayVaults(params) {
722
- return this.process.read({
723
- tags: [
724
- { name: 'Action', value: 'All-Gateway-Vaults' },
725
- ...paginationParamsToTags(params),
726
- ],
727
- });
728
- }
729
- async resolveArNSName({ name, }) {
730
- // derive baseName & undername using last underscore
731
- const lastUnderscore = name.lastIndexOf('_');
732
- const baseName = lastUnderscore === -1 ? name : name.slice(lastUnderscore + 1);
733
- const undername = lastUnderscore === -1 ? '@' : name.slice(0, lastUnderscore);
734
- // guard against missing or unregistered ARNS record
735
- const nameData = await this.getArNSRecord({ name: baseName });
736
- if (nameData === undefined || nameData.processId === undefined) {
737
- throw new Error(`Base ArNS name ${baseName} not found on ARIO contract (${this.process.processId}).`);
738
- }
739
- const ant = ANT.init({
740
- process: new AOProcess({
741
- ao: this.process.ao,
742
- processId: nameData.processId,
743
- }),
744
- hyperbeamUrl: this.hyperbeamUrl,
745
- });
746
- const [owner, antRecord] = await Promise.all([
747
- ant.getOwner(),
748
- ant.getRecord({ undername }),
749
- ]);
750
- if (antRecord === undefined) {
751
- throw new Error(`Record for ${undername} not found on ANT.`);
752
- }
753
- if (antRecord.ttlSeconds === undefined ||
754
- antRecord.transactionId === undefined) {
755
- throw new Error(`Invalid record on ANT. Must have ttlSeconds and transactionId. Record: ${JSON.stringify(antRecord)}`);
756
- }
757
- return {
758
- name,
759
- owner,
760
- txId: antRecord.transactionId,
761
- ttlSeconds: antRecord.ttlSeconds,
762
- priority: antRecord.priority,
763
- // NOTE: we may want return the actual index of the record based on sorting
764
- // in case ANT tries to set duplicate priority values to get around undername limits
765
- processId: nameData.processId,
766
- undernameLimit: nameData.undernameLimit,
767
- type: nameData.type,
768
- };
769
- }
770
- /**
771
- * Get all ARNS names associated with an address using the provided ANT registry address.
772
- *
773
- * By default it will use the mainnet ANT registry address.
774
- *
775
- * @param {Object} params - The parameters for fetching ARNS names
776
- * @param {string} params.address - The address to fetch the ARNS names for
777
- * @returns {Promise<AoArNSNameData[]>} The ARNS names associated with the address
778
- */
779
- async getArNSRecordsForAddress(params) {
780
- const { antRegistryProcessId = ANT_REGISTRY_ID, address } = params;
781
- const antRegistry = ANTRegistry.init({
782
- hyperbeamUrl: this.hyperbeamUrl,
783
- process: new AOProcess({
784
- ao: this.process.ao,
785
- processId: antRegistryProcessId,
786
- }),
787
- });
788
- // Note: there could be a race condition here if the ACL changes during pagination requests, resulting in different results from the `getArNSRecords`.
789
- // This is an unlikely scenario, so to give the client control, and keep this API consistent with other ArNS APIs, we refetch the ACL for each page, and
790
- // return paginated results.
791
- const { Controlled = [], Owned = [] } = await antRegistry.accessControlList({
792
- address,
793
- });
794
- const allProcessIds = new Set([...Controlled, ...Owned]);
795
- if (allProcessIds.size === 0) {
796
- return {
797
- items: [],
798
- hasMore: false,
799
- nextCursor: undefined,
800
- limit: params.limit ?? 1000,
801
- totalItems: 0,
802
- sortOrder: params.sortOrder ?? 'asc',
803
- };
804
- }
805
- const currentPage = await this.getArNSRecords({
806
- ...params,
807
- filters: {
808
- // NOTE: we confirmed that dry-runs are not limited to the same tag limits as data-items.
809
- // Should this change, we'll need to batch the requests.
810
- processId: Array.from(allProcessIds),
811
- },
812
- });
813
- return currentPage;
814
- }
815
- }
816
- export class ARIOWriteable extends ARIOReadable {
817
- signer;
818
- paymentProvider;
819
- constructor({ signer, paymentUrl, ...config }) {
820
- if (config === undefined) {
821
- super({
822
- process: new AOProcess({
823
- processId: ARIO_MAINNET_PROCESS_ID,
824
- }),
825
- });
826
- }
827
- else {
828
- super(config);
829
- }
830
- this.signer = createAoSigner(signer);
831
- this.paymentProvider = TurboArNSPaymentFactory.init({
832
- signer: isTurboArNSSigner(signer) ? signer : undefined,
833
- paymentUrl,
834
- });
835
- }
836
- async transfer({ target, qty, }, options) {
837
- const { tags = [] } = options || {};
838
- return this.process.send({
839
- tags: [
840
- ...tags,
841
- { name: 'Action', value: 'Transfer' },
842
- {
843
- name: 'Recipient',
844
- value: target,
845
- },
846
- {
847
- name: 'Quantity',
848
- value: qty.valueOf().toString(),
849
- },
850
- ],
851
- signer: this.signer,
852
- });
853
- }
854
- async vaultedTransfer({ recipient, quantity, lockLengthMs, revokable = false, }, options) {
855
- const { tags = [] } = options || {};
856
- return this.process.send({
857
- tags: [
858
- ...tags,
859
- { name: 'Action', value: 'Vaulted-Transfer' },
860
- { name: 'Recipient', value: recipient },
861
- { name: 'Quantity', value: quantity.toString() },
862
- { name: 'Lock-Length', value: lockLengthMs.toString() },
863
- { name: 'Revokable', value: `${revokable}` },
864
- ],
865
- signer: this.signer,
866
- });
867
- }
868
- async revokeVault({ vaultId, recipient }, options) {
869
- const { tags = [] } = options || {};
870
- return this.process.send({
871
- tags: [
872
- ...tags,
873
- { name: 'Action', value: 'Revoke-Vault' },
874
- { name: 'Vault-Id', value: vaultId },
875
- { name: 'Recipient', value: recipient },
876
- ],
877
- signer: this.signer,
878
- });
879
- }
880
- async createVault({ lockLengthMs, quantity }, options) {
881
- const { tags = [] } = options || {};
882
- return this.process.send({
883
- tags: [
884
- ...tags,
885
- { name: 'Action', value: 'Create-Vault' },
886
- { name: 'Lock-Length', value: lockLengthMs.toString() },
887
- { name: 'Quantity', value: quantity.toString() },
888
- ],
889
- signer: this.signer,
890
- });
891
- }
892
- async extendVault({ vaultId, extendLengthMs }, options) {
893
- const { tags = [] } = options || {};
894
- return this.process.send({
895
- tags: [
896
- ...tags,
897
- { name: 'Action', value: 'Extend-Vault' },
898
- { name: 'Vault-Id', value: vaultId },
899
- { name: 'Extend-Length', value: extendLengthMs.toString() },
900
- ],
901
- signer: this.signer,
902
- });
903
- }
904
- async increaseVault({ vaultId, quantity }, options) {
905
- const { tags = [] } = options || {};
906
- return this.process.send({
907
- tags: [
908
- ...tags,
909
- { name: 'Action', value: 'Increase-Vault' },
910
- { name: 'Vault-Id', value: vaultId },
911
- { name: 'Quantity', value: quantity.toString() },
912
- ],
913
- signer: this.signer,
914
- });
915
- }
916
- async joinNetwork({ operatorStake, allowDelegatedStaking, allowedDelegates, delegateRewardShareRatio, fqdn, label, minDelegatedStake, note, port, properties, protocol, autoStake, observerAddress, services, }, options) {
917
- const { tags = [] } = options || {};
918
- const allTags = [
919
- ...tags,
920
- { name: 'Action', value: 'Join-Network' },
921
- {
922
- name: 'Operator-Stake',
923
- value: operatorStake.valueOf().toString(),
924
- },
925
- {
926
- name: 'Allow-Delegated-Staking',
927
- value: allowDelegatedStaking?.toString(),
928
- },
929
- {
930
- name: 'Allowed-Delegates',
931
- value: allowedDelegates?.join(','),
932
- },
933
- {
934
- name: 'Delegate-Reward-Share-Ratio',
935
- value: delegateRewardShareRatio?.toString(),
936
- },
937
- {
938
- name: 'FQDN',
939
- value: fqdn,
940
- },
941
- {
942
- name: 'Label',
943
- value: label,
944
- },
945
- {
946
- name: 'Min-Delegated-Stake',
947
- value: minDelegatedStake?.valueOf().toString(),
948
- },
949
- {
950
- name: 'Note',
951
- value: note,
952
- },
953
- {
954
- name: 'Port',
955
- value: port?.toString(),
956
- },
957
- {
958
- name: 'Properties',
959
- value: properties,
960
- },
961
- {
962
- name: 'Protocol',
963
- value: protocol,
964
- },
965
- {
966
- name: 'Auto-Stake',
967
- value: autoStake?.toString(),
968
- },
969
- {
970
- name: 'Observer-Address',
971
- value: observerAddress,
972
- },
973
- {
974
- name: 'Services',
975
- value: services ? JSON.stringify(services) : undefined,
976
- },
977
- ];
978
- return this.process.send({
979
- signer: this.signer,
980
- tags: pruneTags(allTags),
981
- });
982
- }
983
- async leaveNetwork(options) {
984
- const { tags = [] } = options || {};
985
- return this.process.send({
986
- signer: this.signer,
987
- tags: [...tags, { name: 'Action', value: 'Leave-Network' }],
988
- });
989
- }
990
- async updateGatewaySettings({ allowDelegatedStaking, allowedDelegates, delegateRewardShareRatio, fqdn, label, minDelegatedStake, note, port, properties, protocol, autoStake, observerAddress, services, }, options) {
991
- const { tags = [] } = options || {};
992
- const allTags = [
993
- ...tags,
994
- { name: 'Action', value: 'Update-Gateway-Settings' },
995
- { name: 'Label', value: label },
996
- { name: 'Note', value: note },
997
- { name: 'FQDN', value: fqdn },
998
- { name: 'Port', value: port?.toString() },
999
- { name: 'Properties', value: properties },
1000
- { name: 'Protocol', value: protocol },
1001
- { name: 'Observer-Address', value: observerAddress },
1002
- {
1003
- name: 'Allow-Delegated-Staking',
1004
- value: allowDelegatedStaking?.toString(),
1005
- },
1006
- {
1007
- name: 'Allowed-Delegates',
1008
- value: allowedDelegates?.join(','),
1009
- },
1010
- {
1011
- name: 'Delegate-Reward-Share-Ratio',
1012
- value: delegateRewardShareRatio?.toString(),
1013
- },
1014
- {
1015
- name: 'Min-Delegated-Stake',
1016
- value: minDelegatedStake?.valueOf().toString(),
1017
- },
1018
- { name: 'Auto-Stake', value: autoStake?.toString() },
1019
- {
1020
- name: 'Services',
1021
- value: services ? JSON.stringify(services) : undefined,
1022
- },
1023
- ];
1024
- return this.process.send({
1025
- signer: this.signer,
1026
- tags: pruneTags(allTags),
1027
- });
1028
- }
1029
- async delegateStake(params, options) {
1030
- const { tags = [] } = options || {};
1031
- return this.process.send({
1032
- signer: this.signer,
1033
- tags: [
1034
- ...tags,
1035
- { name: 'Action', value: 'Delegate-Stake' },
1036
- { name: 'Target', value: params.target },
1037
- { name: 'Quantity', value: params.stakeQty.valueOf().toString() },
1038
- ],
1039
- });
1040
- }
1041
- async decreaseDelegateStake(params, options) {
1042
- const { tags = [] } = options || {};
1043
- return this.process.send({
1044
- signer: this.signer,
1045
- tags: [
1046
- ...tags,
1047
- { name: 'Action', value: 'Decrease-Delegate-Stake' },
1048
- { name: 'Target', value: params.target },
1049
- { name: 'Quantity', value: params.decreaseQty.valueOf().toString() },
1050
- { name: 'Instant', value: `${params.instant || false}` },
1051
- ],
1052
- });
1053
- }
1054
- /**
1055
- * Initiates an instant withdrawal from a gateway.
1056
- *
1057
- * @param {Object} params - The parameters for initiating an instant withdrawal
1058
- * @param {string} params.address - The gateway address of the withdrawal, if not provided, the signer's address will be used
1059
- * @param {string} params.vaultId - The vault ID of the withdrawal
1060
- * @returns {Promise<AoMessageResult>} The result of the withdrawal
1061
- */
1062
- async instantWithdrawal(params, options) {
1063
- const { tags = [] } = options || {};
1064
- const allTags = [
1065
- ...tags,
1066
- { name: 'Action', value: 'Instant-Withdrawal' },
1067
- { name: 'Vault-Id', value: params.vaultId },
1068
- { name: 'Address', value: params.gatewayAddress },
1069
- ];
1070
- return this.process.send({
1071
- signer: this.signer,
1072
- tags: pruneTags(allTags),
1073
- });
1074
- }
1075
- async increaseOperatorStake(params, options) {
1076
- const { tags = [] } = options || {};
1077
- return this.process.send({
1078
- signer: this.signer,
1079
- tags: [
1080
- ...tags,
1081
- { name: 'Action', value: 'Increase-Operator-Stake' },
1082
- { name: 'Quantity', value: params.increaseQty.valueOf().toString() },
1083
- ],
1084
- });
1085
- }
1086
- async decreaseOperatorStake(params, options) {
1087
- const { tags = [] } = options || {};
1088
- return this.process.send({
1089
- signer: this.signer,
1090
- tags: [
1091
- ...tags,
1092
- { name: 'Action', value: 'Decrease-Operator-Stake' },
1093
- { name: 'Quantity', value: params.decreaseQty.valueOf().toString() },
1094
- { name: 'Instant', value: `${params.instant || false}` },
1095
- ],
1096
- });
1097
- }
1098
- async saveObservations(params, options) {
1099
- const { tags = [] } = options || {};
1100
- return this.process.send({
1101
- signer: this.signer,
1102
- tags: [
1103
- ...tags,
1104
- { name: 'Action', value: 'Save-Observations' },
1105
- {
1106
- name: 'Report-Tx-Id',
1107
- value: params.reportTxId,
1108
- },
1109
- {
1110
- name: 'Failed-Gateways',
1111
- value: params.failedGateways.join(','),
1112
- },
1113
- ],
1114
- });
1115
- }
1116
- async buyRecord(params, options) {
1117
- // spawn a new ANT if not provided
1118
- if (params.processId === undefined) {
1119
- try {
1120
- // if a Name tag is provided, use it. Else, default to the arns name being purchased.
1121
- const { nameTag, otherTags } = (options?.tags || []).reduce((acc, tag) => {
1122
- if (tag.name === 'Name') {
1123
- acc.nameTag = tag;
1124
- }
1125
- else {
1126
- acc.otherTags.push(tag);
1127
- }
1128
- return acc;
1129
- }, { nameTag: { name: 'Name', value: params.name }, otherTags: [] });
1130
- params.processId = await ANT.spawn({
1131
- signer: this.signer,
1132
- ao: this.process.ao,
1133
- logger: this.logger,
1134
- // This lets AOS set the ArNS name as the Name in lua state
1135
- tags: [nameTag, ...otherTags],
1136
- onSigningProgress: options?.onSigningProgress,
1137
- });
1138
- }
1139
- catch (error) {
1140
- this.logger.error('Failed to spawn ANT for name purchase.', {
1141
- error,
1142
- });
1143
- throw error;
1144
- }
1145
- }
1146
- options?.onSigningProgress?.('buying-name', {
1147
- name: params.name,
1148
- years: params.years,
1149
- type: params.type,
1150
- processId: params.processId,
1151
- fundFrom: params.fundFrom,
1152
- referrer: params.referrer,
1153
- });
1154
- // pay with turbo credits if available
1155
- if (params.fundFrom === 'turbo') {
1156
- if (!(this.paymentProvider instanceof TurboArNSPaymentProviderAuthenticated)) {
1157
- throw new Error('Turbo funding is not supported for this payment provider');
1158
- }
1159
- return this.paymentProvider.initiateArNSPurchase({
1160
- intent: 'Buy-Name',
1161
- name: params.name,
1162
- years: params.years,
1163
- type: params.type,
1164
- processId: params.processId,
1165
- paidBy: params.paidBy,
1166
- });
1167
- }
1168
- const { tags = [] } = options || {};
1169
- const allTags = [
1170
- ...tags,
1171
- { name: 'Action', value: 'Buy-Name' },
1172
- { name: 'Name', value: params.name },
1173
- { name: 'Years', value: params.years?.toString() ?? '1' },
1174
- { name: 'Process-Id', value: params.processId },
1175
- { name: 'Purchase-Type', value: params.type || 'lease' },
1176
- { name: 'Fund-From', value: params.fundFrom },
1177
- { name: 'Referrer', value: params.referrer },
1178
- ];
1179
- return this.process.send({
1180
- signer: this.signer,
1181
- tags: pruneTags(allTags),
1182
- });
1183
- }
1184
- /**
1185
- * Upgrades an existing leased record to a permabuy.
1186
- *
1187
- * @param {Object} params - The parameters for upgrading a record
1188
- * @param {string} params.name - The name of the record to upgrade
1189
- * @param {Object} [options] - The options for the upgrade
1190
- * @returns {Promise<AoMessageResult>} The result of the upgrade
1191
- */
1192
- async upgradeRecord(params, options) {
1193
- if (params.fundFrom === 'turbo') {
1194
- if (!(this.paymentProvider instanceof TurboArNSPaymentProviderAuthenticated)) {
1195
- throw new Error('Turbo funding is not supported for this payment provider');
1196
- }
1197
- return this.paymentProvider.initiateArNSPurchase({
1198
- intent: 'Upgrade-Name',
1199
- name: params.name,
1200
- });
1201
- }
1202
- const { tags = [] } = options || {};
1203
- const allTags = [
1204
- ...tags,
1205
- { name: 'Action', value: 'Upgrade-Name' },
1206
- { name: 'Name', value: params.name },
1207
- { name: 'Fund-From', value: params.fundFrom },
1208
- { name: 'Referrer', value: params.referrer },
1209
- ];
1210
- return this.process.send({
1211
- signer: this.signer,
1212
- tags: pruneTags(allTags),
1213
- });
1214
- }
1215
- /**
1216
- * Extends the lease of an existing leased record.
1217
- *
1218
- * @param {Object} params - The parameters for extending a lease
1219
- * @param {string} params.name - The name of the record to extend
1220
- * @param {number} params.years - The number of years to extend the lease
1221
- * @param {Object} [options] - The options for the extension
1222
- * @returns {Promise<AoMessageResult>} The result of the extension
1223
- */
1224
- async extendLease(params, options) {
1225
- if (params.fundFrom === 'turbo') {
1226
- if (!(this.paymentProvider instanceof TurboArNSPaymentProviderAuthenticated)) {
1227
- throw new Error('Turbo funding is not supported for this payment provider');
1228
- }
1229
- return this.paymentProvider.initiateArNSPurchase({
1230
- intent: 'Extend-Lease',
1231
- name: params.name,
1232
- years: params.years,
1233
- });
1234
- }
1235
- const { tags = [] } = options || {};
1236
- const allTags = [
1237
- ...tags,
1238
- { name: 'Action', value: 'Extend-Lease' },
1239
- { name: 'Name', value: params.name },
1240
- { name: 'Years', value: params.years.toString() },
1241
- { name: 'Fund-From', value: params.fundFrom },
1242
- { name: 'Referrer', value: params.referrer },
1243
- ];
1244
- return this.process.send({
1245
- signer: this.signer,
1246
- tags: pruneTags(allTags),
1247
- });
1248
- }
1249
- async increaseUndernameLimit(params, options) {
1250
- if (params.fundFrom === 'turbo') {
1251
- if (!(this.paymentProvider instanceof TurboArNSPaymentProviderAuthenticated)) {
1252
- throw new Error('Turbo funding is not supported for this payment provider');
1253
- }
1254
- return this.paymentProvider.initiateArNSPurchase({
1255
- intent: 'Increase-Undername-Limit',
1256
- quantity: params.increaseCount,
1257
- name: params.name,
1258
- });
1259
- }
1260
- const { tags = [] } = options || {};
1261
- const allTags = [
1262
- ...tags,
1263
- { name: 'Action', value: 'Increase-Undername-Limit' },
1264
- { name: 'Name', value: params.name },
1265
- { name: 'Quantity', value: params.increaseCount.toString() },
1266
- { name: 'Fund-From', value: params.fundFrom },
1267
- { name: 'Referrer', value: params.referrer },
1268
- ];
1269
- return this.process.send({
1270
- signer: this.signer,
1271
- tags: pruneTags(allTags),
1272
- });
1273
- }
1274
- /**
1275
- * Cancel a withdrawal from a gateway.
1276
- *
1277
- * @param {Object} params - The parameters for cancelling a withdrawal
1278
- * @param {string} [params.address] - The address of the withdrawal (optional). If not provided, the signer's address will be used.
1279
- * @param {string} params.vaultId - The vault ID of the withdrawal.
1280
- * @param {Object} [options] - The options for the cancellation
1281
- * @returns {Promise<AoMessageResult>} The result of the cancellation
1282
- */
1283
- async cancelWithdrawal(params, options) {
1284
- const { tags = [] } = options || {};
1285
- const allTags = [
1286
- ...tags,
1287
- { name: 'Action', value: 'Cancel-Withdrawal' },
1288
- { name: 'Vault-Id', value: params.vaultId },
1289
- { name: 'Address', value: params.gatewayAddress },
1290
- ];
1291
- return this.process.send({
1292
- signer: this.signer,
1293
- tags: pruneTags(allTags),
1294
- });
1295
- }
1296
- async requestPrimaryName(params, options) {
1297
- if (params.fundFrom === 'turbo') {
1298
- throw new Error('Turbo funding is not yet supported for primary name requests');
1299
- }
1300
- const { tags = [] } = options || {};
1301
- const allTags = [
1302
- ...tags,
1303
- { name: 'Action', value: 'Request-Primary-Name' },
1304
- { name: 'Name', value: params.name },
1305
- { name: 'Fund-From', value: params.fundFrom },
1306
- ];
1307
- return this.process.send({
1308
- signer: this.signer,
1309
- tags: pruneTags(allTags),
1310
- });
1311
- }
1312
- async setPrimaryName(params, options) {
1313
- options?.onSigningProgress?.('requesting-primary-name', {
1314
- name: params.name,
1315
- fundFrom: params.fundFrom,
1316
- referrer: params.referrer,
1317
- });
1318
- // create the primary name request, if it already exists, get the request and base name owner
1319
- const requestResult = await this.requestPrimaryName(params, options).catch(async (error) => {
1320
- // check for the error message, it may be due to the request already being made
1321
- if (error.message.includes('already exists')) {
1322
- // parse out the initiator from the error message ` "Primary name request by '" .. initiator .. "' for '" .. name .. "' already exists"
1323
- const initiator = error.message.match(/by '([^']+)'/)?.[1];
1324
- if (initiator === undefined) {
1325
- throw error;
1326
- }
1327
- options?.onSigningProgress?.('request-already-exists', {
1328
- name: params.name,
1329
- initiator,
1330
- });
1331
- // get the primary name request
1332
- const primaryNameRequest = await this.getPrimaryNameRequest({
1333
- initiator,
1334
- });
1335
- // check the name exists
1336
- const arnsRecord = await this.getArNSRecord({ name: params.name });
1337
- if (arnsRecord === undefined) {
1338
- throw new Error(`ARNS name '${params.name}' does not exist`);
1339
- }
1340
- if (primaryNameRequest.initiator !== initiator) {
1341
- throw new Error(`Primary name request for name '${params.name}' was not approved`);
1342
- }
1343
- return {
1344
- id: 'stub-id', // stub-id to indicate that the request already exists
1345
- result: {
1346
- // this is a partial stub of the AoCreatePrimaryNameRequest result
1347
- // we only need the request and base name owner for the approval
1348
- request: primaryNameRequest,
1349
- baseNameOwner: arnsRecord.processId,
1350
- fundingPlan: {
1351
- address: initiator,
1352
- },
1353
- },
1354
- };
1355
- }
1356
- // throw any other errors from the contract
1357
- throw error;
1358
- });
1359
- // the result is either a new primary name request or an existing one
1360
- // for new primary name requests the result includes the request, funding plan, and base name owner
1361
- // for existing primary name requests the result includes just the request and base name owner (see above)
1362
- const primaryNameRequest = requestResult.result;
1363
- const antProcessId = primaryNameRequest?.baseNameOwner;
1364
- const initiator = primaryNameRequest?.fundingPlan?.address;
1365
- if (primaryNameRequest === undefined ||
1366
- initiator === undefined ||
1367
- antProcessId === undefined) {
1368
- throw new Error(`Failed to request primary name ${params.name} for ${initiator} owned by ${antProcessId} process`);
1369
- }
1370
- options?.onSigningProgress?.('approving-request', {
1371
- name: params.name,
1372
- processId: antProcessId,
1373
- request: primaryNameRequest.request,
1374
- });
1375
- const antClient = ANT.init({
1376
- process: new AOProcess({
1377
- processId: antProcessId,
1378
- ao: this.process.ao,
1379
- }),
1380
- signer: this.signer,
1381
- hyperbeamUrl: this.hyperbeamUrl,
1382
- });
1383
- // approve the primary name request with the ant
1384
- const approveResult = await antClient.approvePrimaryNameRequest({
1385
- name: params.name,
1386
- address: initiator,
1387
- arioProcessId: this.process.processId,
1388
- }, options);
1389
- return approveResult;
1390
- }
1391
- /**
1392
- * Redelegate stake from one gateway to another gateway.
1393
- *
1394
- * @param {Object} params - The parameters for redelegating stake
1395
- * @param {string} params.target - The target gateway address
1396
- * @param {string} params.source - The source gateway address
1397
- * @param {number} params.stakeQty - The quantity of stake to redelegate
1398
- * @param {string} params.vaultId - An optional vault ID to redelegate from
1399
- * @param {Object} [options] - The options for the redelegation
1400
- * @returns {Promise<AoMessageResult>} The result of the redelegation
1401
- */
1402
- async redelegateStake(params, options) {
1403
- const { tags = [] } = options || {};
1404
- const allTags = [
1405
- ...tags,
1406
- { name: 'Action', value: 'Redelegate-Stake' },
1407
- { name: 'Target', value: params.target },
1408
- { name: 'Source', value: params.source },
1409
- { name: 'Quantity', value: params.stakeQty.valueOf().toString() },
1410
- { name: 'Vault-Id', value: params.vaultId },
1411
- ];
1412
- return this.process.send({
1413
- signer: this.signer,
1414
- tags: pruneTags(allTags),
6
+ if (config.signer) {
7
+ if (!config.rpcSubscriptions) {
8
+ throw new Error('ARIO.init({ signer }) requires rpcSubscriptions for transaction confirmation.');
9
+ }
10
+ return new SolanaARIOWriteable({
11
+ rpc: config.rpc,
12
+ rpcSubscriptions: config.rpcSubscriptions,
13
+ commitment: config.commitment,
14
+ signer: config.signer,
15
+ coreProgramId: config.coreProgramId,
16
+ garProgramId: config.garProgramId,
17
+ arnsProgramId: config.arnsProgramId,
18
+ antProgramId: config.antProgramId,
19
+ });
20
+ }
21
+ return new SolanaARIOReadable({
22
+ rpc: config.rpc,
23
+ commitment: config.commitment,
24
+ coreProgramId: config.coreProgramId,
25
+ garProgramId: config.garProgramId,
26
+ arnsProgramId: config.arnsProgramId,
27
+ antProgramId: config.antProgramId,
1415
28
  });
1416
29
  }
1417
30
  }