@ledgerhq/coin-canton 0.5.0 → 0.5.1-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 (261) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +21 -0
  3. package/lib/api/getBalance.integ.test.js +9 -5
  4. package/lib/api/getBalance.integ.test.js.map +1 -1
  5. package/lib/api/index.d.ts.map +1 -1
  6. package/lib/api/index.js +20 -25
  7. package/lib/api/index.js.map +1 -1
  8. package/lib/api/lastBlock.integ.test.js +1 -1
  9. package/lib/api/lastBlock.integ.test.js.map +1 -1
  10. package/lib/api/listOperations.integ.test.js +1 -1
  11. package/lib/api/listOperations.integ.test.js.map +1 -1
  12. package/lib/bridge/broadcast.d.ts.map +1 -1
  13. package/lib/bridge/broadcast.js +3 -2
  14. package/lib/bridge/broadcast.js.map +1 -1
  15. package/lib/bridge/broadcast.test.js +9 -0
  16. package/lib/bridge/broadcast.test.js.map +1 -1
  17. package/lib/bridge/createTransaction.js +1 -1
  18. package/lib/bridge/createTransaction.js.map +1 -1
  19. package/lib/bridge/getTransactionStatus.js +1 -1
  20. package/lib/bridge/getTransactionStatus.js.map +1 -1
  21. package/lib/bridge/index.d.ts.map +1 -1
  22. package/lib/bridge/index.js +3 -0
  23. package/lib/bridge/index.js.map +1 -1
  24. package/lib/bridge/onboard.d.ts +7 -5
  25. package/lib/bridge/onboard.d.ts.map +1 -1
  26. package/lib/bridge/onboard.integ.test.js +14 -11
  27. package/lib/bridge/onboard.integ.test.js.map +1 -1
  28. package/lib/bridge/onboard.js +110 -42
  29. package/lib/bridge/onboard.js.map +1 -1
  30. package/lib/bridge/prepareTransaction.d.ts.map +1 -1
  31. package/lib/bridge/prepareTransaction.js +5 -7
  32. package/lib/bridge/prepareTransaction.js.map +1 -1
  33. package/lib/bridge/serialization.d.ts +4 -0
  34. package/lib/bridge/serialization.d.ts.map +1 -0
  35. package/lib/bridge/serialization.js +31 -0
  36. package/lib/bridge/serialization.js.map +1 -0
  37. package/lib/bridge/signOperation.d.ts.map +1 -1
  38. package/lib/bridge/signOperation.js +14 -11
  39. package/lib/bridge/signOperation.js.map +1 -1
  40. package/lib/bridge/sync.d.ts +2 -1
  41. package/lib/bridge/sync.d.ts.map +1 -1
  42. package/lib/bridge/sync.integ.test.d.ts +2 -0
  43. package/lib/bridge/sync.integ.test.d.ts.map +1 -0
  44. package/lib/bridge/sync.integ.test.js +175 -0
  45. package/lib/bridge/sync.integ.test.js.map +1 -0
  46. package/lib/bridge/sync.js +50 -27
  47. package/lib/bridge/sync.js.map +1 -1
  48. package/lib/bridge/updateTransaction.d.ts.map +1 -1
  49. package/lib/bridge/updateTransaction.js +0 -4
  50. package/lib/bridge/updateTransaction.js.map +1 -1
  51. package/lib/common-logic/account/getBalance.d.ts +2 -1
  52. package/lib/common-logic/account/getBalance.d.ts.map +1 -1
  53. package/lib/common-logic/account/getBalance.js +7 -7
  54. package/lib/common-logic/account/getBalance.js.map +1 -1
  55. package/lib/common-logic/account/getBalance.unit.test.js +6 -3
  56. package/lib/common-logic/account/getBalance.unit.test.js.map +1 -1
  57. package/lib/common-logic/history/lastBlock.d.ts +2 -1
  58. package/lib/common-logic/history/lastBlock.d.ts.map +1 -1
  59. package/lib/common-logic/history/lastBlock.js +3 -3
  60. package/lib/common-logic/history/lastBlock.js.map +1 -1
  61. package/lib/common-logic/history/lastBlock.test.js +5 -2
  62. package/lib/common-logic/history/lastBlock.test.js.map +1 -1
  63. package/lib/common-logic/history/listOperations.d.ts +2 -1
  64. package/lib/common-logic/history/listOperations.d.ts.map +1 -1
  65. package/lib/common-logic/history/listOperations.js +2 -2
  66. package/lib/common-logic/history/listOperations.js.map +1 -1
  67. package/lib/common-logic/transaction/broadcast.d.ts +2 -1
  68. package/lib/common-logic/transaction/broadcast.d.ts.map +1 -1
  69. package/lib/common-logic/transaction/broadcast.js +5 -4
  70. package/lib/common-logic/transaction/broadcast.js.map +1 -1
  71. package/lib/common-logic/transaction/broadcast.test.js +8 -5
  72. package/lib/common-logic/transaction/broadcast.test.js.map +1 -1
  73. package/lib/common-logic/transaction/combine.d.ts +1 -1
  74. package/lib/common-logic/transaction/combine.d.ts.map +1 -1
  75. package/lib/common-logic/transaction/combine.js +2 -3
  76. package/lib/common-logic/transaction/combine.js.map +1 -1
  77. package/lib/common-logic/transaction/combine.test.js +3 -13
  78. package/lib/common-logic/transaction/combine.test.js.map +1 -1
  79. package/lib/common-logic/transaction/craftTransaction.d.ts +8 -4
  80. package/lib/common-logic/transaction/craftTransaction.d.ts.map +1 -1
  81. package/lib/common-logic/transaction/craftTransaction.js +15 -12
  82. package/lib/common-logic/transaction/craftTransaction.js.map +1 -1
  83. package/lib/common-logic/transaction/estimateFees.d.ts +2 -1
  84. package/lib/common-logic/transaction/estimateFees.d.ts.map +1 -1
  85. package/lib/common-logic/transaction/estimateFees.js +7 -3
  86. package/lib/common-logic/transaction/estimateFees.js.map +1 -1
  87. package/lib/config.d.ts +1 -0
  88. package/lib/config.d.ts.map +1 -1
  89. package/lib/config.js.map +1 -1
  90. package/lib/network/gateway.d.ts +41 -17
  91. package/lib/network/gateway.d.ts.map +1 -1
  92. package/lib/network/gateway.integ.test.js +19 -15
  93. package/lib/network/gateway.integ.test.js.map +1 -1
  94. package/lib/network/gateway.js +74 -48
  95. package/lib/network/gateway.js.map +1 -1
  96. package/lib/network/node.d.ts +2 -2
  97. package/lib/network/node.d.ts.map +1 -1
  98. package/lib/network/node.js.map +1 -1
  99. package/lib/network/types.d.ts +1 -1
  100. package/lib/network/types.d.ts.map +1 -1
  101. package/lib/signer/getAddress.d.ts.map +1 -1
  102. package/lib/signer/getAddress.js +2 -2
  103. package/lib/signer/getAddress.js.map +1 -1
  104. package/lib/types/bridge.d.ts +18 -3
  105. package/lib/types/bridge.d.ts.map +1 -1
  106. package/lib/types/index.d.ts +0 -10
  107. package/lib/types/index.d.ts.map +1 -1
  108. package/lib/types/onboard.d.ts +2 -0
  109. package/lib/types/onboard.d.ts.map +1 -1
  110. package/lib/types/onboard.js.map +1 -1
  111. package/lib/types/signer.d.ts +2 -1
  112. package/lib/types/signer.d.ts.map +1 -1
  113. package/lib-es/api/getBalance.integ.test.js +9 -5
  114. package/lib-es/api/getBalance.integ.test.js.map +1 -1
  115. package/lib-es/api/index.d.ts.map +1 -1
  116. package/lib-es/api/index.js +19 -24
  117. package/lib-es/api/index.js.map +1 -1
  118. package/lib-es/api/lastBlock.integ.test.js +1 -1
  119. package/lib-es/api/lastBlock.integ.test.js.map +1 -1
  120. package/lib-es/api/listOperations.integ.test.js +1 -1
  121. package/lib-es/api/listOperations.integ.test.js.map +1 -1
  122. package/lib-es/bridge/broadcast.d.ts.map +1 -1
  123. package/lib-es/bridge/broadcast.js +3 -2
  124. package/lib-es/bridge/broadcast.js.map +1 -1
  125. package/lib-es/bridge/broadcast.test.js +9 -0
  126. package/lib-es/bridge/broadcast.test.js.map +1 -1
  127. package/lib-es/bridge/createTransaction.js +1 -1
  128. package/lib-es/bridge/createTransaction.js.map +1 -1
  129. package/lib-es/bridge/getTransactionStatus.js +1 -1
  130. package/lib-es/bridge/getTransactionStatus.js.map +1 -1
  131. package/lib-es/bridge/index.d.ts.map +1 -1
  132. package/lib-es/bridge/index.js +3 -0
  133. package/lib-es/bridge/index.js.map +1 -1
  134. package/lib-es/bridge/onboard.d.ts +7 -5
  135. package/lib-es/bridge/onboard.d.ts.map +1 -1
  136. package/lib-es/bridge/onboard.integ.test.js +14 -11
  137. package/lib-es/bridge/onboard.integ.test.js.map +1 -1
  138. package/lib-es/bridge/onboard.js +107 -42
  139. package/lib-es/bridge/onboard.js.map +1 -1
  140. package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
  141. package/lib-es/bridge/prepareTransaction.js +6 -8
  142. package/lib-es/bridge/prepareTransaction.js.map +1 -1
  143. package/lib-es/bridge/serialization.d.ts +4 -0
  144. package/lib-es/bridge/serialization.d.ts.map +1 -0
  145. package/lib-es/bridge/serialization.js +27 -0
  146. package/lib-es/bridge/serialization.js.map +1 -0
  147. package/lib-es/bridge/signOperation.d.ts.map +1 -1
  148. package/lib-es/bridge/signOperation.js +15 -12
  149. package/lib-es/bridge/signOperation.js.map +1 -1
  150. package/lib-es/bridge/sync.d.ts +2 -1
  151. package/lib-es/bridge/sync.d.ts.map +1 -1
  152. package/lib-es/bridge/sync.integ.test.d.ts +2 -0
  153. package/lib-es/bridge/sync.integ.test.d.ts.map +1 -0
  154. package/lib-es/bridge/sync.integ.test.js +137 -0
  155. package/lib-es/bridge/sync.integ.test.js.map +1 -0
  156. package/lib-es/bridge/sync.js +51 -28
  157. package/lib-es/bridge/sync.js.map +1 -1
  158. package/lib-es/bridge/updateTransaction.d.ts.map +1 -1
  159. package/lib-es/bridge/updateTransaction.js +0 -4
  160. package/lib-es/bridge/updateTransaction.js.map +1 -1
  161. package/lib-es/common-logic/account/getBalance.d.ts +2 -1
  162. package/lib-es/common-logic/account/getBalance.d.ts.map +1 -1
  163. package/lib-es/common-logic/account/getBalance.js +7 -7
  164. package/lib-es/common-logic/account/getBalance.js.map +1 -1
  165. package/lib-es/common-logic/account/getBalance.unit.test.js +6 -3
  166. package/lib-es/common-logic/account/getBalance.unit.test.js.map +1 -1
  167. package/lib-es/common-logic/history/lastBlock.d.ts +2 -1
  168. package/lib-es/common-logic/history/lastBlock.d.ts.map +1 -1
  169. package/lib-es/common-logic/history/lastBlock.js +3 -3
  170. package/lib-es/common-logic/history/lastBlock.js.map +1 -1
  171. package/lib-es/common-logic/history/lastBlock.test.js +5 -2
  172. package/lib-es/common-logic/history/lastBlock.test.js.map +1 -1
  173. package/lib-es/common-logic/history/listOperations.d.ts +2 -1
  174. package/lib-es/common-logic/history/listOperations.d.ts.map +1 -1
  175. package/lib-es/common-logic/history/listOperations.js +2 -2
  176. package/lib-es/common-logic/history/listOperations.js.map +1 -1
  177. package/lib-es/common-logic/transaction/broadcast.d.ts +2 -1
  178. package/lib-es/common-logic/transaction/broadcast.d.ts.map +1 -1
  179. package/lib-es/common-logic/transaction/broadcast.js +5 -4
  180. package/lib-es/common-logic/transaction/broadcast.js.map +1 -1
  181. package/lib-es/common-logic/transaction/broadcast.test.js +8 -5
  182. package/lib-es/common-logic/transaction/broadcast.test.js.map +1 -1
  183. package/lib-es/common-logic/transaction/combine.d.ts +1 -1
  184. package/lib-es/common-logic/transaction/combine.d.ts.map +1 -1
  185. package/lib-es/common-logic/transaction/combine.js +2 -3
  186. package/lib-es/common-logic/transaction/combine.js.map +1 -1
  187. package/lib-es/common-logic/transaction/combine.test.js +3 -13
  188. package/lib-es/common-logic/transaction/combine.test.js.map +1 -1
  189. package/lib-es/common-logic/transaction/craftTransaction.d.ts +8 -4
  190. package/lib-es/common-logic/transaction/craftTransaction.d.ts.map +1 -1
  191. package/lib-es/common-logic/transaction/craftTransaction.js +15 -12
  192. package/lib-es/common-logic/transaction/craftTransaction.js.map +1 -1
  193. package/lib-es/common-logic/transaction/estimateFees.d.ts +2 -1
  194. package/lib-es/common-logic/transaction/estimateFees.d.ts.map +1 -1
  195. package/lib-es/common-logic/transaction/estimateFees.js +4 -3
  196. package/lib-es/common-logic/transaction/estimateFees.js.map +1 -1
  197. package/lib-es/config.d.ts +1 -0
  198. package/lib-es/config.d.ts.map +1 -1
  199. package/lib-es/config.js.map +1 -1
  200. package/lib-es/network/gateway.d.ts +41 -17
  201. package/lib-es/network/gateway.d.ts.map +1 -1
  202. package/lib-es/network/gateway.integ.test.js +19 -15
  203. package/lib-es/network/gateway.integ.test.js.map +1 -1
  204. package/lib-es/network/gateway.js +73 -48
  205. package/lib-es/network/gateway.js.map +1 -1
  206. package/lib-es/network/node.d.ts +2 -2
  207. package/lib-es/network/node.d.ts.map +1 -1
  208. package/lib-es/network/node.js.map +1 -1
  209. package/lib-es/network/types.d.ts +1 -1
  210. package/lib-es/network/types.d.ts.map +1 -1
  211. package/lib-es/signer/getAddress.d.ts.map +1 -1
  212. package/lib-es/signer/getAddress.js +2 -2
  213. package/lib-es/signer/getAddress.js.map +1 -1
  214. package/lib-es/types/bridge.d.ts +18 -3
  215. package/lib-es/types/bridge.d.ts.map +1 -1
  216. package/lib-es/types/index.d.ts +0 -10
  217. package/lib-es/types/index.d.ts.map +1 -1
  218. package/lib-es/types/onboard.d.ts +2 -0
  219. package/lib-es/types/onboard.d.ts.map +1 -1
  220. package/lib-es/types/onboard.js.map +1 -1
  221. package/lib-es/types/signer.d.ts +2 -1
  222. package/lib-es/types/signer.d.ts.map +1 -1
  223. package/package.json +8 -8
  224. package/src/api/getBalance.integ.test.ts +9 -6
  225. package/src/api/index.ts +22 -44
  226. package/src/api/lastBlock.integ.test.ts +1 -1
  227. package/src/api/listOperations.integ.test.ts +1 -1
  228. package/src/bridge/broadcast.test.ts +11 -0
  229. package/src/bridge/broadcast.ts +4 -2
  230. package/src/bridge/createTransaction.ts +1 -1
  231. package/src/bridge/getTransactionStatus.ts +1 -1
  232. package/src/bridge/index.ts +3 -0
  233. package/src/bridge/onboard.integ.test.ts +25 -13
  234. package/src/bridge/onboard.ts +143 -51
  235. package/src/bridge/prepareTransaction.ts +6 -15
  236. package/src/bridge/serialization.ts +36 -0
  237. package/src/bridge/signOperation.ts +26 -20
  238. package/src/bridge/sync.integ.test.ts +180 -0
  239. package/src/bridge/sync.ts +61 -33
  240. package/src/bridge/updateTransaction.ts +0 -5
  241. package/src/common-logic/account/getBalance.ts +12 -7
  242. package/src/common-logic/account/getBalance.unit.test.ts +8 -3
  243. package/src/common-logic/history/lastBlock.test.ts +7 -2
  244. package/src/common-logic/history/lastBlock.ts +5 -3
  245. package/src/common-logic/history/listOperations.ts +3 -2
  246. package/src/common-logic/transaction/broadcast.test.ts +10 -5
  247. package/src/common-logic/transaction/broadcast.ts +7 -3
  248. package/src/common-logic/transaction/combine.test.ts +3 -13
  249. package/src/common-logic/transaction/combine.ts +2 -4
  250. package/src/common-logic/transaction/craftTransaction.ts +30 -15
  251. package/src/common-logic/transaction/estimateFees.ts +8 -3
  252. package/src/config.ts +1 -0
  253. package/src/network/gateway.integ.test.ts +31 -12
  254. package/src/network/gateway.ts +141 -62
  255. package/src/network/node.ts +3 -3
  256. package/src/network/types.ts +1 -1
  257. package/src/signer/getAddress.ts +6 -4
  258. package/src/types/bridge.ts +21 -0
  259. package/src/types/index.ts +0 -11
  260. package/src/types/onboard.ts +3 -0
  261. package/src/types/signer.ts +2 -1
