@ar.io/sdk 3.15.1 → 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.
@@ -403,6 +403,7 @@ const utils_js_1 = require("./utils.js");
403
403
  options: options_js_1.buyRecordOptions,
404
404
  action: arnsPurchaseCommands_js_1.buyRecordCLICommand,
405
405
  });
406
+ // TODO alias buy-record with buy-name
406
407
  (0, utils_js_1.makeCommand)({
407
408
  name: 'upgrade-record',
408
409
  description: 'Upgrade the lease of a record to a permabuy',
@@ -5,6 +5,22 @@ exports.upgradeRecordCLICommand = upgradeRecordCLICommand;
5
5
  exports.extendLeaseCLICommand = extendLeaseCLICommand;
6
6
  exports.increaseUndernameLimitCLICommand = increaseUndernameLimitCLICommand;
7
7
  exports.requestPrimaryNameCLICommand = requestPrimaryNameCLICommand;
8
+ /**
9
+ * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
10
+ *
11
+ * Licensed under the Apache License, Version 2.0 (the "License");
12
+ * you may not use this file except in compliance with the License.
13
+ * You may obtain a copy of the License at
14
+ *
15
+ * http://www.apache.org/licenses/LICENSE-2.0
16
+ *
17
+ * Unless required by applicable law or agreed to in writing, software
18
+ * distributed under the License is distributed on an "AS IS" BASIS,
19
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
+ * See the License for the specific language governing permissions and
21
+ * limitations under the License.
22
+ */
23
+ const ant_js_1 = require("../../common/ant.js");
8
24
  const utils_js_1 = require("../utils.js");
9
25
  async function buyRecordCLICommand(o) {
10
26
  const { ario, signerAddress } = (0, utils_js_1.writeARIOFromOptions)(o);
@@ -14,10 +30,6 @@ async function buyRecordCLICommand(o) {
14
30
  const fundFrom = (0, utils_js_1.fundFromFromOptions)(o);
15
31
  const referrer = (0, utils_js_1.referrerFromOptions)(o);
16
32
  const processId = o.processId;
17
- if (processId === undefined) {
18
- // TODO: Spawn ANT process, register it to ANT registry, get process ID
19
- throw new Error('Process ID must be provided for buy-record');
20
- }
21
33
  if (!o.skipConfirmation) {
22
34
  const existingRecord = await ario.getArNSRecord({
23
35
  name,
@@ -37,7 +49,13 @@ async function buyRecordCLICommand(o) {
37
49
  fromAddress: signerAddress,
38
50
  },
39
51
  });
40
- await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to ${type} the record ${name}?`, o);
52
+ // assert spawn new ant with module id
53
+ let antSpawnConfirmation = '';
54
+ if (processId === undefined) {
55
+ const { moduleId, version } = await ant_js_1.ANT.versions.getLatestANTVersion();
56
+ antSpawnConfirmation = `Note: A new ANT process will be spawned with module ${moduleId} (v${version}) and assigned to this name.`;
57
+ }
58
+ await (0, utils_js_1.assertConfirmationPrompt)(`Are you sure you want to ${type} the record ${name}? ${antSpawnConfirmation}`, o);
41
59
  }
42
60
  return ario.buyRecord({
43
61
  name: (0, utils_js_1.requiredStringFromOptions)(o, 'name'),
@@ -25,7 +25,18 @@ const schema_js_1 = require("../utils/schema.js");
25
25
  const ant_versions_js_1 = require("./ant-versions.js");
26
26
  const index_js_2 = require("./index.js");
27
27
  class ANT {
28
- static versions = ant_versions_js_1.ANTVersions.init();
28
+ /**
29
+ * Versions of ANTs according to the ANT registry.
30
+ *
31
+ * Needs to be wrapped in a getter to avoid circular dependency issues.
32
+ */
33
+ static get versions() {
34
+ return ant_versions_js_1.ANTVersions.init();
35
+ }
36
+ /**
37
+ * Spawn a new ANT.
38
+ */
39
+ static spawn = ao_js_1.spawnANT;
29
40
  // implementation
30
41
  static init(config) {
31
42
  if (config !== undefined && 'signer' in config) {
@@ -26,6 +26,7 @@ const arweave_js_2 = require("./arweave.js");
26
26
  const ao_process_js_1 = require("./contracts/ao-process.js");
27
27
  const error_js_1 = require("./error.js");
28
28
  const faucet_js_1 = require("./faucet.js");
29
+ const logger_js_1 = require("./logger.js");
29
30
  const turbo_js_1 = require("./turbo.js");
30
31
  class ARIO {
31
32
  // Implementation
@@ -100,6 +101,7 @@ class ARIOReadable {
100
101
  epochSettings;
101
102
  arweave;
102
103
  paymentProvider; // TODO: this could be an array/map of payment providers
104
+ logger = logger_js_1.Logger.default;
103
105
  constructor(config) {
104
106
  this.arweave = config?.arweave ?? arweave_js_2.defaultArweave;
105
107
  if (config === undefined || Object.keys(config).length === 0) {
@@ -964,6 +966,23 @@ class ARIOWriteable extends ARIOReadable {
964
966
  });
965
967
  }
966
968
  async buyRecord(params, options) {
969
+ // spawn a new ANT if not provided
970
+ if (params.processId === undefined) {
971
+ try {
972
+ params.processId = await ant_js_1.ANT.spawn({
973
+ signer: this.signer,
974
+ ao: this.process.ao,
975
+ logger: this.logger,
976
+ });
977
+ }
978
+ catch (error) {
979
+ this.logger.error('Failed to spawn ANT for name purchase.', {
980
+ error,
981
+ });
982
+ throw error;
983
+ }
984
+ }
985
+ // pay with turbo credits if available
967
986
  if (params.fundFrom === 'turbo') {
968
987
  if (!(this.paymentProvider instanceof turbo_js_1.TurboArNSPaymentProviderAuthenticated)) {
969
988
  throw new Error('Turbo funding is not supported for this payment provider');
@@ -30,7 +30,13 @@ exports.ARIO_TESTNET_PROCESS_ID = 'agYcCFJtrMG6cqMuZfskIkFTGvUPddICmtQSBIoPdiA';
30
30
  exports.ARIO_MAINNET_PROCESS_ID = 'qNvAoz0TgcH7DMg8BCVn8jF32QH5L6T29VjHxhHqqGE';
31
31
  exports.ANT_REGISTRY_ID = 'i_le_yKKPVstLTDSmkHRqf-wYphMnwB9OhleiTgMkWc';
32
32
  exports.MARIO_PER_ARIO = 1_000_000;
33
+ /**
34
+ * @deprecated - use ANT.versions.getLatestANTVersion() to get latest ANT module
35
+ **/
33
36
  exports.AOS_MODULE_ID = 'nEjlSFA_8narJlVHApbczDPkMc9znSqYtqtf1iOdoxM';
37
+ /**
38
+ * @deprecated - use ANT.versions.getLatestANTVersion() to get latest ANT module
39
+ **/
34
40
  exports.ANT_LUA_ID = 'sOW9Sdm1yoPRrzerC5iu1nsupp4e6I-HnJyYVHzvzQo';
35
41
  exports.AO_AUTHORITY = 'fcoN_xJeisVsPXA-trzVAuIiqO3ydLQxM-L4XbrQKzY';
36
42
  exports.DEFAULT_SCHEDULER_ID = '_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA';
@@ -27,17 +27,35 @@ exports.removeUnicodeFromError = removeUnicodeFromError;
27
27
  const arbundles_1 = require("@dha-team/arbundles");
28
28
  const aoconnect_1 = require("@permaweb/aoconnect");
29
29
  const zod_1 = require("zod");
30
+ const ant_registry_js_1 = require("../common/ant-registry.js");
31
+ const ant_versions_js_1 = require("../common/ant-versions.js");
30
32
  const arweave_js_1 = require("../common/arweave.js");
31
33
  const index_js_1 = require("../common/index.js");
32
34
  const constants_js_1 = require("../constants.js");
33
35
  const ant_js_1 = require("../types/ant.js");
34
36
  const schema_js_1 = require("./schema.js");
35
- async function spawnANT({ signer, module = constants_js_1.AOS_MODULE_ID, ao = (0, aoconnect_1.connect)({
37
+ async function spawnANT({ signer, module, ao = (0, aoconnect_1.connect)({
36
38
  MODE: 'legacy',
37
39
  }), scheduler = constants_js_1.DEFAULT_SCHEDULER_ID, state, antRegistryId = constants_js_1.ANT_REGISTRY_ID, logger = index_js_1.Logger.default, authority = constants_js_1.AO_AUTHORITY, }) {
38
40
  if (state) {
39
41
  (0, schema_js_1.parseSchemaResult)(ant_js_1.SpawnANTStateSchema, state);
40
42
  }
43
+ if (module === undefined) {
44
+ const antRegistry = ant_versions_js_1.ANTVersions.init({
45
+ process: new index_js_1.AOProcess({
46
+ processId: antRegistryId,
47
+ ao,
48
+ logger,
49
+ }),
50
+ });
51
+ const { moduleId: latestAntModule, version } = await antRegistry.getLatestANTVersion();
52
+ logger.debug('Spawning new ANT with latest module from ANT registry', {
53
+ moduleId: latestAntModule,
54
+ version,
55
+ antRegistryId,
56
+ });
57
+ module = latestAntModule;
58
+ }
41
59
  const processId = await ao.spawn({
42
60
  module,
43
61
  scheduler,
@@ -55,64 +73,139 @@ async function spawnANT({ signer, module = constants_js_1.AOS_MODULE_ID, ao = (0
55
73
  },
56
74
  ],
57
75
  });
58
- let bootRes;
59
- let attempts = 0;
60
- while (attempts < 5 && bootRes === undefined) {
61
- try {
62
- if (bootRes === undefined) {
63
- bootRes = await ao.result({
64
- process: processId,
65
- message: processId,
76
+ /**
77
+ * Note: if we are given a state, ensure the ANT was initialized with it
78
+ * there is a bug in the ANT source where we try to parse the empty default
79
+ * 'Data' string as JSON that causes the Invalid-Boot-Notice error, even though
80
+ * the ANT was initialized with the default state set by the ANT source code.
81
+ *
82
+ * Reference: https://github.com/ar-io/ar-io-ant-process/blob/b89018ffcce079add2e90e7ab82d0bbc9b671346/src/common/main.lua#L355-L358
83
+ */
84
+ if (state !== undefined) {
85
+ let bootRes;
86
+ let attempts = 0;
87
+ while (attempts < 5 && bootRes === undefined) {
88
+ try {
89
+ if (bootRes === undefined) {
90
+ bootRes = await ao.result({
91
+ process: processId,
92
+ message: processId,
93
+ });
94
+ }
95
+ break;
96
+ }
97
+ catch (error) {
98
+ logger.debug('Retrying ANT boot result fetch', {
99
+ processId,
100
+ module,
101
+ scheduler,
102
+ attempts,
103
+ error,
66
104
  });
105
+ attempts++;
106
+ await new Promise((resolve) => setTimeout(resolve, 1000 * attempts ** 2));
67
107
  }
68
- break;
69
108
  }
70
- catch (error) {
71
- logger.debug('Retrying ANT boot result fetch', {
109
+ if (bootRes === undefined ||
110
+ bootRes.Messages?.some((m) => m?.Tags?.some((t) => t.value === 'Invalid-Boot-Notice'))) {
111
+ if (bootRes === undefined) {
112
+ throw new Error('Failed to get boot result');
113
+ }
114
+ const bootError = errorMessageFromOutput(bootRes);
115
+ logger.error('ANT failed to boot correctly', {
72
116
  processId,
73
117
  module,
74
118
  scheduler,
75
- attempts,
76
- error,
119
+ bootRes,
120
+ bootError,
77
121
  });
78
- attempts++;
79
- await new Promise((resolve) => setTimeout(resolve, 1000 * attempts ** 2));
122
+ throw new Error(`ANT failed to boot correctly: ${bootError}`);
80
123
  }
81
124
  }
82
- if (bootRes === undefined ||
83
- bootRes.Messages?.some((m) => m?.Tags?.some((t) => t.value === 'Invalid-Boot-Notice'))) {
84
- if (bootRes === undefined) {
85
- //
86
- throw new Error('Failed to get boot result');
125
+ // Note: for hyperbeam caching, due to a SU issue, we need to send a second message to the ANT to cache the state
126
+ // We wait for the first message to be processed before sending the second one to ensure this is the second message
127
+ // We use the resulting state to check the owner of the ANT is set in the registry. Should this be patched on MUs,
128
+ // we can convert to just a simple dry-run to avoid sending/signing another message.
129
+ let owner;
130
+ try {
131
+ const processApi = new index_js_1.AOProcess({
132
+ processId,
133
+ ao,
134
+ logger,
135
+ });
136
+ const { id } = await processApi.send({
137
+ tags: [{ name: 'Action', value: 'State' }],
138
+ signer,
139
+ });
140
+ const stateResult = await ao.result({
141
+ process: processId,
142
+ message: id,
143
+ });
144
+ if (stateResult === undefined) {
145
+ throw new Error('Failed to get state result');
87
146
  }
88
- const bootError = errorMessageFromOutput(bootRes);
89
- logger.error('ANT failed to boot correctly', {
147
+ const { Owner } = JSON.parse(stateResult.Messages?.[0]?.Data ?? '{}');
148
+ owner = Owner;
149
+ logger.debug(`Successfully spawned new ANT and validated owner`, {
90
150
  processId,
91
151
  module,
92
- scheduler,
93
- bootRes,
94
- bootError,
152
+ owner,
95
153
  });
96
- throw new Error(`ANT failed to boot correctly: ${bootError}`);
97
154
  }
98
- // for hyperbeam caching, due to a SU issue, we need to send a second message to the ANT to cache the state
99
- // We wait for the first message to be processed before sending the second one to ensure this is the second message
100
- const processApi = new index_js_1.AOProcess({
101
- processId,
102
- ao,
103
- logger,
104
- });
105
- await processApi.send({
106
- tags: [{ name: 'Action', value: 'State' }],
155
+ catch (error) {
156
+ logger.error('Failed to validate owner of spawned ANT', {
157
+ processId,
158
+ module,
159
+ error,
160
+ });
161
+ throw error;
162
+ }
163
+ /**
164
+ * Now confirm the owner of the ANT is set in the registry
165
+ * This is to ensure the ANT is available via the ANT registry
166
+ * for the owner to find and use the ANT.
167
+ */
168
+ if (owner === undefined) {
169
+ throw new Error(`Spawning ANT (${processId}) failed to set owner`);
170
+ }
171
+ // check the ACL for the owner
172
+ const antRegistry = ant_registry_js_1.ANTRegistry.init({
107
173
  signer,
174
+ processId: antRegistryId,
108
175
  });
109
- logger.debug(`Spawned ANT`, {
110
- processId,
111
- module,
112
- scheduler,
113
- });
176
+ let attempts = 0;
177
+ const maxAttempts = 5;
178
+ while (attempts < maxAttempts) {
179
+ try {
180
+ const acl = await antRegistry.accessControlList({ address: owner });
181
+ if (acl === undefined) {
182
+ throw new Error('ACL not found for owner');
183
+ }
184
+ const { Owned } = acl;
185
+ if (!Owned.includes(processId)) {
186
+ throw new Error(`Spawned ANT (${processId}) not found in registry for owner ${owner}`);
187
+ }
188
+ return processId;
189
+ }
190
+ catch (error) {
191
+ logger.debug('Retrying ANT registry access control list fetch', {
192
+ owner,
193
+ antRegistryId,
194
+ attempts,
195
+ error,
196
+ });
197
+ attempts++;
198
+ await new Promise((resolve) => setTimeout(resolve, 1000 * attempts ** 2));
199
+ }
200
+ }
114
201
  return processId;
115
202
  }
203
+ // TODO: add a utility for forking an ANT to the latest module that leverages getState and spawnANT
204
+ /**
205
+ * @deprecated
206
+ * Direct Evals are not encouraged when dealing with ANTs.
207
+ * Instead, use spawnANT to fork an ANT to new module source code
208
+ */
116
209
  async function evolveANT({ signer, processId, luaCodeTxId = constants_js_1.ANT_LUA_ID, ao = (0, aoconnect_1.connect)({
117
210
  MODE: 'legacy',
118
211
  }), logger = index_js_1.Logger.default, arweave = arweave_js_1.defaultArweave, }) {
@@ -121,6 +214,7 @@ async function evolveANT({ signer, processId, luaCodeTxId = constants_js_1.ANT_L
121
214
  ao,
122
215
  logger,
123
216
  });
217
+ logger.warn('Directly running an Eval on a process is not encouraged.');
124
218
  //TODO: cache locally and only fetch if not cached
125
219
  // We do not use arweave to get the data because it may throw on l2 tx data
126
220
  const { api: { host, port, protocol }, } = arweave.getConfig();
@@ -17,4 +17,4 @@
17
17
  Object.defineProperty(exports, "__esModule", { value: true });
18
18
  exports.version = void 0;
19
19
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
20
- exports.version = '3.15.1';
20
+ exports.version = '3.16.0-alpha.1';
@@ -401,6 +401,7 @@ makeCommand({
401
401
  options: buyRecordOptions,
402
402
  action: buyRecordCLICommand,
403
403
  });
404
+ // TODO alias buy-record with buy-name
404
405
  makeCommand({
405
406
  name: 'upgrade-record',
406
407
  description: 'Upgrade the lease of a record to a permabuy',
@@ -1,3 +1,19 @@
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 { ANT } from '../../common/ant.js';
1
17
  import { assertConfirmationPrompt, assertEnoughBalanceForArNSPurchase, customTagsFromOptions, fundFromFromOptions, positiveIntegerFromOptions, recordTypeFromOptions, referrerFromOptions, requiredPositiveIntegerFromOptions, requiredStringFromOptions, stringArrayFromOptions, writeARIOFromOptions, } from '../utils.js';
2
18
  export async function buyRecordCLICommand(o) {
3
19
  const { ario, signerAddress } = writeARIOFromOptions(o);
@@ -7,10 +23,6 @@ export async function buyRecordCLICommand(o) {
7
23
  const fundFrom = fundFromFromOptions(o);
8
24
  const referrer = referrerFromOptions(o);
9
25
  const processId = o.processId;
10
- if (processId === undefined) {
11
- // TODO: Spawn ANT process, register it to ANT registry, get process ID
12
- throw new Error('Process ID must be provided for buy-record');
13
- }
14
26
  if (!o.skipConfirmation) {
15
27
  const existingRecord = await ario.getArNSRecord({
16
28
  name,
@@ -30,7 +42,13 @@ export async function buyRecordCLICommand(o) {
30
42
  fromAddress: signerAddress,
31
43
  },
32
44
  });
33
- await assertConfirmationPrompt(`Are you sure you want to ${type} the record ${name}?`, o);
45
+ // assert spawn new ant with module id
46
+ let antSpawnConfirmation = '';
47
+ if (processId === undefined) {
48
+ const { moduleId, version } = await ANT.versions.getLatestANTVersion();
49
+ antSpawnConfirmation = `Note: A new ANT process will be spawned with module ${moduleId} (v${version}) and assigned to this name.`;
50
+ }
51
+ await assertConfirmationPrompt(`Are you sure you want to ${type} the record ${name}? ${antSpawnConfirmation}`, o);
34
52
  }
35
53
  return ario.buyRecord({
36
54
  name: requiredStringFromOptions(o, 'name'),
@@ -17,12 +17,23 @@ import { z } from 'zod';
17
17
  import { AntBalancesSchema, AntControllersSchema, AntInfoSchema, AntRecordSchema, AntRecordsSchema, AntStateSchema, } from '../types/ant.js';
18
18
  import { isProcessConfiguration, isProcessIdConfiguration, } from '../types/index.js';
19
19
  import { convertHyperBeamStateToAoANTState, isHyperBeamANTState, sortANTRecords, } from '../utils/ant.js';
20
- import { createAoSigner } from '../utils/ao.js';
20
+ import { createAoSigner, spawnANT } from '../utils/ao.js';
21
21
  import { parseSchemaResult } from '../utils/schema.js';
22
22
  import { ANTVersions } from './ant-versions.js';
23
23
  import { AOProcess, InvalidContractConfigurationError, Logger, } from './index.js';
24
24
  export class ANT {
25
- static versions = ANTVersions.init();
25
+ /**
26
+ * Versions of ANTs according to the ANT registry.
27
+ *
28
+ * Needs to be wrapped in a getter to avoid circular dependency issues.
29
+ */
30
+ static get versions() {
31
+ return ANTVersions.init();
32
+ }
33
+ /**
34
+ * Spawn a new ANT.
35
+ */
36
+ static spawn = spawnANT;
26
37
  // implementation
27
38
  static init(config) {
28
39
  if (config !== undefined && 'signer' in config) {
@@ -23,6 +23,7 @@ import { defaultArweave } from './arweave.js';
23
23
  import { AOProcess } from './contracts/ao-process.js';
24
24
  import { InvalidContractConfigurationError } from './error.js';
25
25
  import { createFaucet } from './faucet.js';
26
+ import { Logger } from './logger.js';
26
27
  import { TurboArNSPaymentFactory, TurboArNSPaymentProviderAuthenticated, isTurboArNSSigner, } from './turbo.js';
27
28
  export class ARIO {
28
29
  // Implementation
@@ -96,6 +97,7 @@ export class ARIOReadable {
96
97
  epochSettings;
97
98
  arweave;
98
99
  paymentProvider; // TODO: this could be an array/map of payment providers
100
+ logger = Logger.default;
99
101
  constructor(config) {
100
102
  this.arweave = config?.arweave ?? defaultArweave;
101
103
  if (config === undefined || Object.keys(config).length === 0) {
@@ -959,6 +961,23 @@ export class ARIOWriteable extends ARIOReadable {
959
961
  });
960
962
  }
961
963
  async buyRecord(params, options) {
964
+ // spawn a new ANT if not provided
965
+ if (params.processId === undefined) {
966
+ try {
967
+ params.processId = await ANT.spawn({
968
+ signer: this.signer,
969
+ ao: this.process.ao,
970
+ logger: this.logger,
971
+ });
972
+ }
973
+ catch (error) {
974
+ this.logger.error('Failed to spawn ANT for name purchase.', {
975
+ error,
976
+ });
977
+ throw error;
978
+ }
979
+ }
980
+ // pay with turbo credits if available
962
981
  if (params.fundFrom === 'turbo') {
963
982
  if (!(this.paymentProvider instanceof TurboArNSPaymentProviderAuthenticated)) {
964
983
  throw new Error('Turbo funding is not supported for this payment provider');
@@ -27,7 +27,13 @@ export const ARIO_TESTNET_PROCESS_ID = 'agYcCFJtrMG6cqMuZfskIkFTGvUPddICmtQSBIoP
27
27
  export const ARIO_MAINNET_PROCESS_ID = 'qNvAoz0TgcH7DMg8BCVn8jF32QH5L6T29VjHxhHqqGE';
28
28
  export const ANT_REGISTRY_ID = 'i_le_yKKPVstLTDSmkHRqf-wYphMnwB9OhleiTgMkWc';
29
29
  export const MARIO_PER_ARIO = 1_000_000;
30
+ /**
31
+ * @deprecated - use ANT.versions.getLatestANTVersion() to get latest ANT module
32
+ **/
30
33
  export const AOS_MODULE_ID = 'nEjlSFA_8narJlVHApbczDPkMc9znSqYtqtf1iOdoxM';
34
+ /**
35
+ * @deprecated - use ANT.versions.getLatestANTVersion() to get latest ANT module
36
+ **/
31
37
  export const ANT_LUA_ID = 'sOW9Sdm1yoPRrzerC5iu1nsupp4e6I-HnJyYVHzvzQo';
32
38
  export const AO_AUTHORITY = 'fcoN_xJeisVsPXA-trzVAuIiqO3ydLQxM-L4XbrQKzY';
33
39
  export const DEFAULT_SCHEDULER_ID = '_GQ33BkPtZrqxA84vM8Zk-N2aO0toNNu_C-l-rawrBA';