@ledgerhq/coin-internet_computer 1.9.0-nightly.8 → 1.9.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.
Files changed (106) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/CHANGELOG.md +20 -73
  3. package/lib/api/api.d.ts +11 -6
  4. package/lib/api/api.d.ts.map +1 -1
  5. package/lib/api/api.js +64 -84
  6. package/lib/api/api.js.map +1 -1
  7. package/lib/bridge/bridgeHelpers/account.d.ts.map +1 -1
  8. package/lib/bridge/bridgeHelpers/account.js +33 -52
  9. package/lib/bridge/bridgeHelpers/account.js.map +1 -1
  10. package/lib/bridge/bridgeHelpers/addresses.d.ts +6 -0
  11. package/lib/bridge/bridgeHelpers/addresses.d.ts.map +1 -1
  12. package/lib/bridge/bridgeHelpers/addresses.js +29 -1
  13. package/lib/bridge/bridgeHelpers/addresses.js.map +1 -1
  14. package/lib/bridge/bridgeHelpers/icpRosetta/index.d.ts +30 -0
  15. package/lib/bridge/bridgeHelpers/icpRosetta/index.d.ts.map +1 -0
  16. package/lib/bridge/bridgeHelpers/icpRosetta/index.js +88 -0
  17. package/lib/bridge/bridgeHelpers/icpRosetta/index.js.map +1 -0
  18. package/lib/bridge/bridgeHelpers/icpRosetta/types.d.ts +145 -0
  19. package/lib/bridge/bridgeHelpers/icpRosetta/types.d.ts.map +1 -0
  20. package/lib/bridge/bridgeHelpers/icpRosetta/types.js +3 -0
  21. package/lib/bridge/bridgeHelpers/icpRosetta/types.js.map +1 -0
  22. package/lib/bridge/bridgeHelpers/icpRosetta/utils.d.ts +17 -0
  23. package/lib/bridge/bridgeHelpers/icpRosetta/utils.d.ts.map +1 -0
  24. package/lib/bridge/bridgeHelpers/icpRosetta/utils.js +155 -0
  25. package/lib/bridge/bridgeHelpers/icpRosetta/utils.js.map +1 -0
  26. package/lib/bridge/broadcast.d.ts.map +1 -1
  27. package/lib/bridge/broadcast.js +6 -22
  28. package/lib/bridge/broadcast.js.map +1 -1
  29. package/lib/bridge/getTransactionStatus.d.ts.map +1 -1
  30. package/lib/bridge/getTransactionStatus.js +3 -4
  31. package/lib/bridge/getTransactionStatus.js.map +1 -1
  32. package/lib/bridge/prepareTransaction.d.ts.map +1 -1
  33. package/lib/bridge/prepareTransaction.js +1 -2
  34. package/lib/bridge/prepareTransaction.js.map +1 -1
  35. package/lib/bridge/signOperation.d.ts +2 -2
  36. package/lib/bridge/signOperation.d.ts.map +1 -1
  37. package/lib/bridge/signOperation.js +13 -44
  38. package/lib/bridge/signOperation.js.map +1 -1
  39. package/lib/consts.d.ts +0 -2
  40. package/lib/consts.d.ts.map +1 -1
  41. package/lib/consts.js +1 -8
  42. package/lib/consts.js.map +1 -1
  43. package/lib/hw-signMessage.d.ts.map +1 -1
  44. package/lib/hw-signMessage.js +2 -1
  45. package/lib/hw-signMessage.js.map +1 -1
  46. package/lib/types/signer.d.ts +1 -1
  47. package/lib/types/signer.d.ts.map +1 -1
  48. package/lib-es/api/api.d.ts +11 -6
  49. package/lib-es/api/api.d.ts.map +1 -1
  50. package/lib-es/api/api.js +60 -81
  51. package/lib-es/api/api.js.map +1 -1
  52. package/lib-es/bridge/bridgeHelpers/account.d.ts.map +1 -1
  53. package/lib-es/bridge/bridgeHelpers/account.js +33 -52
  54. package/lib-es/bridge/bridgeHelpers/account.js.map +1 -1
  55. package/lib-es/bridge/bridgeHelpers/addresses.d.ts +6 -0
  56. package/lib-es/bridge/bridgeHelpers/addresses.d.ts.map +1 -1
  57. package/lib-es/bridge/bridgeHelpers/addresses.js +23 -0
  58. package/lib-es/bridge/bridgeHelpers/addresses.js.map +1 -1
  59. package/lib-es/bridge/bridgeHelpers/icpRosetta/index.d.ts +30 -0
  60. package/lib-es/bridge/bridgeHelpers/icpRosetta/index.d.ts.map +1 -0
  61. package/lib-es/bridge/bridgeHelpers/icpRosetta/index.js +76 -0
  62. package/lib-es/bridge/bridgeHelpers/icpRosetta/index.js.map +1 -0
  63. package/lib-es/bridge/bridgeHelpers/icpRosetta/types.d.ts +145 -0
  64. package/lib-es/bridge/bridgeHelpers/icpRosetta/types.d.ts.map +1 -0
  65. package/lib-es/bridge/bridgeHelpers/icpRosetta/types.js +2 -0
  66. package/lib-es/bridge/bridgeHelpers/icpRosetta/types.js.map +1 -0
  67. package/lib-es/bridge/bridgeHelpers/icpRosetta/utils.d.ts +17 -0
  68. package/lib-es/bridge/bridgeHelpers/icpRosetta/utils.d.ts.map +1 -0
  69. package/lib-es/bridge/bridgeHelpers/icpRosetta/utils.js +123 -0
  70. package/lib-es/bridge/bridgeHelpers/icpRosetta/utils.js.map +1 -0
  71. package/lib-es/bridge/broadcast.d.ts.map +1 -1
  72. package/lib-es/bridge/broadcast.js +6 -19
  73. package/lib-es/bridge/broadcast.js.map +1 -1
  74. package/lib-es/bridge/getTransactionStatus.d.ts.map +1 -1
  75. package/lib-es/bridge/getTransactionStatus.js +1 -2
  76. package/lib-es/bridge/getTransactionStatus.js.map +1 -1
  77. package/lib-es/bridge/prepareTransaction.d.ts.map +1 -1
  78. package/lib-es/bridge/prepareTransaction.js +1 -2
  79. package/lib-es/bridge/prepareTransaction.js.map +1 -1
  80. package/lib-es/bridge/signOperation.d.ts +2 -2
  81. package/lib-es/bridge/signOperation.d.ts.map +1 -1
  82. package/lib-es/bridge/signOperation.js +13 -41
  83. package/lib-es/bridge/signOperation.js.map +1 -1
  84. package/lib-es/consts.d.ts +0 -2
  85. package/lib-es/consts.d.ts.map +1 -1
  86. package/lib-es/consts.js +0 -3
  87. package/lib-es/consts.js.map +1 -1
  88. package/lib-es/hw-signMessage.d.ts.map +1 -1
  89. package/lib-es/hw-signMessage.js +2 -1
  90. package/lib-es/hw-signMessage.js.map +1 -1
  91. package/lib-es/types/signer.d.ts +1 -1
  92. package/lib-es/types/signer.d.ts.map +1 -1
  93. package/package.json +13 -7
  94. package/src/api/api.ts +71 -126
  95. package/src/bridge/bridgeHelpers/account.ts +43 -70
  96. package/src/bridge/bridgeHelpers/addresses.ts +25 -0
  97. package/src/bridge/bridgeHelpers/icpRosetta/index.ts +154 -0
  98. package/src/bridge/bridgeHelpers/icpRosetta/types.ts +166 -0
  99. package/src/bridge/bridgeHelpers/icpRosetta/utils.ts +151 -0
  100. package/src/bridge/broadcast.ts +6 -31
  101. package/src/bridge/getTransactionStatus.ts +1 -2
  102. package/src/bridge/prepareTransaction.ts +1 -2
  103. package/src/bridge/signOperation.ts +18 -68
  104. package/src/consts.ts +0 -10
  105. package/src/hw-signMessage.ts +6 -1
  106. package/src/types/signer.ts +1 -1
