@ledgerhq/device-signer-kit-concordium 0.4.0 → 0.5.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 (75) hide show
  1. package/README.md +49 -3
  2. package/lib/cjs/api/SignerConcordium.js.map +1 -1
  3. package/lib/cjs/internal/app-binder/command/SignPltCommand.js +2 -0
  4. package/lib/cjs/internal/app-binder/command/SignPltCommand.js.map +7 -0
  5. package/lib/cjs/internal/app-binder/command/SignPltCommand.test.js +2 -0
  6. package/lib/cjs/internal/app-binder/command/SignPltCommand.test.js.map +7 -0
  7. package/lib/cjs/internal/app-binder/command/utils/ConcordiumApplicationErrors.js +1 -1
  8. package/lib/cjs/internal/app-binder/command/utils/ConcordiumApplicationErrors.js.map +2 -2
  9. package/lib/cjs/internal/app-binder/command/utils/InvalidPltTransactionError.js +2 -0
  10. package/lib/cjs/internal/app-binder/command/utils/InvalidPltTransactionError.js.map +7 -0
  11. package/lib/cjs/internal/app-binder/command/utils/UnsupportedAppVersionError.js +2 -0
  12. package/lib/cjs/internal/app-binder/command/utils/UnsupportedAppVersionError.js.map +7 -0
  13. package/lib/cjs/internal/app-binder/command/utils/UnsupportedTransactionTypeError.js +1 -1
  14. package/lib/cjs/internal/app-binder/command/utils/UnsupportedTransactionTypeError.js.map +2 -2
  15. package/lib/cjs/internal/app-binder/constants.js +1 -1
  16. package/lib/cjs/internal/app-binder/constants.js.map +2 -2
  17. package/lib/cjs/internal/app-binder/task/SendPltTask.js +2 -0
  18. package/lib/cjs/internal/app-binder/task/SendPltTask.js.map +7 -0
  19. package/lib/cjs/internal/app-binder/task/SendPltTask.test.js +2 -0
  20. package/lib/cjs/internal/app-binder/task/SendPltTask.test.js.map +7 -0
  21. package/lib/cjs/internal/app-binder/task/SignTransactionTaskFactory.js +1 -1
  22. package/lib/cjs/internal/app-binder/task/SignTransactionTaskFactory.js.map +3 -3
  23. package/lib/cjs/internal/app-binder/task/SignTransactionTaskFactory.test.js +1 -1
  24. package/lib/cjs/internal/app-binder/task/SignTransactionTaskFactory.test.js.map +3 -3
  25. package/lib/cjs/internal/shared/ConcordiumAppVersions.js +1 -1
  26. package/lib/cjs/internal/shared/ConcordiumAppVersions.js.map +3 -3
  27. package/lib/cjs/package.json +3 -3
  28. package/lib/esm/internal/app-binder/command/SignPltCommand.js +2 -0
  29. package/lib/esm/internal/app-binder/command/SignPltCommand.js.map +7 -0
  30. package/lib/esm/internal/app-binder/command/SignPltCommand.test.js +2 -0
  31. package/lib/esm/internal/app-binder/command/SignPltCommand.test.js.map +7 -0
  32. package/lib/esm/internal/app-binder/command/utils/ConcordiumApplicationErrors.js +1 -1
  33. package/lib/esm/internal/app-binder/command/utils/ConcordiumApplicationErrors.js.map +2 -2
  34. package/lib/esm/internal/app-binder/command/utils/InvalidPltTransactionError.js +2 -0
  35. package/lib/esm/internal/app-binder/command/utils/InvalidPltTransactionError.js.map +7 -0
  36. package/lib/esm/internal/app-binder/command/utils/UnsupportedAppVersionError.js +2 -0
  37. package/lib/esm/internal/app-binder/command/utils/UnsupportedAppVersionError.js.map +7 -0
  38. package/lib/esm/internal/app-binder/command/utils/UnsupportedTransactionTypeError.js +1 -1
  39. package/lib/esm/internal/app-binder/command/utils/UnsupportedTransactionTypeError.js.map +2 -2
  40. package/lib/esm/internal/app-binder/constants.js +1 -1
  41. package/lib/esm/internal/app-binder/constants.js.map +2 -2
  42. package/lib/esm/internal/app-binder/task/SendPltTask.js +2 -0
  43. package/lib/esm/internal/app-binder/task/SendPltTask.js.map +7 -0
  44. package/lib/esm/internal/app-binder/task/SendPltTask.test.js +2 -0
  45. package/lib/esm/internal/app-binder/task/SendPltTask.test.js.map +7 -0
  46. package/lib/esm/internal/app-binder/task/SignTransactionTaskFactory.js +1 -1
  47. package/lib/esm/internal/app-binder/task/SignTransactionTaskFactory.js.map +3 -3
  48. package/lib/esm/internal/app-binder/task/SignTransactionTaskFactory.test.js +1 -1
  49. package/lib/esm/internal/app-binder/task/SignTransactionTaskFactory.test.js.map +3 -3
  50. package/lib/esm/internal/shared/ConcordiumAppVersions.js +1 -1
  51. package/lib/esm/internal/shared/ConcordiumAppVersions.js.map +3 -3
  52. package/lib/esm/package.json +3 -3
  53. package/lib/types/api/SignerConcordium.d.ts +10 -0
  54. package/lib/types/api/SignerConcordium.d.ts.map +1 -1
  55. package/lib/types/internal/app-binder/command/SignPltCommand.d.ts +30 -0
  56. package/lib/types/internal/app-binder/command/SignPltCommand.d.ts.map +1 -0
  57. package/lib/types/internal/app-binder/command/SignPltCommand.test.d.ts +2 -0
  58. package/lib/types/internal/app-binder/command/SignPltCommand.test.d.ts.map +1 -0
  59. package/lib/types/internal/app-binder/command/utils/ConcordiumApplicationErrors.d.ts +14 -0
  60. package/lib/types/internal/app-binder/command/utils/ConcordiumApplicationErrors.d.ts.map +1 -1
  61. package/lib/types/internal/app-binder/command/utils/InvalidPltTransactionError.d.ts +11 -0
  62. package/lib/types/internal/app-binder/command/utils/InvalidPltTransactionError.d.ts.map +1 -0
  63. package/lib/types/internal/app-binder/command/utils/UnsupportedAppVersionError.d.ts +11 -0
  64. package/lib/types/internal/app-binder/command/utils/UnsupportedAppVersionError.d.ts.map +1 -0
  65. package/lib/types/internal/app-binder/constants.d.ts +3 -0
  66. package/lib/types/internal/app-binder/constants.d.ts.map +1 -1
  67. package/lib/types/internal/app-binder/task/SendPltTask.d.ts +35 -0
  68. package/lib/types/internal/app-binder/task/SendPltTask.d.ts.map +1 -0
  69. package/lib/types/internal/app-binder/task/SendPltTask.test.d.ts +2 -0
  70. package/lib/types/internal/app-binder/task/SendPltTask.test.d.ts.map +1 -0
  71. package/lib/types/internal/app-binder/task/SignTransactionTaskFactory.d.ts.map +1 -1
  72. package/lib/types/internal/shared/ConcordiumAppVersions.d.ts +4 -0
  73. package/lib/types/internal/shared/ConcordiumAppVersions.d.ts.map +1 -1
  74. package/lib/types/tsconfig.prod.tsbuildinfo +1 -1
  75. package/package.json +6 -6
package/README.md CHANGED
@@ -4,7 +4,7 @@ This module provides the implementation of the Ledger Concordium signer of the D
4
4
 
5
5
  - Querying the device app configuration and version;
6
6
  - Retrieving the Concordium public key using a given derivation path;
7
- - Signing a Concordium transaction (Transfer and TransferWithMemo);
7
+ - Signing a Concordium transaction (Transfer, TransferWithMemo and TokenUpdate / PLT);
8
8
  - Signing a Concordium credential deployment transaction;
9
9
  - Verifying a Concordium address on-device using a trusted backend;
10
10
 
