@twin.org/dlt-iota 0.0.2-next.1 → 0.0.2-next.10

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.
@@ -105,7 +105,7 @@ class Iota {
105
105
  * Prepare and post a transaction.
106
106
  * @param config The configuration.
107
107
  * @param vaultConnector The vault connector.
108
- * @param loggingConnector The logging connector.
108
+ * @param logging The logging component.
109
109
  * @param identity The identity of the user to access the vault keys.
110
110
  * @param client The client instance.
111
111
  * @param source The source address.
@@ -114,7 +114,7 @@ class Iota {
114
114
  * @param options The transaction options.
115
115
  * @returns The transaction result.
116
116
  */
117
- static async prepareAndPostValueTransaction(config, vaultConnector, loggingConnector, identity, client, source, amount, recipient, options) {
117
+ static async prepareAndPostValueTransaction(config, vaultConnector, logging, identity, client, source, amount, recipient, options) {
118
118
  try {
119
119
  const txb = new transactions.Transaction();
120
120
  const [coin] = txb.splitCoins(txb.gas, [txb.pure.u64(amount)]);
@@ -123,7 +123,7 @@ class Iota {
123
123
  if (core.Is.object(config.gasStation)) {
124
124
  return await this.prepareAndPostGasStationTransaction(config, vaultConnector, identity, client, source, txb);
125
125
  }
126
- const result = await this.prepareAndPostTransaction(config, vaultConnector, loggingConnector, identity, client, source, txb, options);
126
+ const result = await this.prepareAndPostTransaction(config, vaultConnector, logging, identity, client, source, txb, options);
127
127
  return result;
128
128
  }
129
129
  catch (error) {
@@ -134,7 +134,7 @@ class Iota {
134
134
  * Prepare and post a transaction.
135
135
  * @param config The configuration.
136
136
  * @param vaultConnector The vault connector.
137
- * @param loggingConnector The logging connector.
137
+ * @param logging The logging component.
138
138
  * @param identity The identity of the user to access the vault keys.
139
139
  * @param client The client instance.
140
140
  * @param owner The owner of the address.
@@ -142,7 +142,7 @@ class Iota {
142
142
  * @param options The transaction options.
143
143
  * @returns The transaction response.
144
144
  */
145
- static async prepareAndPostTransaction(config, vaultConnector, loggingConnector, identity, client, owner, transaction, options) {
145
+ static async prepareAndPostTransaction(config, vaultConnector, logging, identity, client, owner, transaction, options) {
146
146
  // Check if gas station configuration is present
147
147
  if (core.Is.object(config.gasStation)) {
148
148
  return this.prepareAndPostGasStationTransaction(config, vaultConnector, identity, client, owner, transaction, options);
@@ -150,7 +150,7 @@ class Iota {
150
150
  // Traditional transaction flow
151
151
  // Dry run the transaction if cost logging is enabled to get the gas and storage costs
152
152
  if (core.Is.stringValue(options?.dryRunLabel)) {
153
- await Iota.dryRunTransaction(client, loggingConnector, transaction, owner, options.dryRunLabel);
153
+ await Iota.dryRunTransaction(client, logging, transaction, owner, options.dryRunLabel);
154
154
  }
155
155
  const seed = await this.getSeed(config, vaultConnector, identity);
156
156
  const addressKeyPair = Iota.findAddress(config.maxAddressScanRange ?? Iota.DEFAULT_SCAN_RANGE, config.coinType ?? Iota.DEFAULT_COIN_TYPE, seed, owner);
@@ -226,6 +226,9 @@ class Iota {
226
226
  if (!core.Is.empty(error.inner)) {
227
227
  error.inner = Iota.extractPayloadError(error.inner);
228
228
  }
229
+ if (!core.Is.empty(error.cause)) {
230
+ error.cause = Iota.extractPayloadError(error.cause);
231
+ }
229
232
  if (error.code === "InsufficientGas") {
230
233
  return new core.GeneralError(Iota._CLASS_NAME, "insufficientFunds");
231
234
  }
@@ -288,15 +291,14 @@ class Iota {
288
291
  }
289
292
  catch (error) {
290
293
  throw new core.GeneralError(Iota._CLASS_NAME, "packageNotFoundOnNetwork", {
291
- packageId,
292
- error: Iota.extractPayloadError(error)
293
- });
294
+ packageId
295
+ }, Iota.extractPayloadError(error));
294
296
  }
295
297
  }
296
298
  /**
297
299
  * Dry run a transaction and log the results.
298
300
  * @param client The IOTA client.
299
- * @param logging The logging connector.
301
+ * @param logging The logging component.
300
302
  * @param txb The transaction to dry run.
301
303
  * @param sender The sender address.
302
304
  * @param operation The operation to log.
@@ -511,4 +513,436 @@ class Iota {
511
513
  }
512
514
  }
513
515
 
516
+ // Copyright 2024 IOTA Stiftung.
517
+ // SPDX-License-Identifier: Apache-2.0.
518
+ /**
519
+ * Utility class providing common smart contract operations for IOTA-based contracts.
520
+ * This class uses composition pattern to provide shared functionality without inheritance complexity.
521
+ */
522
+ class IotaSmartContractUtils {
523
+ /**
524
+ * Runtime name for the class.
525
+ */
526
+ static CLASS_NAME = "IotaSmartContractUtils";
527
+ /**
528
+ * Migrate a smart contract object to the current version using admin privileges.
529
+ * This is a generic migration method that works with any IOTA smart contract.
530
+ * @param config The IOTA configuration.
531
+ * @param client The IOTA client instance.
532
+ * @param vaultConnector The vault connector for key management.
533
+ * @param walletConnector The wallet connector for address generation.
534
+ * @param logging Optional logging component.
535
+ * @param gasBudget The gas budget for the transaction.
536
+ * @param identity The identity of the controller with admin privileges.
537
+ * @param objectId The ID of the object to migrate.
538
+ * @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
539
+ * @param packageId The deployed package ID for the contract.
540
+ * @param deploymentConfig The deployment configuration containing object IDs.
541
+ * @param walletAddressIndex Optional wallet address index for the controller.
542
+ * @returns Promise that resolves when migration is complete.
543
+ */
544
+ static async migrateSmartContract(config, client, vaultConnector, walletConnector, logging, gasBudget, identity, objectId, namespace, packageId, deploymentConfig, walletAddressIndex) {
545
+ try {
546
+ const txb = new transactions.Transaction();
547
+ txb.setGasBudget(gasBudget);
548
+ const moduleName = this.getModuleName(namespace);
549
+ // Get admin address for the transaction
550
+ const adminAddress = await this.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
551
+ // Get the required object IDs from deployment config
552
+ const { adminCapId, migrationStateId } = await this.getContractObjectIds(client, namespace, config.network, deploymentConfig, packageId, adminAddress);
553
+ txb.moveCall({
554
+ target: `${packageId}::${moduleName}::migrate_${moduleName}`,
555
+ arguments: [txb.object(adminCapId), txb.object(migrationStateId), txb.object(objectId)]
556
+ });
557
+ const result = await Iota.prepareAndPostTransaction(config, vaultConnector, logging, identity, client, adminAddress, txb, {
558
+ dryRunLabel: config.enableCostLogging ? "migrate_object" : undefined
559
+ });
560
+ if (result.effects?.status?.status !== "success") {
561
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "migrationFailed", {
562
+ error: result.effects?.status?.error,
563
+ objectId
564
+ });
565
+ }
566
+ }
567
+ catch (error) {
568
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "migrateSmartContractFailed", { objectId }, error);
569
+ }
570
+ }
571
+ /**
572
+ * Enable migration operations using admin privileges.
573
+ * @param config The IOTA configuration.
574
+ * @param client The IOTA client instance.
575
+ * @param vaultConnector The vault connector for key management.
576
+ * @param walletConnector The wallet connector for address generation.
577
+ * @param logging Optional logging component.
578
+ * @param gasBudget The gas budget for the transaction.
579
+ * @param identity The identity of the controller with admin privileges.
580
+ * @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
581
+ * @param packageId The deployed package ID for the contract.
582
+ * @param deploymentConfig The deployment configuration containing object IDs.
583
+ * @param walletAddressIndex Optional wallet address index for the controller.
584
+ * @returns Promise that resolves when migration is enabled.
585
+ */
586
+ static async enableMigration(config, client, vaultConnector, walletConnector, logging, gasBudget, identity, namespace, packageId, deploymentConfig, walletAddressIndex) {
587
+ try {
588
+ const txb = new transactions.Transaction();
589
+ txb.setGasBudget(gasBudget);
590
+ const moduleName = this.getModuleName(namespace);
591
+ // Get admin address for the transaction
592
+ const adminAddress = await this.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
593
+ // Get the required object IDs from deployment config
594
+ const { adminCapId, migrationStateId } = await this.getContractObjectIds(client, namespace, config.network, deploymentConfig, packageId, adminAddress);
595
+ txb.moveCall({
596
+ target: `${packageId}::${moduleName}::enable_migration`,
597
+ arguments: [txb.object(adminCapId), txb.object(migrationStateId)]
598
+ });
599
+ const result = await Iota.prepareAndPostTransaction(config, vaultConnector, logging, identity, client, adminAddress, txb, {
600
+ dryRunLabel: config.enableCostLogging ? "enable_migration" : undefined
601
+ });
602
+ if (result.effects?.status?.status !== "success") {
603
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "enableMigrationFailed", {
604
+ error: result.effects?.status?.error
605
+ });
606
+ }
607
+ }
608
+ catch (error) {
609
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "enableMigrationFailed", undefined, error);
610
+ }
611
+ }
612
+ /**
613
+ * Disable migration operations using admin privileges.
614
+ * @param config The IOTA configuration.
615
+ * @param client The IOTA client instance.
616
+ * @param vaultConnector The vault connector for key management.
617
+ * @param walletConnector The wallet connector for address generation.
618
+ * @param logging Optional logging component.
619
+ * @param gasBudget The gas budget for the transaction.
620
+ * @param identity The identity of the controller with admin privileges.
621
+ * @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
622
+ * @param packageId The deployed package ID for the contract.
623
+ * @param deploymentConfig The deployment configuration containing object IDs.
624
+ * @param walletAddressIndex Optional wallet address index for the controller.
625
+ * @returns Promise that resolves when migration is disabled.
626
+ */
627
+ static async disableMigration(config, client, vaultConnector, walletConnector, logging, gasBudget, identity, namespace, packageId, deploymentConfig, walletAddressIndex) {
628
+ try {
629
+ const txb = new transactions.Transaction();
630
+ txb.setGasBudget(gasBudget);
631
+ const moduleName = this.getModuleName(namespace);
632
+ // Get admin address for the transaction
633
+ const adminAddress = await this.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
634
+ // Get the required object IDs from deployment config
635
+ const { adminCapId, migrationStateId } = await this.getContractObjectIds(client, namespace, config.network, deploymentConfig, packageId, adminAddress);
636
+ txb.moveCall({
637
+ target: `${packageId}::${moduleName}::disable_migration`,
638
+ arguments: [txb.object(adminCapId), txb.object(migrationStateId)]
639
+ });
640
+ const result = await Iota.prepareAndPostTransaction(config, vaultConnector, logging, identity, client, adminAddress, txb, {
641
+ dryRunLabel: config.enableCostLogging ? "disable_migration" : undefined
642
+ });
643
+ if (result.effects?.status?.status !== "success") {
644
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "disableMigrationFailed", {
645
+ error: result.effects?.status?.error
646
+ });
647
+ }
648
+ }
649
+ catch (error) {
650
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "disableMigrationFailed", undefined, error);
651
+ }
652
+ }
653
+ /**
654
+ * Check if migration is currently active for a smart contract.
655
+ * @param config The IOTA configuration.
656
+ * @param client The IOTA client instance.
657
+ * @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
658
+ * @param packageId The deployed package ID for the contract.
659
+ * @param deploymentConfig The deployment configuration containing object IDs.
660
+ * @param identity The identity for MigrationState discovery.
661
+ * @param walletConnector The wallet connector for address generation.
662
+ * @param walletAddressIndex Optional wallet address index.
663
+ * @returns True if migration is enabled, false otherwise.
664
+ */
665
+ static async isMigrationActive(config, client, namespace, packageId, deploymentConfig, identity, walletConnector, walletAddressIndex) {
666
+ try {
667
+ // Get admin address for discovery
668
+ const adminAddress = await this.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
669
+ // Get the migration state ID
670
+ const { migrationStateId } = await this.getContractObjectIds(client, namespace, config.network, deploymentConfig, packageId, adminAddress);
671
+ const migrationStateResponse = await client.getObject({
672
+ id: migrationStateId,
673
+ options: {
674
+ showContent: true,
675
+ showType: true
676
+ }
677
+ });
678
+ if (!migrationStateResponse.data?.content) {
679
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "migrationStateNotReadable", {
680
+ migrationStateId
681
+ });
682
+ }
683
+ const content = migrationStateResponse.data.content;
684
+ if (content.dataType === "moveObject" && core.Is.objectValue(content.fields)) {
685
+ const fields = content.fields;
686
+ return core.Is.boolean(fields.enabled) ? fields.enabled : false;
687
+ }
688
+ return false;
689
+ }
690
+ catch (error) {
691
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "isMigrationActiveFailed", undefined, error);
692
+ }
693
+ }
694
+ /**
695
+ * Get the current contract version from the deployed smart contract.
696
+ * @param config The IOTA configuration.
697
+ * @param client The IOTA client instance.
698
+ * @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
699
+ * @param packageId The deployed package ID for the contract.
700
+ * @param identity The identity for package controller address.
701
+ * @param walletConnector The wallet connector for address generation.
702
+ * @param walletAddressIndex Optional wallet address index.
703
+ * @returns The current version number of the contract.
704
+ */
705
+ static async getCurrentContractVersion(config, client, namespace, packageId, identity, walletConnector, walletAddressIndex) {
706
+ try {
707
+ const tx = new transactions.Transaction();
708
+ const moduleName = this.getModuleName(namespace);
709
+ tx.moveCall({
710
+ target: `${packageId}::${moduleName}::get_current_version`,
711
+ arguments: []
712
+ });
713
+ const controllerAddress = await this.getPackageControllerAddress(walletConnector, identity, walletAddressIndex);
714
+ const result = await client.devInspectTransactionBlock({
715
+ sender: controllerAddress,
716
+ transactionBlock: tx
717
+ });
718
+ if (core.Is.arrayValue(result.results) &&
719
+ core.Is.object(result.results[0]) &&
720
+ core.Is.arrayValue(result.results[0].returnValues)) {
721
+ const versionBytes = result.results[0].returnValues[0];
722
+ // Convert to Uint8Array if it's a regular array
723
+ const byteData = versionBytes[0];
724
+ if (!core.Is.arrayValue(byteData) && !core.Is.uint8Array(byteData)) {
725
+ throw new core.GeneralError(this.CLASS_NAME, "invalidVersionData");
726
+ }
727
+ // Convert to Uint8Array for BCS parsing
728
+ const uint8Data = core.Is.uint8Array(byteData) ? byteData : new Uint8Array(byteData);
729
+ // The version is returned as a u64, decode it from bytes using BCS
730
+ // IOTA Move contracts return data in BCS format
731
+ const version = Number(bcs.bcs.u64().parse(uint8Data));
732
+ return version;
733
+ }
734
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "getCurrentContractVersionNoData", {
735
+ resultExists: core.Is.arrayValue(result.results),
736
+ resultLength: core.Is.arrayValue(result.results) ? result.results.length : 0,
737
+ hasReturnValues: core.Is.arrayValue(result.results?.[0]?.returnValues)
738
+ });
739
+ }
740
+ catch (error) {
741
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "getCurrentContractVersionFailed", undefined, error);
742
+ }
743
+ }
744
+ /**
745
+ * Validate that an object version is compatible with the current contract.
746
+ * @param config The IOTA configuration.
747
+ * @param client The IOTA client instance.
748
+ * @param namespace The contract namespace (e.g., "nft", "verifiable_storage").
749
+ * @param packageId The deployed package ID for the contract.
750
+ * @param identity The identity for version checking.
751
+ * @param objectId The object ID to validate.
752
+ * @param walletConnector The wallet connector for address generation.
753
+ * @param versionExtractor Function to extract version from object content.
754
+ * @param walletAddressIndex Optional wallet address index.
755
+ * @returns True if the object version is compatible, false otherwise.
756
+ */
757
+ static async validateObjectVersion(config, client, namespace, packageId, identity, objectId, walletConnector, versionExtractor, walletAddressIndex) {
758
+ try {
759
+ // Get current contract version
760
+ const currentVersion = await this.getCurrentContractVersion(config, client, namespace, packageId, identity, walletConnector, walletAddressIndex);
761
+ // Get object version
762
+ const objectResponse = await client.getObject({
763
+ id: objectId,
764
+ options: {
765
+ showContent: true,
766
+ showType: true
767
+ }
768
+ });
769
+ if (!objectResponse.data?.content) {
770
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "objectNotReadable", {
771
+ objectId
772
+ });
773
+ }
774
+ const content = objectResponse.data.content;
775
+ if (content.dataType === "moveObject" && core.Is.objectValue(content.fields)) {
776
+ const objectVersion = versionExtractor(content);
777
+ return objectVersion <= currentVersion;
778
+ }
779
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "objectInvalidFormat", {
780
+ objectId,
781
+ content
782
+ });
783
+ }
784
+ catch (error) {
785
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "validateObjectVersionFailed", { objectId }, error);
786
+ }
787
+ }
788
+ /**
789
+ * Get the module name for a given namespace.
790
+ * @param namespace The contract namespace.
791
+ * @returns The module name in snake_case format.
792
+ * @internal
793
+ */
794
+ static getModuleName(namespace) {
795
+ // Convert namespace to snake_case for module name
796
+ return core.StringHelper.snakeCase(namespace);
797
+ }
798
+ /**
799
+ * Get the package controller address for transactions.
800
+ * @param walletConnector The wallet connector for address generation.
801
+ * @param identity The identity to use.
802
+ * @param addressIndex Optional address index to use.
803
+ * @returns The controller address.
804
+ * @internal
805
+ */
806
+ static async getPackageControllerAddress(walletConnector, identity, addressIndex = 0) {
807
+ const addresses = await walletConnector.getAddresses(identity, 0, addressIndex, 1);
808
+ return addresses[0];
809
+ }
810
+ /**
811
+ * Get contract object IDs (AdminCap and MigrationState) from deployment config with fallback discovery.
812
+ * @param client The IOTA client instance.
813
+ * @param namespace The contract namespace.
814
+ * @param network The network name.
815
+ * @param deploymentConfig The deployment configuration.
816
+ * @param packageId The package ID.
817
+ * @param adminAddress The admin address for object discovery.
818
+ * @returns Object containing adminCapId and migrationStateId.
819
+ * @internal
820
+ */
821
+ static async getContractObjectIds(client, namespace, network, deploymentConfig, packageId, adminAddress) {
822
+ try {
823
+ // First try to load from deployment JSON
824
+ const networkConfig = deploymentConfig[network];
825
+ if (core.Is.objectValue(networkConfig)) {
826
+ const migrationStateId = networkConfig.migrationStateId;
827
+ // AdminCap must be discovered from blockchain (not stored in JSON)
828
+ const adminCapId = await this.discoverAdminCap(client, packageId, namespace, adminAddress);
829
+ if (core.Is.stringValue(migrationStateId) && core.Is.stringValue(adminCapId)) {
830
+ return { adminCapId, migrationStateId };
831
+ }
832
+ }
833
+ // Fallback: discover both from blockchain
834
+ return await this.discoverContractObjectsFromBlockchain(client, packageId, namespace, adminAddress);
835
+ }
836
+ catch (error) {
837
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "getContractObjectIdsFailed", { namespace, network, packageId }, error);
838
+ }
839
+ }
840
+ /**
841
+ * Discover AdminCap object from the blockchain.
842
+ * @param client The IOTA client instance.
843
+ * @param packageId The package ID.
844
+ * @param namespace The contract namespace.
845
+ * @param adminAddress The admin address.
846
+ * @returns The AdminCap object ID.
847
+ * @internal
848
+ */
849
+ static async discoverAdminCap(client, packageId, namespace, adminAddress) {
850
+ const adminCapType = `${packageId}::${this.getModuleName(namespace)}::AdminCap`;
851
+ const adminCapObjects = await client.getOwnedObjects({
852
+ owner: adminAddress,
853
+ filter: {
854
+ StructType: adminCapType
855
+ },
856
+ options: {
857
+ showContent: true,
858
+ showType: true
859
+ }
860
+ });
861
+ if (core.Is.arrayValue(adminCapObjects.data) && adminCapObjects.data.length > 0) {
862
+ const adminCapObject = adminCapObjects.data[0];
863
+ if (core.Is.stringValue(adminCapObject.data?.objectId)) {
864
+ return adminCapObject.data.objectId;
865
+ }
866
+ }
867
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "adminCapNotFound", {
868
+ adminCapType,
869
+ adminAddress
870
+ });
871
+ }
872
+ /**
873
+ * Discover contract objects from blockchain as fallback.
874
+ * @param client The IOTA client instance.
875
+ * @param packageId The package ID.
876
+ * @param namespace The contract namespace.
877
+ * @param adminAddress The admin address.
878
+ * @returns Object containing adminCapId and migrationStateId.
879
+ * @internal
880
+ */
881
+ static async discoverContractObjectsFromBlockchain(client, packageId, namespace, adminAddress) {
882
+ // Discover AdminCap
883
+ const adminCapId = await this.discoverAdminCap(client, packageId, namespace, adminAddress);
884
+ // Discover MigrationState through transaction history
885
+ const migrationStateType = `${packageId}::${this.getModuleName(namespace)}::MigrationState`;
886
+ const transactions = await client.queryTransactionBlocks({
887
+ filter: {
888
+ FromAddress: adminAddress
889
+ },
890
+ options: {
891
+ showObjectChanges: true,
892
+ showEffects: true
893
+ },
894
+ limit: 20,
895
+ order: "descending"
896
+ });
897
+ // Look for MigrationState object creation in transaction history
898
+ let migrationStateId;
899
+ for (const tx of transactions.data) {
900
+ const objectChanges = tx.objectChanges;
901
+ if (core.Is.arrayValue(objectChanges)) {
902
+ for (const change of objectChanges) {
903
+ if ((change.type === "created" || change.type === "mutated") &&
904
+ "objectType" in change &&
905
+ change.objectType === migrationStateType) {
906
+ migrationStateId = change.objectId;
907
+ break;
908
+ }
909
+ }
910
+ if (migrationStateId) {
911
+ break;
912
+ }
913
+ }
914
+ }
915
+ if (!migrationStateId) {
916
+ throw new core.GeneralError(IotaSmartContractUtils.CLASS_NAME, "migrationStateNotFound", {
917
+ migrationStateType,
918
+ adminAddress
919
+ });
920
+ }
921
+ return { adminCapId, migrationStateId };
922
+ }
923
+ }
924
+
925
+ // Copyright 2024 IOTA Stiftung.
926
+ // SPDX-License-Identifier: Apache-2.0.
927
+ /**
928
+ * Network types supported for deployment
929
+ */
930
+ // eslint-disable-next-line @typescript-eslint/naming-convention
931
+ const NetworkTypes = {
932
+ /**
933
+ * Testnet.
934
+ */
935
+ Testnet: "testnet",
936
+ /**
937
+ * Devnet.
938
+ */
939
+ Devnet: "devnet",
940
+ /**
941
+ * Mainnet.
942
+ */
943
+ Mainnet: "mainnet"
944
+ };
945
+
514
946
  exports.Iota = Iota;
947
+ exports.IotaSmartContractUtils = IotaSmartContractUtils;
948
+ exports.NetworkTypes = NetworkTypes;