@@ -1,14 +1,14 @@
1
1
  import BigNumber from "bignumber.js";
2
- import { Operation } from "@ledgerhq/types-live";
3
- import { encodeAccountId } from "@ledgerhq/coin-framework/account/index";
2
+ import { Operation, OperationType } from "@ledgerhq/types-live";
3
+ import { decodeAccountId, encodeAccountId } from "@ledgerhq/coin-framework/account/index";
4
4
  import { GetAccountShape, mergeOps } from "@ledgerhq/coin-framework/bridge/jsHelpers";
5
- import { getBalance, getLedgerEnd, getOperations, type OperationInfo } from "../network/gateway";
6
-
7
5
  import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
6
+ import { getBalance, getLedgerEnd, getOperations, type OperationInfo } from "../network/gateway";
7
+ import { CantonAccount } from "../types";
8
8
  import coinConfig from "../config";
9
9
 
10
10
  const txInfoToOperationAdapter =
11
- (accountId: string, address: string) =>
11
+ (accountId: string, partyId: string) =>
12
12
  (txInfo: OperationInfo): Operation => {
13
13
  const {
14
14
  transaction_hash,
@@ -18,12 +18,17 @@ const txInfoToOperationAdapter =
18
18
  recipients,
19
19
  transaction_timestamp,
20
20
  fee: { value: fee },
21
- transfers: [{ value: transferValue }],
21
+ transfers: [{ value: transferValue, details }],
22
22
  } = txInfo;
23
-
24
- const type = senders.includes(address) ? "OUT" : "IN";
23
+ let type: OperationType = "UNKNOWN";
24
+ if (txInfo.type === "Send") {
25
+ type = senders.includes(partyId) ? "OUT" : "IN";
26
+ } else if (txInfo.type === "Receive") {
27
+ type = "IN";
28
+ }
25
29
  const value = new BigNumber(transferValue);
26
30
  const feeValue = new BigNumber(fee);
31
+ const memo = details.metadata.reason;
27
32
 
28
33
  const op: Operation = {
29
34
  id: encodeOperationId(accountId, transaction_hash, type),
@@ -40,6 +45,7 @@ const txInfoToOperationAdapter =
40
45
  transactionSequenceNumber: height,
41
46
  extra: {
42
47
  uid,
48
+ memo,
43
49
  },
44
50
  };
45
51
 
@@ -49,47 +55,64 @@ const txInfoToOperationAdapter =
49
55
  const filterOperations = (
50
56
  transactions: OperationInfo[],
51
57
  accountId: string,
52
- address: string,
58
+ partyId: string,
53
59
  ): Operation[] => {
54
- return transactions
55
- .filter(tx => tx.type === "Receive" || tx.type === "Send")
56
- .map(txInfoToOperationAdapter(accountId, address));
60
+ return transactions.map(txInfoToOperationAdapter(accountId, partyId));
57
61
  };
58
62
 
59
- export const getAccountShape: GetAccountShape = async info => {
60
- const { address, initialAccount, currency, derivationMode } = info;
61
- // TODO: we need better solution ?
62
- const xpubOrAddress = address?.replace(/:/g, "_") || "";
63
+ export const getAccountShape: GetAccountShape<CantonAccount> = async info => {
64
+ const { address, initialAccount, currency, derivationMode, derivationPath, rest } = info;
65
+
66
+ const xpubOrAddress = (
67
+ (initialAccount && initialAccount.id && decodeAccountId(initialAccount.id).xpubOrAddress) ||
68
+ ""
69
+ ).replace(/:/g, "_");
70
+ const partyId =
71
+ rest?.cantonResources?.partyId ||
72
+ initialAccount?.cantonResources?.partyId ||
73
+ xpubOrAddress.replace(/_/g, ":");
63
74
 
64
75
  const accountId = encodeAccountId({
65
76
  type: "js",
66
77
  version: "2",
67
78
  currencyId: currency.id,
68
79
  xpubOrAddress,
69
- derivationMode: "",
80
+ derivationMode,
70
81
  });
71
82
 
72
- // blockheight retrieval
73
- const blockHeight = await getLedgerEnd();
74
-
75
83
  // Account info retrieval + spendable balance calculation
76
84
  // const accountInfo = await getAccountInfo(address);
77
- const balanceData = await getBalance(address);
78
- const balance = new BigNumber(balanceData[0]?.amount || "0");
79
- const reserveMin = coinConfig.getCoinConfig().minReserve || 0;
80
- const spendableBalance = balance.minus(BigNumber(reserveMin));
85
+ const balances = await getBalance(currency, partyId);
81
86
 
82
- // Tx history fetching
83
- const oldOperations = initialAccount?.operations || [];
84
- const startAt = oldOperations.length ? (oldOperations[0].blockHeight || 0) + 1 : 0;
85
- const transactionData = await getOperations(address, {
86
- cursor: 0,
87
- limit: 100,
88
- });
87
+ const balanceData = balances.find(balance => balance.instrument_id === "Amulet") || {
88
+ instrument_id: "Amulet",
89
+ amount: 0,
90
+ locked: false,
91
+ };
89
92
 
90
- const newOperations = filterOperations(transactionData.operations, accountId, address);
91
- const operations = mergeOps(oldOperations, newOperations);
93
+ const balance = new BigNumber(balanceData.amount);
94
+ const reserveMin = coinConfig.getCoinConfig(currency).minReserve || 0;
95
+ const lockedAmount = balanceData.locked ? balance : new BigNumber(0);
96
+ const spendableBalance = BigNumber.max(
97
+ 0,
98
+ balance.minus(lockedAmount).minus(BigNumber(reserveMin)),
99
+ );
92
100
 
101
+ let operations: Operation[] = [];
102
+ // Tx history fetching if xpubOrAddress is not empty
103
+ if (xpubOrAddress) {
104
+ const oldOperations = initialAccount?.operations || [];
105
+ const startAt = oldOperations.length ? (oldOperations[0].blockHeight || 0) + 1 : 0;
106
+ const transactionData = await getOperations(currency, partyId, {
107
+ cursor: startAt,
108
+ limit: 100,
109
+ });
110
+
111
+ const newOperations = filterOperations(transactionData.operations, accountId, partyId);
112
+ operations = mergeOps(oldOperations, newOperations);
113
+ }
114
+ // blockheight retrieval
115
+ const blockHeight = await getLedgerEnd(currency);
93
116
  // We return the new account shape
94
117
  const shape = {
95
118
  id: accountId,
@@ -99,6 +122,11 @@ export const getAccountShape: GetAccountShape = async info => {
99
122
  spendableBalance,
100
123
  operations,
101
124
  operationsCount: operations.length,
125
+ freshAddress: address,
126
+ freshAddressPath: derivationPath,
127
+ cantonResources: {
128
+ partyId,
129
+ },
102
130
  };
103
131
 
104
132
  return shape;
@@ -8,10 +8,5 @@ import type { Transaction } from "../types";
8
8
  // NOTE: here is an example transaction updater function
9
9
  // in this case, it resets fee to null depending on the patch content
10
10
  export const updateTransaction: AccountBridge<Transaction>["updateTransaction"] = (tx, patch) => {
11
- // eslint-disable-next-line no-constant-condition
12
- if (patch.recipient === "boilerplate1" || true) {
13
- patch = { ...patch, fee: null };
14
- }
15
-
16
11
  return defaultUpdateTransaction(tx, patch);
17
12
  };
@@ -1,23 +1,28 @@
1
1
  import { Balance } from "@ledgerhq/coin-framework/api/types";
2
2
  import { getBalance as gatewayGetBalance, type InstrumentBalance } from "../../network/gateway";
3
3
  import coinConfig from "../../config";
4
+ import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
4
5
 
5
- const useGateway = () => coinConfig.getCoinConfig().useGateway === true;
6
- const getNativeId = () => coinConfig.getCoinConfig().nativeInstrumentId;
6
+ const useGateway = (currency: CryptoCurrency) =>
7
+ coinConfig.getCoinConfig(currency).useGateway === true;
8
+ const getNativeId = (currency: CryptoCurrency) =>
9
+ coinConfig.getCoinConfig(currency).nativeInstrumentId;
7
10
 
8
- function adaptInstrument(instrument: InstrumentBalance): Balance {
11
+ function adaptInstrument(currency: CryptoCurrency, instrument: InstrumentBalance): Balance {
9
12
  return {
10
13
  value: BigInt(instrument.amount),
11
14
  locked: instrument.locked === true ? BigInt(instrument.amount) : BigInt(0),
12
15
  asset:
13
- getNativeId() === instrument.instrument_id
16
+ getNativeId(currency) === instrument.instrument_id
14
17
  ? { type: "native" }
15
18
  : { type: "token", assetReference: instrument.instrument_id },
16
19
  };
17
20
  }
18
21
 
19
- export async function getBalance(partyId: string): Promise<Balance[]> {
20
- if (useGateway())
21
- return (await gatewayGetBalance(partyId)).map(instrument => adaptInstrument(instrument));
22
+ export async function getBalance(currency: CryptoCurrency, partyId: string): Promise<Balance[]> {
23
+ if (useGateway(currency))
24
+ return (await gatewayGetBalance(currency, partyId)).map(instrument =>
25
+ adaptInstrument(currency, instrument),
26
+ );
22
27
  else throw new Error("Not implemented");
23
28
  }
@@ -2,6 +2,11 @@ import { getBalance as getBalanceFromNetwork } from "../../network/gateway";
2
2
  import * as coinConfigModule from "../../config";
3
3
  import { getBalance } from "./getBalance";
4
4
  import { Balance } from "@ledgerhq/coin-framework/api/types";
5
+ import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
6
+
7
+ const mockCurrency = {
8
+ id: "canton_network",
9
+ } as unknown as CryptoCurrency;
5
10
 
6
11
  jest.mock("../../network/gateway", () => ({
7
12
  getBalance: jest.fn(),
@@ -35,9 +40,9 @@ describe("getBalance", () => {
35
40
 
36
41
  (getBalanceFromNetwork as jest.Mock).mockResolvedValue(mockInstruments);
37
42
 
38
- const result = await getBalance("party-id");
43
+ const result = await getBalance(mockCurrency, "party-id");
39
44
 
40
- expect(getBalanceFromNetwork).toHaveBeenCalledWith("party-id");
45
+ expect(getBalanceFromNetwork).toHaveBeenCalledWith(mockCurrency, "party-id");
41
46
  expect(result).toEqual<Balance[]>([
42
47
  {
43
48
  value: BigInt(1000),
@@ -57,7 +62,7 @@ describe("getBalance", () => {
57
62
  useGateway: false,
58
63
  } as any);
59
64
 
60
- await expect(getBalance("party-id")).rejects.toThrow("Not implemented");
65
+ await expect(getBalance(mockCurrency, "party-id")).rejects.toThrow("Not implemented");
61
66
  expect(getBalanceFromNetwork).not.toHaveBeenCalled();
62
67
  });
63
68
  });
@@ -1,6 +1,7 @@
1
1
  import { lastBlock } from "./lastBlock";
2
2
  import { getLedgerEnd as gatewayGetLedgerEnd } from "../../network/gateway";
3
3
  import { getLedgerEnd as nodeGetLedgerEnd } from "../../network/node";
4
+ import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
4
5
 
5
6
  jest.mock("../../network/gateway", () => ({
6
7
  getLedgerEnd: jest.fn(),
@@ -18,6 +19,10 @@ jest.mock("../../config", () => ({
18
19
 
19
20
  import coinConfig from "../../config";
20
21
 
22
+ const mockCurrency = {
23
+ id: "canton_network",
24
+ } as unknown as CryptoCurrency;
25
+
21
26
  describe("lastBlock", () => {
22
27
  beforeEach(() => {
23
28
  jest.clearAllMocks();
@@ -27,7 +32,7 @@ describe("lastBlock", () => {
27
32
  (coinConfig.getCoinConfig as jest.Mock).mockReturnValue({ useGateway: true });
28
33
  (gatewayGetLedgerEnd as jest.Mock).mockResolvedValue(100);
29
34
 
30
- const result = await lastBlock();
35
+ const result = await lastBlock(mockCurrency);
31
36
 
32
37
  expect(result).toEqual({ height: 100 });
33
38
  expect(gatewayGetLedgerEnd).toHaveBeenCalledTimes(1);
@@ -38,7 +43,7 @@ describe("lastBlock", () => {
38
43
  (coinConfig.getCoinConfig as jest.Mock).mockReturnValue({ useGateway: false });
39
44
  (nodeGetLedgerEnd as jest.Mock).mockResolvedValue(200);
40
45
 
41
- const result = await lastBlock();
46
+ const result = await lastBlock(mockCurrency);
42
47
 
43
48
  expect(result).toEqual({ height: 200 });
44
49
  expect(nodeGetLedgerEnd).toHaveBeenCalledTimes(1);
@@ -2,11 +2,13 @@ import type { BlockInfo } from "@ledgerhq/coin-framework/api/index";
2
2
  import { getLedgerEnd as nodeGetLedgerEnd } from "../../network/node";
3
3
  import { getLedgerEnd } from "../../network/gateway";
4
4
  import coinConfig from "../../config";
5
+ import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
5
6
 
6
- const useGateway = () => coinConfig.getCoinConfig().useGateway === true;
7
+ const useGateway = (currency: CryptoCurrency) =>
8
+ coinConfig.getCoinConfig(currency).useGateway === true;
7
9
 
8
- export async function lastBlock(): Promise<BlockInfo> {
10
+ export async function lastBlock(currency: CryptoCurrency): Promise<BlockInfo> {
9
11
  return {
10
- height: useGateway() ? await getLedgerEnd() : await nodeGetLedgerEnd(),
12
+ height: useGateway(currency) ? await getLedgerEnd(currency) : await nodeGetLedgerEnd(),
11
13
  };
12
14
  }
@@ -1,6 +1,6 @@
1
1
  import type { Operation, Pagination } from "@ledgerhq/coin-framework/api/index";
2
2
  import { getOperations } from "../../network/gateway";
3
- import coinConfig from "../../config";
3
+ import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
4
4
 
5
5
  /**
6
6
  * Returns list of operations associated to an account.
@@ -10,10 +10,11 @@ import coinConfig from "../../config";
10
10
  * Impl to finalize when backend is ready
11
11
  */
12
12
  export async function listOperations(
13
+ currency: CryptoCurrency,
13
14
  partyId: string,
14
15
  page: Pagination,
15
16
  ): Promise<[Operation[], string]> {
16
- const { operations, next } = await getOperations(partyId, {
17
+ const { operations, next } = await getOperations(currency, partyId, {
17
18
  cursor: page.pagingToken !== undefined ? parseInt(page.pagingToken) : undefined,
18
19
  minOffset: page.minHeight,
19
20
  limit: page.limit,
@@ -1,6 +1,7 @@
1
1
  import { submit } from "../../network/gateway";
2
2
  import * as coinConfigModule from "../../config";
3
3
  import { broadcast } from "./broadcast";
4
+ import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
4
5
 
5
6
  jest.mock("../../network/gateway", () => ({
6
7
  submit: jest.fn(),
@@ -8,9 +9,13 @@ jest.mock("../../network/gateway", () => ({
8
9
 
9
10
  const mockSerialized = JSON.stringify({
10
11
  serialized: "serialized-tx",
11
- signature: "signature",
12
+ signature: "signature__PARTY__alice:123",
12
13
  });
13
14
 
15
+ const mockCurrency = {
16
+ id: "canton_network",
17
+ } as unknown as CryptoCurrency;
18
+
14
19
  describe("broadcast", () => {
15
20
  const mockGetCoinConfig = jest.spyOn(coinConfigModule.default, "getCoinConfig");
16
21
 
@@ -23,11 +28,11 @@ describe("broadcast", () => {
23
28
  useGateway: true,
24
29
  } as any);
25
30
 
26
- (submit as jest.Mock).mockResolvedValue({ updateId: "my-update-id" });
31
+ (submit as jest.Mock).mockResolvedValue({ update_id: "my-update-id" });
27
32
 
28
- const result = await broadcast(mockSerialized);
33
+ const result = await broadcast(mockCurrency, mockSerialized);
29
34
 
30
- expect(submit).toHaveBeenCalledWith("serialized-tx", "signature");
35
+ expect(submit).toHaveBeenCalledWith(mockCurrency, "alice:123", "serialized-tx", "signature");
31
36
  expect(result).toEqual("my-update-id");
32
37
  });
33
38
 
@@ -36,7 +41,7 @@ describe("broadcast", () => {
36
41
  useGateway: false,
37
42
  } as any);
38
43
 
39
- await expect(broadcast(mockSerialized)).rejects.toThrow("Not implemented");
44
+ await expect(broadcast(mockCurrency, mockSerialized)).rejects.toThrow("Not implemented");
40
45
  expect(submit).not.toHaveBeenCalled();
41
46
  });
42
47
  });
@@ -1,10 +1,14 @@
1
1
  import coinConfig from "../../config";
2
2
  import { submit } from "../../network/gateway";
3
+ import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
3
4
 
4
- const useGateway = () => coinConfig.getCoinConfig().useGateway === true;
5
+ const useGateway = (currency: CryptoCurrency) =>
6
+ coinConfig.getCoinConfig(currency).useGateway === true;
5
7
 
6
- export async function broadcast(signedTx: string): Promise<string> {
8
+ export async function broadcast(currency: CryptoCurrency, signedTx: string): Promise<string> {
7
9
  const parsed: { serialized: string; signature: string } = JSON.parse(signedTx);
8
- if (useGateway()) return (await submit(parsed.serialized, parsed.signature)).updateId;
10
+ const [sig, party] = parsed.signature.split("__PARTY__");
11
+ if (useGateway(currency))
12
+ return (await submit(currency, party, parsed.serialized, sig)).update_id;
9
13
  else throw new Error("Not implemented");
10
14
  }
@@ -3,25 +3,15 @@ import { combine } from "./combine";
3
3
  describe("combine", () => {
4
4
  it("responds with a Stringify version of the payload to broadcast", () => {
5
5
  // GIVEN
6
- const transaction = {
7
- transaction: {
8
- serialized: "SERIALIZED",
9
- json: "JSON",
10
- hash: "HASH",
11
- },
12
- };
6
+ const transaction = "0x000000001";
13
7
  const signature = "SIGNATURE";
14
8
 
15
9
  // WHEN
16
- const result = combine(JSON.stringify(transaction), signature);
10
+ const result = combine(transaction, signature);
17
11
 
18
12
  // THEN
19
13
  expect(JSON.parse(result)).toEqual({
20
- transaction: {
21
- serialized: "SERIALIZED",
22
- json: "JSON",
23
- hash: "HASH",
24
- },
14
+ serialized: "0x000000001",
25
15
  signature: "SIGNATURE",
26
16
  });
27
17
  });
@@ -1,9 +1,7 @@
1
1
  // Combines signature with raw transaction
2
- export function combine(transaction: string, signature: string): string {
3
- const tx = JSON.parse(transaction);
4
-
2
+ export function combine(serialized: string, signature: string): string {
5
3
  return JSON.stringify({
6
- ...tx,
4
+ serialized,
7
5
  signature,
8
6
  });
9
7
  }
@@ -1,9 +1,13 @@
1
1
  import BigNumber from "bignumber.js";
2
- import { BoilerplateNativeTransaction } from "../../types";
3
-
4
- const encodeNativeTx = (nativeTx: BoilerplateNativeTransaction) => JSON.stringify(nativeTx);
2
+ import {
3
+ PrepareTransferRequest,
4
+ prepareTransferRequest,
5
+ PrepareTransferResponse,
6
+ } from "../../network/gateway";
7
+ import { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
5
8
 
6
9
  export async function craftTransaction(
10
+ currency: CryptoCurrency,
7
11
  account: {
8
12
  address: string;
9
13
  nextSequenceNumber?: number;
@@ -12,25 +16,36 @@ export async function craftTransaction(
12
16
  transaction: {
13
17
  recipient?: string;
14
18
  amount: BigNumber;
15
- fee?: BigNumber;
19
+ tokenId: string;
20
+ expireInSeconds: number;
21
+ memo?: string;
16
22
  },
17
23
  ): Promise<{
18
- nativeTransaction: BoilerplateNativeTransaction;
24
+ nativeTransaction: PrepareTransferResponse;
19
25
  serializedTransaction: string;
26
+ hash: string;
20
27
  }> {
21
- const nativeTransaction: BoilerplateNativeTransaction = {
22
- TransactionType: "Payment",
23
- Account: account.address,
24
- Amount: transaction.amount.toString(),
25
- Destination: transaction.recipient || "",
26
- Fee: transaction.fee?.toString() || "0",
27
- Sequence: account.nextSequenceNumber || 0,
28
+ const params: PrepareTransferRequest = {
29
+ recipient: transaction.recipient || "",
30
+ amount: transaction.amount.toString(),
31
+ type: "token-transfer-request" as const,
32
+ execute_before_secs: transaction.expireInSeconds,
33
+ instrument_id: transaction.tokenId,
28
34
  };
29
35
 
30
- const serializedTransaction = encodeNativeTx(nativeTransaction);
36
+ if (transaction.memo) {
37
+ params.reason = transaction.memo;
38
+ }
39
+
40
+ const { serialized, json, hash } = await prepareTransferRequest(
41
+ currency,
42
+ account.address,
43
+ params,
44
+ );
31
45
 
32
46
  return {
33
- nativeTransaction,
34
- serializedTransaction,
47
+ nativeTransaction: json,
48
+ serializedTransaction: serialized,
49
+ hash,
35
50
  };
36
51
  }
@@ -1,4 +1,9 @@
1
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
2
- export async function estimateFees(serializedTransaction: string): Promise<bigint> {
3
- return Promise.resolve(BigInt(10_000)); // TODO replace with real implementation
1
+ import coinConfig from "../../config";
2
+ import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
3
+
4
+ const feeValue = (currency: CryptoCurrency) =>
5
+ coinConfig.getCoinConfig(currency).fee ?? 2n * 10n ** 38n;
6
+
7
+ export async function estimateFees(currency: CryptoCurrency): Promise<bigint> {
8
+ return Promise.resolve(BigInt(feeValue(currency)));
4
9
  }
package/src/config.ts CHANGED
@@ -10,6 +10,7 @@ export type CantonConfig = {
10
10
  networkType: "mainnet" | "devnet" | "localnet";
11
11
  useGateway?: boolean;
12
12
  nativeInstrumentId?: string;
13
+ fee?: number;
13
14
  };
14
15
 
15
16
  export type CantonCoinConfig = CurrencyConfig & CantonConfig;
@@ -13,6 +13,11 @@ import {
13
13
  preparePreApprovalTransaction,
14
14
  submitPreApprovalTransaction,
15
15
  } from "./gateway";
16
+ import type { CryptoCurrency } from "@ledgerhq/types-cryptoassets";
17
+
18
+ const mockCurrency = {
19
+ id: "canton_network",
20
+ } as unknown as CryptoCurrency;
16
21
 
17
22
  describe("gateway (devnet)", () => {
18
23
  let onboardedAccount: {
@@ -50,7 +55,7 @@ describe("gateway (devnet)", () => {
50
55
  };
51
56
 
52
57
  // WHEN
53
- const response = await prepareOnboarding(keyPair.publicKeyHex, "ed25519");
58
+ const response = await prepareOnboarding(mockCurrency, keyPair.publicKeyHex, "ed25519");
54
59
 
55
60
  // THEN
56
61
  expect(response).toHaveProperty("party_id");
@@ -58,7 +63,8 @@ describe("gateway (devnet)", () => {
58
63
  expect(response).toHaveProperty("public_key_fingerprint");
59
64
  expect(response).toHaveProperty("transactions");
60
65
  expect(response.transactions).toHaveProperty("combined_hash");
61
- expect(response.party_name).toBe(keyPair.publicKeyHex);
66
+ expect(response.party_name).toBeDefined();
67
+ expect(typeof response.party_name).toBe("string");
62
68
 
63
69
  expect(response.public_key_fingerprint).toBe(keyPair.fingerprint);
64
70
  }, 30000);
@@ -69,11 +75,20 @@ describe("gateway (devnet)", () => {
69
75
  // GIVEN
70
76
  const { keyPair } = getOnboardedAccount();
71
77
  const prepareRequest = { public_key: keyPair.publicKeyHex, public_key_type: "ed25519" };
72
- const prepareResponse = await prepareOnboarding(keyPair.publicKeyHex, "ed25519");
78
+ const prepareResponse = await prepareOnboarding(
79
+ mockCurrency,
80
+ keyPair.publicKeyHex,
81
+ "ed25519",
82
+ );
73
83
  const signature = keyPair.sign(prepareResponse.transactions.combined_hash);
74
84
 
75
85
  // WHEN
76
- const response = await submitOnboarding(prepareRequest, prepareResponse, signature);
86
+ const response = await submitOnboarding(
87
+ mockCurrency,
88
+ prepareRequest,
89
+ prepareResponse,
90
+ signature,
91
+ );
77
92
 
78
93
  // Save onboarded account for all tests that need a valid party ID
79
94
  onboardedAccount = {
@@ -91,7 +106,7 @@ describe("gateway (devnet)", () => {
91
106
 
92
107
  describe("getLedgerEnd", () => {
93
108
  it("should return ledger end", async () => {
94
- const end = await getLedgerEnd();
109
+ const end = await getLedgerEnd(mockCurrency);
95
110
  expect(end).toBeGreaterThanOrEqual(0);
96
111
  });
97
112
  });
@@ -99,7 +114,7 @@ describe("gateway (devnet)", () => {
99
114
  describe("getBalance", () => {
100
115
  it("should return user balance", async () => {
101
116
  const { partyId } = getOnboardedAccount();
102
- const balance = await getBalance(partyId);
117
+ const balance = await getBalance(mockCurrency, partyId);
103
118
  expect(balance.length).toBeGreaterThanOrEqual(0);
104
119
  if (balance.length > 0) {
105
120
  expect(balance[0].amount).toBeGreaterThanOrEqual(0);
@@ -110,7 +125,7 @@ describe("gateway (devnet)", () => {
110
125
 
111
126
  describe("getPartyById", () => {
112
127
  it.skip("should return party info", async () => {
113
- const party = await getPartyById("4f2e1485107adf5f");
128
+ const party = await getPartyById(mockCurrency, "4f2e1485107adf5f");
114
129
  expect(party).toBeDefined();
115
130
  });
116
131
  });
@@ -118,6 +133,7 @@ describe("gateway (devnet)", () => {
118
133
  describe("getPartyByPubKey", () => {
119
134
  it.skip("should return party info", async () => {
120
135
  const party = await getPartyByPubKey(
136
+ mockCurrency,
121
137
  "122027c6dbbbdbffe0fa3122ae05175f3b9328e879e9ce96b670354deb64a45683c1",
122
138
  );
123
139
  expect(party).toBeDefined();
@@ -127,7 +143,9 @@ describe("gateway (devnet)", () => {
127
143
  describe("getOperations", () => {
128
144
  it("should return user transactions", async () => {
129
145
  const { operations } = await getOperations(
146
+ mockCurrency,
130
147
  "party-5f29bb32e9939939::12202becd8062a1d170209956cfd977fca76fcb4d2a892d08c77a7483f35a11d6440",
148
+ {},
131
149
  );
132
150
  expect(operations.length).toBeGreaterThanOrEqual(0);
133
151
  });
@@ -140,7 +158,7 @@ describe("gateway (devnet)", () => {
140
158
  const amount = 1000;
141
159
 
142
160
  // WHEN
143
- const response = await prepareTapRequest({ partyId, amount });
161
+ const response = await prepareTapRequest(mockCurrency, { partyId, amount });
144
162
 
145
163
  // THEN
146
164
  expect(response).toHaveProperty("serialized");
@@ -154,14 +172,14 @@ describe("gateway (devnet)", () => {
154
172
  it("should submit tap request with proper signature", async () => {
155
173
  // GIVEN
156
174
  const { keyPair, partyId } = getOnboardedAccount();
157
- const tapPrepareResponse = await prepareTapRequest({
175
+ const tapPrepareResponse = await prepareTapRequest(mockCurrency, {
158
176
  partyId,
159
177
  amount: 1000,
160
178
  });
161
179
  const tapSignature = keyPair.sign(tapPrepareResponse.hash);
162
180
 
163
181
  // WHEN
164
- const response = await submitTapRequest({
182
+ const response = await submitTapRequest(mockCurrency, {
165
183
  partyId,
166
184
  serialized: tapPrepareResponse.serialized,
167
185
  signature: tapSignature,
@@ -181,7 +199,7 @@ describe("gateway (devnet)", () => {
181
199
  const { partyId } = getOnboardedAccount();
182
200
 
183
201
  // WHEN
184
- const response = await preparePreApprovalTransaction(partyId);
202
+ const response = await preparePreApprovalTransaction(mockCurrency, partyId);
185
203
 
186
204
  // THEN
187
205
  expect(response).toHaveProperty("serialized");
@@ -195,11 +213,12 @@ describe("gateway (devnet)", () => {
195
213
  it("should submit pre-approval transaction with proper signature", async () => {
196
214
  // GIVEN
197
215
  const { keyPair, partyId } = getOnboardedAccount();
198
- const preparedTransaction = await preparePreApprovalTransaction(partyId);
216
+ const preparedTransaction = await preparePreApprovalTransaction(mockCurrency, partyId);
199
217
  const preApprovalSignature = keyPair.sign(preparedTransaction.hash);
200
218
 
201
219
  // WHEN
202
220
  const response = await submitPreApprovalTransaction(
221
+ mockCurrency,
203
222
  partyId,
204
223
  preparedTransaction,
205
224
  preApprovalSignature,