@ledgerhq/coin-sui 0.11.0 → 0.12.0-nightly.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (188) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.turbo/turbo-build.log +1 -1
  3. package/.unimportedrc.json +1 -0
  4. package/CHANGELOG.md +21 -0
  5. package/index.d.ts +0 -1
  6. package/jest.config.js +1 -1
  7. package/lib/bridge/broadcast.d.ts.map +1 -1
  8. package/lib/bridge/broadcast.js +3 -0
  9. package/lib/bridge/broadcast.js.map +1 -1
  10. package/lib/bridge/buildOptimisticOperation.js +31 -0
  11. package/lib/bridge/buildOptimisticOperation.js.map +1 -1
  12. package/lib/bridge/buildTransaction.d.ts +1 -1
  13. package/lib/bridge/buildTransaction.d.ts.map +1 -1
  14. package/lib/bridge/buildTransaction.js +3 -1
  15. package/lib/bridge/buildTransaction.js.map +1 -1
  16. package/lib/bridge/buildTransaction.test.js +4 -0
  17. package/lib/bridge/buildTransaction.test.js.map +1 -1
  18. package/lib/bridge/estimateMaxSpendable.d.ts.map +1 -1
  19. package/lib/bridge/estimateMaxSpendable.js +15 -3
  20. package/lib/bridge/estimateMaxSpendable.js.map +1 -1
  21. package/lib/bridge/estimateMaxSpendable.test.js +27 -0
  22. package/lib/bridge/estimateMaxSpendable.test.js.map +1 -1
  23. package/lib/bridge/getFeesForTransaction.d.ts.map +1 -1
  24. package/lib/bridge/getFeesForTransaction.js +13 -1
  25. package/lib/bridge/getFeesForTransaction.js.map +1 -1
  26. package/lib/bridge/getOperationExtra.d.ts +2 -0
  27. package/lib/bridge/getOperationExtra.d.ts.map +1 -0
  28. package/lib/bridge/getOperationExtra.js +6 -0
  29. package/lib/bridge/getOperationExtra.js.map +1 -0
  30. package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
  31. package/lib/bridge/getTransactionStatus.js +45 -20
  32. package/lib/bridge/getTransactionStatus.js.map +1 -1
  33. package/lib/bridge/preload.d.ts.map +1 -1
  34. package/lib/bridge/preload.js +5 -3
  35. package/lib/bridge/preload.js.map +1 -1
  36. package/lib/bridge/preload.test.js +13 -217
  37. package/lib/bridge/preload.test.js.map +1 -1
  38. package/lib/bridge/prepareTransaction.js +1 -1
  39. package/lib/bridge/prepareTransaction.js.map +1 -1
  40. package/lib/bridge/synchronisation.d.ts.map +1 -1
  41. package/lib/bridge/synchronisation.js +5 -2
  42. package/lib/bridge/synchronisation.js.map +1 -1
  43. package/lib/bridge/synchronisation.test.js +355 -7
  44. package/lib/bridge/synchronisation.test.js.map +1 -1
  45. package/lib/bridge/utils.d.ts +1 -1
  46. package/lib/bridge/utils.d.ts.map +1 -1
  47. package/lib/bridge/utils.js +22 -0
  48. package/lib/bridge/utils.js.map +1 -1
  49. package/lib/constants.d.ts +4 -0
  50. package/lib/constants.d.ts.map +1 -0
  51. package/lib/constants.js +7 -0
  52. package/lib/constants.js.map +1 -0
  53. package/lib/errors.d.ts +13 -0
  54. package/lib/errors.d.ts.map +1 -0
  55. package/lib/errors.js +21 -0
  56. package/lib/errors.js.map +1 -0
  57. package/lib/logic/craftTransaction.d.ts +5 -10
  58. package/lib/logic/craftTransaction.d.ts.map +1 -1
  59. package/lib/logic/craftTransaction.js +2 -1
  60. package/lib/logic/craftTransaction.js.map +1 -1
  61. package/lib/logic/estimateFees.d.ts +1 -1
  62. package/lib/logic/estimateFees.d.ts.map +1 -1
  63. package/lib/logic/estimateFees.js +14 -2
  64. package/lib/logic/estimateFees.js.map +1 -1
  65. package/lib/logic/index.d.ts +2 -1
  66. package/lib/logic/index.d.ts.map +1 -1
  67. package/lib/logic/index.js +3 -1
  68. package/lib/logic/index.js.map +1 -1
  69. package/lib/logic/stake.d.ts +3 -0
  70. package/lib/logic/stake.d.ts.map +1 -0
  71. package/lib/logic/stake.js +12 -0
  72. package/lib/logic/stake.js.map +1 -0
  73. package/lib/network/index.d.ts +5 -4
  74. package/lib/network/index.d.ts.map +1 -1
  75. package/lib/network/index.js +5 -3
  76. package/lib/network/index.js.map +1 -1
  77. package/lib/network/sdk.d.ts +5 -3
  78. package/lib/network/sdk.d.ts.map +1 -1
  79. package/lib/network/sdk.js +148 -26
  80. package/lib/network/sdk.js.map +1 -1
  81. package/lib/network/sdk.test.js +491 -6
  82. package/lib/network/sdk.test.js.map +1 -1
  83. package/lib/types/bridge.d.ts +33 -6
  84. package/lib/types/bridge.d.ts.map +1 -1
  85. package/lib-es/bridge/broadcast.d.ts.map +1 -1
  86. package/lib-es/bridge/broadcast.js +3 -0
  87. package/lib-es/bridge/broadcast.js.map +1 -1
  88. package/lib-es/bridge/buildOptimisticOperation.js +31 -0
  89. package/lib-es/bridge/buildOptimisticOperation.js.map +1 -1
  90. package/lib-es/bridge/buildTransaction.d.ts +1 -1
  91. package/lib-es/bridge/buildTransaction.d.ts.map +1 -1
  92. package/lib-es/bridge/buildTransaction.js +3 -1
  93. package/lib-es/bridge/buildTransaction.js.map +1 -1
  94. package/lib-es/bridge/buildTransaction.test.js +4 -0
  95. package/lib-es/bridge/buildTransaction.test.js.map +1 -1
  96. package/lib-es/bridge/estimateMaxSpendable.d.ts.map +1 -1
  97. package/lib-es/bridge/estimateMaxSpendable.js +15 -3
  98. package/lib-es/bridge/estimateMaxSpendable.js.map +1 -1
  99. package/lib-es/bridge/estimateMaxSpendable.test.js +27 -0
  100. package/lib-es/bridge/estimateMaxSpendable.test.js.map +1 -1
  101. package/lib-es/bridge/getFeesForTransaction.d.ts.map +1 -1
  102. package/lib-es/bridge/getFeesForTransaction.js +13 -1
  103. package/lib-es/bridge/getFeesForTransaction.js.map +1 -1
  104. package/lib-es/bridge/getOperationExtra.d.ts +2 -0
  105. package/lib-es/bridge/getOperationExtra.d.ts.map +1 -0
  106. package/lib-es/bridge/getOperationExtra.js +2 -0
  107. package/lib-es/bridge/getOperationExtra.js.map +1 -0
  108. package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
  109. package/lib-es/bridge/getTransactionStatus.js +46 -21
  110. package/lib-es/bridge/getTransactionStatus.js.map +1 -1
  111. package/lib-es/bridge/preload.d.ts.map +1 -1
  112. package/lib-es/bridge/preload.js +5 -3
  113. package/lib-es/bridge/preload.js.map +1 -1
  114. package/lib-es/bridge/preload.test.js +14 -218
  115. package/lib-es/bridge/preload.test.js.map +1 -1
  116. package/lib-es/bridge/prepareTransaction.js +1 -1
  117. package/lib-es/bridge/prepareTransaction.js.map +1 -1
  118. package/lib-es/bridge/synchronisation.d.ts.map +1 -1
  119. package/lib-es/bridge/synchronisation.js +6 -3
  120. package/lib-es/bridge/synchronisation.js.map +1 -1
  121. package/lib-es/bridge/synchronisation.test.js +332 -7
  122. package/lib-es/bridge/synchronisation.test.js.map +1 -1
  123. package/lib-es/bridge/utils.d.ts +1 -1
  124. package/lib-es/bridge/utils.d.ts.map +1 -1
  125. package/lib-es/bridge/utils.js +22 -0
  126. package/lib-es/bridge/utils.js.map +1 -1
  127. package/lib-es/constants.d.ts +4 -0
  128. package/lib-es/constants.d.ts.map +1 -0
  129. package/lib-es/constants.js +4 -0
  130. package/lib-es/constants.js.map +1 -0
  131. package/lib-es/errors.d.ts +13 -0
  132. package/lib-es/errors.d.ts.map +1 -0
  133. package/lib-es/errors.js +18 -0
  134. package/lib-es/errors.js.map +1 -0
  135. package/lib-es/logic/craftTransaction.d.ts +5 -10
  136. package/lib-es/logic/craftTransaction.d.ts.map +1 -1
  137. package/lib-es/logic/craftTransaction.js +2 -1
  138. package/lib-es/logic/craftTransaction.js.map +1 -1
  139. package/lib-es/logic/estimateFees.d.ts +1 -1
  140. package/lib-es/logic/estimateFees.d.ts.map +1 -1
  141. package/lib-es/logic/estimateFees.js +14 -2
  142. package/lib-es/logic/estimateFees.js.map +1 -1
  143. package/lib-es/logic/index.d.ts +2 -1
  144. package/lib-es/logic/index.d.ts.map +1 -1
  145. package/lib-es/logic/index.js +1 -0
  146. package/lib-es/logic/index.js.map +1 -1
  147. package/lib-es/logic/stake.d.ts +3 -0
  148. package/lib-es/logic/stake.d.ts.map +1 -0
  149. package/lib-es/logic/stake.js +8 -0
  150. package/lib-es/logic/stake.js.map +1 -0
  151. package/lib-es/network/index.d.ts +5 -4
  152. package/lib-es/network/index.d.ts.map +1 -1
  153. package/lib-es/network/index.js +4 -3
  154. package/lib-es/network/index.js.map +1 -1
  155. package/lib-es/network/sdk.d.ts +5 -3
  156. package/lib-es/network/sdk.d.ts.map +1 -1
  157. package/lib-es/network/sdk.js +144 -25
  158. package/lib-es/network/sdk.js.map +1 -1
  159. package/lib-es/network/sdk.test.js +491 -6
  160. package/lib-es/network/sdk.test.js.map +1 -1
  161. package/lib-es/types/bridge.d.ts +33 -6
  162. package/lib-es/types/bridge.d.ts.map +1 -1
  163. package/package.json +20 -12
  164. package/src/bridge/broadcast.ts +3 -0
  165. package/src/bridge/buildOptimisticOperation.ts +47 -4
  166. package/src/bridge/buildTransaction.test.ts +4 -0
  167. package/src/bridge/buildTransaction.ts +3 -1
  168. package/src/bridge/estimateMaxSpendable.test.ts +33 -0
  169. package/src/bridge/estimateMaxSpendable.ts +17 -3
  170. package/src/bridge/getFeesForTransaction.ts +14 -1
  171. package/src/bridge/getOperationExtra.ts +1 -0
  172. package/src/bridge/getTransactionStatus.ts +53 -21
  173. package/src/bridge/preload.test.ts +13 -279
  174. package/src/bridge/preload.ts +5 -3
  175. package/src/bridge/prepareTransaction.ts +1 -1
  176. package/src/bridge/synchronisation.test.ts +389 -7
  177. package/src/bridge/synchronisation.ts +6 -3
  178. package/src/bridge/utils.ts +25 -1
  179. package/src/constants.ts +4 -0
  180. package/src/errors.ts +21 -0
  181. package/src/logic/craftTransaction.ts +6 -9
  182. package/src/logic/estimateFees.ts +16 -1
  183. package/src/logic/index.ts +2 -1
  184. package/src/logic/stake.ts +9 -0
  185. package/src/network/index.ts +6 -3
  186. package/src/network/sdk.test.ts +538 -10
  187. package/src/network/sdk.ts +179 -31
  188. package/src/types/bridge.ts +32 -6
