@0xobelisk/sui-client 1.0.3 → 1.0.5

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/src/dubhe.ts CHANGED
@@ -9,6 +9,7 @@ import type {
9
9
  SuiMoveNormalizedModules,
10
10
  SuiMoveNormalizedType,
11
11
  SuiObjectData,
12
+ SuiMoveNormalizedModule,
12
13
  } from '@mysten/sui/client';
13
14
  import { SuiAccountManager } from './libs/suiAccountManager';
14
15
  import { SuiTx } from './libs/suiTxBuilder';
@@ -18,12 +19,14 @@ import {
18
19
  MoveStructType,
19
20
  DubheObjectContent,
20
21
  SuiDubheReturnType,
22
+ MoveEnumType,
21
23
  } from './types';
22
24
  import { SuiContractFactory } from './libs/suiContractFactory';
23
25
  import {
24
26
  SuiMoveMoudleFuncType,
25
27
  SuiMoveMoudleValueType,
26
28
  } from './libs/suiContractFactory/types';
29
+ import { getDefaultURL, NetworkConfig } from './libs/suiInteractor';
27
30
  import {
28
31
  ContractQuery,
29
32
  ContractTx,
@@ -37,7 +40,11 @@ import {
37
40
  SuiObjectArg,
38
41
  SuiVecTxArg,
39
42
  } from './types';
40
- import { normalizeHexAddress, numberToAddressHex } from './utils';
43
+ import {
44
+ normalizeHexAddress,
45
+ normalizePackageId,
46
+ numberToAddressHex,
47
+ } from './utils';
41
48
  import { bcs, fromHEX, toHEX } from '@mysten/bcs';
42
49
  import { ContractDataParsingError } from './errors';
43
50
 
@@ -237,7 +244,7 @@ export class Dubhe {
237
244
  fullnodeUrls = fullnodeUrls || [getFullnodeUrl(networkType ?? 'mainnet')];
238
245
  this.suiInteractor = new SuiInteractor(fullnodeUrls, networkType);
239
246
 
240
- this.packageId = packageId;
247
+ this.packageId = packageId ? normalizePackageId(packageId) : undefined;
241
248
  if (metadata !== undefined) {
242
249
  this.metadata = metadata as SuiMoveNormalizedModules;
243
250
 
@@ -248,10 +255,38 @@ export class Dubhe {
248
255
  let loopFlag = false;
249
256
  Object.values(metadata as SuiMoveNormalizedModules).forEach(
250
257
  (moudlevalue) => {
251
- const data = moudlevalue as SuiMoveMoudleValueType;
258
+ const data = moudlevalue as SuiMoveNormalizedModule;
252
259
  const moduleName = data.name;
253
260
  const objMoudleId = `${packageId}::${moduleName}`;
254
261
 
262
+ if (data.enums) {
263
+ Object.entries(data.enums).forEach(([enumName, enumType]) => {
264
+ const objectId = `${objMoudleId}::${enumName}`;
265
+ const bcsmeta: MoveEnumType = {
266
+ objectId,
267
+ objectName: enumName,
268
+ objectType: enumType,
269
+ };
270
+ // console.log('--------');
271
+ // console.log(JSON.stringify(bcsmeta, null, 2));
272
+ // if (isUndefined(this.#object[objectId])) {
273
+ let bcsObj = this.#bcsenum(bcsmeta);
274
+ if (bcsObj.loopFlag === true) {
275
+ loopFlag = bcsObj.loopFlag;
276
+ }
277
+ if (this.#object[objectId] === undefined) {
278
+ this.#object[objectId] = bcsObj.bcs;
279
+ this.#object[`vector<${objectId}>`] = bcs.vector(bcsObj.bcs);
280
+ this.#object[`vector<vector<${objectId}>>`] = bcs.vector(
281
+ bcs.vector(bcsObj.bcs)
282
+ );
283
+ this.#object[`0x1::option::Option<${objectId}>`] = bcs.option(
284
+ bcsObj.bcs
285
+ );
286
+ }
287
+ });
288
+ }
289
+
255
290
  Object.entries(data.structs).forEach(([objectName, objectType]) => {
256
291
  const objectId = `${objMoudleId}::${objectName}`;
257
292
  const bcsmeta: MoveStructType = {
@@ -373,6 +408,13 @@ export class Dubhe {
373
408
  return await this.inspectTxn(tx);
374
409
  };
375
410
 
411
+ #getVectorDepth = (field: SuiMoveNormalizedType): number => {
412
+ if (typeof field === 'object' && 'Vector' in field) {
413
+ return 1 + this.#getVectorDepth(field.Vector);
414
+ }
415
+ return 0;
416
+ };
417
+
376
418
  #bcs = (bcsmeta: MoveStructType) => {
377
419
  let loopFlag = false;
378
420
  const bcsJson: Record<string, BcsType<any, any>> = {};
@@ -483,40 +525,68 @@ export class Dubhe {
483
525
  }
484
526
  return;
485
527
  case 'Vector':
486
- switch (value) {
487
- case 'U8':
488
- bcsJson[objName] = bcs.vector(bcs.u8());
489
- return;
490
- case 'U16':
491
- bcsJson[objName] = bcs.vector(bcs.u16());
492
- return;
493
- case 'U32':
494
- bcsJson[objName] = bcs.vector(bcs.u32());
495
- return;
496
- case 'U64':
497
- bcsJson[objName] = bcs.vector(bcs.u64());
498
- return;
499
- case 'U128':
500
- bcsJson[objName] = bcs.vector(bcs.u128());
501
- return;
502
- case 'U256':
503
- bcsJson[objName] = bcs.vector(bcs.u256());
504
- return;
505
- case 'Bool':
506
- bcsJson[objName] = bcs.vector(bcs.bool());
507
- return;
508
- case 'Address':
509
- bcsJson[objName] = bcs.vector(
510
- bcs.bytes(32).transform({
511
- // To change the input type, you need to provide a type definition for the input
512
- input: (val: string) => fromHEX(val),
513
- output: (val) => toHEX(val),
514
- })
515
- );
528
+ if (typeof value === 'string') {
529
+ switch (value) {
530
+ case 'U8':
531
+ bcsJson[objName] = bcs.vector(bcs.u8());
532
+ return;
533
+ case 'U16':
534
+ bcsJson[objName] = bcs.vector(bcs.u16());
535
+ return;
536
+ case 'U32':
537
+ bcsJson[objName] = bcs.vector(bcs.u32());
538
+ return;
539
+ case 'U64':
540
+ bcsJson[objName] = bcs.vector(bcs.u64());
541
+ return;
542
+ case 'U128':
543
+ bcsJson[objName] = bcs.vector(bcs.u128());
544
+ return;
545
+ case 'U256':
546
+ bcsJson[objName] = bcs.vector(bcs.u256());
547
+ return;
548
+ case 'Bool':
549
+ bcsJson[objName] = bcs.vector(bcs.bool());
550
+ return;
551
+ case 'Address':
552
+ bcsJson[objName] = bcs.vector(
553
+ bcs.bytes(32).transform({
554
+ // To change the input type, you need to provide a type definition for the input
555
+ input: (val: string) => fromHEX(val),
556
+ output: (val) => toHEX(val),
557
+ })
558
+ );
559
+ return;
560
+ default:
561
+ // throw new Error('Unsupported type');
562
+ }
563
+ }
564
+ if (typeof value === 'object') {
565
+ const vectorDepth = this.#getVectorDepth(value);
566
+ let innerType = value;
567
+ for (let i = 0; i < vectorDepth; i++) {
568
+ innerType = innerType.Vector;
569
+ }
570
+
571
+ if ('Struct' in innerType) {
572
+ const structType = innerType.Struct;
573
+ const structId = `${structType.address}::${structType.module}::${structType.name}`;
574
+
575
+ let bcsType = this.#object[structId];
576
+ if (!bcsType) {
577
+ loopFlag = true;
578
+ return;
579
+ }
580
+ let baseType = bcsType;
581
+ for (let i = 0; i <= vectorDepth; i++) {
582
+ baseType = bcs.vector(baseType);
583
+ }
584
+
585
+ bcsJson[objName] = baseType;
516
586
  return;
517
- default:
518
- // throw new Error('Unsupported type');
587
+ }
519
588
  }
589
+ return;
520
590
  case 'TypeParameter':
521
591
  bcsJson[objName] = bcs.u128();
522
592
  return;
@@ -573,6 +643,233 @@ export class Dubhe {
573
643
  };
574
644
  };
575
645
 
646
+ #bcsenum = (bcsmeta: MoveEnumType) => {
647
+ let loopFlag = false;
648
+ const variantJson: Record<string, BcsType<any, any> | null> = {};
649
+
650
+ // const databcs = bcs.vector(
651
+ // bcs.struct('Account', {
652
+ // balance: bcs.u64(),
653
+ // status: bcs.enum('AccountStatus', {
654
+ // Liquid: null,
655
+ // Frozen: null,
656
+ // Blocked: null,
657
+ // }),
658
+ // })
659
+ // );
660
+
661
+ Object.entries(bcsmeta.objectType.variants).forEach(([name, type]) => {
662
+ if (type.length > 0) {
663
+ Object.entries(type).forEach(([index, value]) => {
664
+ const objType: SuiMoveNormalizedType = value.type;
665
+ const objName = value.name;
666
+ switch (typeof objType) {
667
+ case 'object':
668
+ for (const [key, value] of Object.entries(objType)) {
669
+ switch (key) {
670
+ case 'Struct':
671
+ const structType = value as {
672
+ address: string;
673
+ module: string;
674
+ name: string;
675
+ typeArguments: SuiMoveNormalizedType[];
676
+ };
677
+ if (
678
+ structType.address === '0x1' &&
679
+ structType.module === 'ascii' &&
680
+ structType.name === 'String'
681
+ ) {
682
+ variantJson[objName] = bcs.string();
683
+ return;
684
+ } else if (
685
+ structType.address === '0x2' &&
686
+ structType.module === 'object' &&
687
+ structType.name === 'UID'
688
+ ) {
689
+ variantJson[objName] = bcs
690
+ .fixedArray(32, bcs.u8())
691
+ .transform({
692
+ input: (id: string) => fromHEX(id),
693
+ output: (id) => toHEX(Uint8Array.from(id)),
694
+ });
695
+ return;
696
+ } else if (
697
+ structType.address === '0x2' &&
698
+ structType.module === 'object' &&
699
+ structType.name === 'ID'
700
+ ) {
701
+ variantJson[objName] = bcs
702
+ .fixedArray(32, bcs.u8())
703
+ .transform({
704
+ input: (id: string) => fromHEX(id),
705
+ output: (id) => toHEX(Uint8Array.from(id)),
706
+ });
707
+ return;
708
+ } else if (
709
+ structType.address === '0x2' &&
710
+ structType.module === 'bag' &&
711
+ structType.name === 'Bag'
712
+ ) {
713
+ variantJson[objName] = bcs
714
+ .fixedArray(32, bcs.u8())
715
+ .transform({
716
+ input: (id: string) => fromHEX(id),
717
+ output: (id) => toHEX(Uint8Array.from(id)),
718
+ });
719
+ return;
720
+ } else if (
721
+ structType.address === '0x1' &&
722
+ structType.module === 'option' &&
723
+ structType.name === 'Option'
724
+ ) {
725
+ switch (structType.typeArguments[0]) {
726
+ case 'U8':
727
+ variantJson[objName] = bcs.option(bcs.u8());
728
+ return;
729
+ case 'U16':
730
+ variantJson[objName] = bcs.option(bcs.u16());
731
+ return;
732
+ case 'U32':
733
+ variantJson[objName] = bcs.option(bcs.u32());
734
+ return;
735
+ case 'U64':
736
+ variantJson[objName] = bcs.option(bcs.u64());
737
+ return;
738
+ case 'U128':
739
+ variantJson[objName] = bcs.option(bcs.u128());
740
+ return;
741
+ case 'U256':
742
+ variantJson[objName] = bcs.option(bcs.u256());
743
+ return;
744
+ case 'Bool':
745
+ variantJson[objName] = bcs.option(bcs.bool());
746
+ return;
747
+ case 'Address':
748
+ variantJson[objName] = bcs.option(
749
+ bcs.bytes(32).transform({
750
+ // To change the input type, you need to provide a type definition for the input
751
+ input: (val: string) => fromHEX(val),
752
+ output: (val) => toHEX(val),
753
+ })
754
+ );
755
+ return;
756
+ default:
757
+ // throw new Error('Unsupported type');
758
+ }
759
+ } else {
760
+ if (
761
+ this.object[
762
+ `${structType.address}::${structType.module}::${structType.name}`
763
+ ] === undefined
764
+ ) {
765
+ loopFlag = true;
766
+ } else {
767
+ variantJson[objName] =
768
+ this.object[
769
+ `${structType.address}::${structType.module}::${structType.name}`
770
+ ];
771
+ return;
772
+ }
773
+ }
774
+ return;
775
+ case 'Vector':
776
+ if (typeof value === 'string') {
777
+ switch (value) {
778
+ case 'U8':
779
+ variantJson[objName] = bcs.vector(bcs.u8());
780
+ return;
781
+ case 'U16':
782
+ variantJson[objName] = bcs.vector(bcs.u16());
783
+ return;
784
+ case 'U32':
785
+ variantJson[objName] = bcs.vector(bcs.u32());
786
+ return;
787
+ case 'U64':
788
+ variantJson[objName] = bcs.vector(bcs.u64());
789
+ return;
790
+ case 'U128':
791
+ variantJson[objName] = bcs.vector(bcs.u128());
792
+ return;
793
+ case 'U256':
794
+ variantJson[objName] = bcs.vector(bcs.u256());
795
+ return;
796
+ case 'Bool':
797
+ variantJson[objName] = bcs.vector(bcs.bool());
798
+ return;
799
+ case 'Address':
800
+ variantJson[objName] = bcs.vector(
801
+ bcs.bytes(32).transform({
802
+ // To change the input type, you need to provide a type definition for the input
803
+ input: (val: string) => fromHEX(val),
804
+ output: (val) => toHEX(val),
805
+ })
806
+ );
807
+ return;
808
+ default:
809
+ // throw new Error('Unsupported type');
810
+ }
811
+ }
812
+ // if (typeof value === 'object') {
813
+ // }
814
+ case 'TypeParameter':
815
+ variantJson[objName] = bcs.u128();
816
+ return;
817
+ // case 'Reference':
818
+
819
+ // case 'MutableReference':
820
+
821
+ default:
822
+ throw new Error('Unsupported type');
823
+ }
824
+ }
825
+ return;
826
+ case 'string':
827
+ switch (objType) {
828
+ case 'U8':
829
+ variantJson[objName] = bcs.u8();
830
+ return;
831
+ case 'U16':
832
+ variantJson[objName] = bcs.u16();
833
+ return;
834
+ case 'U32':
835
+ variantJson[objName] = bcs.u32();
836
+ return;
837
+ case 'U64':
838
+ variantJson[objName] = bcs.u64();
839
+ return;
840
+ case 'U128':
841
+ variantJson[objName] = bcs.u128();
842
+ return;
843
+ case 'U256':
844
+ variantJson[objName] = bcs.u256();
845
+ return;
846
+ case 'Bool':
847
+ variantJson[objName] = bcs.bool();
848
+ return;
849
+ case 'Address':
850
+ variantJson[objName] = bcs.bytes(32).transform({
851
+ // To change the input type, you need to provide a type definition for the input
852
+ input: (val: string) => fromHEX(val),
853
+ output: (val) => toHEX(val),
854
+ });
855
+ return;
856
+ default:
857
+ return;
858
+ }
859
+ default:
860
+ throw new Error('Unsupported type');
861
+ }
862
+ });
863
+ } else {
864
+ variantJson[name] = null;
865
+ }
866
+ });
867
+ return {
868
+ bcs: bcs.enum(bcsmeta.objectName, variantJson),
869
+ loopFlag,
870
+ };
871
+ };
872
+
576
873
  view(dryResult: DevInspectResults) {
577
874
  let returnValues = [];
578
875
 
@@ -652,6 +949,10 @@ export class Dubhe {
652
949
  }
653
950
 
654
951
  if (this.#object[baseType]) {
952
+ // console.log('=========== here');
953
+ // console.log(baseType);
954
+ // console.log(JSON.stringify(this.#object[baseType], null, 2));
955
+ // console.log('-------------');
655
956
  returnValues.push(this.#object[baseType].parse(value));
656
957
  continue;
657
958
  }
@@ -698,21 +999,45 @@ export class Dubhe {
698
999
  }
699
1000
 
700
1001
  async state({
1002
+ tx,
1003
+ schema,
1004
+ params,
1005
+ }: {
1006
+ tx: Transaction;
1007
+ schema: string;
1008
+ params: any[];
1009
+ }): Promise<any[] | undefined> {
1010
+ const moduleName = `schema`;
1011
+ const functionName = `get_${schema}`;
1012
+
1013
+ let queryResponse = undefined;
1014
+ try {
1015
+ queryResponse = (await this.query[moduleName][functionName]({
1016
+ tx,
1017
+ params,
1018
+ })) as DevInspectResults;
1019
+
1020
+ if (queryResponse.effects.status.status !== 'success') {
1021
+ return undefined;
1022
+ }
1023
+ } catch {
1024
+ return undefined;
1025
+ }
1026
+ return this.view(queryResponse);
1027
+ }
1028
+
1029
+ async parseState({
701
1030
  schema,
702
- field,
703
1031
  objectId,
704
1032
  storageType,
705
1033
  params,
706
1034
  }: {
707
1035
  schema: string;
708
- field: string;
709
1036
  objectId: string;
710
1037
  storageType: string; // 'StorageValue<V>' | 'StorageMap<K, V>' | 'StorageDoubleMap<K1, K2, V>'
711
1038
  params: any[];
712
- }) {
1039
+ }): Promise<any[] | undefined> {
713
1040
  const tx = new Transaction();
714
- const moduleName = `${schema}_schema`;
715
- const functionName = `get_${field}`;
716
1041
  const schemaObject = tx.object(objectId);
717
1042
  // Parse storage type
718
1043
  const storageValueMatch = storageType.match(/^StorageValue<(.+)>$/);
@@ -753,11 +1078,11 @@ export class Dubhe {
753
1078
  `Invalid storage type: ${storageType}. Must be StorageValue<V>, StorageMap<K,V>, or StorageDoubleMap<K1,K2,V>`
754
1079
  );
755
1080
  }
756
- const queryResponse = (await this.query[moduleName][functionName]({
1081
+ return this.state({
757
1082
  tx,
1083
+ schema,
758
1084
  params: processedParams,
759
- })) as DevInspectResults;
760
- return this.view(queryResponse);
1085
+ });
761
1086
  }
762
1087
 
763
1088
  #processKeyParameter(tx: Transaction, keyType: string, value: any) {
@@ -805,12 +1130,11 @@ export class Dubhe {
805
1130
  }
806
1131
 
807
1132
  /**
808
- * if derivePathParams is not provided or mnemonics is empty, it will return the keypair.
809
1133
  * else:
810
1134
  * it will generate signer from the mnemonic with the given derivePathParams.
811
1135
  * @param derivePathParams, such as { accountIndex: 2, isExternal: false, addressIndex: 10 }, comply with the BIP44 standard
812
1136
  */
813
- getKeypair(derivePathParams?: DerivePathParams) {
1137
+ getSigner(derivePathParams?: DerivePathParams) {
814
1138
  return this.accountManager.getKeyPair(derivePathParams);
815
1139
  }
816
1140
 
@@ -845,6 +1169,23 @@ export class Dubhe {
845
1169
  getNetwork() {
846
1170
  return this.suiInteractor.network;
847
1171
  }
1172
+
1173
+ getNetworkConfig(): NetworkConfig {
1174
+ return getDefaultURL(this.getNetwork());
1175
+ }
1176
+
1177
+ getTxExplorerUrl(txHash: string) {
1178
+ return this.getNetworkConfig().txExplorer.replace(':txHash', txHash);
1179
+ }
1180
+
1181
+ getAccountExplorerUrl(address: string) {
1182
+ return this.getNetworkConfig().accountExplorer.replace(':address', address);
1183
+ }
1184
+
1185
+ getExplorerUrl() {
1186
+ return this.getNetworkConfig().explorer;
1187
+ }
1188
+
848
1189
  /**
849
1190
  * Request some SUI from faucet
850
1191
  * @Returns {Promise<boolean>}, true if the request is successful, false otherwise.
@@ -907,7 +1248,7 @@ export class Dubhe {
907
1248
  txBlock instanceof Transaction
908
1249
  ? await txBlock.build({ client: this.client() })
909
1250
  : txBlock;
910
- const keyPair = this.getKeypair(derivePathParams);
1251
+ const keyPair = this.getSigner(derivePathParams);
911
1252
  return await keyPair.signTransaction(txBytes);
912
1253
  }
913
1254
 
@@ -916,14 +1257,18 @@ export class Dubhe {
916
1257
  derivePathParams?: DerivePathParams
917
1258
  ): Promise<SuiTransactionBlockResponse> {
918
1259
  const { bytes, signature } = await this.signTxn(tx, derivePathParams);
919
- return this.suiInteractor.sendTx(bytes, signature);
1260
+ return this.sendTx(bytes, signature);
920
1261
  }
921
1262
 
922
- async sendTxn(
923
- transactionBlock: Uint8Array | string,
1263
+ async sendTx(
1264
+ transaction: Uint8Array | string,
924
1265
  signature: string | string[]
925
1266
  ): Promise<SuiTransactionBlockResponse> {
926
- return this.suiInteractor.sendTx(transactionBlock, signature);
1267
+ return this.suiInteractor.sendTx(transaction, signature);
1268
+ }
1269
+
1270
+ async waitForTransaction(digest: string) {
1271
+ return this.suiInteractor.waitForTransaction({ digest });
927
1272
  }
928
1273
 
929
1274
  /**
@@ -0,0 +1,63 @@
1
+ import { NetworkType } from 'src/types';
2
+
3
+ export interface NetworkConfig {
4
+ fullNode: string;
5
+ graphql?: string;
6
+ network: string;
7
+ txExplorer: string;
8
+ accountExplorer: string;
9
+ explorer: string;
10
+ }
11
+
12
+ export const getDefaultURL = (
13
+ networkType: NetworkType = 'testnet'
14
+ ): NetworkConfig => {
15
+ switch (networkType) {
16
+ case 'localnet':
17
+ return {
18
+ fullNode: 'http://127.0.0.1:9000',
19
+ graphql: 'http://127.0.0.1:9125',
20
+ network: 'localnet',
21
+ txExplorer:
22
+ 'https://explorer.polymedia.app/txblock/:txHash?network=local',
23
+ accountExplorer:
24
+ 'https://explorer.polymedia.app/address/:address?network=local',
25
+ explorer: 'https://explorer.polymedia.app?network=local',
26
+ };
27
+ case 'devnet':
28
+ return {
29
+ fullNode: 'https://fullnode.devnet.sui.io:443',
30
+ network: 'devnet',
31
+ txExplorer: 'https://suiscan.xyz/devnet/tx/:txHash',
32
+ accountExplorer: 'https://suiscan.xyz/devnet/address/:address',
33
+ explorer: 'https://suiscan.xyz/devnet',
34
+ };
35
+ case 'testnet':
36
+ return {
37
+ fullNode: 'https://fullnode.testnet.sui.io:443',
38
+ graphql: 'https://sui-testnet.mystenlabs.com/graphql',
39
+ network: 'testnet',
40
+ txExplorer: 'https://suiscan.xyz/testnet/tx/:txHash',
41
+ accountExplorer: 'https://suiscan.xyz/testnet/address/:address',
42
+ explorer: 'https://suiscan.xyz/testnet',
43
+ };
44
+ case 'mainnet':
45
+ return {
46
+ fullNode: 'https://fullnode.mainnet.sui.io:443',
47
+ graphql: 'https://sui-mainnet.mystenlabs.com/graphql',
48
+ network: 'mainnet',
49
+ txExplorer: 'https://suiscan.xyz/mainnet/tx/:txHash',
50
+ accountExplorer: 'https://suiscan.xyz/mainnet/address/:address',
51
+ explorer: 'https://suiscan.xyz/mainnet',
52
+ };
53
+ default:
54
+ return {
55
+ fullNode: 'https://fullnode.testnet.sui.io:443',
56
+ graphql: 'https://sui-testnet.mystenlabs.com/graphql',
57
+ network: 'testnet',
58
+ txExplorer: 'https://suiscan.xyz/testnet/tx/:txHash',
59
+ accountExplorer: 'https://suiscan.xyz/testnet/address/:address',
60
+ explorer: 'https://suiscan.xyz/testnet',
61
+ };
62
+ }
63
+ };
@@ -1 +1,3 @@
1
1
  export { SuiInteractor } from './suiInteractor';
2
+ export { getDefaultURL } from './defaultConfig';
3
+ export type { NetworkConfig } from './defaultConfig';
@@ -76,6 +76,32 @@ export class SuiInteractor {
76
76
  throw new Error('Failed to send transaction with all fullnodes');
77
77
  }
78
78
 
79
+ async waitForTransaction({
80
+ digest,
81
+ timeout = 60 * 1000,
82
+ pollInterval = 2 * 1000,
83
+ }: {
84
+ digest: string;
85
+ timeout?: number;
86
+ pollInterval?: number;
87
+ }) {
88
+ for (const clientIdx in this.clients) {
89
+ try {
90
+ return await this.clients[clientIdx].waitForTransaction({
91
+ digest,
92
+ timeout,
93
+ pollInterval,
94
+ });
95
+ } catch (err) {
96
+ console.warn(
97
+ `Failed to wait for transaction with fullnode ${this.fullNodes[clientIdx]}: ${err}`
98
+ );
99
+ await delay(2000);
100
+ }
101
+ }
102
+ throw new Error('Failed to wait for transaction with all fullnodes');
103
+ }
104
+
79
105
  async getObjects(
80
106
  ids: string[],
81
107
  options?: SuiObjectDataOptions