@ledgerhq/coin-sui 0.16.1-nightly.0 → 0.17.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 (49) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +13 -0
  3. package/lib/api/index.d.ts.map +1 -1
  4. package/lib/api/index.js +1 -0
  5. package/lib/api/index.js.map +1 -1
  6. package/lib/logic/getValidators.d.ts +3 -0
  7. package/lib/logic/getValidators.d.ts.map +1 -0
  8. package/lib/logic/getValidators.js +24 -0
  9. package/lib/logic/getValidators.js.map +1 -0
  10. package/lib/logic/index.d.ts +1 -0
  11. package/lib/logic/index.d.ts.map +1 -1
  12. package/lib/logic/index.js +3 -1
  13. package/lib/logic/index.js.map +1 -1
  14. package/lib/network/index.d.ts +3 -2
  15. package/lib/network/index.d.ts.map +1 -1
  16. package/lib/network/index.js +3 -1
  17. package/lib/network/index.js.map +1 -1
  18. package/lib/network/sdk.d.ts +4 -1
  19. package/lib/network/sdk.d.ts.map +1 -1
  20. package/lib/network/sdk.js +42 -16
  21. package/lib/network/sdk.js.map +1 -1
  22. package/lib-es/api/index.d.ts.map +1 -1
  23. package/lib-es/api/index.js +2 -1
  24. package/lib-es/api/index.js.map +1 -1
  25. package/lib-es/logic/getValidators.d.ts +3 -0
  26. package/lib-es/logic/getValidators.d.ts.map +1 -0
  27. package/lib-es/logic/getValidators.js +20 -0
  28. package/lib-es/logic/getValidators.js.map +1 -0
  29. package/lib-es/logic/index.d.ts +1 -0
  30. package/lib-es/logic/index.d.ts.map +1 -1
  31. package/lib-es/logic/index.js +1 -0
  32. package/lib-es/logic/index.js.map +1 -1
  33. package/lib-es/network/index.d.ts +3 -2
  34. package/lib-es/network/index.d.ts.map +1 -1
  35. package/lib-es/network/index.js +3 -2
  36. package/lib-es/network/index.js.map +1 -1
  37. package/lib-es/network/sdk.d.ts +4 -1
  38. package/lib-es/network/sdk.d.ts.map +1 -1
  39. package/lib-es/network/sdk.js +40 -15
  40. package/lib-es/network/sdk.js.map +1 -1
  41. package/package.json +2 -2
  42. package/src/api/index.integration.test.ts +37 -1
  43. package/src/api/index.ts +2 -0
  44. package/src/logic/getValidators.test.ts +92 -0
  45. package/src/logic/getValidators.ts +23 -0
  46. package/src/logic/index.ts +1 -0
  47. package/src/network/index.ts +3 -0
  48. package/src/network/sdk.test.ts +90 -56
  49. package/src/network/sdk.ts +43 -16