@@ -39,6 +39,20 @@ jest.mock("@mysten/sui/client", () => {
39
39
  },
40
40
  }),
41
41
  getReferenceGasPrice: jest.fn().mockResolvedValue("1000"),
42
+ getTransactionBlock: jest.fn().mockResolvedValue({
43
+ transaction: {
44
+ data: {
45
+ transaction: {
46
+ kind: "ProgrammableTransaction",
47
+ inputs: [],
48
+ transactions: [],
49
+ },
50
+ },
51
+ },
52
+ effects: {
53
+ status: { status: "success" },
54
+ },
55
+ }),
42
56
  })),
43
57
  getFullnodeUrl: jest.fn().mockReturnValue("https://mockapi.sui.io"),
44
58
  };
@@ -57,7 +71,14 @@ jest.mock("@mysten/sui/transactions", () => {
57
71
  setSender: jest.fn(),
58
72
  splitCoins: jest.fn().mockReturnValue(["0xmock_coin"]),
59
73
  transferObjects: jest.fn(),
74
+ moveCall: jest.fn(),
75
+ object: jest.fn(),
76
+ pure: {
77
+ address: jest.fn(),
78
+ u64: jest.fn(),
79
+ },
60
80
  build: jest.fn().mockResolvedValue(mockTxb),
81
+ setGasBudgetIfNotSet: jest.fn(),
61
82
  };
62
83
  }),
