@ar.io/sdk 2.0.0-alpha.1 → 2.0.0-alpha.11

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 (41) hide show
  1. package/README.md +253 -129
  2. package/bundles/web.bundle.min.js +131 -98
  3. package/lib/cjs/common/ant.js +294 -3
  4. package/lib/cjs/common/contracts/ao-process.js +1 -1
  5. package/lib/cjs/common/http.js +1 -2
  6. package/lib/cjs/common/index.js +0 -1
  7. package/lib/cjs/common/io.js +87 -39
  8. package/lib/cjs/common/logger.js +31 -19
  9. package/lib/cjs/utils/http-client.js +1 -1
  10. package/lib/cjs/utils/index.js +1 -1
  11. package/lib/cjs/utils/{graphql/processes.js → processes.js} +40 -10
  12. package/lib/cjs/version.js +1 -1
  13. package/lib/esm/common/ant.js +290 -1
  14. package/lib/esm/common/contracts/ao-process.js +2 -2
  15. package/lib/esm/common/http.js +2 -3
  16. package/lib/esm/common/index.js +0 -1
  17. package/lib/esm/common/io.js +87 -36
  18. package/lib/esm/common/logger.js +29 -14
  19. package/lib/esm/utils/http-client.js +2 -2
  20. package/lib/esm/utils/index.js +1 -1
  21. package/lib/esm/utils/{graphql/processes.js → processes.js} +38 -9
  22. package/lib/esm/version.js +1 -1
  23. package/lib/types/common/ant.d.ts +174 -23
  24. package/lib/types/common/contracts/ao-process.d.ts +2 -2
  25. package/lib/types/common/http.d.ts +3 -2
  26. package/lib/types/common/index.d.ts +0 -1
  27. package/lib/types/common/io.d.ts +5 -4
  28. package/lib/types/common/logger.d.ts +10 -3
  29. package/lib/types/common.d.ts +0 -7
  30. package/lib/types/io.d.ts +28 -3
  31. package/lib/types/utils/http-client.d.ts +2 -2
  32. package/lib/types/utils/index.d.ts +1 -1
  33. package/lib/types/utils/{graphql/processes.d.ts → processes.d.ts} +6 -1
  34. package/lib/types/version.d.ts +1 -1
  35. package/package.json +6 -6
  36. package/lib/cjs/common/ant-ao.js +0 -297
  37. package/lib/cjs/utils/graphql/index.js +0 -33
  38. package/lib/esm/common/ant-ao.js +0 -292
  39. package/lib/esm/utils/graphql/index.js +0 -17
  40. package/lib/types/common/ant-ao.d.ts +0 -194
  41. package/lib/types/utils/graphql/index.d.ts +0 -17
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ArNSEventEmitter = exports.getANTProcessesOwnedByWallet = void 0;
3
+ exports.fetchAllArNSRecords = exports.ArNSEventEmitter = exports.getANTProcessesOwnedByWallet = void 0;
4
4
  /**
5
5
  * Copyright (C) 2022-2024 Permanent Data Solutions, Inc. All Rights Reserved.
6
6
  *
@@ -19,19 +19,20 @@ exports.ArNSEventEmitter = exports.getANTProcessesOwnedByWallet = void 0;
19
19
  */
20
20
  const eventemitter3_1 = require("eventemitter3");
21
21
  const plimit_lit_1 = require("plimit-lit");
