@0xobelisk/sui-client 1.0.2 → 1.0.4

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.
@@ -0,0 +1,10 @@
1
+ import { NetworkType } from 'src/types';
2
+ export interface NetworkConfig {
3
+ fullNode: string;
4
+ graphql?: string;
5
+ network: string;
6
+ txExplorer: string;
7
+ accountExplorer: string;
8
+ explorer: string;
9
+ }
10
+ export declare const getDefaultURL: (networkType?: NetworkType) => NetworkConfig;
@@ -1 +1,3 @@
1
1
  export { SuiInteractor } from './suiInteractor';
2
+ export { getDefaultURL } from './defaultConfig';
3
+ export type { NetworkConfig } from './defaultConfig';
@@ -17,6 +17,11 @@ export declare class SuiInteractor {
17
17
  constructor(fullNodeUrls: string[], network?: NetworkType);
18
18
  switchToNextClient(): void;
19
19
  sendTx(transactionBlock: Uint8Array | string, signature: string | string[]): Promise<SuiTransactionBlockResponse>;
20
+ waitForTransaction({ digest, timeout, pollInterval, }: {
21
+ digest: string;
22
+ timeout?: number;
23
+ pollInterval?: number;
24
+ }): Promise<SuiTransactionBlockResponse>;
20
25
  getObjects(ids: string[], options?: SuiObjectDataOptions): Promise<SuiObjectData[]>;
21
26
  getObject(id: string): Promise<SuiObjectData>;
22
27
  getDynamicFieldObject(parentId: string, name: RpcTypes.DynamicFieldName): Promise<RpcTypes.SuiObjectResponse>;
@@ -47,7 +47,7 @@ export declare class SuiTx {
47
47
  resultIndex: number;
48
48
  })[];
49
49
  kind: "MoveCall";
