@twin.org/dlt-iota 0.9.1-next.1 → 0.9.1-next.2
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.
- package/dist/es/iota.js +189 -31
- package/dist/es/iota.js.map +1 -1
- package/dist/es/models/IIotaConfig.js.map +1 -1
- package/dist/types/iota.d.ts +42 -0
- package/dist/types/models/IIotaConfig.d.ts +12 -0
- package/docs/changelog.md +12 -0
- package/docs/reference/classes/Iota.md +117 -0
- package/docs/reference/interfaces/IIotaConfig.md +30 -0
- package/locales/en.json +1 -0
- package/package.json +1 -1
package/dist/es/iota.js
CHANGED
|
@@ -54,6 +54,27 @@ export class Iota {
|
|
|
54
54
|
* @internal
|
|
55
55
|
*/
|
|
56
56
|
static _DEFAULT_GAS_RESERVATION_DURATION = 60;
|
|
57
|
+
/**
|
|
58
|
+
* Default number of retries when owned objects are reserved by another transaction.
|
|
59
|
+
* @internal
|
|
60
|
+
*/
|
|
61
|
+
static _DEFAULT_OBJECT_LOCK_RETRIES = 3;
|
|
62
|
+
/**
|
|
63
|
+
* Default base delay in milliseconds between object-lock retries.
|
|
64
|
+
* @internal
|
|
65
|
+
*/
|
|
66
|
+
static _DEFAULT_OBJECT_LOCK_RETRY_DELAY_MS = 1000;
|
|
67
|
+
/**
|
|
68
|
+
* Pattern that identifies the retryable "objects reserved by another transaction" node error.
|
|
69
|
+
* @internal
|
|
70
|
+
*/
|
|
71
|
+
static _RESERVED_OBJECT_ERROR_PATTERN = /reserved for another transaction/;
|
|
72
|
+
/**
|
|
73
|
+
* Pattern that identifies the node error for an owned-object version that was consumed by a
|
|
74
|
+
* concurrent transaction. Retryable since the retry rebuild re-resolves to the current version.
|
|
75
|
+
* @internal
|
|
76
|
+
*/
|
|
77
|
+
static _STALE_OBJECT_ERROR_PATTERN = /is not available for consumption/;
|
|
57
78
|
/**
|
|
58
79
|
* Create a new IOTA client.
|
|
59
80
|
* @param config The configuration.
|
|
@@ -211,6 +232,10 @@ export class Iota {
|
|
|
211
232
|
return result;
|
|
212
233
|
}
|
|
213
234
|
catch (error) {
|
|
235
|
+
// Pass through the clear object-conflict error; wrap everything else as before.
|
|
236
|
+
if (Iota.isRetryableObjectConflictError(error)) {
|
|
237
|
+
throw error;
|
|
238
|
+
}
|
|
214
239
|
throw new GeneralError(Iota.CLASS_NAME, "valueTransactionFailed", undefined, Iota.extractPayloadError(error));
|
|
215
240
|
}
|
|
216
241
|
}
|
|
@@ -232,6 +257,12 @@ export class Iota {
|
|
|
232
257
|
return Iota.prepareAndPostGasStationTransaction(config, vaultConnector, identity, client, owner, transaction, options);
|
|
233
258
|
}
|
|
234
259
|
// Traditional transaction flow
|
|
260
|
+
// Capture the transaction while its inputs are still unresolved. The SDK pins owned-object
|
|
261
|
+
// versions and gas payment on the first build, so a single built transaction would resubmit
|
|
262
|
+
// byte-identical bytes on every retry. Cloning this template per attempt lets object
|
|
263
|
+
// versions and gas re-resolve, which is what allows a retry to actually recover once the
|
|
264
|
+
// conflicting transaction clears.
|
|
265
|
+
const template = Transaction.from(transaction);
|
|
235
266
|
// Dry run the transaction if cost logging is enabled to get the gas and storage costs
|
|
236
267
|
if (Is.stringValue(options?.dryRunLabel)) {
|
|
237
268
|
await Iota.dryRunTransaction(client, logging, transaction, owner, options.dryRunLabel);
|
|
@@ -239,28 +270,38 @@ export class Iota {
|
|
|
239
270
|
const { keyName, publicKey } = await Iota.ensureOwnerKey(vaultConnector, config, identity, owner);
|
|
240
271
|
const signer = new VaultSigner(vaultConnector, keyName, publicKey);
|
|
241
272
|
try {
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
273
|
+
// Concurrent transactions that reference the same owned objects can be rejected while
|
|
274
|
+
// those objects are reserved for another in-flight transaction, so retry the submission
|
|
275
|
+
// with back-off until the reservation clears. Each attempt rebuilds from the unresolved
|
|
276
|
+
// template so versions and gas re-resolve rather than resubmitting identical bytes.
|
|
277
|
+
return await Iota.executeWithReservationRetry(config, async () => {
|
|
278
|
+
const response = await client.signAndExecuteTransaction({
|
|
279
|
+
transaction: Transaction.from(template),
|
|
280
|
+
signer,
|
|
281
|
+
requestType: "WaitForLocalExecution",
|
|
282
|
+
options: {
|
|
283
|
+
showEffects: options?.showEffects ?? true,
|
|
284
|
+
showEvents: options?.showEvents ?? true,
|
|
285
|
+
showObjectChanges: options?.showObjectChanges ?? true
|
|
286
|
+
}
|
|
287
|
+
});
|
|
288
|
+
if (options?.waitForConfirmation ?? true) {
|
|
289
|
+
// Wait for transaction to be indexed and available over API
|
|
290
|
+
return Iota.waitForTransactionConfirmation(client, response.digest, config, {
|
|
291
|
+
showEffects: options?.showEffects ?? true,
|
|
292
|
+
showEvents: options?.showEvents ?? true,
|
|
293
|
+
showObjectChanges: options?.showObjectChanges ?? true
|
|
294
|
+
});
|
|
250
295
|
}
|
|
296
|
+
return response;
|
|
251
297
|
});
|
|
252
|
-
if (options?.waitForConfirmation ?? true) {
|
|
253
|
-
// Wait for transaction to be indexed and available over API
|
|
254
|
-
const confirmedTransaction = await Iota.waitForTransactionConfirmation(client, response.digest, config, {
|
|
255
|
-
showEffects: options?.showEffects ?? true,
|
|
256
|
-
showEvents: options?.showEvents ?? true,
|
|
257
|
-
showObjectChanges: options?.showObjectChanges ?? true
|
|
258
|
-
});
|
|
259
|
-
return confirmedTransaction;
|
|
260
|
-
}
|
|
261
|
-
return response;
|
|
262
298
|
}
|
|
263
299
|
catch (error) {
|
|
300
|
+
// Pass through the clear object-conflict error; wrap everything else (including any
|
|
301
|
+
// non-conflict GeneralError raised inside, e.g. a vault signing failure) as before.
|
|
302
|
+
if (Iota.isRetryableObjectConflictError(error)) {
|
|
303
|
+
throw error;
|
|
304
|
+
}
|
|
264
305
|
throw new GeneralError(Iota.CLASS_NAME, "transactionFailed", undefined, Iota.extractPayloadError(error));
|
|
265
306
|
}
|
|
266
307
|
}
|
|
@@ -433,6 +474,98 @@ export class Iota {
|
|
|
433
474
|
}
|
|
434
475
|
}
|
|
435
476
|
}
|
|
477
|
+
/**
|
|
478
|
+
* Check if an error is a retryable "owned object reserved by another transaction" conflict.
|
|
479
|
+
* IOTA locks owned objects for the first in-flight transaction that claims them, so a
|
|
480
|
+
* concurrent transaction referencing the same objects is rejected until the lock clears. This
|
|
481
|
+
* only matches the transient "reserved for another transaction" case, not the non-retryable
|
|
482
|
+
* "equivocated until the next epoch" case.
|
|
483
|
+
* @param error The error to check.
|
|
484
|
+
* @returns True if the error is a retryable object reservation conflict.
|
|
485
|
+
*/
|
|
486
|
+
static isReservedObjectError(error) {
|
|
487
|
+
return Is.stringValue(Iota.objectConflictMessage(error, Iota._RESERVED_OBJECT_ERROR_PATTERN));
|
|
488
|
+
}
|
|
489
|
+
/**
|
|
490
|
+
* Check if an error is a retryable owned-object conflict caused by a concurrent transaction.
|
|
491
|
+
* This covers both the "reserved for another transaction" case (the object is locked by an
|
|
492
|
+
* in-flight transaction) and the "is not available for consumption" case (a concurrent
|
|
493
|
+
* transaction already consumed the referenced version); a retry rebuild re-resolves to the
|
|
494
|
+
* current version so both can recover. The non-retryable "equivocated until the next epoch"
|
|
495
|
+
* case is not matched.
|
|
496
|
+
* @param error The error to check.
|
|
497
|
+
* @returns True if the error is a retryable owned-object conflict.
|
|
498
|
+
*/
|
|
499
|
+
static isRetryableObjectConflictError(error) {
|
|
500
|
+
return (Is.stringValue(Iota.objectConflictMessage(error, Iota._RESERVED_OBJECT_ERROR_PATTERN)) ||
|
|
501
|
+
Is.stringValue(Iota.objectConflictMessage(error, Iota._STALE_OBJECT_ERROR_PATTERN)));
|
|
502
|
+
}
|
|
503
|
+
/**
|
|
504
|
+
* Extract the conflicting transaction digests from an object reservation conflict error.
|
|
505
|
+
* The node error lists the digests of the transactions currently locking the objects (the
|
|
506
|
+
* underlying object ids are only present in the RPC error data, which the IOTA SDK discards).
|
|
507
|
+
* Only the "reserved for another transaction" error carries digests, so this returns an empty
|
|
508
|
+
* array for the stale-version conflict case.
|
|
509
|
+
* @param error The error to extract from.
|
|
510
|
+
* @returns The conflicting transaction digests, or an empty array if none can be parsed.
|
|
511
|
+
*/
|
|
512
|
+
static extractReservationConflictDigests(error) {
|
|
513
|
+
const message = Iota.objectConflictMessage(error, Iota._RESERVED_OBJECT_ERROR_PATTERN);
|
|
514
|
+
if (!Is.stringValue(message)) {
|
|
515
|
+
return [];
|
|
516
|
+
}
|
|
517
|
+
const digests = [];
|
|
518
|
+
// The direct path preserves real newlines; through the gas station the node message is
|
|
519
|
+
// Debug-formatted so the newlines arrive as the literal two-character sequence "\n", hence
|
|
520
|
+
// both a real newline and an escaped one are treated as a line start here.
|
|
521
|
+
const linePattern = /(?:^|\n|\\n)- (\S+) \(stake /g;
|
|
522
|
+
let match = linePattern.exec(message);
|
|
523
|
+
while (match !== null) {
|
|
524
|
+
digests.push(match[1]);
|
|
525
|
+
match = linePattern.exec(message);
|
|
526
|
+
}
|
|
527
|
+
return digests;
|
|
528
|
+
}
|
|
529
|
+
/**
|
|
530
|
+
* Run a transaction submission operation, retrying with exponential back-off if it is rejected
|
|
531
|
+
* because of a retryable owned-object conflict with a concurrent transaction (the objects are
|
|
532
|
+
* reserved by an in-flight transaction, or the referenced version was already consumed).
|
|
533
|
+
* Other errors are rethrown immediately. If the conflict persists after all retries a clear,
|
|
534
|
+
* retryable error is thrown instead of the opaque underlying failure.
|
|
535
|
+
* @param config The configuration controlling retry counts and delays.
|
|
536
|
+
* @param operation The transaction submission operation to run.
|
|
537
|
+
* @returns The result of the operation.
|
|
538
|
+
*/
|
|
539
|
+
static async executeWithReservationRetry(config, operation) {
|
|
540
|
+
if (!Is.undefined(config.objectLockRetries)) {
|
|
541
|
+
Guards.integer(Iota.CLASS_NAME, "config.objectLockRetries", config.objectLockRetries);
|
|
542
|
+
}
|
|
543
|
+
if (!Is.undefined(config.objectLockRetryDelayMs)) {
|
|
544
|
+
Guards.integer(Iota.CLASS_NAME, "config.objectLockRetryDelayMs", config.objectLockRetryDelayMs);
|
|
545
|
+
}
|
|
546
|
+
const maxRetries = Math.max(0, config.objectLockRetries ?? Iota._DEFAULT_OBJECT_LOCK_RETRIES);
|
|
547
|
+
const baseDelayMs = Math.max(0, config.objectLockRetryDelayMs ?? Iota._DEFAULT_OBJECT_LOCK_RETRY_DELAY_MS);
|
|
548
|
+
let lastError;
|
|
549
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
550
|
+
try {
|
|
551
|
+
return await operation();
|
|
552
|
+
}
|
|
553
|
+
catch (error) {
|
|
554
|
+
if (!Iota.isRetryableObjectConflictError(error)) {
|
|
555
|
+
throw error;
|
|
556
|
+
}
|
|
557
|
+
lastError = error;
|
|
558
|
+
if (attempt < maxRetries) {
|
|
559
|
+
// Exponential back-off with jitter: concurrent losers fail at nearly the same moment,
|
|
560
|
+
// so without jitter they would resubmit in lockstep and re-race each other each round.
|
|
561
|
+
const jitter = (1 + Math.random()) / 2;
|
|
562
|
+
const delayMs = baseDelayMs * Math.pow(2, attempt) * jitter;
|
|
563
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
564
|
+
}
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
throw new GeneralError(Iota.CLASS_NAME, "objectReservationConflict", { conflictingTransactions: Iota.extractReservationConflictDigests(lastError) }, Iota.extractPayloadError(lastError));
|
|
568
|
+
}
|
|
436
569
|
/**
|
|
437
570
|
* Prepare and post a transaction using gas station sponsoring.
|
|
438
571
|
* @param config The configuration.
|
|
@@ -446,22 +579,33 @@ export class Iota {
|
|
|
446
579
|
*/
|
|
447
580
|
static async prepareAndPostGasStationTransaction(config, vaultConnector, identity, client, owner, transaction, options) {
|
|
448
581
|
Guards.object(Iota.CLASS_NAME, "config.gasStation", config.gasStation);
|
|
582
|
+
// Capture the transaction while its inputs are still unresolved so each retry attempt can
|
|
583
|
+
// rebuild with fresh object versions (see prepareAndPostTransaction).
|
|
584
|
+
const template = Transaction.from(transaction);
|
|
585
|
+
const { keyName, publicKey } = await Iota.ensureOwnerKey(vaultConnector, config, identity, owner);
|
|
586
|
+
const signer = new VaultSigner(vaultConnector, keyName, publicKey);
|
|
449
587
|
try {
|
|
450
|
-
//
|
|
451
|
-
|
|
452
|
-
//
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
588
|
+
// Sponsored transactions still reference the sender's owned objects, so the same
|
|
589
|
+
// reservation conflict can occur. Retry with a fresh gas reservation and a rebuilt
|
|
590
|
+
// transaction on each attempt (the reserved sponsor coins and object versions change).
|
|
591
|
+
return await Iota.executeWithReservationRetry(config, async () => {
|
|
592
|
+
const gasReservation = await Iota.reserveGas(config);
|
|
593
|
+
// Rebuild and set the sponsoring parameters for this attempt.
|
|
594
|
+
const attemptTransaction = Transaction.from(template);
|
|
595
|
+
attemptTransaction.setSender(owner);
|
|
596
|
+
attemptTransaction.setGasOwner(gasReservation.sponsorAddress);
|
|
597
|
+
attemptTransaction.setGasPayment(gasReservation.gasCoins);
|
|
598
|
+
attemptTransaction.setGasBudget(config.gasBudget ?? Iota._DEFAULT_GAS_BUDGET);
|
|
599
|
+
const unsignedTxBytes = await attemptTransaction.build({ client });
|
|
600
|
+
const signature = await signer.signTransaction(unsignedTxBytes);
|
|
601
|
+
return Iota.executeAndConfirmGasStationTransaction(config, client, gasReservation.reservationId, unsignedTxBytes, signature.signature, options);
|
|
602
|
+
});
|
|
463
603
|
}
|
|
464
604
|
catch (error) {
|
|
605
|
+
// Pass through the clear object-conflict error; wrap everything else as before.
|
|
606
|
+
if (Iota.isRetryableObjectConflictError(error)) {
|
|
607
|
+
throw error;
|
|
608
|
+
}
|
|
465
609
|
throw new GeneralError(Iota.CLASS_NAME, "gasStationTransactionFailed", undefined, Iota.extractPayloadError(error));
|
|
466
610
|
}
|
|
467
611
|
}
|
|
@@ -650,6 +794,20 @@ export class Iota {
|
|
|
650
794
|
static transactionFromBytes(bytes) {
|
|
651
795
|
return Transaction.from(bytes);
|
|
652
796
|
}
|
|
797
|
+
/**
|
|
798
|
+
* Find the raw node message matching an object conflict pattern, wherever it surfaces. On the
|
|
799
|
+
* direct submission path it is the thrown error's message; through the gas station it arrives as
|
|
800
|
+
* an HTTP error whose body the fetch layer nests as the message of a cause error. Flattening the
|
|
801
|
+
* error tree and matching each message covers both.
|
|
802
|
+
* @param error The error to inspect.
|
|
803
|
+
* @param pattern The conflict pattern to match.
|
|
804
|
+
* @returns The raw node message if the pattern matches, otherwise undefined.
|
|
805
|
+
* @internal
|
|
806
|
+
*/
|
|
807
|
+
static objectConflictMessage(error, pattern) {
|
|
808
|
+
const match = BaseError.flatten(error).find(flattened => Is.stringValue(flattened.message) && pattern.test(flattened.message));
|
|
809
|
+
return match?.message;
|
|
810
|
+
}
|
|
653
811
|
/**
|
|
654
812
|
* Find the vault key name and public key for the given owner address.
|
|
655
813
|
* Keys are individually registered in the vault by buildKeyPairRange, so no addKey is needed here.
|
package/dist/es/iota.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"iota.js","sourceRoot":"","sources":["../../src/iota.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { IotaClient } from \"@iota/iota-sdk/client\";\nimport { requestIotaFromFaucetV0 } from \"@iota/iota-sdk/faucet\";\nimport { Transaction } from \"@iota/iota-sdk/transactions\";\nimport {\n\tBaseError,\n\tCoerce,\n\tConverter,\n\tGeneralError,\n\tGuards,\n\tIs,\n\tStringHelper,\n\ttype IError\n} from \"@twin.org/core\";\nimport { Bip39, Bip44, Blake2b, KeyType } from \"@twin.org/crypto\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { VaultConnectorHelper, VaultKeyType } from \"@twin.org/vault-models\";\nimport type { IVaultConnector } from \"@twin.org/vault-models\";\nimport { FetchHelper, HttpMethod } from \"@twin.org/web\";\nimport type { IGasReservationResult } from \"./models/IGasReservationResult.js\";\nimport type { IGasStationConfig } from \"./models/IGasStationConfig.js\";\nimport type { IGasStationExecuteResponse } from \"./models/IGasStationExecuteResponse.js\";\nimport type { IGasStationReserveGasResponse } from \"./models/IGasStationReserveGasResponse.js\";\nimport type { IIotaClient } from \"./models/IIotaClient.js\";\nimport type { IIotaConfig } from \"./models/IIotaConfig.js\";\nimport type { IIotaDryRun } from \"./models/IIotaDryRun.js\";\nimport type { IIotaResponseOptions } from \"./models/IIotaResponseOptions.js\";\nimport type { IIotaTransaction } from \"./models/IIotaTransaction.js\";\nimport type { IIotaTransactionBlockResponse } from \"./models/IIotaTransactionBlockResponse.js\";\nimport { VaultSigner } from \"./vaultSigner.js\";\nimport { VaultTransactionSigner } from \"./vaultTransactionSigner.js\";\n\n/**\n * Class for performing operations on IOTA.\n */\nexport class Iota {\n\t/**\n\t * Default name for the mnemonic secret.\n\t */\n\tpublic static readonly DEFAULT_MNEMONIC_SECRET_NAME: string = \"mnemonic\";\n\n\t/**\n\t * Default name for the seed secret.\n\t */\n\tpublic static readonly DEFAULT_SEED_SECRET_NAME: string = \"seed\";\n\n\t/**\n\t * Default coin type.\n\t */\n\tpublic static readonly DEFAULT_COIN_TYPE: number = 4218;\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Iota>();\n\n\t/**\n\t * Default scan range.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_SCAN_RANGE: number = 1000;\n\n\t/**\n\t * Default pre-calculation chunk size.\n\t * @internal\n\t */\n\tprivate static readonly _PRE_CALC_CHUNK_SIZE: number = 25;\n\n\t/**\n\t * Default inclusion timeout.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_INCLUSION_TIMEOUT: number = 60;\n\n\t/**\n\t * Default gas budget for all transactions (including sponsored and direct).\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_GAS_BUDGET: number = 50000000;\n\n\t/**\n\t * Default gas reservation duration.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_GAS_RESERVATION_DURATION: number = 60;\n\n\t/**\n\t * Create a new IOTA client.\n\t * @param config The configuration.\n\t * @returns The client instance.\n\t */\n\tpublic static createClient(config: IIotaConfig): IIotaClient {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config.clientOptions), config.clientOptions);\n\t\tGuards.string(Iota.CLASS_NAME, nameof(config.clientOptions.url), config.clientOptions.url);\n\n\t\treturn new IotaClient(config.clientOptions);\n\t}\n\n\t/**\n\t * Create configuration using defaults where necessary.\n\t * @param config The configuration to populate.\n\t */\n\tpublic static populateConfig(config: IIotaConfig): void {\n\t\tGuards.object<IIotaConfig[\"clientOptions\"]>(\n\t\t\tIota.CLASS_NAME,\n\t\t\tnameof(config.clientOptions),\n\t\t\tconfig.clientOptions\n\t\t);\n\n\t\tconfig.vaultMnemonicId ??= Iota.DEFAULT_MNEMONIC_SECRET_NAME;\n\t\tconfig.vaultSeedId ??= Iota.DEFAULT_SEED_SECRET_NAME;\n\t\tconfig.coinType ??= Iota.DEFAULT_COIN_TYPE;\n\t\tconfig.inclusionTimeoutSeconds ??= Iota._DEFAULT_INCLUSION_TIMEOUT;\n\t}\n\n\t/**\n\t * Store a mnemonic in the vault, derive and store the seed, and pre-cache the first keypair chunk.\n\t * @param vaultConnector The vault connector.\n\t * @param config The configuration.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param mnemonic The mnemonic to store, if undefined a new one will be generated and returned.\n\t * @param accountIndex The account index to pre-cache.\n\t * @returns The mnemonic that was stored.\n\t */\n\tpublic static async storeMnemonic(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: IIotaConfig,\n\t\tidentity: string,\n\t\tmnemonic: string | undefined,\n\t\taccountIndex: number\n\t): Promise<string> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(vaultConnector), vaultConnector);\n\t\tGuards.object<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(accountIndex), accountIndex);\n\n\t\tconst mnemonicToStore = mnemonic ?? Bip39.randomMnemonic();\n\n\t\tawait vaultConnector.setSecret(\n\t\t\tIota.buildMnemonicKey(identity, config.vaultMnemonicId),\n\t\t\tmnemonicToStore\n\t\t);\n\n\t\tconst seed = Bip39.mnemonicToSeed(mnemonicToStore);\n\t\tawait vaultConnector.setSecret(\n\t\t\tIota.buildSeedKey(identity, config.vaultSeedId),\n\t\t\tConverter.bytesToBase64(seed)\n\t\t);\n\n\t\tawait Iota.getPublicKeys(\n\t\t\tvaultConnector,\n\t\t\tconfig,\n\t\t\tidentity,\n\t\t\taccountIndex,\n\t\t\tfalse,\n\t\t\t0,\n\t\t\tasync () => seed\n\t\t);\n\n\t\treturn mnemonicToStore;\n\t}\n\n\t/**\n\t * Derive an address from a public key.\n\t * @param publicKey The public key to derive the address from.\n\t * @returns The derived address.\n\t */\n\tpublic static publicKeyToAddress(publicKey: Uint8Array): string {\n\t\treturn Converter.bytesToHex(Blake2b.sum256(publicKey), true);\n\t}\n\n\t/**\n\t * Get address for the identity.\n\t * @param vaultConnector The vault connector.\n\t * @param config The configuration.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param accountIndex The account index to get the addresses for.\n\t * @param startAddressIndex The start index for the addresses.\n\t * @param isInternal Whether the addresses are internal.\n\t * @returns The address.\n\t */\n\tpublic static async getAddress(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: Pick<IIotaConfig, \"coinType\" | \"vaultMnemonicId\" | \"vaultSeedId\">,\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\tstartAddressIndex: number,\n\t\tisInternal?: boolean\n\t): Promise<string> {\n\t\tconst addresses = await Iota.getAddresses(\n\t\t\tvaultConnector,\n\t\t\tconfig,\n\t\t\tidentity,\n\t\t\taccountIndex,\n\t\t\tstartAddressIndex,\n\t\t\t1,\n\t\t\tisInternal\n\t\t);\n\t\treturn addresses[0];\n\t}\n\n\t/**\n\t * Get addresses for the identity.\n\t * @param vaultConnector The vault connector.\n\t * @param config The configuration.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param accountIndex The account index to get the addresses for.\n\t * @param startAddressIndex The start index for the addresses.\n\t * @param count The number of addresses to generate.\n\t * @param isInternal Whether the addresses are internal.\n\t * @returns The list of addresses.\n\t */\n\tpublic static async getAddresses(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: Pick<IIotaConfig, \"coinType\" | \"vaultMnemonicId\" | \"vaultSeedId\">,\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\tstartAddressIndex: number,\n\t\tcount: number,\n\t\tisInternal?: boolean\n\t): Promise<string[]> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(vaultConnector), vaultConnector);\n\t\tGuards.object<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(accountIndex), accountIndex);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(startAddressIndex), startAddressIndex);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(count), count);\n\n\t\tconst addresses: string[] = [];\n\t\tconst internal = isInternal ?? false;\n\t\tlet currentIndex = startAddressIndex;\n\t\tlet cachedSeed: Uint8Array | undefined;\n\t\tconst seedProvider = async (): Promise<Uint8Array> => {\n\t\t\tcachedSeed ??= await Iota.getSeed(vaultConnector, config, identity);\n\t\t\treturn cachedSeed;\n\t\t};\n\n\t\twhile (addresses.length < count) {\n\t\t\tconst chunkStart =\n\t\t\t\tMath.floor(currentIndex / Iota._PRE_CALC_CHUNK_SIZE) * Iota._PRE_CALC_CHUNK_SIZE;\n\t\t\tconst publicKeys = await Iota.getPublicKeys(\n\t\t\t\tvaultConnector,\n\t\t\t\tconfig,\n\t\t\t\tidentity,\n\t\t\t\taccountIndex,\n\t\t\t\tinternal,\n\t\t\t\tchunkStart,\n\t\t\t\tseedProvider\n\t\t\t);\n\t\t\tconst chunk = publicKeys.map((pk: string) =>\n\t\t\t\tIota.publicKeyToAddress(Converter.base64ToBytes(pk))\n\t\t\t);\n\t\t\tconst offsetInChunk = currentIndex - chunkStart;\n\t\t\tconst remaining = count - addresses.length;\n\t\t\taddresses.push(...chunk.slice(offsetInChunk, offsetInChunk + remaining));\n\t\t\tcurrentIndex = chunkStart + Iota._PRE_CALC_CHUNK_SIZE;\n\t\t}\n\n\t\treturn addresses;\n\t}\n\n\t/**\n\t * Get a vault-backed transaction signer for the given identity and key indices.\n\t * @param vaultConnector The vault connector.\n\t * @param config The configuration.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param accountIndex The account index.\n\t * @param addressIndex The address index within the account.\n\t * @returns A VaultTransactionSigner for the specified key.\n\t */\n\tpublic static async getTransactionSigner(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: IIotaConfig,\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\taddressIndex: number\n\t): Promise<VaultTransactionSigner> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(vaultConnector), vaultConnector);\n\t\tGuards.object<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(accountIndex), accountIndex);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(addressIndex), addressIndex);\n\n\t\tconst publicKeys = await Iota.getPublicKeys(\n\t\t\tvaultConnector,\n\t\t\tconfig,\n\t\t\tidentity,\n\t\t\taccountIndex,\n\t\t\tfalse,\n\t\t\taddressIndex,\n\t\t\tasync () => Iota.getSeed(vaultConnector, config, identity)\n\t\t);\n\n\t\tconst chunkStart = addressIndex - (addressIndex % Iota._PRE_CALC_CHUNK_SIZE);\n\t\tconst offsetInChunk = addressIndex - chunkStart;\n\t\tconst publicKey = Converter.base64ToBytes(publicKeys[offsetInChunk]);\n\t\tconst keyName = Iota.buildAddressKeyName(identity, accountIndex, false, addressIndex);\n\n\t\treturn new VaultTransactionSigner(vaultConnector, keyName, publicKey);\n\t}\n\n\t/**\n\t * Create a new transaction instance.\n\t * @returns A new transaction instance.\n\t */\n\tpublic static createTransaction(): IIotaTransaction {\n\t\treturn new Transaction();\n\t}\n\n\t/**\n\t * Prepare and post a transaction.\n\t * @param config The configuration.\n\t * @param vaultConnector The vault connector.\n\t * @param logging The logging component.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param client The client instance.\n\t * @param source The source address.\n\t * @param amount The amount to transfer.\n\t * @param recipient The recipient address.\n\t * @param options The transaction options.\n\t * @returns The transaction result.\n\t */\n\tpublic static async prepareAndPostValueTransaction(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tlogging: ILoggingComponent | undefined,\n\t\tidentity: string,\n\t\tclient: IIotaClient,\n\t\tsource: string,\n\t\tamount: bigint,\n\t\trecipient: string,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\ttry {\n\t\t\tconst txb = new Transaction();\n\t\t\tconst [coin] = txb.splitCoins(txb.gas, [txb.pure.u64(amount)]);\n\t\t\ttxb.transferObjects([coin], txb.pure.address(recipient));\n\n\t\t\t// Check if gas station configuration is present\n\t\t\tif (Is.object<IGasStationConfig>(config.gasStation)) {\n\t\t\t\treturn await Iota.prepareAndPostGasStationTransaction(\n\t\t\t\t\tconfig,\n\t\t\t\t\tvaultConnector,\n\t\t\t\t\tidentity,\n\t\t\t\t\tclient,\n\t\t\t\t\tsource,\n\t\t\t\t\ttxb\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst result = await Iota.prepareAndPostTransaction(\n\t\t\t\tconfig,\n\t\t\t\tvaultConnector,\n\t\t\t\tlogging,\n\t\t\t\tidentity,\n\t\t\t\tclient,\n\t\t\t\tsource,\n\t\t\t\ttxb,\n\t\t\t\toptions\n\t\t\t);\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"valueTransactionFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Prepare and post a transaction.\n\t * @param config The configuration.\n\t * @param vaultConnector The vault connector.\n\t * @param logging The logging component.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param client The client instance.\n\t * @param owner The owner of the address.\n\t * @param transaction The transaction to execute.\n\t * @param options The transaction options.\n\t * @returns The transaction response.\n\t */\n\tpublic static async prepareAndPostTransaction(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tlogging: ILoggingComponent | undefined,\n\t\tidentity: string,\n\t\tclient: IIotaClient,\n\t\towner: string,\n\t\ttransaction: IIotaTransaction,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\t// Check if gas station configuration is present\n\t\tif (Is.object<IGasStationConfig>(config.gasStation)) {\n\t\t\treturn Iota.prepareAndPostGasStationTransaction(\n\t\t\t\tconfig,\n\t\t\t\tvaultConnector,\n\t\t\t\tidentity,\n\t\t\t\tclient,\n\t\t\t\towner,\n\t\t\t\ttransaction,\n\t\t\t\toptions\n\t\t\t);\n\t\t}\n\n\t\t// Traditional transaction flow\n\t\t// Dry run the transaction if cost logging is enabled to get the gas and storage costs\n\t\tif (Is.stringValue(options?.dryRunLabel)) {\n\t\t\tawait Iota.dryRunTransaction(client, logging, transaction, owner, options.dryRunLabel);\n\t\t}\n\n\t\tconst { keyName, publicKey } = await Iota.ensureOwnerKey(\n\t\t\tvaultConnector,\n\t\t\tconfig,\n\t\t\tidentity,\n\t\t\towner\n\t\t);\n\t\tconst signer = new VaultSigner(vaultConnector, keyName, publicKey);\n\n\t\ttry {\n\t\t\tconst response = await client.signAndExecuteTransaction({\n\t\t\t\ttransaction,\n\t\t\t\tsigner,\n\t\t\t\trequestType: \"WaitForLocalExecution\",\n\t\t\t\toptions: {\n\t\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (options?.waitForConfirmation ?? true) {\n\t\t\t\t// Wait for transaction to be indexed and available over API\n\t\t\t\tconst confirmedTransaction = await Iota.waitForTransactionConfirmation(\n\t\t\t\t\tclient,\n\t\t\t\t\tresponse.digest,\n\t\t\t\t\tconfig,\n\t\t\t\t\t{\n\t\t\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t\t\t}\n\t\t\t\t);\n\n\t\t\t\treturn confirmedTransaction;\n\t\t\t}\n\n\t\t\treturn response;\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"transactionFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Extract error from SDK payload.\n\t * Errors from the IOTA SDK are usually not JSON strings but objects.\n\t * @param error The error to extract.\n\t * @returns The extracted error.\n\t */\n\tpublic static extractPayloadError(error: unknown): IError {\n\t\tif (Is.object<{ code?: string; message?: string; inner?: unknown; cause?: unknown }>(error)) {\n\t\t\tif (!Is.empty(error.inner)) {\n\t\t\t\terror.inner = Iota.extractPayloadError(error.inner);\n\t\t\t}\n\t\t\tif (!Is.empty(error.cause)) {\n\t\t\t\terror.cause = Iota.extractPayloadError(error.cause);\n\t\t\t}\n\n\t\t\tif (error.code === \"InsufficientGas\") {\n\t\t\t\treturn new GeneralError(Iota.CLASS_NAME, \"insufficientFunds\");\n\t\t\t} else if (error.message?.startsWith(\"ErrorObject\")) {\n\t\t\t\tconst msg = /message: \"(.*)\"/.exec(error.message);\n\t\t\t\tif (msg && msg.length > 1) {\n\t\t\t\t\terror = msg[1];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst baseError = BaseError.fromError(error);\n\t\tif (baseError.name === \"Base\" && !Is.stringValue(baseError.source)) {\n\t\t\tbaseError.name = \"IOTA\";\n\t\t\tbaseError.source = Iota.CLASS_NAME;\n\t\t}\n\t\treturn baseError;\n\t}\n\n\t/**\n\t * Check if the package exists on the network.\n\t * @param client The client to use.\n\t * @param packageId The package ID to check.\n\t * @returns True if the package exists, false otherwise.\n\t */\n\tpublic static async packageExistsOnNetwork(\n\t\tclient: IIotaClient,\n\t\tpackageId: string\n\t): Promise<boolean> {\n\t\ttry {\n\t\t\tconst packageObject = await client.getObject({\n\t\t\t\tid: packageId,\n\t\t\t\toptions: {\n\t\t\t\t\tshowType: true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (\"error\" in packageObject) {\n\t\t\t\tif (packageObject?.error?.code === \"notExists\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"packageObjectError\", {\n\t\t\t\t\tpackageId,\n\t\t\t\t\terror: packageObject.error\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"packageNotFoundOnNetwork\",\n\t\t\t\t{\n\t\t\t\t\tpackageId\n\t\t\t\t},\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Dry run a transaction and log the results.\n\t * @param client The IOTA client.\n\t * @param logging The logging component.\n\t * @param txb The transaction to dry run.\n\t * @param sender The sender address.\n\t * @param operation The operation to log.\n\t * @returns The dry run result including status, costs, events, and object changes.\n\t */\n\tpublic static async dryRunTransaction(\n\t\tclient: IIotaClient,\n\t\tlogging: ILoggingComponent | undefined,\n\t\ttxb: IIotaTransaction,\n\t\tsender: string,\n\t\toperation: string\n\t): Promise<IIotaDryRun> {\n\t\ttry {\n\t\t\ttxb.setSender(sender);\n\n\t\t\tconst builtTx = await txb.build({\n\t\t\t\tclient,\n\t\t\t\tonlyTransactionKind: false\n\t\t\t});\n\n\t\t\tconst dryRunResult = await client.dryRunTransactionBlock({\n\t\t\t\ttransactionBlock: builtTx\n\t\t\t});\n\n\t\t\tif (dryRunResult.effects.status?.status !== \"success\") {\n\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"dryRunFailed\", {\n\t\t\t\t\terror: dryRunResult.effects?.status?.error\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst result = {\n\t\t\t\tstatus: dryRunResult.effects.status.status,\n\t\t\t\tcosts: {\n\t\t\t\t\tcomputationCost: dryRunResult.effects.gasUsed.computationCost,\n\t\t\t\t\tcomputationCostBurned: dryRunResult.effects.gasUsed.computationCostBurned,\n\t\t\t\t\tstorageCost: dryRunResult.effects.gasUsed.storageCost,\n\t\t\t\t\tstorageRebate: dryRunResult.effects.gasUsed.storageRebate,\n\t\t\t\t\tnonRefundableStorageFee: dryRunResult.effects.gasUsed.nonRefundableStorageFee\n\t\t\t\t},\n\t\t\t\tevents: dryRunResult.events ?? [],\n\t\t\t\tbalanceChanges: dryRunResult.balanceChanges ?? [],\n\t\t\t\tobjectChanges: dryRunResult.objectChanges ?? []\n\t\t\t};\n\n\t\t\tawait logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: Iota.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"transactionCosts\",\n\t\t\t\tdata: {\n\t\t\t\t\toperation,\n\t\t\t\t\tcost: JSON.stringify(result)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (BaseError.isErrorName(error, GeneralError.CLASS_NAME)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"dryRunFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a transaction to be indexed and available over the API.\n\t * @param client The IOTA client instance.\n\t * @param digest The digest of the transaction to wait for.\n\t * @param config The IOTA configuration.\n\t * @param options Additional options for the transaction query.\n\t * @param options.showEffects Whether to show effects.\n\t * @param options.showEvents Whether to show events.\n\t * @param options.showObjectChanges Whether to show object changes.\n\t * @returns The confirmed transaction response.\n\t */\n\tpublic static async waitForTransactionConfirmation(\n\t\tclient: IIotaClient,\n\t\tdigest: string,\n\t\tconfig: IIotaConfig,\n\t\toptions?: {\n\t\t\tshowEffects?: boolean;\n\t\t\tshowEvents?: boolean;\n\t\t\tshowObjectChanges?: boolean;\n\t\t}\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\tconst timeoutMs = (config.inclusionTimeoutSeconds ?? Iota._DEFAULT_INCLUSION_TIMEOUT) * 1000;\n\n\t\treturn client.waitForTransaction({\n\t\t\tdigest,\n\t\t\ttimeout: timeoutMs,\n\t\t\toptions: {\n\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Check if the error is an abort error with a specific code.\n\t * @param error The error to check.\n\t * @param code The error code to check for.\n\t * @returns True if the error is an abort error, false otherwise.\n\t */\n\tpublic static isAbortError(error: unknown, code: number): boolean {\n\t\tconst err = BaseError.fromError(error);\n\t\tif (Is.stringValue(err.properties?.error)) {\n\t\t\tconst abortCodeMatch = /abort code\\s*:\\s*(\\d+)/i.exec(err.properties.error);\n\t\t\treturn abortCodeMatch?.[1] === code.toString();\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Extracts the abort code from a transaction result if the transaction was aborted.\n\t * @param response The transaction result to extract the abort code from.\n\t * @returns The abort code if the transaction was aborted, or undefined if it was not an abort error or the code could not be extracted.\n\t */\n\tpublic static extractAbortCode(response: IIotaTransactionBlockResponse): number | undefined {\n\t\tif (\n\t\t\tresponse.effects?.status?.status === \"failure\" &&\n\t\t\tIs.stringValue(response.effects.status.error)\n\t\t) {\n\t\t\tconst match = /abort code: (\\d+)/.exec(response.effects.status.error);\n\t\t\tif (match) {\n\t\t\t\treturn Coerce.integer(match[1]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Prepare and post a transaction using gas station sponsoring.\n\t * @param config The configuration.\n\t * @param vaultConnector The vault connector.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param client The client instance.\n\t * @param owner The owner of the address.\n\t * @param transaction The transaction to execute.\n\t * @param options Response options including confirmation behavior.\n\t * @returns The transaction response.\n\t */\n\tpublic static async prepareAndPostGasStationTransaction(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tidentity: string,\n\t\tclient: IIotaClient,\n\t\towner: string,\n\t\ttransaction: IIotaTransaction,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\ttry {\n\t\t\t// Reserve gas from the gas station\n\t\t\tconst gasReservation = await Iota.reserveGas(config);\n\n\t\t\t// Set transaction parameters for sponsoring\n\t\t\ttransaction.setSender(owner);\n\t\t\ttransaction.setGasOwner(gasReservation.sponsorAddress);\n\t\t\ttransaction.setGasPayment(gasReservation.gasCoins);\n\t\t\ttransaction.setGasBudget(config.gasBudget ?? Iota._DEFAULT_GAS_BUDGET);\n\n\t\t\t// Build and sign transaction\n\t\t\tconst unsignedTxBytes = await transaction.build({ client });\n\n\t\t\tconst { keyName, publicKey } = await Iota.ensureOwnerKey(\n\t\t\t\tvaultConnector,\n\t\t\t\tconfig,\n\t\t\t\tidentity,\n\t\t\t\towner\n\t\t\t);\n\t\t\tconst signer = new VaultSigner(vaultConnector, keyName, publicKey);\n\t\t\tconst signature = await signer.signTransaction(unsignedTxBytes);\n\n\t\t\treturn await Iota.executeAndConfirmGasStationTransaction(\n\t\t\t\tconfig,\n\t\t\t\tclient,\n\t\t\t\tgasReservation.reservationId,\n\t\t\t\tunsignedTxBytes,\n\t\t\t\tsignature.signature,\n\t\t\t\toptions\n\t\t\t);\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"gasStationTransactionFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Reserve gas from the gas station.\n\t * @param config The configuration containing gas station settings.\n\t * @returns The gas reservation result.\n\t */\n\tpublic static async reserveGas(config: IIotaConfig): Promise<IGasReservationResult> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\tconst requestData = {\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tgas_budget: config.gasBudget ?? Iota._DEFAULT_GAS_BUDGET,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\treserve_duration_secs: config.gasReservationDuration ?? Iota._DEFAULT_GAS_RESERVATION_DURATION\n\t\t};\n\n\t\tconst baseUrl = StringHelper.trimTrailingSlashes(config.gasStation.gasStationUrl);\n\t\tconst result = await FetchHelper.fetchJson<typeof requestData, IGasStationReserveGasResponse>(\n\t\t\tIota.CLASS_NAME,\n\t\t\t`${baseUrl}/v1/reserve_gas`,\n\t\t\tHttpMethod.POST,\n\t\t\trequestData,\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.gasStation.gasStationAuthToken}`\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\n\t\tconst apiResponse = result.result;\n\n\t\treturn {\n\t\t\tsponsorAddress: apiResponse.sponsor_address,\n\t\t\treservationId: apiResponse.reservation_id,\n\t\t\tgasCoins: apiResponse.gas_coins\n\t\t};\n\t}\n\n\t/**\n\t * Execute a sponsored transaction through the gas station.\n\t * @param config The configuration containing gas station settings.\n\t * @param reservationId The reservation ID from gas reservation.\n\t * @param transactionBytes The unsigned transaction bytes.\n\t * @param userSignature The user's signature.\n\t * @returns The transaction response.\n\t */\n\tpublic static async executeGasStationTransaction(\n\t\tconfig: IIotaConfig,\n\t\treservationId: number,\n\t\ttransactionBytes: Uint8Array,\n\t\tuserSignature: string\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\tGuards.object<IGasStationConfig>(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\tconst requestData = {\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\treservation_id: reservationId,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\ttx_bytes: Converter.bytesToBase64(transactionBytes),\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tuser_sig: userSignature\n\t\t};\n\n\t\tconst baseUrl = StringHelper.trimTrailingSlashes(config.gasStation.gasStationUrl);\n\t\tconst result = await FetchHelper.fetchJson<typeof requestData, IGasStationExecuteResponse>(\n\t\t\tIota.CLASS_NAME,\n\t\t\t`${baseUrl}/v1/execute_tx`,\n\t\t\tHttpMethod.POST,\n\t\t\trequestData,\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.gasStation.gasStationAuthToken}`\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\n\t\tconst effectsData = result.effects;\n\n\t\t// Match IotaTransactionBlockResponse format\n\t\treturn {\n\t\t\tdigest: effectsData.transactionDigest,\n\t\t\teffects: effectsData as unknown,\n\t\t\tevents: [],\n\t\t\tobjectChanges: [],\n\t\t\tconfirmedLocalExecution: true\n\t\t} as unknown as IIotaTransactionBlockResponse;\n\t}\n\n\t/**\n\t * Execute and confirm a gas station transaction.\n\t * @param config The configuration containing gas station settings.\n\t * @param client The IOTA client for confirmation.\n\t * @param reservationId The reservation ID from gas reservation.\n\t * @param transactionBytes The unsigned transaction bytes.\n\t * @param userSignature The user's signature.\n\t * @param options Response options including confirmation behavior.\n\t * @returns The transaction response (confirmed if waitForConfirmation is true).\n\t */\n\tpublic static async executeAndConfirmGasStationTransaction(\n\t\tconfig: IIotaConfig,\n\t\tclient: IIotaClient,\n\t\treservationId: number,\n\t\ttransactionBytes: Uint8Array,\n\t\tuserSignature: string,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\tGuards.object<IGasStationConfig>(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\tconst response = await Iota.executeGasStationTransaction(\n\t\t\tconfig,\n\t\t\treservationId,\n\t\t\ttransactionBytes,\n\t\t\tuserSignature\n\t\t);\n\n\t\tif (options?.waitForConfirmation ?? true) {\n\t\t\tconst confirmedTransaction = await Iota.waitForTransactionConfirmation(\n\t\t\t\tclient,\n\t\t\t\tresponse.digest,\n\t\t\t\tconfig,\n\t\t\t\t{\n\t\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t\t}\n\t\t\t);\n\n\t\t\treturn confirmedTransaction;\n\t\t}\n\n\t\treturn response;\n\t}\n\n\t/**\n\t * Fund an address with IOTA from the faucet.\n\t * @param config The configuration containing endpoint information.\n\t * @param faucetUrl The URL of the faucet to request funds from.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param address The address to fund.\n\t * @param timeoutInSeconds The timeout in seconds to wait for the funding to complete.\n\t * @returns The amount funded.\n\t */\n\tpublic static async fundAddress(\n\t\tconfig: IIotaConfig,\n\t\tfaucetUrl: string,\n\t\tidentity: string,\n\t\taddress: string,\n\t\ttimeoutInSeconds: number = 60\n\t): Promise<bigint> {\n\t\tGuards.objectValue<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(config.clientOptions.url), config.clientOptions.url);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(faucetUrl), faucetUrl);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(address), address);\n\n\t\ttry {\n\t\t\tconst initialBalance = await Iota.getBalance(config, address);\n\n\t\t\tconst response = await requestIotaFromFaucetV0({\n\t\t\t\thost: faucetUrl,\n\t\t\t\trecipient: address\n\t\t\t});\n\n\t\t\tif (response?.error) {\n\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"fundingFailed\", undefined, response.error);\n\t\t\t}\n\n\t\t\t// Poll for balance change\n\t\t\tconst numTries = Math.ceil(timeoutInSeconds / 5);\n\t\t\tfor (let i = 0; i < numTries; i++) {\n\t\t\t\tconst newBalance = await Iota.getBalance(config, address);\n\n\t\t\t\tif (newBalance > initialBalance) {\n\t\t\t\t\treturn newBalance - initialBalance;\n\t\t\t\t}\n\n\t\t\t\tif (i < numTries - 1) {\n\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, 5000));\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst payloadError = Iota.extractPayloadError(error);\n\t\t\tif (\n\t\t\t\tpayloadError.message.includes(\n\t\t\t\t\t\"Too many requests from this client have been sent to the faucet\"\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\t\"faucetRateLimit\",\n\t\t\t\t\tundefined,\n\t\t\t\t\tIota.extractPayloadError(error)\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"fundingFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\n\t\treturn 0n;\n\t}\n\n\t/**\n\t * Ensure the balance for the given address is at least the given amount.\n\t * @param config The configuration containing endpoint information.\n\t * @param faucetUrl The URL of the faucet to request funds from.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param address The address to ensure the balance for.\n\t * @param ensureBalance The minimum balance to ensure.\n\t * @param timeoutInSeconds Optional timeout in seconds, defaults to 10 seconds.\n\t * @returns True if the balance is at least the given amount, false otherwise.\n\t */\n\tpublic static async ensureBalance(\n\t\tconfig: IIotaConfig,\n\t\tfaucetUrl: string | undefined,\n\t\tidentity: string,\n\t\taddress: string,\n\t\tensureBalance: bigint,\n\t\ttimeoutInSeconds?: number\n\t): Promise<boolean> {\n\t\tGuards.objectValue<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(config.clientOptions.url), config.clientOptions.url);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(address), address);\n\t\tGuards.bigint(Iota.CLASS_NAME, nameof(ensureBalance), ensureBalance);\n\n\t\tlet currentBalance = await Iota.getBalance(config, address);\n\n\t\tif (Is.stringValue(faucetUrl)) {\n\t\t\tlet retryCount = 10;\n\n\t\t\twhile (currentBalance < ensureBalance && retryCount > 0) {\n\t\t\t\tconst addedBalance = await Iota.fundAddress(\n\t\t\t\t\tconfig,\n\t\t\t\t\tfaucetUrl,\n\t\t\t\t\tidentity,\n\t\t\t\t\taddress,\n\t\t\t\t\ttimeoutInSeconds\n\t\t\t\t);\n\t\t\t\tif (addedBalance === 0n) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcurrentBalance += addedBalance;\n\t\t\t\tif (currentBalance < ensureBalance) {\n\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, 1000));\n\t\t\t\t\tretryCount--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn currentBalance >= ensureBalance;\n\t}\n\n\t/**\n\t * Get the balance for the given address.\n\t * @param config The configuration containing endpoint information.\n\t * @param address The address to get the balance for.\n\t * @returns The balance of the given address.\n\t */\n\tpublic static async getBalance(config: IIotaConfig, address: string): Promise<bigint> {\n\t\tGuards.objectValue<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(config.clientOptions.url), config.clientOptions.url);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(address), address);\n\n\t\tconst client = Iota.createClient(config);\n\t\tconst balance = await client.getBalance({\n\t\t\towner: address\n\t\t});\n\t\treturn BigInt(balance.totalBalance);\n\t}\n\n\t/**\n\t * Create a transaction instance from the given bytes.\n\t * @param bytes The transaction bytes to create the transaction from.\n\t * @returns The transaction instance created from the given bytes.\n\t */\n\tpublic static transactionFromBytes(bytes: Uint8Array): IIotaTransaction {\n\t\treturn Transaction.from(bytes);\n\t}\n\n\t/**\n\t * Find the vault key name and public key for the given owner address.\n\t * Keys are individually registered in the vault by buildKeyPairRange, so no addKey is needed here.\n\t * @param vaultConnector The vault connector to use.\n\t * @param config The configuration to use.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param owner The owner address whose key should be located.\n\t * @param accountIndex The account index to search.\n\t * @returns The vault key name and the public key bytes.\n\t * @internal\n\t */\n\tprivate static async ensureOwnerKey(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: IIotaConfig,\n\t\tidentity: string,\n\t\towner: string,\n\t\taccountIndex: number = 0\n\t): Promise<{ keyName: string; publicKey: Uint8Array }> {\n\t\tconst scanRange = config.maxAddressScanRange ?? Iota._DEFAULT_SCAN_RANGE;\n\t\tlet cachedSeed: Uint8Array | undefined;\n\t\tconst seedProvider = async (): Promise<Uint8Array> => {\n\t\t\tcachedSeed ??= await Iota.getSeed(vaultConnector, config, identity);\n\t\t\treturn cachedSeed;\n\t\t};\n\n\t\tfor (let chunkStart = 0; chunkStart < scanRange; chunkStart += Iota._PRE_CALC_CHUNK_SIZE) {\n\t\t\tconst publicKeys = await Iota.getPublicKeys(\n\t\t\t\tvaultConnector,\n\t\t\t\tconfig,\n\t\t\t\tidentity,\n\t\t\t\taccountIndex,\n\t\t\t\tfalse,\n\t\t\t\tchunkStart,\n\t\t\t\tseedProvider\n\t\t\t);\n\t\t\tconst matchIndex = publicKeys.findIndex(\n\t\t\t\t(pk: string) => Iota.publicKeyToAddress(Converter.base64ToBytes(pk)) === owner\n\t\t\t);\n\t\t\tif (matchIndex >= 0) {\n\t\t\t\tconst addressIndex = chunkStart + matchIndex;\n\t\t\t\treturn {\n\t\t\t\t\tkeyName: Iota.buildAddressKeyName(identity, accountIndex, false, addressIndex),\n\t\t\t\t\tpublicKey: Converter.base64ToBytes(publicKeys[matchIndex])\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tthrow new GeneralError(Iota.CLASS_NAME, \"addressNotFound\", { address: owner });\n\t}\n\n\t/**\n\t * Get the seed from the vault, deriving it from the mnemonic if necessary.\n\t * @param vaultConnector The vault connector to use.\n\t * @param config The configuration to use.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @returns The seed bytes.\n\t * @internal\n\t */\n\tprivate static async getSeed(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: Pick<IIotaConfig, \"vaultMnemonicId\" | \"vaultSeedId\">,\n\t\tidentity: string\n\t): Promise<Uint8Array> {\n\t\tconst seedKey = Iota.buildSeedKey(identity, config.vaultSeedId);\n\n\t\ttry {\n\t\t\tconst seedBase64 = await vaultConnector.getSecret<string>(seedKey);\n\t\t\treturn Converter.base64ToBytes(seedBase64);\n\t\t} catch {}\n\n\t\tconst mnemonic = await vaultConnector.getSecret<string>(\n\t\t\tIota.buildMnemonicKey(identity, config.vaultMnemonicId)\n\t\t);\n\n\t\t// If the seed is not found but the mnemonic exists, derive the seed and store it for future use\n\t\tconst seed = Bip39.mnemonicToSeed(mnemonic);\n\t\tawait vaultConnector.setSecret(seedKey, Converter.bytesToBase64(seed));\n\n\t\treturn seed;\n\t}\n\n\t/**\n\t * Get the key for storing the mnemonic.\n\t * @param identity The identity to use.\n\t * @param vaultMnemonicId The mnemonic ID to use.\n\t * @returns The mnemonic key.\n\t * @internal\n\t */\n\tprivate static buildMnemonicKey(identity: string, vaultMnemonicId?: string): string {\n\t\treturn VaultConnectorHelper.buildKeyName(\n\t\t\tidentity,\n\t\t\tvaultMnemonicId ?? Iota.DEFAULT_MNEMONIC_SECRET_NAME\n\t\t);\n\t}\n\n\t/**\n\t * Get the key for storing the seed.\n\t * @param identity The identity to use.\n\t * @param vaultSeedId The seed ID to use.\n\t * @returns The seed key.\n\t * @internal\n\t */\n\tprivate static buildSeedKey(identity: string, vaultSeedId?: string): string {\n\t\treturn VaultConnectorHelper.buildKeyName(\n\t\t\tidentity,\n\t\t\tvaultSeedId ?? Iota.DEFAULT_SEED_SECRET_NAME\n\t\t);\n\t}\n\n\t/**\n\t * Ensure a range of BIP44-derived keys are registered as individual vault keys and return their public keys.\n\t * If the first key of the range already exists the range is considered registered and only public keys are derived.\n\t * If not registered, all keys are derived and added to the vault before returning the public keys.\n\t * @param vaultConnector The vault connector to use.\n\t * @param config The configuration to use.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param accountIndex The account index.\n\t * @param internal Whether the addresses are internal or external.\n\t * @param addressIndex Any address index within the desired chunk; aligned internally.\n\t * @param seedProvider Callback invoked at most once per call to supply the seed when a chunk is not yet registered.\n\t * @returns The base64-encoded public keys for each address in the range.\n\t * @internal\n\t */\n\tprivate static async getPublicKeys(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: Pick<IIotaConfig, \"coinType\">,\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\tinternal: boolean,\n\t\taddressIndex: number,\n\t\tseedProvider: () => Promise<Uint8Array>\n\t): Promise<string[]> {\n\t\tconst chunkStart = addressIndex - (addressIndex % Iota._PRE_CALC_CHUNK_SIZE);\n\t\tconst firstKeyName = Iota.buildAddressKeyName(identity, accountIndex, internal, chunkStart);\n\t\tconst publicKeys: string[] = [];\n\n\t\tif (await vaultConnector.keyExists(firstKeyName)) {\n\t\t\tfor (let i = chunkStart; i < chunkStart + Iota._PRE_CALC_CHUNK_SIZE; i++) {\n\t\t\t\tconst keyName = Iota.buildAddressKeyName(identity, accountIndex, internal, i);\n\t\t\t\tconst keyData = await vaultConnector.getKey(keyName, \"public\");\n\t\t\t\tif (!keyData.publicKey) {\n\t\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"missingPublicKey\", { keyName });\n\t\t\t\t}\n\t\t\t\tpublicKeys.push(Converter.bytesToBase64(keyData.publicKey));\n\t\t\t}\n\t\t} else {\n\t\t\tconst seed = await seedProvider();\n\t\t\tconst coinType = config.coinType ?? Iota.DEFAULT_COIN_TYPE;\n\n\t\t\tfor (let i = chunkStart; i < chunkStart + Iota._PRE_CALC_CHUNK_SIZE; i++) {\n\t\t\t\tconst keyName = Iota.buildAddressKeyName(identity, accountIndex, internal, i);\n\t\t\t\tconst keyPair = Bip44.keyPair(seed, KeyType.Ed25519, coinType, accountIndex, internal, i);\n\t\t\t\tawait vaultConnector.addKey(\n\t\t\t\t\tkeyName,\n\t\t\t\t\tVaultKeyType.Ed25519,\n\t\t\t\t\tkeyPair.privateKey,\n\t\t\t\t\tkeyPair.publicKey\n\t\t\t\t);\n\t\t\t\tpublicKeys.push(Converter.bytesToBase64(keyPair.publicKey));\n\t\t\t}\n\t\t}\n\n\t\treturn publicKeys;\n\t}\n\n\t/**\n\t * Build the vault key name for a specific derived address.\n\t * @param identity The identity to use.\n\t * @param accountIndex The account index.\n\t * @param internal Whether the address is internal or external.\n\t * @param addressIndex The address index.\n\t * @returns The vault key name.\n\t * @internal\n\t */\n\tprivate static buildAddressKeyName(\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\tinternal: boolean,\n\t\taddressIndex: number\n\t): string {\n\t\treturn VaultConnectorHelper.buildKeyName(\n\t\t\tidentity,\n\t\t\t\"account\",\n\t\t\taccountIndex.toString(),\n\t\t\tinternal ? \"1\" : \"0\",\n\t\t\t`${addressIndex}`\n\t\t);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"iota.js","sourceRoot":"","sources":["../../src/iota.ts"],"names":[],"mappings":"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","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport { IotaClient } from \"@iota/iota-sdk/client\";\nimport { requestIotaFromFaucetV0 } from \"@iota/iota-sdk/faucet\";\nimport { Transaction } from \"@iota/iota-sdk/transactions\";\nimport {\n\tBaseError,\n\tCoerce,\n\tConverter,\n\tGeneralError,\n\tGuards,\n\tIs,\n\tStringHelper,\n\ttype IError\n} from \"@twin.org/core\";\nimport { Bip39, Bip44, Blake2b, KeyType } from \"@twin.org/crypto\";\nimport type { ILoggingComponent } from \"@twin.org/logging-models\";\nimport { nameof } from \"@twin.org/nameof\";\nimport { VaultConnectorHelper, VaultKeyType } from \"@twin.org/vault-models\";\nimport type { IVaultConnector } from \"@twin.org/vault-models\";\nimport { FetchHelper, HttpMethod } from \"@twin.org/web\";\nimport type { IGasReservationResult } from \"./models/IGasReservationResult.js\";\nimport type { IGasStationConfig } from \"./models/IGasStationConfig.js\";\nimport type { IGasStationExecuteResponse } from \"./models/IGasStationExecuteResponse.js\";\nimport type { IGasStationReserveGasResponse } from \"./models/IGasStationReserveGasResponse.js\";\nimport type { IIotaClient } from \"./models/IIotaClient.js\";\nimport type { IIotaConfig } from \"./models/IIotaConfig.js\";\nimport type { IIotaDryRun } from \"./models/IIotaDryRun.js\";\nimport type { IIotaResponseOptions } from \"./models/IIotaResponseOptions.js\";\nimport type { IIotaTransaction } from \"./models/IIotaTransaction.js\";\nimport type { IIotaTransactionBlockResponse } from \"./models/IIotaTransactionBlockResponse.js\";\nimport { VaultSigner } from \"./vaultSigner.js\";\nimport { VaultTransactionSigner } from \"./vaultTransactionSigner.js\";\n\n/**\n * Class for performing operations on IOTA.\n */\nexport class Iota {\n\t/**\n\t * Default name for the mnemonic secret.\n\t */\n\tpublic static readonly DEFAULT_MNEMONIC_SECRET_NAME: string = \"mnemonic\";\n\n\t/**\n\t * Default name for the seed secret.\n\t */\n\tpublic static readonly DEFAULT_SEED_SECRET_NAME: string = \"seed\";\n\n\t/**\n\t * Default coin type.\n\t */\n\tpublic static readonly DEFAULT_COIN_TYPE: number = 4218;\n\n\t/**\n\t * Runtime name for the class.\n\t */\n\tpublic static readonly CLASS_NAME: string = nameof<Iota>();\n\n\t/**\n\t * Default scan range.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_SCAN_RANGE: number = 1000;\n\n\t/**\n\t * Default pre-calculation chunk size.\n\t * @internal\n\t */\n\tprivate static readonly _PRE_CALC_CHUNK_SIZE: number = 25;\n\n\t/**\n\t * Default inclusion timeout.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_INCLUSION_TIMEOUT: number = 60;\n\n\t/**\n\t * Default gas budget for all transactions (including sponsored and direct).\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_GAS_BUDGET: number = 50000000;\n\n\t/**\n\t * Default gas reservation duration.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_GAS_RESERVATION_DURATION: number = 60;\n\n\t/**\n\t * Default number of retries when owned objects are reserved by another transaction.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_OBJECT_LOCK_RETRIES: number = 3;\n\n\t/**\n\t * Default base delay in milliseconds between object-lock retries.\n\t * @internal\n\t */\n\tprivate static readonly _DEFAULT_OBJECT_LOCK_RETRY_DELAY_MS: number = 1000;\n\n\t/**\n\t * Pattern that identifies the retryable \"objects reserved by another transaction\" node error.\n\t * @internal\n\t */\n\tprivate static readonly _RESERVED_OBJECT_ERROR_PATTERN: RegExp =\n\t\t/reserved for another transaction/;\n\n\t/**\n\t * Pattern that identifies the node error for an owned-object version that was consumed by a\n\t * concurrent transaction. Retryable since the retry rebuild re-resolves to the current version.\n\t * @internal\n\t */\n\tprivate static readonly _STALE_OBJECT_ERROR_PATTERN: RegExp = /is not available for consumption/;\n\n\t/**\n\t * Create a new IOTA client.\n\t * @param config The configuration.\n\t * @returns The client instance.\n\t */\n\tpublic static createClient(config: IIotaConfig): IIotaClient {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config.clientOptions), config.clientOptions);\n\t\tGuards.string(Iota.CLASS_NAME, nameof(config.clientOptions.url), config.clientOptions.url);\n\n\t\treturn new IotaClient(config.clientOptions);\n\t}\n\n\t/**\n\t * Create configuration using defaults where necessary.\n\t * @param config The configuration to populate.\n\t */\n\tpublic static populateConfig(config: IIotaConfig): void {\n\t\tGuards.object<IIotaConfig[\"clientOptions\"]>(\n\t\t\tIota.CLASS_NAME,\n\t\t\tnameof(config.clientOptions),\n\t\t\tconfig.clientOptions\n\t\t);\n\n\t\tconfig.vaultMnemonicId ??= Iota.DEFAULT_MNEMONIC_SECRET_NAME;\n\t\tconfig.vaultSeedId ??= Iota.DEFAULT_SEED_SECRET_NAME;\n\t\tconfig.coinType ??= Iota.DEFAULT_COIN_TYPE;\n\t\tconfig.inclusionTimeoutSeconds ??= Iota._DEFAULT_INCLUSION_TIMEOUT;\n\t}\n\n\t/**\n\t * Store a mnemonic in the vault, derive and store the seed, and pre-cache the first keypair chunk.\n\t * @param vaultConnector The vault connector.\n\t * @param config The configuration.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param mnemonic The mnemonic to store, if undefined a new one will be generated and returned.\n\t * @param accountIndex The account index to pre-cache.\n\t * @returns The mnemonic that was stored.\n\t */\n\tpublic static async storeMnemonic(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: IIotaConfig,\n\t\tidentity: string,\n\t\tmnemonic: string | undefined,\n\t\taccountIndex: number\n\t): Promise<string> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(vaultConnector), vaultConnector);\n\t\tGuards.object<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(accountIndex), accountIndex);\n\n\t\tconst mnemonicToStore = mnemonic ?? Bip39.randomMnemonic();\n\n\t\tawait vaultConnector.setSecret(\n\t\t\tIota.buildMnemonicKey(identity, config.vaultMnemonicId),\n\t\t\tmnemonicToStore\n\t\t);\n\n\t\tconst seed = Bip39.mnemonicToSeed(mnemonicToStore);\n\t\tawait vaultConnector.setSecret(\n\t\t\tIota.buildSeedKey(identity, config.vaultSeedId),\n\t\t\tConverter.bytesToBase64(seed)\n\t\t);\n\n\t\tawait Iota.getPublicKeys(\n\t\t\tvaultConnector,\n\t\t\tconfig,\n\t\t\tidentity,\n\t\t\taccountIndex,\n\t\t\tfalse,\n\t\t\t0,\n\t\t\tasync () => seed\n\t\t);\n\n\t\treturn mnemonicToStore;\n\t}\n\n\t/**\n\t * Derive an address from a public key.\n\t * @param publicKey The public key to derive the address from.\n\t * @returns The derived address.\n\t */\n\tpublic static publicKeyToAddress(publicKey: Uint8Array): string {\n\t\treturn Converter.bytesToHex(Blake2b.sum256(publicKey), true);\n\t}\n\n\t/**\n\t * Get address for the identity.\n\t * @param vaultConnector The vault connector.\n\t * @param config The configuration.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param accountIndex The account index to get the addresses for.\n\t * @param startAddressIndex The start index for the addresses.\n\t * @param isInternal Whether the addresses are internal.\n\t * @returns The address.\n\t */\n\tpublic static async getAddress(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: Pick<IIotaConfig, \"coinType\" | \"vaultMnemonicId\" | \"vaultSeedId\">,\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\tstartAddressIndex: number,\n\t\tisInternal?: boolean\n\t): Promise<string> {\n\t\tconst addresses = await Iota.getAddresses(\n\t\t\tvaultConnector,\n\t\t\tconfig,\n\t\t\tidentity,\n\t\t\taccountIndex,\n\t\t\tstartAddressIndex,\n\t\t\t1,\n\t\t\tisInternal\n\t\t);\n\t\treturn addresses[0];\n\t}\n\n\t/**\n\t * Get addresses for the identity.\n\t * @param vaultConnector The vault connector.\n\t * @param config The configuration.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param accountIndex The account index to get the addresses for.\n\t * @param startAddressIndex The start index for the addresses.\n\t * @param count The number of addresses to generate.\n\t * @param isInternal Whether the addresses are internal.\n\t * @returns The list of addresses.\n\t */\n\tpublic static async getAddresses(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: Pick<IIotaConfig, \"coinType\" | \"vaultMnemonicId\" | \"vaultSeedId\">,\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\tstartAddressIndex: number,\n\t\tcount: number,\n\t\tisInternal?: boolean\n\t): Promise<string[]> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(vaultConnector), vaultConnector);\n\t\tGuards.object<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(accountIndex), accountIndex);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(startAddressIndex), startAddressIndex);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(count), count);\n\n\t\tconst addresses: string[] = [];\n\t\tconst internal = isInternal ?? false;\n\t\tlet currentIndex = startAddressIndex;\n\t\tlet cachedSeed: Uint8Array | undefined;\n\t\tconst seedProvider = async (): Promise<Uint8Array> => {\n\t\t\tcachedSeed ??= await Iota.getSeed(vaultConnector, config, identity);\n\t\t\treturn cachedSeed;\n\t\t};\n\n\t\twhile (addresses.length < count) {\n\t\t\tconst chunkStart =\n\t\t\t\tMath.floor(currentIndex / Iota._PRE_CALC_CHUNK_SIZE) * Iota._PRE_CALC_CHUNK_SIZE;\n\t\t\tconst publicKeys = await Iota.getPublicKeys(\n\t\t\t\tvaultConnector,\n\t\t\t\tconfig,\n\t\t\t\tidentity,\n\t\t\t\taccountIndex,\n\t\t\t\tinternal,\n\t\t\t\tchunkStart,\n\t\t\t\tseedProvider\n\t\t\t);\n\t\t\tconst chunk = publicKeys.map((pk: string) =>\n\t\t\t\tIota.publicKeyToAddress(Converter.base64ToBytes(pk))\n\t\t\t);\n\t\t\tconst offsetInChunk = currentIndex - chunkStart;\n\t\t\tconst remaining = count - addresses.length;\n\t\t\taddresses.push(...chunk.slice(offsetInChunk, offsetInChunk + remaining));\n\t\t\tcurrentIndex = chunkStart + Iota._PRE_CALC_CHUNK_SIZE;\n\t\t}\n\n\t\treturn addresses;\n\t}\n\n\t/**\n\t * Get a vault-backed transaction signer for the given identity and key indices.\n\t * @param vaultConnector The vault connector.\n\t * @param config The configuration.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param accountIndex The account index.\n\t * @param addressIndex The address index within the account.\n\t * @returns A VaultTransactionSigner for the specified key.\n\t */\n\tpublic static async getTransactionSigner(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: IIotaConfig,\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\taddressIndex: number\n\t): Promise<VaultTransactionSigner> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(vaultConnector), vaultConnector);\n\t\tGuards.object<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(accountIndex), accountIndex);\n\t\tGuards.integer(Iota.CLASS_NAME, nameof(addressIndex), addressIndex);\n\n\t\tconst publicKeys = await Iota.getPublicKeys(\n\t\t\tvaultConnector,\n\t\t\tconfig,\n\t\t\tidentity,\n\t\t\taccountIndex,\n\t\t\tfalse,\n\t\t\taddressIndex,\n\t\t\tasync () => Iota.getSeed(vaultConnector, config, identity)\n\t\t);\n\n\t\tconst chunkStart = addressIndex - (addressIndex % Iota._PRE_CALC_CHUNK_SIZE);\n\t\tconst offsetInChunk = addressIndex - chunkStart;\n\t\tconst publicKey = Converter.base64ToBytes(publicKeys[offsetInChunk]);\n\t\tconst keyName = Iota.buildAddressKeyName(identity, accountIndex, false, addressIndex);\n\n\t\treturn new VaultTransactionSigner(vaultConnector, keyName, publicKey);\n\t}\n\n\t/**\n\t * Create a new transaction instance.\n\t * @returns A new transaction instance.\n\t */\n\tpublic static createTransaction(): IIotaTransaction {\n\t\treturn new Transaction();\n\t}\n\n\t/**\n\t * Prepare and post a transaction.\n\t * @param config The configuration.\n\t * @param vaultConnector The vault connector.\n\t * @param logging The logging component.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param client The client instance.\n\t * @param source The source address.\n\t * @param amount The amount to transfer.\n\t * @param recipient The recipient address.\n\t * @param options The transaction options.\n\t * @returns The transaction result.\n\t */\n\tpublic static async prepareAndPostValueTransaction(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tlogging: ILoggingComponent | undefined,\n\t\tidentity: string,\n\t\tclient: IIotaClient,\n\t\tsource: string,\n\t\tamount: bigint,\n\t\trecipient: string,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\ttry {\n\t\t\tconst txb = new Transaction();\n\t\t\tconst [coin] = txb.splitCoins(txb.gas, [txb.pure.u64(amount)]);\n\t\t\ttxb.transferObjects([coin], txb.pure.address(recipient));\n\n\t\t\t// Check if gas station configuration is present\n\t\t\tif (Is.object<IGasStationConfig>(config.gasStation)) {\n\t\t\t\treturn await Iota.prepareAndPostGasStationTransaction(\n\t\t\t\t\tconfig,\n\t\t\t\t\tvaultConnector,\n\t\t\t\t\tidentity,\n\t\t\t\t\tclient,\n\t\t\t\t\tsource,\n\t\t\t\t\ttxb\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tconst result = await Iota.prepareAndPostTransaction(\n\t\t\t\tconfig,\n\t\t\t\tvaultConnector,\n\t\t\t\tlogging,\n\t\t\t\tidentity,\n\t\t\t\tclient,\n\t\t\t\tsource,\n\t\t\t\ttxb,\n\t\t\t\toptions\n\t\t\t);\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\t// Pass through the clear object-conflict error; wrap everything else as before.\n\t\t\tif (Iota.isRetryableObjectConflictError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"valueTransactionFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Prepare and post a transaction.\n\t * @param config The configuration.\n\t * @param vaultConnector The vault connector.\n\t * @param logging The logging component.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param client The client instance.\n\t * @param owner The owner of the address.\n\t * @param transaction The transaction to execute.\n\t * @param options The transaction options.\n\t * @returns The transaction response.\n\t */\n\tpublic static async prepareAndPostTransaction(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tlogging: ILoggingComponent | undefined,\n\t\tidentity: string,\n\t\tclient: IIotaClient,\n\t\towner: string,\n\t\ttransaction: IIotaTransaction,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\t// Check if gas station configuration is present\n\t\tif (Is.object<IGasStationConfig>(config.gasStation)) {\n\t\t\treturn Iota.prepareAndPostGasStationTransaction(\n\t\t\t\tconfig,\n\t\t\t\tvaultConnector,\n\t\t\t\tidentity,\n\t\t\t\tclient,\n\t\t\t\towner,\n\t\t\t\ttransaction,\n\t\t\t\toptions\n\t\t\t);\n\t\t}\n\n\t\t// Traditional transaction flow\n\t\t// Capture the transaction while its inputs are still unresolved. The SDK pins owned-object\n\t\t// versions and gas payment on the first build, so a single built transaction would resubmit\n\t\t// byte-identical bytes on every retry. Cloning this template per attempt lets object\n\t\t// versions and gas re-resolve, which is what allows a retry to actually recover once the\n\t\t// conflicting transaction clears.\n\t\tconst template = Transaction.from(transaction);\n\n\t\t// Dry run the transaction if cost logging is enabled to get the gas and storage costs\n\t\tif (Is.stringValue(options?.dryRunLabel)) {\n\t\t\tawait Iota.dryRunTransaction(client, logging, transaction, owner, options.dryRunLabel);\n\t\t}\n\n\t\tconst { keyName, publicKey } = await Iota.ensureOwnerKey(\n\t\t\tvaultConnector,\n\t\t\tconfig,\n\t\t\tidentity,\n\t\t\towner\n\t\t);\n\t\tconst signer = new VaultSigner(vaultConnector, keyName, publicKey);\n\n\t\ttry {\n\t\t\t// Concurrent transactions that reference the same owned objects can be rejected while\n\t\t\t// those objects are reserved for another in-flight transaction, so retry the submission\n\t\t\t// with back-off until the reservation clears. Each attempt rebuilds from the unresolved\n\t\t\t// template so versions and gas re-resolve rather than resubmitting identical bytes.\n\t\t\treturn await Iota.executeWithReservationRetry(config, async () => {\n\t\t\t\tconst response = await client.signAndExecuteTransaction({\n\t\t\t\t\ttransaction: Transaction.from(template),\n\t\t\t\t\tsigner,\n\t\t\t\t\trequestType: \"WaitForLocalExecution\",\n\t\t\t\t\toptions: {\n\t\t\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tif (options?.waitForConfirmation ?? true) {\n\t\t\t\t\t// Wait for transaction to be indexed and available over API\n\t\t\t\t\treturn Iota.waitForTransactionConfirmation(client, response.digest, config, {\n\t\t\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t\t\t});\n\t\t\t\t}\n\n\t\t\t\treturn response;\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t// Pass through the clear object-conflict error; wrap everything else (including any\n\t\t\t// non-conflict GeneralError raised inside, e.g. a vault signing failure) as before.\n\t\t\tif (Iota.isRetryableObjectConflictError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"transactionFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Extract error from SDK payload.\n\t * Errors from the IOTA SDK are usually not JSON strings but objects.\n\t * @param error The error to extract.\n\t * @returns The extracted error.\n\t */\n\tpublic static extractPayloadError(error: unknown): IError {\n\t\tif (Is.object<{ code?: string; message?: string; inner?: unknown; cause?: unknown }>(error)) {\n\t\t\tif (!Is.empty(error.inner)) {\n\t\t\t\terror.inner = Iota.extractPayloadError(error.inner);\n\t\t\t}\n\t\t\tif (!Is.empty(error.cause)) {\n\t\t\t\terror.cause = Iota.extractPayloadError(error.cause);\n\t\t\t}\n\n\t\t\tif (error.code === \"InsufficientGas\") {\n\t\t\t\treturn new GeneralError(Iota.CLASS_NAME, \"insufficientFunds\");\n\t\t\t} else if (error.message?.startsWith(\"ErrorObject\")) {\n\t\t\t\tconst msg = /message: \"(.*)\"/.exec(error.message);\n\t\t\t\tif (msg && msg.length > 1) {\n\t\t\t\t\terror = msg[1];\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tconst baseError = BaseError.fromError(error);\n\t\tif (baseError.name === \"Base\" && !Is.stringValue(baseError.source)) {\n\t\t\tbaseError.name = \"IOTA\";\n\t\t\tbaseError.source = Iota.CLASS_NAME;\n\t\t}\n\t\treturn baseError;\n\t}\n\n\t/**\n\t * Check if the package exists on the network.\n\t * @param client The client to use.\n\t * @param packageId The package ID to check.\n\t * @returns True if the package exists, false otherwise.\n\t */\n\tpublic static async packageExistsOnNetwork(\n\t\tclient: IIotaClient,\n\t\tpackageId: string\n\t): Promise<boolean> {\n\t\ttry {\n\t\t\tconst packageObject = await client.getObject({\n\t\t\t\tid: packageId,\n\t\t\t\toptions: {\n\t\t\t\t\tshowType: true\n\t\t\t\t}\n\t\t\t});\n\n\t\t\tif (\"error\" in packageObject) {\n\t\t\t\tif (packageObject?.error?.code === \"notExists\") {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"packageObjectError\", {\n\t\t\t\t\tpackageId,\n\t\t\t\t\terror: packageObject.error\n\t\t\t\t});\n\t\t\t}\n\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"packageNotFoundOnNetwork\",\n\t\t\t\t{\n\t\t\t\t\tpackageId\n\t\t\t\t},\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Dry run a transaction and log the results.\n\t * @param client The IOTA client.\n\t * @param logging The logging component.\n\t * @param txb The transaction to dry run.\n\t * @param sender The sender address.\n\t * @param operation The operation to log.\n\t * @returns The dry run result including status, costs, events, and object changes.\n\t */\n\tpublic static async dryRunTransaction(\n\t\tclient: IIotaClient,\n\t\tlogging: ILoggingComponent | undefined,\n\t\ttxb: IIotaTransaction,\n\t\tsender: string,\n\t\toperation: string\n\t): Promise<IIotaDryRun> {\n\t\ttry {\n\t\t\ttxb.setSender(sender);\n\n\t\t\tconst builtTx = await txb.build({\n\t\t\t\tclient,\n\t\t\t\tonlyTransactionKind: false\n\t\t\t});\n\n\t\t\tconst dryRunResult = await client.dryRunTransactionBlock({\n\t\t\t\ttransactionBlock: builtTx\n\t\t\t});\n\n\t\t\tif (dryRunResult.effects.status?.status !== \"success\") {\n\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"dryRunFailed\", {\n\t\t\t\t\terror: dryRunResult.effects?.status?.error\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tconst result = {\n\t\t\t\tstatus: dryRunResult.effects.status.status,\n\t\t\t\tcosts: {\n\t\t\t\t\tcomputationCost: dryRunResult.effects.gasUsed.computationCost,\n\t\t\t\t\tcomputationCostBurned: dryRunResult.effects.gasUsed.computationCostBurned,\n\t\t\t\t\tstorageCost: dryRunResult.effects.gasUsed.storageCost,\n\t\t\t\t\tstorageRebate: dryRunResult.effects.gasUsed.storageRebate,\n\t\t\t\t\tnonRefundableStorageFee: dryRunResult.effects.gasUsed.nonRefundableStorageFee\n\t\t\t\t},\n\t\t\t\tevents: dryRunResult.events ?? [],\n\t\t\t\tbalanceChanges: dryRunResult.balanceChanges ?? [],\n\t\t\t\tobjectChanges: dryRunResult.objectChanges ?? []\n\t\t\t};\n\n\t\t\tawait logging?.log({\n\t\t\t\tlevel: \"info\",\n\t\t\t\tsource: Iota.CLASS_NAME,\n\t\t\t\tts: Date.now(),\n\t\t\t\tmessage: \"transactionCosts\",\n\t\t\t\tdata: {\n\t\t\t\t\toperation,\n\t\t\t\t\tcost: JSON.stringify(result)\n\t\t\t\t}\n\t\t\t});\n\n\t\t\treturn result;\n\t\t} catch (error) {\n\t\t\tif (BaseError.isErrorName(error, GeneralError.CLASS_NAME)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"dryRunFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Wait for a transaction to be indexed and available over the API.\n\t * @param client The IOTA client instance.\n\t * @param digest The digest of the transaction to wait for.\n\t * @param config The IOTA configuration.\n\t * @param options Additional options for the transaction query.\n\t * @param options.showEffects Whether to show effects.\n\t * @param options.showEvents Whether to show events.\n\t * @param options.showObjectChanges Whether to show object changes.\n\t * @returns The confirmed transaction response.\n\t */\n\tpublic static async waitForTransactionConfirmation(\n\t\tclient: IIotaClient,\n\t\tdigest: string,\n\t\tconfig: IIotaConfig,\n\t\toptions?: {\n\t\t\tshowEffects?: boolean;\n\t\t\tshowEvents?: boolean;\n\t\t\tshowObjectChanges?: boolean;\n\t\t}\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\tconst timeoutMs = (config.inclusionTimeoutSeconds ?? Iota._DEFAULT_INCLUSION_TIMEOUT) * 1000;\n\n\t\treturn client.waitForTransaction({\n\t\t\tdigest,\n\t\t\ttimeout: timeoutMs,\n\t\t\toptions: {\n\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t}\n\t\t});\n\t}\n\n\t/**\n\t * Check if the error is an abort error with a specific code.\n\t * @param error The error to check.\n\t * @param code The error code to check for.\n\t * @returns True if the error is an abort error, false otherwise.\n\t */\n\tpublic static isAbortError(error: unknown, code: number): boolean {\n\t\tconst err = BaseError.fromError(error);\n\t\tif (Is.stringValue(err.properties?.error)) {\n\t\t\tconst abortCodeMatch = /abort code\\s*:\\s*(\\d+)/i.exec(err.properties.error);\n\t\t\treturn abortCodeMatch?.[1] === code.toString();\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t * Extracts the abort code from a transaction result if the transaction was aborted.\n\t * @param response The transaction result to extract the abort code from.\n\t * @returns The abort code if the transaction was aborted, or undefined if it was not an abort error or the code could not be extracted.\n\t */\n\tpublic static extractAbortCode(response: IIotaTransactionBlockResponse): number | undefined {\n\t\tif (\n\t\t\tresponse.effects?.status?.status === \"failure\" &&\n\t\t\tIs.stringValue(response.effects.status.error)\n\t\t) {\n\t\t\tconst match = /abort code: (\\d+)/.exec(response.effects.status.error);\n\t\t\tif (match) {\n\t\t\t\treturn Coerce.integer(match[1]);\n\t\t\t}\n\t\t}\n\t}\n\n\t/**\n\t * Check if an error is a retryable \"owned object reserved by another transaction\" conflict.\n\t * IOTA locks owned objects for the first in-flight transaction that claims them, so a\n\t * concurrent transaction referencing the same objects is rejected until the lock clears. This\n\t * only matches the transient \"reserved for another transaction\" case, not the non-retryable\n\t * \"equivocated until the next epoch\" case.\n\t * @param error The error to check.\n\t * @returns True if the error is a retryable object reservation conflict.\n\t */\n\tpublic static isReservedObjectError(error: unknown): boolean {\n\t\treturn Is.stringValue(Iota.objectConflictMessage(error, Iota._RESERVED_OBJECT_ERROR_PATTERN));\n\t}\n\n\t/**\n\t * Check if an error is a retryable owned-object conflict caused by a concurrent transaction.\n\t * This covers both the \"reserved for another transaction\" case (the object is locked by an\n\t * in-flight transaction) and the \"is not available for consumption\" case (a concurrent\n\t * transaction already consumed the referenced version); a retry rebuild re-resolves to the\n\t * current version so both can recover. The non-retryable \"equivocated until the next epoch\"\n\t * case is not matched.\n\t * @param error The error to check.\n\t * @returns True if the error is a retryable owned-object conflict.\n\t */\n\tpublic static isRetryableObjectConflictError(error: unknown): boolean {\n\t\treturn (\n\t\t\tIs.stringValue(Iota.objectConflictMessage(error, Iota._RESERVED_OBJECT_ERROR_PATTERN)) ||\n\t\t\tIs.stringValue(Iota.objectConflictMessage(error, Iota._STALE_OBJECT_ERROR_PATTERN))\n\t\t);\n\t}\n\n\t/**\n\t * Extract the conflicting transaction digests from an object reservation conflict error.\n\t * The node error lists the digests of the transactions currently locking the objects (the\n\t * underlying object ids are only present in the RPC error data, which the IOTA SDK discards).\n\t * Only the \"reserved for another transaction\" error carries digests, so this returns an empty\n\t * array for the stale-version conflict case.\n\t * @param error The error to extract from.\n\t * @returns The conflicting transaction digests, or an empty array if none can be parsed.\n\t */\n\tpublic static extractReservationConflictDigests(error: unknown): string[] {\n\t\tconst message = Iota.objectConflictMessage(error, Iota._RESERVED_OBJECT_ERROR_PATTERN);\n\t\tif (!Is.stringValue(message)) {\n\t\t\treturn [];\n\t\t}\n\n\t\tconst digests: string[] = [];\n\t\t// The direct path preserves real newlines; through the gas station the node message is\n\t\t// Debug-formatted so the newlines arrive as the literal two-character sequence \"\\n\", hence\n\t\t// both a real newline and an escaped one are treated as a line start here.\n\t\tconst linePattern = /(?:^|\\n|\\\\n)- (\\S+) \\(stake /g;\n\t\tlet match = linePattern.exec(message);\n\t\twhile (match !== null) {\n\t\t\tdigests.push(match[1]);\n\t\t\tmatch = linePattern.exec(message);\n\t\t}\n\t\treturn digests;\n\t}\n\n\t/**\n\t * Run a transaction submission operation, retrying with exponential back-off if it is rejected\n\t * because of a retryable owned-object conflict with a concurrent transaction (the objects are\n\t * reserved by an in-flight transaction, or the referenced version was already consumed).\n\t * Other errors are rethrown immediately. If the conflict persists after all retries a clear,\n\t * retryable error is thrown instead of the opaque underlying failure.\n\t * @param config The configuration controlling retry counts and delays.\n\t * @param operation The transaction submission operation to run.\n\t * @returns The result of the operation.\n\t */\n\tpublic static async executeWithReservationRetry<T>(\n\t\tconfig: IIotaConfig,\n\t\toperation: () => Promise<T>\n\t): Promise<T> {\n\t\tif (!Is.undefined(config.objectLockRetries)) {\n\t\t\tGuards.integer(Iota.CLASS_NAME, nameof(config.objectLockRetries), config.objectLockRetries);\n\t\t}\n\t\tif (!Is.undefined(config.objectLockRetryDelayMs)) {\n\t\t\tGuards.integer(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\tnameof(config.objectLockRetryDelayMs),\n\t\t\t\tconfig.objectLockRetryDelayMs\n\t\t\t);\n\t\t}\n\t\tconst maxRetries = Math.max(0, config.objectLockRetries ?? Iota._DEFAULT_OBJECT_LOCK_RETRIES);\n\t\tconst baseDelayMs = Math.max(\n\t\t\t0,\n\t\t\tconfig.objectLockRetryDelayMs ?? Iota._DEFAULT_OBJECT_LOCK_RETRY_DELAY_MS\n\t\t);\n\n\t\tlet lastError: unknown;\n\t\tfor (let attempt = 0; attempt <= maxRetries; attempt++) {\n\t\t\ttry {\n\t\t\t\treturn await operation();\n\t\t\t} catch (error) {\n\t\t\t\tif (!Iota.isRetryableObjectConflictError(error)) {\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tlastError = error;\n\t\t\t\tif (attempt < maxRetries) {\n\t\t\t\t\t// Exponential back-off with jitter: concurrent losers fail at nearly the same moment,\n\t\t\t\t\t// so without jitter they would resubmit in lockstep and re-race each other each round.\n\t\t\t\t\tconst jitter = (1 + Math.random()) / 2;\n\t\t\t\t\tconst delayMs = baseDelayMs * Math.pow(2, attempt) * jitter;\n\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, delayMs));\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrow new GeneralError(\n\t\t\tIota.CLASS_NAME,\n\t\t\t\"objectReservationConflict\",\n\t\t\t{ conflictingTransactions: Iota.extractReservationConflictDigests(lastError) },\n\t\t\tIota.extractPayloadError(lastError)\n\t\t);\n\t}\n\n\t/**\n\t * Prepare and post a transaction using gas station sponsoring.\n\t * @param config The configuration.\n\t * @param vaultConnector The vault connector.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param client The client instance.\n\t * @param owner The owner of the address.\n\t * @param transaction The transaction to execute.\n\t * @param options Response options including confirmation behavior.\n\t * @returns The transaction response.\n\t */\n\tpublic static async prepareAndPostGasStationTransaction(\n\t\tconfig: IIotaConfig,\n\t\tvaultConnector: IVaultConnector,\n\t\tidentity: string,\n\t\tclient: IIotaClient,\n\t\towner: string,\n\t\ttransaction: IIotaTransaction,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\t// Capture the transaction while its inputs are still unresolved so each retry attempt can\n\t\t// rebuild with fresh object versions (see prepareAndPostTransaction).\n\t\tconst template = Transaction.from(transaction);\n\n\t\tconst { keyName, publicKey } = await Iota.ensureOwnerKey(\n\t\t\tvaultConnector,\n\t\t\tconfig,\n\t\t\tidentity,\n\t\t\towner\n\t\t);\n\t\tconst signer = new VaultSigner(vaultConnector, keyName, publicKey);\n\n\t\ttry {\n\t\t\t// Sponsored transactions still reference the sender's owned objects, so the same\n\t\t\t// reservation conflict can occur. Retry with a fresh gas reservation and a rebuilt\n\t\t\t// transaction on each attempt (the reserved sponsor coins and object versions change).\n\t\t\treturn await Iota.executeWithReservationRetry(config, async () => {\n\t\t\t\tconst gasReservation = await Iota.reserveGas(config);\n\n\t\t\t\t// Rebuild and set the sponsoring parameters for this attempt.\n\t\t\t\tconst attemptTransaction = Transaction.from(template);\n\t\t\t\tattemptTransaction.setSender(owner);\n\t\t\t\tattemptTransaction.setGasOwner(gasReservation.sponsorAddress);\n\t\t\t\tattemptTransaction.setGasPayment(gasReservation.gasCoins);\n\t\t\t\tattemptTransaction.setGasBudget(config.gasBudget ?? Iota._DEFAULT_GAS_BUDGET);\n\n\t\t\t\tconst unsignedTxBytes = await attemptTransaction.build({ client });\n\t\t\t\tconst signature = await signer.signTransaction(unsignedTxBytes);\n\n\t\t\t\treturn Iota.executeAndConfirmGasStationTransaction(\n\t\t\t\t\tconfig,\n\t\t\t\t\tclient,\n\t\t\t\t\tgasReservation.reservationId,\n\t\t\t\t\tunsignedTxBytes,\n\t\t\t\t\tsignature.signature,\n\t\t\t\t\toptions\n\t\t\t\t);\n\t\t\t});\n\t\t} catch (error) {\n\t\t\t// Pass through the clear object-conflict error; wrap everything else as before.\n\t\t\tif (Iota.isRetryableObjectConflictError(error)) {\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"gasStationTransactionFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\t}\n\n\t/**\n\t * Reserve gas from the gas station.\n\t * @param config The configuration containing gas station settings.\n\t * @returns The gas reservation result.\n\t */\n\tpublic static async reserveGas(config: IIotaConfig): Promise<IGasReservationResult> {\n\t\tGuards.object(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\tconst requestData = {\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tgas_budget: config.gasBudget ?? Iota._DEFAULT_GAS_BUDGET,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\treserve_duration_secs: config.gasReservationDuration ?? Iota._DEFAULT_GAS_RESERVATION_DURATION\n\t\t};\n\n\t\tconst baseUrl = StringHelper.trimTrailingSlashes(config.gasStation.gasStationUrl);\n\t\tconst result = await FetchHelper.fetchJson<typeof requestData, IGasStationReserveGasResponse>(\n\t\t\tIota.CLASS_NAME,\n\t\t\t`${baseUrl}/v1/reserve_gas`,\n\t\t\tHttpMethod.POST,\n\t\t\trequestData,\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.gasStation.gasStationAuthToken}`\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\n\t\tconst apiResponse = result.result;\n\n\t\treturn {\n\t\t\tsponsorAddress: apiResponse.sponsor_address,\n\t\t\treservationId: apiResponse.reservation_id,\n\t\t\tgasCoins: apiResponse.gas_coins\n\t\t};\n\t}\n\n\t/**\n\t * Execute a sponsored transaction through the gas station.\n\t * @param config The configuration containing gas station settings.\n\t * @param reservationId The reservation ID from gas reservation.\n\t * @param transactionBytes The unsigned transaction bytes.\n\t * @param userSignature The user's signature.\n\t * @returns The transaction response.\n\t */\n\tpublic static async executeGasStationTransaction(\n\t\tconfig: IIotaConfig,\n\t\treservationId: number,\n\t\ttransactionBytes: Uint8Array,\n\t\tuserSignature: string\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\tGuards.object<IGasStationConfig>(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\tconst requestData = {\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\treservation_id: reservationId,\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\ttx_bytes: Converter.bytesToBase64(transactionBytes),\n\t\t\t// eslint-disable-next-line camelcase\n\t\t\tuser_sig: userSignature\n\t\t};\n\n\t\tconst baseUrl = StringHelper.trimTrailingSlashes(config.gasStation.gasStationUrl);\n\t\tconst result = await FetchHelper.fetchJson<typeof requestData, IGasStationExecuteResponse>(\n\t\t\tIota.CLASS_NAME,\n\t\t\t`${baseUrl}/v1/execute_tx`,\n\t\t\tHttpMethod.POST,\n\t\t\trequestData,\n\t\t\t{\n\t\t\t\theaders: {\n\t\t\t\t\tAuthorization: `Bearer ${config.gasStation.gasStationAuthToken}`\n\t\t\t\t}\n\t\t\t}\n\t\t);\n\n\t\tconst effectsData = result.effects;\n\n\t\t// Match IotaTransactionBlockResponse format\n\t\treturn {\n\t\t\tdigest: effectsData.transactionDigest,\n\t\t\teffects: effectsData as unknown,\n\t\t\tevents: [],\n\t\t\tobjectChanges: [],\n\t\t\tconfirmedLocalExecution: true\n\t\t} as unknown as IIotaTransactionBlockResponse;\n\t}\n\n\t/**\n\t * Execute and confirm a gas station transaction.\n\t * @param config The configuration containing gas station settings.\n\t * @param client The IOTA client for confirmation.\n\t * @param reservationId The reservation ID from gas reservation.\n\t * @param transactionBytes The unsigned transaction bytes.\n\t * @param userSignature The user's signature.\n\t * @param options Response options including confirmation behavior.\n\t * @returns The transaction response (confirmed if waitForConfirmation is true).\n\t */\n\tpublic static async executeAndConfirmGasStationTransaction(\n\t\tconfig: IIotaConfig,\n\t\tclient: IIotaClient,\n\t\treservationId: number,\n\t\ttransactionBytes: Uint8Array,\n\t\tuserSignature: string,\n\t\toptions?: IIotaResponseOptions\n\t): Promise<IIotaTransactionBlockResponse> {\n\t\tGuards.object<IGasStationConfig>(Iota.CLASS_NAME, nameof(config.gasStation), config.gasStation);\n\n\t\tconst response = await Iota.executeGasStationTransaction(\n\t\t\tconfig,\n\t\t\treservationId,\n\t\t\ttransactionBytes,\n\t\t\tuserSignature\n\t\t);\n\n\t\tif (options?.waitForConfirmation ?? true) {\n\t\t\tconst confirmedTransaction = await Iota.waitForTransactionConfirmation(\n\t\t\t\tclient,\n\t\t\t\tresponse.digest,\n\t\t\t\tconfig,\n\t\t\t\t{\n\t\t\t\t\tshowEffects: options?.showEffects ?? true,\n\t\t\t\t\tshowEvents: options?.showEvents ?? true,\n\t\t\t\t\tshowObjectChanges: options?.showObjectChanges ?? true\n\t\t\t\t}\n\t\t\t);\n\n\t\t\treturn confirmedTransaction;\n\t\t}\n\n\t\treturn response;\n\t}\n\n\t/**\n\t * Fund an address with IOTA from the faucet.\n\t * @param config The configuration containing endpoint information.\n\t * @param faucetUrl The URL of the faucet to request funds from.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param address The address to fund.\n\t * @param timeoutInSeconds The timeout in seconds to wait for the funding to complete.\n\t * @returns The amount funded.\n\t */\n\tpublic static async fundAddress(\n\t\tconfig: IIotaConfig,\n\t\tfaucetUrl: string,\n\t\tidentity: string,\n\t\taddress: string,\n\t\ttimeoutInSeconds: number = 60\n\t): Promise<bigint> {\n\t\tGuards.objectValue<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(config.clientOptions.url), config.clientOptions.url);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(faucetUrl), faucetUrl);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(address), address);\n\n\t\ttry {\n\t\t\tconst initialBalance = await Iota.getBalance(config, address);\n\n\t\t\tconst response = await requestIotaFromFaucetV0({\n\t\t\t\thost: faucetUrl,\n\t\t\t\trecipient: address\n\t\t\t});\n\n\t\t\tif (response?.error) {\n\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"fundingFailed\", undefined, response.error);\n\t\t\t}\n\n\t\t\t// Poll for balance change\n\t\t\tconst numTries = Math.ceil(timeoutInSeconds / 5);\n\t\t\tfor (let i = 0; i < numTries; i++) {\n\t\t\t\tconst newBalance = await Iota.getBalance(config, address);\n\n\t\t\t\tif (newBalance > initialBalance) {\n\t\t\t\t\treturn newBalance - initialBalance;\n\t\t\t\t}\n\n\t\t\t\tif (i < numTries - 1) {\n\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, 5000));\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tconst payloadError = Iota.extractPayloadError(error);\n\t\t\tif (\n\t\t\t\tpayloadError.message.includes(\n\t\t\t\t\t\"Too many requests from this client have been sent to the faucet\"\n\t\t\t\t)\n\t\t\t) {\n\t\t\t\tthrow new GeneralError(\n\t\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\t\"faucetRateLimit\",\n\t\t\t\t\tundefined,\n\t\t\t\t\tIota.extractPayloadError(error)\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow new GeneralError(\n\t\t\t\tIota.CLASS_NAME,\n\t\t\t\t\"fundingFailed\",\n\t\t\t\tundefined,\n\t\t\t\tIota.extractPayloadError(error)\n\t\t\t);\n\t\t}\n\n\t\treturn 0n;\n\t}\n\n\t/**\n\t * Ensure the balance for the given address is at least the given amount.\n\t * @param config The configuration containing endpoint information.\n\t * @param faucetUrl The URL of the faucet to request funds from.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param address The address to ensure the balance for.\n\t * @param ensureBalance The minimum balance to ensure.\n\t * @param timeoutInSeconds Optional timeout in seconds, defaults to 10 seconds.\n\t * @returns True if the balance is at least the given amount, false otherwise.\n\t */\n\tpublic static async ensureBalance(\n\t\tconfig: IIotaConfig,\n\t\tfaucetUrl: string | undefined,\n\t\tidentity: string,\n\t\taddress: string,\n\t\tensureBalance: bigint,\n\t\ttimeoutInSeconds?: number\n\t): Promise<boolean> {\n\t\tGuards.objectValue<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(config.clientOptions.url), config.clientOptions.url);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(identity), identity);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(address), address);\n\t\tGuards.bigint(Iota.CLASS_NAME, nameof(ensureBalance), ensureBalance);\n\n\t\tlet currentBalance = await Iota.getBalance(config, address);\n\n\t\tif (Is.stringValue(faucetUrl)) {\n\t\t\tlet retryCount = 10;\n\n\t\t\twhile (currentBalance < ensureBalance && retryCount > 0) {\n\t\t\t\tconst addedBalance = await Iota.fundAddress(\n\t\t\t\t\tconfig,\n\t\t\t\t\tfaucetUrl,\n\t\t\t\t\tidentity,\n\t\t\t\t\taddress,\n\t\t\t\t\ttimeoutInSeconds\n\t\t\t\t);\n\t\t\t\tif (addedBalance === 0n) {\n\t\t\t\t\treturn false;\n\t\t\t\t}\n\t\t\t\tcurrentBalance += addedBalance;\n\t\t\t\tif (currentBalance < ensureBalance) {\n\t\t\t\t\tawait new Promise(resolve => setTimeout(resolve, 1000));\n\t\t\t\t\tretryCount--;\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\treturn currentBalance >= ensureBalance;\n\t}\n\n\t/**\n\t * Get the balance for the given address.\n\t * @param config The configuration containing endpoint information.\n\t * @param address The address to get the balance for.\n\t * @returns The balance of the given address.\n\t */\n\tpublic static async getBalance(config: IIotaConfig, address: string): Promise<bigint> {\n\t\tGuards.objectValue<IIotaConfig>(Iota.CLASS_NAME, nameof(config), config);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(config.clientOptions.url), config.clientOptions.url);\n\t\tGuards.stringValue(Iota.CLASS_NAME, nameof(address), address);\n\n\t\tconst client = Iota.createClient(config);\n\t\tconst balance = await client.getBalance({\n\t\t\towner: address\n\t\t});\n\t\treturn BigInt(balance.totalBalance);\n\t}\n\n\t/**\n\t * Create a transaction instance from the given bytes.\n\t * @param bytes The transaction bytes to create the transaction from.\n\t * @returns The transaction instance created from the given bytes.\n\t */\n\tpublic static transactionFromBytes(bytes: Uint8Array): IIotaTransaction {\n\t\treturn Transaction.from(bytes);\n\t}\n\n\t/**\n\t * Find the raw node message matching an object conflict pattern, wherever it surfaces. On the\n\t * direct submission path it is the thrown error's message; through the gas station it arrives as\n\t * an HTTP error whose body the fetch layer nests as the message of a cause error. Flattening the\n\t * error tree and matching each message covers both.\n\t * @param error The error to inspect.\n\t * @param pattern The conflict pattern to match.\n\t * @returns The raw node message if the pattern matches, otherwise undefined.\n\t * @internal\n\t */\n\tprivate static objectConflictMessage(error: unknown, pattern: RegExp): string | undefined {\n\t\tconst match = BaseError.flatten(error).find(\n\t\t\tflattened => Is.stringValue(flattened.message) && pattern.test(flattened.message)\n\t\t);\n\t\treturn match?.message;\n\t}\n\n\t/**\n\t * Find the vault key name and public key for the given owner address.\n\t * Keys are individually registered in the vault by buildKeyPairRange, so no addKey is needed here.\n\t * @param vaultConnector The vault connector to use.\n\t * @param config The configuration to use.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param owner The owner address whose key should be located.\n\t * @param accountIndex The account index to search.\n\t * @returns The vault key name and the public key bytes.\n\t * @internal\n\t */\n\tprivate static async ensureOwnerKey(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: IIotaConfig,\n\t\tidentity: string,\n\t\towner: string,\n\t\taccountIndex: number = 0\n\t): Promise<{ keyName: string; publicKey: Uint8Array }> {\n\t\tconst scanRange = config.maxAddressScanRange ?? Iota._DEFAULT_SCAN_RANGE;\n\t\tlet cachedSeed: Uint8Array | undefined;\n\t\tconst seedProvider = async (): Promise<Uint8Array> => {\n\t\t\tcachedSeed ??= await Iota.getSeed(vaultConnector, config, identity);\n\t\t\treturn cachedSeed;\n\t\t};\n\n\t\tfor (let chunkStart = 0; chunkStart < scanRange; chunkStart += Iota._PRE_CALC_CHUNK_SIZE) {\n\t\t\tconst publicKeys = await Iota.getPublicKeys(\n\t\t\t\tvaultConnector,\n\t\t\t\tconfig,\n\t\t\t\tidentity,\n\t\t\t\taccountIndex,\n\t\t\t\tfalse,\n\t\t\t\tchunkStart,\n\t\t\t\tseedProvider\n\t\t\t);\n\t\t\tconst matchIndex = publicKeys.findIndex(\n\t\t\t\t(pk: string) => Iota.publicKeyToAddress(Converter.base64ToBytes(pk)) === owner\n\t\t\t);\n\t\t\tif (matchIndex >= 0) {\n\t\t\t\tconst addressIndex = chunkStart + matchIndex;\n\t\t\t\treturn {\n\t\t\t\t\tkeyName: Iota.buildAddressKeyName(identity, accountIndex, false, addressIndex),\n\t\t\t\t\tpublicKey: Converter.base64ToBytes(publicKeys[matchIndex])\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tthrow new GeneralError(Iota.CLASS_NAME, \"addressNotFound\", { address: owner });\n\t}\n\n\t/**\n\t * Get the seed from the vault, deriving it from the mnemonic if necessary.\n\t * @param vaultConnector The vault connector to use.\n\t * @param config The configuration to use.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @returns The seed bytes.\n\t * @internal\n\t */\n\tprivate static async getSeed(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: Pick<IIotaConfig, \"vaultMnemonicId\" | \"vaultSeedId\">,\n\t\tidentity: string\n\t): Promise<Uint8Array> {\n\t\tconst seedKey = Iota.buildSeedKey(identity, config.vaultSeedId);\n\n\t\ttry {\n\t\t\tconst seedBase64 = await vaultConnector.getSecret<string>(seedKey);\n\t\t\treturn Converter.base64ToBytes(seedBase64);\n\t\t} catch {}\n\n\t\tconst mnemonic = await vaultConnector.getSecret<string>(\n\t\t\tIota.buildMnemonicKey(identity, config.vaultMnemonicId)\n\t\t);\n\n\t\t// If the seed is not found but the mnemonic exists, derive the seed and store it for future use\n\t\tconst seed = Bip39.mnemonicToSeed(mnemonic);\n\t\tawait vaultConnector.setSecret(seedKey, Converter.bytesToBase64(seed));\n\n\t\treturn seed;\n\t}\n\n\t/**\n\t * Get the key for storing the mnemonic.\n\t * @param identity The identity to use.\n\t * @param vaultMnemonicId The mnemonic ID to use.\n\t * @returns The mnemonic key.\n\t * @internal\n\t */\n\tprivate static buildMnemonicKey(identity: string, vaultMnemonicId?: string): string {\n\t\treturn VaultConnectorHelper.buildKeyName(\n\t\t\tidentity,\n\t\t\tvaultMnemonicId ?? Iota.DEFAULT_MNEMONIC_SECRET_NAME\n\t\t);\n\t}\n\n\t/**\n\t * Get the key for storing the seed.\n\t * @param identity The identity to use.\n\t * @param vaultSeedId The seed ID to use.\n\t * @returns The seed key.\n\t * @internal\n\t */\n\tprivate static buildSeedKey(identity: string, vaultSeedId?: string): string {\n\t\treturn VaultConnectorHelper.buildKeyName(\n\t\t\tidentity,\n\t\t\tvaultSeedId ?? Iota.DEFAULT_SEED_SECRET_NAME\n\t\t);\n\t}\n\n\t/**\n\t * Ensure a range of BIP44-derived keys are registered as individual vault keys and return their public keys.\n\t * If the first key of the range already exists the range is considered registered and only public keys are derived.\n\t * If not registered, all keys are derived and added to the vault before returning the public keys.\n\t * @param vaultConnector The vault connector to use.\n\t * @param config The configuration to use.\n\t * @param identity The identity of the user to access the vault keys.\n\t * @param accountIndex The account index.\n\t * @param internal Whether the addresses are internal or external.\n\t * @param addressIndex Any address index within the desired chunk; aligned internally.\n\t * @param seedProvider Callback invoked at most once per call to supply the seed when a chunk is not yet registered.\n\t * @returns The base64-encoded public keys for each address in the range.\n\t * @internal\n\t */\n\tprivate static async getPublicKeys(\n\t\tvaultConnector: IVaultConnector,\n\t\tconfig: Pick<IIotaConfig, \"coinType\">,\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\tinternal: boolean,\n\t\taddressIndex: number,\n\t\tseedProvider: () => Promise<Uint8Array>\n\t): Promise<string[]> {\n\t\tconst chunkStart = addressIndex - (addressIndex % Iota._PRE_CALC_CHUNK_SIZE);\n\t\tconst firstKeyName = Iota.buildAddressKeyName(identity, accountIndex, internal, chunkStart);\n\t\tconst publicKeys: string[] = [];\n\n\t\tif (await vaultConnector.keyExists(firstKeyName)) {\n\t\t\tfor (let i = chunkStart; i < chunkStart + Iota._PRE_CALC_CHUNK_SIZE; i++) {\n\t\t\t\tconst keyName = Iota.buildAddressKeyName(identity, accountIndex, internal, i);\n\t\t\t\tconst keyData = await vaultConnector.getKey(keyName, \"public\");\n\t\t\t\tif (!keyData.publicKey) {\n\t\t\t\t\tthrow new GeneralError(Iota.CLASS_NAME, \"missingPublicKey\", { keyName });\n\t\t\t\t}\n\t\t\t\tpublicKeys.push(Converter.bytesToBase64(keyData.publicKey));\n\t\t\t}\n\t\t} else {\n\t\t\tconst seed = await seedProvider();\n\t\t\tconst coinType = config.coinType ?? Iota.DEFAULT_COIN_TYPE;\n\n\t\t\tfor (let i = chunkStart; i < chunkStart + Iota._PRE_CALC_CHUNK_SIZE; i++) {\n\t\t\t\tconst keyName = Iota.buildAddressKeyName(identity, accountIndex, internal, i);\n\t\t\t\tconst keyPair = Bip44.keyPair(seed, KeyType.Ed25519, coinType, accountIndex, internal, i);\n\t\t\t\tawait vaultConnector.addKey(\n\t\t\t\t\tkeyName,\n\t\t\t\t\tVaultKeyType.Ed25519,\n\t\t\t\t\tkeyPair.privateKey,\n\t\t\t\t\tkeyPair.publicKey\n\t\t\t\t);\n\t\t\t\tpublicKeys.push(Converter.bytesToBase64(keyPair.publicKey));\n\t\t\t}\n\t\t}\n\n\t\treturn publicKeys;\n\t}\n\n\t/**\n\t * Build the vault key name for a specific derived address.\n\t * @param identity The identity to use.\n\t * @param accountIndex The account index.\n\t * @param internal Whether the address is internal or external.\n\t * @param addressIndex The address index.\n\t * @returns The vault key name.\n\t * @internal\n\t */\n\tprivate static buildAddressKeyName(\n\t\tidentity: string,\n\t\taccountIndex: number,\n\t\tinternal: boolean,\n\t\taddressIndex: number\n\t): string {\n\t\treturn VaultConnectorHelper.buildKeyName(\n\t\t\tidentity,\n\t\t\t\"account\",\n\t\t\taccountIndex.toString(),\n\t\t\tinternal ? \"1\" : \"0\",\n\t\t\t`${addressIndex}`\n\t\t);\n\t}\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IIotaConfig.js","sourceRoot":"","sources":["../../../src/models/IIotaConfig.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IotaClientOptions } from \"@iota/iota-sdk/client\";\nimport type { IGasStationConfig } from \"./IGasStationConfig.js\";\n\n/**\n * Configuration for IOTA.\n */\nexport interface IIotaConfig {\n\t/**\n\t * The configuration for the client.\n\t */\n\tclientOptions: IotaClientOptions;\n\n\t/**\n\t * The network the operations are being performed on.\n\t */\n\tnetwork: string;\n\n\t/**\n\t * The id of the entry in the vault containing the mnemonic.\n\t * @default mnemonic\n\t */\n\tvaultMnemonicId?: string;\n\n\t/**\n\t * The id of the entry in the vault containing the seed.\n\t * @default seed\n\t */\n\tvaultSeedId?: string;\n\n\t/**\n\t * The coin type.\n\t * @default IOTA 4218\n\t */\n\tcoinType?: number;\n\n\t/**\n\t * The maximum range to scan for addresses.\n\t * @default 1000\n\t */\n\tmaxAddressScanRange?: number;\n\n\t/**\n\t * The length of time to wait for the inclusion of a transaction in seconds.\n\t * @default 60\n\t */\n\tinclusionTimeoutSeconds?: number;\n\n\t/**\n\t * Gas station configuration for sponsored transactions.\n\t * If provided, transactions will be processed through the gas station.\n\t */\n\tgasStation?: IGasStationConfig;\n\n\t/**\n\t * The default gas budget for all transactions (including sponsored and direct).\n\t * @default 50000000\n\t */\n\tgasBudget?: number;\n\n\t/**\n\t * The default gas reservation duration in seconds for all transactions (including sponsored and direct).\n\t * @default 60\n\t */\n\tgasReservationDuration?: number;\n\n\t/**\n\t * Enable cost logging for transactions.\n\t * @default false\n\t */\n\tenableCostLogging?: boolean;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"IIotaConfig.js","sourceRoot":"","sources":["../../../src/models/IIotaConfig.ts"],"names":[],"mappings":"","sourcesContent":["// Copyright 2024 IOTA Stiftung.\n// SPDX-License-Identifier: Apache-2.0.\nimport type { IotaClientOptions } from \"@iota/iota-sdk/client\";\nimport type { IGasStationConfig } from \"./IGasStationConfig.js\";\n\n/**\n * Configuration for IOTA.\n */\nexport interface IIotaConfig {\n\t/**\n\t * The configuration for the client.\n\t */\n\tclientOptions: IotaClientOptions;\n\n\t/**\n\t * The network the operations are being performed on.\n\t */\n\tnetwork: string;\n\n\t/**\n\t * The id of the entry in the vault containing the mnemonic.\n\t * @default mnemonic\n\t */\n\tvaultMnemonicId?: string;\n\n\t/**\n\t * The id of the entry in the vault containing the seed.\n\t * @default seed\n\t */\n\tvaultSeedId?: string;\n\n\t/**\n\t * The coin type.\n\t * @default IOTA 4218\n\t */\n\tcoinType?: number;\n\n\t/**\n\t * The maximum range to scan for addresses.\n\t * @default 1000\n\t */\n\tmaxAddressScanRange?: number;\n\n\t/**\n\t * The length of time to wait for the inclusion of a transaction in seconds.\n\t * @default 60\n\t */\n\tinclusionTimeoutSeconds?: number;\n\n\t/**\n\t * Gas station configuration for sponsored transactions.\n\t * If provided, transactions will be processed through the gas station.\n\t */\n\tgasStation?: IGasStationConfig;\n\n\t/**\n\t * The default gas budget for all transactions (including sponsored and direct).\n\t * @default 50000000\n\t */\n\tgasBudget?: number;\n\n\t/**\n\t * The default gas reservation duration in seconds for all transactions (including sponsored and direct).\n\t * @default 60\n\t */\n\tgasReservationDuration?: number;\n\n\t/**\n\t * Enable cost logging for transactions.\n\t * @default false\n\t */\n\tenableCostLogging?: boolean;\n\n\t/**\n\t * The number of times to retry a transaction that is rejected because one or more of its owned\n\t * objects is reserved by another in-flight transaction.\n\t * @default 3\n\t */\n\tobjectLockRetries?: number;\n\n\t/**\n\t * The base delay in milliseconds between object-lock retries; the delay grows exponentially\n\t * with each attempt.\n\t * @default 1000\n\t */\n\tobjectLockRetryDelayMs?: number;\n}\n"]}
|
package/dist/types/iota.d.ts
CHANGED
|
@@ -174,6 +174,48 @@ export declare class Iota {
|
|
|
174
174
|
* @returns The abort code if the transaction was aborted, or undefined if it was not an abort error or the code could not be extracted.
|
|
175
175
|
*/
|
|
176
176
|
static extractAbortCode(response: IIotaTransactionBlockResponse): number | undefined;
|
|
177
|
+
/**
|
|
178
|
+
* Check if an error is a retryable "owned object reserved by another transaction" conflict.
|
|
179
|
+
* IOTA locks owned objects for the first in-flight transaction that claims them, so a
|
|
180
|
+
* concurrent transaction referencing the same objects is rejected until the lock clears. This
|
|
181
|
+
* only matches the transient "reserved for another transaction" case, not the non-retryable
|
|
182
|
+
* "equivocated until the next epoch" case.
|
|
183
|
+
* @param error The error to check.
|
|
184
|
+
* @returns True if the error is a retryable object reservation conflict.
|
|
185
|
+
*/
|
|
186
|
+
static isReservedObjectError(error: unknown): boolean;
|
|
187
|
+
/**
|
|
188
|
+
* Check if an error is a retryable owned-object conflict caused by a concurrent transaction.
|
|
189
|
+
* This covers both the "reserved for another transaction" case (the object is locked by an
|
|
190
|
+
* in-flight transaction) and the "is not available for consumption" case (a concurrent
|
|
191
|
+
* transaction already consumed the referenced version); a retry rebuild re-resolves to the
|
|
192
|
+
* current version so both can recover. The non-retryable "equivocated until the next epoch"
|
|
193
|
+
* case is not matched.
|
|
194
|
+
* @param error The error to check.
|
|
195
|
+
* @returns True if the error is a retryable owned-object conflict.
|
|
196
|
+
*/
|
|
197
|
+
static isRetryableObjectConflictError(error: unknown): boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Extract the conflicting transaction digests from an object reservation conflict error.
|
|
200
|
+
* The node error lists the digests of the transactions currently locking the objects (the
|
|
201
|
+
* underlying object ids are only present in the RPC error data, which the IOTA SDK discards).
|
|
202
|
+
* Only the "reserved for another transaction" error carries digests, so this returns an empty
|
|
203
|
+
* array for the stale-version conflict case.
|
|
204
|
+
* @param error The error to extract from.
|
|
205
|
+
* @returns The conflicting transaction digests, or an empty array if none can be parsed.
|
|
206
|
+
*/
|
|
207
|
+
static extractReservationConflictDigests(error: unknown): string[];
|
|
208
|
+
/**
|
|
209
|
+
* Run a transaction submission operation, retrying with exponential back-off if it is rejected
|
|
210
|
+
* because of a retryable owned-object conflict with a concurrent transaction (the objects are
|
|
211
|
+
* reserved by an in-flight transaction, or the referenced version was already consumed).
|
|
212
|
+
* Other errors are rethrown immediately. If the conflict persists after all retries a clear,
|
|
213
|
+
* retryable error is thrown instead of the opaque underlying failure.
|
|
214
|
+
* @param config The configuration controlling retry counts and delays.
|
|
215
|
+
* @param operation The transaction submission operation to run.
|
|
216
|
+
* @returns The result of the operation.
|
|
217
|
+
*/
|
|
218
|
+
static executeWithReservationRetry<T>(config: IIotaConfig, operation: () => Promise<T>): Promise<T>;
|
|
177
219
|
/**
|
|
178
220
|
* Prepare and post a transaction using gas station sponsoring.
|
|
179
221
|
* @param config The configuration.
|
|
@@ -57,4 +57,16 @@ export interface IIotaConfig {
|
|
|
57
57
|
* @default false
|
|
58
58
|
*/
|
|
59
59
|
enableCostLogging?: boolean;
|
|
60
|
+
/**
|
|
61
|
+
* The number of times to retry a transaction that is rejected because one or more of its owned
|
|
62
|
+
* objects is reserved by another in-flight transaction.
|
|
63
|
+
* @default 3
|
|
64
|
+
*/
|
|
65
|
+
objectLockRetries?: number;
|
|
66
|
+
/**
|
|
67
|
+
* The base delay in milliseconds between object-lock retries; the delay grows exponentially
|
|
68
|
+
* with each attempt.
|
|
69
|
+
* @default 1000
|
|
70
|
+
*/
|
|
71
|
+
objectLockRetryDelayMs?: number;
|
|
60
72
|
}
|
package/docs/changelog.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.9.1-next.2](https://github.com/iotaledger/twin-dlt/compare/dlt-iota-v0.9.1-next.1...dlt-iota-v0.9.1-next.2) (2026-07-03)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* update components ([18f16b4](https://github.com/iotaledger/twin-dlt/commit/18f16b434b0909d56530e6c3bdc709921a2599b9))
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* retry transactions when owned objects are reserved by another transaction ([#91](https://github.com/iotaledger/twin-dlt/issues/91)) ([5a3a2d0](https://github.com/iotaledger/twin-dlt/commit/5a3a2d0123ba268cd7f747a3ff0b591e8fa49ef0))
|
|
14
|
+
|
|
3
15
|
## [0.9.1-next.1](https://github.com/iotaledger/twin-dlt/compare/dlt-iota-v0.9.1-next.0...dlt-iota-v0.9.1-next.1) (2026-06-26)
|
|
4
16
|
|
|
5
17
|
|
|
@@ -663,6 +663,123 @@ The abort code if the transaction was aborted, or undefined if it was not an abo
|
|
|
663
663
|
|
|
664
664
|
***
|
|
665
665
|
|
|
666
|
+
### isReservedObjectError() {#isreservedobjecterror}
|
|
667
|
+
|
|
668
|
+
> `static` **isReservedObjectError**(`error`): `boolean`
|
|
669
|
+
|
|
670
|
+
Check if an error is a retryable "owned object reserved by another transaction" conflict.
|
|
671
|
+
IOTA locks owned objects for the first in-flight transaction that claims them, so a
|
|
672
|
+
concurrent transaction referencing the same objects is rejected until the lock clears. This
|
|
673
|
+
only matches the transient "reserved for another transaction" case, not the non-retryable
|
|
674
|
+
"equivocated until the next epoch" case.
|
|
675
|
+
|
|
676
|
+
#### Parameters
|
|
677
|
+
|
|
678
|
+
##### error
|
|
679
|
+
|
|
680
|
+
`unknown`
|
|
681
|
+
|
|
682
|
+
The error to check.
|
|
683
|
+
|
|
684
|
+
#### Returns
|
|
685
|
+
|
|
686
|
+
`boolean`
|
|
687
|
+
|
|
688
|
+
True if the error is a retryable object reservation conflict.
|
|
689
|
+
|
|
690
|
+
***
|
|
691
|
+
|
|
692
|
+
### isRetryableObjectConflictError() {#isretryableobjectconflicterror}
|
|
693
|
+
|
|
694
|
+
> `static` **isRetryableObjectConflictError**(`error`): `boolean`
|
|
695
|
+
|
|
696
|
+
Check if an error is a retryable owned-object conflict caused by a concurrent transaction.
|
|
697
|
+
This covers both the "reserved for another transaction" case (the object is locked by an
|
|
698
|
+
in-flight transaction) and the "is not available for consumption" case (a concurrent
|
|
699
|
+
transaction already consumed the referenced version); a retry rebuild re-resolves to the
|
|
700
|
+
current version so both can recover. The non-retryable "equivocated until the next epoch"
|
|
701
|
+
case is not matched.
|
|
702
|
+
|
|
703
|
+
#### Parameters
|
|
704
|
+
|
|
705
|
+
##### error
|
|
706
|
+
|
|
707
|
+
`unknown`
|
|
708
|
+
|
|
709
|
+
The error to check.
|
|
710
|
+
|
|
711
|
+
#### Returns
|
|
712
|
+
|
|
713
|
+
`boolean`
|
|
714
|
+
|
|
715
|
+
True if the error is a retryable owned-object conflict.
|
|
716
|
+
|
|
717
|
+
***
|
|
718
|
+
|
|
719
|
+
### extractReservationConflictDigests() {#extractreservationconflictdigests}
|
|
720
|
+
|
|
721
|
+
> `static` **extractReservationConflictDigests**(`error`): `string`[]
|
|
722
|
+
|
|
723
|
+
Extract the conflicting transaction digests from an object reservation conflict error.
|
|
724
|
+
The node error lists the digests of the transactions currently locking the objects (the
|
|
725
|
+
underlying object ids are only present in the RPC error data, which the IOTA SDK discards).
|
|
726
|
+
Only the "reserved for another transaction" error carries digests, so this returns an empty
|
|
727
|
+
array for the stale-version conflict case.
|
|
728
|
+
|
|
729
|
+
#### Parameters
|
|
730
|
+
|
|
731
|
+
##### error
|
|
732
|
+
|
|
733
|
+
`unknown`
|
|
734
|
+
|
|
735
|
+
The error to extract from.
|
|
736
|
+
|
|
737
|
+
#### Returns
|
|
738
|
+
|
|
739
|
+
`string`[]
|
|
740
|
+
|
|
741
|
+
The conflicting transaction digests, or an empty array if none can be parsed.
|
|
742
|
+
|
|
743
|
+
***
|
|
744
|
+
|
|
745
|
+
### executeWithReservationRetry() {#executewithreservationretry}
|
|
746
|
+
|
|
747
|
+
> `static` **executeWithReservationRetry**\<`T`\>(`config`, `operation`): `Promise`\<`T`\>
|
|
748
|
+
|
|
749
|
+
Run a transaction submission operation, retrying with exponential back-off if it is rejected
|
|
750
|
+
because of a retryable owned-object conflict with a concurrent transaction (the objects are
|
|
751
|
+
reserved by an in-flight transaction, or the referenced version was already consumed).
|
|
752
|
+
Other errors are rethrown immediately. If the conflict persists after all retries a clear,
|
|
753
|
+
retryable error is thrown instead of the opaque underlying failure.
|
|
754
|
+
|
|
755
|
+
#### Type Parameters
|
|
756
|
+
|
|
757
|
+
##### T
|
|
758
|
+
|
|
759
|
+
`T`
|
|
760
|
+
|
|
761
|
+
#### Parameters
|
|
762
|
+
|
|
763
|
+
##### config
|
|
764
|
+
|
|
765
|
+
[`IIotaConfig`](../interfaces/IIotaConfig.md)
|
|
766
|
+
|
|
767
|
+
The configuration controlling retry counts and delays.
|
|
768
|
+
|
|
769
|
+
##### operation
|
|
770
|
+
|
|
771
|
+
() => `Promise`\<`T`\>
|
|
772
|
+
|
|
773
|
+
The transaction submission operation to run.
|
|
774
|
+
|
|
775
|
+
#### Returns
|
|
776
|
+
|
|
777
|
+
`Promise`\<`T`\>
|
|
778
|
+
|
|
779
|
+
The result of the operation.
|
|
780
|
+
|
|
781
|
+
***
|
|
782
|
+
|
|
666
783
|
### prepareAndPostGasStationTransaction() {#prepareandpostgasstationtransaction}
|
|
667
784
|
|
|
668
785
|
> `static` **prepareAndPostGasStationTransaction**(`config`, `vaultConnector`, `identity`, `client`, `owner`, `transaction`, `options?`): `Promise`\<`IotaTransactionBlockResponse`\>
|
|
@@ -138,3 +138,33 @@ Enable cost logging for transactions.
|
|
|
138
138
|
```ts
|
|
139
139
|
false
|
|
140
140
|
```
|
|
141
|
+
|
|
142
|
+
***
|
|
143
|
+
|
|
144
|
+
### objectLockRetries? {#objectlockretries}
|
|
145
|
+
|
|
146
|
+
> `optional` **objectLockRetries?**: `number`
|
|
147
|
+
|
|
148
|
+
The number of times to retry a transaction that is rejected because one or more of its owned
|
|
149
|
+
objects is reserved by another in-flight transaction.
|
|
150
|
+
|
|
151
|
+
#### Default
|
|
152
|
+
|
|
153
|
+
```ts
|
|
154
|
+
3
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
***
|
|
158
|
+
|
|
159
|
+
### objectLockRetryDelayMs? {#objectlockretrydelayms}
|
|
160
|
+
|
|
161
|
+
> `optional` **objectLockRetryDelayMs?**: `number`
|
|
162
|
+
|
|
163
|
+
The base delay in milliseconds between object-lock retries; the delay grows exponentially
|
|
164
|
+
with each attempt.
|
|
165
|
+
|
|
166
|
+
#### Default
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
1000
|
|
170
|
+
```
|
package/locales/en.json
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
"packageObjectError": "Failed to fetch the package object \"{packageId}\"",
|
|
7
7
|
"valueTransactionFailed": "The value transaction failed",
|
|
8
8
|
"transactionFailed": "The transaction failed",
|
|
9
|
+
"objectReservationConflict": "One or more of the transaction's owned objects are contended by another in-flight transaction; submit transactions that share objects sequentially and retry",
|
|
9
10
|
"addressNotFound": "The address is missing could not be found from the seed \"{address}\"",
|
|
10
11
|
"gasStationTransactionFailed": "The gas station transaction failed",
|
|
11
12
|
"dryRunFailed": "The dry run execution failed",
|