@@ -236,7 +236,6 @@ function mockStakingTx(address: string, amount: string) {
236
236
 
237
237
  // amount must be a positive number
238
238
  function mockUnstakingTx(address: string, amount: string) {
239
- assert(new BigNumber(amount).gte(0), "amount must be a positive number");
240
239
  return {
241
240
  digest: "undelegate_tx_digest_456",
242
241
  transaction: {
@@ -696,17 +695,20 @@ describe("Staking Operations", () => {
696
695
  }
697
696
 
698
697
  test("alpaca getOperationAmount should calculate staking amount", () =>
699
- expect(alpacaOperationAmount(mockStakingTx(address, "-1000000000"))).toEqual(
698
+ expect(alpacaOperationAmount(mockStakingTx(address, "-1001050000"))).toEqual(
700
699
  new BigNumber("1000000000"),
701
700
  ));
702
701
 
702
+ // 1000 unstaked & 1050000 gas fees = -1049000 balance change
703
703
  test("alpaca getOperationAmount should calculate unstaking amount of 1000", () =>
704
- expect(alpacaOperationAmount(mockUnstakingTx(address, "1000"))).toEqual(
704
+ expect(alpacaOperationAmount(mockUnstakingTx(address, "-1049000"))).toEqual(
705
705
  new BigNumber("1000"),
706
706
  ));
707
707
 
708
708
  test("alpaca getOperationAmount should calculate unstaking amount of 0", () =>
709
- expect(alpacaOperationAmount(mockUnstakingTx(address, "0"))).toEqual(new BigNumber("0")));
709
+ expect(alpacaOperationAmount(mockUnstakingTx(address, "-1050000"))).toEqual(
710
+ new BigNumber("0"),
711
+ ));
710
712
 
711
713
  test("alpaca getOperationAmount should calculate amount correctly for SUI", () =>
712
714
  expect(alpacaOperationAmount(mockTransaction)).toEqual(new BigNumber("9998990120")));
@@ -859,7 +861,7 @@ describe("Staking Operations", () => {
859
861
  test("transactionToOp should map staking transaction correctly", () => {
860
862
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
861
863
 
862
- const operation = sdk.alpacaTransactionToOp(address, mockStakingTx(address, "-1000000000"));
864
+ const operation = sdk.alpacaTransactionToOp(address, mockStakingTx(address, "-1001050000"));
863
865
 
864
866
  expect(operation.id).toEqual("delegate_tx_digest_123");
865
867
  expect(operation.type).toEqual("DELEGATE");
@@ -873,7 +875,7 @@ describe("Staking Operations", () => {
873
875
  test("transactionToOp should map unstaking transaction correctly", () => {
874
876
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
875
877
 
876
- const operation = sdk.alpacaTransactionToOp(address, mockUnstakingTx(address, "1000000000"));
878
+ const operation = sdk.alpacaTransactionToOp(address, mockUnstakingTx(address, "998950000"));
877
879
 
878
880
  expect(operation.id).toEqual("undelegate_tx_digest_456");
879
881
  expect(operation.type).toEqual("UNDELEGATE");
@@ -1772,13 +1774,17 @@ describe("filterOperations", () => {
1772
1774
  describe("conversion methods", () => {
1773
1775
  test("toBlockOperation should map native transfers correctly", () => {
1774
1776
  expect(
1775
- sdk.toBlockOperation(mockTransaction, {
1776
- owner: {
1777
- AddressOwner: "0x65449f57946938c84c5127",
1777
+ sdk.toBlockOperation(
1778
+ mockTransaction,
1779
+ {
1780
+ owner: {
1781
+ AddressOwner: "0x65449f57946938c84c5127",
1782
+ },
1783
+ coinType: sdk.DEFAULT_COIN_TYPE,
1784
+ amount: "-10000000000",
1778
1785
  },
1779
- coinType: sdk.DEFAULT_COIN_TYPE,
1780
- amount: "-10000000000",
1781
- }),
1786
+ BigNumber(0),
1787
+ ),
1782
1788
  ).toEqual([
1783
1789
  {
1784
1790
  type: "transfer",
@@ -1792,64 +1798,84 @@ describe("filterOperations", () => {
1792
1798
 
1793
1799
  test("toBlockOperation should ignore transfers from shared owner", () => {
1794
1800
  expect(
1795
- sdk.toBlockOperation(mockTransaction, {
1796
- owner: {
1797
- Shared: {
1798
- initial_shared_version: "0",
1801
+ sdk.toBlockOperation(
1802
+ mockTransaction,
1803
+ {
1804
+ owner: {
1805
+ Shared: {
1806
+ initial_shared_version: "0",
1807
+ },
1799
1808
  },
1809
+ coinType: sdk.DEFAULT_COIN_TYPE,
1810
+ amount: "-10000000000",
1800
1811
  },
1801
- coinType: sdk.DEFAULT_COIN_TYPE,
1802
- amount: "-10000000000",
1803
- }),
1812
+ BigNumber(0),
1813
+ ),
1804
1814
  ).toEqual([]);
1805
1815
  });
1806
1816
 
1807
1817
  test("toBlockOperation should ignore transfers from object owner", () => {
1808
1818
  expect(
1809
- sdk.toBlockOperation(mockTransaction, {
1810
- owner: {
1811
- ObjectOwner: "test",
1819
+ sdk.toBlockOperation(
1820
+ mockTransaction,
1821
+ {
1822
+ owner: {
1823
+ ObjectOwner: "test",
1824
+ },
1825
+ coinType: sdk.DEFAULT_COIN_TYPE,
1826
+ amount: "-10000000000",
1812
1827
  },
1813
- coinType: sdk.DEFAULT_COIN_TYPE,
1814
- amount: "-10000000000",
1815
- }),
1828
+ BigNumber(0),
1829
+ ),
1816
1830
  ).toEqual([]);
1817
1831
  });
1818
1832
 
1819
1833
  test("toBlockOperation should ignore transfers from immutable owner", () => {
1820
1834
  expect(
1821
- sdk.toBlockOperation(mockTransaction, {
1822
- owner: "Immutable",
1823
- coinType: sdk.DEFAULT_COIN_TYPE,
1824
- amount: "-10000000000",
1825
- }),
1835
+ sdk.toBlockOperation(
1836
+ mockTransaction,
1837
+ {
1838
+ owner: "Immutable",
1839
+ coinType: sdk.DEFAULT_COIN_TYPE,
1840
+ amount: "-10000000000",
1841
+ },
1842
+ BigNumber(0),
1843
+ ),
1826
1844
  ).toEqual([]);
1827
1845
  });
1828
1846
 
1829
1847
  test("toBlockOperation should ignore transfers from consensus owner", () => {
1830
1848
  expect(
1831
- sdk.toBlockOperation(mockTransaction, {
1832
- owner: {
1833
- ConsensusAddressOwner: {
1834
- owner: "test",
1835
- start_version: "1",
1849
+ sdk.toBlockOperation(
1850
+ mockTransaction,
1851
+ {
1852
+ owner: {
1853
+ ConsensusAddressOwner: {
1854
+ owner: "test",
1855
+ start_version: "1",
1856
+ },
1836
1857
  },
1858
+ coinType: sdk.DEFAULT_COIN_TYPE,
1859
+ amount: "-10000000000",
1837
1860
  },
1838
- coinType: sdk.DEFAULT_COIN_TYPE,
1839
- amount: "-10000000000",
1840
- }),
1861
+ BigNumber(0),
1862
+ ),
1841
1863
  ).toEqual([]);
1842
1864
  });
1843
1865
 
1844
1866
  test("toBlockOperation should map token transfers correctly", () => {
1845
1867
  expect(
1846
- sdk.toBlockOperation(mockTransaction, {
1847
- owner: {
1848
- AddressOwner: "0x65449f57946938c84c5127",
1868
+ sdk.toBlockOperation(
1869
+ mockTransaction,
1870
+ {
1871
+ owner: {
1872
+ AddressOwner: "0x65449f57946938c84c5127",
1873
+ },
1874
+ coinType: "0x168da5bf1f48dafc111b0a488fa454aca95e0b5e::usdc::USDC",
1875
+ amount: "8824",
1849
1876
  },
1850
- coinType: "0x168da5bf1f48dafc111b0a488fa454aca95e0b5e::usdc::USDC",
1851
- amount: "8824",
1852
- }),
1877
+ BigNumber(0),
1878
+ ),
1853
1879
  ).toEqual([
1854
1880
  {
1855
1881
  type: "transfer",
@@ -1867,18 +1893,22 @@ describe("filterOperations", () => {
1867
1893
  test("toBlockOperation should map staking operations correctly", () => {
1868
1894
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
1869
1895
  expect(
1870
- sdk.toBlockOperation(mockStakingTx(address, "-1000000000"), {
1871
- owner: { AddressOwner: address },
1872
- coinType: sdk.DEFAULT_COIN_TYPE,
1873
- amount: "-10000000000",
1874
- }),
1896
+ sdk.toBlockOperation(
1897
+ mockStakingTx(address, "-1000000000"),
1898
+ {
1899
+ owner: { AddressOwner: address },
1900
+ coinType: sdk.DEFAULT_COIN_TYPE,
1901
+ amount: "-10000000000",
1902
+ },
1903
+ BigNumber(0),
1904
+ ),
1875
1905
  ).toEqual([
1876
1906
  {
1877
1907
  type: "other",
1878
1908
  operationType: "DELEGATE",
1879
1909
  address: address,
1880
1910
  asset: { type: "native" },
1881
- amount: 10000000000n,
1911
+ amount: -10000000000n,
1882
1912
  },
1883
1913
  ]);
1884
1914
  });
@@ -1886,11 +1916,15 @@ describe("filterOperations", () => {
1886
1916
  test("toBlockOperation should map unstaking operations correctly", () => {
1887
1917
  const address = "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24";
1888
1918
  expect(
1889
- sdk.toBlockOperation(mockUnstakingTx(address, "1000000000"), {
1890
- owner: { AddressOwner: address },
1891
- coinType: sdk.DEFAULT_COIN_TYPE,
1892
- amount: "10000000000",
1893
- }),
1919
+ sdk.toBlockOperation(
1920
+ mockUnstakingTx(address, "1000000000"),
1921
+ {
1922
+ owner: { AddressOwner: address },
1923
+ coinType: sdk.DEFAULT_COIN_TYPE,
1924
+ amount: "10000000000",
1925
+ },
1926
+ BigNumber(0),
1927
+ ),
1894
1928
  ).toEqual([
1895
1929
  {
1896
1930
  type: "other",
@@ -1947,7 +1981,7 @@ describe("filterOperations", () => {
1947
1981
  {
1948
1982
  address: "0x65449f57946938c84c512732f1d69405d1fce417d9c9894696ddf4522f479e24",
1949
1983
  peer: "0x6e143fe0a8ca010a86580dafac44298e5b1b7d73efc345356a59a15f0d7824f0",
1950
- amount: -10000000000n,
1984
+ amount: -9998990120n,
1951
1985
  asset: { type: "native" },
1952
1986
  type: "transfer",
1953
1987
  },
@@ -343,10 +343,6 @@ export function transactionToOperation(
343
343
  };
344
344
  }
345
345
 
346
- function absoluteAmount(balanceChange: BalanceChange | undefined): BigNumber {
347
- return new BigNumber(balanceChange?.amount || 0).abs();
348
- }
349
-
350
346
  // This function is only used by alpaca code path
351
347
  // Logic is similar to getOperationAmount, but we guarantee to return a positive amount in any case
352
348
  // If there is need to display negative amount for staking or unstaking, the view can handle it based on the type of the operation
@@ -358,9 +354,11 @@ export const alpacaGetOperationAmount = (
358
354
  const zero = BigNumber(0);
359
355
 
360
356
  const tx = transaction.transaction?.data.transaction;
361
-
362
- if (isStaking(tx) || isUnstaking(tx)) return absoluteAmount(transaction.balanceChanges?.[0]);
363
- else {
357
+ const change = transaction.balanceChanges;
358
+ if (isStaking(tx) || isUnstaking(tx)) {
359
+ if (change) return removeFeesFromAmountForNative(change[0], getOperationFee(transaction)).abs();
360
+ return BigNumber(0);
361
+ } else {
364
362
  return (
365
363
  transaction.balanceChanges
366
364
  ?.filter(
@@ -370,7 +368,11 @@ export const alpacaGetOperationAmount = (
370
368
  balanceChange.owner.AddressOwner === address &&
371
369
  balanceChange.coinType === coinType,
372
370
  )
373
- .map(absoluteAmount)
371
+ .map(change => {
372
+ if (isSender(address, transaction.transaction?.data))
373
+ return removeFeesFromAmountForNative(change, getOperationFee(transaction)).abs();
374
+ else return BigNumber(change.amount).abs();
375
+ })
374
376
  .reduce((acc, curr) => acc.plus(curr), zero) || zero
375
377
  );
376
378
  }
@@ -443,35 +445,46 @@ export function toBlockInfo(checkpoint: Checkpoint): BlockInfo {
443
445
  * @param transaction SUI RPC transaction block response
444
446
  */
445
447
  export function toBlockTransaction(transaction: SuiTransactionBlockResponse): BlockTransaction {
448
+ const operationFee = getOperationFee(transaction);
446
449
  return {
447
450
  hash: transaction.digest,
448
451
  failed: transaction.effects?.status.status !== "success",
449
452
  operations:
450
- transaction.balanceChanges?.flatMap(change => toBlockOperation(transaction, change)) || [],
451
- fees: BigInt(getOperationFee(transaction).toString()),
453
+ transaction.balanceChanges?.flatMap(change =>
454
+ toBlockOperation(transaction, change, operationFee),
455
+ ) || [],
456
+ fees: BigInt(operationFee.toString()),
452
457
  feesPayer: transaction.transaction?.data.sender || "",
453
458
  };
454
459
  }
455
460
 
461
+ export function removeFeesFromAmountForNative(change: BalanceChange, fees: BigNumber): BigNumber {
462
+ if (change.coinType === DEFAULT_COIN_TYPE) return BigNumber(change.amount).plus(fees);
463
+ return BigNumber(change.amount);
464
+ }
465
+
456
466
  /**
457
467
  * Convert a SUI RPC transaction balance change to a {@link BlockOperation}.
458
468
  *
469
+ * @param transaction
459
470
  * @param change balance change
471
+ * @param fees transaction fees to be deducted from the amount if applicable
460
472
  */
461
473
  export function toBlockOperation(
462
474
  transaction: SuiTransactionBlockResponse,
463
475
  change: BalanceChange,
476
+ fees: BigNumber,
464
477
  ): BlockOperation[] {
465
478
  if (typeof change.owner === "string" || !("AddressOwner" in change.owner)) return [];
466
479
  const address = change.owner.AddressOwner;
467
480
  const operationType = getOperationType(address, transaction);
468
481
 
469
- function transferOp(peer: string | undefined): BlockOperation {
482
+ function transferOp(peer: string | undefined, amount: bigint): BlockOperation {
470
483
  const op: BlockOperation = {
471
484
  type: "transfer",
472
485
  address: address,
473
486
  asset: toSuiAsset(change.coinType),
474
- amount: BigInt(change.amount),
487
+ amount: amount,
475
488
  };
476
489
  if (peer) op.peer = peer;
477
490
  return op;
@@ -479,9 +492,16 @@ export function toBlockOperation(
479
492
 
480
493
  switch (operationType) {
481
494
  case "IN":
482
- return [transferOp(getOperationSenders(transaction.transaction?.data).at(0))];
495
+ return [
496
+ transferOp(getOperationSenders(transaction.transaction?.data).at(0), BigInt(change.amount)),
497
+ ];
483
498
  case "OUT":
484
- return [transferOp(getOperationRecipients(transaction.transaction?.data).at(0))];
499
+ return [
500
+ transferOp(
501
+ getOperationRecipients(transaction.transaction?.data).at(0),
502
+ BigInt(removeFeesFromAmountForNative(change, fees).toString()),
503
+ ),
504
+ ];
485
505
  case "DELEGATE":
486
506
  case "UNDELEGATE":
487
507
  return [
@@ -490,11 +510,18 @@ export function toBlockOperation(
490
510
  operationType: operationType,
491
511
  address: change.owner.AddressOwner,
492
512
  asset: toSuiAsset(change.coinType),
493
- amount: BigInt(absoluteAmount(change).toString()),
513
+ amount: BigInt(removeFeesFromAmountForNative(change, fees).toString()),
494
514
  },
495
515
  ];
496
516
  default:
497
- return [];
517
+ return [
518
+ {
519
+ type: "transfer",
520
+ address: address,
521
+ asset: toSuiAsset(change.coinType),
522
+ amount: BigInt(change.amount),
523
+ },
524
+ ];
498
525
  }
499
526
  }
500
527