@ar.io/sdk 3.15.0 → 3.16.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.
@@ -16,17 +16,35 @@
16
16
  import { ArconnectSigner, DataItem, createData } from '@dha-team/arbundles';
17
17
  import { connect, createDataItemSigner } from '@permaweb/aoconnect';
18
18
  import { z } from 'zod';
19
+ import { ANTRegistry } from '../common/ant-registry.js';
20
+ import { ANTVersions } from '../common/ant-versions.js';
19
21
  import { defaultArweave } from '../common/arweave.js';
20
22
  import { AOProcess, Logger } from '../common/index.js';
21
- import { ANT_LUA_ID, ANT_REGISTRY_ID, AOS_MODULE_ID, AO_AUTHORITY, DEFAULT_SCHEDULER_ID, } from '../constants.js';
23
+ import { ANT_LUA_ID, ANT_REGISTRY_ID, AO_AUTHORITY, DEFAULT_SCHEDULER_ID, } from '../constants.js';
22
24
  import { SpawnANTStateSchema } from '../types/ant.js';
23
25
  import { parseSchemaResult } from './schema.js';
24
- export async function spawnANT({ signer, module = AOS_MODULE_ID, ao = connect({
26
+ export async function spawnANT({ signer, module, ao = connect({
25
27
  MODE: 'legacy',
26
28
  }), scheduler = DEFAULT_SCHEDULER_ID, state, antRegistryId = ANT_REGISTRY_ID, logger = Logger.default, authority = AO_AUTHORITY, }) {
27
29
  if (state) {
28
30
  parseSchemaResult(SpawnANTStateSchema, state);
29
31
  }
32
+ if (module === undefined) {
33
+ const antRegistry = ANTVersions.init({
34
+ process: new AOProcess({
35
+ processId: antRegistryId,
36
+ ao,
37
+ logger,
38
+ }),
39
+ });
40
+ const { moduleId: latestAntModule, version } = await antRegistry.getLatestANTVersion();
41
+ logger.debug('Spawning new ANT with latest module from ANT registry', {
42
+ moduleId: latestAntModule,
43
+ version,
44
+ antRegistryId,
45
+ });
46
+ module = latestAntModule;
47
+ }
30
48
  const processId = await ao.spawn({
31
49
  module,
32
50
  scheduler,
@@ -44,64 +62,139 @@ export async function spawnANT({ signer, module = AOS_MODULE_ID, ao = connect({
44
62
  },
45
63
  ],
46
64
  });
47
- let bootRes;
48
- let attempts = 0;
49
- while (attempts < 5 && bootRes === undefined) {
50
- try {
51
- if (bootRes === undefined) {
52
- bootRes = await ao.result({
53
- process: processId,
54
- message: processId,
65
+ /**
66
+ * Note: if we are given a state, ensure the ANT was initialized with it
67
+ * there is a bug in the ANT source where we try to parse the empty default
68
+ * 'Data' string as JSON that causes the Invalid-Boot-Notice error, even though
69
+ * the ANT was initialized with the default state set by the ANT source code.
70
+ *
71
+ * Reference: https://github.com/ar-io/ar-io-ant-process/blob/b89018ffcce079add2e90e7ab82d0bbc9b671346/src/common/main.lua#L355-L358
72
+ */
73
+ if (state !== undefined) {
74
+ let bootRes;
75
+ let attempts = 0;
76
+ while (attempts < 5 && bootRes === undefined) {
77
+ try {
78
+ if (bootRes === undefined) {
79
+ bootRes = await ao.result({
80
+ process: processId,
81
+ message: processId,
82
+ });
83
+ }
84
+ break;
85
+ }
86
+ catch (error) {
87
+ logger.debug('Retrying ANT boot result fetch', {
88
+ processId,
89
+ module,
90
+ scheduler,
91
+ attempts,
92
+ error,
55
93
  });
94
+ attempts++;
95
+ await new Promise((resolve) => setTimeout(resolve, 1000 * attempts ** 2));
56
96
  }
57
- break;
58
97
  }
59
- catch (error) {
60
- logger.debug('Retrying ANT boot result fetch', {
98
+ if (bootRes === undefined ||
99
+ bootRes.Messages?.some((m) => m?.Tags?.some((t) => t.value === 'Invalid-Boot-Notice'))) {
100
+ if (bootRes === undefined) {
101
+ throw new Error('Failed to get boot result');
102
+ }
103
+ const bootError = errorMessageFromOutput(bootRes);
104
+ logger.error('ANT failed to boot correctly', {
61
105
  processId,
62
106
  module,
63
107
  scheduler,
64
- attempts,
65
- error,
108
+ bootRes,
109
+ bootError,
66
110
  });
67
- attempts++;
68
- await new Promise((resolve) => setTimeout(resolve, 1000 * attempts ** 2));
111
+ throw new Error(`ANT failed to boot correctly: ${bootError}`);
69
112
  }
70
113
  }
71
- if (bootRes === undefined ||
72
- bootRes.Messages?.some((m) => m?.Tags?.some((t) => t.value === 'Invalid-Boot-Notice'))) {
73
- if (bootRes === undefined) {
74
- //
75
- throw new Error('Failed to get boot result');
114
+ // Note: for hyperbeam caching, due to a SU issue, we need to send a second message to the ANT to cache the state
115
+ // We wait for the first message to be processed before sending the second one to ensure this is the second message
116
+ // We use the resulting state to check the owner of the ANT is set in the registry. Should this be patched on MUs,
117
+ // we can convert to just a simple dry-run to avoid sending/signing another message.
118
+ let owner;
119
+ try {
120
+ const processApi = new AOProcess({
121
+ processId,
122
+ ao,
123
+ logger,
124
+ });
125
+ const { id } = await processApi.send({
126
+ tags: [{ name: 'Action', value: 'State' }],
127
+ signer,
128
+ });
129
+ const stateResult = await ao.result({
130
+ process: processId,
131
+ message: id,
132
+ });
133
+ if (stateResult === undefined) {
134
+ throw new Error('Failed to get state result');
76
135
  }
77
- const bootError = errorMessageFromOutput(bootRes);
78
- logger.error('ANT failed to boot correctly', {
136
+ const { Owner } = JSON.parse(stateResult.Messages?.[0]?.Data ?? '{}');
137
+ owner = Owner;
138
+ logger.debug(`Successfully spawned new ANT and validated owner`, {
79
139
  processId,
80
140
  module,
81
- scheduler,
82
- bootRes,
83
- bootError,
141
+ owner,
84
142
  });
85
- throw new Error(`ANT failed to boot correctly: ${bootError}`);
86
143
  }
87
- // for hyperbeam caching, due to a SU issue, we need to send a second message to the ANT to cache the state
88
- // We wait for the first message to be processed before sending the second one to ensure this is the second message
89
- const processApi = new AOProcess({
90
- processId,
91
- ao,
92
- logger,
93
- });
94
- await processApi.send({
95
- tags: [{ name: 'Action', value: 'State' }],
144
+ catch (error) {
145
+ logger.error('Failed to validate owner of spawned ANT', {
146
+ processId,
147
+ module,
148
+ error,
149
+ });
150
+ throw error;
151
+ }
152
+ /**
153
+ * Now confirm the owner of the ANT is set in the registry
154
+ * This is to ensure the ANT is available via the ANT registry
155
+ * for the owner to find and use the ANT.
156
+ */
157
+ if (owner === undefined) {
158
+ throw new Error(`Spawning ANT (${processId}) failed to set owner`);
159
+ }
160
+ // check the ACL for the owner
161
+ const antRegistry = ANTRegistry.init({
96
162
  signer,
163
+ processId: antRegistryId,
97
164
  });
98
- logger.debug(`Spawned ANT`, {
99
- processId,
100
- module,
101
- scheduler,
102
- });
165
+ let attempts = 0;
166
+ const maxAttempts = 5;
167
+ while (attempts < maxAttempts) {
168
+ try {
169
+ const acl = await antRegistry.accessControlList({ address: owner });
170
+ if (acl === undefined) {
171
+ throw new Error('ACL not found for owner');
172
+ }
173
+ const { Owned } = acl;
174
+ if (!Owned.includes(processId)) {
175
+ throw new Error(`Spawned ANT (${processId}) not found in registry for owner ${owner}`);
176
+ }
177
+ return processId;
178
+ }
179
+ catch (error) {
180
+ logger.debug('Retrying ANT registry access control list fetch', {
181
+ owner,
182
+ antRegistryId,
183
+ attempts,
184
+ error,
185
+ });
186
+ attempts++;
187
+ await new Promise((resolve) => setTimeout(resolve, 1000 * attempts ** 2));
188
+ }
189
+ }
103
190
  return processId;
104
191
  }
192
+ // TODO: add a utility for forking an ANT to the latest module that leverages getState and spawnANT
193
+ /**
194
+ * @deprecated
195
+ * Direct Evals are not encouraged when dealing with ANTs.
196
+ * Instead, use spawnANT to fork an ANT to new module source code
197
+ */
105
198
  export async function evolveANT({ signer, processId, luaCodeTxId = ANT_LUA_ID, ao = connect({
106
199
  MODE: 'legacy',
107
200
  }), logger = Logger.default, arweave = defaultArweave, }) {
@@ -110,6 +203,7 @@ export async function evolveANT({ signer, processId, luaCodeTxId = ANT_LUA_ID, a
110
203
  ao,
111
204
  logger,
112
205
  });
206
+ logger.warn('Directly running an Eval on a process is not encouraged.');
113
207
  //TODO: cache locally and only fetch if not cached
114
208
  // We do not use arweave to get the data because it may throw on l2 tx data
115
209
  const { api: { host, port, protocol }, } = arweave.getConfig();
@@ -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.15.0';
17
+ export const version = '3.16.0-alpha.1';
@@ -1,18 +1,3 @@
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 { AoArNSPurchaseParams, AoBuyRecordParams, AoExtendLeaseParams, AoIncreaseUndernameLimitParams } from '../../types/io.js';
17
2
  import { CLIWriteOptionsFromAoParams } from '../types.js';
18
3
  export declare function buyRecordCLICommand(o: CLIWriteOptionsFromAoParams<AoBuyRecordParams>): Promise<import("../../types/common.js").AoMessageResult>;
@@ -1,5 +1,6 @@
1
- import { AntReadOptions, AoANTHandler, AoANTInfo, AoANTRead, AoANTRecord, AoANTSetBaseNameRecordParams, AoANTSetUndernameRecordParams, AoANTState, AoANTVersionsRead, AoANTWrite, SortedANTRecords } from '../types/ant.js';
1
+ import { AntReadOptions, AoANTHandler, AoANTInfo, AoANTRead, AoANTRecord, AoANTSetBaseNameRecordParams, AoANTSetUndernameRecordParams, AoANTState, AoANTWrite, SortedANTRecords } from '../types/ant.js';
2
2
  import { AoMessageResult, ProcessConfiguration, WalletAddress, WithSigner, WriteOptions } from '../types/index.js';
3
+ import { spawnANT } from '../utils/ao.js';
3
4
  import { AOProcess } from './index.js';
4
5
  type ANTConfigOptionalStrict = Required<ProcessConfiguration> & {
5
6
  strict?: boolean;
@@ -8,7 +9,16 @@ type ANTConfigOptionalStrict = Required<ProcessConfiguration> & {
8
9
  type ANTConfigNoSigner = ANTConfigOptionalStrict;
9
10
  type ANTConfigWithSigner = WithSigner<ANTConfigOptionalStrict>;
10
11
  export declare class ANT {
11
- static versions: AoANTVersionsRead;
12
+ /**
13
+ * Versions of ANTs according to the ANT registry.
14
+ *
15
+ * Needs to be wrapped in a getter to avoid circular dependency issues.
16
+ */
17
+ static get versions(): import("../types/ant.js").AoANTVersionsRead;
18
+ /**
19
+ * Spawn a new ANT.
20
+ */
21
+ static spawn: typeof spawnANT;
12
22
  static init(config: ANTConfigNoSigner): AoANTRead;
13
23
  static init(config: ANTConfigWithSigner): AoANTWrite;
14
24
  }
@@ -1,6 +1,7 @@
1
1
  import Arweave from 'arweave';
2
2
  import { ARIOWithFaucet, AoARIORead, AoARIOWrite, AoAllDelegates, AoAllGatewayVaults, AoArNSNameData, AoArNSNameDataWithName, AoArNSPurchaseParams, AoArNSReservedNameData, AoArNSReservedNameDataWithName, AoBalanceWithAddress, AoBuyRecordParams, AoCreateVaultParams, AoDelegation, AoEligibleDistribution, AoEpochData, AoEpochDistributed, AoEpochDistributionData, AoEpochDistributionTotalsData, AoEpochObservationData, AoEpochSettings, AoExtendLeaseParams, AoExtendVaultParams, AoGateway, AoGatewayDelegateWithAddress, AoGatewayRegistrySettings, AoGatewayVault, AoGatewayWithAddress, AoGetCostDetailsParams, AoIncreaseUndernameLimitParams, AoIncreaseVaultParams, AoJoinNetworkParams, AoMessageResult, AoPaginatedAddressParams, AoPrimaryName, AoPrimaryNameRequest, AoRedelegationFeeInfo, AoRegistrationFees, AoReturnedName, AoRevokeVaultParams, AoTokenSupplyData, AoUpdateGatewaySettingsParams, AoVaultData, AoVaultedTransferParams, AoWalletVault, AoWeightedObserver, ArNSNameResolutionData, ArNSNameResolver, CostDetailsResult, DemandFactorSettings, EpochInput, OptionalArweave, OptionalPaymentUrl, PaginationParams, PaginationResult, ProcessConfiguration, TransactionId, WalletAddress, WithSigner, WriteOptions, mARIOToken } from '../types/index.js';
3
3
  import { AOProcess } from './contracts/ao-process.js';
4
+ import { Logger } from './logger.js';
4
5
  import { TurboArNSPaymentProviderAuthenticated, TurboArNSPaymentProviderUnauthenticated } from './turbo.js';
5
6
  type ARIOConfigNoSigner = OptionalPaymentUrl<OptionalArweave<ProcessConfiguration>>;
6
7
  type ARIOConfigWithSigner = WithSigner<OptionalPaymentUrl<OptionalArweave<ProcessConfiguration>>>;
@@ -24,6 +25,7 @@ export declare class ARIOReadable implements AoARIORead, ArNSNameResolver {
24
25
  protected epochSettings: AoEpochSettings | undefined;
25
26
  protected arweave: Arweave;
26
27
  protected paymentProvider: TurboArNSPaymentProviderUnauthenticated;
28
+ protected logger: Logger;
27
29
  constructor(config?: ARIOConfigNoSigner);
28
30
  getInfo(): Promise<{
29
31
  Name: string;
@@ -25,7 +25,13 @@ export declare const ARIO_TESTNET_PROCESS_ID = "agYcCFJtrMG6cqMuZfskIkFTGvUPddIC
25
25
  export declare const ARIO_MAINNET_PROCESS_ID = "qNvAoz0TgcH7DMg8BCVn8jF32QH5L6T29VjHxhHqqGE";
26
26
  export declare const ANT_REGISTRY_ID = "i_le_yKKPVstLTDSmkHRqf-wYphMnwB9OhleiTgMkWc";
27
27
  export declare const MARIO_PER_ARIO = 1000000;
28
- export declare const AOS_MODULE_ID = "pb4fCvdJqwT-_bn38ERMdqnOF4weRMjoJ6bY6yfl4a8";
29
- export declare const ANT_LUA_ID = "OO2ewZKq4AHoqGQmYUIl-NhJ-llQyFJ3ha4Uf4-w5RI";
28
+ /**
29
+ * @deprecated - use ANT.versions.getLatestANTVersion() to get latest ANT module
30
+ **/
31
+ export declare const AOS_MODULE_ID = "nEjlSFA_8narJlVHApbczDPkMc9znSqYtqtf1iOdoxM";
32
+ /**
33
+ * @deprecated - use ANT.versions.getLatestANTVersion() to get latest ANT module
34
+ **/
35
+ export declare const ANT_LUA_ID = "sOW9Sdm1yoPRrzerC5iu1nsupp4e6I-HnJyYVHzvzQo";
30
36
  export declare const AO_AUTHORITY = "fcoN_xJeisVsPXA-trzVAuIiqO3ydLQxM-L4XbrQKzY";
31
37
  export declare const DEFAULT_SCHEDULER_ID = "_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA";
@@ -353,7 +353,7 @@ export type AoArNSPurchaseParams = AoArNSNameParams & {
353
353
  export type AoBuyRecordParams = AoArNSPurchaseParams & {
354
354
  years?: number;
355
355
  type: 'lease' | 'permabuy';
356
- processId: string;
356
+ processId?: string;
357
357
  };
358
358
  export type AoExtendLeaseParams = AoArNSPurchaseParams & {
359
359
  years: number;
@@ -1,7 +1,7 @@
1
1
  import Arweave from 'arweave';
2
2
  import { Logger } from '../common/index.js';
3
3
  import { SpawnANTState } from '../types/ant.js';
4
- import { AoClient, AoEpochData, AoEpochDistributed, AoSigner, ContractSigner, WalletAddress } from '../types/index.js';
4
+ import { AoClient, AoEpochData, AoEpochDistributed, AoSigner, ContractSigner, ProcessId, WalletAddress } from '../types/index.js';
5
5
  export type SpawnANTParams = {
6
6
  signer: AoSigner;
7
7
  module?: string;
@@ -21,7 +21,12 @@ export type SpawnANTParams = {
21
21
  */
22
22
  arweave?: Arweave;
23
23
  };
24
- export declare function spawnANT({ signer, module, ao, scheduler, state, antRegistryId, logger, authority, }: SpawnANTParams): Promise<string>;
24
+ export declare function spawnANT({ signer, module, ao, scheduler, state, antRegistryId, logger, authority, }: SpawnANTParams): Promise<ProcessId>;
25
+ /**
26
+ * @deprecated
27
+ * Direct Evals are not encouraged when dealing with ANTs.
28
+ * Instead, use spawnANT to fork an ANT to new module source code
29
+ */
25
30
  export declare function evolveANT({ signer, processId, luaCodeTxId, ao, logger, arweave, }: {
26
31
  signer: AoSigner;
27
32
  processId: string;
@@ -13,4 +13,4 @@
13
13
  * See the License for the specific language governing permissions and
14
14
  * limitations under the License.
15
15
  */
16
- export declare const version = "3.15.0-alpha.1";
16
+ export declare const version = "3.15.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ar.io/sdk",
3
- "version": "3.15.0",
3
+ "version": "3.16.0-alpha.1",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/ar-io/ar-io-sdk.git"