@@ -3,6 +3,4 @@ export declare const ICP_BLK_NAME_ROSETTA = "Internet Computer";
3
3
  export declare const ICP_NET_ID_ROSETTA = "00000000000000020101";
4
4
  export declare const ICP_FEES = 10000;
5
5
  export declare const MAX_MEMO_VALUE: number;
6
- export declare const FETCH_TXNS_LIMIT = 100;
7
- export { MAINNET_GOVERNANCE_CANISTER_ID, MAINNET_LEDGER_CANISTER_ID, MAINNET_INDEX_CANISTER_ID, ICP_NETWORK_URL, } from "@zondax/ledger-live-icp/neurons";
8
6
  //# sourceMappingURL=consts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAGnC,eAAO,MAAM,oBAAoB,sBAAsB,CAAC;AACxD,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AAGzD,eAAO,MAAM,QAAQ,QAAM,CAAC;AAG5B,eAAO,MAAM,cAAc,QAA0B,CAAC;AAGtD,eAAO,MAAM,gBAAgB,MAAM,CAAC;AAEpC,OAAO,EACL,8BAA8B,EAC9B,0BAA0B,EAC1B,yBAAyB,EACzB,eAAe,GAChB,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,iBAAiB,IAAI,CAAC;AAGnC,eAAO,MAAM,oBAAoB,sBAAsB,CAAC;AACxD,eAAO,MAAM,kBAAkB,yBAAyB,CAAC;AAGzD,eAAO,MAAM,QAAQ,QAAM,CAAC;AAG5B,eAAO,MAAM,cAAc,QAA0B,CAAC"}
