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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/README.md +682 -600
  2. package/lib/esm/cli/cli.js +188 -152
  3. package/lib/esm/cli/commands/antCommands.js +23 -58
  4. package/lib/esm/cli/commands/arnsPurchaseCommands.js +48 -30
  5. package/lib/esm/cli/commands/escrowCommands.js +221 -0
  6. package/lib/esm/cli/commands/gatewayWriteCommands.js +142 -23
  7. package/lib/esm/cli/commands/pruneCommands.js +150 -0
  8. package/lib/esm/cli/commands/readCommands.js +22 -3
  9. package/lib/esm/cli/commands/transfer.js +6 -6
  10. package/lib/esm/cli/options.js +124 -58
  11. package/lib/esm/cli/utils.js +280 -174
  12. package/lib/esm/common/ant-registry.js +17 -143
  13. package/lib/esm/common/ant.js +44 -1167
  14. package/lib/esm/common/faucet.js +11 -6
  15. package/lib/esm/common/index.js +0 -4
  16. package/lib/esm/common/io.js +25 -1412
  17. package/lib/esm/constants.js +13 -19
  18. package/lib/esm/solana/ant-readable.js +724 -0
  19. package/lib/esm/solana/ant-registry-readable.js +133 -0
  20. package/lib/esm/solana/ant-registry-writeable.js +472 -0
  21. package/lib/esm/solana/ant-writeable.js +384 -0
  22. package/lib/esm/solana/ata.js +70 -0
  23. package/lib/esm/solana/canonical-message.js +128 -0
  24. package/lib/esm/solana/clusters.js +111 -0
  25. package/lib/esm/solana/constants.js +146 -0
  26. package/lib/esm/solana/delegation-math.js +112 -0
  27. package/lib/esm/solana/deserialize.js +711 -0
  28. package/lib/esm/solana/escrow.js +839 -0
  29. package/lib/{cjs/utils/json.js → esm/solana/events.js} +15 -10
  30. package/lib/esm/solana/funding-plan.js +699 -0
  31. package/lib/esm/solana/index.js +126 -0
  32. package/lib/esm/solana/instruction.js +39 -0
  33. package/lib/esm/solana/io-readable.js +2182 -0
  34. package/lib/esm/solana/io-writeable.js +3196 -0
  35. package/lib/esm/solana/json-rpc.js +90 -0
  36. package/lib/esm/solana/metadata.js +81 -0
  37. package/lib/esm/solana/mpl-core.js +192 -0
  38. package/lib/esm/solana/pda.js +332 -0
  39. package/lib/esm/solana/predict-prescribed-observers.js +110 -0
  40. package/lib/esm/solana/retry.js +117 -0
  41. package/lib/esm/solana/rpc-circuit-breaker.js +258 -0
  42. package/lib/esm/solana/send.js +372 -0
  43. package/lib/esm/solana/spawn-ant.js +224 -0
  44. package/lib/esm/solana/types.js +1 -0
  45. package/lib/esm/types/ant.js +27 -15
  46. package/lib/esm/types/io.js +8 -11
  47. package/lib/esm/utils/ant.js +0 -63
  48. package/lib/esm/utils/index.js +0 -3
  49. package/lib/esm/version.js +1 -1
  50. package/lib/types/cli/commands/antCommands.d.ts +5 -13
  51. package/lib/types/cli/commands/arnsPurchaseCommands.d.ts +33 -7
  52. package/lib/types/cli/commands/escrowCommands.d.ts +68 -0
  53. package/lib/types/cli/commands/gatewayWriteCommands.d.ts +12 -11
  54. package/lib/types/cli/commands/pruneCommands.d.ts +31 -0
  55. package/lib/types/cli/commands/readCommands.d.ts +27 -22
  56. package/lib/types/cli/commands/transfer.d.ts +9 -9
  57. package/lib/types/cli/options.d.ts +76 -21
  58. package/lib/types/cli/types.d.ts +11 -13
  59. package/lib/types/cli/utils.d.ts +71 -31
  60. package/lib/types/common/ant-registry.d.ts +49 -47
  61. package/lib/types/common/ant.d.ts +54 -539
  62. package/lib/types/common/faucet.d.ts +20 -8
  63. package/lib/types/common/index.d.ts +0 -3
  64. package/lib/types/common/io.d.ts +51 -263
  65. package/lib/types/constants.d.ts +11 -18
  66. package/lib/types/solana/ant-readable.d.ts +180 -0
  67. package/lib/types/solana/ant-registry-readable.d.ts +105 -0
  68. package/lib/types/solana/ant-registry-writeable.d.ts +249 -0
  69. package/lib/types/solana/ant-writeable.d.ts +177 -0
  70. package/lib/types/solana/ata.d.ts +44 -0
  71. package/lib/types/solana/canonical-message.d.ts +121 -0
  72. package/lib/types/solana/clusters.d.ts +109 -0
  73. package/lib/types/solana/constants.d.ts +119 -0
  74. package/lib/types/solana/delegation-math.d.ts +45 -0
  75. package/lib/types/solana/deserialize.d.ts +262 -0
  76. package/lib/types/solana/escrow.d.ts +480 -0
  77. package/lib/types/solana/events.d.ts +38 -0
  78. package/lib/types/solana/funding-plan.d.ts +225 -0
  79. package/lib/types/solana/index.d.ts +87 -0
  80. package/lib/types/solana/instruction.d.ts +39 -0
  81. package/lib/types/solana/io-readable.d.ts +499 -0
  82. package/lib/types/solana/io-writeable.d.ts +893 -0
  83. package/lib/types/solana/json-rpc.d.ts +47 -0
  84. package/lib/types/solana/metadata.d.ts +84 -0
  85. package/lib/types/solana/mpl-core.d.ts +120 -0
  86. package/lib/types/solana/pda.d.ts +95 -0
  87. package/lib/types/solana/predict-prescribed-observers.d.ts +28 -0
  88. package/lib/types/solana/retry.d.ts +62 -0
  89. package/lib/types/solana/rpc-circuit-breaker.d.ts +78 -0
  90. package/lib/types/solana/send.d.ts +94 -0
  91. package/lib/types/solana/spawn-ant.d.ts +145 -0
  92. package/lib/types/solana/types.d.ts +82 -0
  93. package/lib/types/types/ant-registry.d.ts +43 -4
  94. package/lib/types/types/ant.d.ts +114 -96
  95. package/lib/types/types/common.d.ts +18 -74
  96. package/lib/types/types/faucet.d.ts +2 -2
  97. package/lib/types/types/io.d.ts +244 -158
  98. package/lib/types/types/token.d.ts +0 -12
  99. package/lib/types/utils/ant.d.ts +1 -12
  100. package/lib/types/utils/index.d.ts +0 -3
  101. package/lib/types/version.d.ts +1 -1
  102. package/package.json +36 -33
  103. package/lib/cjs/cli/cli.js +0 -822
  104. package/lib/cjs/cli/commands/antCommands.js +0 -113
  105. package/lib/cjs/cli/commands/arnsPurchaseCommands.js +0 -212
  106. package/lib/cjs/cli/commands/gatewayWriteCommands.js +0 -210
  107. package/lib/cjs/cli/commands/readCommands.js +0 -215
  108. package/lib/cjs/cli/commands/transfer.js +0 -159
  109. package/lib/cjs/cli/options.js +0 -470
  110. package/lib/cjs/cli/types.js +0 -2
  111. package/lib/cjs/cli/utils.js +0 -639
  112. package/lib/cjs/common/ant-registry.js +0 -155
  113. package/lib/cjs/common/ant-versions.js +0 -93
  114. package/lib/cjs/common/ant.js +0 -1182
  115. package/lib/cjs/common/arweave.js +0 -27
  116. package/lib/cjs/common/contracts/ao-process.js +0 -224
  117. package/lib/cjs/common/error.js +0 -64
  118. package/lib/cjs/common/faucet.js +0 -150
  119. package/lib/cjs/common/hyperbeam/hb.js +0 -173
  120. package/lib/cjs/common/index.js +0 -42
  121. package/lib/cjs/common/io.js +0 -1423
  122. package/lib/cjs/common/logger.js +0 -83
  123. package/lib/cjs/common/loggers/winston.js +0 -68
  124. package/lib/cjs/common/marketplace.js +0 -731
  125. package/lib/cjs/common/turbo.js +0 -223
  126. package/lib/cjs/constants.js +0 -41
  127. package/lib/cjs/node/index.js +0 -39
  128. package/lib/cjs/package.json +0 -1
  129. package/lib/cjs/types/ant-registry.js +0 -2
  130. package/lib/cjs/types/ant.js +0 -168
  131. package/lib/cjs/types/common.js +0 -2
  132. package/lib/cjs/types/faucet.js +0 -2
  133. package/lib/cjs/types/index.js +0 -37
  134. package/lib/cjs/types/io.js +0 -51
  135. package/lib/cjs/types/token.js +0 -116
  136. package/lib/cjs/utils/ant.js +0 -108
  137. package/lib/cjs/utils/ao.js +0 -432
  138. package/lib/cjs/utils/arweave.js +0 -285
  139. package/lib/cjs/utils/base64.js +0 -62
  140. package/lib/cjs/utils/hash.js +0 -56
  141. package/lib/cjs/utils/index.js +0 -38
  142. package/lib/cjs/utils/processes.js +0 -173
  143. package/lib/cjs/utils/random.js +0 -30
  144. package/lib/cjs/utils/schema.js +0 -15
  145. package/lib/cjs/utils/url.js +0 -37
  146. package/lib/cjs/version.js +0 -20
  147. package/lib/cjs/web/index.js +0 -41
  148. package/lib/esm/common/ant-versions.js +0 -87
  149. package/lib/esm/common/arweave.js +0 -21
  150. package/lib/esm/common/contracts/ao-process.js +0 -220
  151. package/lib/esm/common/hyperbeam/hb.js +0 -169
  152. package/lib/esm/common/marketplace.js +0 -724
  153. package/lib/esm/common/turbo.js +0 -215
  154. package/lib/esm/node/index.js +0 -20
  155. package/lib/esm/utils/ao.js +0 -420
  156. package/lib/esm/utils/arweave.js +0 -271
  157. package/lib/esm/utils/processes.js +0 -167
  158. package/lib/esm/web/index.js +0 -20
  159. package/lib/types/common/ant-versions.d.ts +0 -39
  160. package/lib/types/common/arweave.d.ts +0 -17
  161. package/lib/types/common/contracts/ao-process.d.ts +0 -47
  162. package/lib/types/common/hyperbeam/hb.d.ts +0 -88
  163. package/lib/types/common/marketplace.d.ts +0 -568
  164. package/lib/types/common/turbo.d.ts +0 -61
  165. package/lib/types/node/index.d.ts +0 -20
  166. package/lib/types/utils/ao.d.ts +0 -80
  167. package/lib/types/utils/arweave.d.ts +0 -79
  168. package/lib/types/utils/processes.d.ts +0 -39
  169. package/lib/types/web/index.d.ts +0 -20
