@calimero-network/mero-js 15.0.0 → 15.2.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/admin-api/admin-client.d.ts +19 -1
- package/dist/admin-api/admin-client.js +20 -0
- package/dist/admin-api/admin-types.d.ts +63 -0
- 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 +126 -21
- package/dist/index.cjs.map +3 -3
- package/dist/index.d.ts +2 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +126 -21
- package/dist/index.mjs.map +3 -3
- package/dist/warrant/warrant.d.ts +1 -0
- package/dist/warrant/warrant.js +1 -79
- package/package.json +1 -1
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,14 +54,17 @@ __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,
|
|
67
|
+
signDeviceCert: () => signDeviceCert,
|
|
64
68
|
signWarrant: () => signWarrant,
|
|
65
69
|
withCap: () => withCap,
|
|
66
70
|
withRetry: () => withRetry,
|
|
@@ -1228,6 +1232,32 @@ var AdminApiClient = class {
|
|
|
1228
1232
|
)
|
|
1229
1233
|
);
|
|
1230
1234
|
}
|
|
1235
|
+
/**
|
|
1236
|
+
* Present a join this caller signed to a node the inviter named as an
|
|
1237
|
+
* admitter.
|
|
1238
|
+
*
|
|
1239
|
+
* For a member with no node. `joinNamespace` publishes the membership op from
|
|
1240
|
+
* the node making the call; this hands an already-signed op to somebody else's
|
|
1241
|
+
* node to publish. The distinction matters because a keyholder has nowhere to
|
|
1242
|
+
* publish from.
|
|
1243
|
+
*
|
|
1244
|
+
* The op must be signed by the **device key** in the credential it carries —
|
|
1245
|
+
* every peer checks that when applying a join. So the admitter cannot author
|
|
1246
|
+
* this, only carry it: a hostile one can refuse, and nothing else. It cannot
|
|
1247
|
+
* admit a different account, change the group, or grant a role.
|
|
1248
|
+
*
|
|
1249
|
+
* @param namespaceId the namespace being joined, 64 hex
|
|
1250
|
+
* @param request the invitation and the hex-encoded signed op
|
|
1251
|
+
*/
|
|
1252
|
+
async admitJoin(namespaceId, request) {
|
|
1253
|
+
return unwrap(
|
|
1254
|
+
await this.httpClient.post(
|
|
1255
|
+
`/admin-api/namespaces/${namespaceId}/admit`,
|
|
1256
|
+
request,
|
|
1257
|
+
{ timeoutMs: 65e3 }
|
|
1258
|
+
)
|
|
1259
|
+
);
|
|
1260
|
+
}
|
|
1231
1261
|
async joinNamespace(namespaceId, request) {
|
|
1232
1262
|
const data = unwrap(
|
|
1233
1263
|
await this.httpClient.post(
|
|
@@ -2592,9 +2622,7 @@ var CloudClient = class {
|
|
|
2592
2622
|
}
|
|
2593
2623
|
};
|
|
2594
2624
|
|
|
2595
|
-
// src/
|
|
2596
|
-
var SIGN_DOMAIN = new TextEncoder().encode("calimero.warrant.v1");
|
|
2597
|
-
var INTENT_DOMAIN = new TextEncoder().encode("calimero.warrant.intent.v1");
|
|
2625
|
+
// src/crypto/internal.ts
|
|
2598
2626
|
var PKCS8_ED25519_PREFIX = new Uint8Array([
|
|
2599
2627
|
48,
|
|
2600
2628
|
46,
|
|
@@ -2613,6 +2641,11 @@ var PKCS8_ED25519_PREFIX = new Uint8Array([
|
|
|
2613
2641
|
4,
|
|
2614
2642
|
32
|
|
2615
2643
|
]);
|
|
2644
|
+
function u32le(value) {
|
|
2645
|
+
const out = new Uint8Array(4);
|
|
2646
|
+
new DataView(out.buffer).setUint32(0, value, true);
|
|
2647
|
+
return out;
|
|
2648
|
+
}
|
|
2616
2649
|
function hex(bytes) {
|
|
2617
2650
|
return Array.from(bytes, (b) => b.toString(16).padStart(2, "0")).join("");
|
|
2618
2651
|
}
|
|
@@ -2652,10 +2685,6 @@ async function domainHash(domain, parts) {
|
|
|
2652
2685
|
await crypto.subtle.digest("SHA-256", concat(...chunks))
|
|
2653
2686
|
);
|
|
2654
2687
|
}
|
|
2655
|
-
async function intentHash(method, argsJson) {
|
|
2656
|
-
const args = new TextEncoder().encode(JSON.stringify(argsJson));
|
|
2657
|
-
return domainHash(INTENT_DOMAIN, [new TextEncoder().encode(method), args]);
|
|
2658
|
-
}
|
|
2659
2688
|
async function importSigningKey(secretHex) {
|
|
2660
2689
|
const seed = fromHex(secretHex, "deviceSecret", 32);
|
|
2661
2690
|
const pkcs8 = concat(PKCS8_ED25519_PREFIX, seed);
|
|
@@ -2674,6 +2703,31 @@ async function importSigningKey(secretHex) {
|
|
|
2674
2703
|
);
|
|
2675
2704
|
}
|
|
2676
2705
|
}
|
|
2706
|
+
async function derivePublicKey(secretHex) {
|
|
2707
|
+
const seed = fromHex(secretHex, "deviceSecret", 32);
|
|
2708
|
+
const pkcs8 = concat(PKCS8_ED25519_PREFIX, seed);
|
|
2709
|
+
const key = await crypto.subtle.importKey(
|
|
2710
|
+
"pkcs8",
|
|
2711
|
+
pkcs8,
|
|
2712
|
+
{ name: "Ed25519" },
|
|
2713
|
+
true,
|
|
2714
|
+
["sign"]
|
|
2715
|
+
);
|
|
2716
|
+
const jwk = await crypto.subtle.exportKey("jwk", key);
|
|
2717
|
+
const raw = jwk.x;
|
|
2718
|
+
return Uint8Array.from(
|
|
2719
|
+
atob(raw.replace(/-/g, "+").replace(/_/g, "/")),
|
|
2720
|
+
(c) => c.charCodeAt(0)
|
|
2721
|
+
);
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
// src/warrant/warrant.ts
|
|
2725
|
+
var SIGN_DOMAIN = new TextEncoder().encode("calimero.warrant.v1");
|
|
2726
|
+
var INTENT_DOMAIN = new TextEncoder().encode("calimero.warrant.intent.v1");
|
|
2727
|
+
async function intentHash(method, argsJson) {
|
|
2728
|
+
const args = new TextEncoder().encode(JSON.stringify(argsJson));
|
|
2729
|
+
return domainHash(INTENT_DOMAIN, [new TextEncoder().encode(method), args]);
|
|
2730
|
+
}
|
|
2677
2731
|
async function signWarrant(input) {
|
|
2678
2732
|
const context = fromHex(input.context, "context", 32);
|
|
2679
2733
|
const authorAccount = fromHex(input.authorAccount, "authorAccount", 32);
|
|
@@ -2708,21 +2762,72 @@ async function signWarrant(input) {
|
|
|
2708
2762
|
)
|
|
2709
2763
|
);
|
|
2710
2764
|
}
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
|
|
2718
|
-
|
|
2719
|
-
|
|
2765
|
+
|
|
2766
|
+
// src/device-cert/device-cert.ts
|
|
2767
|
+
var CERT_DOMAIN = new TextEncoder().encode("calimero.device.cert.v1");
|
|
2768
|
+
var ACCOUNT_ID_DOMAIN = new TextEncoder().encode("calimero.account.genesis.v1");
|
|
2769
|
+
var DEVICE_ID_DOMAIN = new TextEncoder().encode("calimero.device.id.v1");
|
|
2770
|
+
var ACCOUNT_GENESIS_VERSION = 1;
|
|
2771
|
+
async function mintDeviceId(account, nonce) {
|
|
2772
|
+
if (nonce.length !== 16) {
|
|
2773
|
+
throw new Error(`nonce must be 16 bytes, got ${nonce.length}`);
|
|
2774
|
+
}
|
|
2775
|
+
const accountBytes = fromHex(account, "account", 32);
|
|
2776
|
+
return hex(await domainHash(DEVICE_ID_DOMAIN, [accountBytes, nonce]));
|
|
2777
|
+
}
|
|
2778
|
+
async function deviceCertPayload(input) {
|
|
2779
|
+
return domainHash(CERT_DOMAIN, [
|
|
2780
|
+
fromHex(input.account, "account", 32),
|
|
2781
|
+
fromHex(input.device, "device", 32),
|
|
2782
|
+
fromHex(input.signPublicKey, "signPublicKey", 32),
|
|
2783
|
+
fromHex(input.kemPublicKey, "kemPublicKey", 32),
|
|
2784
|
+
u32le(input.keyEpoch),
|
|
2785
|
+
u32le(input.deviceEpoch)
|
|
2786
|
+
]);
|
|
2787
|
+
}
|
|
2788
|
+
async function signDeviceCert(input) {
|
|
2789
|
+
const rootPublicKey = await derivePublicKey(input.rootSecret);
|
|
2790
|
+
const account = hex(
|
|
2791
|
+
await domainHash(ACCOUNT_ID_DOMAIN, [
|
|
2792
|
+
concat(new Uint8Array([ACCOUNT_GENESIS_VERSION]), rootPublicKey)
|
|
2793
|
+
])
|
|
2720
2794
|
);
|
|
2721
|
-
const
|
|
2722
|
-
const
|
|
2723
|
-
|
|
2724
|
-
|
|
2725
|
-
|
|
2795
|
+
const keyEpoch = 0;
|
|
2796
|
+
const payload = await deviceCertPayload({
|
|
2797
|
+
account,
|
|
2798
|
+
device: input.device,
|
|
2799
|
+
signPublicKey: input.signPublicKey,
|
|
2800
|
+
kemPublicKey: input.kemPublicKey,
|
|
2801
|
+
keyEpoch,
|
|
2802
|
+
deviceEpoch: input.deviceEpoch
|
|
2803
|
+
});
|
|
2804
|
+
const key = await importSigningKey(input.rootSecret);
|
|
2805
|
+
const signature = new Uint8Array(
|
|
2806
|
+
await crypto.subtle.sign("Ed25519", key, payload)
|
|
2807
|
+
);
|
|
2808
|
+
const credential = concat(
|
|
2809
|
+
// AccountGenesis
|
|
2810
|
+
new Uint8Array([ACCOUNT_GENESIS_VERSION]),
|
|
2811
|
+
rootPublicKey,
|
|
2812
|
+
// chain: Vec<RootKeyHandoff>, empty
|
|
2813
|
+
u32le(0),
|
|
2814
|
+
// DeviceCert
|
|
2815
|
+
fromHex(account, "account", 32),
|
|
2816
|
+
fromHex(input.device, "device", 32),
|
|
2817
|
+
fromHex(input.signPublicKey, "signPublicKey", 32),
|
|
2818
|
+
fromHex(input.kemPublicKey, "kemPublicKey", 32),
|
|
2819
|
+
u32le(keyEpoch),
|
|
2820
|
+
u32le(input.deviceEpoch),
|
|
2821
|
+
signature
|
|
2822
|
+
);
|
|
2823
|
+
return hex(credential);
|
|
2824
|
+
}
|
|
2825
|
+
async function accountForRoot(rootSecret) {
|
|
2826
|
+
const rootPublicKey = await derivePublicKey(rootSecret);
|
|
2827
|
+
return hex(
|
|
2828
|
+
await domainHash(ACCOUNT_ID_DOMAIN, [
|
|
2829
|
+
concat(new Uint8Array([ACCOUNT_GENESIS_VERSION]), rootPublicKey)
|
|
2830
|
+
])
|
|
2726
2831
|
);
|
|
2727
2832
|
}
|
|
2728
2833
|
|