package/lib-es/consts.js CHANGED
@@ -6,7 +6,4 @@ export const ICP_NET_ID_ROSETTA = "00000000000000020101";
6
6
  export const ICP_FEES = 1e4;
7
7
  // Max Memo value on ICP network
8
8
  export const MAX_MEMO_VALUE = Number.MAX_SAFE_INTEGER;
9
- // API limits
10
- export const FETCH_TXNS_LIMIT = 100;
11
- export { MAINNET_GOVERNANCE_CANISTER_ID, MAINNET_LEDGER_CANISTER_ID, MAINNET_INDEX_CANISTER_ID, ICP_NETWORK_URL, } from "@zondax/ledger-live-icp/neurons";
12
9
  //# sourceMappingURL=consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC,kBAAkB;AAClB,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AACxD,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAEzD,eAAe;AACf,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,CAAC;AAE5B,gCAAgC;AAChC,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC;AAEtD,aAAa;AACb,MAAM,CAAC,MAAM,gBAAgB,GAAG,GAAG,CAAC;AAEpC,OAAO,EACL,8BAA8B,EAC9B,0BAA0B,EAC1B,yBAAyB,EACzB,eAAe,GAChB,MAAM,iCAAiC,CAAC"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AAEnC,kBAAkB;AAClB,MAAM,CAAC,MAAM,oBAAoB,GAAG,mBAAmB,CAAC;AACxD,MAAM,CAAC,MAAM,kBAAkB,GAAG,sBAAsB,CAAC;AAEzD,eAAe;AACf,MAAM,CAAC,MAAM,QAAQ,GAAG,GAAG,CAAC;AAE5B,gCAAgC;AAChC,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC,gBAAgB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"hw-signMessage.d.ts","sourceRoot":"","sources":["../src/hw-signMessage.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAO3D,eAAO,MAAM,WAAW,kBACN,cAAc,SAAS,CAAC,gBACvB,MAAM,WAAW,OAAO,eAAe,UAAU;;;;;;;EAuBjE,CAAC"}