@@ -150,7 +150,15 @@ type PublicKey = {
150
150
 
151
151
  ### Use Case 3: Sign Transaction
152
152
 
153
- Securely sign a Concordium transaction on Ledger devices. Supports both Transfer and TransferWithMemo transaction types. The transaction type is automatically detected from the serialized payload.
153
+ Securely sign a Concordium transaction on Ledger devices. The transaction kind is detected automatically from the kind byte at offset 60 of the serialized payload.
154
+
155
+ | Kind | Byte | Name |
156
+ | ---------------- | ------------- | ------------------------------------ |
157
+ | Transfer | `3` (`0x03`) | Plain CCD transfer |
158
+ | TransferWithMemo | `22` (`0x16`) | CCD transfer with a memo |
159
+ | TokenUpdate | `27` (`0x1B`) | Protocol Level Token (PLT) operation |
160
+
161
+ Any other kind byte is rejected with `UnsupportedTransactionTypeError` (errorCode `"unsupported_transaction_type"`) before anything is sent to the device.
154
162
 
155
163
  ```typescript
156
164
  const { observable, cancel } = signerConcordium.signTransaction(
@@ -173,7 +181,18 @@ const { observable, cancel } = signerConcordium.signTransaction(
173
181
 
174
182
  - **Required**
175
183
  - **Type:** `Uint8Array`
176
- - The serialized transaction bytes to sign. The transaction type (Transfer or TransferWithMemo) is detected automatically from the type byte at offset 60.
184
+ - The serialized transaction bytes to sign. The transaction kind is detected automatically from the kind byte at offset 60.
185
+ - For **TokenUpdate (PLT)** the expected layout is flat:
186
+
187
+ ```text
188
+ [header:60][kind:1 = 0x1B][token_id_length:1][token_id:1..128][cbor_total_length:4 BE][cbor:N]
189
+ ```
190
+
191
+ This matches the serialization produced by the official Concordium JS SDK: a token id with a word8 length prefix, followed by the operations payload with a word32 length prefix.
192
+
193
+ The signer streams this to the device as one INIT frame carrying everything up to and including `cbor_total_length`, then CONT frames carrying the CBOR payload. Chunking is byte-oriented, so a CBOR field may span a frame boundary.
194
+
195
+ The CBOR payload is passed through **opaque**. The signer does not decode or validate PLT semantics — the operation type, amount, recipient and memo are parsed and displayed by the device app. The signer checks only the framing: `token_id_length` within `1..128`, `cbor_total_length` within `1..512` and consistent with the remaining byte count. A layout failure is reported as `InvalidPltTransactionError` (errorCode `"invalid_plt_transaction"`) with the offending field named in the message, before any APDU is sent.
177
196
 
178
197
  - `maxFee`
179
198
 
@@ -181,6 +200,7 @@ const { observable, cancel } = signerConcordium.signTransaction(
181
200
  - **Type:** `bigint` (µCCD)
182
201
  - The max-fee value to display, as a uint64 in µCCD. Rendered on-device alongside the recipient and amount. The value is **display-only**: it is not part of the canonical signed bytes, so the on-chain transaction hash is unaffected.
183
202
  - Requires Concordium app version **5.6.0 or newer** on the device. On older firmware the value is dropped at the wire boundary and the device falls back to the legacy display. Signing still succeeds; only the on-device display degrades. Callers should always pass a real value; do not gate on detected firmware version.
203
+ - **Ignored for TokenUpdate (PLT) transactions.** The device displays no fee for `INS 0x27`, and the handler rejects both a non-zero P2 and any trailing fee suffix. The value is still validated for range, so pass `0n` unless you have a real figure.
184
204
  - Invalid values (non-bigint, negative, or above uint64 range) are rejected with `InvalidMaxFeeError` (errorCode `"invalid_max_fee"`).
185
205
 
186
206
  - `options`
@@ -196,6 +216,32 @@ const { observable, cancel } = signerConcordium.signTransaction(
196
216
 
197
217
  - `skipOpenApp`: An optional boolean indicating whether to skip opening the Concordium app on the device.
198
218
 
219
+ #### **PLT app-version requirement**
220
+
221
+ PLT signing requires a Concordium app that implements `INS 0x27`, currently **5.7.0 or newer**. The signer checks the running app version before sending anything and rejects an older app with `UnsupportedAppVersionError` (errorCode `"unsupported_app_version"`). This is deliberately distinct from a signing failure, so an integrator can prompt the user to update the app rather than reporting a failed transaction. Transfer and TransferWithMemo are unaffected and keep working on older apps.
222
+
223
+ #### **PLT status words**
224
+
225
+ Device-originated errors on the PLT path are surfaced via `DeviceActionStatus.Error` and discriminated by the `errorCode` string:
226
+
227
+ | `errorCode` | Meaning | Integrator action |
228
+ | ----------- | -------------------------------------------------------------------------- | ----------------------------------------- |
229
+ | `"6b00"` | P2 was not `0x00` | Signer bug; report it |
230
+ | `"6b01"` | INIT sent twice, or CONT before INIT | Signer bug; report it |
231
+ | `"6b02"` | Derivation path invalid or deeper than 8 nodes | Correct the derivation path |
232
+ | `"6b03"` | P1 was neither `0x00` nor `0x01` | Signer bug; report it |
233
+ | `"6b04"` | Kind byte was not `27`, or the header is too short | Correct the serialized transaction |
234
+ | `"6b06"` | Display formatting overflow | Report with the payload that triggered it |
235
+ | `"6b07"` | Device crypto initialisation failed | Retry; escalate if persistent |
236
+ | `"6b0d"` | Empty CONT frame, CBOR overflow, or a CBOR payload the device cannot parse | Check the CBOR against CIS-7 |
237
+ | `"6b0e"` | `cbor_total_length` is `0` or above `512` | Reduce the payload |
238
+ | `"6b0f"` | `token_id_length` outside `1..128` | Correct the token id |
239
+ | `"6b10"` | The CBOR array carries more than one operation | Send one operation per transaction |
240
+
241
+ The device accepts exactly **one** operation per PLT transaction. Batching several into the outer CBOR array is refused with `"6b10"`, so that the user cannot approve a screen showing only part of what they are signing.
242
+
243
+ The generic codes apply here too: `"6985"` user rejected, `"5515"` locked device, `"6d00"` the app does not implement `INS 0x27`.
244
+
199
245
  #### **Returns**
200
246
 
201
247
  - `observable` Emits DeviceActionState updates, including the following details:
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/api/SignerConcordium.ts"],
4
- "sourcesContent": ["import { type AccountOwnershipNetwork } from \"@ledgerhq/context-module\";\n\nimport { type GetAppConfigDAReturnType } from \"@api/app-binder/GetAppConfigDeviceActionTypes\";\nimport { type GetPublicKeyDAReturnType } from \"@api/app-binder/GetPublicKeyDeviceActionTypes\";\nimport { type SignCredentialDeploymentTransactionDAReturnType } from \"@api/app-binder/SignCredentialDeploymentTransactionDeviceActionTypes\";\nimport { type SignTransactionDAReturnType } from \"@api/app-binder/SignTransactionDeviceActionTypes\";\nimport { type VerifyAddressDAReturnType } from \"@api/app-binder/VerifyAddressDeviceActionTypes\";\nimport { type PublicKeyOptions } from \"@api/model/PublicKeyOptions\";\nimport { type TransactionOptions } from \"@api/model/TransactionOptions\";\nimport { type VerifyAddressOptions } from \"@api/model/VerifyAddressOptions\";\n\nexport interface SignerConcordium {\n getAppConfiguration: () => GetAppConfigDAReturnType;\n\n getPublicKey: (\n derivationPath: string,\n options?: PublicKeyOptions,\n ) => GetPublicKeyDAReturnType;\n\n signTransaction: (\n derivationPath: string,\n transaction: Uint8Array,\n maxFee: bigint,\n options?: TransactionOptions,\n ) => SignTransactionDAReturnType;\n\n signCredentialDeploymentTransaction: (\n derivationPath: string,\n transaction: Uint8Array,\n options?: TransactionOptions,\n ) => SignCredentialDeploymentTransactionDAReturnType;\n\n verifyAddress: (\n derivationPath: string,\n address: string,\n network: AccountOwnershipNetwork,\n options?: VerifyAddressOptions,\n ) => VerifyAddressDAReturnType;\n}\n"],
4
+ "sourcesContent": ["import { type AccountOwnershipNetwork } from \"@ledgerhq/context-module\";\n\nimport { type GetAppConfigDAReturnType } from \"@api/app-binder/GetAppConfigDeviceActionTypes\";\nimport { type GetPublicKeyDAReturnType } from \"@api/app-binder/GetPublicKeyDeviceActionTypes\";\nimport { type SignCredentialDeploymentTransactionDAReturnType } from \"@api/app-binder/SignCredentialDeploymentTransactionDeviceActionTypes\";\nimport { type SignTransactionDAReturnType } from \"@api/app-binder/SignTransactionDeviceActionTypes\";\nimport { type VerifyAddressDAReturnType } from \"@api/app-binder/VerifyAddressDeviceActionTypes\";\nimport { type PublicKeyOptions } from \"@api/model/PublicKeyOptions\";\nimport { type TransactionOptions } from \"@api/model/TransactionOptions\";\nimport { type VerifyAddressOptions } from \"@api/model/VerifyAddressOptions\";\n\nexport interface SignerConcordium {\n getAppConfiguration: () => GetAppConfigDAReturnType;\n\n getPublicKey: (\n derivationPath: string,\n options?: PublicKeyOptions,\n ) => GetPublicKeyDAReturnType;\n\n /**\n * Sign a serialized Concordium account transaction.\n *\n * Supported kinds are Transfer (3), TransferWithMemo (22) and\n * TokenUpdate (27, PLT).\n *\n * @param maxFee - Maximum fee in \u00B5CCD, shown on the device review screens.\n * Used for every supported kind, PLT included. The device does not hash it,\n * so it affects the display only.\n */\n signTransaction: (\n derivationPath: string,\n transaction: Uint8Array,\n maxFee: bigint,\n options?: TransactionOptions,\n ) => SignTransactionDAReturnType;\n\n signCredentialDeploymentTransaction: (\n derivationPath: string,\n transaction: Uint8Array,\n options?: TransactionOptions,\n ) => SignCredentialDeploymentTransactionDAReturnType;\n\n verifyAddress: (\n derivationPath: string,\n address: string,\n network: AccountOwnershipNetwork,\n options?: VerifyAddressOptions,\n ) => VerifyAddressDAReturnType;\n}\n"],
5
5
  "mappings": "+WAAA,IAAAA,EAAA,kBAAAC,EAAAD",
6
6
  "names": ["SignerConcordium_exports", "__toCommonJS"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var s=Object.defineProperty;var l=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var g=Object.prototype.hasOwnProperty;var C=(e,r)=>{for(var o in r)s(e,o,{get:r[o],enumerable:!0})},y=(e,r,o,a)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of u(r))!g.call(e,n)&&n!==o&&s(e,n,{get:()=>r[n],enumerable:!(a=l(r,n))||a.enumerable});return e};var c=e=>y(s({},"__esModule",{value:!0}),e);var A={};C(A,{SignPltCommand:()=>S});module.exports=c(A);var t=require("@ledgerhq/device-management-kit"),p=require("@ledgerhq/signer-utils"),i=require("purify-ts"),m=require("../../app-binder/command/utils/ConcordiumApplicationErrors"),d=require("../../app-binder/constants");class S{name="SignPlt";args;errorHelper=new p.CommandErrorHelper(m.CONCORDIUM_APP_ERRORS,m.ConcordiumAppCommandErrorFactory);constructor(r){this.args=r}getApdu(){const r=new t.ApduBuilder({cla:d.LEDGER_CLA,ins:d.INS.SIGN_PLT,p1:this.args.p1,p2:this.args.p2});return r.addBufferToData(this.args.data),r.build()}parseResponse(r){return i.Maybe.fromNullable(this.errorHelper.getError(r)).orDefaultLazy(()=>{const o=new t.ApduParser(r),a=o.getUnparsedRemainingLength(),n=o.extractFieldByLength(a);return(0,t.CommandResultFactory)({data:n})})}}0&&(module.exports={SignPltCommand});
2
+ //# sourceMappingURL=SignPltCommand.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/command/SignPltCommand.ts"],
4
+ "sourcesContent": ["import {\n type Apdu,\n ApduBuilder,\n ApduParser,\n type ApduResponse,\n type Command,\n type CommandResult,\n CommandResultFactory,\n} from \"@ledgerhq/device-management-kit\";\nimport { CommandErrorHelper } from \"@ledgerhq/signer-utils\";\nimport { Maybe } from \"purify-ts\";\n\nimport { type Signature } from \"@api/model/Signature\";\nimport {\n CONCORDIUM_APP_ERRORS,\n ConcordiumAppCommandErrorFactory,\n type ConcordiumErrorCodes,\n} from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { INS, LEDGER_CLA } from \"@internal/app-binder/constants\";\n\nexport type SignPltCommandArgs = {\n readonly p1: number;\n readonly p2: number;\n readonly data: Uint8Array;\n};\n\n/**\n * Empty for the INIT frame and every intermediate CONT frame; the 64-byte\n * Ed25519 signature on the final CONT frame.\n */\nexport type SignPltCommandResponse = Signature;\n\n/**\n * PLT (Protocol Level Token) signing, INS 0x27.\n *\n * P2 selects fee display on the INIT frame: `0x00` sends no fee, `0x01` appends\n * an 8-byte big-endian \u00B5CCD suffix and the device renders a \"Max fees\" step.\n * A CONT frame must use `0x00`, and returns 0x6B00 otherwise, so the caller\n * chooses P2 per frame rather than reusing one value for the whole flow.\n */\nexport class SignPltCommand\n implements\n Command<SignPltCommandResponse, SignPltCommandArgs, ConcordiumErrorCodes>\n{\n readonly name = \"SignPlt\";\n\n private readonly args: SignPltCommandArgs;\n\n private readonly errorHelper = new CommandErrorHelper<\n SignPltCommandResponse,\n ConcordiumErrorCodes\n >(CONCORDIUM_APP_ERRORS, ConcordiumAppCommandErrorFactory);\n\n constructor(args: SignPltCommandArgs) {\n this.args = args;\n }\n\n getApdu(): Apdu {\n const apduBuilder = new ApduBuilder({\n cla: LEDGER_CLA,\n ins: INS.SIGN_PLT,\n p1: this.args.p1,\n p2: this.args.p2,\n });\n\n apduBuilder.addBufferToData(this.args.data);\n\n return apduBuilder.build();\n }\n\n parseResponse(\n apduResponse: ApduResponse,\n ): CommandResult<SignPltCommandResponse, ConcordiumErrorCodes> {\n return Maybe.fromNullable(\n this.errorHelper.getError(apduResponse),\n ).orDefaultLazy(() => {\n const apduParser = new ApduParser(apduResponse);\n const remaining = apduParser.getUnparsedRemainingLength();\n const signature = apduParser.extractFieldByLength(remaining);\n\n return CommandResultFactory({\n data: signature as Signature,\n });\n });\n }\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,oBAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAQO,2CACPC,EAAmC,kCACnCC,EAAsB,qBAGtBC,EAIO,0EACPC,EAAgC,0CAsBzB,MAAMN,CAGb,CACW,KAAO,UAEC,KAEA,YAAc,IAAI,qBAGjC,wBAAuB,kCAAgC,EAEzD,YAAYO,EAA0B,CACpC,KAAK,KAAOA,CACd,CAEA,SAAgB,CACd,MAAMC,EAAc,IAAI,cAAY,CAClC,IAAK,aACL,IAAK,MAAI,SACT,GAAI,KAAK,KAAK,GACd,GAAI,KAAK,KAAK,EAChB,CAAC,EAED,OAAAA,EAAY,gBAAgB,KAAK,KAAK,IAAI,EAEnCA,EAAY,MAAM,CAC3B,CAEA,cACEC,EAC6D,CAC7D,OAAO,QAAM,aACX,KAAK,YAAY,SAASA,CAAY,CACxC,EAAE,cAAc,IAAM,CACpB,MAAMC,EAAa,IAAI,aAAWD,CAAY,EACxCE,EAAYD,EAAW,2BAA2B,EAClDE,EAAYF,EAAW,qBAAqBC,CAAS,EAE3D,SAAO,wBAAqB,CAC1B,KAAMC,CACR,CAAC,CACH,CAAC,CACH,CACF",
6
+ "names": ["SignPltCommand_exports", "__export", "SignPltCommand", "__toCommonJS", "import_device_management_kit", "import_signer_utils", "import_purify_ts", "import_ConcordiumApplicationErrors", "import_constants", "args", "apduBuilder", "apduResponse", "apduParser", "remaining", "signature"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var o=require("@ledgerhq/device-management-kit"),a=require("../../app-binder/command/SignPltCommand"),n=require("../../app-binder/command/utils/ConcordiumApplicationErrors"),e=require("../../app-binder/constants");const i=new Uint8Array([144,0]);function c(r,t=new Uint8Array){return new o.ApduResponse({statusCode:r,data:t})}describe("SignPltCommand",()=>{describe("getApdu",()=>{it("should build the INIT frame with INS=0x27, P1=0x00 and P2=0x00",()=>{const t=new a.SignPltCommand({p1:e.P1.PLT_INIT,p2:e.P2.NONE,data:new Uint8Array(80).fill(1)}).getApdu().getRawApdu();expect(t[0]).toBe(e.LEDGER_CLA),expect(t[1]).toBe(e.INS.SIGN_PLT),expect(t[2]).toBe(e.P1.PLT_INIT),expect(t[3]).toBe(e.P2.NONE),expect(t[4]).toBe(80)}),it("should build the CONT frame with P1=0x01",()=>{const t=new a.SignPltCommand({p1:e.P1.PLT_CONT,p2:e.P2.NONE,data:new Uint8Array(9).fill(204)}).getApdu().getRawApdu();expect(t[1]).toBe(e.INS.SIGN_PLT),expect(t[2]).toBe(e.P1.PLT_CONT),expect(t[3]).toBe(e.P2.NONE)}),it("should forward P2 to the APDU rather than pinning it",()=>{const r=t=>new a.SignPltCommand({p1:e.P1.PLT_INIT,p2:t,data:new Uint8Array(4)}).getApdu().getRawApdu()[3];expect(r(e.P2.NONE)).toBe(0),expect(r(e.P2.FEE_DISPLAY)).toBe(1)}),it("should include the data in the APDU payload",()=>{const r=new Uint8Array([222,173,190,239]),d=new a.SignPltCommand({p1:e.P1.PLT_CONT,p2:e.P2.NONE,data:r}).getApdu().getRawApdu();expect(d.slice(5)).toStrictEqual(r)})}),describe("parseResponse",()=>{it("should return an empty signature for INIT and intermediate CONT frames",()=>{const t=new a.SignPltCommand({p1:e.P1.PLT_INIT,p2:e.P2.NONE,data:new Uint8Array(4)}).parseResponse(c(i));expect((0,o.isSuccessCommandResult)(t)).toBe(!0),(0,o.isSuccessCommandResult)(t)&&expect(t.data).toStrictEqual(new Uint8Array)}),it("should extract the 64-byte signature from the final CONT frame",()=>{const r=new a.SignPltCommand({p1:e.P1.PLT_CONT,p2:e.P2.NONE,data:new Uint8Array(9)}),t=new Uint8Array(64).fill(171),d=r.parseResponse(c(i,t));expect((0,o.isSuccessCommandResult)(d)).toBe(!0),(0,o.isSuccessCommandResult)(d)&&expect(d.data).toStrictEqual(t)}),it.each([[[105,133],n.ConcordiumErrorCodes.USER_REJECTED],[[85,21],n.ConcordiumErrorCodes.LOCKED_DEVICE],[[106,128],n.ConcordiumErrorCodes.DATA_INVALID],[[107,0],n.ConcordiumErrorCodes.WRONG_P1_P2],[[107,1],n.ConcordiumErrorCodes.INVALID_STATE],[[107,2],n.ConcordiumErrorCodes.INVALID_PATH],[[107,3],n.ConcordiumErrorCodes.INVALID_PARAM],[[107,4],n.ConcordiumErrorCodes.INVALID_TRANSACTION],[[107,6],n.ConcordiumErrorCodes.BUFFER_OVERFLOW],[[107,7],n.ConcordiumErrorCodes.FAILED_CX_OPERATION],[[107,13],n.ConcordiumErrorCodes.PLT_CBOR_ERROR],[[107,14],n.ConcordiumErrorCodes.PLT_BUFFER_ERROR],[[107,15],n.ConcordiumErrorCodes.PLT_DATA_ERROR],[[107,16],n.ConcordiumErrorCodes.PLT_MULTI_OP]])("should map status word %s to a typed error",(r,t)=>{const p=new a.SignPltCommand({p1:e.P1.PLT_CONT,p2:e.P2.NONE,data:new Uint8Array(4)}).parseResponse(c(new Uint8Array(r)));expect((0,o.isSuccessCommandResult)(p)).toBe(!1),(0,o.isSuccessCommandResult)(p)||expect(p.error.errorCode).toStrictEqual(t)})})});
2
+ //# sourceMappingURL=SignPltCommand.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/command/SignPltCommand.test.ts"],
4
+ "sourcesContent": ["import {\n ApduResponse,\n isSuccessCommandResult,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { SignPltCommand } from \"@internal/app-binder/command/SignPltCommand\";\nimport {\n type ConcordiumAppCommandError,\n ConcordiumErrorCodes,\n} from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { INS, LEDGER_CLA, P1, P2 } from \"@internal/app-binder/constants\";\n\nconst SUCCESS = new Uint8Array([0x90, 0x00]);\n\nfunction buildResponse(statusCode: Uint8Array, data = new Uint8Array()) {\n return new ApduResponse({ statusCode, data });\n}\n\ndescribe(\"SignPltCommand\", () => {\n describe(\"getApdu\", () => {\n it(\"should build the INIT frame with INS=0x27, P1=0x00 and P2=0x00\", () => {\n const command = new SignPltCommand({\n p1: P1.PLT_INIT,\n p2: P2.NONE,\n data: new Uint8Array(80).fill(0x01),\n });\n\n const raw = command.getApdu().getRawApdu();\n\n expect(raw[0]).toBe(LEDGER_CLA);\n expect(raw[1]).toBe(INS.SIGN_PLT);\n expect(raw[2]).toBe(P1.PLT_INIT);\n expect(raw[3]).toBe(P2.NONE);\n expect(raw[4]).toBe(80);\n });\n\n it(\"should build the CONT frame with P1=0x01\", () => {\n const command = new SignPltCommand({\n p1: P1.PLT_CONT,\n p2: P2.NONE,\n data: new Uint8Array(9).fill(0xcc),\n });\n\n const raw = command.getApdu().getRawApdu();\n\n expect(raw[1]).toBe(INS.SIGN_PLT);\n expect(raw[2]).toBe(P1.PLT_CONT);\n expect(raw[3]).toBe(P2.NONE);\n });\n\n // The command forwards P2 verbatim; choosing it per frame is the caller's\n // job, because the device accepts fee display only on INIT.\n it(\"should forward P2 to the APDU rather than pinning it\", () => {\n const build = (p2: number) =>\n new SignPltCommand({ p1: P1.PLT_INIT, p2, data: new Uint8Array(4) })\n .getApdu()\n .getRawApdu()[3];\n\n expect(build(P2.NONE)).toBe(0x00);\n expect(build(P2.FEE_DISPLAY)).toBe(0x01);\n });\n\n it(\"should include the data in the APDU payload\", () => {\n const data = new Uint8Array([0xde, 0xad, 0xbe, 0xef]);\n const command = new SignPltCommand({\n p1: P1.PLT_CONT,\n p2: P2.NONE,\n data,\n });\n\n const raw = command.getApdu().getRawApdu();\n\n expect(raw.slice(5)).toStrictEqual(data);\n });\n });\n\n describe(\"parseResponse\", () => {\n it(\"should return an empty signature for INIT and intermediate CONT frames\", () => {\n const command = new SignPltCommand({\n p1: P1.PLT_INIT,\n p2: P2.NONE,\n data: new Uint8Array(4),\n });\n\n const result = command.parseResponse(buildResponse(SUCCESS));\n\n expect(isSuccessCommandResult(result)).toBe(true);\n if (isSuccessCommandResult(result)) {\n expect(result.data).toStrictEqual(new Uint8Array());\n }\n });\n\n it(\"should extract the 64-byte signature from the final CONT frame\", () => {\n const command = new SignPltCommand({\n p1: P1.PLT_CONT,\n p2: P2.NONE,\n data: new Uint8Array(9),\n });\n const signature = new Uint8Array(64).fill(0xab);\n\n const result = command.parseResponse(buildResponse(SUCCESS, signature));\n\n expect(isSuccessCommandResult(result)).toBe(true);\n if (isSuccessCommandResult(result)) {\n expect(result.data).toStrictEqual(signature);\n }\n });\n\n it.each([\n [[0x69, 0x85], ConcordiumErrorCodes.USER_REJECTED],\n [[0x55, 0x15], ConcordiumErrorCodes.LOCKED_DEVICE],\n [[0x6a, 0x80], ConcordiumErrorCodes.DATA_INVALID],\n [[0x6b, 0x00], ConcordiumErrorCodes.WRONG_P1_P2],\n [[0x6b, 0x01], ConcordiumErrorCodes.INVALID_STATE],\n [[0x6b, 0x02], ConcordiumErrorCodes.INVALID_PATH],\n [[0x6b, 0x03], ConcordiumErrorCodes.INVALID_PARAM],\n [[0x6b, 0x04], ConcordiumErrorCodes.INVALID_TRANSACTION],\n [[0x6b, 0x06], ConcordiumErrorCodes.BUFFER_OVERFLOW],\n [[0x6b, 0x07], ConcordiumErrorCodes.FAILED_CX_OPERATION],\n [[0x6b, 0x0d], ConcordiumErrorCodes.PLT_CBOR_ERROR],\n [[0x6b, 0x0e], ConcordiumErrorCodes.PLT_BUFFER_ERROR],\n [[0x6b, 0x0f], ConcordiumErrorCodes.PLT_DATA_ERROR],\n [[0x6b, 0x10], ConcordiumErrorCodes.PLT_MULTI_OP],\n ])(\"should map status word %s to a typed error\", (statusCode, expected) => {\n const command = new SignPltCommand({\n p1: P1.PLT_CONT,\n p2: P2.NONE,\n data: new Uint8Array(4),\n });\n\n const result = command.parseResponse(\n buildResponse(new Uint8Array(statusCode)),\n );\n\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(\n (result.error as ConcordiumAppCommandError).errorCode,\n ).toStrictEqual(expected);\n }\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["import_device_management_kit", "import_SignPltCommand", "import_ConcordiumApplicationErrors", "import_constants", "SUCCESS", "buildResponse", "statusCode", "data", "raw", "build", "p2", "result", "command", "signature", "expected"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var _=Object.defineProperty;var p=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var o=Object.prototype.hasOwnProperty;var A=(r,e)=>{for(var t in e)_(r,t,{get:e[t],enumerable:!0})},R=(r,e,t,m)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of i(e))!o.call(r,s)&&s!==t&&_(r,s,{get:()=>e[s],enumerable:!(m=p(e,s))||m.enumerable});return r};var T=r=>R(_({},"__esModule",{value:!0}),r);var g={};A(g,{CONCORDIUM_APP_ERRORS:()=>c,ConcordiumAppCommandError:()=>E,ConcordiumAppCommandErrorFactory:()=>D,ConcordiumErrorCodes:()=>d});module.exports=T(g);var n=require("@ledgerhq/device-management-kit"),d=(a=>(a.USER_REJECTED="6985",a.LOCKED_DEVICE="5515",a.DATA_INVALID="6a80",a.INS_NOT_SUPPORTED="6d00",a.CLA_NOT_SUPPORTED="6e00",a.UNKNOWN_ERROR="6f00",a.TRUSTED_NAME_MISMATCH="6b0c",a.UNSUPPORTED_TRANSACTION_TYPE="unsupported_transaction_type",a.TRUSTED_METADATA_SERVICE_ERROR="trusted_metadata_service_error",a.ADDRESS_VERIFICATION_FAILED="address_verification_failed",a.INVALID_MAX_FEE="invalid_max_fee",a))(d||{});const c={6985:{message:"User rejected"},5515:{message:"Locked device"},"6a80":{message:"Data invalid"},"6d00":{message:"INS not supported"},"6e00":{message:"CLA not supported"},"6f00":{message:"Unknown error"},"6b0c":{message:"Trusted name mismatch"},unsupported_transaction_type:{message:"Unsupported transaction type"},trusted_metadata_service_error:{message:"Trusted metadata service error"},address_verification_failed:{message:"Address verification failed"},invalid_max_fee:{message:"Invalid maxFee value"}};class E extends n.DeviceExchangeError{constructor(e){super({tag:"ConcordiumAppCommandError",...e})}}const D=r=>new E(r);0&&(module.exports={CONCORDIUM_APP_ERRORS,ConcordiumAppCommandError,ConcordiumAppCommandErrorFactory,ConcordiumErrorCodes});
1
+ "use strict";var p=Object.defineProperty;var m=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var P=Object.prototype.hasOwnProperty;var i=(s,a)=>{for(var _ in a)p(s,_,{get:a[_],enumerable:!0})},g=(s,a,_,n)=>{if(a&&typeof a=="object"||typeof a=="function")for(let t of I(a))!P.call(s,t)&&t!==_&&p(s,t,{get:()=>a[t],enumerable:!(n=m(a,t))||n.enumerable});return s};var O=s=>g(p({},"__esModule",{value:!0}),s);var L={};i(L,{CONCORDIUM_APP_ERRORS:()=>N,ConcordiumAppCommandError:()=>R,ConcordiumAppCommandErrorFactory:()=>D,ConcordiumErrorCodes:()=>T});module.exports=O(L);var A=require("@ledgerhq/device-management-kit"),T=(e=>(e.USER_REJECTED="6985",e.LOCKED_DEVICE="5515",e.DATA_INVALID="6a80",e.INS_NOT_SUPPORTED="6d00",e.CLA_NOT_SUPPORTED="6e00",e.UNKNOWN_ERROR="6f00",e.WRONG_P1_P2="6b00",e.INVALID_STATE="6b01",e.INVALID_PATH="6b02",e.INVALID_PARAM="6b03",e.INVALID_TRANSACTION="6b04",e.BUFFER_OVERFLOW="6b06",e.FAILED_CX_OPERATION="6b07",e.TRUSTED_NAME_MISMATCH="6b0c",e.PLT_CBOR_ERROR="6b0d",e.PLT_BUFFER_ERROR="6b0e",e.PLT_DATA_ERROR="6b0f",e.PLT_MULTI_OP="6b10",e.PLT_UNSUPPORTED_DECIMALS="6b11",e.UNSUPPORTED_TRANSACTION_TYPE="unsupported_transaction_type",e.UNSUPPORTED_APP_VERSION="unsupported_app_version",e.INVALID_PLT_TRANSACTION="invalid_plt_transaction",e.TRUSTED_METADATA_SERVICE_ERROR="trusted_metadata_service_error",e.ADDRESS_VERIFICATION_FAILED="address_verification_failed",e.INVALID_MAX_FEE="invalid_max_fee",e))(T||{});const N={6985:{message:"User rejected"},5515:{message:"Locked device"},"6a80":{message:"Data invalid"},"6d00":{message:"INS not supported"},"6e00":{message:"CLA not supported"},"6f00":{message:"Unknown error"},"6b00":{message:"Wrong P1 or P2"},"6b01":{message:"Invalid state"},"6b02":{message:"Invalid derivation path"},"6b03":{message:"Invalid parameter"},"6b04":{message:"Invalid transaction"},"6b06":{message:"Buffer overflow"},"6b07":{message:"Failed crypto operation"},"6b0c":{message:"Trusted name mismatch"},"6b0d":{message:"PLT CBOR error"},"6b0e":{message:"PLT buffer error"},"6b0f":{message:"PLT data error"},"6b10":{message:"PLT payload has more than one operation"},"6b11":{message:"PLT amount has more than the 18 decimal places the app can display"},unsupported_transaction_type:{message:"Unsupported transaction type"},unsupported_app_version:{message:"Unsupported app version"},invalid_plt_transaction:{message:"Invalid PLT transaction"},trusted_metadata_service_error:{message:"Trusted metadata service error"},address_verification_failed:{message:"Address verification failed"},invalid_max_fee:{message:"Invalid maxFee value"}};class R extends A.DeviceExchangeError{constructor(a){super({tag:"ConcordiumAppCommandError",...a})}}const D=s=>new R(s);0&&(module.exports={CONCORDIUM_APP_ERRORS,ConcordiumAppCommandError,ConcordiumAppCommandErrorFactory,ConcordiumErrorCodes});
2
2
  //# sourceMappingURL=ConcordiumApplicationErrors.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/internal/app-binder/command/utils/ConcordiumApplicationErrors.ts"],
4
- "sourcesContent": ["import {\n type CommandErrorArgs,\n type CommandErrors,\n DeviceExchangeError,\n} from \"@ledgerhq/device-management-kit\";\n\nexport enum ConcordiumErrorCodes {\n USER_REJECTED = \"6985\",\n LOCKED_DEVICE = \"5515\",\n DATA_INVALID = \"6a80\",\n INS_NOT_SUPPORTED = \"6d00\",\n CLA_NOT_SUPPORTED = \"6e00\",\n UNKNOWN_ERROR = \"6f00\",\n TRUSTED_NAME_MISMATCH = \"6b0c\",\n UNSUPPORTED_TRANSACTION_TYPE = \"unsupported_transaction_type\",\n TRUSTED_METADATA_SERVICE_ERROR = \"trusted_metadata_service_error\",\n ADDRESS_VERIFICATION_FAILED = \"address_verification_failed\",\n INVALID_MAX_FEE = \"invalid_max_fee\",\n}\n\nexport const CONCORDIUM_APP_ERRORS: CommandErrors<ConcordiumErrorCodes> = {\n \"6985\": { message: \"User rejected\" },\n \"5515\": { message: \"Locked device\" },\n \"6a80\": { message: \"Data invalid\" },\n \"6d00\": { message: \"INS not supported\" },\n \"6e00\": { message: \"CLA not supported\" },\n \"6f00\": { message: \"Unknown error\" },\n \"6b0c\": { message: \"Trusted name mismatch\" },\n unsupported_transaction_type: { message: \"Unsupported transaction type\" },\n trusted_metadata_service_error: {\n message: \"Trusted metadata service error\",\n },\n address_verification_failed: {\n message: \"Address verification failed\",\n },\n invalid_max_fee: {\n message: \"Invalid maxFee value\",\n },\n};\n\nexport class ConcordiumAppCommandError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(args: CommandErrorArgs<ConcordiumErrorCodes>) {\n super({ tag: \"ConcordiumAppCommandError\", ...args });\n }\n}\n\nexport const ConcordiumAppCommandErrorFactory = (\n args: CommandErrorArgs<ConcordiumErrorCodes>,\n) => new ConcordiumAppCommandError(args);\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,2BAAAE,EAAA,8BAAAC,EAAA,qCAAAC,EAAA,yBAAAC,IAAA,eAAAC,EAAAN,GAAA,IAAAO,EAIO,2CAEKF,OACVA,EAAA,cAAgB,OAChBA,EAAA,cAAgB,OAChBA,EAAA,aAAe,OACfA,EAAA,kBAAoB,OACpBA,EAAA,kBAAoB,OACpBA,EAAA,cAAgB,OAChBA,EAAA,sBAAwB,OACxBA,EAAA,6BAA+B,+BAC/BA,EAAA,+BAAiC,iCACjCA,EAAA,4BAA8B,8BAC9BA,EAAA,gBAAkB,kBAXRA,OAAA,IAcL,MAAMH,EAA6D,CACxE,KAAQ,CAAE,QAAS,eAAgB,EACnC,KAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,cAAe,EAClC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,uBAAwB,EAC3C,6BAA8B,CAAE,QAAS,8BAA+B,EACxE,+BAAgC,CAC9B,QAAS,gCACX,EACA,4BAA6B,CAC3B,QAAS,6BACX,EACA,gBAAiB,CACf,QAAS,sBACX,CACF,EAEO,MAAMC,UAAkC,qBAA0C,CACvF,YAAYK,EAA8C,CACxD,MAAM,CAAE,IAAK,4BAA6B,GAAGA,CAAK,CAAC,CACrD,CACF,CAEO,MAAMJ,EACXI,GACG,IAAIL,EAA0BK,CAAI",
4
+ "sourcesContent": ["import {\n type CommandErrorArgs,\n type CommandErrors,\n DeviceExchangeError,\n} from \"@ledgerhq/device-management-kit\";\n\nexport enum ConcordiumErrorCodes {\n USER_REJECTED = \"6985\",\n LOCKED_DEVICE = \"5515\",\n DATA_INVALID = \"6a80\",\n INS_NOT_SUPPORTED = \"6d00\",\n CLA_NOT_SUPPORTED = \"6e00\",\n UNKNOWN_ERROR = \"6f00\",\n WRONG_P1_P2 = \"6b00\",\n INVALID_STATE = \"6b01\",\n INVALID_PATH = \"6b02\",\n INVALID_PARAM = \"6b03\",\n INVALID_TRANSACTION = \"6b04\",\n BUFFER_OVERFLOW = \"6b06\",\n FAILED_CX_OPERATION = \"6b07\",\n TRUSTED_NAME_MISMATCH = \"6b0c\",\n PLT_CBOR_ERROR = \"6b0d\",\n PLT_BUFFER_ERROR = \"6b0e\",\n PLT_DATA_ERROR = \"6b0f\",\n PLT_MULTI_OP = \"6b10\",\n PLT_UNSUPPORTED_DECIMALS = \"6b11\",\n UNSUPPORTED_TRANSACTION_TYPE = \"unsupported_transaction_type\",\n UNSUPPORTED_APP_VERSION = \"unsupported_app_version\",\n INVALID_PLT_TRANSACTION = \"invalid_plt_transaction\",\n TRUSTED_METADATA_SERVICE_ERROR = \"trusted_metadata_service_error\",\n ADDRESS_VERIFICATION_FAILED = \"address_verification_failed\",\n INVALID_MAX_FEE = \"invalid_max_fee\",\n}\n\nexport const CONCORDIUM_APP_ERRORS: CommandErrors<ConcordiumErrorCodes> = {\n \"6985\": { message: \"User rejected\" },\n \"5515\": { message: \"Locked device\" },\n \"6a80\": { message: \"Data invalid\" },\n \"6d00\": { message: \"INS not supported\" },\n \"6e00\": { message: \"CLA not supported\" },\n \"6f00\": { message: \"Unknown error\" },\n \"6b00\": { message: \"Wrong P1 or P2\" },\n \"6b01\": { message: \"Invalid state\" },\n \"6b02\": { message: \"Invalid derivation path\" },\n \"6b03\": { message: \"Invalid parameter\" },\n \"6b04\": { message: \"Invalid transaction\" },\n \"6b06\": { message: \"Buffer overflow\" },\n \"6b07\": { message: \"Failed crypto operation\" },\n \"6b0c\": { message: \"Trusted name mismatch\" },\n \"6b0d\": { message: \"PLT CBOR error\" },\n \"6b0e\": { message: \"PLT buffer error\" },\n \"6b0f\": { message: \"PLT data error\" },\n \"6b10\": { message: \"PLT payload has more than one operation\" },\n \"6b11\": {\n message:\n \"PLT amount has more than the 18 decimal places the app can display\",\n },\n unsupported_transaction_type: { message: \"Unsupported transaction type\" },\n unsupported_app_version: { message: \"Unsupported app version\" },\n invalid_plt_transaction: { message: \"Invalid PLT transaction\" },\n trusted_metadata_service_error: {\n message: \"Trusted metadata service error\",\n },\n address_verification_failed: {\n message: \"Address verification failed\",\n },\n invalid_max_fee: {\n message: \"Invalid maxFee value\",\n },\n};\n\nexport class ConcordiumAppCommandError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(args: CommandErrorArgs<ConcordiumErrorCodes>) {\n super({ tag: \"ConcordiumAppCommandError\", ...args });\n }\n}\n\nexport const ConcordiumAppCommandErrorFactory = (\n args: CommandErrorArgs<ConcordiumErrorCodes>,\n) => new ConcordiumAppCommandError(args);\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,2BAAAE,EAAA,8BAAAC,EAAA,qCAAAC,EAAA,yBAAAC,IAAA,eAAAC,EAAAN,GAAA,IAAAO,EAIO,2CAEKF,OACVA,EAAA,cAAgB,OAChBA,EAAA,cAAgB,OAChBA,EAAA,aAAe,OACfA,EAAA,kBAAoB,OACpBA,EAAA,kBAAoB,OACpBA,EAAA,cAAgB,OAChBA,EAAA,YAAc,OACdA,EAAA,cAAgB,OAChBA,EAAA,aAAe,OACfA,EAAA,cAAgB,OAChBA,EAAA,oBAAsB,OACtBA,EAAA,gBAAkB,OAClBA,EAAA,oBAAsB,OACtBA,EAAA,sBAAwB,OACxBA,EAAA,eAAiB,OACjBA,EAAA,iBAAmB,OACnBA,EAAA,eAAiB,OACjBA,EAAA,aAAe,OACfA,EAAA,yBAA2B,OAC3BA,EAAA,6BAA+B,+BAC/BA,EAAA,wBAA0B,0BAC1BA,EAAA,wBAA0B,0BAC1BA,EAAA,+BAAiC,iCACjCA,EAAA,4BAA8B,8BAC9BA,EAAA,gBAAkB,kBAzBRA,OAAA,IA4BL,MAAMH,EAA6D,CACxE,KAAQ,CAAE,QAAS,eAAgB,EACnC,KAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,cAAe,EAClC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,gBAAiB,EACpC,OAAQ,CAAE,QAAS,eAAgB,EACnC,OAAQ,CAAE,QAAS,yBAA0B,EAC7C,OAAQ,CAAE,QAAS,mBAAoB,EACvC,OAAQ,CAAE,QAAS,qBAAsB,EACzC,OAAQ,CAAE,QAAS,iBAAkB,EACrC,OAAQ,CAAE,QAAS,yBAA0B,EAC7C,OAAQ,CAAE,QAAS,uBAAwB,EAC3C,OAAQ,CAAE,QAAS,gBAAiB,EACpC,OAAQ,CAAE,QAAS,kBAAmB,EACtC,OAAQ,CAAE,QAAS,gBAAiB,EACpC,OAAQ,CAAE,QAAS,yCAA0C,EAC7D,OAAQ,CACN,QACE,oEACJ,EACA,6BAA8B,CAAE,QAAS,8BAA+B,EACxE,wBAAyB,CAAE,QAAS,yBAA0B,EAC9D,wBAAyB,CAAE,QAAS,yBAA0B,EAC9D,+BAAgC,CAC9B,QAAS,gCACX,EACA,4BAA6B,CAC3B,QAAS,6BACX,EACA,gBAAiB,CACf,QAAS,sBACX,CACF,EAEO,MAAMC,UAAkC,qBAA0C,CACvF,YAAYK,EAA8C,CACxD,MAAM,CAAE,IAAK,4BAA6B,GAAGA,CAAK,CAAC,CACrD,CACF,CAEO,MAAMJ,EACXI,GACG,IAAIL,EAA0BK,CAAI",
6
6
  "names": ["ConcordiumApplicationErrors_exports", "__export", "CONCORDIUM_APP_ERRORS", "ConcordiumAppCommandError", "ConcordiumAppCommandErrorFactory", "ConcordiumErrorCodes", "__toCommonJS", "import_device_management_kit", "args"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var a=Object.defineProperty;var c=Object.getOwnPropertyDescriptor;var d=Object.getOwnPropertyNames;var m=Object.prototype.hasOwnProperty;var l=(o,r)=>{for(var t in r)a(o,t,{get:r[t],enumerable:!0})},C=(o,r,t,e)=>{if(r&&typeof r=="object"||typeof r=="function")for(let n of d(r))!m.call(o,n)&&n!==t&&a(o,n,{get:()=>r[n],enumerable:!(e=c(r,n))||e.enumerable});return o};var E=o=>C(a({},"__esModule",{value:!0}),o);var T={};l(T,{InvalidPltTransactionError:()=>I});module.exports=E(T);var s=require("@ledgerhq/device-management-kit"),i=require("../../../app-binder/command/utils/ConcordiumApplicationErrors");class I extends s.DeviceExchangeError{constructor(r){super({tag:"InvalidPltTransactionError",message:`Invalid PLT transaction: ${r}`,errorCode:i.ConcordiumErrorCodes.INVALID_PLT_TRANSACTION})}}0&&(module.exports={InvalidPltTransactionError});
2
+ //# sourceMappingURL=InvalidPltTransactionError.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/command/utils/InvalidPltTransactionError.ts"],
4
+ "sourcesContent": ["import { DeviceExchangeError } from \"@ledgerhq/device-management-kit\";\n\nimport { ConcordiumErrorCodes } from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\n\n/**\n * Raised when a PLT transaction fails the local layout checks that mirror the\n * device-side validation. Rejecting here reports which field is malformed,\n * where the device reports only a status word.\n */\nexport class InvalidPltTransactionError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(message: string) {\n super({\n tag: \"InvalidPltTransactionError\",\n message: `Invalid PLT transaction: ${message}`,\n errorCode: ConcordiumErrorCodes.INVALID_PLT_TRANSACTION,\n });\n }\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAoC,2CAEpCC,EAAqC,0EAO9B,MAAMH,UAAmC,qBAA0C,CACxF,YAAYI,EAAiB,CAC3B,MAAM,CACJ,IAAK,6BACL,QAAS,4BAA4BA,CAAO,GAC5C,UAAW,uBAAqB,uBAClC,CAAC,CACH,CACF",
6
+ "names": ["InvalidPltTransactionError_exports", "__export", "InvalidPltTransactionError", "__toCommonJS", "import_device_management_kit", "import_ConcordiumApplicationErrors", "message"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var p=Object.defineProperty;var d=Object.getOwnPropertyDescriptor;var u=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var m=(o,r)=>{for(var e in r)p(o,e,{get:r[e],enumerable:!0})},E=(o,r,e,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let s of u(r))!c.call(o,s)&&s!==e&&p(o,s,{get:()=>r[s],enumerable:!(n=d(r,s))||n.enumerable});return o};var a=o=>E(p({},"__esModule",{value:!0}),o);var g={};m(g,{UnsupportedAppVersionError:()=>C});module.exports=a(g);var t=require("@ledgerhq/device-management-kit"),i=require("../../../app-binder/command/utils/ConcordiumApplicationErrors");class C extends t.DeviceExchangeError{constructor(r,e){super({tag:"UnsupportedAppVersionError",message:`The installed Concordium app does not support ${r}. Version ${e} or later is required.`,errorCode:i.ConcordiumErrorCodes.UNSUPPORTED_APP_VERSION})}}0&&(module.exports={UnsupportedAppVersionError});
2
+ //# sourceMappingURL=UnsupportedAppVersionError.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../../src/internal/app-binder/command/utils/UnsupportedAppVersionError.ts"],
4
+ "sourcesContent": ["import { DeviceExchangeError } from \"@ledgerhq/device-management-kit\";\n\nimport { ConcordiumErrorCodes } from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\n\n/**\n * Raised when the transaction kind is supported by the signer but not by the\n * app version installed on the device. Distinguishable from a signing failure\n * so that the caller can prompt the user to update the app.\n */\nexport class UnsupportedAppVersionError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(feature: string, minVersion: string) {\n super({\n tag: \"UnsupportedAppVersionError\",\n message: `The installed Concordium app does not support ${feature}. Version ${minVersion} or later is required.`,\n errorCode: ConcordiumErrorCodes.UNSUPPORTED_APP_VERSION,\n });\n }\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,gCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAoC,2CAEpCC,EAAqC,0EAO9B,MAAMH,UAAmC,qBAA0C,CACxF,YAAYI,EAAiBC,EAAoB,CAC/C,MAAM,CACJ,IAAK,6BACL,QAAS,iDAAiDD,CAAO,aAAaC,CAAU,yBACxF,UAAW,uBAAqB,uBAClC,CAAC,CACH,CACF",
6
+ "names": ["UnsupportedAppVersionError_exports", "__export", "UnsupportedAppVersionError", "__toCommonJS", "import_device_management_kit", "import_ConcordiumApplicationErrors", "feature", "minVersion"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var t=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var T=(e,r)=>{for(var n in r)t(e,n,{get:r[n],enumerable:!0})},m=(e,r,n,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of p(r))!c.call(e,o)&&o!==n&&t(e,o,{get:()=>r[o],enumerable:!(s=i(r,o))||s.enumerable});return e};var u=e=>m(t({},"__esModule",{value:!0}),e);var f={};T(f,{UnsupportedTransactionTypeError:()=>E});module.exports=u(f);var a=require("@ledgerhq/device-management-kit"),d=require("../../../app-binder/command/utils/ConcordiumApplicationErrors");class E extends a.DeviceExchangeError{constructor(r){super({tag:"UnsupportedTransactionTypeError",message:r!==void 0?`Unsupported transaction type: ${r} (0x${r.toString(16)}). Expected Transfer (3) or TransferWithMemo (22).`:"Transaction too short to determine type (need at least 61 bytes).",errorCode:d.ConcordiumErrorCodes.UNSUPPORTED_TRANSACTION_TYPE})}}0&&(module.exports={UnsupportedTransactionTypeError});
1
+ "use strict";var t=Object.defineProperty;var i=Object.getOwnPropertyDescriptor;var p=Object.getOwnPropertyNames;var c=Object.prototype.hasOwnProperty;var T=(e,r)=>{for(var n in r)t(e,n,{get:r[n],enumerable:!0})},m=(e,r,n,s)=>{if(r&&typeof r=="object"||typeof r=="function")for(let o of p(r))!c.call(e,o)&&o!==n&&t(e,o,{get:()=>r[o],enumerable:!(s=i(r,o))||s.enumerable});return e};var u=e=>m(t({},"__esModule",{value:!0}),e);var f={};T(f,{UnsupportedTransactionTypeError:()=>E});module.exports=u(f);var a=require("@ledgerhq/device-management-kit"),d=require("../../../app-binder/command/utils/ConcordiumApplicationErrors");class E extends a.DeviceExchangeError{constructor(r){super({tag:"UnsupportedTransactionTypeError",message:r!==void 0?`Unsupported transaction type: ${r} (0x${r.toString(16)}). Expected Transfer (3), TransferWithMemo (22) or TokenUpdate (27).`:"Transaction too short to determine type (need at least 61 bytes).",errorCode:d.ConcordiumErrorCodes.UNSUPPORTED_TRANSACTION_TYPE})}}0&&(module.exports={UnsupportedTransactionTypeError});
2
2
  //# sourceMappingURL=UnsupportedTransactionTypeError.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/internal/app-binder/command/utils/UnsupportedTransactionTypeError.ts"],
4
- "sourcesContent": ["import { DeviceExchangeError } from \"@ledgerhq/device-management-kit\";\n\nimport { ConcordiumErrorCodes } from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\n\nexport class UnsupportedTransactionTypeError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(type: number | undefined) {\n super({\n tag: \"UnsupportedTransactionTypeError\",\n message:\n type !== undefined\n ? `Unsupported transaction type: ${type} (0x${type.toString(16)}). Expected Transfer (3) or TransferWithMemo (22).`\n : \"Transaction too short to determine type (need at least 61 bytes).\",\n errorCode: ConcordiumErrorCodes.UNSUPPORTED_TRANSACTION_TYPE,\n });\n }\n}\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAoC,2CAEpCC,EAAqC,0EAE9B,MAAMH,UAAwC,qBAA0C,CAC7F,YAAYI,EAA0B,CACpC,MAAM,CACJ,IAAK,kCACL,QACEA,IAAS,OACL,iCAAiCA,CAAI,OAAOA,EAAK,SAAS,EAAE,CAAC,qDAC7D,oEACN,UAAW,uBAAqB,4BAClC,CAAC,CACH,CACF",
4
+ "sourcesContent": ["import { DeviceExchangeError } from \"@ledgerhq/device-management-kit\";\n\nimport { ConcordiumErrorCodes } from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\n\nexport class UnsupportedTransactionTypeError extends DeviceExchangeError<ConcordiumErrorCodes> {\n constructor(type: number | undefined) {\n super({\n tag: \"UnsupportedTransactionTypeError\",\n message:\n type !== undefined\n ? `Unsupported transaction type: ${type} (0x${type.toString(16)}). Expected Transfer (3), TransferWithMemo (22) or TokenUpdate (27).`\n : \"Transaction too short to determine type (need at least 61 bytes).\",\n errorCode: ConcordiumErrorCodes.UNSUPPORTED_TRANSACTION_TYPE,\n });\n }\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,qCAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAAoC,2CAEpCC,EAAqC,0EAE9B,MAAMH,UAAwC,qBAA0C,CAC7F,YAAYI,EAA0B,CACpC,MAAM,CACJ,IAAK,kCACL,QACEA,IAAS,OACL,iCAAiCA,CAAI,OAAOA,EAAK,SAAS,EAAE,CAAC,uEAC7D,oEACN,UAAW,uBAAqB,4BAClC,CAAC,CACH,CACF",
6
6
  "names": ["UnsupportedTransactionTypeError_exports", "__export", "UnsupportedTransactionTypeError", "__toCommonJS", "import_device_management_kit", "import_ConcordiumApplicationErrors", "type"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var x=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var O=(_,E)=>{for(var I in E)x(_,I,{get:E[I],enumerable:!0})},L=(_,E,I,N)=>{if(E&&typeof E=="object"||typeof E=="function")for(let T of R(E))!S.call(_,T)&&T!==I&&x(_,T,{get:()=>E[T],enumerable:!(N=A(E,T))||N.enumerable});return _};var o=_=>L(x({},"__esModule",{value:!0}),_);var P={};O(P,{APP_NAME:()=>D,FEE_DISPLAY_SIZE:()=>C,INS:()=>t,LEDGER_CLA:()=>F,P1:()=>G,P2:()=>M});module.exports=o(P);const D="Concordium",F=224,t={VERIFY_ADDRESS:0,GET_PUBLIC_KEY:1,SIGN_TRANSFER:2,SIGN_TRANSFER_WITH_SCHEDULE:3,SIGN_CREDENTIAL_DEPLOYMENT:4,SIGN_TRANSFER_WITH_MEMO:50,SIGN_TRANSFER_WITH_SCHEDULE_AND_MEMO:52,REGISTER_DATA:53,SET_TRUSTED_NAME:34,GET_CHALLENGE:35,GET_APP_VERSION:64},G={NON_CONFIRM:1,CONFIRM:0,FIRST_CHUNK:0,INITIAL:0,INITIAL_WITH_MEMO:1,MEMO:2,AMOUNT:3,VERIFICATION_KEY_COUNT:10,VERIFICATION_KEY:1,SIGNATURE_THRESHOLD:2,AR_IDENTITY:3,CREDENTIAL_DATES:4,ATTRIBUTE_TAG:5,ATTRIBUTE_VALUE:6,LENGTH_OF_PROOFS:7,PROOFS:8,NEW_OR_EXISTING:9,FULL_PATH:2},M={NONE:0,MORE:128,LAST:0,FEE_DISPLAY:1},C=8;0&&(module.exports={APP_NAME,FEE_DISPLAY_SIZE,INS,LEDGER_CLA,P1,P2});
1
+ "use strict";var x=Object.defineProperty;var A=Object.getOwnPropertyDescriptor;var R=Object.getOwnPropertyNames;var S=Object.prototype.hasOwnProperty;var L=(_,E)=>{for(var I in E)x(_,I,{get:E[I],enumerable:!0})},O=(_,E,I,N)=>{if(E&&typeof E=="object"||typeof E=="function")for(let T of R(E))!S.call(_,T)&&T!==I&&x(_,T,{get:()=>E[T],enumerable:!(N=A(E,T))||N.enumerable});return _};var o=_=>O(x({},"__esModule",{value:!0}),_);var M={};L(M,{APP_NAME:()=>D,FEE_DISPLAY_SIZE:()=>C,INS:()=>G,LEDGER_CLA:()=>F,P1:()=>P,P2:()=>t});module.exports=o(M);const D="Concordium",F=224,G={VERIFY_ADDRESS:0,GET_PUBLIC_KEY:1,SIGN_TRANSFER:2,SIGN_TRANSFER_WITH_SCHEDULE:3,SIGN_CREDENTIAL_DEPLOYMENT:4,SIGN_TRANSFER_WITH_MEMO:50,SIGN_TRANSFER_WITH_SCHEDULE_AND_MEMO:52,REGISTER_DATA:53,SIGN_PLT:39,SET_TRUSTED_NAME:34,GET_CHALLENGE:35,GET_APP_VERSION:64},P={NON_CONFIRM:1,CONFIRM:0,FIRST_CHUNK:0,INITIAL:0,INITIAL_WITH_MEMO:1,MEMO:2,AMOUNT:3,PLT_INIT:0,PLT_CONT:1,VERIFICATION_KEY_COUNT:10,VERIFICATION_KEY:1,SIGNATURE_THRESHOLD:2,AR_IDENTITY:3,CREDENTIAL_DATES:4,ATTRIBUTE_TAG:5,ATTRIBUTE_VALUE:6,LENGTH_OF_PROOFS:7,PROOFS:8,NEW_OR_EXISTING:9,FULL_PATH:2},t={NONE:0,MORE:128,LAST:0,FEE_DISPLAY:1},C=8;0&&(module.exports={APP_NAME,FEE_DISPLAY_SIZE,INS,LEDGER_CLA,P1,P2});
2
2
  //# sourceMappingURL=constants.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/internal/app-binder/constants.ts"],
4
- "sourcesContent": ["export const APP_NAME = \"Concordium\";\n\nexport const LEDGER_CLA = 0xe0;\n\nexport const INS = {\n VERIFY_ADDRESS: 0x00,\n GET_PUBLIC_KEY: 0x01,\n SIGN_TRANSFER: 0x02,\n SIGN_TRANSFER_WITH_SCHEDULE: 0x03,\n SIGN_CREDENTIAL_DEPLOYMENT: 0x04,\n SIGN_TRANSFER_WITH_MEMO: 0x32,\n SIGN_TRANSFER_WITH_SCHEDULE_AND_MEMO: 0x34,\n REGISTER_DATA: 0x35,\n SET_TRUSTED_NAME: 0x22,\n GET_CHALLENGE: 0x23,\n GET_APP_VERSION: 0x40,\n} as const;\n\nexport const P1 = {\n NON_CONFIRM: 0x01,\n CONFIRM: 0x00,\n FIRST_CHUNK: 0x00,\n INITIAL: 0x00,\n INITIAL_WITH_MEMO: 0x01,\n MEMO: 0x02,\n AMOUNT: 0x03,\n\n // Credential Deployment\n VERIFICATION_KEY_COUNT: 0x0a,\n VERIFICATION_KEY: 0x01,\n SIGNATURE_THRESHOLD: 0x02,\n AR_IDENTITY: 0x03,\n CREDENTIAL_DATES: 0x04,\n ATTRIBUTE_TAG: 0x05,\n ATTRIBUTE_VALUE: 0x06,\n LENGTH_OF_PROOFS: 0x07,\n PROOFS: 0x08,\n NEW_OR_EXISTING: 0x09,\n FULL_PATH: 0x02,\n} as const;\n\nexport const P2 = {\n NONE: 0x00,\n MORE: 0x80,\n LAST: 0x00,\n FEE_DISPLAY: 0x01,\n} as const;\n\nexport const FEE_DISPLAY_SIZE = 8;\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,cAAAE,EAAA,qBAAAC,EAAA,QAAAC,EAAA,eAAAC,EAAA,OAAAC,EAAA,OAAAC,IAAA,eAAAC,EAAAR,GAAO,MAAME,EAAW,aAEXG,EAAa,IAEbD,EAAM,CACjB,eAAgB,EAChB,eAAgB,EAChB,cAAe,EACf,4BAA6B,EAC7B,2BAA4B,EAC5B,wBAAyB,GACzB,qCAAsC,GACtC,cAAe,GACf,iBAAkB,GAClB,cAAe,GACf,gBAAiB,EACnB,EAEaE,EAAK,CAChB,YAAa,EACb,QAAS,EACT,YAAa,EACb,QAAS,EACT,kBAAmB,EACnB,KAAM,EACN,OAAQ,EAGR,uBAAwB,GACxB,iBAAkB,EAClB,oBAAqB,EACrB,YAAa,EACb,iBAAkB,EAClB,cAAe,EACf,gBAAiB,EACjB,iBAAkB,EAClB,OAAQ,EACR,gBAAiB,EACjB,UAAW,CACb,EAEaC,EAAK,CAChB,KAAM,EACN,KAAM,IACN,KAAM,EACN,YAAa,CACf,EAEaJ,EAAmB",
4
+ "sourcesContent": ["export const APP_NAME = \"Concordium\";\n\nexport const LEDGER_CLA = 0xe0;\n\nexport const INS = {\n VERIFY_ADDRESS: 0x00,\n GET_PUBLIC_KEY: 0x01,\n SIGN_TRANSFER: 0x02,\n SIGN_TRANSFER_WITH_SCHEDULE: 0x03,\n SIGN_CREDENTIAL_DEPLOYMENT: 0x04,\n SIGN_TRANSFER_WITH_MEMO: 0x32,\n SIGN_TRANSFER_WITH_SCHEDULE_AND_MEMO: 0x34,\n REGISTER_DATA: 0x35,\n SIGN_PLT: 0x27,\n SET_TRUSTED_NAME: 0x22,\n GET_CHALLENGE: 0x23,\n GET_APP_VERSION: 0x40,\n} as const;\n\nexport const P1 = {\n NON_CONFIRM: 0x01,\n CONFIRM: 0x00,\n FIRST_CHUNK: 0x00,\n INITIAL: 0x00,\n INITIAL_WITH_MEMO: 0x01,\n MEMO: 0x02,\n AMOUNT: 0x03,\n\n // Protocol Level Tokens (INS 0x27)\n PLT_INIT: 0x00,\n PLT_CONT: 0x01,\n\n // Credential Deployment\n VERIFICATION_KEY_COUNT: 0x0a,\n VERIFICATION_KEY: 0x01,\n SIGNATURE_THRESHOLD: 0x02,\n AR_IDENTITY: 0x03,\n CREDENTIAL_DATES: 0x04,\n ATTRIBUTE_TAG: 0x05,\n ATTRIBUTE_VALUE: 0x06,\n LENGTH_OF_PROOFS: 0x07,\n PROOFS: 0x08,\n NEW_OR_EXISTING: 0x09,\n FULL_PATH: 0x02,\n} as const;\n\nexport const P2 = {\n NONE: 0x00,\n MORE: 0x80,\n LAST: 0x00,\n FEE_DISPLAY: 0x01,\n} as const;\n\nexport const FEE_DISPLAY_SIZE = 8;\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,cAAAE,EAAA,qBAAAC,EAAA,QAAAC,EAAA,eAAAC,EAAA,OAAAC,EAAA,OAAAC,IAAA,eAAAC,EAAAR,GAAO,MAAME,EAAW,aAEXG,EAAa,IAEbD,EAAM,CACjB,eAAgB,EAChB,eAAgB,EAChB,cAAe,EACf,4BAA6B,EAC7B,2BAA4B,EAC5B,wBAAyB,GACzB,qCAAsC,GACtC,cAAe,GACf,SAAU,GACV,iBAAkB,GAClB,cAAe,GACf,gBAAiB,EACnB,EAEaE,EAAK,CAChB,YAAa,EACb,QAAS,EACT,YAAa,EACb,QAAS,EACT,kBAAmB,EACnB,KAAM,EACN,OAAQ,EAGR,SAAU,EACV,SAAU,EAGV,uBAAwB,GACxB,iBAAkB,EAClB,oBAAqB,EACrB,YAAa,EACb,iBAAkB,EAClB,cAAe,EACf,gBAAiB,EACjB,iBAAkB,EAClB,OAAQ,EACR,gBAAiB,EACjB,UAAW,CACb,EAEaC,EAAK,CAChB,KAAM,EACN,KAAM,IACN,KAAM,EACN,YAAa,CACf,EAEaJ,EAAmB",
6
6
  "names": ["constants_exports", "__export", "APP_NAME", "FEE_DISPLAY_SIZE", "INS", "LEDGER_CLA", "P1", "P2", "__toCommonJS"]
7
7
  }
@@ -0,0 +1,2 @@
1
+ "use strict";var P=Object.defineProperty;var v=Object.getOwnPropertyDescriptor;var x=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var k=(n,t)=>{for(var e in t)P(n,e,{get:t[e],enumerable:!0})},w=(n,t,e,d)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of x(t))!j.call(n,o)&&o!==e&&P(n,o,{get:()=>t[o],enumerable:!(d=v(t,o))||d.enumerable});return n};var B=n=>w(P({},"__esModule",{value:!0}),n);var H={};k(H,{SendPltTask:()=>F});module.exports=B(H);var r=require("@ledgerhq/device-management-kit"),E=require("../../app-binder/command/SignPltCommand"),_=require("../../app-binder/command/utils/EncodeDerivationPath"),y=require("../../app-binder/command/utils/EncodeMaxFee"),R=require("../../app-binder/command/utils/InvalidPltTransactionError"),a=require("../../app-binder/constants");const p=60,T=1,L=1,O=4,S=27,b=128,I=512,N=p+T+L+1+O+1;class F{constructor(t,e,d){this.api=t;this.args=e;this.logger=d}async run(){const{derivationPath:t,transaction:e,maxFee:d}=this.args;if(this.logger.debug("[run] Starting SendPltTask",{data:{derivationPath:t,transactionLength:e.length}}),e.length<N)return this.reject(`expected at least ${N} bytes, got ${e.length}`);const o=e[p];if(o!==S)return this.reject(`expected transaction kind ${S} (0x1b), got ${o} (0x${o.toString(16)})`);const g=e[p+T];if(g<1||g>b)return this.reject(`token id length must be between 1 and ${b}, got ${g}`);const A=p+T+L+g,i=A+O;if(e.length<i)return this.reject(`truncated before the CBOR length field: need ${i} bytes, got ${e.length}`);const c=U(e,A);if(c<1||c>I)return this.reject(`CBOR length must be between 1 and ${I}, got ${c}`);const m=e.slice(i);if(m.length!==c)return this.reject(`declared CBOR length ${c} does not match the ${m.length} remaining bytes`);const u=(0,_.encodeDerivationPath)(t),$=(0,y.encodeMaxFeeBigEndian)(d),s=new Uint8Array(u.length+i+a.FEE_DISPLAY_SIZE);if(s.set(u,0),s.set(e.slice(0,i),u.length),s.set($,u.length+i),s.length>r.APDU_MAX_PAYLOAD)return this.reject(`INIT frame exceeds the APDU limit: ${s.length} bytes > ${r.APDU_MAX_PAYLOAD}`);const f=await this.api.sendCommand(new E.SignPltCommand({p1:a.P1.PLT_INIT,p2:a.P2.FEE_DISPLAY,data:s}));if(!(0,r.isSuccessCommandResult)(f))return this.logger.debug("[run] INIT frame failed",{data:{error:f.error}}),f;let C=new Uint8Array;for(let l=0;l<m.length;l+=r.APDU_MAX_PAYLOAD){const D=m.slice(l,l+r.APDU_MAX_PAYLOAD),h=await this.api.sendCommand(new E.SignPltCommand({p1:a.P1.PLT_CONT,p2:a.P2.NONE,data:D}));if(!(0,r.isSuccessCommandResult)(h))return this.logger.debug("[run] CONT frame failed",{data:{offset:l,error:h.error}}),h;C=h.data}return this.logger.debug("[run] All frames completed successfully",{data:{signature:C}}),(0,r.CommandResultFactory)({data:C})}reject(t){return this.logger.debug("[run] Local validation rejected the transaction",{data:{message:t}}),(0,r.CommandResultFactory)({error:new R.InvalidPltTransactionError(t)})}}function U(n,t){return(n[t]<<24|n[t+1]<<16|n[t+2]<<8|n[t+3])>>>0}0&&(module.exports={SendPltTask});
2
+ //# sourceMappingURL=SendPltTask.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/task/SendPltTask.ts"],
4
+ "sourcesContent": ["import {\n APDU_MAX_PAYLOAD,\n type CommandResult,\n CommandResultFactory,\n type InternalApi,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type Signature } from \"@api/model/Signature\";\nimport {\n SignPltCommand,\n type SignPltCommandResponse,\n} from \"@internal/app-binder/command/SignPltCommand\";\nimport { type ConcordiumErrorCodes } from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { encodeDerivationPath } from \"@internal/app-binder/command/utils/EncodeDerivationPath\";\nimport { encodeMaxFeeBigEndian } from \"@internal/app-binder/command/utils/EncodeMaxFee\";\nimport { InvalidPltTransactionError } from \"@internal/app-binder/command/utils/InvalidPltTransactionError\";\nimport { FEE_DISPLAY_SIZE, P1, P2 } from \"@internal/app-binder/constants\";\n\n// Serialized TokenUpdate transaction layout:\n// [header:60][kind:1 = 0x1B][tokenIdLength:1][tokenId:1..128][cborTotalLength:4 BE][cbor:N]\n//\n// The INIT frame is everything up to and including cborTotalLength, prefixed\n// with the derivation path and suffixed with the 8-byte max fee. Worst case with\n// a 5-node path and a 128-byte token id: 21 + 60 + 1 + 1 + 128 + 4 + 8 = 223\n// bytes, still inside APDU_MAX_PAYLOAD but with less headroom than it looks.\n\nconst HEADER_LENGTH = 60;\nconst KIND_LENGTH = 1;\nconst TOKEN_ID_LENGTH_FIELD = 1;\nconst CBOR_LENGTH_FIELD = 4;\n\nconst TRANSACTION_KIND_TOKEN_UPDATE = 0x1b;\n\n/** Maximum token-id length the device accepts, per CIS-7. */\nconst TOKEN_ID_MAX = 128;\n/** Maximum PLT CBOR operations blob the device will buffer. */\nconst CBOR_MAX = 512;\n\nconst MIN_TRANSACTION_LENGTH =\n HEADER_LENGTH +\n KIND_LENGTH +\n TOKEN_ID_LENGTH_FIELD +\n 1 +\n CBOR_LENGTH_FIELD +\n 1;\n\ntype SendPltTaskArgs = {\n derivationPath: string;\n transaction: Uint8Array;\n /** Max fee in \u00B5CCD, rendered as a \"Max fees\" step on the review screens. */\n maxFee: bigint;\n};\n\n/**\n * Streams a PLT (TokenUpdate) transaction to the device over INS 0x27.\n *\n * One INIT frame (P1=0x00) carries the derivation path and everything up to and\n * including the CBOR length, plus the 8-byte big-endian \u00B5CCD max fee. CONT\n * frames (P1=0x01) then carry the CBOR payload. Chunking is byte-oriented: a\n * CBOR field may span a frame boundary, since the device buffers the whole\n * payload before parsing it.\n *\n * Fee display is unconditional here. The factory only reaches this task on an\n * app at or above `MIN_APP_VERSION_FOR_PLT`, and that release ships PLT signing\n * and clear-signing together, so a PLT-capable app always accepts the suffix.\n *\n * The fee suffix is not hashed by the device, so the signature is identical\n * whether or not it is sent.\n */\nexport class SendPltTask {\n constructor(\n private readonly api: InternalApi,\n private readonly args: SendPltTaskArgs,\n private readonly logger: LoggerPublisherService,\n ) {}\n\n async run(): Promise<\n CommandResult<SignPltCommandResponse, ConcordiumErrorCodes>\n > {\n const { derivationPath, transaction, maxFee } = this.args;\n\n this.logger.debug(\"[run] Starting SendPltTask\", {\n data: {\n derivationPath,\n transactionLength: transaction.length,\n },\n });\n\n if (transaction.length < MIN_TRANSACTION_LENGTH) {\n return this.reject(\n `expected at least ${MIN_TRANSACTION_LENGTH} bytes, got ${transaction.length}`,\n );\n }\n\n const kind = transaction[HEADER_LENGTH]!;\n if (kind !== TRANSACTION_KIND_TOKEN_UPDATE) {\n return this.reject(\n `expected transaction kind ${TRANSACTION_KIND_TOKEN_UPDATE} (0x1b), got ${kind} (0x${kind.toString(16)})`,\n );\n }\n\n const tokenIdLength = transaction[HEADER_LENGTH + KIND_LENGTH]!;\n if (tokenIdLength < 1 || tokenIdLength > TOKEN_ID_MAX) {\n return this.reject(\n `token id length must be between 1 and ${TOKEN_ID_MAX}, got ${tokenIdLength}`,\n );\n }\n\n const cborLengthOffset =\n HEADER_LENGTH + KIND_LENGTH + TOKEN_ID_LENGTH_FIELD + tokenIdLength;\n const cborOffset = cborLengthOffset + CBOR_LENGTH_FIELD;\n\n if (transaction.length < cborOffset) {\n return this.reject(\n `truncated before the CBOR length field: need ${cborOffset} bytes, got ${transaction.length}`,\n );\n }\n\n const cborTotalLength = readUint32BE(transaction, cborLengthOffset);\n if (cborTotalLength < 1 || cborTotalLength > CBOR_MAX) {\n return this.reject(\n `CBOR length must be between 1 and ${CBOR_MAX}, got ${cborTotalLength}`,\n );\n }\n\n const cbor = transaction.slice(cborOffset);\n if (cbor.length !== cborTotalLength) {\n return this.reject(\n `declared CBOR length ${cborTotalLength} does not match the ${cbor.length} remaining bytes`,\n );\n }\n\n const pathBytes = encodeDerivationPath(derivationPath);\n const feeSuffix = encodeMaxFeeBigEndian(maxFee);\n const initPayload = new Uint8Array(\n pathBytes.length + cborOffset + FEE_DISPLAY_SIZE,\n );\n initPayload.set(pathBytes, 0);\n initPayload.set(transaction.slice(0, cborOffset), pathBytes.length);\n initPayload.set(feeSuffix, pathBytes.length + cborOffset);\n\n if (initPayload.length > APDU_MAX_PAYLOAD) {\n return this.reject(\n `INIT frame exceeds the APDU limit: ${initPayload.length} bytes > ${APDU_MAX_PAYLOAD}`,\n );\n }\n\n const initResult = await this.api.sendCommand(\n new SignPltCommand({\n p1: P1.PLT_INIT,\n p2: P2.FEE_DISPLAY,\n data: initPayload,\n }),\n );\n\n if (!isSuccessCommandResult(initResult)) {\n this.logger.debug(\"[run] INIT frame failed\", {\n data: { error: initResult.error },\n });\n return initResult;\n }\n\n let signature: Signature = new Uint8Array() as Signature;\n\n for (let offset = 0; offset < cbor.length; offset += APDU_MAX_PAYLOAD) {\n const chunk = cbor.slice(offset, offset + APDU_MAX_PAYLOAD);\n const contResult: CommandResult<\n SignPltCommandResponse,\n ConcordiumErrorCodes\n > = await this.api.sendCommand(\n new SignPltCommand({ p1: P1.PLT_CONT, p2: P2.NONE, data: chunk }),\n );\n\n if (!isSuccessCommandResult(contResult)) {\n this.logger.debug(\"[run] CONT frame failed\", {\n data: { offset, error: contResult.error },\n });\n return contResult;\n }\n\n signature = contResult.data;\n }\n\n this.logger.debug(\"[run] All frames completed successfully\", {\n data: { signature },\n });\n\n return CommandResultFactory({ data: signature });\n }\n\n private reject(\n message: string,\n ): CommandResult<SignPltCommandResponse, ConcordiumErrorCodes> {\n this.logger.debug(\"[run] Local validation rejected the transaction\", {\n data: { message },\n });\n return CommandResultFactory({\n error: new InvalidPltTransactionError(message),\n });\n }\n}\n\nfunction readUint32BE(bytes: Uint8Array, offset: number): number {\n return (\n ((bytes[offset]! << 24) |\n (bytes[offset + 1]! << 16) |\n (bytes[offset + 2]! << 8) |\n bytes[offset + 3]!) >>>\n 0\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["SendPltTask_exports", "__export", "SendPltTask", "__toCommonJS", "import_device_management_kit", "import_SignPltCommand", "import_EncodeDerivationPath", "import_EncodeMaxFee", "import_InvalidPltTransactionError", "import_constants", "HEADER_LENGTH", "KIND_LENGTH", "TOKEN_ID_LENGTH_FIELD", "CBOR_LENGTH_FIELD", "TRANSACTION_KIND_TOKEN_UPDATE", "TOKEN_ID_MAX", "CBOR_MAX", "MIN_TRANSACTION_LENGTH", "api", "args", "logger", "derivationPath", "transaction", "maxFee", "kind", "tokenIdLength", "cborLengthOffset", "cborOffset", "cborTotalLength", "readUint32BE", "cbor", "pathBytes", "feeSuffix", "initPayload", "initResult", "signature", "offset", "chunk", "contResult", "message", "bytes"]
7
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";var c=require("@ledgerhq/device-management-kit"),P=require("vitest"),A=require("../../app-binder/command/utils/ConcordiumApplicationErrors"),g=require("../../app-binder/command/utils/EncodeDerivationPath"),C=require("../../app-binder/command/utils/EncodeMaxFee"),f=require("../../app-binder/constants"),h=require("../../app-binder/task/SendPltTask");const p="44'/919'/0'/0'/0'",d=726675n,E=new Uint8Array(60).fill(17),T=27,U=new Uint8Array(64).fill(171);function l({kind:e=T,tokenId:t=new TextEncoder().encode("PLT"),cbor:n=new Uint8Array([129,161,101,112,97,117,115,101,160]),tokenIdLengthByte:a,declaredCborLength:o}={}){const r=o??n.length,s=new Uint8Array(62+t.length+4+n.length);return s.set(E,0),s[60]=e,s[61]=a??t.length,s.set(t,62),new DataView(s.buffer,s.byteOffset).setUint32(62+t.length,r,!1),s.set(n,62+t.length+4),s}function m(e){const t=[];let n=0;return{api:{sendCommand:P.vi.fn(o=>{t.push(o);const r=e?.[n++];return Promise.resolve(r??(0,c.CommandResultFactory)({data:U}))})},sentCommands:t}}function u(){return{debug:P.vi.fn()}}function x(e){const t=e.getApdu().getRawApdu();return{cla:t[0],ins:t[1],p1:t[2],p2:t[3],data:t.slice(5)}}describe("SendPltTask",()=>{it("should send one INIT frame and one CONT frame for a small payload",async()=>{const{api:e,sentCommands:t}=m(),n=l(),a=await new h.SendPltTask(e,{derivationPath:p,transaction:n,maxFee:d},u()).run();expect(t).toHaveLength(2),expect((0,c.isSuccessCommandResult)(a)).toBe(!0),(0,c.isSuccessCommandResult)(a)&&expect(a.data).toStrictEqual(U)}),it("should build the INIT frame as path + header + kind + tokenIdLength + tokenId + cborLength",async()=>{const{api:e,sentCommands:t}=m(),n=new TextEncoder().encode("PLT"),a=new Uint8Array(9).fill(1),o=l({tokenId:n,cbor:a});await new h.SendPltTask(e,{derivationPath:p,transaction:o,maxFee:d},u()).run();const r=x(t[0]),s=(0,g.encodeDerivationPath)(p),i=new Uint8Array([...s,...E,T,n.length,...n,0,0,0,a.length,...(0,C.encodeMaxFeeBigEndian)(d)]);expect(r.cla).toBe(f.LEDGER_CLA),expect(r.ins).toBe(f.INS.SIGN_PLT),expect(r.p1).toBe(f.P1.PLT_INIT),expect(r.data).toStrictEqual(i)}),it("should carry P2=0x01 on the INIT frame and end with the 8-byte fee",async()=>{const{api:e,sentCommands:t}=m(),n=l();await new h.SendPltTask(e,{derivationPath:p,transaction:n,maxFee:d},u()).run();const a=x(t[0]),o=(0,g.encodeDerivationPath)(p),r=3;expect(a.p2).toBe(f.P2.FEE_DISPLAY),expect(a.data).toHaveLength(o.length+60+1+1+r+4+8),expect(a.data.slice(-8)).toStrictEqual((0,C.encodeMaxFeeBigEndian)(d))}),it("should carry P2=0x00 on every CONT frame",async()=>{const{api:e,sentCommands:t}=m(),n=l({cbor:new Uint8Array(300)});await new h.SendPltTask(e,{derivationPath:p,transaction:n,maxFee:d},u()).run();const a=t.slice(1).map(o=>x(o).p2);expect(a.length).toBeGreaterThan(1),expect(a.every(o=>o===f.P2.NONE)).toBe(!0)}),it("should not change the signed bytes when the fee changes",async()=>{const e=async t=>{const{api:n,sentCommands:a}=m();await new h.SendPltTask(n,{derivationPath:p,transaction:l(),maxFee:t},u()).run();const o=x(a[0]);return Buffer.from(o.data.slice(0,-8)).toString("hex")};expect(await e(1n)).toBe(await e(999999n))}),it("should send the CBOR payload as CONT frames of at most APDU_MAX_PAYLOAD bytes",async()=>{const{api:e,sentCommands:t}=m(),n=new Uint8Array(300);n.forEach((s,i)=>n[i]=i&255);const a=l({cbor:n});await new h.SendPltTask(e,{derivationPath:p,transaction:a,maxFee:d},u()).run(),expect(t).toHaveLength(3);const o=x(t[1]),r=x(t[2]);expect(o.p1).toBe(f.P1.PLT_CONT),expect(r.p1).toBe(f.P1.PLT_CONT),expect(o.data).toStrictEqual(n.slice(0,c.APDU_MAX_PAYLOAD)),expect(r.data).toStrictEqual(n.slice(c.APDU_MAX_PAYLOAD))}),it("should split a CBOR field across a frame boundary without realigning",async()=>{const{api:e,sentCommands:t}=m(),n=new Uint8Array(260).fill(90);n[c.APDU_MAX_PAYLOAD-1]=240,n[c.APDU_MAX_PAYLOAD]=241;const a=l({cbor:n});await new h.SendPltTask(e,{derivationPath:p,transaction:a,maxFee:d},u()).run();const o=x(t[1]),r=x(t[2]);expect(o.data[c.APDU_MAX_PAYLOAD-1]).toBe(240),expect(r.data[0]).toBe(241)}),it("should fit a 128-byte token id in the INIT frame",async()=>{const{api:e,sentCommands:t}=m(),n=new Uint8Array(128).fill(65),a=l({tokenId:n}),o=await new h.SendPltTask(e,{derivationPath:"44'/919'/0'/0'/0'",transaction:a,maxFee:d},u()).run();expect((0,c.isSuccessCommandResult)(o)).toBe(!0);const r=x(t[0]);expect(r.data.length).toBeLessThanOrEqual(c.APDU_MAX_PAYLOAD);const s=(0,g.encodeDerivationPath)("44'/919'/0'/0'/0'").length;expect(r.data[s+60+1]).toBe(128)}),it("should propagate an INIT frame failure without sending CONT frames",async()=>{const e=(0,c.CommandResultFactory)({error:{errorCode:A.ConcordiumErrorCodes.PLT_DATA_ERROR}}),{api:t,sentCommands:n}=m([e]),a=await new h.SendPltTask(t,{derivationPath:p,transaction:l(),maxFee:d},u()).run();expect(n).toHaveLength(1),expect((0,c.isSuccessCommandResult)(a)).toBe(!1)}),it("should propagate a CONT frame failure and stop streaming",async()=>{const e=(0,c.CommandResultFactory)({data:new Uint8Array}),t=(0,c.CommandResultFactory)({error:{errorCode:A.ConcordiumErrorCodes.PLT_CBOR_ERROR}}),{api:n,sentCommands:a}=m([e,t]),o=new Uint8Array(300).fill(0),r=await new h.SendPltTask(n,{derivationPath:p,transaction:l({cbor:o}),maxFee:d},u()).run();expect(a).toHaveLength(2),expect((0,c.isSuccessCommandResult)(r)).toBe(!1)}),describe("device contract parity",()=>{const e=Uint8Array.from(Buffer.from("20a845815bd43a1999e90fbf971537a70392eb38f89e6bd32b3dd70e1a9551d7000000000000000a0000000000000064000000000000000063de5da7","hex")),t=new Uint8Array([84]),n=new Uint8Array([129,161,101,112,97,117,115,101,160]),a="1105/0/0/0/0/2/0/0",o=Uint8Array.from(Buffer.from("088000045180000000800000008000000080000000800000028000000080000000","hex"));function r(s){const i=new Uint8Array(67+s.length);return i.set(e,0),i[60]=T,i[61]=t.length,i.set(t,62),new DataView(i.buffer,i.byteOffset).setUint32(63,s.length,!1),i.set(s,67),i}it("should match the INIT frame bytes the firmware fixture sends",async()=>{const{api:s,sentCommands:i}=m();await new h.SendPltTask(s,{derivationPath:a,transaction:r(n),maxFee:d},u()).run();const w=x(i[0]),y=new Uint8Array([...o,...e,27,t.length,...t,0,0,0,n.length,...(0,C.encodeMaxFeeBigEndian)(d)]);expect(w.p2).toBe(f.P2.FEE_DISPLAY),expect(w.data).toStrictEqual(y)}),it("should encode the fixture derivation path as the firmware parses it",()=>{expect((0,g.encodeDerivationPath)(a)).toStrictEqual(o)}),it("should split a payload at the 512-byte CBOR maximum as 255 + 255 + 2",async()=>{const{api:s,sentCommands:i}=m(),w=new Uint8Array(512);await new h.SendPltTask(s,{derivationPath:a,transaction:r(w),maxFee:d},u()).run();const y=i.slice(1).map(b=>x(b).data.length);expect(y).toStrictEqual([255,255,2])}),it("should send a 300-byte payload as two CONT frames",async()=>{const{api:s,sentCommands:i}=m(),w=new Uint8Array(300);await new h.SendPltTask(s,{derivationPath:a,transaction:r(w),maxFee:d},u()).run();const y=i.slice(1).map(b=>x(b).data.length);expect(y).toStrictEqual([255,45])})}),describe("local validation",()=>{async function e(t){const{api:n,sentCommands:a}=m(),o=await new h.SendPltTask(n,{derivationPath:p,transaction:t,maxFee:d},u()).run();return expect(a).toHaveLength(0),expect((0,c.isSuccessCommandResult)(o)).toBe(!1),(0,c.isSuccessCommandResult)(o)||expect(o.error.errorCode).toStrictEqual(A.ConcordiumErrorCodes.INVALID_PLT_TRANSACTION),o}it("should reject a transaction shorter than the minimum layout",async()=>{await e(new Uint8Array(66).fill(0))}),it("should reject a transaction kind other than 27",async()=>{await e(l({kind:22}))}),it("should reject a token id length of 0",async()=>{await e(l({tokenIdLengthByte:0}))}),it("should reject a token id length above 128",async()=>{await e(l({tokenId:new Uint8Array(129).fill(65)}))}),it("should reject a declared CBOR length of 0",async()=>{await e(l({declaredCborLength:0}))}),it("should reject a declared CBOR length above 512",async()=>{await e(l({declaredCborLength:513}))}),it("should reject a declared CBOR length that disagrees with the payload",async()=>{await e(l({declaredCborLength:8}))}),it("should reject a transaction truncated before the CBOR length field",async()=>{const t=new Uint8Array(70).fill(0);t[60]=T,t[61]=60,await e(t)})})});
2
+ //# sourceMappingURL=SendPltTask.test.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../../src/internal/app-binder/task/SendPltTask.test.ts"],
4
+ "sourcesContent": ["import {\n APDU_MAX_PAYLOAD,\n type Command,\n CommandResultFactory,\n type InternalApi,\n isSuccessCommandResult,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\nimport { vi } from \"vitest\";\n\nimport {\n type ConcordiumAppCommandError,\n ConcordiumErrorCodes,\n} from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { encodeDerivationPath } from \"@internal/app-binder/command/utils/EncodeDerivationPath\";\nimport { encodeMaxFeeBigEndian } from \"@internal/app-binder/command/utils/EncodeMaxFee\";\nimport { INS, LEDGER_CLA, P1, P2 } from \"@internal/app-binder/constants\";\nimport { SendPltTask } from \"@internal/app-binder/task/SendPltTask\";\n\nconst DERIVATION_PATH = \"44'/919'/0'/0'/0'\";\nconst MAX_FEE = 726_675n;\nconst HEADER = new Uint8Array(60).fill(0x11);\nconst KIND_TOKEN_UPDATE = 0x1b;\nconst SIGNATURE = new Uint8Array(64).fill(0xab);\n\n/**\n * Builds a serialized TokenUpdate transaction:\n * [header:60][kind:1][tokenIdLength:1][tokenId:N][cborTotalLength:4 BE][cbor]\n */\nfunction buildTransaction({\n kind = KIND_TOKEN_UPDATE,\n tokenId = new TextEncoder().encode(\"PLT\"),\n cbor = new Uint8Array([0x81, 0xa1, 0x65, 0x70, 0x61, 0x75, 0x73, 0x65, 0xa0]),\n tokenIdLengthByte,\n declaredCborLength,\n}: {\n kind?: number;\n tokenId?: Uint8Array;\n cbor?: Uint8Array;\n tokenIdLengthByte?: number;\n declaredCborLength?: number;\n} = {}): Uint8Array {\n const declared = declaredCborLength ?? cbor.length;\n const tx = new Uint8Array(60 + 1 + 1 + tokenId.length + 4 + cbor.length);\n tx.set(HEADER, 0);\n tx[60] = kind;\n tx[61] = tokenIdLengthByte ?? tokenId.length;\n tx.set(tokenId, 62);\n const view = new DataView(tx.buffer, tx.byteOffset);\n view.setUint32(62 + tokenId.length, declared, false);\n tx.set(cbor, 62 + tokenId.length + 4);\n return tx;\n}\n\nfunction makeApiMock(responses?: ReturnType<typeof CommandResultFactory>[]) {\n const sentCommands: Command<unknown, unknown>[] = [];\n let call = 0;\n const sendCommand = vi.fn((cmd: Command<unknown, unknown>) => {\n sentCommands.push(cmd);\n const canned = responses?.[call++];\n return Promise.resolve(canned ?? CommandResultFactory({ data: SIGNATURE }));\n });\n return {\n api: { sendCommand } as unknown as InternalApi,\n sentCommands,\n };\n}\n\nfunction makeLogger(): LoggerPublisherService {\n return { debug: vi.fn() } as unknown as LoggerPublisherService;\n}\n\nfunction apduOf(cmd: Command<unknown, unknown>) {\n const raw = cmd.getApdu().getRawApdu();\n return {\n cla: raw[0]!,\n ins: raw[1]!,\n p1: raw[2]!,\n p2: raw[3]!,\n data: raw.slice(5),\n };\n}\n\ndescribe(\"SendPltTask\", () => {\n it(\"should send one INIT frame and one CONT frame for a small payload\", async () => {\n const { api, sentCommands } = makeApiMock();\n const transaction = buildTransaction();\n\n const result = await new SendPltTask(\n api,\n { derivationPath: DERIVATION_PATH, transaction, maxFee: MAX_FEE },\n makeLogger(),\n ).run();\n\n expect(sentCommands).toHaveLength(2);\n expect(isSuccessCommandResult(result)).toBe(true);\n if (isSuccessCommandResult(result)) {\n expect(result.data).toStrictEqual(SIGNATURE);\n }\n });\n\n it(\"should build the INIT frame as path + header + kind + tokenIdLength + tokenId + cborLength\", async () => {\n const { api, sentCommands } = makeApiMock();\n const tokenId = new TextEncoder().encode(\"PLT\");\n const cbor = new Uint8Array(9).fill(0x01);\n const transaction = buildTransaction({ tokenId, cbor });\n\n await new SendPltTask(\n api,\n { derivationPath: DERIVATION_PATH, transaction, maxFee: MAX_FEE },\n makeLogger(),\n ).run();\n\n const init = apduOf(sentCommands[0]!);\n const pathBytes = encodeDerivationPath(DERIVATION_PATH);\n const expected = new Uint8Array([\n ...pathBytes,\n ...HEADER,\n KIND_TOKEN_UPDATE,\n tokenId.length,\n ...tokenId,\n 0x00,\n 0x00,\n 0x00,\n cbor.length,\n ...encodeMaxFeeBigEndian(MAX_FEE),\n ]);\n\n expect(init.cla).toBe(LEDGER_CLA);\n expect(init.ins).toBe(INS.SIGN_PLT);\n expect(init.p1).toBe(P1.PLT_INIT);\n expect(init.data).toStrictEqual(expected);\n });\n\n it(\"should carry P2=0x01 on the INIT frame and end with the 8-byte fee\", async () => {\n const { api, sentCommands } = makeApiMock();\n const transaction = buildTransaction();\n\n await new SendPltTask(\n api,\n { derivationPath: DERIVATION_PATH, transaction, maxFee: MAX_FEE },\n makeLogger(),\n ).run();\n\n const init = apduOf(sentCommands[0]!);\n const pathBytes = encodeDerivationPath(DERIVATION_PATH);\n const tokenIdLength = 3;\n\n expect(init.p2).toBe(P2.FEE_DISPLAY);\n expect(init.data).toHaveLength(\n pathBytes.length + 60 + 1 + 1 + tokenIdLength + 4 + 8,\n );\n expect(init.data.slice(-8)).toStrictEqual(encodeMaxFeeBigEndian(MAX_FEE));\n });\n\n // The device accepts fee display only on INIT; a CONT frame with 0x01 gets 0x6B00.\n it(\"should carry P2=0x00 on every CONT frame\", async () => {\n const { api, sentCommands } = makeApiMock();\n const transaction = buildTransaction({ cbor: new Uint8Array(300) });\n\n await new SendPltTask(\n api,\n { derivationPath: DERIVATION_PATH, transaction, maxFee: MAX_FEE },\n makeLogger(),\n ).run();\n\n const contP2 = sentCommands.slice(1).map((cmd) => apduOf(cmd).p2);\n\n expect(contP2.length).toBeGreaterThan(1);\n expect(contP2.every((p2) => p2 === P2.NONE)).toBe(true);\n });\n\n it(\"should not change the signed bytes when the fee changes\", async () => {\n const run = async (maxFee: bigint) => {\n const { api, sentCommands } = makeApiMock();\n await new SendPltTask(\n api,\n {\n derivationPath: DERIVATION_PATH,\n transaction: buildTransaction(),\n maxFee,\n },\n makeLogger(),\n ).run();\n const init = apduOf(sentCommands[0]!);\n // Everything before the fee suffix is what the device hashes.\n return Buffer.from(init.data.slice(0, -8)).toString(\"hex\");\n };\n\n expect(await run(1n)).toBe(await run(999_999n));\n });\n\n it(\"should send the CBOR payload as CONT frames of at most APDU_MAX_PAYLOAD bytes\", async () => {\n const { api, sentCommands } = makeApiMock();\n const cbor = new Uint8Array(300);\n cbor.forEach((_, i) => (cbor[i] = i & 0xff));\n const transaction = buildTransaction({ cbor });\n\n await new SendPltTask(\n api,\n { derivationPath: DERIVATION_PATH, transaction, maxFee: MAX_FEE },\n makeLogger(),\n ).run();\n\n expect(sentCommands).toHaveLength(3);\n const first = apduOf(sentCommands[1]!);\n const second = apduOf(sentCommands[2]!);\n\n expect(first.p1).toBe(P1.PLT_CONT);\n expect(second.p1).toBe(P1.PLT_CONT);\n expect(first.data).toStrictEqual(cbor.slice(0, APDU_MAX_PAYLOAD));\n expect(second.data).toStrictEqual(cbor.slice(APDU_MAX_PAYLOAD));\n });\n\n it(\"should split a CBOR field across a frame boundary without realigning\", async () => {\n const { api, sentCommands } = makeApiMock();\n // Index 254 is the last byte of the first frame, index 255 the first byte\n // of the second, so these two markers straddle the boundary.\n const cbor = new Uint8Array(260).fill(0x5a);\n cbor[APDU_MAX_PAYLOAD - 1] = 0xf0;\n cbor[APDU_MAX_PAYLOAD] = 0xf1;\n const transaction = buildTransaction({ cbor });\n\n await new SendPltTask(\n api,\n { derivationPath: DERIVATION_PATH, transaction, maxFee: MAX_FEE },\n makeLogger(),\n ).run();\n\n const first = apduOf(sentCommands[1]!);\n const second = apduOf(sentCommands[2]!);\n\n expect(first.data[APDU_MAX_PAYLOAD - 1]).toBe(0xf0);\n expect(second.data[0]).toBe(0xf1);\n });\n\n it(\"should fit a 128-byte token id in the INIT frame\", async () => {\n const { api, sentCommands } = makeApiMock();\n const tokenId = new Uint8Array(128).fill(0x41);\n const transaction = buildTransaction({ tokenId });\n\n const result = await new SendPltTask(\n api,\n {\n derivationPath: \"44'/919'/0'/0'/0'\",\n transaction,\n maxFee: MAX_FEE,\n },\n makeLogger(),\n ).run();\n\n expect(isSuccessCommandResult(result)).toBe(true);\n const init = apduOf(sentCommands[0]!);\n expect(init.data.length).toBeLessThanOrEqual(APDU_MAX_PAYLOAD);\n const pathLength = encodeDerivationPath(\"44'/919'/0'/0'/0'\").length;\n expect(init.data[pathLength + 60 + 1]).toBe(128);\n });\n\n it(\"should propagate an INIT frame failure without sending CONT frames\", async () => {\n const failure = CommandResultFactory({\n error: { errorCode: ConcordiumErrorCodes.PLT_DATA_ERROR },\n } as never);\n const { api, sentCommands } = makeApiMock([failure]);\n\n const result = await new SendPltTask(\n api,\n {\n derivationPath: DERIVATION_PATH,\n transaction: buildTransaction(),\n maxFee: MAX_FEE,\n },\n makeLogger(),\n ).run();\n\n expect(sentCommands).toHaveLength(1);\n expect(isSuccessCommandResult(result)).toBe(false);\n });\n\n it(\"should propagate a CONT frame failure and stop streaming\", async () => {\n const success = CommandResultFactory({ data: new Uint8Array() });\n const failure = CommandResultFactory({\n error: { errorCode: ConcordiumErrorCodes.PLT_CBOR_ERROR },\n } as never);\n const { api, sentCommands } = makeApiMock([success, failure]);\n const cbor = new Uint8Array(300).fill(0x00);\n\n const result = await new SendPltTask(\n api,\n {\n derivationPath: DERIVATION_PATH,\n transaction: buildTransaction({ cbor }),\n maxFee: MAX_FEE,\n },\n makeLogger(),\n ).run();\n\n expect(sentCommands).toHaveLength(2);\n expect(isSuccessCommandResult(result)).toBe(false);\n });\n\n describe(\"device contract parity\", () => {\n // header(60): sender[32] + seqNum[8]=10 + energy[8]=100 + payloadSize[4]\n // + expiry[8]=0x63de5da7.\n const FIXTURE_HEADER = Uint8Array.from(\n Buffer.from(\n \"20a845815bd43a1999e90fbf971537a70392eb38f89e6bd32b3dd70e1a9551d7\" +\n \"000000000000000a\" +\n \"0000000000000064\" +\n \"00000000\" +\n \"0000000063de5da7\",\n \"hex\",\n ),\n );\n // Shortest token id the device accepts: one byte.\n const FIXTURE_TOKEN_ID = new Uint8Array([0x54]);\n // array(1) [ map(1) { \"pause\": map(0) } ]\n const FIXTURE_CBOR = new Uint8Array([\n 0x81, 0xa1, 0x65, 0x70, 0x61, 0x75, 0x73, 0x65, 0xa0,\n ]);\n // Fixture path, without the \"m/\" prefix that encodeDerivationPath rejects.\n const FIXTURE_PATH = \"1105/0/0/0/0/2/0/0\";\n // Expected wire bytes for FIXTURE_PATH, written out literally so that a\n // regression in encodeDerivationPath fails this test rather than being\n // cancelled out by using the same function on both sides.\n //\n // [depth:1 = 8][node:4 BE] x 8, every node hardened.\n const FIXTURE_PATH_BYTES = Uint8Array.from(\n Buffer.from(\n \"08\" +\n \"80000451\" + // 1105'\n \"80000000\" + // 0'\n \"80000000\" + // 0'\n \"80000000\" + // 0'\n \"80000000\" + // 0'\n \"80000002\" + // 2'\n \"80000000\" + // 0'\n \"80000000\", // 0'\n \"hex\",\n ),\n );\n\n function fixtureTransaction(cbor: Uint8Array): Uint8Array {\n const tx = new Uint8Array(60 + 1 + 1 + 1 + 4 + cbor.length);\n tx.set(FIXTURE_HEADER, 0);\n tx[60] = KIND_TOKEN_UPDATE;\n tx[61] = FIXTURE_TOKEN_ID.length;\n tx.set(FIXTURE_TOKEN_ID, 62);\n new DataView(tx.buffer, tx.byteOffset).setUint32(63, cbor.length, false);\n tx.set(cbor, 67);\n return tx;\n }\n\n it(\"should match the INIT frame bytes the firmware fixture sends\", async () => {\n const { api, sentCommands } = makeApiMock();\n\n await new SendPltTask(\n api,\n {\n derivationPath: FIXTURE_PATH,\n transaction: fixtureTransaction(FIXTURE_CBOR),\n maxFee: MAX_FEE,\n },\n makeLogger(),\n ).run();\n\n const init = apduOf(sentCommands[0]!);\n // cborLength is 4 bytes big-endian, then the 8-byte fee suffix.\n const expected = new Uint8Array([\n ...FIXTURE_PATH_BYTES,\n ...FIXTURE_HEADER,\n 0x1b,\n FIXTURE_TOKEN_ID.length,\n ...FIXTURE_TOKEN_ID,\n 0x00,\n 0x00,\n 0x00,\n FIXTURE_CBOR.length,\n ...encodeMaxFeeBigEndian(MAX_FEE),\n ]);\n\n expect(init.p2).toBe(P2.FEE_DISPLAY);\n expect(init.data).toStrictEqual(expected);\n });\n\n it(\"should encode the fixture derivation path as the firmware parses it\", () => {\n expect(encodeDerivationPath(FIXTURE_PATH)).toStrictEqual(\n FIXTURE_PATH_BYTES,\n );\n });\n\n it(\"should split a payload at the 512-byte CBOR maximum as 255 + 255 + 2\", async () => {\n const { api, sentCommands } = makeApiMock();\n const cbor = new Uint8Array(512);\n\n await new SendPltTask(\n api,\n {\n derivationPath: FIXTURE_PATH,\n transaction: fixtureTransaction(cbor),\n maxFee: MAX_FEE,\n },\n makeLogger(),\n ).run();\n\n const contLengths = sentCommands\n .slice(1)\n .map((cmd) => apduOf(cmd).data.length);\n\n expect(contLengths).toStrictEqual([255, 255, 2]);\n });\n\n it(\"should send a 300-byte payload as two CONT frames\", async () => {\n const { api, sentCommands } = makeApiMock();\n const cbor = new Uint8Array(300);\n\n await new SendPltTask(\n api,\n {\n derivationPath: FIXTURE_PATH,\n transaction: fixtureTransaction(cbor),\n maxFee: MAX_FEE,\n },\n makeLogger(),\n ).run();\n\n const contLengths = sentCommands\n .slice(1)\n .map((cmd) => apduOf(cmd).data.length);\n\n expect(contLengths).toStrictEqual([255, 45]);\n });\n });\n\n describe(\"local validation\", () => {\n async function expectRejection(transaction: Uint8Array) {\n const { api, sentCommands } = makeApiMock();\n\n const result = await new SendPltTask(\n api,\n { derivationPath: DERIVATION_PATH, transaction, maxFee: MAX_FEE },\n makeLogger(),\n ).run();\n\n expect(sentCommands).toHaveLength(0);\n expect(isSuccessCommandResult(result)).toBe(false);\n if (!isSuccessCommandResult(result)) {\n expect(\n (result.error as ConcordiumAppCommandError).errorCode,\n ).toStrictEqual(ConcordiumErrorCodes.INVALID_PLT_TRANSACTION);\n }\n return result;\n }\n\n it(\"should reject a transaction shorter than the minimum layout\", async () => {\n await expectRejection(new Uint8Array(66).fill(0x00));\n });\n\n it(\"should reject a transaction kind other than 27\", async () => {\n await expectRejection(buildTransaction({ kind: 22 }));\n });\n\n it(\"should reject a token id length of 0\", async () => {\n await expectRejection(buildTransaction({ tokenIdLengthByte: 0 }));\n });\n\n it(\"should reject a token id length above 128\", async () => {\n await expectRejection(\n buildTransaction({\n tokenId: new Uint8Array(129).fill(0x41),\n }),\n );\n });\n\n it(\"should reject a declared CBOR length of 0\", async () => {\n await expectRejection(buildTransaction({ declaredCborLength: 0 }));\n });\n\n it(\"should reject a declared CBOR length above 512\", async () => {\n await expectRejection(buildTransaction({ declaredCborLength: 513 }));\n });\n\n it(\"should reject a declared CBOR length that disagrees with the payload\", async () => {\n await expectRejection(buildTransaction({ declaredCborLength: 8 }));\n });\n\n it(\"should reject a transaction truncated before the CBOR length field\", async () => {\n // Declares a 60-byte token id but carries only 70 bytes in total, so the\n // length field starts past the end of the buffer.\n const tx = new Uint8Array(70).fill(0x00);\n tx[60] = KIND_TOKEN_UPDATE;\n tx[61] = 60;\n await expectRejection(tx);\n });\n });\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["import_device_management_kit", "import_vitest", "import_ConcordiumApplicationErrors", "import_EncodeDerivationPath", "import_EncodeMaxFee", "import_constants", "import_SendPltTask", "DERIVATION_PATH", "MAX_FEE", "HEADER", "KIND_TOKEN_UPDATE", "SIGNATURE", "buildTransaction", "kind", "tokenId", "cbor", "tokenIdLengthByte", "declaredCborLength", "declared", "tx", "makeApiMock", "responses", "sentCommands", "call", "cmd", "canned", "makeLogger", "apduOf", "raw", "api", "transaction", "result", "init", "pathBytes", "expected", "tokenIdLength", "contP2", "p2", "run", "maxFee", "_", "first", "second", "pathLength", "failure", "success", "FIXTURE_HEADER", "FIXTURE_TOKEN_ID", "FIXTURE_CBOR", "FIXTURE_PATH", "FIXTURE_PATH_BYTES", "fixtureTransaction", "contLengths", "expectRejection"]
7
+ }
@@ -1,2 +1,2 @@
1
- "use strict";var f=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var E=Object.prototype.hasOwnProperty;var F=(e,r)=>{for(var n in r)f(e,n,{get:r[n],enumerable:!0})},_=(e,r,n,o)=>{if(r&&typeof r=="object"||typeof r=="function")for(let t of A(r))!E.call(e,t)&&t!==n&&f(e,t,{get:()=>r[t],enumerable:!(o=y(r,t))||o.enumerable});return e};var h=e=>_(f({},"__esModule",{value:!0}),e);var w={};F(w,{createSignTransactionTask:()=>P});module.exports=h(w);var i=require("@ledgerhq/device-management-kit"),m=require("../../app-binder/command/utils/InvalidMaxFeeError"),u=require("../../app-binder/command/utils/UnsupportedTransactionTypeError"),p=require("../../app-binder/ConcordiumApplicationResolver"),T=require("../../app-binder/task/SendTransferTask"),d=require("../../app-binder/task/SendTransferWithMemoTask"),l=require("../../shared/ConcordiumAppVersions");const s=60,k=3,S=22,I=0xffffffffffffffffn;function P(e,r,n){if(!R(r.maxFee))return()=>Promise.resolve((0,i.CommandResultFactory)({error:new m.InvalidMaxFeeError(r.maxFee)}));const o=C(r.transaction);if(o===void 0){const a=r.transaction.length>s?r.transaction[s]:void 0;return()=>Promise.resolve((0,i.CommandResultFactory)({error:new u.UnsupportedTransactionTypeError(a)}))}const t=v(e),c={...r,supportsFeeDisplay:t};if(o===S){const a=n("SendTransferWithMemoTask");return()=>new d.SendTransferWithMemoTask(e,c,a).run()}const g=n("SendTransferTask");return()=>new T.SendTransferTask(e,c,g).run()}function R(e){return typeof e=="bigint"&&e>=0n&&e<=I}function C(e){if(e.length<=s)return;const r=e[s];if(r===k||r===S)return r}function v(e){try{return new i.ApplicationChecker(e.getDeviceSessionState(),{version:""},new p.ConcordiumApplicationResolver).withMinVersionInclusive(l.MIN_APP_VERSION_FOR_FEE_DISPLAY).check()}catch{return!1}}0&&(module.exports={createSignTransactionTask});
1
+ "use strict";var m=Object.defineProperty;var y=Object.getOwnPropertyDescriptor;var I=Object.getOwnPropertyNames;var R=Object.prototype.hasOwnProperty;var h=(r,e)=>{for(var n in e)m(r,n,{get:e[n],enumerable:!0})},k=(r,e,n,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let t of I(e))!R.call(r,t)&&t!==n&&m(r,t,{get:()=>e[t],enumerable:!(o=y(e,t))||o.enumerable});return r};var F=r=>k(m({},"__esModule",{value:!0}),r);var M={};h(M,{createSignTransactionTask:()=>C});module.exports=F(M);var i=require("@ledgerhq/device-management-kit"),T=require("../../app-binder/command/utils/InvalidMaxFeeError"),p=require("../../app-binder/command/utils/UnsupportedAppVersionError"),d=require("../../app-binder/command/utils/UnsupportedTransactionTypeError"),P=require("../../app-binder/ConcordiumApplicationResolver"),S=require("../../app-binder/task/SendPltTask"),l=require("../../app-binder/task/SendTransferTask"),A=require("../../app-binder/task/SendTransferWithMemoTask"),a=require("../../shared/ConcordiumAppVersions");const f=60,N=3,_=22,E=27,v=0xffffffffffffffffn;function C(r,e,n){if(!w(e.maxFee))return()=>Promise.resolve((0,i.CommandResultFactory)({error:new T.InvalidMaxFeeError(e.maxFee)}));const o=x(e.transaction);if(o===void 0){const s=e.transaction.length>f?e.transaction[f]:void 0;return()=>Promise.resolve((0,i.CommandResultFactory)({error:new d.UnsupportedTransactionTypeError(s)}))}if(o===E){if(!u(r,a.MIN_APP_VERSION_FOR_PLT))return()=>Promise.resolve((0,i.CommandResultFactory)({error:new p.UnsupportedAppVersionError("PLT transactions",a.MIN_APP_VERSION_FOR_PLT)}));const s=n("SendPltTask");return()=>new S.SendPltTask(r,{derivationPath:e.derivationPath,transaction:e.transaction,maxFee:e.maxFee},s).run()}const t=u(r,a.MIN_APP_VERSION_FOR_FEE_DISPLAY),c={...e,supportsFeeDisplay:t};if(o===_){const s=n("SendTransferWithMemoTask");return()=>new A.SendTransferWithMemoTask(r,c,s).run()}const g=n("SendTransferTask");return()=>new l.SendTransferTask(r,c,g).run()}function w(r){return typeof r=="bigint"&&r>=0n&&r<=v}function x(r){if(r.length<=f)return;const e=r[f];if(e===N||e===_||e===E)return e}function u(r,e){try{return new i.ApplicationChecker(r.getDeviceSessionState(),{version:""},new P.ConcordiumApplicationResolver).withMinVersionInclusive(e).check()}catch{return!1}}0&&(module.exports={createSignTransactionTask});
2
2
  //# sourceMappingURL=SignTransactionTaskFactory.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/internal/app-binder/task/SignTransactionTaskFactory.ts"],
4
- "sourcesContent": ["import {\n ApplicationChecker,\n type CommandResult,\n CommandResultFactory,\n type InternalApi,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type Signature } from \"@api/model/Signature\";\nimport { type ConcordiumErrorCodes } from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { InvalidMaxFeeError } from \"@internal/app-binder/command/utils/InvalidMaxFeeError\";\nimport { UnsupportedTransactionTypeError } from \"@internal/app-binder/command/utils/UnsupportedTransactionTypeError\";\nimport { ConcordiumApplicationResolver } from \"@internal/app-binder/ConcordiumApplicationResolver\";\nimport { SendTransferTask } from \"@internal/app-binder/task/SendTransferTask\";\nimport { SendTransferWithMemoTask } from \"@internal/app-binder/task/SendTransferWithMemoTask\";\nimport { MIN_APP_VERSION_FOR_FEE_DISPLAY } from \"@internal/shared/ConcordiumAppVersions\";\n\nconst TYPE_OFFSET = 60;\nconst TRANSACTION_TYPE_TRANSFER = 3;\nconst TRANSACTION_TYPE_TRANSFER_WITH_MEMO = 22;\nconst UINT64_MAX = 0xffffffffffffffffn;\n\ntype TaskArgs = {\n derivationPath: string;\n transaction: Uint8Array;\n maxFee: bigint;\n};\n\nexport function createSignTransactionTask(\n internalApi: InternalApi,\n args: TaskArgs,\n loggerFactory: (tag: string) => LoggerPublisherService,\n): () => Promise<CommandResult<Signature, ConcordiumErrorCodes>> {\n if (!isValidMaxFee(args.maxFee)) {\n return () =>\n Promise.resolve(\n CommandResultFactory({\n error: new InvalidMaxFeeError(args.maxFee),\n }),\n );\n }\n\n const txType = getTransactionType(args.transaction);\n\n if (txType === undefined) {\n const rawType =\n args.transaction.length > TYPE_OFFSET\n ? args.transaction[TYPE_OFFSET]\n : undefined;\n return () =>\n Promise.resolve(\n CommandResultFactory({\n error: new UnsupportedTransactionTypeError(rawType),\n }),\n );\n }\n\n const supportsFeeDisplay = checkFeeDisplaySupport(internalApi);\n const taskArgs = { ...args, supportsFeeDisplay };\n\n if (txType === TRANSACTION_TYPE_TRANSFER_WITH_MEMO) {\n const logger = loggerFactory(\"SendTransferWithMemoTask\");\n return () =>\n new SendTransferWithMemoTask(internalApi, taskArgs, logger).run();\n }\n\n const logger = loggerFactory(\"SendTransferTask\");\n return () => new SendTransferTask(internalApi, taskArgs, logger).run();\n}\n\nfunction isValidMaxFee(value: unknown): value is bigint {\n return typeof value === \"bigint\" && value >= 0n && value <= UINT64_MAX;\n}\n\nfunction getTransactionType(transaction: Uint8Array): number | undefined {\n if (transaction.length <= TYPE_OFFSET) {\n return undefined;\n }\n const type = transaction[TYPE_OFFSET];\n if (\n type === TRANSACTION_TYPE_TRANSFER ||\n type === TRANSACTION_TYPE_TRANSFER_WITH_MEMO\n ) {\n return type;\n }\n return undefined;\n}\n\nfunction checkFeeDisplaySupport(internalApi: InternalApi): boolean {\n try {\n return new ApplicationChecker(\n internalApi.getDeviceSessionState(),\n { version: \"\" },\n new ConcordiumApplicationResolver(),\n )\n .withMinVersionInclusive(MIN_APP_VERSION_FOR_FEE_DISPLAY)\n .check();\n } catch {\n return false;\n }\n}\n"],
5
- "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,+BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAMO,2CAIPC,EAAmC,iEACnCC,EAAgD,8EAChDC,EAA8C,8DAC9CC,EAAiC,sDACjCC,EAAyC,8DACzCC,EAAgD,kDAEhD,MAAMC,EAAc,GACdC,EAA4B,EAC5BC,EAAsC,GACtCC,EAAa,oBAQZ,SAASZ,EACda,EACAC,EACAC,EAC+D,CAC/D,GAAI,CAACC,EAAcF,EAAK,MAAM,EAC5B,MAAO,IACL,QAAQ,WACN,wBAAqB,CACnB,MAAO,IAAI,qBAAmBA,EAAK,MAAM,CAC3C,CAAC,CACH,EAGJ,MAAMG,EAASC,EAAmBJ,EAAK,WAAW,EAElD,GAAIG,IAAW,OAAW,CACxB,MAAME,EACJL,EAAK,YAAY,OAASL,EACtBK,EAAK,YAAYL,CAAW,EAC5B,OACN,MAAO,IACL,QAAQ,WACN,wBAAqB,CACnB,MAAO,IAAI,kCAAgCU,CAAO,CACpD,CAAC,CACH,CACJ,CAEA,MAAMC,EAAqBC,EAAuBR,CAAW,EACvDS,EAAW,CAAE,GAAGR,EAAM,mBAAAM,CAAmB,EAE/C,GAAIH,IAAWN,EAAqC,CAClD,MAAMY,EAASR,EAAc,0BAA0B,EACvD,MAAO,IACL,IAAI,2BAAyBF,EAAaS,EAAUC,CAAM,EAAE,IAAI,CACpE,CAEA,MAAMA,EAASR,EAAc,kBAAkB,EAC/C,MAAO,IAAM,IAAI,mBAAiBF,EAAaS,EAAUC,CAAM,EAAE,IAAI,CACvE,CAEA,SAASP,EAAcQ,EAAiC,CACtD,OAAO,OAAOA,GAAU,UAAYA,GAAS,IAAMA,GAASZ,CAC9D,CAEA,SAASM,EAAmBO,EAA6C,CACvE,GAAIA,EAAY,QAAUhB,EACxB,OAEF,MAAMiB,EAAOD,EAAYhB,CAAW,EACpC,GACEiB,IAAShB,GACTgB,IAASf,EAET,OAAOe,CAGX,CAEA,SAASL,EAAuBR,EAAmC,CACjE,GAAI,CACF,OAAO,IAAI,qBACTA,EAAY,sBAAsB,EAClC,CAAE,QAAS,EAAG,EACd,IAAI,+BACN,EACG,wBAAwB,iCAA+B,EACvD,MAAM,CACX,MAAQ,CACN,MAAO,EACT,CACF",
6
- "names": ["SignTransactionTaskFactory_exports", "__export", "createSignTransactionTask", "__toCommonJS", "import_device_management_kit", "import_InvalidMaxFeeError", "import_UnsupportedTransactionTypeError", "import_ConcordiumApplicationResolver", "import_SendTransferTask", "import_SendTransferWithMemoTask", "import_ConcordiumAppVersions", "TYPE_OFFSET", "TRANSACTION_TYPE_TRANSFER", "TRANSACTION_TYPE_TRANSFER_WITH_MEMO", "UINT64_MAX", "internalApi", "args", "loggerFactory", "isValidMaxFee", "txType", "getTransactionType", "rawType", "supportsFeeDisplay", "checkFeeDisplaySupport", "taskArgs", "logger", "value", "transaction", "type"]
4
+ "sourcesContent": ["import {\n ApplicationChecker,\n type CommandResult,\n CommandResultFactory,\n type InternalApi,\n type LoggerPublisherService,\n} from \"@ledgerhq/device-management-kit\";\n\nimport { type Signature } from \"@api/model/Signature\";\nimport { type ConcordiumErrorCodes } from \"@internal/app-binder/command/utils/ConcordiumApplicationErrors\";\nimport { InvalidMaxFeeError } from \"@internal/app-binder/command/utils/InvalidMaxFeeError\";\nimport { UnsupportedAppVersionError } from \"@internal/app-binder/command/utils/UnsupportedAppVersionError\";\nimport { UnsupportedTransactionTypeError } from \"@internal/app-binder/command/utils/UnsupportedTransactionTypeError\";\nimport { ConcordiumApplicationResolver } from \"@internal/app-binder/ConcordiumApplicationResolver\";\nimport { SendPltTask } from \"@internal/app-binder/task/SendPltTask\";\nimport { SendTransferTask } from \"@internal/app-binder/task/SendTransferTask\";\nimport { SendTransferWithMemoTask } from \"@internal/app-binder/task/SendTransferWithMemoTask\";\nimport {\n MIN_APP_VERSION_FOR_FEE_DISPLAY,\n MIN_APP_VERSION_FOR_PLT,\n} from \"@internal/shared/ConcordiumAppVersions\";\n\nconst TYPE_OFFSET = 60;\nconst TRANSACTION_TYPE_TRANSFER = 3;\nconst TRANSACTION_TYPE_TRANSFER_WITH_MEMO = 22;\nconst TRANSACTION_TYPE_PLT = 0x1b;\nconst UINT64_MAX = 0xffffffffffffffffn;\n\ntype TaskArgs = {\n derivationPath: string;\n transaction: Uint8Array;\n maxFee: bigint;\n};\n\nexport function createSignTransactionTask(\n internalApi: InternalApi,\n args: TaskArgs,\n loggerFactory: (tag: string) => LoggerPublisherService,\n): () => Promise<CommandResult<Signature, ConcordiumErrorCodes>> {\n if (!isValidMaxFee(args.maxFee)) {\n return () =>\n Promise.resolve(\n CommandResultFactory({\n error: new InvalidMaxFeeError(args.maxFee),\n }),\n );\n }\n\n const txType = getTransactionType(args.transaction);\n\n if (txType === undefined) {\n const rawType =\n args.transaction.length > TYPE_OFFSET\n ? args.transaction[TYPE_OFFSET]\n : undefined;\n return () =>\n Promise.resolve(\n CommandResultFactory({\n error: new UnsupportedTransactionTypeError(rawType),\n }),\n );\n }\n\n if (txType === TRANSACTION_TYPE_PLT) {\n if (!checkMinVersion(internalApi, MIN_APP_VERSION_FOR_PLT)) {\n return () =>\n Promise.resolve(\n CommandResultFactory({\n error: new UnsupportedAppVersionError(\n \"PLT transactions\",\n MIN_APP_VERSION_FOR_PLT,\n ),\n }),\n );\n }\n\n const logger = loggerFactory(\"SendPltTask\");\n return () =>\n new SendPltTask(\n internalApi,\n {\n derivationPath: args.derivationPath,\n transaction: args.transaction,\n maxFee: args.maxFee,\n },\n logger,\n ).run();\n }\n\n const supportsFeeDisplay = checkMinVersion(\n internalApi,\n MIN_APP_VERSION_FOR_FEE_DISPLAY,\n );\n const taskArgs = { ...args, supportsFeeDisplay };\n\n if (txType === TRANSACTION_TYPE_TRANSFER_WITH_MEMO) {\n const logger = loggerFactory(\"SendTransferWithMemoTask\");\n return () =>\n new SendTransferWithMemoTask(internalApi, taskArgs, logger).run();\n }\n\n const logger = loggerFactory(\"SendTransferTask\");\n return () => new SendTransferTask(internalApi, taskArgs, logger).run();\n}\n\nfunction isValidMaxFee(value: unknown): value is bigint {\n return typeof value === \"bigint\" && value >= 0n && value <= UINT64_MAX;\n}\n\nfunction getTransactionType(transaction: Uint8Array): number | undefined {\n if (transaction.length <= TYPE_OFFSET) {\n return undefined;\n }\n const type = transaction[TYPE_OFFSET];\n if (\n type === TRANSACTION_TYPE_TRANSFER ||\n type === TRANSACTION_TYPE_TRANSFER_WITH_MEMO ||\n type === TRANSACTION_TYPE_PLT\n ) {\n return type;\n }\n return undefined;\n}\n\nfunction checkMinVersion(\n internalApi: InternalApi,\n minVersion: string,\n): boolean {\n try {\n return new ApplicationChecker(\n internalApi.getDeviceSessionState(),\n { version: \"\" },\n new ConcordiumApplicationResolver(),\n )\n .withMinVersionInclusive(minVersion)\n .check();\n } catch {\n return false;\n }\n}\n"],
5
+ "mappings": "yaAAA,IAAAA,EAAA,GAAAC,EAAAD,EAAA,+BAAAE,IAAA,eAAAC,EAAAH,GAAA,IAAAI,EAMO,2CAIPC,EAAmC,iEACnCC,EAA2C,yEAC3CC,EAAgD,8EAChDC,EAA8C,8DAC9CC,EAA4B,iDAC5BC,EAAiC,sDACjCC,EAAyC,8DACzCC,EAGO,kDAEP,MAAMC,EAAc,GACdC,EAA4B,EAC5BC,EAAsC,GACtCC,EAAuB,GACvBC,EAAa,oBAQZ,SAASf,EACdgB,EACAC,EACAC,EAC+D,CAC/D,GAAI,CAACC,EAAcF,EAAK,MAAM,EAC5B,MAAO,IACL,QAAQ,WACN,wBAAqB,CACnB,MAAO,IAAI,qBAAmBA,EAAK,MAAM,CAC3C,CAAC,CACH,EAGJ,MAAMG,EAASC,EAAmBJ,EAAK,WAAW,EAElD,GAAIG,IAAW,OAAW,CACxB,MAAME,EACJL,EAAK,YAAY,OAASN,EACtBM,EAAK,YAAYN,CAAW,EAC5B,OACN,MAAO,IACL,QAAQ,WACN,wBAAqB,CACnB,MAAO,IAAI,kCAAgCW,CAAO,CACpD,CAAC,CACH,CACJ,CAEA,GAAIF,IAAWN,EAAsB,CACnC,GAAI,CAACS,EAAgBP,EAAa,yBAAuB,EACvD,MAAO,IACL,QAAQ,WACN,wBAAqB,CACnB,MAAO,IAAI,6BACT,mBACA,yBACF,CACF,CAAC,CACH,EAGJ,MAAMQ,EAASN,EAAc,aAAa,EAC1C,MAAO,IACL,IAAI,cACFF,EACA,CACE,eAAgBC,EAAK,eACrB,YAAaA,EAAK,YAClB,OAAQA,EAAK,MACf,EACAO,CACF,EAAE,IAAI,CACV,CAEA,MAAMC,EAAqBF,EACzBP,EACA,iCACF,EACMU,EAAW,CAAE,GAAGT,EAAM,mBAAAQ,CAAmB,EAE/C,GAAIL,IAAWP,EAAqC,CAClD,MAAMW,EAASN,EAAc,0BAA0B,EACvD,MAAO,IACL,IAAI,2BAAyBF,EAAaU,EAAUF,CAAM,EAAE,IAAI,CACpE,CAEA,MAAMA,EAASN,EAAc,kBAAkB,EAC/C,MAAO,IAAM,IAAI,mBAAiBF,EAAaU,EAAUF,CAAM,EAAE,IAAI,CACvE,CAEA,SAASL,EAAcQ,EAAiC,CACtD,OAAO,OAAOA,GAAU,UAAYA,GAAS,IAAMA,GAASZ,CAC9D,CAEA,SAASM,EAAmBO,EAA6C,CACvE,GAAIA,EAAY,QAAUjB,EACxB,OAEF,MAAMkB,EAAOD,EAAYjB,CAAW,EACpC,GACEkB,IAASjB,GACTiB,IAAShB,GACTgB,IAASf,EAET,OAAOe,CAGX,CAEA,SAASN,EACPP,EACAc,EACS,CACT,GAAI,CACF,OAAO,IAAI,qBACTd,EAAY,sBAAsB,EAClC,CAAE,QAAS,EAAG,EACd,IAAI,+BACN,EACG,wBAAwBc,CAAU,EAClC,MAAM,CACX,MAAQ,CACN,MAAO,EACT,CACF",
6
+ "names": ["SignTransactionTaskFactory_exports", "__export", "createSignTransactionTask", "__toCommonJS", "import_device_management_kit", "import_InvalidMaxFeeError", "import_UnsupportedAppVersionError", "import_UnsupportedTransactionTypeError", "import_ConcordiumApplicationResolver", "import_SendPltTask", "import_SendTransferTask", "import_SendTransferWithMemoTask", "import_ConcordiumAppVersions", "TYPE_OFFSET", "TRANSACTION_TYPE_TRANSFER", "TRANSACTION_TYPE_TRANSFER_WITH_MEMO", "TRANSACTION_TYPE_PLT", "UINT64_MAX", "internalApi", "args", "loggerFactory", "isValidMaxFee", "txType", "getTransactionType", "rawType", "checkMinVersion", "logger", "supportsFeeDisplay", "taskArgs", "value", "transaction", "type", "minVersion"]
7
7
  }
@@ -1,2 +1,2 @@
1
- "use strict";var a=require("@ledgerhq/device-management-kit"),v=require("vitest"),f=require("../../app-binder/command/utils/InvalidMaxFeeError"),l=require("../../app-binder/command/utils/UnsupportedTransactionTypeError"),i=require("../../app-binder/task/SignTransactionTaskFactory");const c="44'/919'/0'/0'/0'",h=60;function d(o){const u=new Uint8Array(101).fill(0);return u[h]=o,u}function m(o){return{sessionStateType:a.DeviceSessionStateType.ReadyWithoutSecureChannel,deviceModelId:a.DeviceModelId.NANO_X,currentApp:{name:"Concordium",version:o}}}function p(o){const u=[];return{api:{sendCommand:v.vi.fn().mockImplementation(t=>(u.push(t),Promise.resolve((0,a.CommandResultFactory)({data:new Uint8Array(64).fill(171)})))),getDeviceSessionState:()=>o},sentCommands:u}}function x(o){return o.getApdu().getRawApdu()[3]}describe("createSignTransactionTask",()=>{let o,u;beforeEach(()=>{u=[],o=s=>(u.push(s),{debug:v.vi.fn()})}),it("should create SendTransferTask for Transfer type (3)",()=>{const{api:s}=p(m("5.6.0")),e=d(3);(0,i.createSignTransactionTask)(s,{derivationPath:c,transaction:e,maxFee:0n},o),expect(u).toContain("SendTransferTask")}),it("should create SendTransferWithMemoTask for TransferWithMemo type (22)",()=>{const{api:s}=p(m("5.6.0")),e=d(22);(0,i.createSignTransactionTask)(s,{derivationPath:c,transaction:e,maxFee:0n},o),expect(u).toContain("SendTransferWithMemoTask")}),it("should return error for unsupported transaction type",async()=>{const{api:s}=p(m("5.6.0")),e=d(99),n=await(0,i.createSignTransactionTask)(s,{derivationPath:c,transaction:e,maxFee:0n},o)();if(expect((0,a.isSuccessCommandResult)(n)).toBe(!1),!(0,a.isSuccessCommandResult)(n)){expect(n.error).toBeInstanceOf(l.UnsupportedTransactionTypeError);const r=n.error;expect(r.message).toContain("99")}}),it("should return error for transaction too short to read type",async()=>{const{api:s}=p(m("5.6.0")),e=new Uint8Array(10),n=await(0,i.createSignTransactionTask)(s,{derivationPath:c,transaction:e,maxFee:0n},o)();if(expect((0,a.isSuccessCommandResult)(n)).toBe(!1),!(0,a.isSuccessCommandResult)(n)){expect(n.error).toBeInstanceOf(l.UnsupportedTransactionTypeError);const r=n.error;expect(r.message).toContain("too short")}}),it("should return error for transaction exactly at type offset boundary",async()=>{const{api:s}=p(m("5.6.0")),e=new Uint8Array(h),n=await(0,i.createSignTransactionTask)(s,{derivationPath:c,transaction:e,maxFee:0n},o)();expect((0,a.isSuccessCommandResult)(n)).toBe(!1),(0,a.isSuccessCommandResult)(n)||expect(n.error).toBeInstanceOf(l.UnsupportedTransactionTypeError)}),describe("fee-display capability detection",()=>{it("forwards supportsFeeDisplay=true when device app version >= 5.6.0 (Transfer)",async()=>{const{api:s,sentCommands:e}=p(m("5.6.0")),t=d(3);await(0,i.createSignTransactionTask)(s,{derivationPath:c,transaction:t,maxFee:1000n},o)(),expect(e).toHaveLength(1),expect(x(e[0])).toBe(1)}),it("forwards supportsFeeDisplay=false when device app version < 5.6.0 (Transfer)",async()=>{const{api:s,sentCommands:e}=p(m("5.5.9")),t=d(3);await(0,i.createSignTransactionTask)(s,{derivationPath:c,transaction:t,maxFee:1000n},o)(),expect(e).toHaveLength(1),expect(x(e[0])).toBe(0)}),it("falls back to legacy when device session has no active Concordium app",async()=>{const{api:s,sentCommands:e}=p({sessionStateType:a.DeviceSessionStateType.Connected,deviceModelId:a.DeviceModelId.NANO_X}),t=d(3);await(0,i.createSignTransactionTask)(s,{derivationPath:c,transaction:t,maxFee:1000n},o)(),expect(e).toHaveLength(1),expect(x(e[0])).toBe(0)}),it("forwards supportsFeeDisplay=true on initial step for TransferWithMemo when version >= 5.6.0",async()=>{const{api:s,sentCommands:e}=p(m("5.6.0")),t=new Uint8Array(103);t[h]=22,await(0,i.createSignTransactionTask)(s,{derivationPath:c,transaction:t,maxFee:1000n},o)(),expect(e.length).toBeGreaterThanOrEqual(1),expect(x(e[0])).toBe(1)})}),describe("maxFee validation",()=>{const s=0xffffffffffffffffn;it("rejects negative maxFee with InvalidMaxFeeError on supported firmware",async()=>{const{api:e,sentCommands:t}=p(m("5.6.0")),n=d(3),r=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:n,maxFee:-1n},o)();expect(t).toHaveLength(0),expect((0,a.isSuccessCommandResult)(r)).toBe(!1),(0,a.isSuccessCommandResult)(r)||expect(r.error).toBeInstanceOf(f.InvalidMaxFeeError)}),it("rejects negative maxFee with InvalidMaxFeeError on legacy firmware",async()=>{const{api:e,sentCommands:t}=p(m("5.5.9")),n=d(3),r=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:n,maxFee:-1n},o)();expect(t).toHaveLength(0),expect((0,a.isSuccessCommandResult)(r)).toBe(!1),(0,a.isSuccessCommandResult)(r)||expect(r.error).toBeInstanceOf(f.InvalidMaxFeeError)}),it("rejects maxFee above uint64 range",async()=>{const{api:e,sentCommands:t}=p(m("5.6.0")),n=d(3),r=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:n,maxFee:s+1n},o)();expect(t).toHaveLength(0),expect((0,a.isSuccessCommandResult)(r)).toBe(!1),(0,a.isSuccessCommandResult)(r)||expect(r.error).toBeInstanceOf(f.InvalidMaxFeeError)}),it("rejects non-bigint maxFee (defends against untyped JS callers)",async()=>{const{api:e,sentCommands:t}=p(m("5.6.0")),n=d(3),r=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:n,maxFee:{skipOpenApp:!0}},o)();expect(t).toHaveLength(0),expect((0,a.isSuccessCommandResult)(r)).toBe(!1),(0,a.isSuccessCommandResult)(r)||expect(r.error).toBeInstanceOf(f.InvalidMaxFeeError)}),it("accepts maxFee = 0n as a valid uint64 value",async()=>{const{api:e,sentCommands:t}=p(m("5.6.0")),n=d(3),r=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:n,maxFee:0n},o)();expect(t).toHaveLength(1),expect((0,a.isSuccessCommandResult)(r)).toBe(!0)}),it("accepts maxFee at uint64 max boundary",async()=>{const{api:e,sentCommands:t}=p(m("5.6.0")),n=d(3),r=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:n,maxFee:s},o)();expect(t).toHaveLength(1),expect((0,a.isSuccessCommandResult)(r)).toBe(!0)})})});
1
+ "use strict";var o=require("@ledgerhq/device-management-kit"),g=require("vitest"),f=require("../../app-binder/command/utils/InvalidMaxFeeError"),y=require("../../app-binder/command/utils/UnsupportedAppVersionError"),l=require("../../app-binder/command/utils/UnsupportedTransactionTypeError"),i=require("../../app-binder/task/SignTransactionTaskFactory"),h=require("../../shared/ConcordiumAppVersions");const c="44'/919'/0'/0'/0'",v=60;function m(a){const u=new Uint8Array(101).fill(0);return u[v]=a,u}function d(a){return{sessionStateType:o.DeviceSessionStateType.ReadyWithoutSecureChannel,deviceModelId:o.DeviceModelId.NANO_X,currentApp:{name:"Concordium",version:a}}}function p(a){const u=[];return{api:{sendCommand:g.vi.fn().mockImplementation(n=>(u.push(n),Promise.resolve((0,o.CommandResultFactory)({data:new Uint8Array(64).fill(171)})))),getDeviceSessionState:()=>a},sentCommands:u}}function x(a){return a.getApdu().getRawApdu()[3]}function w(a){return a.getApdu().getRawApdu().slice(5)}describe("createSignTransactionTask",()=>{let a,u;beforeEach(()=>{u=[],a=r=>(u.push(r),{debug:g.vi.fn()})}),it("should create SendTransferTask for Transfer type (3)",()=>{const{api:r}=p(d("5.6.0")),e=m(3);(0,i.createSignTransactionTask)(r,{derivationPath:c,transaction:e,maxFee:0n},a),expect(u).toContain("SendTransferTask")}),it("should create SendTransferWithMemoTask for TransferWithMemo type (22)",()=>{const{api:r}=p(d("5.6.0")),e=m(22);(0,i.createSignTransactionTask)(r,{derivationPath:c,transaction:e,maxFee:0n},a),expect(u).toContain("SendTransferWithMemoTask")}),describe("PLT dispatch",()=>{function r(){const e=new Uint8Array([129,161,101,112,97,117,115,101,160]),n=new TextEncoder().encode("PLT"),t=new Uint8Array(62+n.length+4+e.length);return t[v]=27,t[61]=n.length,t.set(n,62),new DataView(t.buffer,t.byteOffset).setUint32(62+n.length,e.length,!1),t.set(e,62+n.length+4),t}it("should create SendPltTask for TokenUpdate type (0x1B)",()=>{const{api:e}=p(d(h.MIN_APP_VERSION_FOR_PLT));(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:r(),maxFee:0n},a),expect(u).toContain("SendPltTask")}),it("should send P2=0x01 on the PLT INIT frame at the minimum PLT version",async()=>{const{api:e,sentCommands:n}=p(d(h.MIN_APP_VERSION_FOR_PLT));await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:r(),maxFee:1000n},a)(),expect(n.length).toBeGreaterThanOrEqual(1),expect(x(n[0])).toBe(1)}),it("should forward maxFee to the PLT task as an 8-byte big-endian suffix",async()=>{const{api:e,sentCommands:n}=p(d(h.MIN_APP_VERSION_FOR_PLT));await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:r(),maxFee:726675n},a)();const t=w(n[0]);expect(Buffer.from(t.slice(-8)).toString("hex")).toBe("00000000000b1693")}),it("should reject PLT with UnsupportedAppVersionError on an older app",async()=>{const{api:e,sentCommands:n}=p(d("5.6.0")),t=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:r(),maxFee:0n},a)();expect(n).toHaveLength(0),expect((0,o.isSuccessCommandResult)(t)).toBe(!1),(0,o.isSuccessCommandResult)(t)||(expect(t.error).toBeInstanceOf(y.UnsupportedAppVersionError),expect(t.error).not.toBeInstanceOf(l.UnsupportedTransactionTypeError),expect(t.error.message).toContain(h.MIN_APP_VERSION_FOR_PLT))}),it("should reject PLT when the session has no active Concordium app",async()=>{const{api:e,sentCommands:n}=p({sessionStateType:o.DeviceSessionStateType.Connected,deviceModelId:o.DeviceModelId.NANO_X}),t=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:r(),maxFee:0n},a)();expect(n).toHaveLength(0),expect((0,o.isSuccessCommandResult)(t)).toBe(!1),(0,o.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(y.UnsupportedAppVersionError)})}),it("should return error for unsupported transaction type",async()=>{const{api:r}=p(d("5.6.0")),e=m(99),t=await(0,i.createSignTransactionTask)(r,{derivationPath:c,transaction:e,maxFee:0n},a)();if(expect((0,o.isSuccessCommandResult)(t)).toBe(!1),!(0,o.isSuccessCommandResult)(t)){expect(t.error).toBeInstanceOf(l.UnsupportedTransactionTypeError);const s=t.error;expect(s.message).toContain("99")}}),it("should return error for transaction too short to read type",async()=>{const{api:r}=p(d("5.6.0")),e=new Uint8Array(10),t=await(0,i.createSignTransactionTask)(r,{derivationPath:c,transaction:e,maxFee:0n},a)();if(expect((0,o.isSuccessCommandResult)(t)).toBe(!1),!(0,o.isSuccessCommandResult)(t)){expect(t.error).toBeInstanceOf(l.UnsupportedTransactionTypeError);const s=t.error;expect(s.message).toContain("too short")}}),it("should return error for transaction exactly at type offset boundary",async()=>{const{api:r}=p(d("5.6.0")),e=new Uint8Array(v),t=await(0,i.createSignTransactionTask)(r,{derivationPath:c,transaction:e,maxFee:0n},a)();expect((0,o.isSuccessCommandResult)(t)).toBe(!1),(0,o.isSuccessCommandResult)(t)||expect(t.error).toBeInstanceOf(l.UnsupportedTransactionTypeError)}),describe("fee-display capability detection",()=>{it("forwards supportsFeeDisplay=true when device app version >= 5.6.0 (Transfer)",async()=>{const{api:r,sentCommands:e}=p(d("5.6.0")),n=m(3);await(0,i.createSignTransactionTask)(r,{derivationPath:c,transaction:n,maxFee:1000n},a)(),expect(e).toHaveLength(1),expect(x(e[0])).toBe(1)}),it("forwards supportsFeeDisplay=false when device app version < 5.6.0 (Transfer)",async()=>{const{api:r,sentCommands:e}=p(d("5.5.9")),n=m(3);await(0,i.createSignTransactionTask)(r,{derivationPath:c,transaction:n,maxFee:1000n},a)(),expect(e).toHaveLength(1),expect(x(e[0])).toBe(0)}),it("falls back to legacy when device session has no active Concordium app",async()=>{const{api:r,sentCommands:e}=p({sessionStateType:o.DeviceSessionStateType.Connected,deviceModelId:o.DeviceModelId.NANO_X}),n=m(3);await(0,i.createSignTransactionTask)(r,{derivationPath:c,transaction:n,maxFee:1000n},a)(),expect(e).toHaveLength(1),expect(x(e[0])).toBe(0)}),it("forwards supportsFeeDisplay=true on initial step for TransferWithMemo when version >= 5.6.0",async()=>{const{api:r,sentCommands:e}=p(d("5.6.0")),n=new Uint8Array(103);n[v]=22,await(0,i.createSignTransactionTask)(r,{derivationPath:c,transaction:n,maxFee:1000n},a)(),expect(e.length).toBeGreaterThanOrEqual(1),expect(x(e[0])).toBe(1)})}),describe("maxFee validation",()=>{const r=0xffffffffffffffffn;it("rejects negative maxFee with InvalidMaxFeeError on supported firmware",async()=>{const{api:e,sentCommands:n}=p(d("5.6.0")),t=m(3),s=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:t,maxFee:-1n},a)();expect(n).toHaveLength(0),expect((0,o.isSuccessCommandResult)(s)).toBe(!1),(0,o.isSuccessCommandResult)(s)||expect(s.error).toBeInstanceOf(f.InvalidMaxFeeError)}),it("rejects negative maxFee with InvalidMaxFeeError on legacy firmware",async()=>{const{api:e,sentCommands:n}=p(d("5.5.9")),t=m(3),s=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:t,maxFee:-1n},a)();expect(n).toHaveLength(0),expect((0,o.isSuccessCommandResult)(s)).toBe(!1),(0,o.isSuccessCommandResult)(s)||expect(s.error).toBeInstanceOf(f.InvalidMaxFeeError)}),it("rejects maxFee above uint64 range",async()=>{const{api:e,sentCommands:n}=p(d("5.6.0")),t=m(3),s=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:t,maxFee:r+1n},a)();expect(n).toHaveLength(0),expect((0,o.isSuccessCommandResult)(s)).toBe(!1),(0,o.isSuccessCommandResult)(s)||expect(s.error).toBeInstanceOf(f.InvalidMaxFeeError)}),it("rejects non-bigint maxFee (defends against untyped JS callers)",async()=>{const{api:e,sentCommands:n}=p(d("5.6.0")),t=m(3),s=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:t,maxFee:{skipOpenApp:!0}},a)();expect(n).toHaveLength(0),expect((0,o.isSuccessCommandResult)(s)).toBe(!1),(0,o.isSuccessCommandResult)(s)||expect(s.error).toBeInstanceOf(f.InvalidMaxFeeError)}),it("accepts maxFee = 0n as a valid uint64 value",async()=>{const{api:e,sentCommands:n}=p(d("5.6.0")),t=m(3),s=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:t,maxFee:0n},a)();expect(n).toHaveLength(1),expect((0,o.isSuccessCommandResult)(s)).toBe(!0)}),it("accepts maxFee at uint64 max boundary",async()=>{const{api:e,sentCommands:n}=p(d("5.6.0")),t=m(3),s=await(0,i.createSignTransactionTask)(e,{derivationPath:c,transaction:t,maxFee:r},a)();expect(n).toHaveLength(1),expect((0,o.isSuccessCommandResult)(s)).toBe(!0)})})});
2
2
  //# sourceMappingURL=SignTransactionTaskFactory.test.js.map