@ledgerhq/coin-sui 0.15.0-nightly.4 → 0.15.1-nightly.0

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.
@@ -30,6 +30,7 @@ const sdk = __importStar(require("./sdk"));
30
30
  const config_1 = __importDefault(require("../config"));
31
31
  const bignumber_js_1 = require("bignumber.js");
32
32
  const client_1 = require("@mysten/sui/client");
33
+ const assert_1 = __importDefault(require("assert"));
33
34
  // Mock SUI client for tests
34
35
  jest.mock("@mysten/sui/client", () => {
35
36
  return {
@@ -208,6 +209,87 @@ const mockTransaction = {
208
209
  timestampMs: "1742294454878",
209
210
  checkpoint: "313024",
210
211
  };
212
+ // Create a mock staking transaction
213
+ // amount must be a negative number
214
+ function mockStakingTx(address, amount) {
215
+ (0, assert_1.default)(new bignumber_js_1.BigNumber(amount).lte(0), "amount must be a negative number");
216
+ return {
217
+ digest: "delegate_tx_digest_123",
218
+ transaction: {
219
+ data: {
220
+ sender: address,
221
+ transaction: {
222
+ kind: "ProgrammableTransaction",
223
+ inputs: [],
224
+ transactions: [
225
+ {
226
+ MoveCall: {
227
+ function: "request_add_stake",
228
+ },
229
+ },
230
+ ],
231
+ },
232
+ },
233
+ },
234
+ effects: {
235
+ status: { status: "success" },
236
+ gasUsed: {
237
+ computationCost: "1000000",
238
+ storageCost: "500000",
239
+ storageRebate: "450000",
240
+ },
241
+ },
242
+ balanceChanges: [
243
+ {
244
+ owner: { AddressOwner: address },
245
+ coinType: "0x2::sui::SUI",
246
+ amount: amount.startsWith("-") ? amount : `-${amount}`,
247
+ },
248
+ ],
249
+ timestampMs: "1742294454878",
250
+ checkpoint: "313024",
251
+ };
252
+ }
253
+ // amount must be a positive number
254
+ function mockUnstakingTx(address, amount) {
255
+ (0, assert_1.default)(new bignumber_js_1.BigNumber(amount).gte(0), "amount must be a positive number");
256
+ return {
257
+ digest: "undelegate_tx_digest_456",
258
+ transaction: {
259
+ data: {
260
+ sender: address,
261
+ transaction: {
262
+ kind: "ProgrammableTransaction",
263
+ inputs: [],
264
+ transactions: [
265
+ {
266
+ MoveCall: {
267
+ function: "request_withdraw_stake",
268
+ },
269
+ },
270
+ ],
271
+ },
272
+ },
273
+ },
274
+ effects: {
275
+ status: { status: "success" },
276
+ gasUsed: {
277
+ computationCost: "1000000",
278
+ storageCost: "500000",
279
+ storageRebate: "450000",
280
+ },
281
+ },
282
+ balanceChanges: [
283
+ {
284
+ owner: { AddressOwner: address },
285
+ coinType: "0x2::sui::SUI",
286
+ amount: amount,
287
+ },
288
+ ],
289
+ timestampMs: "1742294454878",
290
+ checkpoint: "313024",
291
+ };
292
+ }
211
293
  const mockApi = new client_1.SuiClient({ url: "mock" });
212
294
  // Add getTransactionBlock method to mockApi
213
295
  mockApi.getTransactionBlock = jest.fn();
@@ -493,195 +575,39 @@ describe("Staking Operations", () => {
493
575
  describe("Operation Type Detection", () => {
494
576
  test("getOperationType should return DELEGATE for staking transaction", () => {
495
577
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
496
- // Create a mock staking transaction
497
- const mockStakingTx = {
498
- digest: "delegate_tx_digest_123",
499
- transaction: {
500
- data: {
501
- sender: address,
502
- transaction: {
503
- kind: "ProgrammableTransaction",
504
- inputs: [],
505
- transactions: [
506
- {
507
- MoveCall: {
508
- function: "request_add_stake",
509
- },
510
- },
511
- ],
512
- },
513
- },
514
- },
515
- effects: {
516
- status: { status: "success" },
517
- gasUsed: {
518
- computationCost: "1000000",
519
- storageCost: "500000",
520
- storageRebate: "450000",
521
- },
522
- },
523
- balanceChanges: [
524
- {
525
- owner: { AddressOwner: address },
526
- coinType: "0x2::sui::SUI",
527
- amount: "-1000000000",
528
- },
529
- ],
530
- timestampMs: "1742294454878",
531
- checkpoint: "313024",
532
- };
533
- expect(sdk.getOperationType(address, mockStakingTx)).toBe("DELEGATE");
578
+ expect(sdk.getOperationType(address, mockStakingTx(address, "-1000000000"))).toBe("DELEGATE");
534
579
  });
535
580
  test("getOperationType should return UNDELEGATE for unstaking transaction", () => {
536
581
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
537
- // Create a mock unstaking transaction
538
- const mockUnstakingTx = {
539
- digest: "undelegate_tx_digest_456",
540
- transaction: {
541
- data: {
542
- sender: address,
543
- transaction: {
544
- kind: "ProgrammableTransaction",
545
- inputs: [],
546
- transactions: [
547
- {
548
- MoveCall: {
549
- function: "request_withdraw_stake",
550
- },
551
- },
552
- ],
553
- },
554
- },
555
- },
556
- effects: {
557
- status: { status: "success" },
558
- gasUsed: {
559
- computationCost: "1000000",
560
- storageCost: "500000",
561
- storageRebate: "450000",
562
- },
563
- },
564
- balanceChanges: [
565
- {
566
- owner: { AddressOwner: address },
567
- coinType: "0x2::sui::SUI",
568
- amount: "0",
569
- },
570
- ],
571
- timestampMs: "1742294454878",
572
- checkpoint: "313024",
573
- };
574
- expect(sdk.getOperationType(address, mockUnstakingTx)).toBe("UNDELEGATE");
582
+ expect(sdk.getOperationType(address, mockUnstakingTx(address, "1000000000"))).toBe("UNDELEGATE");
575
583
  });
576
584
  });
577
585
  describe("Operation Amount Calculation", () => {
578
586
  const address = "0x6e143fe0a8ca010a86580dafac44298e5b1b7d73efc345356a59a15f0d7824f0";
579
- const mockStakingTx = {
580
- transaction: {
581
- data: {
582
- transaction: {
583
- kind: "ProgrammableTransaction",
584
- transactions: [
585
- {
586
- MoveCall: {
587
- function: "request_add_stake",
588
- },
589
- },
590
- ],
591
- },
592
- },
593
- },
594
- balanceChanges: [
595
- {
596
- owner: { AddressOwner: address },
597
- coinType: "0x2::sui::SUI",
598
- amount: "-1000000000",
599
- },
600
- ],
601
- };
602
- function mockUnstakingTx(amount) {
603
- return {
604
- transaction: {
605
- data: {
606
- transaction: {
607
- kind: "ProgrammableTransaction",
608
- transactions: [
609
- {
610
- MoveCall: {
611
- function: "request_withdraw_stake",
612
- },
613
- },
614
- ],
615
- },
616
- },
617
- },
618
- balanceChanges: [
619
- {
620
- owner: { AddressOwner: address },
621
- coinType: "0x2::sui::SUI",
622
- amount: amount,
623
- },
624
- ],
625
- };
626
- }
627
587
  function bridgeOperationAmount(mock, coinType = sdk.DEFAULT_COIN_TYPE) {
628
588
  return sdk.getOperationAmount(address, mock, coinType);
629
589
  }
630
- test("getOperationAmount should calculate staking amount", () => expect(bridgeOperationAmount(mockStakingTx)).toEqual(new bignumber_js_1.BigNumber("1000000000")));
631
- test("getOperationAmount should calculate unstaking amount of 1000", () => expect(bridgeOperationAmount(mockUnstakingTx("1000"))).toEqual(new bignumber_js_1.BigNumber("-1000")));
632
- test("getOperationAmount should calculate unstaking amount of 0", () => expect(bridgeOperationAmount(mockUnstakingTx("0"))).toEqual(new bignumber_js_1.BigNumber("0")));
590
+ test("getOperationAmount should calculate staking amount", () => expect(bridgeOperationAmount(mockStakingTx(address, "-1000000000"))).toEqual(new bignumber_js_1.BigNumber("1000000000")));
591
+ test("getOperationAmount should calculate unstaking amount of 1000", () => expect(bridgeOperationAmount(mockUnstakingTx(address, "1000"))).toEqual(new bignumber_js_1.BigNumber("-1000")));
592
+ test("getOperationAmount should calculate unstaking amount of 0", () => expect(bridgeOperationAmount(mockUnstakingTx(address, "0"))).toEqual(new bignumber_js_1.BigNumber("0")));
633
593
  test("getOperationAmount should calculate amount correctly for SUI", () => expect(bridgeOperationAmount(mockTransaction)).toEqual(new bignumber_js_1.BigNumber("9998990120")));
634
594
  test("getOperationAmount should calculate amount correctly for tokens", () => expect(bridgeOperationAmount(mockTransaction, "0x123::test::TOKEN")).toEqual(new bignumber_js_1.BigNumber("500000")));
635
595
  function alpacaOperationAmount(mock, coinType = sdk.DEFAULT_COIN_TYPE) {
636
596
  return sdk.alpacaGetOperationAmount(address, mock, coinType);
637
597
  }
638
- test("alpaca getOperationAmount should calculate staking amount", () => expect(alpacaOperationAmount(mockStakingTx)).toEqual(new bignumber_js_1.BigNumber("1000000000")));
639
- test("alpaca getOperationAmount should calculate unstaking amount of 1000", () => expect(alpacaOperationAmount(mockUnstakingTx("1000"))).toEqual(new bignumber_js_1.BigNumber("1000")));
640
- test("alpaca getOperationAmount should calculate unstaking amount of 0", () => expect(alpacaOperationAmount(mockUnstakingTx("0"))).toEqual(new bignumber_js_1.BigNumber("0")));
598
+ test("alpaca getOperationAmount should calculate staking amount", () => expect(alpacaOperationAmount(mockStakingTx(address, "-1000000000"))).toEqual(new bignumber_js_1.BigNumber("1000000000")));
599
+ test("alpaca getOperationAmount should calculate unstaking amount of 1000", () => expect(alpacaOperationAmount(mockUnstakingTx(address, "1000"))).toEqual(new bignumber_js_1.BigNumber("1000")));
600
+ test("alpaca getOperationAmount should calculate unstaking amount of 0", () => expect(alpacaOperationAmount(mockUnstakingTx(address, "0"))).toEqual(new bignumber_js_1.BigNumber("0")));
641
601
  test("alpaca getOperationAmount should calculate amount correctly for SUI", () => expect(alpacaOperationAmount(mockTransaction)).toEqual(new bignumber_js_1.BigNumber("9998990120")));
642
602
  test("alpaca getOperationAmount should calculate amount correctly for tokens", () => expect(alpacaOperationAmount(mockTransaction, "0x123::test::TOKEN")).toEqual(new bignumber_js_1.BigNumber("500000")));
643
603
  });
644
604
  describe("Operation Recipients", () => {
645
605
  test("getOperationRecipients should return empty array for staking transaction", () => {
646
- const mockStakingTx = {
647
- transaction: {
648
- data: {
649
- transaction: {
650
- kind: "ProgrammableTransaction",
651
- inputs: [],
652
- transactions: [
653
- {
654
- MoveCall: {
655
- function: "request_add_stake",
656
- },
657
- },
658
- ],
659
- },
660
- },
661
- },
662
- };
663
- const recipients = sdk.getOperationRecipients(mockStakingTx.transaction?.data);
606
+ const recipients = sdk.getOperationRecipients(mockStakingTx("0xdeadbeef", "-1000000000").transaction?.data);
664
607
  expect(recipients).toEqual([]);
665
608
  });
666
609
  test("getOperationRecipients should return empty array for unstaking transaction", () => {
667
- const mockUnstakingTx = {
668
- transaction: {
669
- data: {
670
- transaction: {
671
- kind: "ProgrammableTransaction",
672
- inputs: [],
673
- transactions: [
674
- {
675
- MoveCall: {
676
- function: "request_withdraw_stake",
677
- },
678
- },
679
- ],
680
- },
681
- },
682
- },
683
- };
684
- const recipients = sdk.getOperationRecipients(mockUnstakingTx.transaction?.data);
610
+ const recipients = sdk.getOperationRecipients(mockUnstakingTx("0xdeadbeef", "1000000000").transaction?.data);
685
611
  expect(recipients).toEqual([]);
686
612
  });
687
613
  });
@@ -762,43 +688,7 @@ describe("Staking Operations", () => {
762
688
  test("transactionToOperation should map staking transaction correctly", () => {
763
689
  const accountId = "mockAccountId";
764
690
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
765
- const mockStakingTx = {
766
- digest: "delegate_tx_digest_123",
767
- transaction: {
768
- data: {
769
- sender: address,
770
- transaction: {
771
- kind: "ProgrammableTransaction",
772
- inputs: [],
773
- transactions: [
774
- {
775
- MoveCall: {
776
- function: "request_add_stake",
777
- },
778
- },
779
- ],
780
- },
781
- },
782
- },
783
- effects: {
784
- status: { status: "success" },
785
- gasUsed: {
786
- computationCost: "1000000",
787
- storageCost: "500000",
788
- storageRebate: "450000",
789
- },
790
- },
791
- balanceChanges: [
792
- {
793
- owner: { AddressOwner: address },
794
- coinType: "0x2::sui::SUI",
795
- amount: "-1000000000",
796
- },
797
- ],
798
- timestampMs: "1742294454878",
799
- checkpoint: "313024",
800
- };
801
- const operation = sdk.transactionToOperation(accountId, address, mockStakingTx);
691
+ const operation = sdk.transactionToOperation(accountId, address, mockStakingTx(address, "-1000000000"));
802
692
  expect(operation).toHaveProperty("id");
803
693
  expect(operation).toHaveProperty("accountId", accountId);
804
694
  expect(operation).toHaveProperty("type", "DELEGATE");
@@ -812,92 +702,20 @@ describe("Staking Operations", () => {
812
702
  test("transactionToOperation should map unstaking transaction correctly", () => {
813
703
  const accountId = "mockAccountId";
814
704
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
815
- const mockUnstakingTx = {
816
- digest: "undelegate_tx_digest_456",
817
- transaction: {
818
- data: {
819
- sender: address,
820
- transaction: {
821
- kind: "ProgrammableTransaction",
822
- inputs: [],
823
- transactions: [
824
- {
825
- MoveCall: {
826
- function: "request_withdraw_stake",
827
- },
828
- },
829
- ],
830
- },
831
- },
832
- },
833
- effects: {
834
- status: { status: "success" },
835
- gasUsed: {
836
- computationCost: "1000000",
837
- storageCost: "500000",
838
- storageRebate: "450000",
839
- },
840
- },
841
- balanceChanges: [
842
- {
843
- owner: { AddressOwner: address },
844
- coinType: "0x2::sui::SUI",
845
- amount: "0",
846
- },
847
- ],
848
- timestampMs: "1742294454878",
849
- checkpoint: "313024",
850
- };
851
- const operation = sdk.transactionToOperation(accountId, address, mockUnstakingTx);
705
+ const operation = sdk.transactionToOperation(accountId, address, mockUnstakingTx(address, "1000000000"));
852
706
  expect(operation).toHaveProperty("id");
853
707
  expect(operation).toHaveProperty("accountId", accountId);
854
708
  expect(operation).toHaveProperty("type", "UNDELEGATE");
855
709
  expect(operation).toHaveProperty("hash", "undelegate_tx_digest_456");
856
710
  expect(operation).toHaveProperty("extra");
857
711
  expect(operation.extra.coinType).toBe(sdk.DEFAULT_COIN_TYPE);
858
- expect(operation.value).toEqual(new bignumber_js_1.BigNumber("0"));
712
+ expect(operation.value).toEqual(new bignumber_js_1.BigNumber("-1000000000"));
859
713
  expect(operation.recipients).toEqual([]);
860
714
  expect(operation.senders).toEqual([address]);
861
715
  });
862
716
  test("transactionToOp should map staking transaction correctly", () => {
863
717
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
864
- const mockStakingTx = {
865
- digest: "delegate_tx_digest_123",
866
- transaction: {
867
- data: {
868
- sender: address,
869
- transaction: {
870
- kind: "ProgrammableTransaction",
871
- inputs: [],
872
- transactions: [
873
- {
874
- MoveCall: {
875
- function: "request_add_stake",
876
- },
877
- },
878
- ],
879
- },
880
- },
881
- },
882
- effects: {
883
- status: { status: "success" },
884
- gasUsed: {
885
- computationCost: "1000000",
886
- storageCost: "500000",
887
- storageRebate: "450000",
888
- },
889
- },
890
- balanceChanges: [
891
- {
892
- owner: { AddressOwner: address },
893
- coinType: "0x2::sui::SUI",
894
- amount: "-1000000000",
895
- },
896
- ],
897
- timestampMs: "1742294454878",
898
- checkpoint: "313024",
899
- };
900
- const operation = sdk.alpacaTransactionToOp(address, mockStakingTx);
718
+ const operation = sdk.alpacaTransactionToOp(address, mockStakingTx(address, "-1000000000"));
901
719
  expect(operation.id).toEqual("delegate_tx_digest_123");
902
720
  expect(operation.type).toEqual("DELEGATE");
903
721
  expect(operation.senders).toEqual([address]);
@@ -908,48 +726,12 @@ describe("Staking Operations", () => {
908
726
  });
909
727
  test("transactionToOp should map unstaking transaction correctly", () => {
910
728
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
911
- const mockUnstakingTx = {
912
- digest: "undelegate_tx_digest_456",
913
- transaction: {
914
- data: {
915
- sender: address,
916
- transaction: {
917
- kind: "ProgrammableTransaction",
918
- inputs: [],
919
- transactions: [
920
- {
921
- MoveCall: {
922
- function: "request_withdraw_stake",
923
- },
924
- },
925
- ],
926
- },
927
- },
928
- },
929
- effects: {
930
- status: { status: "success" },
931
- gasUsed: {
932
- computationCost: "1000000",
933
- storageCost: "500000",
934
- storageRebate: "450000",
935
- },
936
- },
937
- balanceChanges: [
938
- {
939
- owner: { AddressOwner: address },
940
- coinType: "0x2::sui::SUI",
941
- amount: "0",
942
- },
943
- ],
944
- timestampMs: "1742294454878",
945
- checkpoint: "313024",
946
- };
947
- const operation = sdk.alpacaTransactionToOp(address, mockUnstakingTx);
729
+ const operation = sdk.alpacaTransactionToOp(address, mockUnstakingTx(address, "1000000000"));
948
730
  expect(operation.id).toEqual("undelegate_tx_digest_456");
949
731
  expect(operation.type).toEqual("UNDELEGATE");
950
732
  expect(operation.senders).toEqual([address]);
951
733
  expect(operation.recipients).toEqual([]);
952
- expect(operation.value).toEqual(0n);
734
+ expect(operation.value).toEqual(1000000000n);
953
735
  expect(operation.asset).toEqual({ type: "native" });
954
736
  expect(operation.tx.block.hash).toBeUndefined();
955
737
  });
@@ -1690,7 +1472,7 @@ describe("filterOperations", () => {
1690
1472
  });
1691
1473
  describe("conversion methods", () => {
1692
1474
  test("toBlockOperation should map native transfers correctly", () => {
1693
- expect(sdk.toBlockOperation({
1475
+ expect(sdk.toBlockOperation(mockTransaction, {
1694
1476
  owner: {
1695
1477
  AddressOwner: "0x65449f57946938c84c5127",
1696
1478
  },
@@ -1706,7 +1488,7 @@ describe("filterOperations", () => {
1706
1488
  ]);
1707
1489
  });
1708
1490
  test("toBlockOperation should ignore transfers from shared owner", () => {
1709
- expect(sdk.toBlockOperation({
1491
+ expect(sdk.toBlockOperation(mockTransaction, {
1710
1492
  owner: {
1711
1493
  Shared: {
1712
1494
  initial_shared_version: "0",
@@ -1717,7 +1499,7 @@ describe("filterOperations", () => {
1717
1499
  })).toEqual([]);
1718
1500
  });
1719
1501
  test("toBlockOperation should ignore transfers from object owner", () => {
1720
- expect(sdk.toBlockOperation({
1502
+ expect(sdk.toBlockOperation(mockTransaction, {
1721
1503
  owner: {
1722
1504
  ObjectOwner: "test",
1723
1505
  },
@@ -1726,14 +1508,14 @@ describe("filterOperations", () => {
1726
1508
  })).toEqual([]);
1727
1509
  });
1728
1510
  test("toBlockOperation should ignore transfers from immutable owner", () => {
1729
- expect(sdk.toBlockOperation({
1511
+ expect(sdk.toBlockOperation(mockTransaction, {
1730
1512
  owner: "Immutable",
1731
1513
  coinType: sdk.DEFAULT_COIN_TYPE,
1732
1514
  amount: "-10000000000",
1733
1515
  })).toEqual([]);
1734
1516
  });
1735
1517
  test("toBlockOperation should ignore transfers from consensus owner", () => {
1736
- expect(sdk.toBlockOperation({
1518
+ expect(sdk.toBlockOperation(mockTransaction, {
1737
1519
  owner: {
1738
1520
  ConsensusAddressOwner: {
1739
1521
  owner: "test",
@@ -1745,7 +1527,7 @@ describe("filterOperations", () => {
1745
1527
  })).toEqual([]);
1746
1528
  });
1747
1529
  test("toBlockOperation should map token transfers correctly", () => {
1748
- expect(sdk.toBlockOperation({
1530
+ expect(sdk.toBlockOperation(mockTransaction, {
1749
1531
  owner: {
1750
1532
  AddressOwner: "0x65449f57946938c84c5127",
1751
1533
  },
@@ -1763,6 +1545,38 @@ describe("filterOperations", () => {
1763
1545
  },
1764
1546
  ]);
1765
1547
  });
1548
+ test("toBlockOperation should map staking operations correctly", () => {
1549
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
1550
+ expect(sdk.toBlockOperation(mockStakingTx(address, "-1000000000"), {
1551
+ owner: { AddressOwner: address },
1552
+ coinType: sdk.DEFAULT_COIN_TYPE,
1553
+ amount: "-10000000000",
1554
+ })).toEqual([
1555
+ {
1556
+ type: "other",
1557
+ operationType: "DELEGATE",
1558
+ address: address,
1559
+ asset: { type: "native" },
1560
+ amount: 10000000000n,
1561
+ },
1562
+ ]);
1563
+ });
1564
+ test("toBlockOperation should map unstaking operations correctly", () => {
1565
+ const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
1566
+ expect(sdk.toBlockOperation(mockUnstakingTx(address, "1000000000"), {
1567
+ owner: { AddressOwner: address },
1568
+ coinType: sdk.DEFAULT_COIN_TYPE,
1569
+ amount: "10000000000",
1570
+ })).toEqual([
1571
+ {
1572
+ type: "other",
1573
+ operationType: "UNDELEGATE",
1574
+ address: address,
1575
+ asset: { type: "native" },
1576
+ amount: 10000000000n,
1577
+ },
1578
+ ]);
1579
+ });
1766
1580
  test("toBlockInfo should map checkpoints correctly", () => {
1767
1581
  expect(sdk.toBlockInfo({
1768
1582
  checkpointCommitments: [],