1
+ {"version":3,"file":"hw-signMessage.d.ts","sourceRoot":"","sources":["../src/hw-signMessage.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AAChE,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAO3D,eAAO,MAAM,WAAW,kBACN,cAAc,SAAS,CAAC,gBACvB,MAAM,WAAW,OAAO,eAAe,UAAU;;;;;;;EA2BjE,CAAC"}
@@ -1,5 +1,6 @@
1
1
  import { log } from "@ledgerhq/logs";
2
2
  import { getBufferFromString } from "./common-logic/utils";
3
+ import { ICP_SEND_TXN_TYPE } from "./consts";
3
4
  function bufferToArrayBuffer(buffer) {
4
5
  const sig = buffer.buffer.slice(buffer.byteOffset, buffer.byteOffset + buffer.byteLength);
5
6
  return Buffer.from(sig);
@@ -11,7 +12,7 @@ export const signMessage = (signerContext) => async (deviceId, account, { messag
11
12
  if (typeof message !== "string")
12
13
  throw new Error("Message must be a string");
13
14
  const { r } = await signerContext(deviceId, async (signer) => {
14
- const r = await signer.sign(account.freshAddressPath, getBufferFromString(message));
15
+ const r = await signer.sign(account.freshAddressPath, getBufferFromString(message), ICP_SEND_TXN_TYPE);
15
16
  return { r };
16
17
  });
17
18
  if (!r.signatureRS) {
@@ -1 +1 @@
1
- {"version":3,"file":"hw-signMessage.js","sourceRoot":"","sources":["../src/hw-signMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAK3D,SAAS,mBAAmB,CAAC,MAAc;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC1F,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GACtB,CAAC,aAAuC,EAAE,EAAE,CAC5C,KAAK,EAAE,QAAgB,EAAE,OAAgB,EAAE,EAAE,OAAO,EAAc,EAAE,EAAE;IACpE,GAAG,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC;IAE1C,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACzD,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAE7E,MAAM,EAAE,CAAC,EAAE,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;QACzD,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,OAAO,CAAC,CAAC,CAAC;QACpF,OAAO,EAAE,CAAC,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,GAAG,EAAE;YACH,CAAC,EAAE,EAAE;YACL,CAAC,EAAE,EAAE;YACL,CAAC,EAAE,CAAC;SACL;QACD,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;KAC9D,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"hw-signMessage.js","sourceRoot":"","sources":["../src/hw-signMessage.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,gBAAgB,CAAC;AACrC,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAK7C,SAAS,mBAAmB,CAAC,MAAc;IACzC,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,EAAE,MAAM,CAAC,UAAU,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;IAC1F,OAAO,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GACtB,CAAC,aAAuC,EAAE,EAAE,CAC5C,KAAK,EAAE,QAAgB,EAAE,OAAgB,EAAE,EAAE,OAAO,EAAc,EAAE,EAAE;IACpE,GAAG,CAAC,OAAO,EAAE,2BAA2B,CAAC,CAAC;IAE1C,IAAI,CAAC,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACzD,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAE7E,MAAM,EAAE,CAAC,EAAE,GAAG,MAAM,aAAa,CAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,EAAC,EAAE;QACzD,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,IAAI,CACzB,OAAO,CAAC,gBAAgB,EACxB,mBAAmB,CAAC,OAAO,CAAC,EAC5B,iBAAiB,CAClB,CAAC;QACF,OAAO,EAAE,CAAC,EAAE,CAAC;IACf,CAAC,CAAC,CAAC;IAEH,IAAI,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QACnB,MAAM,KAAK,CAAC,gBAAgB,CAAC,CAAC;IAChC,CAAC;IAED,OAAO;QACL,GAAG,EAAE;YACH,CAAC,EAAE,EAAE;YACL,CAAC,EAAE,EAAE;YACL,CAAC,EAAE,CAAC;SACL;QACD,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;KAC9D,CAAC;AACJ,CAAC,CAAC"}
@@ -16,6 +16,6 @@ export type ICPGetAddrResponse = {
16
16
  export interface ICPSigner {
17
17
  showAddressAndPubKey(path: string): Promise<ICPGetAddrResponse>;
18
18
  getAddressAndPubKey(path: string): Promise<ICPGetAddrResponse>;
19
- sign(path: string, message: Buffer): Promise<ICPSignature>;
19
+ sign(path: string, message: Buffer, txtype: number): Promise<ICPSignature>;
20
20
  }
21
21
  //# sourceMappingURL=signer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/types/signer.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChE,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC/D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC5D"}
1
+ {"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/types/signer.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,YAAY,GAAG;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAChE,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,kBAAkB,CAAC,CAAC;IAC/D,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC5E"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ledgerhq/coin-internet_computer",
3
- "version": "1.9.0-nightly.8",
3
+ "version": "1.9.0",
4
4
  "description": "Ledger Internet Computer integration",
5
5
  "keywords": [
6
6
  "Ledger",
@@ -84,18 +84,24 @@
84
84
  },
85
85
  "license": "Apache-2.0",
86
86
  "dependencies": {
87
- "@zondax/ledger-live-icp": "1.3.2",
87
+ "@dfinity/agent": "^0.21.0",
88
+ "@dfinity/candid": "^0.21.0",
89
+ "@dfinity/principal": "^0.15.6",
90
+ "big-integer": "^1.6.51",
88
91
  "bignumber.js": "^9.1.2",
89
92
  "expect": "^27.4.6",
90
93
  "invariant": "^2.2.2",
91
94
  "lodash": "^4.17.21",
92
95
  "rxjs": "^7.8.1",
93
- "@ledgerhq/coin-framework": "^6.7.0-nightly.8",
94
- "@ledgerhq/cryptoassets": "^13.31.0-nightly.7",
95
- "@ledgerhq/devices": "8.6.2-nightly.0",
96
- "@ledgerhq/errors": "^6.27.0-nightly.0",
96
+ "simple-cbor": "^0.4.1",
97
+ "@ledgerhq/coin-framework": "^6.7.0",
98
+ "@ledgerhq/cryptoassets": "^13.31.0",
99
+ "@ledgerhq/devices": "8.6.1",
100
+ "@ledgerhq/errors": "^6.26.0",
101
+ "@ledgerhq/live-env": "^2.19.0",
102
+ "@ledgerhq/live-network": "^2.0.20",
97
103
  "@ledgerhq/logs": "^6.13.0",
98
- "@ledgerhq/types-live": "^6.87.0-nightly.5"
104
+ "@ledgerhq/types-live": "^6.87.0"
99
105
  },
100
106
  "devDependencies": {
101
107
  "@types/invariant": "^2.2.2",
package/src/api/api.ts CHANGED
@@ -1,147 +1,92 @@
1
1
  import { log } from "@ledgerhq/logs";
2
+ import { AxiosRequestConfig, AxiosResponse } from "axios";
3
+ import { getEnv } from "@ledgerhq/live-env";
4
+ import network from "@ledgerhq/live-network/network";
5
+ import { ICP_BLK_NAME_ROSETTA, ICP_NET_ID_ROSETTA } from "../consts";
2
6
  import {
3
- FETCH_TXNS_LIMIT,
4
- MAINNET_INDEX_CANISTER_ID,
5
- MAINNET_LEDGER_CANISTER_ID,
6
- ICP_NETWORK_URL,
7
- } from "../consts";
7
+ ICPRosettaBlockHeightResponse,
8
+ ICPRosettaGetBalancesResponse,
9
+ ICPRosettaGetTxnsHistoryResponse,
10
+ } from "../bridge/bridgeHelpers/icpRosetta/types";
8
11
 
9
- import {
10
- ledgerIdlFactory,
11
- indexIdlFactory,
12
- getCanisterIdlFunc,
13
- Principal,
14
- encodeCanisterIdlFunc,
15
- decodeCanisterIdlFunc,
16
- GetAccountIdentifierTransactionsResponse,
17
- TransactionWithId,
18
- } from "@zondax/ledger-live-icp";
19
- import BigNumber from "bignumber.js";
20
- import { fromNullable } from "@zondax/ledger-live-icp/utils";
21
- import { getAgent } from "@zondax/ledger-live-icp/agent";
22
- import invariant from "invariant";
23
-
24
- export const fetchBlockHeight = async (): Promise<BigNumber> => {
25
- const canisterId = Principal.fromText(MAINNET_LEDGER_CANISTER_ID);
26
- const queryBlocksRawRequest = {
27
- start: BigInt(0),
28
- length: BigInt(1),
29
- };
30
-
31
- const queryBlocksIdlFunc = getCanisterIdlFunc(ledgerIdlFactory, "query_blocks");
32
- const queryBlocksargs = encodeCanisterIdlFunc(queryBlocksIdlFunc, [queryBlocksRawRequest]);
33
-
34
- const agent = await getAgent(ICP_NETWORK_URL);
35
- const blockHeightRes = await agent.query(canisterId, {
36
- arg: queryBlocksargs,
37
- methodName: "query_blocks",
38
- });
12
+ const getICPURL = (path?: string): string => {
13
+ const baseUrl = getEnv("API_ICP_ENDPOINT");
14
+ if (!baseUrl) throw new Error("API base URL not available");
39
15
 
40
- invariant(blockHeightRes.status === "replied", "[ICP](fetchBlockHeight) Query failed");
41
-
42
- const decodedIdl = decodeCanisterIdlFunc<[{ chain_length: bigint }]>(
43
- queryBlocksIdlFunc,
44
- blockHeightRes.reply.arg,
45
- );
46
- const decoded = fromNullable(decodedIdl);
47
- invariant(decoded, "[ICP](fetchBlockHeight) Decoding failed");
48
-
49
- return BigNumber(decoded.chain_length.toString());
16
+ return `${baseUrl}${path ? path : ""}`;
50
17
  };
51
18
 
52
- export const broadcastTxn = async (
53
- payload: Buffer,
54
- canisterId: string,
55
- type: "call" | "read_state",
56
- ) => {
57
- log("debug", `[ICP] Broadcasting ${type} to ${canisterId}, body: ${payload.toString("hex")}`);
58
- const res = await fetch(`${ICP_NETWORK_URL}/api/v3/canister/${canisterId}/${type}`, {
59
- body: payload,
60
- method: "POST",
61
- headers: {
62
- "Content-Type": "application/cbor",
63
- },
64
- });
65
-
66
- if (res.status === 200) {
67
- return await res.arrayBuffer();
68
- }
69
-
70
- throw new Error(`Failed to broadcast transaction: ${res.text()}`);
71
- };
72
-
73
- export const fetchBalance = async (address: string): Promise<BigNumber> => {
74
- const agent = await getAgent(ICP_NETWORK_URL);
75
- const indexCanister = Principal.fromText(MAINNET_INDEX_CANISTER_ID);
76
- const getBalanceIdlFunc = getCanisterIdlFunc(indexIdlFactory, "get_account_identifier_balance");
77
- const getBalanceArgs = encodeCanisterIdlFunc(getBalanceIdlFunc, [address]);
19
+ const ICPFetchWrapper = async <T>(path: string, body: any) => {
20
+ const url = getICPURL(path);
78
21
 
79
- const balanceRes = await agent.query(indexCanister, {
80
- arg: getBalanceArgs,
81
- methodName: "get_account_identifier_balance",
82
- });
83
-
84
- if (balanceRes.status !== "replied") {
85
- log("debug", `[ICP](fetchBalance) Query failed: ${balanceRes.status}`);
86
- return BigNumber(0);
22
+ // We force data to this way as network func is not using the correct param type. Changing that func will generate errors in other implementations
23
+ const opts: AxiosRequestConfig = {
24
+ method: "POST",
25
+ data: body,
26
+ url,
27
+ };
28
+ const rawResponse = await network(opts);
29
+ if (rawResponse && rawResponse.data && rawResponse.data.details?.error_message) {
30
+ log("error", rawResponse.data.details?.error_message);
87
31
  }
88
32
 
89
- const decodedBalance = decodeCanisterIdlFunc<[bigint]>(getBalanceIdlFunc, balanceRes.reply.arg);
90
- const balance: bigint | undefined = fromNullable(decodedBalance);
91
- if (!balance) {
92
- return BigNumber(0);
93
- }
33
+ // We force data to this way as network func is not using the correct param type. Changing that func will generate errors in other implementations
34
+ const { data } = rawResponse as AxiosResponse<T>;
94
35
 
95
- return BigNumber(balance.toString());
36
+ log("http", url);
37
+ return data;
96
38
  };
97
39
 
98
- export const fetchTxns = async (
99
- address: string,
100
- startBlockHeight: bigint,
101
- stopBlockHeight = BigInt(0),
102
- ): Promise<TransactionWithId[]> => {
103
- if (startBlockHeight <= stopBlockHeight) {
104
- return [];
105
- }
106
-
107
- const agent = await getAgent(ICP_NETWORK_URL);
108
- const canisterId = Principal.fromText(MAINNET_INDEX_CANISTER_ID);
109
- const transactionsRawRequest = {
110
- account_identifier: address,
111
- start: [startBlockHeight],
112
- max_results: BigInt(FETCH_TXNS_LIMIT),
40
+ export const getICPRosettaNetworkIdentifier = () => {
41
+ return {
42
+ network_identifier: {
43
+ blockchain: ICP_BLK_NAME_ROSETTA,
44
+ network: ICP_NET_ID_ROSETTA,
45
+ },
113
46
  };
47
+ };
114
48
 
115
- const getTransactionsIdlFunc = getCanisterIdlFunc(
116
- indexIdlFactory,
117
- "get_account_identifier_transactions",
49
+ export const fetchBlockHeight = async (): Promise<ICPRosettaBlockHeightResponse> => {
50
+ const data = await ICPFetchWrapper<ICPRosettaBlockHeightResponse>(
51
+ "network/status",
52
+ getICPRosettaNetworkIdentifier(),
118
53
  );
119
- const getTransactionsArgs = encodeCanisterIdlFunc(getTransactionsIdlFunc, [
120
- transactionsRawRequest,
121
- ]);
122
-
123
- const transactionsRes = await agent.query(canisterId, {
124
- arg: getTransactionsArgs,
125
- methodName: "get_account_identifier_transactions",
126
- });
54
+ return data;
55
+ };
127
56
 
128
- invariant(transactionsRes.status === "replied", "[ICP](fetchTxns) Query failed");
129
- const decodedTransactions = decodeCanisterIdlFunc<
130
- [{ Ok: GetAccountIdentifierTransactionsResponse }]
131
- >(getTransactionsIdlFunc, transactionsRes.reply.arg);
57
+ export const fetchBalances = async (accountId: string): Promise<ICPRosettaGetBalancesResponse> => {
58
+ const body = {
59
+ ...getICPRosettaNetworkIdentifier(),
60
+ account_identifier: {
61
+ address: accountId,
62
+ metadata: {},
63
+ },
64
+ };
65
+ const data = await ICPFetchWrapper<ICPRosettaGetBalancesResponse>("account/balance", body);
66
+ return data;
67
+ };
132
68
 
133
- const response = fromNullable(decodedTransactions);
134
- invariant(response, "[ICP](fetchTxns) Decoding failed");
69
+ export const fetchTxns = async (accountId: string): Promise<ICPRosettaGetTxnsHistoryResponse> => {
70
+ const body = {
71
+ ...getICPRosettaNetworkIdentifier(),
72
+ account_identifier: {
73
+ address: accountId,
74
+ metadata: {},
75
+ },
76
+ };
77
+ const data = await ICPFetchWrapper<ICPRosettaGetTxnsHistoryResponse>("search/transactions", body);
78
+ return data;
79
+ };
135
80
 
136
- if (response.Ok.transactions.length === 0) {
137
- return [];
138
- }
81
+ export const constructionInvoke = async <TRequest, TResponse>(
82
+ opts: TRequest,
83
+ method: string,
84
+ ): Promise<TResponse> => {
85
+ const body: TRequest = {
86
+ ...opts,
87
+ };
139
88
 
140
- const nextTxns = await fetchTxns(
141
- address,
142
- response.Ok.transactions.at(-1)?.id ?? BigInt(0),
143
- stopBlockHeight,
144
- );
89
+ const data = await ICPFetchWrapper<TResponse>(`construction/${method}`, body);
145
90
 
146
- return [...response.Ok.transactions, ...nextTxns];
91
+ return data;
147
92
  };
@@ -1,19 +1,16 @@
1
1
  import type { GetAccountShape } from "@ledgerhq/coin-framework/bridge/jsHelpers";
2
2
  import { decodeAccountId, encodeAccountId } from "@ledgerhq/coin-framework/account/index";
3
- import { fetchBalance, fetchBlockHeight, fetchTxns } from "../../api";
3
+ import { fetchBalances, fetchBlockHeight, fetchTxns } from "../../api";
4
4
  import flatMap from "lodash/flatMap";
5
- import { Account, OperationType } from "@ledgerhq/types-live";
5
+ import { Account } from "@ledgerhq/types-live";
6
6
  import BigNumber from "bignumber.js";
7
+ import { ICPRosettaGetTxnsHistoryResponse } from "./icpRosetta/types";
7
8
  import { ICP_FEES } from "../../consts";
8
9
  import { encodeOperationId } from "@ledgerhq/coin-framework/operation";
9
10
  import { normalizeEpochTimestamp } from "../../common-logic/utils";
10
11
  import { InternetComputerOperation } from "../../types";
11
12
  import invariant from "invariant";
12
- import {
13
- deriveAddressFromPubkey,
14
- hashTransaction,
15
- TransactionWithId,
16
- } from "@zondax/ledger-live-icp";
13
+ import { deriveAddressFromPubkey } from "./icpRosetta";
17
14
 
18
15
  export const getAccountShape: GetAccountShape = async info => {
19
16
  const { currency, derivationMode, rest = {}, initialAccount } = info;
@@ -35,23 +32,17 @@ export const getAccountShape: GetAccountShape = async info => {
35
32
  // log("debug", `Generation account shape for ${address}`);
36
33
 
37
34
  const blockHeight = await fetchBlockHeight();
38
- const balance = await fetchBalance(address);
39
- const txns = await fetchTxns(
40
- address,
41
- BigInt(blockHeight.toString()),
42
- initialAccount ? BigInt(initialAccount.blockHeight.toString()) : undefined,
43
- );
35
+ const balanceResp = await fetchBalances(address);
36
+ const balance = balanceResp.balances[0];
44
37
 
38
+ const txns = await fetchTxns(address);
45
39
  const result: Partial<Account> = {
46
40
  id: accountId,
47
- balance,
48
- spendableBalance: balance,
49
- operations: flatMap<TransactionWithId, InternetComputerOperation>(
50
- txns,
51
- mapTxToOps(accountId, address),
52
- ),
53
- blockHeight: blockHeight.toNumber(),
54
- operationsCount: (initialAccount?.operations.length ?? 0) + txns.length,
41
+ balance: BigNumber(balance.value),
42
+ spendableBalance: BigNumber(balance.value),
43
+ operations: flatMap(txns.transactions.reverse(), mapTxToOps(accountId, address)),
44
+ blockHeight: blockHeight.current_block_identifier.index,
45
+ operationsCount: txns.transactions.length,
55
46
  xpub: publicKey,
56
47
  };
57
48
 
@@ -68,65 +59,47 @@ function reconciliatePublicKey(publicKey?: string, initialAccount?: Account): st
68
59
  }
69
60
 
70
61
  const mapTxToOps = (accountId: string, address: string, fee = ICP_FEES) => {
71
- return (txInfo: TransactionWithId): InternetComputerOperation[] => {
72
- const { transaction: txn } = txInfo;
62
+ return (
63
+ txInfo: ICPRosettaGetTxnsHistoryResponse["transactions"][0],
64
+ ): InternetComputerOperation[] => {
73
65
  const ops: InternetComputerOperation[] = [];
74
-
75
- if (txn.operation === undefined) {
76
- return [];
77
- }
78
-
79
- if ("Transfer" in txn.operation === undefined) {
80
- return [];
81
- }
82
-
83
- const timeStamp = txn.timestamp[0]?.timestamp_nanos ?? Date.now();
84
- let amount = BigNumber(0);
85
- let fromAccount = "";
86
- let toAccount = "";
87
- let hash = "";
88
- if ("Transfer" in txn.operation) {
89
- amount = BigNumber(txn.operation.Transfer.amount.e8s.toString());
90
- fromAccount = txn.operation.Transfer.from;
91
- toAccount = txn.operation.Transfer.to;
92
- hash = hashTransaction({
93
- from: fromAccount,
94
- to: toAccount,
95
- amount: txn.operation.Transfer.amount.e8s,
96
- fee: txn.operation.Transfer.fee.e8s,
97
- memo: txn.memo,
98
- created_at_time: txn.created_at_time[0]?.timestamp_nanos ?? BigInt(0),
99
- });
100
- }
101
-
102
- const blockHeight = Number(txInfo.id);
103
- const blockHash = "";
104
-
105
- const memo = txInfo.transaction.memo.toString();
66
+ const ownerOperation = txInfo.transaction.operations.find(
67
+ cur => cur.account.address === address,
68
+ );
69
+ const counterOperation = txInfo.transaction.operations.find(
70
+ cur => cur.account.address !== address,
71
+ );
72
+
73
+ if (!ownerOperation || !counterOperation) return ops;
74
+
75
+ const timeStamp = txInfo.transaction.metadata.timestamp;
76
+ const amount = BigNumber(ownerOperation.amount.value);
77
+ const hash = txInfo.transaction.transaction_identifier.hash;
78
+ const fromAccount = amount.isPositive()
79
+ ? counterOperation.account.address
80
+ : ownerOperation.account.address;
81
+ const toAccount = amount.isNegative()
82
+ ? counterOperation.account.address
83
+ : ownerOperation.account.address;
84
+ const memo = txInfo.transaction.metadata.memo.toString();
85
+ const blockHeight = txInfo.transaction.metadata.block_height;
106
86
 
107
87
  const date = new Date(normalizeEpochTimestamp(timeStamp.toString()));
108
88
  const value = amount.abs();
109
89
  const feeToUse = BigNumber(fee);
110
90
 
111
- const isSending = address === fromAccount;
112
- const isReceiving = address === toAccount;
113
-
114
- let type: OperationType;
115
- if (isSending) {
116
- type = "OUT";
117
- } else {
118
- type = "IN";
119
- }
91
+ const isSending = amount.isNegative();
92
+ const isReceiving = amount.isPositive();
120
93
 
121
94
  if (isSending) {
122
95
  ops.push({
123
- id: encodeOperationId(accountId, hash, type),
96
+ id: encodeOperationId(accountId, hash, "OUT"),
124
97
  hash,
125
- type,
98
+ type: "OUT",
126
99
  value: value.plus(feeToUse),
127
100
  fee: feeToUse,
128
101
  blockHeight,
129
- blockHash,
102
+ blockHash: null,
130
103
  accountId,
131
104
  senders: [fromAccount],
132
105
  recipients: [toAccount],
@@ -139,13 +112,13 @@ const mapTxToOps = (accountId: string, address: string, fee = ICP_FEES) => {
139
112
 
140
113
  if (isReceiving) {
141
114
  ops.push({
142
- id: encodeOperationId(accountId, hash, type),
115
+ id: encodeOperationId(accountId, hash, "IN"),
143
116
  hash,
144
- type,
117
+ type: "IN",
145
118
  value,
146
119
  fee: feeToUse,
147
120
  blockHeight,
148
- blockHash,
121
+ blockHash: null,
149
122
  accountId,
150
123
  senders: [fromAccount],
151
124
  recipients: [toAccount],
@@ -1,4 +1,8 @@
1
+ import { log } from "@ledgerhq/logs";
1
2
  import { Account } from "@ledgerhq/types-live";
3
+ import BigNumber from "bignumber.js";
4
+ import { MAX_MEMO_VALUE } from "../../consts";
5
+ import { fetchBalances } from "../../api";
2
6
 
3
7
  export const getAddress = (
4
8
  a: Account,
@@ -6,3 +10,24 @@ export const getAddress = (
6
10
  address: string;
7
11
  derivationPath: string;
8
12
  } => ({ address: a.freshAddress, derivationPath: a.freshAddressPath });
13
+
14
+ export async function validateAddress(address: string): Promise<{ isValid: boolean }> {
15
+ try {
16
+ const res = await fetchBalances(address);
17
+ if (!res.balances) throw Error(res.details?.error_message);
18
+ return { isValid: true };
19
+ } catch (e: any) {
20
+ log("error", e.message ?? "Failed to validate address");
21
+ return { isValid: false };
22
+ }
23
+ }
24
+
25
+ export function validateMemo(memo?: string): { isValid: boolean } {
26
+ const res = BigNumber(memo ?? 0);
27
+
28
+ if (res.isNaN() || res.lt(0) || res.gt(BigNumber(MAX_MEMO_VALUE))) {
29
+ return { isValid: false };
30
+ }
31
+
32
+ return { isValid: true };
33
+ }