@@ -1,116 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.mARIOToken = exports.ARIOToken = void 0;
4
- /**
5
- * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
6
- *
7
- * Licensed under the Apache License, Version 2.0 (the "License");
8
- * you may not use this file except in compliance with the License.
9
- * You may obtain a copy of the License at
10
- *
11
- * http://www.apache.org/licenses/LICENSE-2.0
12
- *
13
- * Unless required by applicable law or agreed to in writing, software
14
- * distributed under the License is distributed on an "AS IS" BASIS,
15
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
- * See the License for the specific language governing permissions and
17
- * limitations under the License.
18
- */
19
- const constants_js_1 = require("../constants.js");
20
- class PositiveFiniteInteger {
21
- positiveFiniteInteger;
22
- constructor(positiveFiniteInteger) {
23
- this.positiveFiniteInteger = positiveFiniteInteger;
24
- if (!Number.isFinite(this.positiveFiniteInteger) ||
25
- !Number.isInteger(this.positiveFiniteInteger) ||
26
- this.positiveFiniteInteger < 0) {
27
- throw new Error(`Number must be a non-negative integer value! ${positiveFiniteInteger}`);
28
- }
29
- }
30
- [Symbol.toPrimitive](hint) {
31
- if (hint === 'string') {
32
- this.toString();
33
- }
34
- return this.positiveFiniteInteger;
35
- }
36
- plus(positiveFiniteInteger) {
37
- return new PositiveFiniteInteger(this.positiveFiniteInteger + positiveFiniteInteger.positiveFiniteInteger);
38
- }
39
- minus(positiveFiniteInteger) {
40
- return new PositiveFiniteInteger(this.positiveFiniteInteger - positiveFiniteInteger.positiveFiniteInteger);
41
- }
42
- isGreaterThan(positiveFiniteInteger) {
43
- return (this.positiveFiniteInteger > positiveFiniteInteger.positiveFiniteInteger);
44
- }
45
- isGreaterThanOrEqualTo(positiveFiniteInteger) {
46
- return (this.positiveFiniteInteger >= positiveFiniteInteger.positiveFiniteInteger);
47
- }
48
- isLessThan(positiveFiniteInteger) {
49
- return (this.positiveFiniteInteger < positiveFiniteInteger.positiveFiniteInteger);
50
- }
51
- isLessThanOrEqualTo(positiveFiniteInteger) {
52
- return (this.positiveFiniteInteger <= positiveFiniteInteger.positiveFiniteInteger);
53
- }
54
- toString() {
55
- return `${this.positiveFiniteInteger}`;
56
- }
57
- valueOf() {
58
- return this.positiveFiniteInteger;
59
- }
60
- toJSON() {
61
- return this.positiveFiniteInteger;
62
- }
63
- equals(other) {
64
- return this.positiveFiniteInteger === other.positiveFiniteInteger;
65
- }
66
- }
67
- class ARIOToken {
68
- value;
69
- constructor(value) {
70
- if (!Number.isFinite(value) || value < 0) {
71
- throw new Error('ARIOToken must be a non-negative finite number');
72
- }
73
- this.value = +value.toFixed(6);
74
- }
75
- valueOf() {
76
- return this.value;
77
- }
78
- toMARIO() {
79
- return new mARIOToken(Math.floor(this.value * constants_js_1.MARIO_PER_ARIO));
80
- }
81
- toString() {
82
- return `${this.value}`;
83
- }
84
- }
85
- exports.ARIOToken = ARIOToken;
86
- class mARIOToken extends PositiveFiniteInteger {
87
- constructor(value) {
88
- super(value);
89
- }
90
- multiply(multiplier) {
91
- // always round down on multiplication and division
92
- const result = Math.floor(this.valueOf() * multiplier.valueOf());
93
- return new mARIOToken(result);
94
- }
95
- divide(divisor) {
96
- if (divisor.valueOf() === 0) {
97
- // TODO: how should we handle this
98
- throw new Error('Cannot divide by zero');
99
- }
100
- // always round down on multiplication and division
101
- const result = Math.floor(this.valueOf() / divisor.valueOf());
102
- return new mARIOToken(result);
103
- }
104
- plus(addend) {
105
- const result = super.plus(addend);
106
- return new mARIOToken(result.valueOf());
107
- }
108
- minus(subtractHend) {
109
- const result = super.minus(subtractHend);
110
- return new mARIOToken(result.valueOf());
111
- }
112
- toARIO() {
113
- return new ARIOToken(this.valueOf() / constants_js_1.MARIO_PER_ARIO);
114
- }
115
- }
116
- exports.mARIOToken = mARIOToken;
@@ -1,108 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.convertHyperBeamStateToAoANTState = exports.isHyperBeamANTState = exports.sortANTRecords = void 0;
4
- /**
5
- * Sorts ANT records by priority and then lexicographically.
6
- *
7
- * Note: javascript guarantees that the order of objects in an object is persistent. Still, adding index to each record is useful for enforcing against undername limits.
8
- *
9
- * Reference: https://github.com/ar-io/ar-io-node/blob/e0a9ec56559cad1b3e35d668563871afb8649913/docs/madr/003-arns-undername-limits.md
10
- *
11
- * @param antRecords - The ANT records to sort.
12
- */
13
- const sortANTRecords = (antRecords) => {
14
- const sortedEntries = Object.entries(antRecords).sort(([a, aRecord], [b, bRecord]) => {
15
- // '@' is the root name and should be resolved first
16
- if (a === '@') {
17
- return -1;
18
- }
19
- if (b === '@') {
20
- return 1;
21
- }
22
- // if a record has a priority, it should be resolved before any other record without a priority
23
- if ('priority' in aRecord && !('priority' in bRecord)) {
24
- return -1;
25
- }
26
- if (!('priority' in aRecord) && 'priority' in bRecord) {
27
- return 1;
28
- }
29
- // if both records have a priority, sort by priority and fallback to lexicographic sorting
30
- if (aRecord.priority !== undefined && bRecord.priority !== undefined) {
31
- if (aRecord.priority === bRecord.priority) {
32
- // use deterministic comparison instead of localeCompare to avoid locale-specific sorting
33
- return a < b ? -1 : a > b ? 1 : 0;
34
- }
35
- return aRecord.priority - bRecord.priority;
36
- }
37
- // all other records are sorted lexicographically, using deterministic comparison instead of localeCompare to avoid locale-specific sorting
38
- return a < b ? -1 : a > b ? 1 : 0;
39
- });
40
- // 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
41
- return Object.fromEntries(sortedEntries.map(([a, aRecord], index) => [a, { ...aRecord, index }]));
42
- };
43
- exports.sortANTRecords = sortANTRecords;
44
- /**
45
- * @deprecated - this is no longer necessary because HyperBeam now uses the AoANTState type
46
- */
47
- const isHyperBeamANTState = (state) => {
48
- return ('name' in state &&
49
- 'ticker' in state &&
50
- 'description' in state &&
51
- 'keywords' in state &&
52
- 'denomination' in state &&
53
- 'owner' in state &&
54
- 'controllers' in state &&
55
- 'records' in state &&
56
- 'balances' in state &&
57
- 'logo' in state &&
58
- 'totalsupply' in state &&
59
- 'initialized' in state);
60
- };
61
- exports.isHyperBeamANTState = isHyperBeamANTState;
62
- /**
63
- * Convert HyperBeam serialized ANT state to backwards compatible format.
64
- *
65
- * @deprecated - this is no longer necessary because HyperBeam now uses the AOANTState type
66
- * @param state - The HyperBeam serialized ANT state.
67
- */
68
- const convertHyperBeamStateToAoANTState = (initialState) => {
69
- function lowerCaseKeys(obj) {
70
- return Object.fromEntries(Object.entries(obj).map(([key, value]) => {
71
- if (key.toLowerCase().includes('balances')) {
72
- return [key.toLowerCase(), value];
73
- }
74
- if (typeof value === 'object' &&
75
- !Array.isArray(value) &&
76
- value !== null) {
77
- return [key.toLowerCase(), lowerCaseKeys(value)];
78
- }
79
- return [key.toLowerCase(), value];
80
- }));
81
- }
82
- // we need to ensure keys are lower cased because hyperbeam json serializes keys to lowercase inconsistently
83
- const state = lowerCaseKeys(initialState);
84
- return {
85
- Name: state.name,
86
- Ticker: state.ticker,
87
- Description: state.description,
88
- Keywords: state.keywords,
89
- Denomination: parseInt(state.denomination),
90
- Owner: state.owner,
91
- Controllers: state.controllers,
92
- Records: Object.entries(state.records).reduce((acc, [key, record]) => {
93
- acc[key] = {
94
- transactionId: record.transactionid,
95
- ttlSeconds: record.ttlseconds,
96
- ...(record.priority !== undefined
97
- ? { priority: record.priority }
98
- : {}),
99
- };
100
- return acc;
101
- }, {}),
102
- Balances: state.balances,
103
- Logo: state.logo,
104
- TotalSupply: state.totalsupply || 1,
105
- Initialized: state.initialized,
106
- };
107
- };
108
- exports.convertHyperBeamStateToAoANTState = convertHyperBeamStateToAoANTState;
@@ -1,432 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defaultANTLogoId = exports.defaultTargetManifestId = void 0;
4
- exports.spawnANT = spawnANT;
5
- exports.forkANT = forkANT;
6
- exports.evolveANT = evolveANT;
7
- exports.isAoSigner = isAoSigner;
8
- exports.createAoSigner = createAoSigner;
9
- exports.initANTStateForAddress = initANTStateForAddress;
10
- exports.parseAoEpochData = parseAoEpochData;
11
- exports.errorMessageFromOutput = errorMessageFromOutput;
12
- exports.removeUnicodeFromError = removeUnicodeFromError;
13
- /**
14
- * Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
15
- *
16
- * Licensed under the Apache License, Version 2.0 (the "License");
17
- * you may not use this file except in compliance with the License.
18
- * You may obtain a copy of the License at
19
- *
20
- * http://www.apache.org/licenses/LICENSE-2.0
21
- *
22
- * Unless required by applicable law or agreed to in writing, software
23
- * distributed under the License is distributed on an "AS IS" BASIS,
24
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
25
- * See the License for the specific language governing permissions and
26
- * limitations under the License.
27
- */
28
- const arbundles_1 = require("@dha-team/arbundles");
29
- const aoconnect_1 = require("@permaweb/aoconnect");
30
- const zod_1 = require("zod");
31
- const ant_registry_js_1 = require("../common/ant-registry.js");
32
- const ant_versions_js_1 = require("../common/ant-versions.js");
33
- const arweave_js_1 = require("../common/arweave.js");
34
- const index_js_1 = require("../common/index.js");
35
- const constants_js_1 = require("../constants.js");
36
- const ant_js_1 = require("../types/ant.js");
37
- const schema_js_1 = require("./schema.js");
38
- async function spawnANT({ signer, module, ao = (0, aoconnect_1.connect)({
39
- MODE: 'legacy',
40
- }), scheduler = constants_js_1.DEFAULT_SCHEDULER_ID, state, tags = [], antRegistryId = constants_js_1.ANT_REGISTRY_ID, logger = index_js_1.Logger.default, authority = constants_js_1.AO_AUTHORITY, onSigningProgress = (name, payload) => {
41
- logger.debug('Signing progress', { name, payload });
42
- }, hyperbeamUrl, }) {
43
- if (state) {
44
- (0, schema_js_1.parseSchemaResult)(ant_js_1.SpawnANTStateSchema, state);
45
- }
46
- let version;
47
- if (module === undefined) {
48
- const antRegistry = ant_versions_js_1.ANTVersions.init({
49
- process: new index_js_1.AOProcess({
50
- processId: antRegistryId,
51
- ao,
52
- logger,
53
- }),
54
- });
55
- const { moduleId: latestAntModule, version: latestVersion } = await antRegistry.getLatestANTVersion();
56
- logger.debug('Spawning new ANT with latest module from ANT registry', {
57
- moduleId: latestAntModule,
58
- version: latestVersion,
59
- antRegistryId,
60
- });
61
- module = latestAntModule;
62
- version = latestVersion;
63
- }
64
- onSigningProgress?.('spawning-ant', {
65
- moduleId: module,
66
- antRegistryId,
67
- version,
68
- state,
69
- });
70
- const processId = await ao.spawn({
71
- module,
72
- scheduler,
73
- signer,
74
- data: state ? JSON.stringify(state) : undefined,
75
- tags: [
76
- // Required for AOS to initialize the authorities table
77
- {
78
- name: 'Authority',
79
- value: authority,
80
- },
81
- {
82
- name: 'ANT-Registry-Id',
83
- value: antRegistryId,
84
- },
85
- ...tags,
86
- ],
87
- });
88
- /**
89
- * Note: if we are given a state, ensure the ANT was initialized with it
90
- * there is a bug in the ANT source where we try to parse the empty default
91
- * 'Data' string as JSON that causes the Invalid-Boot-Notice error, even though
92
- * the ANT was initialized with the default state set by the ANT source code.
93
- *
94
- * Reference: https://github.com/ar-io/ar-io-ant-process/blob/b89018ffcce079add2e90e7ab82d0bbc9b671346/src/common/main.lua#L355-L358
95
- */
96
- if (state !== undefined) {
97
- let bootRes;
98
- let attempts = 0;
99
- while (attempts < 5 && bootRes === undefined) {
100
- try {
101
- // TODO: could add a progress event here to show the boot progress and number of attempts
102
- if (bootRes === undefined) {
103
- bootRes = await ao.result({
104
- process: processId,
105
- message: processId,
106
- });
107
- }
108
- break;
109
- }
110
- catch (error) {
111
- logger.debug('Retrying ANT boot result fetch', {
112
- processId,
113
- module,
114
- scheduler,
115
- attempts,
116
- error,
117
- });
118
- attempts++;
119
- await new Promise((resolve) => setTimeout(resolve, 1000 * attempts ** 2));
120
- }
121
- }
122
- if (bootRes === undefined ||
123
- bootRes.Messages?.some((m) => m?.Tags?.some((t) => t.value === 'Invalid-Boot-Notice'))) {
124
- if (bootRes === undefined) {
125
- throw new Error('Failed to get boot result');
126
- }
127
- const bootError = errorMessageFromOutput(bootRes);
128
- logger.error('ANT failed to boot correctly', {
129
- processId,
130
- module,
131
- scheduler,
132
- bootRes,
133
- bootError,
134
- });
135
- throw new Error(`ANT failed to boot correctly: ${bootError}`);
136
- }
137
- }
138
- onSigningProgress?.('verifying-state', {
139
- processId,
140
- moduleId: module,
141
- antRegistryId,
142
- });
143
- // Note: for hyperbeam caching, due to a SU issue, we need to send a second message to the ANT to cache the state
144
- // We wait for the first message to be processed before sending the second one to ensure this is the second message
145
- // We use the resulting state to check the owner of the ANT is set in the registry. Should this be patched on MUs,
146
- // we can convert to just a simple dry-run to avoid sending/signing another message.
147
- let owner;
148
- try {
149
- const processApi = new index_js_1.AOProcess({
150
- processId,
151
- ao,
152
- logger,
153
- });
154
- const { id } = await processApi.send({
155
- tags: [{ name: 'Action', value: 'State' }],
156
- signer,
157
- });
158
- const stateResult = await ao.result({
159
- process: processId,
160
- message: id,
161
- });
162
- if (stateResult === undefined) {
163
- throw new Error('Failed to get state result');
164
- }
165
- const { Owner } = JSON.parse(stateResult.Messages?.[0]?.Data ?? '{}');
166
- owner = Owner;
167
- logger.debug(`Successfully spawned new ANT and validated owner`, {
168
- processId,
169
- module,
170
- owner,
171
- });
172
- }
173
- catch (error) {
174
- logger.error('Failed to validate owner of spawned ANT', {
175
- processId,
176
- module,
177
- error,
178
- });
179
- throw error;
180
- }
181
- /**
182
- * Now confirm the owner of the ANT is set in the registry
183
- * This is to ensure the ANT is available via the ANT registry
184
- * for the owner to find and use the ANT.
185
- */
186
- if (owner === undefined) {
187
- throw new Error(`Spawning ANT (${processId}) failed to set owner`);
188
- }
189
- onSigningProgress?.('registering-ant', {
190
- processId,
191
- antRegistryId,
192
- owner,
193
- });
194
- // check the ACL for the owner
195
- const antRegistry = ant_registry_js_1.ANTRegistry.init({
196
- signer,
197
- process: new index_js_1.AOProcess({
198
- processId: antRegistryId,
199
- ao,
200
- logger,
201
- }),
202
- hyperbeamUrl,
203
- });
204
- let attempts = 0;
205
- const maxAttempts = 5;
206
- while (attempts < maxAttempts) {
207
- try {
208
- const acl = await antRegistry.accessControlList({ address: owner });
209
- if (acl === undefined) {
210
- throw new Error('ACL not found for owner');
211
- }
212
- const { Owned } = acl;
213
- if (!Owned.includes(processId)) {
214
- throw new Error(`Spawned ANT (${processId}) not found in registry for owner ${owner}`);
215
- }
216
- return processId;
217
- }
218
- catch (error) {
219
- logger.debug('Retrying ANT registry access control list fetch', {
220
- owner,
221
- antRegistryId,
222
- attempts,
223
- error,
224
- });
225
- attempts++;
226
- await new Promise((resolve) => setTimeout(resolve, 1000 * attempts ** 2));
227
- }
228
- }
229
- return processId;
230
- }
231
- async function forkANT({ signer, antProcessId, logger = index_js_1.Logger.default, ao, moduleId, antRegistryId = constants_js_1.ANT_REGISTRY_ID, onSigningProgress = (name, payload) => {
232
- logger.debug('Forking ANT', { name, payload });
233
- }, hyperbeamUrl, }) {
234
- // get the state of the current ANT and use it to spawn a new ANT
235
- const ant = index_js_1.ANT.init({
236
- process: new index_js_1.AOProcess({
237
- processId: antProcessId,
238
- ao,
239
- logger,
240
- }),
241
- hyperbeamUrl,
242
- });
243
- const state = await ant.getState();
244
- if (state === undefined) {
245
- throw new Error(`ANT state (${antProcessId}) is undefined and cannot be upgraded`);
246
- }
247
- const forkedProcessId = await spawnANT({
248
- signer,
249
- antRegistryId,
250
- ao,
251
- logger,
252
- module: moduleId,
253
- onSigningProgress,
254
- state: {
255
- owner: state.Owner,
256
- name: state.Name,
257
- ticker: state.Ticker,
258
- description: state.Description,
259
- keywords: state.Keywords,
260
- controllers: state.Controllers,
261
- records: state.Records,
262
- balances: state.Balances,
263
- logo: state.Logo,
264
- },
265
- hyperbeamUrl,
266
- });
267
- return forkedProcessId;
268
- }
269
- /**
270
- * @deprecated
271
- * Direct Evals are not encouraged when dealing with ANTs.
272
- * Instead, use spawnANT to fork an ANT to new module source code
273
- */
274
- async function evolveANT({ signer, processId, luaCodeTxId = constants_js_1.ANT_LUA_ID, ao = (0, aoconnect_1.connect)({
275
- MODE: 'legacy',
276
- }), logger = index_js_1.Logger.default, arweave = arweave_js_1.defaultArweave, }) {
277
- const aosClient = new index_js_1.AOProcess({
278
- processId,
279
- ao,
280
- logger,
281
- });
282
- logger.warn('Directly running an Eval on a process is not encouraged.');
283
- //TODO: cache locally and only fetch if not cached
284
- // We do not use arweave to get the data because it may throw on l2 tx data
285
- const { api: { host, port, protocol }, } = arweave.getConfig();
286
- const luaString = await fetch(`${protocol}://${host}:${port}/${luaCodeTxId}`).then((res) => res.text());
287
- const { id: evolveMsgId } = await aosClient.send({
288
- tags: [
289
- { name: 'Action', value: 'Eval' },
290
- { name: 'App-Name', value: 'ArNS-ANT' },
291
- { name: 'Source-Code-TX-ID', value: luaCodeTxId },
292
- ],
293
- data: luaString,
294
- signer,
295
- });
296
- logger.debug(`Evolved ANT`, {
297
- processId,
298
- luaCodeTxId,
299
- evalMsgId: evolveMsgId,
300
- });
301
- return evolveMsgId;
302
- }
303
- function isAoSigner(value) {
304
- const TagSchema = zod_1.z.object({
305
- name: zod_1.z.string(),
306
- value: zod_1.z.union([zod_1.z.string(), zod_1.z.number()]),
307
- });
308
- const AoSignerSchema = zod_1.z
309
- .function()
310
- .args(zod_1.z.object({
311
- data: zod_1.z.union([zod_1.z.string(), zod_1.z.instanceof(Buffer)]),
312
- tags: zod_1.z.array(TagSchema).optional(),
313
- target: zod_1.z.string().optional(),
314
- anchor: zod_1.z.string().optional(),
315
- }))
316
- .returns(zod_1.z.promise(zod_1.z.object({
317
- id: zod_1.z.string(),
318
- raw: zod_1.z.instanceof(ArrayBuffer),
319
- })));
320
- try {
321
- AoSignerSchema.parse(value);
322
- return true;
323
- }
324
- catch {
325
- return false;
326
- }
327
- }
328
- function createAoSigner(signer) {
329
- if (isAoSigner(signer)) {
330
- return signer;
331
- }
332
- if (!('publicKey' in signer)) {
333
- return (0, aoconnect_1.createDataItemSigner)(signer);
334
- }
335
- const aoSigner = async ({ data, tags, target, anchor }) => {
336
- // ensure appropriate permissions are granted with injected signers.
337
- if (signer.publicKey === undefined &&
338
- 'setPublicKey' in signer &&
339
- typeof signer.setPublicKey === 'function') {
340
- await signer.setPublicKey();
341
- }
342
- if (signer instanceof arbundles_1.ArconnectSigner) {
343
- // Sign using Arconnect signDataItem API
344
- const signedDataItem = await signer['signer'].signDataItem({
345
- data,
346
- tags,
347
- target,
348
- anchor,
349
- });
350
- const dataItem = new arbundles_1.DataItem(Buffer.from(signedDataItem));
351
- return {
352
- id: await dataItem.id,
353
- raw: await dataItem.getRaw(),
354
- };
355
- }
356
- const dataItem = (0, arbundles_1.createData)(data, signer, { tags, target, anchor });
357
- const signedData = dataItem.sign(signer).then(async () => ({
358
- id: await dataItem.id,
359
- raw: await dataItem.getRaw(),
360
- }));
361
- return signedData;
362
- };
363
- // eslint-disable-next-line
364
- // @ts-ignore Buffer vs ArrayBuffer type mismatch
365
- return aoSigner;
366
- }
367
- exports.defaultTargetManifestId = '-k7t8xMoB8hW482609Z9F4bTFMC3MnuW8bTvTyT8pFI';
368
- exports.defaultANTLogoId = 'Sie_26dvgyok0PZD_-iQAFOhOd5YxDTkczOLoqTTL_A';
369
- function initANTStateForAddress({ owner, targetId, ttlSeconds = 3600, keywords = [], controllers = [], description = '', ticker = 'aos', name = 'ANT', logo = exports.defaultANTLogoId, }) {
370
- return {
371
- ticker,
372
- name,
373
- description,
374
- keywords,
375
- owner,
376
- controllers: [owner, ...controllers],
377
- balances: { [owner]: 1 },
378
- records: {
379
- ['@']: {
380
- transactionId: targetId ?? exports.defaultTargetManifestId.toString(),
381
- ttlSeconds,
382
- },
383
- },
384
- logo,
385
- };
386
- }
387
- /**
388
- * Uses zod schema to parse the epoch data
389
- */
390
- function parseAoEpochData(value) {
391
- const epochDataSchema = zod_1.z.object({
392
- startTimestamp: zod_1.z.number(),
393
- startHeight: zod_1.z.number(),
394
- distributions: zod_1.z.any(), // TODO: add full distributed object type
395
- endTimestamp: zod_1.z.number(),
396
- prescribedObservers: zod_1.z.any(),
397
- prescribedNames: zod_1.z.array(zod_1.z.string()),
398
- observations: zod_1.z.any(),
399
- epochIndex: zod_1.z.number(),
400
- arnsStats: zod_1.z.any(),
401
- });
402
- return epochDataSchema.parse(value);
403
- }
404
- function errorMessageFromOutput(output) {
405
- const errorData = output.Error;
406
- // Attempt to extract error details from Messages.Tags if Error is undefined
407
- const error = errorData ??
408
- output.Messages?.[0]?.Tags?.find((tag) => tag.name === 'Error')?.value;
409
- if (error !== undefined) {
410
- const errorStackTrace = output.Messages?.[0]?.Data;
411
- const errorMessage = errorStackTrace ?? error;
412
- // Regex to match AO error messages like: [string ".src.main"]:5111: Primary name data not found
413
- // or [string "aos"]:128: some error
414
- const match = errorMessage?.match(/\[string "(.+)"\]:(\d+):\s*(.*)/);
415
- if (match) {
416
- // The first group is the src file, the second is the line number, and the third is the error message
417
- const [, , lineNumber, errorMessage] = match;
418
- const cleanError = removeUnicodeFromError(errorMessage);
419
- return `${cleanError.trim()} (line ${lineNumber.trim()})`.trim();
420
- }
421
- // With no match, just remove unicode
422
- return removeUnicodeFromError(error);
423
- }
424
- return undefined;
425
- }
426
- function removeUnicodeFromError(error) {
427
- //The regular expression /[\u001b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]/g is designed to match ANSI escape codes used for terminal formatting. These are sequences that begin with \u001b (ESC character) and are often followed by [ and control codes.
428
- const ESC = String.fromCharCode(27); // Represents '\u001b' or '\x1b'
429
- return error
430
- .replace(new RegExp(`${ESC}[\\[\\]()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]`, 'g'), '')
431
- .trim();
432
- }