63
84
  };
@@ -160,6 +181,8 @@ const mockTransaction = {
160
181
  checkpoint: "313024",
161
182
  };
162
183
  const mockApi = new SuiClient({ url: "mock" });
184
+ // Add getTransactionBlock method to mockApi
185
+ mockApi.getTransactionBlock = jest.fn();
163
186
  // Helper function to generate mock coins from an array of balances
164
187
  const createMockCoins = (balances) => {
165
188
  return balances.map((balance, index) => ({
@@ -215,11 +238,11 @@ describe("SDK Functions", () => {
215
238
  });
216
239
  test("getOperationType should return IN for incoming tx", () => {
217
240
  const address = "0x33444cf803c690db96527cec67e3c9ab512596f4ba2d4eace43f0b4f716e0164";
218
- expect(sdk.getOperationType(address, mockTransaction.transaction?.data)).toBe("IN");
241
+ expect(sdk.getOperationType(address, mockTransaction)).toBe("IN");
219
242
  });
220
243
  test("getOperationType should return OUT for outgoing tx", () => {
221
244
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
222
- expect(sdk.getOperationType(address, mockTransaction.transaction?.data)).toBe("OUT");
245
+ expect(sdk.getOperationType(address, mockTransaction)).toBe("OUT");
223
246
  });
224
247
  test("getOperationSenders should return sender address", () => {
225
248
  expect(sdk.getOperationSenders(mockTransaction.transaction?.data)).toEqual(["0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24"]);
@@ -445,6 +468,470 @@ describe("SDK Functions", () => {
445
468
  }
446
469
  });
447
470
  });
471
+ describe("Staking Operations", () => {
472
+ describe("Operation Type Detection", () => {
473
+ test("getOperationType should return DELEGATE for staking transaction", () => {
474
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
475
+ // Create a mock staking transaction
476
+ const mockStakingTx = {
477
+ digest: "delegate_tx_digest_123",
478
+ transaction: {
479
+ data: {
480
+ sender: address,
481
+ transaction: {
482
+ kind: "ProgrammableTransaction",
483
+ inputs: [],
484
+ transactions: [
485
+ {
486
+ MoveCall: {
487
+ function: "request_add_stake",
488
+ },
489
+ },
490
+ ],
491
+ },
492
+ },
493
+ },
494
+ effects: {
495
+ status: { status: "success" },
496
+ gasUsed: {
497
+ computationCost: "1000000",
498
+ storageCost: "500000",
499
+ storageRebate: "450000",
500
+ },
501
+ },
502
+ balanceChanges: [
503
+ {
504
+ owner: { AddressOwner: address },
505
+ coinType: "0x2::sui::SUI",
506
+ amount: "-1000000000",
507
+ },
508
+ ],
509
+ timestampMs: "1742294454878",
510
+ checkpoint: "313024",
511
+ };
512
+ expect(sdk.getOperationType(address, mockStakingTx)).toBe("DELEGATE");
513
+ });
514
+ test("getOperationType should return UNDELEGATE for unstaking transaction", () => {
515
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
516
+ // Create a mock unstaking transaction
517
+ const mockUnstakingTx = {
518
+ digest: "undelegate_tx_digest_456",
519
+ transaction: {
520
+ data: {
521
+ sender: address,
522
+ transaction: {
523
+ kind: "ProgrammableTransaction",
524
+ inputs: [],
525
+ transactions: [
526
+ {
527
+ MoveCall: {
528
+ function: "request_withdraw_stake",
529
+ },
530
+ },
531
+ ],
532
+ },
533
+ },
534
+ },
535
+ effects: {
536
+ status: { status: "success" },
537
+ gasUsed: {
538
+ computationCost: "1000000",
539
+ storageCost: "500000",
540
+ storageRebate: "450000",
541
+ },
542
+ },
543
+ balanceChanges: [
544
+ {
545
+ owner: { AddressOwner: address },
546
+ coinType: "0x2::sui::SUI",
547
+ amount: "0",
548
+ },
549
+ ],
550
+ timestampMs: "1742294454878",
551
+ checkpoint: "313024",
552
+ };
553
+ expect(sdk.getOperationType(address, mockUnstakingTx)).toBe("UNDELEGATE");
554
+ });
555
+ });
556
+ describe("Operation Amount Calculation", () => {
557
+ test("getOperationAmount should calculate staking amount correctly", () => {
558
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
559
+ const mockStakingTx = {
560
+ transaction: {
561
+ data: {
562
+ transaction: {
563
+ kind: "ProgrammableTransaction",
564
+ transactions: [
565
+ {
566
+ MoveCall: {
567
+ function: "request_add_stake",
568
+ },
569
+ },
570
+ ],
571
+ },
572
+ },
573
+ },
574
+ balanceChanges: [
575
+ {
576
+ owner: { AddressOwner: address },
577
+ coinType: "0x2::sui::SUI",
578
+ amount: "-1000000000",
579
+ },
580
+ ],
581
+ };
582
+ const amount = sdk.getOperationAmount(address, mockStakingTx, sdk.DEFAULT_COIN_TYPE);
583
+ expect(amount).toEqual(new BigNumber("1000000000")); // The function returns minus of the balance change
584
+ });
585
+ test("getOperationAmount should calculate unstaking amount correctly", () => {
586
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
587
+ const mockUnstakingTx = {
588
+ transaction: {
589
+ data: {
590
+ transaction: {
591
+ kind: "ProgrammableTransaction",
592
+ transactions: [
593
+ {
594
+ MoveCall: {
595
+ function: "request_withdraw_stake",
596
+ },
597
+ },
598
+ ],
599
+ },
600
+ },
601
+ },
602
+ balanceChanges: [
603
+ {
604
+ owner: { AddressOwner: address },
605
+ coinType: "0x2::sui::SUI",
606
+ amount: "0",
607
+ },
608
+ ],
609
+ };
610
+ const amount = sdk.getOperationAmount(address, mockUnstakingTx, sdk.DEFAULT_COIN_TYPE);
611
+ expect(amount).toEqual(new BigNumber("0"));
612
+ });
613
+ });
614
+ describe("Operation Recipients", () => {
615
+ test("getOperationRecipients should return empty array for staking transaction", () => {
616
+ const mockStakingTx = {
617
+ transaction: {
618
+ data: {
619
+ transaction: {
620
+ kind: "ProgrammableTransaction",
621
+ inputs: [],
622
+ transactions: [
623
+ {
624
+ MoveCall: {
625
+ function: "request_add_stake",
626
+ },
627
+ },
628
+ ],
629
+ },
630
+ },
631
+ },
632
+ };
633
+ const recipients = sdk.getOperationRecipients(mockStakingTx.transaction?.data);
634
+ expect(recipients).toEqual([]);
635
+ });
636
+ test("getOperationRecipients should return empty array for unstaking transaction", () => {
637
+ const mockUnstakingTx = {
638
+ transaction: {
639
+ data: {
640
+ transaction: {
641
+ kind: "ProgrammableTransaction",
642
+ inputs: [],
643
+ transactions: [
644
+ {
645
+ MoveCall: {
646
+ function: "request_withdraw_stake",
647
+ },
648
+ },
649
+ ],
650
+ },
651
+ },
652
+ },
653
+ };
654
+ const recipients = sdk.getOperationRecipients(mockUnstakingTx.transaction?.data);
655
+ expect(recipients).toEqual([]);
656
+ });
657
+ });
658
+ describe("Transaction Creation", () => {
659
+ test("createTransaction should build delegate transaction", async () => {
660
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
661
+ const transaction = {
662
+ mode: "delegate",
663
+ coinType: sdk.DEFAULT_COIN_TYPE,
664
+ amount: new BigNumber(1000000000), // 1 SUI
665
+ recipient: "0xvalidator_address_123",
666
+ };
667
+ const tx = await sdk.createTransaction(address, transaction);
668
+ expect(tx).toBeDefined();
669
+ });
670
+ test("createTransaction should build undelegate transaction with specific amount", async () => {
671
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
672
+ const transaction = {
673
+ mode: "undelegate",
674
+ coinType: sdk.DEFAULT_COIN_TYPE,
675
+ amount: new BigNumber(500000000), // 0.5 SUI
676
+ stakedSuiId: "0xstaked_sui_object_123",
677
+ useAllAmount: false,
678
+ recipient: "0xvalidator_address_123", // Required by type but not used for undelegate
679
+ };
680
+ const tx = await sdk.createTransaction(address, transaction);
681
+ expect(tx).toBeDefined();
682
+ });
683
+ test("createTransaction should build undelegate transaction with all amount", async () => {
684
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
685
+ const transaction = {
686
+ mode: "undelegate",
687
+ coinType: sdk.DEFAULT_COIN_TYPE,
688
+ amount: new BigNumber(0),
689
+ stakedSuiId: "0xstaked_sui_object_123",
690
+ useAllAmount: true,
691
+ recipient: "0xvalidator_address_123", // Required by type but not used for undelegate
692
+ };
693
+ const tx = await sdk.createTransaction(address, transaction);
694
+ expect(tx).toBeDefined();
695
+ });
696
+ });
697
+ describe("Payment Info for Staking", () => {
698
+ test("paymentInfo should return gas budget and fees for delegate transaction", async () => {
699
+ const sender = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
700
+ const fakeTransaction = {
701
+ mode: "delegate",
702
+ coinType: sdk.DEFAULT_COIN_TYPE,
703
+ family: "sui",
704
+ amount: new BigNumber(1000000000), // 1 SUI
705
+ recipient: "0xvalidator_address_123",
706
+ errors: {},
707
+ };
708
+ const info = await sdk.paymentInfo(sender, fakeTransaction);
709
+ expect(info).toHaveProperty("gasBudget");
710
+ expect(info).toHaveProperty("totalGasUsed");
711
+ expect(info).toHaveProperty("fees");
712
+ });
713
+ test("paymentInfo should return gas budget and fees for undelegate transaction", async () => {
714
+ const sender = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
715
+ const fakeTransaction = {
716
+ mode: "undelegate",
717
+ coinType: sdk.DEFAULT_COIN_TYPE,
718
+ family: "sui",
719
+ amount: new BigNumber(500000000), // 0.5 SUI
720
+ stakedSuiId: "0xstaked_sui_object_123",
721
+ useAllAmount: false,
722
+ recipient: "0xvalidator_address_123", // Required by type but not used for undelegate
723
+ errors: {},
724
+ };
725
+ const info = await sdk.paymentInfo(sender, fakeTransaction);
726
+ expect(info).toHaveProperty("gasBudget");
727
+ expect(info).toHaveProperty("totalGasUsed");
728
+ expect(info).toHaveProperty("fees");
729
+ });
730
+ });
731
+ describe("Transaction to Operation Mapping", () => {
732
+ test("transactionToOperation should map staking transaction correctly", () => {
733
+ const accountId = "mockAccountId";
734
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
735
+ const mockStakingTx = {
736
+ digest: "delegate_tx_digest_123",
737
+ transaction: {
738
+ data: {
739
+ sender: address,
740
+ transaction: {
741
+ kind: "ProgrammableTransaction",
742
+ inputs: [],
743
+ transactions: [
744
+ {
745
+ MoveCall: {
746
+ function: "request_add_stake",
747
+ },
748
+ },
749
+ ],
750
+ },
751
+ },
752
+ },
753
+ effects: {
754
+ status: { status: "success" },
755
+ gasUsed: {
756
+ computationCost: "1000000",
757
+ storageCost: "500000",
758
+ storageRebate: "450000",
759
+ },
760
+ },
761
+ balanceChanges: [
762
+ {
763
+ owner: { AddressOwner: address },
764
+ coinType: "0x2::sui::SUI",
765
+ amount: "-1000000000",
766
+ },
767
+ ],
768
+ timestampMs: "1742294454878",
769
+ checkpoint: "313024",
770
+ };
771
+ const operation = sdk.transactionToOperation(accountId, address, mockStakingTx);
772
+ expect(operation).toHaveProperty("id");
773
+ expect(operation).toHaveProperty("accountId", accountId);
774
+ expect(operation).toHaveProperty("type", "DELEGATE");
775
+ expect(operation).toHaveProperty("hash", "delegate_tx_digest_123");
776
+ expect(operation).toHaveProperty("extra");
777
+ expect(operation.extra.coinType).toBe(sdk.DEFAULT_COIN_TYPE);
778
+ expect(operation.value).toEqual(new BigNumber("1000000000")); // The function returns minus of the balance change
779
+ expect(operation.recipients).toEqual([]);
780
+ expect(operation.senders).toEqual([address]);
781
+ });
782
+ test("transactionToOperation should map unstaking transaction correctly", () => {
783
+ const accountId = "mockAccountId";
784
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
785
+ const mockUnstakingTx = {
786
+ digest: "undelegate_tx_digest_456",
787
+ transaction: {
788
+ data: {
789
+ sender: address,
790
+ transaction: {
791
+ kind: "ProgrammableTransaction",
792
+ inputs: [],
793
+ transactions: [
794
+ {
795
+ MoveCall: {
796
+ function: "request_withdraw_stake",
797
+ },
798
+ },
799
+ ],
800
+ },
801
+ },
802
+ },
803
+ effects: {
804
+ status: { status: "success" },
805
+ gasUsed: {
806
+ computationCost: "1000000",
807
+ storageCost: "500000",
808
+ storageRebate: "450000",
809
+ },
810
+ },
811
+ balanceChanges: [
812
+ {
813
+ owner: { AddressOwner: address },
814
+ coinType: "0x2::sui::SUI",
815
+ amount: "0",
816
+ },
817
+ ],
818
+ timestampMs: "1742294454878",
819
+ checkpoint: "313024",
820
+ };
821
+ const operation = sdk.transactionToOperation(accountId, address, mockUnstakingTx);
822
+ expect(operation).toHaveProperty("id");
823
+ expect(operation).toHaveProperty("accountId", accountId);
824
+ expect(operation).toHaveProperty("type", "UNDELEGATE");
825
+ expect(operation).toHaveProperty("hash", "undelegate_tx_digest_456");
826
+ expect(operation).toHaveProperty("extra");
827
+ expect(operation.extra.coinType).toBe(sdk.DEFAULT_COIN_TYPE);
828
+ expect(operation.value).toEqual(new BigNumber("0"));
829
+ expect(operation.recipients).toEqual([]);
830
+ expect(operation.senders).toEqual([address]);
831
+ });
832
+ test("transactionToOp should map staking transaction correctly", () => {
833
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
834
+ const mockStakingTx = {
835
+ digest: "delegate_tx_digest_123",
836
+ transaction: {
837
+ data: {
838
+ sender: address,
839
+ transaction: {
840
+ kind: "ProgrammableTransaction",
841
+ inputs: [],
842
+ transactions: [
843
+ {
844
+ MoveCall: {
845
+ function: "request_add_stake",
846
+ },
847
+ },
848
+ ],
849
+ },
850
+ },
851
+ },
852
+ effects: {
853
+ status: { status: "success" },
854
+ gasUsed: {
855
+ computationCost: "1000000",
856
+ storageCost: "500000",
857
+ storageRebate: "450000",
858
+ },
859
+ },
860
+ balanceChanges: [
861
+ {
862
+ owner: { AddressOwner: address },
863
+ coinType: "0x2::sui::SUI",
864
+ amount: "-1000000000",
865
+ },
866
+ ],
867
+ timestampMs: "1742294454878",
868
+ checkpoint: "313024",
869
+ };
870
+ const operation = sdk.transactionToOp(address, mockStakingTx);
871
+ expect(operation.id).toEqual("delegate_tx_digest_123");
872
+ expect(operation.type).toEqual("DELEGATE");
873
+ expect(operation.senders).toEqual([address]);
874
+ expect(operation.recipients).toEqual([]);
875
+ expect(operation.value).toEqual(1000000000n); // The function returns minus of the balance change
876
+ expect(operation.asset).toEqual({ type: "native" });
877
+ });
878
+ test("transactionToOp should map unstaking transaction correctly", () => {
879
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
880
+ const mockUnstakingTx = {
881
+ digest: "undelegate_tx_digest_456",
882
+ transaction: {
883
+ data: {
884
+ sender: address,
885
+ transaction: {
886
+ kind: "ProgrammableTransaction",
887
+ inputs: [],
888
+ transactions: [
889
+ {
890
+ MoveCall: {
891
+ function: "request_withdraw_stake",
892
+ },
893
+ },
894
+ ],
895
+ },
896
+ },
897
+ },
898
+ effects: {
899
+ status: { status: "success" },
900
+ gasUsed: {
901
+ computationCost: "1000000",
902
+ storageCost: "500000",
903
+ storageRebate: "450000",
904
+ },
905
+ },
906
+ balanceChanges: [
907
+ {
908
+ owner: { AddressOwner: address },
909
+ coinType: "0x2::sui::SUI",
910
+ amount: "0",
911
+ },
912
+ ],
913
+ timestampMs: "1742294454878",
914
+ checkpoint: "313024",
915
+ };
916
+ const operation = sdk.transactionToOp(address, mockUnstakingTx);
917
+ expect(operation.id).toEqual("undelegate_tx_digest_456");
918
+ expect(operation.type).toEqual("UNDELEGATE");
919
+ expect(operation.senders).toEqual([address]);
920
+ expect(operation.recipients).toEqual([]);
921
+ expect(operation.value).toEqual(0n);
922
+ expect(operation.asset).toEqual({ type: "native" });
923
+ });
924
+ });
925
+ describe("Operation Extra Information", () => {
926
+ test("getOperationExtra should be a function", () => {
927
+ expect(typeof sdk.getOperationExtra).toBe("function");
928
+ });
929
+ test("getOperationExtra should return a Promise", () => {
930
+ const result = sdk.getOperationExtra("test_digest");
931
+ expect(result).toBeInstanceOf(Promise);
932
+ });
933
+ });
934
+ });
448
935
  describe("queryTransactions", () => {
449
936
  it("should call api.queryTransactionBlocks with correct params for IN", async () => {
450
937
  mockApi.queryTransactionBlocks.mockResolvedValueOnce({
@@ -1117,10 +1604,8 @@ describe("filterOperations", () => {
1117
1604
  test("toBlockOperation should ignore transfers from consensus owner", () => {
1118
1605
  expect(sdk.toBlockOperation({
1119
1606
  owner: {
1120
- ConsensusV2: {
1121
- authenticator: {
1122
- SingleOwner: "test",
1123
- },
1607
+ ConsensusAddressOwner: {
1608
+ owner: "test",
1124
1609
  start_version: "1",
1125
1610
  },
1126
1611
  },