@ar.io/sdk 3.2.0 → 3.3.0-alpha.10

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.
@@ -16,15 +16,15 @@
16
16
  */
17
17
  // eslint-disable-next-line header/header -- This is a CLI file
18
18
  import { program } from 'commander';
19
- import { spawnANT } from '../node/index.js';
19
+ import { AOProcess, spawnANT } from '../node/index.js';
20
20
  import { mARIOToken } from '../types/token.js';
21
21
  import { version } from '../version.js';
22
22
  import { buyRecordCLICommand, extendLeaseCLICommand, increaseUndernameLimitCLICommand, requestPrimaryNameCLICommand, upgradeRecordCLICommand, } from './commands/arnsPurchaseCommands.js';
23
23
  import { cancelWithdrawal, decreaseDelegateStake, decreaseOperatorStake, delegateStake, increaseOperatorStake, instantWithdrawal, joinNetwork, leaveNetwork, redelegateStake, saveObservations, updateGatewaySettings, } from './commands/gatewayWriteCommands.js';
24
- import { getAllowedDelegates, getArNSRecord, getArNSReservedName, getArNSReturnedName, getCostDetails, getDelegations, getEpoch, getGateway, getGatewayDelegates, getGatewayVaults, getPrescribedNames, getPrescribedObservers, getPrimaryName, getTokenCost, getVault, listArNSRecords, listArNSReservedNames, listArNSReturnedNames, listGateways, } from './commands/readCommands.js';
24
+ import { getAllowedDelegates, getArNSRecord, getArNSReservedName, getArNSReturnedName, getCostDetails, getDelegations, getEpoch, getGateway, getGatewayDelegates, getGatewayVaults, getPrescribedNames, getPrescribedObservers, getPrimaryName, getTokenCost, getVault, listAllDelegatesCLICommand, listArNSRecords, listArNSReservedNames, listArNSReturnedNames, listGateways, } from './commands/readCommands.js';
25
25
  import { transfer } from './commands/transfer.js';
26
26
  import { addressAndVaultIdOptions, antStateOptions, arnsPurchaseOptions, buyRecordOptions, decreaseDelegateStakeOptions, delegateStakeOptions, epochOptions, getVaultOptions, globalOptions, joinNetworkOptions, operatorStakeOptions, optionMap, paginationAddressOptions, paginationOptions, redelegateStakeOptions, tokenCostOptions, transferOptions, updateGatewaySettingsOptions, writeActionOptions, } from './options.js';
