@ar.io/sdk 3.19.0-alpha.1 → 3.19.0-alpha.3

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.
@@ -14,13 +14,15 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { z } from 'zod';
17
+ import { ARIO_MAINNET_PROCESS_ID } from '../constants.js';
18
+ import { ANT_REGISTRY_ID } from '../constants.js';
17
19
  import { AntBalancesSchema, AntControllersSchema, AntInfoSchema, AntRecordSchema, AntRecordsSchema, AntStateSchema, } from '../types/ant.js';
18
20
  import { isProcessConfiguration, isProcessIdConfiguration, } from '../types/index.js';
19
21
  import { convertHyperBeamStateToAoANTState, isHyperBeamANTState, sortANTRecords, } from '../utils/ant.js';
20
22
  import { createAoSigner, forkANT, spawnANT } from '../utils/ao.js';
21
23
  import { parseSchemaResult } from '../utils/schema.js';
22
24
  import { ANTVersions } from './ant-versions.js';
23
- import { AOProcess, InvalidContractConfigurationError, Logger, } from './index.js';
25
+ import { AOProcess, ARIO, InvalidContractConfigurationError, Logger, } from './index.js';
24
26
  export class ANT {
25
27
  /**
26
28
  * Versions of ANTs according to the ANT registry.
@@ -40,6 +42,115 @@ export class ANT {
40
42
  * @param config
41
43
  */
42
44
  static fork = forkANT;
45
+ /**
46
+ * Upgrade an ANT by forking it to the latest version and reassigning names.
47
+ *
48
+ *
49
+ * @param config Configuration object for the upgrade process
50
+ * @returns Promise resolving to the forked process ID and successfully reassigned names
51
+ */
52
+ static async upgrade({ signer, antProcessId, reassignAffiliatedNames = false, // if true, will reassign all affiliated names, otherwise will use the names parameter
53
+ names = [], arioProcessId = ARIO_MAINNET_PROCESS_ID, antRegistryId = ANT_REGISTRY_ID, ao, logger = Logger.default, skipVersionCheck = false, onSigningProgress, hyperbeamUrl, }) {
54
+ // if names is not empty but reassignAffiliatedNames it true, throw
55
+ if (names.length > 0 && reassignAffiliatedNames) {
56
+ throw new Error('Cannot reassign all affiliated names and provide specific names');
57
+ }
58
+ const ario = ARIO.init({
59
+ process: new AOProcess({ processId: arioProcessId, ao }),
60
+ });
61
+ // get all the affiliated names if reassign all affiliated names is true
62
+ if (reassignAffiliatedNames) {
63
+ onSigningProgress?.('fetching-affiliated-names', {
64
+ arioProcessId,
65
+ antProcessId,
66
+ });
67
+ const allAffiliatedNames = await ario.getArNSRecords({
68
+ filters: {
69
+ processId: antProcessId,
70
+ },
71
+ });
72
+ names.push(...allAffiliatedNames.items.map((record) => record.name));
73
+ }
74
+ else {
75
+ onSigningProgress?.('validating-names', {
76
+ arioProcessId,
77
+ antProcessId,
78
+ names,
79
+ });
80
+ // confirm all names are affiliated with the ANT
81
+ const allAffiliatedNames = await ario.getArNSRecords({
82
+ filters: {
83
+ processId: antProcessId,
84
+ },
85
+ });
86
+ if (names.every((name) => allAffiliatedNames.items.some((record) => record.name === name))) {
87
+ // find any that are not affiliated with the ANT
88
+ const notAffiliatedNames = names.filter((name) => !allAffiliatedNames.items.some((record) => record.name === name));
89
+ throw new Error(`All names must be affiliated with the ANT on the provided ARIO process. The following names are not affiliated to this ANT: ${notAffiliatedNames.join(', ')}`);
90
+ }
91
+ }
92
+ // if names is empty and reassign all affiliated names is false, throw an error
93
+ if (names.length === 0) {
94
+ throw new Error('There are no names to reassign for this ANT.');
95
+ }
96
+ const existingAntProcess = ANT.init({
97
+ process: new AOProcess({
98
+ processId: antProcessId,
99
+ ao,
100
+ logger,
101
+ }),
102
+ hyperbeamUrl,
103
+ signer,
104
+ });
105
+ if (!skipVersionCheck) {
106
+ onSigningProgress?.('checking-version', {
107
+ antProcessId,
108
+ antRegistryId,
109
+ });
110
+ const isLatestVersion = await existingAntProcess.isLatestVersion({
111
+ antRegistryId,
112
+ });
113
+ if (isLatestVersion) {
114
+ return {
115
+ forkedProcessId: antProcessId,
116
+ reassignedNames: [],
117
+ failedReassignedNames: [],
118
+ };
119
+ }
120
+ }
121
+ const forkedProcessId = await ANT.fork({
122
+ signer,
123
+ antProcessId,
124
+ ao,
125
+ logger,
126
+ antRegistryId,
127
+ onSigningProgress,
128
+ });
129
+ // we could parallelize this, but then signing progress would be harder to track
130
+ const reassignedNames = [];
131
+ const failedReassignedNames = [];
132
+ for (const name of names) {
133
+ try {
134
+ onSigningProgress?.('reassigning-name', {
135
+ name,
136
+ arioProcessId,
137
+ antProcessId: forkedProcessId,
138
+ });
139
+ await existingAntProcess.reassignName({
140
+ name,
141
+ arioProcessId,
142
+ antProcessId: forkedProcessId,
143
+ });
144
+ reassignedNames.push(name);
145
+ }
146
+ catch (error) {
147
+ logger.error(`Failed to reassign name ${name}:`, { error });
148
+ // Continue with other names rather than failing completely
149
+ failedReassignedNames.push(name);
150
+ }
151
+ }
152
+ return { forkedProcessId, reassignedNames, failedReassignedNames };
153
+ }
43
154
  static init(config) {
44
155
  if (config !== undefined && 'signer' in config) {
45
156
  return new AoANTWriteable(config);
@@ -53,6 +164,8 @@ export class AoANTReadable {
53
164
  strict;
54
165
  hyperbeamUrl;
55
166
  checkHyperBeamPromise;
167
+ moduleId;
168
+ moduleIdPromise;
56
169
  logger = Logger.default;
57
170
  constructor(config) {
58
171
  this.strict = config.strict || false;
@@ -185,6 +298,184 @@ export class AoANTReadable {
185
298
  const info = await this.getInfo();
186
299
  return info.Logo;
187
300
  }
301
+ /**
302
+ * Gets the module ID of the current ANT process by querying its spawn transaction tags.
303
+ * Results are cached after the first successful fetch.
304
+ *
305
+ * @param graphqlUrl The GraphQL endpoint URL (defaults to Arweave's GraphQL endpoint)
306
+ * @param retries Number of retry attempts (defaults to 3)
307
+ * @returns Promise<string> The module ID used to spawn this ANT process
308
+ * @example
309
+ * ```ts
310
+ * const moduleId = await ant.getModuleId();
311
+ * console.log(`ANT was spawned with module: ${moduleId}`);
312
+ * ```
313
+ */
314
+ async getModuleId({
315
+ // TODO: we could use wayfinder for this
316
+ graphqlUrl = 'https://arweave.net/graphql', retries = 3, } = {}) {
317
+ // Return cached result if available
318
+ if (this.moduleId !== undefined) {
319
+ this.logger.debug('Returning cached module ID', {
320
+ processId: this.processId,
321
+ moduleId: this.moduleId,
322
+ });
323
+ return this.moduleId;
324
+ }
325
+ // Return existing promise if already in flight
326
+ if (this.moduleIdPromise) {
327
+ this.logger.debug('Returning in-flight module ID promise', {
328
+ processId: this.processId,
329
+ });
330
+ return this.moduleIdPromise;
331
+ }
332
+ // Create and cache the promise to prevent multiple concurrent requests
333
+ this.moduleIdPromise = this.fetchModuleId({ graphqlUrl, retries });
334
+ try {
335
+ const moduleId = await this.moduleIdPromise;
336
+ this.moduleId = moduleId;
337
+ this.logger.debug('Successfully fetched and cached module ID', {
338
+ processId: this.processId,
339
+ moduleId,
340
+ });
341
+ return moduleId;
342
+ }
343
+ finally {
344
+ // Clear the promise so future calls can retry if this one failed
345
+ this.moduleIdPromise = undefined;
346
+ }
347
+ }
348
+ /**
349
+ * Internal method to fetch the module ID from GraphQL.
350
+ *
351
+ * TODO: this could be more like get process headers/metadata and fetch additional details.
352
+ *
353
+ * It seems like module is the only relevant one, but scheduler and authority are also available.
354
+ */
355
+ async fetchModuleId({ graphqlUrl, retries, }) {
356
+ const query = JSON.stringify({
357
+ query: `
358
+ query {
359
+ transactions(
360
+ ids: ["${this.processId}"]
361
+ first: 1,
362
+ ) {
363
+ edges {
364
+ node {
365
+ tags {
366
+ name
367
+ value
368
+ }
369
+ }
370
+ }
371
+ }
372
+ }
373
+ `,
374
+ });
375
+ for (let i = 0; i < retries; i++) {
376
+ try {
377
+ const response = await fetch(graphqlUrl, {
378
+ method: 'POST',
379
+ body: query,
380
+ headers: {
381
+ 'Content-Type': 'application/json',
382
+ },
383
+ });
384
+ if (!response.ok) {
385
+ throw new Error(`GraphQL request failed: ${response.statusText}`);
386
+ }
387
+ const result = (await response.json());
388
+ if (result.errors) {
389
+ throw new Error(`GraphQL errors: ${result.errors.map((e) => e.message).join(', ')}`);
390
+ }
391
+ const edges = result.data?.transactions?.edges;
392
+ if (!edges || edges.length === 0) {
393
+ throw new Error(`No transaction found for process ID: ${this.processId}`);
394
+ }
395
+ const tags = edges[0].node.tags;
396
+ const moduleTag = tags.find((tag) => tag.name === 'Module');
397
+ if (!moduleTag) {
398
+ throw new Error(`No Module tag found for process ID: ${this.processId}`);
399
+ }
400
+ return moduleTag.value;
401
+ }
402
+ catch (error) {
403
+ if (i === retries - 1) {
404
+ // Final attempt failed
405
+ this.logger.error('Failed to get ANT module ID after all retries:', {
406
+ error,
407
+ });
408
+ throw new Error(`Unable to determine module ID for ANT process ${this.processId}: ${error.message}`);
409
+ }
410
+ // Exponential backoff
411
+ await new Promise((resolve) => setTimeout(resolve, Math.pow(2, i) * 1000));
412
+ }
413
+ }
414
+ throw new Error(`Unexpected error getting module ID for process ${this.processId}`);
415
+ }
416
+ /**
417
+ * Gets the version string of the current ANT by matching its module ID
418
+ * with versions from the ANT registry.
419
+ *
420
+ * @param antRegistryId The ANT registry process ID (defaults to mainnet registry)
421
+ * @param graphqlUrl The GraphQL endpoint URL for getModuleId (defaults to Arweave's GraphQL endpoint)
422
+ * @param retries Number of retry attempts for getModuleId (defaults to 3)
423
+ * @returns Promise<string> The version string (e.g., "1.0.15") or "unknown" if not found
424
+ * @example
425
+ * ```ts
426
+ * const version = await ant.getVersion();
427
+ * console.log(`ANT is running version: ${version}`);
428
+ * ```
429
+ */
430
+ async getVersion({ antRegistryId = ANT_REGISTRY_ID, graphqlUrl = 'https://arweave.net/graphql', retries = 3, } = {}) {
431
+ // Get the current ANT's module ID
432
+ const currentModuleId = await this.getModuleId({ graphqlUrl, retries });
433
+ // Get all versions from the ANT registry
434
+ const antVersions = ANTVersions.init({
435
+ processId: antRegistryId,
436
+ });
437
+ const versions = await antVersions.getANTVersions();
438
+ // Find the version that matches our module ID
439
+ for (const [version, versionInfo] of Object.entries(versions)) {
440
+ if (versionInfo.moduleId === currentModuleId) {
441
+ this.logger.debug('Found matching ANT version', {
442
+ processId: this.processId,
443
+ moduleId: currentModuleId,
444
+ version,
445
+ });
446
+ return version;
447
+ }
448
+ }
449
+ const versionForModuleId = Object.entries(versions)
450
+ .map(([version, versionInfo]) => ({
451
+ version,
452
+ ...versionInfo,
453
+ }))
454
+ .find((obj) => obj.moduleId === currentModuleId);
455
+ return versionForModuleId?.version ?? 'unknown';
456
+ }
457
+ /**
458
+ * Checks if the current ANT version is the latest according to the ANT registry.
459
+ *
460
+ * @param antRegistryId Optional ANT registry process ID. Defaults to mainnet ANT registry.
461
+ * @param graphqlUrl Optional GraphQL endpoint. Defaults to https://arweave.net/graphql.
462
+ * @param retries Optional number of retries for fetching module ID. Defaults to 3.
463
+ * @returns {Promise<boolean>} True if current ANT version is the latest, false otherwise.
464
+ */
465
+ async isLatestVersion({ antRegistryId = ANT_REGISTRY_ID, graphqlUrl = 'https://arweave.net/graphql', retries = 3, } = {}) {
466
+ // Get the current ANT's version
467
+ const currentVersion = await this.getVersion({
468
+ antRegistryId,
469
+ graphqlUrl,
470
+ retries,
471
+ });
472
+ // Get all versions from the ANT registry
473
+ const antVersions = ANTVersions.init({
474
+ processId: antRegistryId,
475
+ });
476
+ const latestVersion = await antVersions.getLatestANTVersion();
477
+ return currentVersion === latestVersion.version;
478
+ }
188
479
  /**
189
480
  * @param undername @type {string} The domain name.
190
481
  * @returns {Promise<ANTRecord>} The record of the undername domain.
@@ -716,4 +1007,39 @@ export class AoANTWriteable extends AoANTReadable {
716
1007
  signer: this.signer,
717
1008
  });
718
1009
  }
1010
+ /**
1011
+ * Upgrade this ANT by forking it to the latest version and reassigning names.
1012
+ *
1013
+ * This is a convenience method that calls the static ANT.upgrade() method
1014
+ * using this instance's process ID and signer.
1015
+ *
1016
+ * current version with latest ANT registry version and skip if already up to date.
1017
+ *
1018
+ * @param names @type {string[]} The ArNS names to reassign to the upgraded ANT.
1019
+ * @param arioProcessId @type {string} The processId of the ARIO contract.
1020
+ * @param antRegistryId @type {string} Optional ANT registry ID.
1021
+ * @param onSigningProgress Progress callback function.
1022
+ * @returns {Promise} The upgrade results.
1023
+ * @example
1024
+ * ```ts
1025
+ * const result = await ant.upgrade({
1026
+ * names: ["example", "test"],
1027
+ * arioProcessId: ARIO_MAINNET_PROCESS_ID
1028
+ * });
1029
+ * console.log(`Upgraded to process: ${result.forkedProcessId}`);
1030
+ * ```
1031
+ */
1032
+ async upgrade({ names, reassignAffiliatedNames = true, arioProcessId, antRegistryId, onSigningProgress, skipVersionCheck = false, }) {
1033
+ return ANT.upgrade({
1034
+ signer: this.signer,
1035
+ antProcessId: this.processId,
1036
+ ao: this.process.ao,
1037
+ names,
1038
+ reassignAffiliatedNames,
1039
+ arioProcessId,
1040
+ antRegistryId,
1041
+ onSigningProgress,
1042
+ skipVersionCheck,
1043
+ });
1044
+ }
719
1045
  }
@@ -21,6 +21,7 @@ export const ARIO_DEVNET_PROCESS_ID = 'GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGr
21
21
  export const arioDevnetProcessId = ARIO_DEVNET_PROCESS_ID;
22
22
  export const ARIO_TESTNET_PROCESS_ID = 'agYcCFJtrMG6cqMuZfskIkFTGvUPddICmtQSBIoPdiA';
23
23
  export const ARIO_MAINNET_PROCESS_ID = 'qNvAoz0TgcH7DMg8BCVn8jF32QH5L6T29VjHxhHqqGE';
24
+ export const ANT_REGISTRY_TESTNET_ID = 'RR0vheYqtsKuJCWh6xj0beE35tjaEug5cejMw9n2aa8';
24
25
  export const ANT_REGISTRY_ID = 'i_le_yKKPVstLTDSmkHRqf-wYphMnwB9OhleiTgMkWc';
25
26
  export const MARIO_PER_ARIO = 1_000_000;
26
27
  /**
@@ -37,6 +37,9 @@ export const sortANTRecords = (antRecords) => {
37
37
  // now that they are sorted, add the index to each record - this is their position in the sorted list and is used to enforce undername limits
38
38
  return Object.fromEntries(sortedEntries.map(([a, aRecord], index) => [a, { ...aRecord, index }]));
39
39
  };
40
+ /**
41
+ * @deprecated - this is no longer necessary because HyperBeam now uses the AoANTState type
42
+ */
40
43
  export const isHyperBeamANTState = (state) => {
41
44
  return ('name' in state &&
42
45
  'ticker' in state &&
@@ -54,6 +57,7 @@ export const isHyperBeamANTState = (state) => {
54
57
  /**
55
58
  * Convert HyperBeam serialized ANT state to backwards compatible format.
56
59
  *
60
+ * @deprecated - this is no longer necessary because HyperBeam now uses the AOANTState type
57
61
  * @param state - The HyperBeam serialized ANT state.
58
62
  */
59
63
  export const convertHyperBeamStateToAoANTState = (initialState) => {
@@ -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.19.0-alpha.1';
17
+ export const version = '3.19.0-alpha.3';
@@ -19,3 +19,8 @@ import { CLIWriteOptionsFromAoAntParams } from '../types.js';
19
19
  export declare function setAntRecordCLICommand(o: CLIWriteOptionsFromAoAntParams<AoANTSetUndernameRecordParams>): Promise<import("../../types/common.js").AoMessageResult<Record<string, string | number | boolean | null>>>;
20
20
  export declare function setAntBaseNameCLICommand(o: CLIWriteOptionsFromAoAntParams<AoANTSetBaseNameRecordParams>): Promise<import("../../types/common.js").AoMessageResult<Record<string, string | number | boolean | null>>>;
21
21
  export declare function setAntUndernameCLICommand(o: CLIWriteOptionsFromAoAntParams<AoANTSetUndernameRecordParams>): Promise<import("../../types/common.js").AoMessageResult<Record<string, string | number | boolean | null>>>;
22
+ export declare function upgradeAntCLICommand(o: CLIWriteOptionsFromAoAntParams<Record<string, unknown>>): Promise<{
23
+ forkedProcessId: string;
24
+ reassignedNames: string[];
25
+ failedReassignedNames: string[];
26
+ }>;
@@ -390,3 +390,7 @@ export declare const setAntUndernameOptions: {
390
390
  alias: string;
391
391
  description: string;
392
392
  }[];
393
+ export declare const upgradeAntOptions: {
394
+ alias: string;
395
+ description: string;
396
+ }[];
@@ -1,6 +1,6 @@
1
1
  import { JWKInterface } from 'arweave/node/lib/wallet.js';
2
2
  import { Command, OptionValues } from 'commander';
3
- import { AOProcess, ARIOToken, AoANTRead, AoANTRegistryRead, AoANTWrite, AoARIORead, AoARIOWrite, AoGetCostDetailsParams, AoRedelegateStakeParams, AoSigner, AoUpdateGatewaySettingsParams, ContractSigner, EpochInput, FundFrom, Logger, PaginationParams, SpawnANTState, WriteOptions, mARIOToken } from '../node/index.js';
3
+ import { ARIOToken, AoANTRead, AoANTRegistryRead, AoANTWrite, AoARIORead, AoARIOWrite, AoGetCostDetailsParams, AoRedelegateStakeParams, AoSigner, AoUpdateGatewaySettingsParams, ContractSigner, EpochInput, FundFrom, Logger, PaginationParams, SpawnANTState, WriteOptions, mARIOToken } from '../node/index.js';
4
4
  import { ANTStateCLIOptions, AddressCLIOptions, EpochCLIOptions, GetTokenCostCLIOptions, GlobalCLIOptions, InitiatorCLIOptions, JsonSerializable, PaginationCLIOptions, ProcessIdCLIOptions, RedelegateStakeCLIOptions, TransferCLIOptions, UpdateGatewaySettingsCLIOptions, WalletCLIOptions, WriteActionCLIOptions } from './types.js';
5
5
  export declare const defaultTtlSecondsCLI = 3600;
6
6
  export declare function stringifyJsonForCLIDisplay(json: JsonSerializable | unknown): string;
@@ -18,11 +18,11 @@ export declare function makeCommand<O extends OptionValues = GlobalCLIOptions>({
18
18
  options?: CommanderOption[];
19
19
  }): Command;
20
20
  export declare function arioProcessIdFromOptions({ arioProcessId, devnet, testnet, }: GlobalCLIOptions): string;
21
+ export declare function antRegistryIdFromOptions({ antRegistryProcessId, testnet, }: GlobalCLIOptions): string;
21
22
  export declare function requiredJwkFromOptions(options: WalletCLIOptions): JWKInterface;
22
23
  export declare function jwkToAddress(jwk: JWKInterface): string;
23
24
  export declare function getLoggerFromOptions(options: GlobalCLIOptions): Logger;
24
25
  export declare function readARIOFromOptions(options: GlobalCLIOptions): AoARIORead;
25
- export declare function ANTRegistryProcessFromOptions(options: ProcessIdCLIOptions): AOProcess;
26
26
  export declare function readANTRegistryFromOptions(options: ProcessIdCLIOptions): AoANTRegistryRead;
27
27
  export declare function contractSignerFromOptions(options: WalletCLIOptions): {
28
28
  signer: ContractSigner;
@@ -1,7 +1,7 @@
1
1
  import { AntReadOptions, AoANTHandler, AoANTInfo, AoANTRead, AoANTRecord, AoANTSetBaseNameRecordParams, AoANTSetUndernameRecordParams, AoANTState, AoANTWrite, SortedANTRecords } from '../types/ant.js';
2
- import { AoMessageResult, ProcessConfiguration, WalletAddress, WithSigner, WriteOptions } from '../types/index.js';
2
+ import { AoClient, AoMessageResult, AoSigner, ProcessConfiguration, UpgradeAntProgressEvent, WalletAddress, WithSigner, WriteOptions } from '../types/index.js';
3
3
  import { forkANT, spawnANT } from '../utils/ao.js';
4
- import { AOProcess } from './index.js';
4
+ import { AOProcess, Logger } from './index.js';
5
5
  type ANTConfigOptionalStrict = Required<ProcessConfiguration> & {
6
6
  strict?: boolean;
7
7
  hyperbeamUrl?: string;
@@ -25,6 +25,31 @@ export declare class ANT {
25
25
  * @param config
26
26
  */
27
27
  static fork: typeof forkANT;
28
+ /**
29
+ * Upgrade an ANT by forking it to the latest version and reassigning names.
30
+ *
31
+ *
32
+ * @param config Configuration object for the upgrade process
33
+ * @returns Promise resolving to the forked process ID and successfully reassigned names
34
+ */
35
+ static upgrade({ signer, antProcessId, reassignAffiliatedNames, // if true, will reassign all affiliated names, otherwise will use the names parameter
36
+ names, arioProcessId, antRegistryId, ao, logger, skipVersionCheck, onSigningProgress, hyperbeamUrl, }: {
37
+ signer: AoSigner;
38
+ antProcessId: string;
39
+ names?: string[];
40
+ reassignAffiliatedNames?: boolean;
41
+ arioProcessId?: string;
42
+ skipVersionCheck?: boolean;
43
+ ao?: AoClient;
44
+ logger?: Logger;
45
+ antRegistryId?: string;
46
+ hyperbeamUrl?: string;
47
+ onSigningProgress?: (name: keyof UpgradeAntProgressEvent, payload: UpgradeAntProgressEvent[keyof UpgradeAntProgressEvent]) => void;
48
+ }): Promise<{
49
+ forkedProcessId: string;
50
+ reassignedNames: string[];
51
+ failedReassignedNames: string[];
52
+ }>;
28
53
  /**
29
54
  * Initialize overloads.
30
55
  *
@@ -39,6 +64,8 @@ export declare class AoANTReadable implements AoANTRead {
39
64
  private strict;
40
65
  private hyperbeamUrl;
41
66
  private checkHyperBeamPromise;
67
+ private moduleId;
68
+ private moduleIdPromise;
42
69
  private logger;
43
70
  constructor(config: ANTConfigOptionalStrict);
44
71
  /**
@@ -53,6 +80,63 @@ export declare class AoANTReadable implements AoANTRead {
53
80
  * Returns the TX ID of the logo set for the ANT.
54
81
  */
55
82
  getLogo(): Promise<string>;
83
+ /**
84
+ * Gets the module ID of the current ANT process by querying its spawn transaction tags.
85
+ * Results are cached after the first successful fetch.
86
+ *
87
+ * @param graphqlUrl The GraphQL endpoint URL (defaults to Arweave's GraphQL endpoint)
88
+ * @param retries Number of retry attempts (defaults to 3)
89
+ * @returns Promise<string> The module ID used to spawn this ANT process
90
+ * @example
91
+ * ```ts
92
+ * const moduleId = await ant.getModuleId();
93
+ * console.log(`ANT was spawned with module: ${moduleId}`);
94
+ * ```
95
+ */
96
+ getModuleId({ graphqlUrl, retries, }?: {
97
+ graphqlUrl?: string;
98
+ retries?: number;
99
+ }): Promise<string>;
100
+ /**
101
+ * Internal method to fetch the module ID from GraphQL.
102
+ *
103
+ * TODO: this could be more like get process headers/metadata and fetch additional details.
104
+ *
105
+ * It seems like module is the only relevant one, but scheduler and authority are also available.
106
+ */
107
+ private fetchModuleId;
108
+ /**
109
+ * Gets the version string of the current ANT by matching its module ID
110
+ * with versions from the ANT registry.
111
+ *
112
+ * @param antRegistryId The ANT registry process ID (defaults to mainnet registry)
113
+ * @param graphqlUrl The GraphQL endpoint URL for getModuleId (defaults to Arweave's GraphQL endpoint)
114
+ * @param retries Number of retry attempts for getModuleId (defaults to 3)
115
+ * @returns Promise<string> The version string (e.g., "1.0.15") or "unknown" if not found
116
+ * @example
117
+ * ```ts
118
+ * const version = await ant.getVersion();
119
+ * console.log(`ANT is running version: ${version}`);
120
+ * ```
121
+ */
122
+ getVersion({ antRegistryId, graphqlUrl, retries, }?: {
123
+ antRegistryId?: string;
124
+ graphqlUrl?: string;
125
+ retries?: number;
126
+ }): Promise<string>;
127
+ /**
128
+ * Checks if the current ANT version is the latest according to the ANT registry.
129
+ *
130
+ * @param antRegistryId Optional ANT registry process ID. Defaults to mainnet ANT registry.
131
+ * @param graphqlUrl Optional GraphQL endpoint. Defaults to https://arweave.net/graphql.
132
+ * @param retries Optional number of retries for fetching module ID. Defaults to 3.
133
+ * @returns {Promise<boolean>} True if current ANT version is the latest, false otherwise.
134
+ */
135
+ isLatestVersion({ antRegistryId, graphqlUrl, retries, }?: {
136
+ antRegistryId?: string;
137
+ graphqlUrl?: string;
138
+ retries?: number;
139
+ }): Promise<boolean>;
56
140
  /**
57
141
  * @param undername @type {string} The domain name.
58
142
  * @returns {Promise<ANTRecord>} The record of the undername domain.
@@ -373,5 +457,39 @@ export declare class AoANTWriteable extends AoANTReadable implements AoANTWrite
373
457
  arioProcessId: string;
374
458
  notifyOwners?: boolean;
375
459
  }, options?: WriteOptions): Promise<AoMessageResult>;
460
+ /**
461
+ * Upgrade this ANT by forking it to the latest version and reassigning names.
462
+ *
463
+ * This is a convenience method that calls the static ANT.upgrade() method
464
+ * using this instance's process ID and signer.
465
+ *
466
+ * current version with latest ANT registry version and skip if already up to date.
467
+ *
468
+ * @param names @type {string[]} The ArNS names to reassign to the upgraded ANT.
469
+ * @param arioProcessId @type {string} The processId of the ARIO contract.
470
+ * @param antRegistryId @type {string} Optional ANT registry ID.
471
+ * @param onSigningProgress Progress callback function.
472
+ * @returns {Promise} The upgrade results.
473
+ * @example
474
+ * ```ts
475
+ * const result = await ant.upgrade({
476
+ * names: ["example", "test"],
477
+ * arioProcessId: ARIO_MAINNET_PROCESS_ID
478
+ * });
479
+ * console.log(`Upgraded to process: ${result.forkedProcessId}`);
480
+ * ```
481
+ */
482
+ upgrade({ names, reassignAffiliatedNames, arioProcessId, antRegistryId, onSigningProgress, skipVersionCheck, }: {
483
+ names?: string[];
484
+ arioProcessId?: string;
485
+ antRegistryId?: string;
486
+ skipVersionCheck?: boolean;
487
+ reassignAffiliatedNames?: boolean;
488
+ onSigningProgress?: (name: keyof UpgradeAntProgressEvent, payload: UpgradeAntProgressEvent[keyof UpgradeAntProgressEvent]) => void;
489
+ }): Promise<{
490
+ forkedProcessId: string;
491
+ reassignedNames: string[];
492
+ failedReassignedNames: string[];
493
+ }>;
376
494
  }
377
495
  export {};
@@ -20,6 +20,7 @@ export declare const ARIO_DEVNET_PROCESS_ID = "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelV
20
20
  export declare const arioDevnetProcessId = "GaQrvEMKBpkjofgnBi_B3IgIDmY_XYelVLB6GcRGrHc";
21
21
  export declare const ARIO_TESTNET_PROCESS_ID = "agYcCFJtrMG6cqMuZfskIkFTGvUPddICmtQSBIoPdiA";
22
22
  export declare const ARIO_MAINNET_PROCESS_ID = "qNvAoz0TgcH7DMg8BCVn8jF32QH5L6T29VjHxhHqqGE";
23
+ export declare const ANT_REGISTRY_TESTNET_ID = "RR0vheYqtsKuJCWh6xj0beE35tjaEug5cejMw9n2aa8";
23
24
  export declare const ANT_REGISTRY_ID = "i_le_yKKPVstLTDSmkHRqf-wYphMnwB9OhleiTgMkWc";
24
25
  export declare const MARIO_PER_ARIO = 1000000;
25
26
  /**
@@ -14,7 +14,7 @@
14
14
  * limitations under the License.
15
15
  */
16
16
  import { z } from 'zod';
17
- import { AoWriteAction, WalletAddress } from './common.js';
17
+ import { AoWriteAction, UpgradeAntProgressEvent, WalletAddress } from './common.js';
18
18
  /**
19
19
  * example error:
20
20
  * {
@@ -264,6 +264,20 @@ export interface AoANTRead {
264
264
  }, opts?: AntReadOptions): Promise<number>;
265
265
  getBalances(opts?: AntReadOptions): Promise<Record<WalletAddress, number>>;
266
266
  getHandlers(): Promise<AoANTHandler[]>;
267
+ getModuleId(opts?: {
268
+ graphqlUrl?: string;
269
+ retries?: number;
270
+ }): Promise<string>;
271
+ getVersion(opts?: {
272
+ antRegistryId?: string;
273
+ graphqlUrl?: string;
274
+ retries?: number;
275
+ }): Promise<string>;
276
+ isLatestVersion(opts?: {
277
+ antRegistryId?: string;
278
+ graphqlUrl?: string;
279
+ retries?: number;
280
+ }): Promise<boolean>;
267
281
  }
268
282
  export interface AoANTWrite extends AoANTRead {
269
283
  transfer: AoWriteAction<{
@@ -320,6 +334,17 @@ export interface AoANTWrite extends AoANTRead {
320
334
  arioProcessId: string;
321
335
  notifyOwners?: boolean;
322
336
  }>;
337
+ upgrade(params: {
338
+ names?: string[];
339
+ reassignAffiliatedNames?: boolean;
340
+ arioProcessId?: string;
341
+ antRegistryId?: string;
342
+ onSigningProgress?: (name: keyof UpgradeAntProgressEvent, payload: UpgradeAntProgressEvent[keyof UpgradeAntProgressEvent]) => void;
343
+ }): Promise<{
344
+ forkedProcessId: string;
345
+ reassignedNames: string[];
346
+ failedReassignedNames: string[];
347
+ }>;
323
348
  }
324
349
  export type AoANTSetBaseNameRecordParams = {
325
350
  transactionId: string;
@@ -126,6 +126,26 @@ export type SpawnAntProgressEvent = {
126
126
  owner: WalletAddress;
127
127
  };
128
128
  };
129
+ export type UpgradeAntProgressEvent = SpawnAntProgressEvent & {
130
+ 'checking-version': {
131
+ antProcessId: string;
132
+ antRegistryId: string;
133
+ };
134
+ 'fetching-affiliated-names': {
135
+ arioProcessId: string;
136
+ antProcessId: string;
137
+ };
138
+ 'reassigning-name': {
139
+ name: string;
140
+ arioProcessId: string;
141
+ antProcessId: string;
142
+ };
143
+ 'validating-names': {
144
+ arioProcessId: string;
145
+ antProcessId: string;
146
+ names: string[];
147
+ };
148
+ };
129
149
  export type BuyArNSNameProgressEvents = SpawnAntProgressEvent & {
130
150
  'buying-name': AoBuyRecordParams;
131
151
  };