50
- target: `${string}::${string}::${string}`;
50
+ target: import("valibot").GenericSchema<`${string}::${string}::${string}`>;
51
51
  } | {
52
52
  address: {
53
53
  kind: "Input";
@@ -336,9 +336,21 @@ export declare class SuiTx {
336
336
  transferSuiToMany(recipients: SuiAddressArg[], amounts: (SuiTxArg | number | bigint)[]): this;
337
337
  transferSui(address: SuiAddressArg, amount: SuiTxArg | number | bigint): this;
338
338
  takeAmountFromCoins(coins: SuiObjectArg[], amount: SuiTxArg | number | bigint): TransactionObjectArgument[];
339
- splitSUIFromGas(amounts: SuiAmountsArg[]): import("@mysten/sui/transactions").TransactionResult;
339
+ splitSUIFromGas(amounts: SuiAmountsArg[]): {
340
+ $kind: "Result";
341
+ Result: number;
342
+ } & {
343
+ $kind: "NestedResult";
344
+ NestedResult: [number, number];
345
+ }[];
340
346
  splitMultiCoins(coins: SuiObjectArg[], amounts: SuiAmountsArg[]): {
341
- splitedCoins: import("@mysten/sui/transactions").TransactionResult;
347
+ splitedCoins: {
348
+ $kind: "Result";
349
+ Result: number;
350
+ } & {
351
+ $kind: "NestedResult";
352
+ NestedResult: [number, number];
353
+ }[];
342
354
  mergedCoin: TransactionObjectArgument;
343
355
  };
344
356
  transferCoinToMany(coins: SuiObjectArg[], sender: SuiAddressArg, recipients: SuiAddressArg[], amounts: SuiAmountsArg[]): this;
@@ -2,7 +2,7 @@ import type { Infer } from 'superstruct';
2
2
  import type { BcsType, SerializedBcs } from '@mysten/bcs';
3
3
  import type { TransactionArgument } from '@mysten/sui/transactions';
4
4
  import type { Transaction, TransactionObjectArgument, TransactionResult, Argument, Inputs } from '@mysten/sui/transactions';
5
- import type { SuiMoveNormalizedModules, DevInspectResults, SuiTransactionBlockResponse, DisplayFieldsResponse, SuiMoveNormalizedType, MoveStruct } from '@mysten/sui/client';
5
+ import type { SuiMoveNormalizedModules, DevInspectResults, SuiTransactionBlockResponse, DisplayFieldsResponse, MoveStruct, SuiMoveNormalizedEnum, SuiMoveNormalizedStruct } from '@mysten/sui/client';
6
6
  import { SuiTx } from '../libs/suiTxBuilder';
7
7
  import { SuiMoveMoudleFuncType } from '../libs/suiContractFactory/types';
8
8
  export declare const ObjectContentFields: import("superstruct").Struct<Record<string, any>, null>;
@@ -79,24 +79,14 @@ export type MapMessageTx = Record<string, ContractTx>;
79
79
  export type MapMessageQuery = Record<string, ContractQuery>;
80
80
  export type MapMoudleFuncTx = Record<string, MapMessageTx>;
81
81
  export type MapMoudleFuncQuery = Record<string, MapMessageQuery>;
82
- export type MoveStructValueType = {
83
- fields: {
84
- type: SuiMoveNormalizedType;
85
- name: string;
86
- }[];
87
- abilities: {
88
- abilities: string[];
89
- };
90
- typeParameters: {
91
- constraints: {
92
- abilities: string[];
93
- };
94
- isPhantom: boolean;
95
- }[];
96
- };
97
82
  export type MoveStructType = {
98
83
  objectId: string;
99
- objectType: MoveStructValueType;
84
+ objectType: SuiMoveNormalizedStruct;
85
+ objectName: string;
86
+ };
87
+ export type MoveEnumType = {
88
+ objectId: string;
89
+ objectType: SuiMoveNormalizedEnum;
100
90
  objectName: string;
101
91
  };
102
92
  export type MapObjectStruct = Record<string, BcsType<any, any>>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@0xobelisk/sui-client",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Tookit for interacting with move eps framework",
5
5
  "keywords": [
6
6
  "sui",
@@ -37,8 +37,8 @@
37
37
  "src"
38
38
  ],
39
39
  "dependencies": {
40
- "@mysten/bcs": "^1.0.4",
41
- "@mysten/sui": "^1.7.0",
40
+ "@mysten/bcs": "^1.2.1",
41
+ "@mysten/sui": "^1.19.0",
42
42
  "@noble/curves": "^1.4.2",
43
43
  "@noble/hashes": "^1.4.0",
44
44
  "@scure/bip39": "^1.3.0",
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,
@@ -248,10 +251,38 @@ export class Dubhe {
248
251
  let loopFlag = false;
249
252
  Object.values(metadata as SuiMoveNormalizedModules).forEach(
250
253
  (moudlevalue) => {
251
- const data = moudlevalue as SuiMoveMoudleValueType;
254
+ const data = moudlevalue as SuiMoveNormalizedModule;
252
255
  const moduleName = data.name;
253
256
  const objMoudleId = `${packageId}::${moduleName}`;
254
257
 
258
+ if (data.enums) {
259
+ Object.entries(data.enums).forEach(([enumName, enumType]) => {
260
+ const objectId = `${objMoudleId}::${enumName}`;
261
+ const bcsmeta: MoveEnumType = {
262
+ objectId,
263
+ objectName: enumName,
264
+ objectType: enumType,
265
+ };
266
+ // console.log('--------');
267
+ // console.log(JSON.stringify(bcsmeta, null, 2));
268
+ // if (isUndefined(this.#object[objectId])) {
269
+ let bcsObj = this.#bcsenum(bcsmeta);
270
+ if (bcsObj.loopFlag === true) {
271
+ loopFlag = bcsObj.loopFlag;
272
+ }
273
+ if (this.#object[objectId] === undefined) {
274
+ this.#object[objectId] = bcsObj.bcs;
275
+ this.#object[`vector<${objectId}>`] = bcs.vector(bcsObj.bcs);
276
+ this.#object[`vector<vector<${objectId}>>`] = bcs.vector(
277
+ bcs.vector(bcsObj.bcs)
278
+ );
279
+ this.#object[`0x1::option::Option<${objectId}>`] = bcs.option(
280
+ bcsObj.bcs
281
+ );
282
+ }
283
+ });
284
+ }
285
+
255
286
  Object.entries(data.structs).forEach(([objectName, objectType]) => {
256
287
  const objectId = `${objMoudleId}::${objectName}`;
257
288
  const bcsmeta: MoveStructType = {
@@ -373,6 +404,13 @@ export class Dubhe {
373
404
  return await this.inspectTxn(tx);
374
405
  };
375
406
 
407
+ #getVectorDepth = (field: SuiMoveNormalizedType): number => {
408
+ if (typeof field === 'object' && 'Vector' in field) {
409
+ return 1 + this.#getVectorDepth(field.Vector);
410
+ }
411
+ return 0;
412
+ };
413
+
376
414
  #bcs = (bcsmeta: MoveStructType) => {
377
415
  let loopFlag = false;
378
416
  const bcsJson: Record<string, BcsType<any, any>> = {};
@@ -483,40 +521,68 @@ export class Dubhe {
483
521
  }
484
522
  return;
485
523
  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
- );
524
+ if (typeof value === 'string') {
525
+ switch (value) {
526
+ case 'U8':
527
+ bcsJson[objName] = bcs.vector(bcs.u8());
528
+ return;
529
+ case 'U16':
530
+ bcsJson[objName] = bcs.vector(bcs.u16());
531
+ return;
532
+ case 'U32':
533
+ bcsJson[objName] = bcs.vector(bcs.u32());
534
+ return;
535
+ case 'U64':
536
+ bcsJson[objName] = bcs.vector(bcs.u64());
537
+ return;
538
+ case 'U128':
539
+ bcsJson[objName] = bcs.vector(bcs.u128());
540
+ return;
541
+ case 'U256':
542
+ bcsJson[objName] = bcs.vector(bcs.u256());
543
+ return;
544
+ case 'Bool':
545
+ bcsJson[objName] = bcs.vector(bcs.bool());
546
+ return;
547
+ case 'Address':
548
+ bcsJson[objName] = bcs.vector(
549
+ bcs.bytes(32).transform({
550
+ // To change the input type, you need to provide a type definition for the input
551
+ input: (val: string) => fromHEX(val),
552
+ output: (val) => toHEX(val),
553
+ })
554
+ );
555
+ return;
556
+ default:
557
+ // throw new Error('Unsupported type');
558
+ }
559
+ }
560
+ if (typeof value === 'object') {
561
+ const vectorDepth = this.#getVectorDepth(value);
562
+ let innerType = value;
563
+ for (let i = 0; i < vectorDepth; i++) {
564
+ innerType = innerType.Vector;
565
+ }
566
+
567
+ if ('Struct' in innerType) {
568
+ const structType = innerType.Struct;
569
+ const structId = `${structType.address}::${structType.module}::${structType.name}`;
570
+
571
+ let bcsType = this.#object[structId];
572
+ if (!bcsType) {
573
+ loopFlag = true;
574
+ return;
575
+ }
576
+ let baseType = bcsType;
577
+ for (let i = 0; i <= vectorDepth; i++) {
578
+ baseType = bcs.vector(baseType);
579
+ }
580
+
581
+ bcsJson[objName] = baseType;
516
582
  return;
517
- default:
518
- // throw new Error('Unsupported type');
583
+ }
519
584
  }
585
+ return;
520
586
  case 'TypeParameter':
521
587
  bcsJson[objName] = bcs.u128();
522
588
  return;
@@ -573,6 +639,233 @@ export class Dubhe {
573
639
  };
574
640
  };
575
641
 
642
+ #bcsenum = (bcsmeta: MoveEnumType) => {
643
+ let loopFlag = false;
644
+ const variantJson: Record<string, BcsType<any, any> | null> = {};
645
+
646
+ // const databcs = bcs.vector(
647
+ // bcs.struct('Account', {
648
+ // balance: bcs.u64(),
649
+ // status: bcs.enum('AccountStatus', {
650
+ // Liquid: null,
651
+ // Frozen: null,
652
+ // Blocked: null,
653
+ // }),
654
+ // })
655
+ // );
656
+
657
+ Object.entries(bcsmeta.objectType.variants).forEach(([name, type]) => {
658
+ if (type.length > 0) {
659
+ Object.entries(type).forEach(([index, value]) => {
660
+ const objType: SuiMoveNormalizedType = value.type;
661
+ const objName = value.name;
662
+ switch (typeof objType) {
663
+ case 'object':
664
+ for (const [key, value] of Object.entries(objType)) {
665
+ switch (key) {
666
+ case 'Struct':
667
+ const structType = value as {
668
+ address: string;
669
+ module: string;
670
+ name: string;
671
+ typeArguments: SuiMoveNormalizedType[];
672
+ };
673
+ if (
674
+ structType.address === '0x1' &&
675
+ structType.module === 'ascii' &&
676
+ structType.name === 'String'
677
+ ) {
678
+ variantJson[objName] = bcs.string();
679
+ return;
680
+ } else if (
681
+ structType.address === '0x2' &&
682
+ structType.module === 'object' &&
683
+ structType.name === 'UID'
684
+ ) {
685
+ variantJson[objName] = bcs
686
+ .fixedArray(32, bcs.u8())
687
+ .transform({
688
+ input: (id: string) => fromHEX(id),
689
+ output: (id) => toHEX(Uint8Array.from(id)),
690
+ });
691
+ return;
692
+ } else if (
693
+ structType.address === '0x2' &&
694
+ structType.module === 'object' &&
695
+ structType.name === 'ID'
696
+ ) {
697
+ variantJson[objName] = bcs
698
+ .fixedArray(32, bcs.u8())
699
+ .transform({
700
+ input: (id: string) => fromHEX(id),
701
+ output: (id) => toHEX(Uint8Array.from(id)),
702
+ });
703
+ return;
704
+ } else if (
705
+ structType.address === '0x2' &&
706
+ structType.module === 'bag' &&
707
+ structType.name === 'Bag'
708
+ ) {
709
+ variantJson[objName] = bcs
710
+ .fixedArray(32, bcs.u8())
711
+ .transform({
712
+ input: (id: string) => fromHEX(id),
713
+ output: (id) => toHEX(Uint8Array.from(id)),
714
+ });
715
+ return;
716
+ } else if (
717
+ structType.address === '0x1' &&
718
+ structType.module === 'option' &&
719
+ structType.name === 'Option'
720
+ ) {
721
+ switch (structType.typeArguments[0]) {
722
+ case 'U8':
723
+ variantJson[objName] = bcs.option(bcs.u8());
724
+ return;
725
+ case 'U16':
726
+ variantJson[objName] = bcs.option(bcs.u16());
727
+ return;
728
+ case 'U32':
729
+ variantJson[objName] = bcs.option(bcs.u32());
730
+ return;
731
+ case 'U64':
732
+ variantJson[objName] = bcs.option(bcs.u64());
733
+ return;
734
+ case 'U128':
735
+ variantJson[objName] = bcs.option(bcs.u128());
736
+ return;
737
+ case 'U256':
738
+ variantJson[objName] = bcs.option(bcs.u256());
739
+ return;
740
+ case 'Bool':
741
+ variantJson[objName] = bcs.option(bcs.bool());
742
+ return;
743
+ case 'Address':
744
+ variantJson[objName] = bcs.option(
745
+ bcs.bytes(32).transform({
746
+ // To change the input type, you need to provide a type definition for the input
747
+ input: (val: string) => fromHEX(val),
748
+ output: (val) => toHEX(val),
749
+ })
750
+ );
751
+ return;
752
+ default:
753
+ // throw new Error('Unsupported type');
754
+ }
755
+ } else {
756
+ if (
757
+ this.object[
758
+ `${structType.address}::${structType.module}::${structType.name}`
759
+ ] === undefined
760
+ ) {
761
+ loopFlag = true;
762
+ } else {
763
+ variantJson[objName] =
764
+ this.object[
765
+ `${structType.address}::${structType.module}::${structType.name}`
766
+ ];
767
+ return;
768
+ }
769
+ }
770
+ return;
771
+ case 'Vector':
772
+ if (typeof value === 'string') {
773
+ switch (value) {
774
+ case 'U8':
775
+ variantJson[objName] = bcs.vector(bcs.u8());
776
+ return;
777
+ case 'U16':
778
+ variantJson[objName] = bcs.vector(bcs.u16());
779
+ return;
780
+ case 'U32':
781
+ variantJson[objName] = bcs.vector(bcs.u32());
782
+ return;
783
+ case 'U64':
784
+ variantJson[objName] = bcs.vector(bcs.u64());
785
+ return;
786
+ case 'U128':
787
+ variantJson[objName] = bcs.vector(bcs.u128());
788
+ return;
789
+ case 'U256':
790
+ variantJson[objName] = bcs.vector(bcs.u256());
791
+ return;
792
+ case 'Bool':
793
+ variantJson[objName] = bcs.vector(bcs.bool());
794
+ return;
795
+ case 'Address':
796
+ variantJson[objName] = bcs.vector(
797
+ bcs.bytes(32).transform({
798
+ // To change the input type, you need to provide a type definition for the input
799
+ input: (val: string) => fromHEX(val),
800
+ output: (val) => toHEX(val),
801
+ })
802
+ );
803
+ return;
804
+ default:
805
+ // throw new Error('Unsupported type');
806
+ }
807
+ }
808
+ // if (typeof value === 'object') {
809
+ // }
810
+ case 'TypeParameter':
811
+ variantJson[objName] = bcs.u128();
812
+ return;
813
+ // case 'Reference':
814
+
815
+ // case 'MutableReference':
816
+
817
+ default:
818
+ throw new Error('Unsupported type');
819
+ }
820
+ }
821
+ return;
822
+ case 'string':
823
+ switch (objType) {
824
+ case 'U8':
825
+ variantJson[objName] = bcs.u8();
826
+ return;
827
+ case 'U16':
828
+ variantJson[objName] = bcs.u16();
829
+ return;
830
+ case 'U32':
831
+ variantJson[objName] = bcs.u32();
832
+ return;
833
+ case 'U64':
834
+ variantJson[objName] = bcs.u64();
835
+ return;
836
+ case 'U128':
837
+ variantJson[objName] = bcs.u128();
838
+ return;
839
+ case 'U256':
840
+ variantJson[objName] = bcs.u256();
841
+ return;
842
+ case 'Bool':
843
+ variantJson[objName] = bcs.bool();
844
+ return;
845
+ case 'Address':
846
+ variantJson[objName] = bcs.bytes(32).transform({
847
+ // To change the input type, you need to provide a type definition for the input
848
+ input: (val: string) => fromHEX(val),
849
+ output: (val) => toHEX(val),
850
+ });
851
+ return;
852
+ default:
853
+ return;
854
+ }
855
+ default:
856
+ throw new Error('Unsupported type');
857
+ }
858
+ });
859
+ } else {
860
+ variantJson[name] = null;
861
+ }
862
+ });
863
+ return {
864
+ bcs: bcs.enum(bcsmeta.objectName, variantJson),
865
+ loopFlag,
866
+ };
867
+ };
868
+
576
869
  view(dryResult: DevInspectResults) {
577
870
  let returnValues = [];
578
871
 
@@ -652,6 +945,10 @@ export class Dubhe {
652
945
  }
653
946
 
654
947
  if (this.#object[baseType]) {
948
+ // console.log('=========== here');
949
+ // console.log(baseType);
950
+ // console.log(JSON.stringify(this.#object[baseType], null, 2));
951
+ // console.log('-------------');
655
952
  returnValues.push(this.#object[baseType].parse(value));
656
953
  continue;
657
954
  }
@@ -698,21 +995,45 @@ export class Dubhe {
698
995
  }
699
996
 
700
997
  async state({
998
+ tx,
999
+ schema,
1000
+ params,
1001
+ }: {
1002
+ tx: Transaction;
1003
+ schema: string;
1004
+ params: any[];
1005
+ }): Promise<any[] | undefined> {
1006
+ const moduleName = `schema`;
1007
+ const functionName = `get_${schema}`;
1008
+
1009
+ let queryResponse = undefined;
1010
+ try {
1011
+ queryResponse = (await this.query[moduleName][functionName]({
1012
+ tx,
1013
+ params,
1014
+ })) as DevInspectResults;
1015
+
1016
+ if (queryResponse.effects.status.status !== 'success') {
1017
+ return undefined;
1018
+ }
1019
+ } catch {
1020
+ return undefined;
1021
+ }
1022
+ return this.view(queryResponse);
1023
+ }
1024
+
1025
+ async parseState({
701
1026
  schema,
702
- struct,
703
1027
  objectId,
704
1028
  storageType,
705
1029
  params,
706
1030
  }: {
707
1031
  schema: string;
708
- struct: string;
709
1032
  objectId: string;
710
1033
  storageType: string; // 'StorageValue<V>' | 'StorageMap<K, V>' | 'StorageDoubleMap<K1, K2, V>'
711
1034
  params: any[];
712
- }) {
1035
+ }): Promise<any[] | undefined> {
713
1036
  const tx = new Transaction();
714
- const moduleName = `${schema}_schema`;
715
- const functionName = `get_${struct}`;
716
1037
  const schemaObject = tx.object(objectId);
717
1038
  // Parse storage type
718
1039
  const storageValueMatch = storageType.match(/^StorageValue<(.+)>$/);
@@ -753,11 +1074,11 @@ export class Dubhe {
753
1074
  `Invalid storage type: ${storageType}. Must be StorageValue<V>, StorageMap<K,V>, or StorageDoubleMap<K1,K2,V>`
754
1075
  );
755
1076
  }
756
- const queryResponse = (await this.query[moduleName][functionName]({
1077
+ return this.state({
757
1078
  tx,
1079
+ schema,
758
1080
  params: processedParams,
759
- })) as DevInspectResults;
760
- return this.view(queryResponse);
1081
+ });
761
1082
  }
762
1083
 
763
1084
  #processKeyParameter(tx: Transaction, keyType: string, value: any) {
@@ -805,12 +1126,11 @@ export class Dubhe {
805
1126
  }
806
1127
 
807
1128
  /**
808
- * if derivePathParams is not provided or mnemonics is empty, it will return the keypair.
809
1129
  * else:
810
1130
  * it will generate signer from the mnemonic with the given derivePathParams.
811
1131
  * @param derivePathParams, such as { accountIndex: 2, isExternal: false, addressIndex: 10 }, comply with the BIP44 standard
812
1132
  */
813
- getKeypair(derivePathParams?: DerivePathParams) {
1133
+ getSigner(derivePathParams?: DerivePathParams) {
814
1134
  return this.accountManager.getKeyPair(derivePathParams);
815
1135
  }
816
1136
 
@@ -845,6 +1165,23 @@ export class Dubhe {
845
1165
  getNetwork() {
846
1166
  return this.suiInteractor.network;
847
1167
  }
1168
+
1169
+ getNetworkConfig(): NetworkConfig {
1170
+ return getDefaultURL(this.getNetwork());
1171
+ }
1172
+
1173
+ getTxExplorerUrl(txHash: string) {
1174
+ return this.getNetworkConfig().txExplorer.replace(':txHash', txHash);
1175
+ }
1176
+
1177
+ getAccountExplorerUrl(address: string) {
1178
+ return this.getNetworkConfig().accountExplorer.replace(':address', address);
1179
+ }
1180
+
1181
+ getExplorerUrl() {
1182
+ return this.getNetworkConfig().explorer;
1183
+ }
1184
+
848
1185
  /**
849
1186
  * Request some SUI from faucet
850
1187
  * @Returns {Promise<boolean>}, true if the request is successful, false otherwise.
@@ -907,7 +1244,7 @@ export class Dubhe {
907
1244
  txBlock instanceof Transaction
908
1245
  ? await txBlock.build({ client: this.client() })
909
1246
  : txBlock;
910
- const keyPair = this.getKeypair(derivePathParams);
1247
+ const keyPair = this.getSigner(derivePathParams);
911
1248
  return await keyPair.signTransaction(txBytes);
912
1249
  }
913
1250
 
@@ -916,14 +1253,18 @@ export class Dubhe {
916
1253
  derivePathParams?: DerivePathParams
917
1254
  ): Promise<SuiTransactionBlockResponse> {
918
1255
  const { bytes, signature } = await this.signTxn(tx, derivePathParams);
919
- return this.suiInteractor.sendTx(bytes, signature);
1256
+ return this.sendTx(bytes, signature);
920
1257
  }
921
1258
 
922
- async sendTxn(
923
- transactionBlock: Uint8Array | string,
1259
+ async sendTx(
1260
+ transaction: Uint8Array | string,
924
1261
  signature: string | string[]
925
1262
  ): Promise<SuiTransactionBlockResponse> {
926
- return this.suiInteractor.sendTx(transactionBlock, signature);
1263
+ return this.suiInteractor.sendTx(transaction, signature);
1264
+ }
1265
+
1266
+ async waitForTransaction(digest: string) {
1267
+ return this.suiInteractor.waitForTransaction({ digest });
927
1268
  }
928
1269
 
929
1270
  /**