27
- import { applyOptions, arioProcessIdFromOptions, assertConfirmationPrompt, epochInputFromOptions, formatARIOWithCommas, getANTStateFromOptions, getLoggerFromOptions, makeCommand, paginationParamsFromOptions, readANTFromOptions, readARIOFromOptions, requiredAddressFromOptions, requiredAoSignerFromOptions, requiredStringArrayFromOptions, requiredStringFromOptions, writeANTFromOptions, writeActionTagsFromOptions, } from './utils.js';
27
+ import { applyOptions, arioProcessIdFromOptions, assertConfirmationPrompt, epochInputFromOptions, formatARIOWithCommas, getANTStateFromOptions, getLoggerFromOptions, makeCommand, paginationParamsFromOptions, readANTFromOptions, readARIOFromOptions, requiredAddressFromOptions, requiredAoSignerFromOptions, requiredProcessIdFromOptions, requiredStringArrayFromOptions, requiredStringFromOptions, writeANTFromOptions, writeActionTagsFromOptions, } from './utils.js';
28
28
  applyOptions(program
29
29
  .name('ar.io')
30
30
  .version(version)
@@ -62,6 +62,12 @@ makeCommand({
62
62
  options: paginationOptions,
63
63
  action: listGateways,
64
64
  });
65
+ makeCommand({
66
+ name: 'list-all-delegates',
67
+ description: 'List all paginated delegates from all gateways',
68
+ options: paginationOptions,
69
+ action: listAllDelegatesCLICommand,
70
+ });
65
71
  makeCommand({
66
72
  name: 'get-gateway-delegates',
67
73
  description: 'Get the delegates of a gateway',
@@ -143,13 +149,17 @@ makeCommand({
143
149
  name: 'get-observations',
144
150
  description: 'Get observations for an epoch',
145
151
  options: epochOptions,
146
- action: (o) => readARIOFromOptions(o).getObservations(epochInputFromOptions(o)),
152
+ action: (o) => readARIOFromOptions(o)
153
+ .getObservations(epochInputFromOptions(o))
154
+ .then((result) => result ?? { message: 'No observations found for epoch' }),
147
155
  });
148
156
  makeCommand({
149
157
  name: 'get-distributions',
150
158
  description: 'Get distributions for an epoch',
151
159
  options: epochOptions,
152
- action: (o) => readARIOFromOptions(o).getDistributions(epochInputFromOptions(o)),
160
+ action: (o) => readARIOFromOptions(o)
161
+ .getDistributions(epochInputFromOptions(o))
162
+ .then((result) => result ?? { message: 'No distributions found for epoch' }),
153
163
  });
154
164
  makeCommand({
155
165
  name: 'get-token-cost',
@@ -652,6 +662,20 @@ makeCommand({
652
662
  }, writeActionTagsFromOptions(options));
653
663
  },
654
664
  });
665
+ makeCommand({
666
+ name: 'write-action',
667
+ description: 'Send a write action to an AO Process',
668
+ options: [...writeActionOptions, optionMap.processId],
669
+ action: async (options) => {
670
+ const process = new AOProcess({
671
+ processId: requiredProcessIdFromOptions(options),
672
+ });
673
+ return process.send({
674
+ tags: writeActionTagsFromOptions(options).tags ?? [],
675
+ signer: requiredAoSignerFromOptions(options),
676
+ });
677
+ },
678
+ });
655
679
  if (process.argv[1].includes('bin/ar.io') || // Running from global .bin
656
680
  process.argv[1].includes('cli/cli') // Running from source
657
681
  ) {
@@ -11,6 +11,10 @@ export async function listGateways(o) {
11
11
  const gateways = await readARIOFromOptions(o).getGateways(paginationParamsFromOptions(o));
12
12
  return gateways.items.length ? gateways : { message: 'No gateways found' };
13
13
  }
14
+ export async function listAllDelegatesCLICommand(o) {
15
+ const delegates = await readARIOFromOptions(o).getAllDelegates(paginationParamsFromOptions(o));
16
+ return delegates.items.length ? delegates : { message: 'No delegates found' };
17
+ }
14
18
  export async function getGatewayDelegates(o) {
15
19
  const address = requiredAddressFromOptions(o);
16
20
  const result = await readARIOFromOptions(o).getGatewayDelegates({
@@ -19,12 +19,8 @@ import { createAoSigner } from '../utils/ao.js';
19
19
  import { AOProcess, InvalidContractConfigurationError } from './index.js';
20
20
  export class ANTRegistry {
21
21
  static init(config) {
22
- if (config && config.signer) {
23
- const { signer, ...rest } = config;
24
- return new AoANTRegistryWriteable({
25
- ...rest,
26
- signer,
27
- });
22
+ if (config !== undefined && 'signer' in config) {
23
+ return new AoANTRegistryWriteable(config);
28
24
  }
29
25
  return new AoANTRegistryReadable(config);
30
26
  }
@@ -32,25 +28,22 @@ export class ANTRegistry {
32
28
  export class AoANTRegistryReadable {
33
29
  process;
34
30
  constructor(config) {
35
- if (config &&
36
- (isProcessIdConfiguration(config) || isProcessConfiguration(config))) {
37
- if (isProcessConfiguration(config)) {
38
- this.process = config.process;
39
- }
40
- else if (isProcessIdConfiguration(config)) {
41
- this.process = new AOProcess({
42
- processId: config.processId,
43
- });
44
- }
45
- else {
46
- throw new InvalidContractConfigurationError();
47
- }
48
- }
49
- else {
31
+ if (config === undefined || Object.keys(config).length === 0) {
50
32
  this.process = new AOProcess({
51
33
  processId: ANT_REGISTRY_ID,
52
34
  });
53
35
  }
36
+ else if (isProcessConfiguration(config)) {
37
+ this.process = config.process;
38
+ }
39
+ else if (isProcessIdConfiguration(config)) {
40
+ this.process = new AOProcess({
41
+ processId: config.processId,
42
+ });
43
+ }
44
+ else {
45
+ throw new InvalidContractConfigurationError();
46
+ }
54
47
  }
55
48
  // Should we rename this to "getANTsByAddress"? seems more clear, though not same as handler name
56
49
  async accessControlList({ address, }) {
@@ -20,15 +20,12 @@ import { createAoSigner } from '../utils/ao.js';
20
20
  import { parseSchemaResult } from '../utils/schema.js';
21
21
  import { AOProcess, InvalidContractConfigurationError } from './index.js';
22
22
  export class ANT {
23
- static init({ signer, strict = false, ...config }) {
24
- // ao supported implementation
25
- if (isProcessConfiguration(config) || isProcessIdConfiguration(config)) {
26
- if (!signer) {
27
- return new AoANTReadable({ strict, ...config });
28
- }
29
- return new AoANTWriteable({ signer, strict, ...config });
23
+ // implementation
24
+ static init(config) {
25
+ if (config !== undefined && 'signer' in config) {
26
+ return new AoANTWriteable(config);
30
27
  }
31
- throw new InvalidContractConfigurationError();
28
+ return new AoANTReadable(config);
32
29
  }
33
30
  }
34
31
  export class AoANTReadable {
@@ -21,8 +21,8 @@ import { WriteInteractionError } from '../error.js';
21
21
  import { Logger } from '../logger.js';
22
22
  export class AOProcess {
23
23
  logger;
24
- processId;
25
24
  ao;
25
+ processId;
26
26
  constructor({ processId, ao = connect(), logger = Logger.default, }) {
27
27
  this.processId = processId;
28
28
  this.logger = logger;
@@ -39,8 +39,9 @@ export class AOProcess {
39
39
  let lastError;
40
40
  while (attempts < retries) {
41
41
  try {
42
- this.logger.debug(`Evaluating read interaction on contract`, {
42
+ this.logger.debug(`Evaluating read interaction on process`, {
43
43
  tags,
44
+ processId: this.processId,
44
45
  });
45
46
  // map tags to inputs
46
47
  const dryRunInput = {
@@ -53,13 +54,18 @@ export class AOProcess {
53
54
  const result = await this.ao.dryrun(dryRunInput);
54
55
  this.logger.debug(`Read interaction result`, {
55
56
  result,
57
+ processId: this.processId,
56
58
  });
57
59
  const error = errorMessageFromOutput(result);
58
60
  if (error !== undefined) {
59
61
  throw new Error(error);
60
62
  }
61
63
  if (result.Messages === undefined || result.Messages.length === 0) {
62
- this.logger.debug(`Process ${this.processId} does not support provided action.`, result, tags);
64
+ this.logger.debug(`Process ${this.processId} does not support provided action.`, {
65
+ result,
66
+ tags,
67
+ processId: this.processId,
68
+ });
63
69
  throw new Error(`Process ${this.processId} does not support provided action.`);
64
70
  }
65
71
  const messageData = result.Messages?.[0]?.Data;
@@ -67,16 +73,18 @@ export class AOProcess {
67
73
  if (this.isMessageDataEmpty(messageData)) {
68
74
  return undefined;
69
75
  }
70
- const response = safeDecode(result.Messages[0].Data);
76
+ const response = safeDecode(messageData);
71
77
  return response;
72
78
  }
73
- catch (e) {
79
+ catch (error) {
74
80
  attempts++;
75
81
  this.logger.debug(`Read attempt ${attempts} failed`, {
76
- error: e instanceof Error ? e.message : e,
82
+ error: error?.message,
83
+ stack: error?.stack,
77
84
  tags,
85
+ processId: this.processId,
78
86
  });
79
- lastError = e;
87
+ lastError = error;
80
88
  // exponential backoff
81
89
  await new Promise((resolve) => setTimeout(resolve, 2 ** attempts * 1000));
82
90
  }
@@ -144,16 +152,17 @@ export class AOProcess {
144
152
  }
145
153
  catch (error) {
146
154
  this.logger.error('Error sending message to process', {
147
- error: error.message,
155
+ error: error?.message,
156
+ stack: error?.stack,
148
157
  processId: this.processId,
149
158
  tags,
150
159
  });
151
- // throw on write interaction errors. No point retrying wr ite interactions, waste of gas.
160
+ // throw on write interaction errors. No point retrying write interactions, waste of gas.
152
161
  if (error.message.includes('500')) {
153
162
  this.logger.debug('Retrying send interaction', {
154
163
  attempts,
155
164
  retries,
156
- error: error.message,
165
+ error: error?.message,
157
166
  processId: this.processId,
158
167
  });
159
168
  // exponential backoff
@@ -170,18 +179,16 @@ export class AOProcess {
170
179
  }
171
180
  function errorMessageFromOutput(output) {
172
181
  const errorData = output.Error;
173
- if (errorData !== undefined) {
174
- // TODO: Could clean this one up too, current error is verbose, but not always deterministic for parsing
175
- // Throw the whole raw error if AO process level error
176
- return errorData;
177
- }
178
- const error = output.Messages?.[0]?.Tags?.find((tag) => tag.name === 'Error')?.value;
182
+ // Attempt to extract error details from Messages.Tags if Error is undefined
183
+ const error = errorData ??
184
+ output.Messages?.[0]?.Tags?.find((tag) => tag.name === 'Error')?.value;
179
185
  if (error !== undefined) {
180
- // from [string "aos"]:6846: Name is already registered
181
- const lineNumber = error.match(/\d+/)?.[0];
182
- const message = error.replace(/\[string "aos"\]:\d+:/, '');
183
- // to more user friendly: Name is already registered (line 6846)
184
- return `${message} (line ${lineNumber})`.trim();
186
+ // Consolidated regex to match and extract line number and AO error message or Error Tags
187
+ const match = error.match(/\[string "aos"]:(\d+):\s*(.+)/);
188
+ if (match) {
189
+ const [, lineNumber, errorMessage] = match;
190
+ return `${errorMessage.trim()} (line ${lineNumber.trim()})`.trim();
191
+ }
185
192
  }
186
193
  return undefined;
187
194
  }
@@ -1,32 +1,15 @@
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
1
  import { ARIO_TESTNET_PROCESS_ID } from '../constants.js';
17
2
  import { isProcessConfiguration, isProcessIdConfiguration, } from '../types/io.js';
18
3
  import { createAoSigner } from '../utils/ao.js';
19
- import { paginationParamsToTags, pruneTags } from '../utils/arweave.js';
4
+ import { getEpochDataFromGql, paginationParamsToTags, pruneTags, } from '../utils/arweave.js';
5
+ import { defaultArweave } from './arweave.js';
20
6
  import { AOProcess } from './contracts/ao-process.js';
21
7
  import { InvalidContractConfigurationError } from './error.js';
22
8
  export class ARIO {
9
+ // Implementation
23
10
  static init(config) {
24
- if (config && config.signer) {
25
- const { signer, ...rest } = config;
26
- return new ARIOWriteable({
27
- ...rest,
28
- signer,
29
- });
11
+ if (config !== undefined && 'signer' in config) {
12
+ return new ARIOWriteable(config);
30
13
  }
31
14
  return new ARIOReadable(config);
32
15
  }
@@ -34,8 +17,10 @@ export class ARIO {
34
17
  export class ARIOReadable {
35
18
  process;
36
19
  epochSettings;
20
+ arweave;
37
21
  constructor(config) {
38
- if (!config) {
22
+ this.arweave = config?.arweave ?? defaultArweave;
23
+ if (config === undefined || Object.keys(config).length === 0) {
39
24
  this.process = new AOProcess({
40
25
  processId: ARIO_TESTNET_PROCESS_ID,
41
26
  });
@@ -68,6 +53,13 @@ export class ARIOReadable {
68
53
  const epochLengthMs = epochSettings.durationMs;
69
54
  return Math.floor((timestamp - epochZeroStartTimestamp) / epochLengthMs);
70
55
  }
56
+ async computeCurrentEpochIndex() {
57
+ const epochSettings = await this.getEpochSettings();
58
+ const epochZeroStartTimestamp = epochSettings.epochZeroStartTimestamp;
59
+ const epochLengthMs = epochSettings.durationMs;
60
+ const currentTimestamp = Date.now();
61
+ return Math.floor((currentTimestamp - epochZeroStartTimestamp) / epochLengthMs);
62
+ }
71
63
  async computeEpochIndex(params) {
72
64
  const epochIndex = params?.epochIndex;
73
65
  if (epochIndex !== undefined) {
@@ -85,6 +77,17 @@ export class ARIOReadable {
85
77
  }));
86
78
  }
87
79
  async getEpoch(epoch) {
80
+ const epochIndex = await this.computeEpochIndex(epoch);
81
+ const currentIndex = await this.computeCurrentEpochIndex();
82
+ if (epochIndex !== undefined && +epochIndex < currentIndex) {
83
+ const epochData = await getEpochDataFromGql({
84
+ arweave: this.arweave,
85
+ epochIndex: +epochIndex,
86
+ processId: this.process.processId,
87
+ });
88
+ return epochData;
89
+ }
90
+ // go to the process epoch and fetch the epoch data
88
91
  const allTags = [
89
92
  { name: 'Action', value: 'Epoch' },
90
93
  { name: 'Epoch-Index', value: await this.computeEpochIndex(epoch) },
@@ -215,7 +218,19 @@ export class ARIOReadable {
215
218
  tags: pruneTags(allTags),
216
219
  });
217
220
  }
221
+ // we need to find the epoch index for the epoch that is currently being distributed and fetch it from gql
218
222
  async getObservations(epoch) {
223
+ const epochIndex = await this.computeEpochIndex(epoch);
224
+ const currentIndex = await this.computeCurrentEpochIndex();
225
+ if (epochIndex !== undefined && +epochIndex < currentIndex) {
226
+ const epochData = await getEpochDataFromGql({
227
+ arweave: this.arweave,
228
+ epochIndex: +epochIndex,
229
+ processId: this.process.processId,
230
+ });
231
+ return epochData?.observations;
232
+ }
233
+ // go to the process epoch and fetch the observations
219
234
  const allTags = [
220
235
  { name: 'Action', value: 'Epoch-Observations' },
221
236
  { name: 'Epoch-Index', value: await this.computeEpochIndex(epoch) },
@@ -225,6 +240,17 @@ export class ARIOReadable {
225
240
  });
226
241
  }
227
242
  async getDistributions(epoch) {
243
+ const epochIndex = await this.computeEpochIndex(epoch);
244
+ const currentIndex = await this.computeCurrentEpochIndex();
245
+ if (epochIndex !== undefined && +epochIndex < currentIndex) {
246
+ const epochData = await getEpochDataFromGql({
247
+ arweave: this.arweave,
248
+ epochIndex: +epochIndex,
249
+ processId: this.process.processId,
250
+ });
251
+ return epochData?.distributions;
252
+ }
253
+ // go to the process epoch and fetch the distributions
228
254
  const allTags = [
229
255
  { name: 'Action', value: 'Epoch-Distributions' },
230
256
  { name: 'Epoch-Index', value: await this.computeEpochIndex(epoch) },
@@ -411,33 +437,29 @@ export class ARIOReadable {
411
437
  tags: [{ name: 'Action', value: 'Gateway-Registry-Settings' }],
412
438
  });
413
439
  }
440
+ async getAllDelegates(params) {
441
+ return this.process.read({
442
+ tags: [
443
+ { name: 'Action', value: 'All-Paginated-Delegates' },
444
+ ...paginationParamsToTags(params),
445
+ ],
446
+ });
447
+ }
414
448
  }
415
449
  export class ARIOWriteable extends ARIOReadable {
416
450
  signer;
417
451
  constructor({ signer, ...config }) {
418
- if (Object.keys(config).length === 0) {
452
+ if (config === undefined) {
419
453
  super({
420
454
  process: new AOProcess({
421
455
  processId: ARIO_TESTNET_PROCESS_ID,
422
456
  }),
423
457
  });
424
- this.signer = createAoSigner(signer);
425
- }
426
- else if (isProcessConfiguration(config)) {
427
- super({ process: config.process });
428
- this.signer = createAoSigner(signer);
429
- }
430
- else if (isProcessIdConfiguration(config)) {
431
- super({
432
- process: new AOProcess({
433
- processId: config.processId,
434
- }),
435
- });
436
- this.signer = createAoSigner(signer);
437
458
  }
438
459
  else {
439
- throw new InvalidContractConfigurationError();
460
+ super(config);
440
461
  }
462
+ this.signer = createAoSigner(signer);
441
463
  }
442
464
  async transfer({ target, qty, }, options) {
443
465
  const { tags = [] } = options || {};
@@ -26,6 +26,6 @@ export const arioDevnetProcessId = ARIO_DEVNET_PROCESS_ID;
26
26
  export const ARIO_TESTNET_PROCESS_ID = 'agYcCFJtrMG6cqMuZfskIkFTGvUPddICmtQSBIoPdiA';
27
27
  export const ANT_REGISTRY_ID = 'i_le_yKKPVstLTDSmkHRqf-wYphMnwB9OhleiTgMkWc';
28
28
  export const MARIO_PER_ARIO = 1_000_000;
29
- export const AOS_MODULE_ID = 'cbn0KKrBZH7hdNkNokuXLtGryrWM--PjSTBqIzw9Kkk';
30
- export const ANT_LUA_ID = '16_FyX-V2QU0RPSh1GIaEETSaUjNb0oVjCFpVbAfQq4';
29
+ export const AOS_MODULE_ID = 'BRyNPIJWZaQ4IudfNnsfvMrZBO2YDPjgKqg_wCYT2U8';
30
+ export const ANT_LUA_ID = 'k9tQkbnFYZOGp6ist1yFuaqk_wOkzM5KUSNDtWzCLtg';
31
31
  export const DEFAULT_SCHEDULER_ID = '_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA';
@@ -13,18 +13,14 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- import { createData } from '@dha-team/arbundles';
16
+ import { ArconnectSigner, DataItem, createData } from '@dha-team/arbundles';
17
17
  import { connect, createDataItemSigner } from '@permaweb/aoconnect';
18
18
  import { z } from 'zod';
19
19
  import { defaultArweave } from '../common/arweave.js';
20
20
  import { ANTRegistry, AOProcess, Logger } from '../common/index.js';
21
21
  import { ANT_LUA_ID, ANT_REGISTRY_ID, AOS_MODULE_ID, DEFAULT_SCHEDULER_ID, } from '../constants.js';
22
- export async function spawnANT({ signer, module = AOS_MODULE_ID, luaCodeTxId = ANT_LUA_ID, ao = connect(), scheduler = DEFAULT_SCHEDULER_ID, state, stateContractTxId, antRegistryId = ANT_REGISTRY_ID, logger = Logger.default, arweave = defaultArweave, }) {
23
- //TODO: cache locally and only fetch if not cached
24
- const luaString = (await arweave.transactions.getData(luaCodeTxId, {
25
- decode: true,
26
- string: true,
27
- }));
22
+ export async function spawnANT({ signer, module = AOS_MODULE_ID, ao = connect(), scheduler = DEFAULT_SCHEDULER_ID, state, stateContractTxId, antRegistryId = ANT_REGISTRY_ID, logger = Logger.default, }) {
23
+ // TODO: use On-Boot data handler for bootstrapping state instead of initialize-state
28
24
  const processId = await ao.spawn({
29
25
  module,
30
26
  scheduler,
@@ -34,10 +30,6 @@ export async function spawnANT({ signer, module = AOS_MODULE_ID, luaCodeTxId = A
34
30
  name: 'ANT-Registry-Id',
35
31
  value: antRegistryId,
36
32
  },
37
- {
38
- name: 'Source-Code-TX-ID', // utility for understanding what the original source id of the lua code was
39
- value: luaCodeTxId,
40
- },
41
33
  ],
42
34
  });
43
35
  const aosClient = new AOProcess({
@@ -45,21 +37,10 @@ export async function spawnANT({ signer, module = AOS_MODULE_ID, luaCodeTxId = A
45
37
  ao,
46
38
  logger,
47
39
  });
48
- const { id: evalId } = await aosClient.send({
49
- tags: [
50
- { name: 'Action', value: 'Eval' },
51
- { name: 'App-Name', value: 'ArNS-ANT' },
52
- { name: 'Source-Code-TX-ID', value: luaCodeTxId },
53
- ],
54
- data: luaString,
55
- signer,
56
- });
57
40
  logger.debug(`Spawned ANT`, {
58
41
  processId,
59
42
  module,
60
43
  scheduler,
61
- luaCodeTxId,
62
- evalId,
63
44
  });
64
45
  if (state) {
65
46
  const { id: initializeMsgId } = await aosClient.send({
@@ -79,6 +60,7 @@ export async function spawnANT({ signer, module = AOS_MODULE_ID, luaCodeTxId = A
79
60
  initializeMsgId,
80
61
  });
81
62
  }
63
+ // This could be done by the ANT in On-Boot to self-register with its tagged ANT registry
82
64
  const registryClient = ANTRegistry.init({
83
65
  process: new AOProcess({
84
66
  processId: antRegistryId,
@@ -165,6 +147,20 @@ export function createAoSigner(signer) {
165
147
  typeof signer.setPublicKey === 'function') {
166
148
  await signer.setPublicKey();
167
149
  }
150
+ if (signer instanceof ArconnectSigner) {
151
+ // Sign using Arconnect signDataItem API
152
+ const signedDataItem = await signer['signer'].signDataItem({
153
+ data,
154
+ tags,
155
+ target,
156
+ anchor,
157
+ });
158
+ const dataItem = new DataItem(Buffer.from(signedDataItem));
159
+ return {
160
+ id: await dataItem.id,
161
+ raw: await dataItem.getRaw(),
162
+ };
163
+ }
168
164
  const dataItem = createData(data, signer, { tags, target, anchor });
169
165
  const signedData = dataItem.sign(signer).then(async () => ({
170
166
  id: await dataItem.id,
@@ -192,3 +188,20 @@ export function initANTStateForAddress({ owner, targetId, ttlSeconds = 3600, key
192
188
  },
193
189
  };
194
190
  }
191
+ /**
192
+ * Uses zod schema to parse the epoch data
193
+ */
194
+ export function parseAoEpochData(value) {
195
+ const epochDataSchema = z.object({
196
+ startTimestamp: z.number(),
197
+ startHeight: z.number(),
198
+ distributions: z.any(),
199
+ endTimestamp: z.number(),
200
+ prescribedObservers: z.any(),
201
+ prescribedNames: z.array(z.string()),
202
+ observations: z.any(),
203
+ distributionTimestamp: z.number(),
204
+ epochIndex: z.number(),
205
+ });
206
+ return epochDataSchema.parse(value);
207
+ }
@@ -1,19 +1,5 @@
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 { ARWEAVE_TX_REGEX } from '../constants.js';
1
+ import { ARIO_TESTNET_PROCESS_ID, ARWEAVE_TX_REGEX } from '../constants.js';
2
+ import { parseAoEpochData } from './ao.js';
17
3
  export const validateArweaveId = (id) => {
18
4
  return ARWEAVE_TX_REGEX.test(id);
19
5
  };
@@ -37,3 +23,50 @@ export const paginationParamsToTags = (params) => {
37
23
  ];
38
24
  return pruneTags(tags);
39
25
  };
26
+ /**
27
+ * Get the epoch with distribution data for the current epoch
28
+ * @param arweave - The Arweave instance
29
+ * @returns The epoch with distribution data
30
+ */
31
+ export const getEpochDataFromGql = async ({ arweave, epochIndex, processId = ARIO_TESTNET_PROCESS_ID, }) => {
32
+ // fetch from gql
33
+ const query = epochDistributionNoticeGqlQuery({ epochIndex, processId });
34
+ const response = await arweave.api.post('graphql', query);
35
+ // parse the nodes to get the id
36
+ if (response.data.data.transactions?.edges?.length === 0) {
37
+ return undefined;
38
+ }
39
+ const id = response.data.data.transactions.edges[0].node.id;
40
+ // fetch the transaction from arweave
41
+ const transaction = await arweave.api.get(id);
42
+ const data = transaction.data;
43
+ // assert it is the correct type
44
+ return parseAoEpochData(data);
45
+ };
46
+ export const epochDistributionNoticeGqlQuery = ({ epochIndex, processId = ARIO_TESTNET_PROCESS_ID, }) => {
47
+ // write the query
48
+ const gqlQuery = JSON.stringify({
49
+ query: `
50
+ query {
51
+ transactions(
52
+ tags: [
53
+ { name: "From-Process", values: ["${processId}"] }
54
+ { name: "Action", values: ["Epoch-Distribution-Notice"] }
55
+ { name: "Epoch-Index", values: ["${epochIndex}"] }
56
+ { name: "Data-Protocol", values: ["ao"] }
57
+ ],
58
+ owners: ["fcoN_xJeisVsPXA-trzVAuIiqO3ydLQxM-L4XbrQKzY"],
59
+ first: 1,
60
+ sort: HEIGHT_DESC
61
+ ) {
62
+ edges {
63
+ node {
64
+ id
65
+ }
66
+ }
67
+ }
68
+ }
69
+ `,
70
+ });
71
+ return gqlQuery;
72
+ };
@@ -14,4 +14,4 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
17
- export const version = '3.2.0';
17
+ export const version = '3.3.0-alpha.10';
@@ -21,6 +21,9 @@ export declare function getGateway(o: AddressCLIOptions): Promise<import("../../
21
21
  export declare function listGateways(o: PaginationCLIOptions): Promise<import("../../types/io.js").PaginationResult<import("../../types/io.js").AoGatewayWithAddress> | {
22
22
  message: string;
23
23
  }>;
24
+ export declare function listAllDelegatesCLICommand(o: PaginationCLIOptions): Promise<import("../../types/io.js").PaginationResult<import("../../types/io.js").AoAllDelegates> | {
25
+ message: string;
26
+ }>;
24
27
  export declare function getGatewayDelegates(o: AddressCLIOptions): Promise<import("../../types/io.js").PaginationResult<import("../../types/io.js").AoGatewayDelegateWithAddress> | {
25
28
  message: string;
26
29
  }>;
@@ -1,12 +1,12 @@
1
1
  import { AoANTRegistryRead, AoANTRegistryWrite } from '../types/ant-registry.js';
2
2
  import { AoMessageResult, ProcessConfiguration, WithSigner } from '../types/index.js';
3
3
  import { AOProcess } from './index.js';
4
+ type ANTRegistryNoSigner = ProcessConfiguration;
5
+ type ANTRegistryWithSigner = WithSigner<ProcessConfiguration>;
4
6
  export declare class ANTRegistry {
5
7
  static init(): AoANTRegistryRead;
6
- static init(config: Required<ProcessConfiguration> & {
7
- signer?: undefined;
8
- }): AoANTRegistryRead;
9
- static init({ signer, ...config }: WithSigner<Required<ProcessConfiguration>>): AoANTRegistryWrite;
8
+ static init(config: ANTRegistryNoSigner): AoANTRegistryRead;
9
+ static init(config: ANTRegistryWithSigner): AoANTRegistryWrite;
10
10
  }
11
11
  export declare class AoANTRegistryReadable implements AoANTRegistryRead {
12
12
  protected process: AOProcess;
@@ -25,3 +25,4 @@ export declare class AoANTRegistryWriteable extends AoANTRegistryReadable implem
25
25
  processId: string;
26
26
  }): Promise<AoMessageResult>;
27
27
  }
28
+ export {};