@ledgerhq/concordium-core 0.2.0-nightly.20260220030210

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 (67) hide show
  1. package/.turbo/turbo-build.log +4 -0
  2. package/.unimportedrc.json +14 -0
  3. package/CHANGELOG.md +7 -0
  4. package/LICENSE.txt +21 -0
  5. package/README.md +74 -0
  6. package/jest.config.js +37 -0
  7. package/lib/address.d.ts +73 -0
  8. package/lib/address.d.ts.map +1 -0
  9. package/lib/address.js +113 -0
  10. package/lib/address.js.map +1 -0
  11. package/lib/cbor.d.ts +73 -0
  12. package/lib/cbor.d.ts.map +1 -0
  13. package/lib/cbor.js +144 -0
  14. package/lib/cbor.js.map +1 -0
  15. package/lib/index.d.ts +6 -0
  16. package/lib/index.d.ts.map +1 -0
  17. package/lib/index.js +22 -0
  18. package/lib/index.js.map +1 -0
  19. package/lib/serialization.d.ts +153 -0
  20. package/lib/serialization.d.ts.map +1 -0
  21. package/lib/serialization.js +421 -0
  22. package/lib/serialization.js.map +1 -0
  23. package/lib/types.d.ts +138 -0
  24. package/lib/types.d.ts.map +1 -0
  25. package/lib/types.js +22 -0
  26. package/lib/types.js.map +1 -0
  27. package/lib/utils.d.ts +115 -0
  28. package/lib/utils.d.ts.map +1 -0
  29. package/lib/utils.js +225 -0
  30. package/lib/utils.js.map +1 -0
  31. package/lib-es/address.d.ts +73 -0
  32. package/lib-es/address.d.ts.map +1 -0
  33. package/lib-es/address.js +106 -0
  34. package/lib-es/address.js.map +1 -0
  35. package/lib-es/cbor.d.ts +73 -0
  36. package/lib-es/cbor.d.ts.map +1 -0
  37. package/lib-es/cbor.js +138 -0
  38. package/lib-es/cbor.js.map +1 -0
  39. package/lib-es/index.d.ts +6 -0
  40. package/lib-es/index.d.ts.map +1 -0
  41. package/lib-es/index.js +6 -0
  42. package/lib-es/index.js.map +1 -0
  43. package/lib-es/serialization.d.ts +153 -0
  44. package/lib-es/serialization.d.ts.map +1 -0
  45. package/lib-es/serialization.js +406 -0
  46. package/lib-es/serialization.js.map +1 -0
  47. package/lib-es/types.d.ts +138 -0
  48. package/lib-es/types.d.ts.map +1 -0
  49. package/lib-es/types.js +18 -0
  50. package/lib-es/types.js.map +1 -0
  51. package/lib-es/utils.d.ts +115 -0
  52. package/lib-es/utils.d.ts.map +1 -0
  53. package/lib-es/utils.js +205 -0
  54. package/lib-es/utils.js.map +1 -0
  55. package/package.json +48 -0
  56. package/src/address.test.ts +217 -0
  57. package/src/address.ts +113 -0
  58. package/src/bip32-path.d.ts +9 -0
  59. package/src/cbor.test.ts +236 -0
  60. package/src/cbor.ts +153 -0
  61. package/src/index.ts +5 -0
  62. package/src/serialization.test.ts +1160 -0
  63. package/src/serialization.ts +515 -0
  64. package/src/types.ts +141 -0
  65. package/src/utils.test.ts +1069 -0
  66. package/src/utils.ts +236 -0
  67. package/tsconfig.json +11 -0