22
- const ant_js_1 = require("../../common/ant.js");
23
- const io_js_1 = require("../../common/io.js");
24
- const constants_js_1 = require("../../constants.js");
22
+ const ant_js_1 = require("../common/ant.js");
23
+ const io_js_1 = require("../common/io.js");
24
+ const constants_js_1 = require("../constants.js");
25
25
  const getANTProcessesOwnedByWallet = async ({ address, contract = io_js_1.IO.init({
26
26
  processId: constants_js_1.IO_TESTNET_PROCESS_ID,
27
27
  }), }) => {
28
28
  const throttle = (0, plimit_lit_1.pLimit)(50);
29
29
  // get the record names of the registry - TODO: this may need to be paginated
30
- const uniqueContractProcessIds = await contract
31
- .getArNSRecords()
32
- .then((records) => Object.values(records)
30
+ const records = await (0, exports.fetchAllArNSRecords)({
31
+ contract: contract,
32
+ });
33
+ const uniqueContractProcessIds = Object.values(records)
33
34
  .filter((record) => record.processId !== undefined)
34
- .map((record) => record.processId));
35
+ .map((record) => record.processId);
35
36
  // check the contract owner and controllers
36
37
  const ownedOrControlledByWallet = await Promise.all(uniqueContractProcessIds.map(async (processId) => throttle(async () => {
37
38
  const ant = ant_js_1.ANT.init({
@@ -80,10 +81,12 @@ class ArNSEventEmitter extends eventemitter3_1.EventEmitter {
80
81
  }
81
82
  async fetchProcessesOwnedByWallet({ address }) {
82
83
  const uniqueContractProcessIds = {};
83
- await timeout(this.timeoutMs, this.contract.getArNSRecords().catch((e) => {
84
+ await timeout(this.timeoutMs, (0, exports.fetchAllArNSRecords)({ contract: this.contract }))
85
+ .catch((e) => {
84
86
  this.emit('error', `Error getting ArNS records: ${e}`);
85
87
  return {};
86
- })).then((records) => {
88
+ })
89
+ .then((records) => {
87
90
  if (!records)
88
91
  return;
89
92
  Object.entries(records).forEach(([name, record]) => {
@@ -125,3 +128,30 @@ class ArNSEventEmitter extends eventemitter3_1.EventEmitter {
125
128
  }
126
129
  }
127
130
  exports.ArNSEventEmitter = ArNSEventEmitter;
131
+ const fetchAllArNSRecords = async ({ contract = io_js_1.IO.init({
132
+ processId: constants_js_1.IO_TESTNET_PROCESS_ID,
133
+ }), logger, }) => {
134
+ let cursor;
135
+ const records = {};
136
+ do {
137
+ const pageResult = await contract
138
+ .getArNSRecords({ cursor })
139
+ .catch((e) => {
140
+ logger?.error(`Error getting ArNS records`, {
141
+ message: e?.message,
142
+ stack: e?.stack,
143
+ });
144
+ return undefined;
145
+ });
146
+ if (!pageResult) {
147
+ return {};
148
+ }
149
+ pageResult.items.forEach((record) => {
150
+ const { name, ...recordDetails } = record;
151
+ records[name] = recordDetails;
152
+ });
153
+ cursor = pageResult.nextCursor;
154
+ } while (cursor !== undefined);
155
+ return records;
156
+ };
157
+ exports.fetchAllArNSRecords = fetchAllArNSRecords;
@@ -18,4 +18,4 @@
18
18
  Object.defineProperty(exports, "__esModule", { value: true });
19
19
  exports.version = void 0;
20
20
  // AUTOMATICALLY GENERATED FILE - DO NOT TOUCH
21
- exports.version = '2.0.0-alpha.1';
21
+ exports.version = '2.0.0-alpha.11';
@@ -15,7 +15,7 @@
15
15
  * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
16
  */
17
17
  import { isProcessConfiguration, isProcessIdConfiguration, } from '../types.js';
18
- import { AoANTReadable, AoANTWriteable, InvalidContractConfigurationError, } from './index.js';
18
+ import { AOProcess, InvalidContractConfigurationError } from './index.js';
19
19
  export class ANT {
20
20
  static init({ signer, ...config }) {
21
21
  // ao supported implementation
@@ -28,3 +28,292 @@ export class ANT {
28
28
  throw new InvalidContractConfigurationError();
29
29
  }
30
30
  }
31
+ export class AoANTReadable {
32
+ process;
33
+ constructor(config) {
34
+ if (isProcessConfiguration(config)) {
35
+ this.process = config.process;
36
+ }
37
+ else if (isProcessIdConfiguration(config)) {
38
+ this.process = new AOProcess({
39
+ processId: config.processId,
40
+ });
41
+ }
42
+ else {
43
+ throw new InvalidContractConfigurationError();
44
+ }
45
+ }
46
+ async getState() {
47
+ const tags = [{ name: 'Action', value: 'State' }];
48
+ const res = await this.process.read({
49
+ tags,
50
+ });
51
+ return res;
52
+ }
53
+ async getInfo() {
54
+ const tags = [{ name: 'Action', value: 'Info' }];
55
+ const info = await this.process.read({
56
+ tags,
57
+ });
58
+ return info;
59
+ }
60
+ /**
61
+ * @param undername @type {string} The domain name.
62
+ * @returns {Promise<ANTRecord>} The record of the undername domain.
63
+ * @example
64
+ * Get the current record
65
+ * ```ts
66
+ * ant.getRecord({ undername: "john" });
67
+ * ```
68
+ */
69
+ async getRecord({ undername }) {
70
+ const tags = [
71
+ { name: 'Sub-Domain', value: undername },
72
+ { name: 'Action', value: 'Record' },
73
+ ];
74
+ const record = await this.process.read({
75
+ tags,
76
+ });
77
+ return record;
78
+ }
79
+ /**
80
+ * @returns {Promise<Record<string, ANTRecord>>} All the undernames managed by the ANT.
81
+ * @example
82
+ * Get the current records
83
+ * ```ts
84
+ * ant.getRecords();
85
+ * ````
86
+ */
87
+ async getRecords() {
88
+ const tags = [{ name: 'Action', value: 'Records' }];
89
+ const records = await this.process.read({
90
+ tags,
91
+ });
92
+ return records;
93
+ }
94
+ /**
95
+ * @returns {Promise<string>} The owner of the ANT.
96
+ * @example
97
+ * Get the current owner
98
+ * ```ts
99
+ * ant.getOwner();
100
+ * ```
101
+ */
102
+ async getOwner() {
103
+ const info = await this.getInfo();
104
+ return info.Owner;
105
+ }
106
+ /**
107
+ * @returns {Promise<string[]>} The controllers of the ANT.
108
+ * @example
109
+ * Get the controllers of the ANT.
110
+ * ```ts
111
+ * ant.getControllers();
112
+ * ```
113
+ */
114
+ async getControllers() {
115
+ const tags = [{ name: 'Action', value: 'Controllers' }];
116
+ const controllers = await this.process.read({
117
+ tags,
118
+ });
119
+ return controllers;
120
+ }
121
+ /**
122
+ * @returns {Promise<string>} The name of the ANT (not the same as ArNS name).
123
+ * @example
124
+ * Get the current name
125
+ * ```ts
126
+ * ant.getName();
127
+ * ```
128
+ */
129
+ async getName() {
130
+ const info = await this.getInfo();
131
+ return info.Name;
132
+ }
133
+ /**
134
+ * @returns {Promise<string>} The name of the ANT (not the same as ArNS name).
135
+ * @example
136
+ * The current ticker of the ANT.
137
+ * ```ts
138
+ * ant.getTicker();
139
+ * ```
140
+ */
141
+ async getTicker() {
142
+ const info = await this.getInfo();
143
+ return info.Ticker;
144
+ }
145
+ /**
146
+ * @returns {Promise<Record<WalletAddress, number>>} The balances of the ANT
147
+ * @example
148
+ * The current balances of the ANT.
149
+ * ```ts
150
+ * ant.getBalances();
151
+ * ```
152
+ */
153
+ async getBalances() {
154
+ const tags = [{ name: 'Action', value: 'Balances' }];
155
+ const balances = await this.process.read({
156
+ tags,
157
+ });
158
+ return balances;
159
+ }
160
+ /**
161
+ * @param address @type {string} The address of the account you want the balance of.
162
+ * @returns {Promise<number>} The balance of the provided address
163
+ * @example
164
+ * The current balance of the address.
165
+ * ```ts
166
+ * ant.getBalance({ address });
167
+ * ```
168
+ */
169
+ async getBalance({ address }) {
170
+ const tags = [
171
+ { name: 'Action', value: 'Balance' },
172
+ { name: 'Recipient', value: address },
173
+ ];
174
+ const balance = await this.process.read({
175
+ tags,
176
+ });
177
+ return balance;
178
+ }
179
+ }
180
+ export class AoANTWriteable extends AoANTReadable {
181
+ signer;
182
+ constructor({ signer, ...config }) {
183
+ super(config);
184
+ this.signer = signer;
185
+ }
186
+ /**
187
+ * @param target @type {string} The address of the account you want to transfer the ANT to.
188
+ * @returns {Promise<AoMessageResult>} The result of the interaction.
189
+ * @example
190
+ * ```ts
191
+ * ant.transfer({ target: "fGht8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk" });
192
+ * ```
193
+ */
194
+ async transfer({ target }) {
195
+ const tags = [
196
+ { name: 'Action', value: 'Transfer' },
197
+ { name: 'Recipient', value: target },
198
+ ];
199
+ return this.process.send({
200
+ tags,
201
+ data: {},
202
+ signer: this.signer,
203
+ });
204
+ }
205
+ /**
206
+ * @param controller @type {string} The address of the account you want to set as a controller.
207
+ * @returns {Promise<AoMessageResult>} The result of the interaction.
208
+ * @example
209
+ * ```ts
210
+ * ant.setController({ controller: "fGht8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk" });
211
+ * ```
212
+ */
213
+ async addController({ controller, }) {
214
+ const tags = [
215
+ { name: 'Action', value: 'Add-Controller' },
216
+ { name: 'Controller', value: controller },
217
+ ];
218
+ return this.process.send({
219
+ tags,
220
+ data: {},
221
+ signer: this.signer,
222
+ });
223
+ }
224
+ /**
225
+ * @param controller @type {string} The address of the account you want to remove from the controllers list
226
+ * @returns {Promise<AoMessageResult>} The result of the interaction.
227
+ * @example
228
+ * ```ts
229
+ * ant.removeController({ controller: "fGht8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk" });
230
+ * ```
231
+ */
232
+ async removeController({ controller, }) {
233
+ const tags = [
234
+ { name: 'Action', value: 'Remove-Controller' },
235
+ { name: 'Controller', value: controller },
236
+ ];
237
+ return this.process.send({
238
+ tags,
239
+ data: {},
240
+ signer: this.signer,
241
+ });
242
+ }
243
+ /**
244
+ * @param undername @type {string} The record you want to set the transactionId and ttlSeconds of.
245
+ * @param transactionId @type {string} The transactionId of the record.
246
+ * @param ttlSeconds @type {number} The time to live of the record.
247
+ * @returns {Promise<AoMessageResult>} The result of the interaction.
248
+ * @example
249
+ * ```ts
250
+ * ant.setController({ controller: "fGht8v4STuwPnTck1zFVkQqJh5K9q9Zik4Y5-5dV7nk" });
251
+ * ```
252
+ */
253
+ async setRecord({ undername, transactionId, ttlSeconds, }) {
254
+ return this.process.send({
255
+ tags: [
256
+ { name: 'Action', value: 'Set-Record' },
257
+ { name: 'Sub-Domain', value: undername },
258
+ { name: 'Transaction-Id', value: transactionId },
259
+ { name: 'TTL-Seconds', value: ttlSeconds.toString() },
260
+ ],
261
+ data: { transactionId, ttlSeconds },
262
+ signer: this.signer,
263
+ });
264
+ }
265
+ /**
266
+ * @param undername @type {string} The record you want to remove.
267
+ * @returns {Promise<AoMessageResult>} The result of the interaction.
268
+ * @example
269
+ * ```ts
270
+ * ant.removeRecord({ subDomain: "shorts" });
271
+ * ```
272
+ */
273
+ async removeRecord({ undername, }) {
274
+ return this.process.send({
275
+ tags: [
276
+ { name: 'Action', value: 'Remove-Record' },
277
+ { name: 'Sub-Domain', value: undername },
278
+ ],
279
+ data: { undername },
280
+ signer: this.signer,
281
+ });
282
+ }
283
+ /**
284
+ * @param ticker @type {string} Sets the ANT Ticker.
285
+ * @returns {Promise<AoMessageResult>} The result of the interaction.
286
+ * @example
287
+ * ```ts
288
+ * ant.setTicker({ ticker: "KAPOW" });
289
+ * ```
290
+ */
291
+ async setTicker({ ticker }) {
292
+ return this.process.send({
293
+ tags: [
294
+ { name: 'Action', value: 'Set-Ticker' },
295
+ { name: 'Ticker', value: ticker },
296
+ ],
297
+ data: { ticker },
298
+ signer: this.signer,
299
+ });
300
+ }
301
+ /**
302
+ * @param name @type {string} Sets the Name of the ANT.
303
+ * @returns {Promise<AoMessageResult>} The result of the interaction.
304
+ * @example
305
+ * ```ts
306
+ * ant.setName({ name: "ships at sea" });
307
+ * ```
308
+ */
309
+ async setName({ name }) {
310
+ return this.process.send({
311
+ tags: [
312
+ { name: 'Action', value: 'Set-Name' },
313
+ { name: 'Name', value: name },
314
+ ],
315
+ data: { name },
316
+ signer: this.signer,
317
+ });
318
+ }
319
+ }
@@ -19,12 +19,12 @@ import { createData } from 'arbundles';
19
19
  import { safeDecode } from '../../utils/json.js';
20
20
  import { version } from '../../version.js';
21
21
  import { WriteInteractionError } from '../error.js';
22
- import { DefaultLogger } from '../logger.js';
22
+ import { Logger } from '../logger.js';
23
23
  export class AOProcess {
24
24
  logger;
25
25
  processId;
26
26
  ao;
27
- constructor({ processId, ao = connect(), logger = new DefaultLogger({ level: 'info' }), }) {
27
+ constructor({ processId, ao = connect(), logger = Logger.default, }) {
28
28
  this.processId = processId;
29
29
  this.logger = logger;
30
30
  this.ao = ao;
@@ -1,11 +1,10 @@
1
1
  import { createAxiosInstance } from '../utils/index.js';
2
2
  import { FailedRequestError, NotFound, UnknownError } from './error.js';
3
- import { DefaultLogger } from './logger.js';
3
+ import { Logger } from './logger.js';
4
4
  export class AxiosHTTPService {
5
5
  axios;
6
6
  logger;
7
- // TODO: re-implement axios-retry. Currently that package is broken for nodenext.
8
- constructor({ url, logger = new DefaultLogger(), }) {
7
+ constructor({ url, logger = Logger.default, }) {
9
8
  this.logger = logger;
10
9
  this.axios = createAxiosInstance({
11
10
  axiosConfig: {
@@ -19,5 +19,4 @@ export * from './logger.js';
19
19
  export * from './ant.js';
20
20
  // ao
21
21
  export * from './io.js';
22
- export * from './ant-ao.js';
23
22
  export * from './contracts/ao-process.js';
@@ -1,25 +1,8 @@
1
- /**
2
- * Copyright (C) 2022-2024 Permanent Data Solutions, Inc. All Rights Reserved.
3
- *
4
- * This program is free software: you can redistribute it and/or modify
5
- * it under the terms of the GNU Affero General Public License as published by
6
- * the Free Software Foundation, either version 3 of the License, or
7
- * (at your option) any later version.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU Affero General Public License for more details.
13
- *
14
- * You should have received a copy of the GNU Affero General Public License
15
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
16
- */
17
- import Arweave from 'arweave';
18
1
  import { IO_TESTNET_PROCESS_ID } from '../constants.js';
19
2
  import { isProcessConfiguration, isProcessIdConfiguration, } from '../io.js';
3
+ import { defaultArweave } from './arweave.js';
20
4
  import { AOProcess } from './contracts/ao-process.js';
21
5
  import { InvalidContractConfigurationError } from './error.js';
22
- import { DefaultLogger } from './logger.js';
23
6
  export class IO {
24
7
  static init(config) {
25
8
  if (config && config.signer) {
@@ -35,7 +18,7 @@ export class IO {
35
18
  export class IOReadable {
36
19
  process;
37
20
  arweave;
38
- constructor(config, arweave = new Arweave({})) {
21
+ constructor(config, arweave = defaultArweave) {
39
22
  if (!config) {
40
23
  this.process = new AOProcess({
41
24
  processId: IO_TESTNET_PROCESS_ID,
@@ -47,9 +30,6 @@ export class IOReadable {
47
30
  else if (isProcessIdConfiguration(config)) {
48
31
  this.process = new AOProcess({
49
32
  processId: config.processId,
50
- logger: new DefaultLogger({
51
- level: 'info',
52
- }),
53
33
  });
54
34
  }
55
35
  else {
@@ -68,7 +48,12 @@ export class IOReadable {
68
48
  {
69
49
  name: 'Timestamp',
70
50
  value: params?.timestamp?.toString() ??
71
- (await this.arweave.blocks.getCurrent().catch(() => {
51
+ (await this.arweave.blocks
52
+ .getCurrent()
53
+ .then((block) => {
54
+ return { timestamp: block.timestamp * 1000 };
55
+ })
56
+ .catch(() => {
72
57
  return { timestamp: Date.now() }; // fallback to current time
73
58
  })).timestamp.toString(),
74
59
  },
@@ -88,7 +73,12 @@ export class IOReadable {
88
73
  {
89
74
  name: 'Timestamp',
90
75
  value: epoch?.timestamp?.toString() ??
91
- (await this.arweave.blocks.getCurrent().catch(() => {
76
+ (await this.arweave.blocks
77
+ .getCurrent()
78
+ .then((block) => {
79
+ return { timestamp: block.timestamp * 1000 };
80
+ })
81
+ .catch(() => {
92
82
  return { timestamp: Date.now() }; // fallback to current time
93
83
  })).timestamp.toString(),
94
84
  },
@@ -110,9 +100,17 @@ export class IOReadable {
110
100
  ],
111
101
  });
112
102
  }
113
- async getArNSRecords() {
103
+ async getArNSRecords(pageParams) {
104
+ const allTags = [
105
+ { name: 'Action', value: 'Paginated-Records' },
106
+ { name: 'Cursor', value: pageParams?.cursor?.toString() },
107
+ { name: 'Limit', value: pageParams?.limit?.toString() },
108
+ { name: 'Sort-By', value: pageParams?.sortBy },
109
+ { name: 'Sort-Order', value: pageParams?.sortOrder },
110
+ ];
111
+ const prunedTags = allTags.filter((tag) => tag.value !== undefined);
114
112
  return this.process.read({
115
- tags: [{ name: 'Action', value: 'Records' }],
113
+ tags: prunedTags,
116
114
  });
117
115
  }
118
116
  async getArNSReservedNames() {
@@ -136,9 +134,17 @@ export class IOReadable {
136
134
  ],
137
135
  });
138
136
  }
139
- async getBalances() {
137
+ async getBalances(pageParams) {
138
+ const allTags = [
139
+ { name: 'Action', value: 'Paginated-Balances' },
140
+ { name: 'Cursor', value: pageParams?.cursor?.toString() },
141
+ { name: 'Limit', value: pageParams?.limit?.toString() },
142
+ { name: 'Sort-By', value: pageParams?.sortBy },
143
+ { name: 'Sort-Order', value: pageParams?.sortOrder },
144
+ ];
145
+ const prunedTags = allTags.filter((tag) => tag.value !== undefined);
140
146
  return this.process.read({
141
- tags: [{ name: 'Action', value: 'Balances' }],
147
+ tags: prunedTags,
142
148
  });
143
149
  }
144
150
  async getGateway({ address, }) {
@@ -149,9 +155,17 @@ export class IOReadable {
149
155
  ],
150
156
  });
151
157
  }
152
- async getGateways() {
158
+ async getGateways(pageParams) {
159
+ const allTags = [
160
+ { name: 'Action', value: 'Paginated-Gateways' },
161
+ { name: 'Cursor', value: pageParams?.cursor?.toString() },
162
+ { name: 'Limit', value: pageParams?.limit?.toString() },
163
+ { name: 'Sort-By', value: pageParams?.sortBy },
164
+ { name: 'Sort-Order', value: pageParams?.sortOrder },
165
+ ];
166
+ const prunedTags = allTags.filter((tag) => tag.value !== undefined);
153
167
  return this.process.read({
154
- tags: [{ name: 'Action', value: 'Gateways' }],
168
+ tags: prunedTags,
155
169
  });
156
170
  }
157
171
  async getCurrentEpoch() {
@@ -160,7 +174,12 @@ export class IOReadable {
160
174
  { name: 'Action', value: 'Epoch' },
161
175
  {
162
176
  name: 'Timestamp',
163
- value: (await this.arweave.blocks.getCurrent().catch(() => {
177
+ value: (await this.arweave.blocks
178
+ .getCurrent()
179
+ .then((block) => {
180
+ return { timestamp: block.timestamp * 1000 };
181
+ })
182
+ .catch(() => {
164
183
  return { timestamp: Date.now() }; // fallback to current time
165
184
  })).timestamp.toString(),
166
185
  },
@@ -173,7 +192,12 @@ export class IOReadable {
173
192
  {
174
193
  name: 'Timestamp',
175
194
  value: epoch?.timestamp?.toString() ??
176
- (await this.arweave.blocks.getCurrent().catch(() => {
195
+ (await this.arweave.blocks
196
+ .getCurrent()
197
+ .then((block) => {
198
+ return { timestamp: block.timestamp * 1000 };
199
+ })
200
+ .catch(() => {
177
201
  return { timestamp: Date.now() }; // fallback to current time
178
202
  })).timestamp.toString(),
179
203
  },
@@ -193,7 +217,12 @@ export class IOReadable {
193
217
  {
194
218
  name: 'Timestamp',
195
219
  value: epoch?.timestamp?.toString() ??
196
- (await this.arweave.blocks.getCurrent().catch(() => {
220
+ (await this.arweave.blocks
221
+ .getCurrent()
222
+ .then((block) => {
223
+ return { timestamp: block.timestamp * 1000 };
224
+ })
225
+ .catch(() => {
197
226
  return { timestamp: Date.now() }; // fallback to current time
198
227
  })).timestamp.toString(),
199
228
  },
@@ -213,7 +242,12 @@ export class IOReadable {
213
242
  {
214
243
  name: 'Timestamp',
215
244
  value: epoch?.timestamp?.toString() ??
216
- (await this.arweave.blocks.getCurrent().catch(() => {
245
+ (await this.arweave.blocks
246
+ .getCurrent()
247
+ .then((block) => {
248
+ return { timestamp: block.timestamp * 1000 };
249
+ })
250
+ .catch(() => {
217
251
  return { timestamp: `${Date.now()}` }; // fallback to current time
218
252
  })).timestamp.toString(),
219
253
  },
@@ -233,7 +267,12 @@ export class IOReadable {
233
267
  {
234
268
  name: 'Timestamp',
235
269
  value: epoch?.timestamp?.toString() ??
236
- (await this.arweave.blocks.getCurrent().catch(() => {
270
+ (await this.arweave.blocks
271
+ .getCurrent()
272
+ .then((block) => {
273
+ return { timestamp: block.timestamp * 1000 };
274
+ })
275
+ .catch(() => {
237
276
  return { timestamp: Date.now() }; // fallback to current time
238
277
  })).timestamp.toString(),
239
278
  },
@@ -272,7 +311,12 @@ export class IOReadable {
272
311
  },
273
312
  {
274
313
  name: 'Timestamp',
275
- value: (await this.arweave.blocks.getCurrent().catch(() => {
314
+ value: (await this.arweave.blocks
315
+ .getCurrent()
316
+ .then((block) => {
317
+ return { timestamp: block.timestamp * 1000 };
318
+ })
319
+ .catch(() => {
276
320
  return { timestamp: Date.now() }; // fallback to current time
277
321
  })).timestamp.toString(),
278
322
  },
@@ -388,6 +432,13 @@ export class IOWriteable extends IOReadable {
388
432
  tags: prunedTags,
389
433
  });
390
434
  }
435
+ async leaveNetwork(options) {
436
+ const { tags = [] } = options || {};
437
+ return this.process.send({
438
+ signer: this.signer,
439
+ tags: [...tags, { name: 'Action', value: 'Leave-Network' }],
440
+ });
441
+ }
391
442
  async updateGatewaySettings({ allowDelegatedStaking, delegateRewardShareRatio, fqdn, label, minDelegatedStake, note, port, properties, protocol, autoStake, observerAddress, }, options) {
392
443
  const { tags = [] } = options || {};
393
444
  const allTags = [