@calimero-network/mero-js 14.0.0 → 15.1.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.
- package/dist/crypto/internal.d.ts +30 -0
- package/dist/crypto/internal.js +93 -0
- package/dist/device-cert/device-cert.d.ts +68 -0
- package/dist/device-cert/device-cert.js +110 -0
- package/dist/device-cert/index.d.ts +2 -0
- package/dist/device-cert/index.js +2 -0
- package/dist/index.browser.mjs +2 -2
- package/dist/index.browser.mjs.map +4 -4
- package/dist/index.cjs +105 -116
- package/dist/index.cjs.map +4 -4
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -2
- package/dist/index.mjs +105 -116
- package/dist/index.mjs.map +4 -4
- package/dist/warrant/warrant.d.ts +1 -0
- package/dist/warrant/warrant.js +1 -79
- package/package.json +1 -1
- package/dist/account/index.d.ts +0 -43
- package/dist/account/index.js +0 -139
package/dist/index.cjs
CHANGED
|
@@ -35,6 +35,7 @@ __export(index_exports, {
|
|
|
35
35
|
SseClient: () => SseClient,
|
|
36
36
|
WebHttpClient: () => WebHttpClient,
|
|
37
37
|
WsClient: () => WsClient,
|
|
38
|
+
accountForRoot: () => accountForRoot,
|
|
38
39
|
buildAuthLoginUrl: () => buildAuthLoginUrl,
|
|
39
40
|
combineSignals: () => combineSignals,
|
|
40
41
|
compareSemver: () => compareSemver,
|
|
@@ -53,18 +54,18 @@ __export(index_exports, {
|
|
|
53
54
|
createRetryableMethod: () => createRetryableMethod,
|
|
54
55
|
createTimeoutSignal: () => createTimeoutSignal,
|
|
55
56
|
createUniversalHttpClient: () => createUniversalHttpClient,
|
|
57
|
+
deviceCertPayload: () => deviceCertPayload,
|
|
56
58
|
discoverLocalNodes: () => discoverLocalNodes,
|
|
57
59
|
hasCap: () => hasCap,
|
|
58
60
|
intentHash: () => intentHash,
|
|
59
61
|
jsonCodec: () => jsonCodec,
|
|
60
62
|
localNodeUrl: () => localNodeUrl,
|
|
63
|
+
mintDeviceId: () => mintDeviceId,
|
|
61
64
|
nodeEndpoint: () => nodeEndpoint,
|
|
62
65
|
parseAuthCallback: () => parseAuthCallback,
|
|
63
66
|
probeNodeHealth: () => probeNodeHealth,
|
|
64
|
-
|
|
67
|
+
signDeviceCert: () => signDeviceCert,
|
|
65
68
|
signWarrant: () => signWarrant,
|
|
66
|
-
toAccountBase58: () => toAccountBase58,
|
|
67
|
-
toAccountHex: () => toAccountHex,
|
|
68
69
|
withCap: () => withCap,
|
|
69
70
|
withRetry: () => withRetry,
|
|
70
71
|
withoutCap: () => withoutCap
|
|
@@ -2514,93 +2515,6 @@ function createMeroJs(config) {
|
|
|
2514
2515
|
return new MeroJs(config);
|
|
2515
2516
|
}
|
|
2516
2517
|
|
|
2517
|
-
// src/account/index.ts
|
|
2518
|
-
var BASE58_ALPHABET = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
|
|
2519
|
-
var HEX_ACCOUNT = /^[0-9a-f]{64}$/i;
|
|
2520
|
-
function encodeBase58(bytes) {
|
|
2521
|
-
if (bytes.length === 0) return "";
|
|
2522
|
-
const digits = [0];
|
|
2523
|
-
for (const byte of bytes) {
|
|
2524
|
-
let carry = byte;
|
|
2525
|
-
for (let i = 0; i < digits.length; i++) {
|
|
2526
|
-
carry += digits[i] << 8;
|
|
2527
|
-
digits[i] = carry % 58;
|
|
2528
|
-
carry = carry / 58 | 0;
|
|
2529
|
-
}
|
|
2530
|
-
while (carry > 0) {
|
|
2531
|
-
digits.push(carry % 58);
|
|
2532
|
-
carry = carry / 58 | 0;
|
|
2533
|
-
}
|
|
2534
|
-
}
|
|
2535
|
-
let out = "";
|
|
2536
|
-
for (const byte of bytes) {
|
|
2537
|
-
if (byte !== 0) break;
|
|
2538
|
-
out += BASE58_ALPHABET[0];
|
|
2539
|
-
}
|
|
2540
|
-
for (let i = digits.length - 1; i >= 0; i--) {
|
|
2541
|
-
out += BASE58_ALPHABET[digits[i]];
|
|
2542
|
-
}
|
|
2543
|
-
return out;
|
|
2544
|
-
}
|
|
2545
|
-
function decodeBase58(value) {
|
|
2546
|
-
if (value.length === 0) return null;
|
|
2547
|
-
const bytes = [0];
|
|
2548
|
-
for (const char of value) {
|
|
2549
|
-
const index = BASE58_ALPHABET.indexOf(char);
|
|
2550
|
-
if (index < 0) return null;
|
|
2551
|
-
let carry = index;
|
|
2552
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
2553
|
-
carry += bytes[i] * 58;
|
|
2554
|
-
bytes[i] = carry & 255;
|
|
2555
|
-
carry >>= 8;
|
|
2556
|
-
}
|
|
2557
|
-
while (carry > 0) {
|
|
2558
|
-
bytes.push(carry & 255);
|
|
2559
|
-
carry >>= 8;
|
|
2560
|
-
}
|
|
2561
|
-
}
|
|
2562
|
-
let leadingZeros = 0;
|
|
2563
|
-
for (const char of value) {
|
|
2564
|
-
if (char !== BASE58_ALPHABET[0]) break;
|
|
2565
|
-
leadingZeros++;
|
|
2566
|
-
}
|
|
2567
|
-
return Uint8Array.from([
|
|
2568
|
-
...new Array(leadingZeros).fill(0),
|
|
2569
|
-
...bytes.reverse()
|
|
2570
|
-
]);
|
|
2571
|
-
}
|
|
2572
|
-
function toHex(bytes) {
|
|
2573
|
-
let out = "";
|
|
2574
|
-
for (const byte of bytes) out += byte.toString(16).padStart(2, "0");
|
|
2575
|
-
return out;
|
|
2576
|
-
}
|
|
2577
|
-
function fromHex(hex2) {
|
|
2578
|
-
const bytes = new Uint8Array(hex2.length / 2);
|
|
2579
|
-
for (let i = 0; i < bytes.length; i++) {
|
|
2580
|
-
bytes[i] = parseInt(hex2.slice(i * 2, i * 2 + 2), 16);
|
|
2581
|
-
}
|
|
2582
|
-
return bytes;
|
|
2583
|
-
}
|
|
2584
|
-
function toAccountHex(id) {
|
|
2585
|
-
const trimmed = (id ?? "").trim();
|
|
2586
|
-
if (!trimmed) return "";
|
|
2587
|
-
if (HEX_ACCOUNT.test(trimmed)) return trimmed.toLowerCase();
|
|
2588
|
-
const decoded = decodeBase58(trimmed);
|
|
2589
|
-
if (!decoded || decoded.length !== 32) return trimmed;
|
|
2590
|
-
return toHex(decoded);
|
|
2591
|
-
}
|
|
2592
|
-
function toAccountBase58(id) {
|
|
2593
|
-
const trimmed = (id ?? "").trim();
|
|
2594
|
-
if (!trimmed) return "";
|
|
2595
|
-
if (!HEX_ACCOUNT.test(trimmed)) return trimmed;
|
|
2596
|
-
return encodeBase58(fromHex(trimmed));
|
|
2597
|
-
}
|
|
2598
|
-
function sameAccount(a, b) {
|
|
2599
|
-
const left = toAccountHex(a);
|
|
2600
|
-
const right = toAccountHex(b);
|
|
2601
|
-
return HEX_ACCOUNT.test(left) && left === right;
|
|
2602
|
-
}
|
|
2603
|
-
|
|
2604
2518
|
// src/token-store/index.ts
|
|
2605
2519
|
var MemoryTokenStore = class {
|
|
2606
2520
|
constructor() {
|
|
@@ -2682,9 +2596,7 @@ var CloudClient = class {
|
|
|
2682
2596
|
}
|
|
2683
2597
|
};
|
|
2684
2598
|
|
|
2685
|
-
// src/
|
|
2686
|
-
var SIGN_DOMAIN = new TextEncoder().encode("calimero.warrant.v1");
|
|
2687
|
-
var INTENT_DOMAIN = new TextEncoder().encode("calimero.warrant.intent.v1");
|
|
2599
|
+
// src/crypto/internal.ts
|
|
2688
2600
|
var PKCS8_ED25519_PREFIX = new Uint8Array([
|
|
2689
2601
|
48,
|
|
2690
2602
|
46,
|
|
@@ -2703,10 +2615,15 @@ var PKCS8_ED25519_PREFIX = new Uint8Array([
|
|
|
2703
2615
|
4,
|
|
2704
2616
|
32
|
|
2705
2617
|
]);
|
|
2618
|
+
function u32le(value) {
|
|
2619
|
+
const out = new Uint8Array(4);
|
|
2620
|
+
new DataView(out.buffer).setUint32(0, value, true);
|
|
2621
|
+
return out;
|
|
2622
|
+
}
|
|
2706
2623
|
function hex(bytes) {
|
|
2707
2624
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
2708
2625
|
}
|
|
2709
|
-
function
|
|
2626
|
+
function fromHex(value, label, expectedBytes) {
|
|
2710
2627
|
const clean = value.trim();
|
|
2711
2628
|
if (!/^[0-9a-fA-F]*$/.test(clean) || clean.length !== expectedBytes * 2) {
|
|
2712
2629
|
throw new Error(
|
|
@@ -2742,12 +2659,8 @@ async function domainHash(domain, parts) {
|
|
|
2742
2659
|
await crypto.subtle.digest("SHA-256", concat(...chunks))
|
|
2743
2660
|
);
|
|
2744
2661
|
}
|
|
2745
|
-
async function intentHash(method, argsJson) {
|
|
2746
|
-
const args = new TextEncoder().encode(JSON.stringify(argsJson));
|
|
2747
|
-
return domainHash(INTENT_DOMAIN, [new TextEncoder().encode(method), args]);
|
|
2748
|
-
}
|
|
2749
2662
|
async function importSigningKey(secretHex) {
|
|
2750
|
-
const seed =
|
|
2663
|
+
const seed = fromHex(secretHex, "deviceSecret", 32);
|
|
2751
2664
|
const pkcs8 = concat(PKCS8_ED25519_PREFIX, seed);
|
|
2752
2665
|
try {
|
|
2753
2666
|
return await crypto.subtle.importKey(
|
|
@@ -2764,10 +2677,35 @@ async function importSigningKey(secretHex) {
|
|
|
2764
2677
|
);
|
|
2765
2678
|
}
|
|
2766
2679
|
}
|
|
2680
|
+
async function derivePublicKey(secretHex) {
|
|
2681
|
+
const seed = fromHex(secretHex, "deviceSecret", 32);
|
|
2682
|
+
const pkcs8 = concat(PKCS8_ED25519_PREFIX, seed);
|
|
2683
|
+
const key = await crypto.subtle.importKey(
|
|
2684
|
+
"pkcs8",
|
|
2685
|
+
pkcs8,
|
|
2686
|
+
{ name: "Ed25519" },
|
|
2687
|
+
true,
|
|
2688
|
+
["sign"]
|
|
2689
|
+
);
|
|
2690
|
+
const jwk = await crypto.subtle.exportKey("jwk", key);
|
|
2691
|
+
const raw = jwk.x;
|
|
2692
|
+
return Uint8Array.from(
|
|
2693
|
+
atob(raw.replace(/-/g, "+").replace(/_/g, "/")),
|
|
2694
|
+
(c) => c.charCodeAt(0)
|
|
2695
|
+
);
|
|
2696
|
+
}
|
|
2697
|
+
|
|
2698
|
+
// src/warrant/warrant.ts
|
|
2699
|
+
var SIGN_DOMAIN = new TextEncoder().encode("calimero.warrant.v1");
|
|
2700
|
+
var INTENT_DOMAIN = new TextEncoder().encode("calimero.warrant.intent.v1");
|
|
2701
|
+
async function intentHash(method, argsJson) {
|
|
2702
|
+
const args = new TextEncoder().encode(JSON.stringify(argsJson));
|
|
2703
|
+
return domainHash(INTENT_DOMAIN, [new TextEncoder().encode(method), args]);
|
|
2704
|
+
}
|
|
2767
2705
|
async function signWarrant(input) {
|
|
2768
|
-
const context =
|
|
2769
|
-
const authorAccount =
|
|
2770
|
-
const executor =
|
|
2706
|
+
const context = fromHex(input.context, "context", 32);
|
|
2707
|
+
const authorAccount = fromHex(input.authorAccount, "authorAccount", 32);
|
|
2708
|
+
const executor = fromHex(input.executor, "executor", 32);
|
|
2771
2709
|
const key = await importSigningKey(input.deviceSecret);
|
|
2772
2710
|
const publicKey = await derivePublicKey(input.deviceSecret);
|
|
2773
2711
|
const commitment = await intentHash(input.method, input.argsJson);
|
|
@@ -2798,21 +2736,72 @@ async function signWarrant(input) {
|
|
|
2798
2736
|
)
|
|
2799
2737
|
);
|
|
2800
2738
|
}
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
|
|
2807
|
-
|
|
2808
|
-
|
|
2809
|
-
|
|
2739
|
+
|
|
2740
|
+
// src/device-cert/device-cert.ts
|
|
2741
|
+
var CERT_DOMAIN = new TextEncoder().encode("calimero.device.cert.v1");
|
|
2742
|
+
var ACCOUNT_ID_DOMAIN = new TextEncoder().encode("calimero.account.genesis.v1");
|
|
2743
|
+
var DEVICE_ID_DOMAIN = new TextEncoder().encode("calimero.device.id.v1");
|
|
2744
|
+
var ACCOUNT_GENESIS_VERSION = 1;
|
|
2745
|
+
async function mintDeviceId(account, nonce) {
|
|
2746
|
+
if (nonce.length !== 16) {
|
|
2747
|
+
throw new Error(`nonce must be 16 bytes, got ${nonce.length}`);
|
|
2748
|
+
}
|
|
2749
|
+
const accountBytes = fromHex(account, "account", 32);
|
|
2750
|
+
return hex(await domainHash(DEVICE_ID_DOMAIN, [accountBytes, nonce]));
|
|
2751
|
+
}
|
|
2752
|
+
async function deviceCertPayload(input) {
|
|
2753
|
+
return domainHash(CERT_DOMAIN, [
|
|
2754
|
+
fromHex(input.account, "account", 32),
|
|
2755
|
+
fromHex(input.device, "device", 32),
|
|
2756
|
+
fromHex(input.signPublicKey, "signPublicKey", 32),
|
|
2757
|
+
fromHex(input.kemPublicKey, "kemPublicKey", 32),
|
|
2758
|
+
u32le(input.keyEpoch),
|
|
2759
|
+
u32le(input.deviceEpoch)
|
|
2760
|
+
]);
|
|
2761
|
+
}
|
|
2762
|
+
async function signDeviceCert(input) {
|
|
2763
|
+
const rootPublicKey = await derivePublicKey(input.rootSecret);
|
|
2764
|
+
const account = hex(
|
|
2765
|
+
await domainHash(ACCOUNT_ID_DOMAIN, [
|
|
2766
|
+
concat(new Uint8Array([ACCOUNT_GENESIS_VERSION]), rootPublicKey)
|
|
2767
|
+
])
|
|
2810
2768
|
);
|
|
2811
|
-
const
|
|
2812
|
-
const
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2769
|
+
const keyEpoch = 0;
|
|
2770
|
+
const payload = await deviceCertPayload({
|
|
2771
|
+
account,
|
|
2772
|
+
device: input.device,
|
|
2773
|
+
signPublicKey: input.signPublicKey,
|
|
2774
|
+
kemPublicKey: input.kemPublicKey,
|
|
2775
|
+
keyEpoch,
|
|
2776
|
+
deviceEpoch: input.deviceEpoch
|
|
2777
|
+
});
|
|
2778
|
+
const key = await importSigningKey(input.rootSecret);
|
|
2779
|
+
const signature = new Uint8Array(
|
|
2780
|
+
await crypto.subtle.sign("Ed25519", key, payload)
|
|
2781
|
+
);
|
|
2782
|
+
const credential = concat(
|
|
2783
|
+
// AccountGenesis
|
|
2784
|
+
new Uint8Array([ACCOUNT_GENESIS_VERSION]),
|
|
2785
|
+
rootPublicKey,
|
|
2786
|
+
// chain: Vec<RootKeyHandoff>, empty
|
|
2787
|
+
u32le(0),
|
|
2788
|
+
// DeviceCert
|
|
2789
|
+
fromHex(account, "account", 32),
|
|
2790
|
+
fromHex(input.device, "device", 32),
|
|
2791
|
+
fromHex(input.signPublicKey, "signPublicKey", 32),
|
|
2792
|
+
fromHex(input.kemPublicKey, "kemPublicKey", 32),
|
|
2793
|
+
u32le(keyEpoch),
|
|
2794
|
+
u32le(input.deviceEpoch),
|
|
2795
|
+
signature
|
|
2796
|
+
);
|
|
2797
|
+
return hex(credential);
|
|
2798
|
+
}
|
|
2799
|
+
async function accountForRoot(rootSecret) {
|
|
2800
|
+
const rootPublicKey = await derivePublicKey(rootSecret);
|
|
2801
|
+
return hex(
|
|
2802
|
+
await domainHash(ACCOUNT_ID_DOMAIN, [
|
|
2803
|
+
concat(new Uint8Array([ACCOUNT_GENESIS_VERSION]), rootPublicKey)
|
|
2804
|
+
])
|
|
2816
2805
|
);
|
|
2817
2806
|
}
|
|
2818
2807
|
|