@@ -0,0 +1,4 @@
1
+
2
+ > @ledgerhq/concordium-core@0.1.0 build /home/runner/work/ledger-live/ledger-live/libs/concordium-core
3
+ > tsc && tsc -m esnext --moduleResolution bundler --outDir lib-es
4
+
@@ -0,0 +1,14 @@
1
+ {
2
+ "entry": [
3
+ "src/index.ts"
4
+ ],
5
+ "ignorePatterns": [
6
+ "**/node_modules/**",
7
+ "**/*.test.{js,jsx,ts,tsx}"
8
+ ],
9
+ "ignoreUnimported": [
10
+ "src/bip32-path.d.ts"
11
+ ],
12
+ "ignoreUnresolved": [],
13
+ "ignoreUnused": []
14
+ }
package/CHANGELOG.md ADDED
@@ -0,0 +1,7 @@
1
+ # @ledgerhq/concordium-core
2
+
3
+ ## 0.2.0-nightly.20260220030210
4
+
5
+ ### Minor Changes
6
+
7
+ - [#14258](https://github.com/LedgerHQ/ledger-live/pull/14258) [`5f1c644`](https://github.com/LedgerHQ/ledger-live/commit/5f1c644fd5f757f48618b62e976faac274ced40d) Thanks [@lysyi3m](https://github.com/lysyi3m)! - added concordium proxy & grpc client and core functionality implementation; extracted shared concordium-core package with types, serialization, CBOR and address utilities; simplified hw-app-concordium API to single signTransaction method with type-based routing
package/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License
2
+
3
+ Copyright (c) 2017-present Ledger https://www.ledger.com/
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # @ledgerhq/concordium-core
2
+
3
+ Shared Concordium protocol types, serialization, and utilities used by both `@ledgerhq/hw-app-concordium` and `@ledgerhq/coin-concordium`.
4
+
5
+ ## Purpose
6
+
7
+ This package extracts shared protocol-level logic so that the hardware wallet app and the coin module can depend on it independently, without the coin module depending on the hardware wallet app.
8
+
9
+ ```
10
+ hw-app-concordium ←── @ledgerhq/concordium-core ──→ coin-concordium
11
+ ```
12
+
13
+ ## Exported APIs
14
+
15
+ ### Types (`src/types.ts`)
16
+
17
+ - `SchemeId` — Ed25519 cryptographic scheme identifier
18
+ - `TransactionType` — Transaction type discriminators (Transfer, TransferWithMemo)
19
+ - `Transaction` — Transaction structure for signing
20
+ - `TransferPayload` — Simple transfer payload
21
+ - `TransferWithMemoPayload` — Transfer with memo payload
22
+ - `TransactionPayload` — Union of transfer payload types
23
+ - `CredentialDeploymentTransaction` — Credential deployment in hw-app format
24
+ - `IdOwnershipProofs` — ID ownership proofs from Concordium ID App
25
+ - `Address` — Address response from device
26
+ - `VerifyAddressResponse` — Verify address response from device
27
+ - `SigningResult` — Signing result with signature and serialized transaction
28
+
29
+ ### Address (`src/address.ts`)
30
+
31
+ - `AccountAddress` — Concordium account address with Base58 ↔ Buffer conversion
32
+ - `AccountAddress.fromBase58(address: string): AccountAddress` — Parse Base58Check address
33
+ - `AccountAddress.isValid(address: string): boolean` — Check if a string is a valid Concordium address
34
+ - `toBase58(): string` — Convert to Base58Check string
35
+ - `toBuffer(): Buffer` — Get raw 32-byte address buffer
36
+
37
+ ### CBOR (`src/cbor.ts`)
38
+
39
+ - `encodeMemoToCbor(memo: string): Buffer` — Encode memo string to CBOR text string
40
+ - `memoEncodedSize(memo: string): number` — CBOR-encoded byte length without allocating (useful for size checks before encoding)
41
+ - `decodeMemoFromCbor(cborEncoded: Buffer): string` — Decode CBOR-encoded memo
42
+ - `MAX_MEMO_LENGTH` — Maximum memo length before CBOR encoding (254 bytes)
43
+ - `MAX_CBOR_SIZE` — Maximum CBOR-encoded memo size (256 bytes)
44
+
45
+ ### Utils (`src/utils.ts`)
46
+
47
+ - `encodeWord8/16/32/64` — Encode integers to Buffer (big/little endian)
48
+ - `decodeWord16/32/64` — Decode integers from Buffer
49
+ - `encodeWord8FromString` — Encode a string-represented number as Word8
50
+ - `serializeMap` — Serialize a Record to binary format
51
+ - `serializeVerifyKey` — Serialize a public key with scheme prefix
52
+ - `serializeYearMonth` — Serialize YYYYMM date string
53
+ - `serializePath` — Serialize BIP32 path array to Buffer
54
+ - `pathToBuffer` — Convert BIP32 path string to device-compatible Buffer
55
+ - `chunkBuffer` — Split a buffer into fixed-size chunks
56
+
57
+ ### Serialization (`src/serialization.ts`)
58
+
59
+ - `serializeTransfer(tx): Buffer` — Serialize a Transfer transaction
60
+ - `serializeTransferWithMemo(tx): Buffer` — Serialize a TransferWithMemo transaction
61
+ - `serializeTransaction(tx): Buffer` — Serialize any supported transaction type
62
+ - `deserializeTransfer(buffer): Transaction` — Deserialize Transfer from buffer
63
+ - `deserializeTransferWithMemo(buffer): Transaction` — Deserialize TransferWithMemo from buffer
64
+ - `deserializeTransaction(buffer): Transaction` — Deserialize any transaction by auto-detecting type
65
+ - `getTransactionType(buffer): TransactionType` — Get transaction type from serialized buffer
66
+ - `serializeCredentialDeploymentValues(payload): Buffer` — Serialize credential deployment values
67
+ - `serializeIdOwnershipProofs(proofs): Buffer` — Serialize ID ownership proofs
68
+ - `serializeAccountOwnershipProofs(signatures): Buffer` — Serialize account ownership proofs
69
+ - `insertAccountOwnershipProofs(idProofs, accountSig): string` — Combine ID + account proofs
70
+
71
+ ## Related Packages
72
+
73
+ - `@ledgerhq/hw-app-concordium` — Ledger device communication for Concordium (depends on this package for shared types/serialization; adds APDU-specific functions)
74
+ - `@ledgerhq/coin-concordium` — Ledger Live coin module for Concordium (depends on this package for shared types/serialization)
package/jest.config.js ADDED
@@ -0,0 +1,37 @@
1
+ module.exports = {
2
+ testEnvironment: "node",
3
+ transform: {
4
+ "^.+\\.(t|j)sx?$": [
5
+ "@swc/jest",
6
+ {
7
+ jsc: {
8
+ target: "es2022",
9
+ parser: {
10
+ syntax: "typescript",
11
+ tsx: false,
12
+ decorators: false,
13
+ dynamicImport: true,
14
+ },
15
+ },
16
+ },
17
+ ],
18
+ },
19
+ collectCoverage: true,
20
+ collectCoverageFrom: [
21
+ "src/**/*.ts",
22
+ "!src/**/*.test.ts",
23
+ "!src/**/*.spec.ts",
24
+ "!src/**/*.d.ts",
25
+ "!src/index.ts",
26
+ ],
27
+ coverageReporters: [
28
+ "json",
29
+ ["lcov", { file: "lcov.info", projectRoot: "../../" }],
30
+ "text",
31
+ ],
32
+ testPathIgnorePatterns: ["lib/", "lib-es/"],
33
+ reporters: [
34
+ "default",
35
+ ["jest-sonar", { outputName: "sonar-executionTests-report.xml", reportedFilePath: "absolute" }],
36
+ ],
37
+ };
@@ -0,0 +1,73 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /**
4
+ * Concordium account address with Base58 ↔ Buffer conversion.
5
+ *
6
+ * Handles Concordium-specific Base58Check encoding:
7
+ * - Version byte: 1 (prepended before Base58 encoding)
8
+ * - Raw address: 32 bytes
9
+ * - Base58 encoded: exactly 50 characters
10
+ *
11
+ * This class provides a type-safe wrapper for Concordium addresses,
12
+ * ensuring correct encoding/decoding and validation.
13
+ */
14
+ export declare class AccountAddress {
15
+ private readonly buffer;
16
+ /** Base58-encoded address string (50 characters) */
17
+ readonly address: string;
18
+ /**
19
+ * Private constructor - use fromBase58() or fromBuffer() to create instances.
20
+ * @param buffer - Raw 32-byte address
21
+ */
22
+ private constructor();
23
+ /**
24
+ * Parse a Base58-encoded Concordium address.
25
+ *
26
+ * @param address - Base58 address string (must be exactly 50 characters)
27
+ * @returns AccountAddress instance
28
+ * @throws Error if address is not 50 characters or has invalid version byte
29
+ *
30
+ * @example
31
+ * const addr = AccountAddress.fromBase58("3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G");
32
+ */
33
+ static fromBase58(address: string): AccountAddress;
34
+ /**
35
+ * Create an AccountAddress from raw 32-byte buffer.
36
+ *
37
+ * @param buffer - Raw address bytes (must be exactly 32 bytes)
38
+ * @returns AccountAddress instance
39
+ * @throws Error if buffer is not 32 bytes
40
+ *
41
+ * @example
42
+ * const addr = AccountAddress.fromBuffer(Buffer.from("...", "hex"));
43
+ */
44
+ static fromBuffer(buffer: Buffer): AccountAddress;
45
+ /**
46
+ * Convert address to Base58-encoded string.
47
+ *
48
+ * @returns Base58-encoded address (50 characters)
49
+ *
50
+ * @example
51
+ * const base58 = addr.toBase58();
52
+ * // "3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G"
53
+ */
54
+ toBase58(): string;
55
+ /**
56
+ * Get raw 32-byte address buffer.
57
+ *
58
+ * @returns Raw address bytes (32 bytes)
59
+ *
60
+ * @example
61
+ * const raw = addr.toBuffer();
62
+ * // Buffer of 32 bytes
63
+ */
64
+ toBuffer(): Buffer;
65
+ /**
66
+ * Check if a string is a valid Concordium account address.
67
+ *
68
+ * @param address - String to validate
69
+ * @returns true if the address is valid, false otherwise
70
+ */
71
+ static isValid(address: string): boolean;
72
+ }
73
+ //# sourceMappingURL=address.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.d.ts","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":";;AAEA;;;;;;;;;;GAUG;AACH,qBAAa,cAAc;IAQL,OAAO,CAAC,QAAQ,CAAC,MAAM;IAP3C,oDAAoD;IACpD,SAAgB,OAAO,EAAE,MAAM,CAAC;IAEhC;;;OAGG;IACH,OAAO;IAOP;;;;;;;;;OASG;IACH,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc;IAgBlD;;;;;;;;;OASG;IACH,MAAM,CAAC,UAAU,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc;IAOjD;;;;;;;;OAQG;IACH,QAAQ,IAAI,MAAM;IAKlB;;;;;;;;OAQG;IACH,QAAQ,IAAI,MAAM;IAIlB;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;CAQzC"}
package/lib/address.js ADDED
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AccountAddress = void 0;
7
+ const bs58check_1 = __importDefault(require("bs58check"));
8
+ /**
9
+ * Concordium account address with Base58 ↔ Buffer conversion.
10
+ *
11
+ * Handles Concordium-specific Base58Check encoding:
12
+ * - Version byte: 1 (prepended before Base58 encoding)
13
+ * - Raw address: 32 bytes
14
+ * - Base58 encoded: exactly 50 characters
15
+ *
16
+ * This class provides a type-safe wrapper for Concordium addresses,
17
+ * ensuring correct encoding/decoding and validation.
18
+ */
19
+ class AccountAddress {
20
+ buffer;
21
+ /** Base58-encoded address string (50 characters) */
22
+ address;
23
+ /**
24
+ * Private constructor - use fromBase58() or fromBuffer() to create instances.
25
+ * @param buffer - Raw 32-byte address
26
+ */
27
+ constructor(buffer) {
28
+ this.buffer = buffer;
29
+ if (buffer.length !== 32) {
30
+ throw new Error("Address must be 32 bytes");
31
+ }
32
+ this.address = this.toBase58();
33
+ }
34
+ /**
35
+ * Parse a Base58-encoded Concordium address.
36
+ *
37
+ * @param address - Base58 address string (must be exactly 50 characters)
38
+ * @returns AccountAddress instance
39
+ * @throws Error if address is not 50 characters or has invalid version byte
40
+ *
41
+ * @example
42
+ * const addr = AccountAddress.fromBase58("3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G");
43
+ */
44
+ static fromBase58(address) {
45
+ if (address.length !== 50) {
46
+ throw new Error("Address must be 50 characters");
47
+ }
48
+ const decoded = bs58check_1.default.decode(address);
49
+ if (decoded[0] !== 1) {
50
+ throw new Error("Invalid address version");
51
+ }
52
+ const addressBytes = Buffer.from(decoded.subarray(1));
53
+ return new AccountAddress(addressBytes);
54
+ }
55
+ /**
56
+ * Create an AccountAddress from raw 32-byte buffer.
57
+ *
58
+ * @param buffer - Raw address bytes (must be exactly 32 bytes)
59
+ * @returns AccountAddress instance
60
+ * @throws Error if buffer is not 32 bytes
61
+ *
62
+ * @example
63
+ * const addr = AccountAddress.fromBuffer(Buffer.from("...", "hex"));
64
+ */
65
+ static fromBuffer(buffer) {
66
+ if (buffer.length !== 32) {
67
+ throw new Error("Address buffer must be 32 bytes");
68
+ }
69
+ return new AccountAddress(buffer);
70
+ }
71
+ /**
72
+ * Convert address to Base58-encoded string.
73
+ *
74
+ * @returns Base58-encoded address (50 characters)
75
+ *
76
+ * @example
77
+ * const base58 = addr.toBase58();
78
+ * // "3kBx2h5Y2veb4hZgAJWPrr8RyQESKm5TjzF3ti1QQ4VSYLwK1G"
79
+ */
80
+ toBase58() {
81
+ const withVersion = Buffer.concat([Buffer.from([1]), this.buffer]);
82
+ return bs58check_1.default.encode(withVersion);
83
+ }
84
+ /**
85
+ * Get raw 32-byte address buffer.
86
+ *
87
+ * @returns Raw address bytes (32 bytes)
88
+ *
89
+ * @example
90
+ * const raw = addr.toBuffer();
91
+ * // Buffer of 32 bytes
92
+ */
93
+ toBuffer() {
94
+ return Buffer.from(this.buffer);
95
+ }
96
+ /**
97
+ * Check if a string is a valid Concordium account address.
98
+ *
99
+ * @param address - String to validate
100
+ * @returns true if the address is valid, false otherwise
101
+ */
102
+ static isValid(address) {
103
+ try {
104
+ AccountAddress.fromBase58(address);
105
+ return true;
106
+ }
107
+ catch {
108
+ return false;
109
+ }
110
+ }
111
+ }
112
+ exports.AccountAddress = AccountAddress;
113
+ //# sourceMappingURL=address.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"address.js","sourceRoot":"","sources":["../src/address.ts"],"names":[],"mappings":";;;;;;AAAA,0DAAkC;AAElC;;;;;;;;;;GAUG;AACH,MAAa,cAAc;IAQY;IAPrC,oDAAoD;IACpC,OAAO,CAAS;IAEhC;;;OAGG;IACH,YAAqC,MAAc;QAAd,WAAM,GAAN,MAAM,CAAQ;QACjD,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC;IACjC,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,UAAU,CAAC,OAAe;QAC/B,IAAI,OAAO,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,OAAO,GAAG,mBAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE1C,IAAI,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC;YACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;QAC7C,CAAC;QAED,MAAM,YAAY,GAAG,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;QAEtD,OAAO,IAAI,cAAc,CAAC,YAAY,CAAC,CAAC;IAC1C,CAAC;IAED;;;;;;;;;OASG;IACH,MAAM,CAAC,UAAU,CAAC,MAAc;QAC9B,IAAI,MAAM,CAAC,MAAM,KAAK,EAAE,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,IAAI,cAAc,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAED;;;;;;;;OAQG;IACH,QAAQ;QACN,MAAM,WAAW,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;QACnE,OAAO,mBAAS,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC;IACvC,CAAC;IAED;;;;;;;;OAQG;IACH,QAAQ;QACN,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAClC,CAAC;IAED;;;;;OAKG;IACH,MAAM,CAAC,OAAO,CAAC,OAAe;QAC5B,IAAI,CAAC;YACH,cAAc,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;YACnC,OAAO,IAAI,CAAC;QACd,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAnGD,wCAmGC"}
package/lib/cbor.d.ts ADDED
@@ -0,0 +1,73 @@
1
+ /**
2
+ * CBOR encoding/decoding utilities for Concordium memos.
3
+ *
4
+ * Concordium memos must be CBOR-encoded text strings before transmission to the device.
5
+ * The device firmware expects CBOR and decodes it for display during signing.
6
+ *
7
+ * This is a minimal CBOR implementation supporting only text strings (major type 3),
8
+ * which is all that's needed for Concordium memos.
9
+ * @private
10
+ */
11
+ /// <reference types="node" />
12
+ /// <reference types="node" />
13
+ /**
14
+ * Maximum memo length in bytes (UTF-8 encoded) before CBOR encoding.
15
+ * The device firmware enforces a 256-byte limit on CBOR-encoded data.
16
+ * CBOR text string encoding adds 2 bytes overhead for lengths 24-254,
17
+ * so the maximum UTF-8 text is 254 bytes.
18
+ */
19
+ export declare const MAX_MEMO_LENGTH = 254;
20
+ /**
21
+ * Maximum CBOR-encoded memo size (including CBOR overhead).
22
+ * This is the device firmware limit.
23
+ */
24
+ export declare const MAX_CBOR_SIZE = 256;
25
+ /**
26
+ * Encodes a memo string to CBOR text string format.
27
+ *
28
+ * Concordium memos must be CBOR-encoded before transmission to the device.
29
+ * The device expects CBOR text strings and will decode them for display.
30
+ *
31
+ * CBOR text string encoding (major type 3):
32
+ * - 0x60-0x77: lengths 0-23 (direct encoding, 1 byte overhead)
33
+ * - 0x78 + length byte: lengths 24-254 (2 bytes overhead)
34
+ * - 0x79 + 2 length bytes: lengths 255-65535 (3 bytes overhead, not supported for memos)
35
+ *
36
+ * @param memo - The memo string to encode (max 254 bytes UTF-8)
37
+ * @returns Buffer containing CBOR-encoded text string
38
+ * @throws Error if memo exceeds 254 bytes UTF-8
39
+ */
40
+ export declare function encodeMemoToCbor(memo: string): Buffer;
41
+ /**
42
+ * Returns the CBOR-encoded byte length of a memo string without allocating.
43
+ *
44
+ * Equivalent to `encodeMemoToCbor(memo).length` but without the Buffer allocation,
45
+ * useful for size checks before encoding.
46
+ *
47
+ * @param memo - The memo string (UTF-8)
48
+ * @returns Total byte length after CBOR encoding
49
+ */
50
+ export declare function memoEncodedSize(memo: string): number;
51
+ /**
52
+ * Decodes a CBOR-encoded memo string.
53
+ *
54
+ * The wallet-proxy and device return memos in CBOR-encoded format.
55
+ * This function decodes them back to plain UTF-8 strings for display.
56
+ *
57
+ * Supports CBOR text string decoding:
58
+ * - 0x60-0x77: lengths 0-23
59
+ * - 0x78 + 1 byte: lengths 24-255
60
+ * - 0x79 + 2 bytes: lengths 256-65535
61
+ *
62
+ * Note: While we only encode up to 254 bytes, we support decoding larger memos
63
+ * that may come from wallet-proxy or other sources.
64
+ *
65
+ * If you have a hex or base64 encoded string, convert it to Buffer first:
66
+ * - From hex: `Buffer.from(hexString, "hex")`
67
+ * - From base64: `Buffer.from(base64String, "base64")`
68
+ *
69
+ * @param cborEncoded - CBOR-encoded memo as Buffer
70
+ * @returns Decoded UTF-8 string
71
+ */
72
+ export declare function decodeMemoFromCbor(cborEncoded: Buffer): string;
73
+ //# sourceMappingURL=cbor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cbor.d.ts","sourceRoot":"","sources":["../src/cbor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;;;AAWH;;;;;GAKG;AACH,eAAO,MAAM,eAAe,MAAM,CAAC;AAEnC;;;GAGG;AACH,eAAO,MAAM,aAAa,MAAM,CAAC;AAEjC;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAqBrD;AAED;;;;;;;;GAQG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIpD;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CA4C9D"}
package/lib/cbor.js ADDED
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ /**
3
+ * CBOR encoding/decoding utilities for Concordium memos.
4
+ *
5
+ * Concordium memos must be CBOR-encoded text strings before transmission to the device.
6
+ * The device firmware expects CBOR and decodes it for display during signing.
7
+ *
8
+ * This is a minimal CBOR implementation supporting only text strings (major type 3),
9
+ * which is all that's needed for Concordium memos.
10
+ * @private
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.decodeMemoFromCbor = exports.memoEncodedSize = exports.encodeMemoToCbor = exports.MAX_CBOR_SIZE = exports.MAX_MEMO_LENGTH = void 0;
14
+ /** @private */
15
+ const CBOR_TEXT_STRING_BASE = 0x60;
16
+ /** @private */
17
+ const CBOR_MAX_SHORT_LENGTH = 24;
18
+ /** @private */
19
+ const CBOR_TEXT_STRING_1BYTE = 0x78;
20
+ /** @private */
21
+ const CBOR_TEXT_STRING_2BYTE = 0x79;
22
+ /**
23
+ * Maximum memo length in bytes (UTF-8 encoded) before CBOR encoding.
24
+ * The device firmware enforces a 256-byte limit on CBOR-encoded data.
25
+ * CBOR text string encoding adds 2 bytes overhead for lengths 24-254,
26
+ * so the maximum UTF-8 text is 254 bytes.
27
+ */
28
+ exports.MAX_MEMO_LENGTH = 254;
29
+ /**
30
+ * Maximum CBOR-encoded memo size (including CBOR overhead).
31
+ * This is the device firmware limit.
32
+ */
33
+ exports.MAX_CBOR_SIZE = 256;
34
+ /**
35
+ * Encodes a memo string to CBOR text string format.
36
+ *
37
+ * Concordium memos must be CBOR-encoded before transmission to the device.
38
+ * The device expects CBOR text strings and will decode them for display.
39
+ *
40
+ * CBOR text string encoding (major type 3):
41
+ * - 0x60-0x77: lengths 0-23 (direct encoding, 1 byte overhead)
42
+ * - 0x78 + length byte: lengths 24-254 (2 bytes overhead)
43
+ * - 0x79 + 2 length bytes: lengths 255-65535 (3 bytes overhead, not supported for memos)
44
+ *
45
+ * @param memo - The memo string to encode (max 254 bytes UTF-8)
46
+ * @returns Buffer containing CBOR-encoded text string
47
+ * @throws Error if memo exceeds 254 bytes UTF-8
48
+ */
49
+ function encodeMemoToCbor(memo) {
50
+ const memoBytes = Buffer.from(memo, "utf-8");
51
+ const memoLength = memoBytes.length;
52
+ if (memoLength > exports.MAX_MEMO_LENGTH) {
53
+ throw new Error(`Memo length ${memoLength} exceeds maximum of ${exports.MAX_MEMO_LENGTH} bytes (UTF-8)`);
54
+ }
55
+ let cborHeader;
56
+ if (memoLength < CBOR_MAX_SHORT_LENGTH) {
57
+ // Short form: 0x60-0x77 (length 0-23)
58
+ cborHeader = Buffer.from([CBOR_TEXT_STRING_BASE + memoLength]);
59
+ }
60
+ else {
61
+ // 1-byte length form: 0x78 + 1 byte length (length 24-254)
62
+ cborHeader = Buffer.from([CBOR_TEXT_STRING_1BYTE, memoLength]);
63
+ }
64
+ return Buffer.concat([cborHeader, memoBytes]);
65
+ }
66
+ exports.encodeMemoToCbor = encodeMemoToCbor;
67
+ /**
68
+ * Returns the CBOR-encoded byte length of a memo string without allocating.
69
+ *
70
+ * Equivalent to `encodeMemoToCbor(memo).length` but without the Buffer allocation,
71
+ * useful for size checks before encoding.
72
+ *
73
+ * @param memo - The memo string (UTF-8)
74
+ * @returns Total byte length after CBOR encoding
75
+ */
76
+ function memoEncodedSize(memo) {
77
+ const memoBytes = Buffer.byteLength(memo, "utf-8");
78
+ const cborOverhead = memoBytes < CBOR_MAX_SHORT_LENGTH ? 1 : 2;
79
+ return memoBytes + cborOverhead;
80
+ }
81
+ exports.memoEncodedSize = memoEncodedSize;
82
+ /**
83
+ * Decodes a CBOR-encoded memo string.
84
+ *
85
+ * The wallet-proxy and device return memos in CBOR-encoded format.
86
+ * This function decodes them back to plain UTF-8 strings for display.
87
+ *
88
+ * Supports CBOR text string decoding:
89
+ * - 0x60-0x77: lengths 0-23
90
+ * - 0x78 + 1 byte: lengths 24-255
91
+ * - 0x79 + 2 bytes: lengths 256-65535
92
+ *
93
+ * Note: While we only encode up to 254 bytes, we support decoding larger memos
94
+ * that may come from wallet-proxy or other sources.
95
+ *
96
+ * If you have a hex or base64 encoded string, convert it to Buffer first:
97
+ * - From hex: `Buffer.from(hexString, "hex")`
98
+ * - From base64: `Buffer.from(base64String, "base64")`
99
+ *
100
+ * @param cborEncoded - CBOR-encoded memo as Buffer
101
+ * @returns Decoded UTF-8 string
102
+ */
103
+ function decodeMemoFromCbor(cborEncoded) {
104
+ if (cborEncoded.length === 0) {
105
+ return "";
106
+ }
107
+ // Read CBOR header (first byte)
108
+ const header = cborEncoded[0];
109
+ let length;
110
+ let dataStart;
111
+ if (header >= CBOR_TEXT_STRING_BASE && header < CBOR_TEXT_STRING_BASE + CBOR_MAX_SHORT_LENGTH) {
112
+ // Short form: 0x60-0x77 (length 0-23)
113
+ length = header - CBOR_TEXT_STRING_BASE;
114
+ dataStart = 1;
115
+ }
116
+ else if (header === CBOR_TEXT_STRING_1BYTE) {
117
+ // 1-byte length form: 0x78 + 1 byte length
118
+ if (cborEncoded.length < 2) {
119
+ throw new Error("Invalid CBOR: insufficient data for 1-byte length");
120
+ }
121
+ length = cborEncoded[1];
122
+ dataStart = 2;
123
+ }
124
+ else if (header === CBOR_TEXT_STRING_2BYTE) {
125
+ // 2-byte length form: 0x79 + 2 bytes length (big-endian)
126
+ if (cborEncoded.length < 3) {
127
+ throw new Error("Invalid CBOR: insufficient data for 2-byte length");
128
+ }
129
+ length = cborEncoded.readUInt16BE(1);
130
+ dataStart = 3;
131
+ }
132
+ else {
133
+ throw new Error(`Invalid CBOR: expected text string (major type 3), got header byte 0x${header.toString(16)}`);
134
+ }
135
+ // Validate we have enough data
136
+ if (cborEncoded.length < dataStart + length) {
137
+ throw new Error(`Invalid CBOR: insufficient data (expected ${dataStart + length} bytes, got ${cborEncoded.length})`);
138
+ }
139
+ // Extract and decode the text data
140
+ const textData = cborEncoded.subarray(dataStart, dataStart + length);
141
+ return textData.toString("utf-8");
142
+ }
143
+ exports.decodeMemoFromCbor = decodeMemoFromCbor;
144
+ //# sourceMappingURL=cbor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cbor.js","sourceRoot":"","sources":["../src/cbor.ts"],"names":[],"mappings":"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"}
package/lib/index.d.ts ADDED
@@ -0,0 +1,6 @@
1
+ export * from "./types";
2
+ export * from "./address";
3
+ export * from "./cbor";
4
+ export * from "./utils";
5
+ export * from "./serialization";
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,SAAS,CAAC;AACxB,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,SAAS,CAAC;AACxB,cAAc,iBAAiB,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./address"), exports);
19
+ __exportStar(require("./cbor"), exports);
20
+ __exportStar(require("./utils"), exports);
21
+ __exportStar(require("./serialization"), exports);
22
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,0CAAwB;AACxB,4CAA0B;AAC1B,yCAAuB;AACvB,0CAAwB;AACxB,kDAAgC"}