@calimero-network/mero-js 23.2.0 → 23.4.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/index.d.ts CHANGED
@@ -15,13 +15,15 @@ export { MeroClient, createMeroClient, RelayTransport, RelayObserver, defaultAud
15
15
  export type { MeroClientConfig, NodeTransportConfig, RelayTransportConfig, RelayObserveConfig, ExecuteTransport, ExecuteResult, TransportKind, } from './transport/index.js';
16
16
  export { SseClient, WsClient } from "./events/index.js";
17
17
  export type { SseEventData, WsEventData, AppVersionChangedEvent, GroupMembershipEventData, GroupMigrationEventData, MigrationStartedData, MigrationProgressData, CascadeProgressData, MigrationCompletedData, } from "./events/index.js";
18
- export { EphemeralClient, jsonCodec } from "./ephemeral/index.js";
18
+ export { EphemeralClient, jsonCodec, subscribePresence } from "./ephemeral/index.js";
19
+ export { RelayPresenceClient } from "./presence/relay-presence.js";
20
+ export { presenceStatementBytes, stateHash, PRESENCE_DOMAIN } from "./presence/statement.js";
19
21
  export type { Codec, EphemeralEntry } from "./ephemeral/index.js";
20
22
  export * from "./cloud/index.js";
21
23
  export * from "./sealed/index.js";
22
24
  export * from "./relay/index.js";
23
25
  export * from "./request-proof/index.js";
24
- export { signWarrant, intentHash, signCreationWarrant, parseCreationWarrant, creationInitHash, signGovernanceWarrant, parseGovernanceWarrant, governanceOpHash, memberAddedOp, memberRemovedOp, memberLeftOp, memberRoleSetOp, groupCreatedOp, createdSubgroupId, subgroupCreation, groupReparentedOp, groupDeletedOp, memberCapabilitySetOp, contextDetachedOp, subgroupVisibilitySetOp, groupMetadataSetOp, memberMetadataSetOp, contextMetadataSetOp, contextCapabilityGrantedOp, contextCapabilityRevokedOp, memberJoinedOpenOp, namespaceCreatedOp, defaultCapabilitiesSetOp, foundedNamespaceId, } from "./warrant/index.js";
26
+ export { signWarrant, intentHash, signCreationWarrant, parseCreationWarrant, creationInitHash, signGovernanceWarrant, parseGovernanceWarrant, governanceOpHash, memberAddedOp, memberRemovedOp, memberLeftOp, memberRoleSetOp, groupCreatedOp, createdSubgroupId, subgroupCreation, groupReparentedOp, groupDeletedOp, memberCapabilitySetOp, contextDetachedOp, subgroupVisibilitySetOp, groupMetadataSetOp, memberMetadataSetOp, contextMetadataSetOp, contextCapabilityGrantedOp, contextCapabilityRevokedOp, memberJoinedOpenOp, namespaceCreatedOp, defaultCapabilitiesSetOp, targetApplicationSetOp, foundedNamespaceId, } from "./warrant/index.js";
25
27
  export { signerFromSecret, signerFromCryptoKey } from "./signer/index.js";
26
28
  export type { Signer } from "./signer/index.js";
27
29
  export { generateAccountRoot, accountRootFromPhrase, accountRootFromSecret, createAccountRootSigner, accountRootSignerFromPhrase, signAccountLink, signAccountLogin, resolveRoot, resolveRootPair, } from "./account/index.js";
package/dist/index.js CHANGED
@@ -24,7 +24,9 @@ RelayObserver, defaultAudience, } from './transport/index.js';
24
24
  // Events (SSE / WebSocket)
25
25
  export { SseClient, WsClient } from "./events/index.js";
26
26
  // Ephemeral presence (cursors / typing / online)
27
- export { EphemeralClient, jsonCodec } from "./ephemeral/index.js";
27
+ export { EphemeralClient, jsonCodec, subscribePresence } from "./ephemeral/index.js";
28
+ export { RelayPresenceClient } from "./presence/relay-presence.js";
29
+ export { presenceStatementBytes, stateHash, PRESENCE_DOMAIN } from "./presence/statement.js";
28
30
  // Cloud client — namespaces, relays, HA, and the cloud sign-in path
29
31
  export * from "./cloud/index.js";
30
32
  // Sealed transport — requests encrypted to a TEE node's attested key
@@ -34,7 +36,7 @@ export * from "./relay/index.js";
34
36
  // Request proofs — a caller's identity on the request itself, no session needed
35
37
  export * from "./request-proof/index.js";
36
38
  // Warrant signing — mint the author's consent for a relay to run one intent
37
- export { signWarrant, intentHash, signCreationWarrant, parseCreationWarrant, creationInitHash, signGovernanceWarrant, parseGovernanceWarrant, governanceOpHash, memberAddedOp, memberRemovedOp, memberLeftOp, memberRoleSetOp, groupCreatedOp, createdSubgroupId, subgroupCreation, groupReparentedOp, groupDeletedOp, memberCapabilitySetOp, contextDetachedOp, subgroupVisibilitySetOp, groupMetadataSetOp, memberMetadataSetOp, contextMetadataSetOp, contextCapabilityGrantedOp, contextCapabilityRevokedOp, memberJoinedOpenOp, namespaceCreatedOp, defaultCapabilitiesSetOp, foundedNamespaceId, } from "./warrant/index.js";
39
+ export { signWarrant, intentHash, signCreationWarrant, parseCreationWarrant, creationInitHash, signGovernanceWarrant, parseGovernanceWarrant, governanceOpHash, memberAddedOp, memberRemovedOp, memberLeftOp, memberRoleSetOp, groupCreatedOp, createdSubgroupId, subgroupCreation, groupReparentedOp, groupDeletedOp, memberCapabilitySetOp, contextDetachedOp, subgroupVisibilitySetOp, groupMetadataSetOp, memberMetadataSetOp, contextMetadataSetOp, contextCapabilityGrantedOp, contextCapabilityRevokedOp, memberJoinedOpenOp, namespaceCreatedOp, defaultCapabilitiesSetOp, targetApplicationSetOp, foundedNamespaceId, } from "./warrant/index.js";
38
40
  // Who signs — a key's capability, separated from its material, so a
39
41
  // non-extractable key can be used wherever a hex secret could.
40
42
  export { signerFromSecret, signerFromCryptoKey } from "./signer/index.js";
package/dist/index.mjs CHANGED
@@ -3292,28 +3292,32 @@ var EphemeralClient = class {
3292
3292
  * and zero mean different things). Returns an unsubscribe function.
3293
3293
  */
3294
3294
  subscribe(contextId, handler, codec = jsonCodec()) {
3295
- const listener = (event) => {
3296
- const e = event;
3297
- if (e.type !== "Ephemeral" || e.contextId !== contextId) return;
3298
- const data = e.data;
3299
- if (!data?.author) return;
3300
- const removed = Boolean(data.removed);
3301
- const entry = {
3302
- author: data.author,
3303
- state: removed || data.state === void 0 ? void 0 : codec.decode(data.state),
3304
- removed
3305
- };
3306
- if (data.ageMs !== void 0) entry.ageMs = data.ageMs;
3307
- handler(entry);
3308
- };
3309
- this.sse.on("event", listener);
3310
- void this.sse.connect().catch(() => void 0);
3311
- void this.sse.subscribe([contextId]).catch(() => void 0);
3312
- return () => {
3313
- this.sse.off("event", listener);
3314
- };
3295
+ return subscribePresence(this.sse, contextId, handler, codec);
3315
3296
  }
3316
3297
  };
3298
+ function subscribePresence(sse, contextId, handler, codec = jsonCodec()) {
3299
+ const listener = (event) => {
3300
+ const e = event;
3301
+ if (e.type !== "Ephemeral" || e.contextId !== contextId) return;
3302
+ const data = e.data;
3303
+ if (!data?.author) return;
3304
+ const removed = Boolean(data.removed);
3305
+ const entry = {
3306
+ author: data.author,
3307
+ state: removed || data.state === void 0 ? void 0 : codec.decode(data.state),
3308
+ removed
3309
+ };
3310
+ if (data.ageMs !== void 0) entry.ageMs = data.ageMs;
3311
+ if (data.account !== void 0) entry.account = data.account;
3312
+ handler(entry);
3313
+ };
3314
+ sse.on("event", listener);
3315
+ void sse.connect().catch(() => void 0);
3316
+ void sse.subscribe([contextId]).catch(() => void 0);
3317
+ return () => {
3318
+ sse.off("event", listener);
3319
+ };
3320
+ }
3317
3321
 
3318
3322
  // src/signer/signer.ts
3319
3323
  var PKCS8_ED25519_PREFIX2 = new Uint8Array([
@@ -7405,6 +7409,7 @@ var GROUP_OP = {
7405
7409
  MemberRoleSet: 4,
7406
7410
  MemberCapabilitySet: 5,
7407
7411
  DefaultCapabilitiesSet: 6,
7412
+ TargetApplicationSet: 7,
7408
7413
  ContextDetached: 9,
7409
7414
  SubgroupVisibilitySet: 10,
7410
7415
  GroupMetadataSet: 11,
@@ -7478,6 +7483,23 @@ async function createdSubgroupId(admin, parentId, restricted, salt) {
7478
7483
  ])
7479
7484
  );
7480
7485
  }
7486
+ function borshString2(value, what) {
7487
+ if (value.length === 0) throw new Error(`${what} must not be empty`);
7488
+ const bytes = new TextEncoder().encode(value);
7489
+ return concat(u32le(bytes.length), bytes);
7490
+ }
7491
+ function targetApplicationSetOp(input) {
7492
+ return {
7493
+ kind: "group",
7494
+ bytes: concat(
7495
+ tag(GROUP_OP.TargetApplicationSet),
7496
+ CLEARED_HASH,
7497
+ fromHex(input.applicationId, "applicationId", 32),
7498
+ borshString2(input.package, "package"),
7499
+ borshString2(input.version, "version")
7500
+ )
7501
+ };
7502
+ }
7481
7503
  function defaultCapabilitiesSetOp(capabilities) {
7482
7504
  if (!Number.isInteger(capabilities) || capabilities < 0 || capabilities > 4294967295) {
7483
7505
  throw new Error(`capabilities must be a u32 bit mask, got ${String(capabilities)}`);
@@ -7739,6 +7761,19 @@ var RelayClient = class {
7739
7761
  );
7740
7762
  return { rootHash: body.data.rootHash, returns: body.data.returns ?? null };
7741
7763
  }
7764
+ /**
7765
+ * Publish one presence statement through the relay (`presence-intents`).
7766
+ *
7767
+ * Not retried on 429: presence resends every 2.5 s anyway, and a retry would
7768
+ * only queue behind the next resend. A refusal throws with its `status`.
7769
+ */
7770
+ async presenceIntent(contextId, body) {
7771
+ await this.jsonOnce(
7772
+ "POST",
7773
+ `/admin-api/contexts/${encodeURIComponent(contextId)}/presence-intents`,
7774
+ body
7775
+ );
7776
+ }
7742
7777
  /**
7743
7778
  * Ask the relay what it can do about creating contexts in `groupId`.
7744
7779
  *
@@ -7919,6 +7954,7 @@ var RelayClient = class {
7919
7954
  salt
7920
7955
  });
7921
7956
  const capabilitiesOp = input.defaultCapabilities === void 0 ? void 0 : defaultCapabilitiesSetOp(input.defaultCapabilities);
7957
+ const applicationOp = input.application ? targetApplicationSetOp(input.application) : void 0;
7922
7958
  const signer = await this.authorSigner();
7923
7959
  const nonce2 = await this.config.nonces.next();
7924
7960
  const ttl = this.config.ttlSeconds ?? DEFAULT_TTL_SECONDS;
@@ -7938,17 +7974,25 @@ var RelayClient = class {
7938
7974
  teeEnabled: data.teeEnabled ?? false,
7939
7975
  ...data.teeError ? { teeError: data.teeError } : {}
7940
7976
  };
7941
- if (!capabilitiesOp) return founded;
7942
- try {
7943
- await this.govern({ groupId: founded.namespaceId, op: capabilitiesOp });
7944
- return { ...founded, defaultCapabilitiesSet: true };
7945
- } catch (err) {
7946
- return {
7947
- ...founded,
7948
- defaultCapabilitiesSet: false,
7949
- defaultCapabilitiesError: err instanceof Error ? err.message : String(err)
7950
- };
7977
+ let result = founded;
7978
+ const message = (err) => err instanceof Error ? err.message : String(err);
7979
+ if (applicationOp) {
7980
+ try {
7981
+ await this.govern({ groupId: founded.namespaceId, op: applicationOp });
7982
+ result = { ...result, applicationSet: true };
7983
+ } catch (err) {
7984
+ result = { ...result, applicationSet: false, applicationError: message(err) };
7985
+ }
7986
+ }
7987
+ if (capabilitiesOp) {
7988
+ try {
7989
+ await this.govern({ groupId: founded.namespaceId, op: capabilitiesOp });
7990
+ result = { ...result, defaultCapabilitiesSet: true };
7991
+ } catch (err) {
7992
+ result = { ...result, defaultCapabilitiesSet: false, defaultCapabilitiesError: message(err) };
7993
+ }
7951
7994
  }
7995
+ return result;
7952
7996
  }
7953
7997
  async postGovernance(groupId, op, warrant) {
7954
7998
  const body = await this.json("POST", `/admin-api/groups/${encodeURIComponent(groupId)}/governance-intents`, {
@@ -8040,6 +8084,7 @@ var RelayClient = class {
8040
8084
  text
8041
8085
  );
8042
8086
  }
8087
+ if (response.status === 204) return void 0;
8043
8088
  return await response.json();
8044
8089
  }
8045
8090
  };
@@ -8467,6 +8512,121 @@ function signedPath(url) {
8467
8512
  return new URL(url).pathname;
8468
8513
  }
8469
8514
 
8515
+ // src/presence/statement.ts
8516
+ var PRESENCE_DOMAIN = new TextEncoder().encode("calimero/presence/1");
8517
+ async function stateHash(state) {
8518
+ const borsh = state === null ? new Uint8Array([0]) : concat(new Uint8Array([1]), u32le(state.length), state);
8519
+ return new Uint8Array(await crypto.subtle.digest("SHA-256", borsh));
8520
+ }
8521
+ async function presenceStatementBytes(input) {
8522
+ return concat(
8523
+ PRESENCE_DOMAIN,
8524
+ fromHex(input.contextId, "contextId", 32),
8525
+ fromHex(input.author, "author", 32),
8526
+ u64le(input.seq),
8527
+ u64le(input.sentAtMs),
8528
+ await stateHash(input.state)
8529
+ );
8530
+ }
8531
+
8532
+ // src/presence/relay-presence.ts
8533
+ var HEARTBEAT_MS = 2500;
8534
+ var RelayPresenceClient = class {
8535
+ /**
8536
+ * @param opts.events the relay's event stream, asked for only on `subscribe`:
8537
+ * publishing needs none, so a client with no node key can still publish.
8538
+ */
8539
+ constructor(opts) {
8540
+ this.timers = /* @__PURE__ */ new Map();
8541
+ this.lastSeq = /* @__PURE__ */ new Map();
8542
+ this.refused = /* @__PURE__ */ new Set();
8543
+ /**
8544
+ * Bumped by every `set` and `close`, per context. A `set` installs its
8545
+ * resends only if nothing newer happened while its first send was in flight,
8546
+ * so a retract (or a newer state) can never be overtaken by an older one.
8547
+ */
8548
+ this.generation = /* @__PURE__ */ new Map();
8549
+ this.relay = opts.relay;
8550
+ this.events = opts.events;
8551
+ this.heartbeatMs = opts.heartbeatMs ?? HEARTBEAT_MS;
8552
+ this.now = opts.now ?? Date.now;
8553
+ }
8554
+ /**
8555
+ * Set this account's presence in `contextId`, or retract it with `null`.
8556
+ * Throws when the relay refuses this first send for good (a 4xx other than
8557
+ * 429), which also stops the resends. A rate limit, a network failure or a
8558
+ * 5xx is not thrown: the next resend covers it.
8559
+ */
8560
+ async set(contextId, state, codec = jsonCodec()) {
8561
+ const generation = this.bump(contextId);
8562
+ this.refused.delete(contextId);
8563
+ const bytes = state === null ? null : new Uint8Array(codec.encode(state));
8564
+ await this.send(contextId, bytes);
8565
+ if (bytes === null || this.refused.has(contextId)) return;
8566
+ if (this.generation.get(contextId) !== generation) return;
8567
+ this.timers.set(
8568
+ contextId,
8569
+ setInterval(() => void this.send(contextId, bytes).catch(() => void 0), this.heartbeatMs)
8570
+ );
8571
+ }
8572
+ subscribe(contextId, handler, codec = jsonCodec()) {
8573
+ return subscribePresence(this.events(), contextId, handler, codec);
8574
+ }
8575
+ /** Stop every resend. Entries expire on the relay and its peers within 7 s. */
8576
+ close() {
8577
+ for (const contextId of /* @__PURE__ */ new Set([...this.timers.keys(), ...this.generation.keys()])) {
8578
+ this.bump(contextId);
8579
+ }
8580
+ }
8581
+ /** Stop the context's resends and invalidate any `set` still in flight. */
8582
+ bump(contextId) {
8583
+ this.stop(contextId);
8584
+ const next = (this.generation.get(contextId) ?? 0) + 1;
8585
+ this.generation.set(contextId, next);
8586
+ return next;
8587
+ }
8588
+ stop(contextId) {
8589
+ const timer = this.timers.get(contextId);
8590
+ if (timer !== void 0) clearInterval(timer);
8591
+ this.timers.delete(contextId);
8592
+ }
8593
+ /** Wall-clock seeded and strictly rising, so a relay restart never sees an old seq. */
8594
+ nextSeq(contextId) {
8595
+ const seq = Math.max(this.now(), (this.lastSeq.get(contextId) ?? 0) + 1);
8596
+ this.lastSeq.set(contextId, seq);
8597
+ return seq;
8598
+ }
8599
+ async send(contextId, state) {
8600
+ if (this.refused.has(contextId)) return;
8601
+ const signer = await this.relay.authorSigner();
8602
+ const seq = this.nextSeq(contextId);
8603
+ const sentAtMs = this.now();
8604
+ const statement = await presenceStatementBytes({
8605
+ contextId,
8606
+ author: signer.publicKey,
8607
+ seq: BigInt(seq),
8608
+ sentAtMs: BigInt(sentAtMs),
8609
+ state
8610
+ });
8611
+ const signature = hex(await signer.sign(statement));
8612
+ try {
8613
+ await this.relay.presenceIntent(contextId, {
8614
+ state: state === null ? null : hex(state),
8615
+ seq,
8616
+ sentAtMs,
8617
+ signature,
8618
+ authorProof: this.relay.authorProof
8619
+ });
8620
+ } catch (err) {
8621
+ const status = err.status;
8622
+ if (status === void 0 || status === 0 || status === 429 || status >= 500) return;
8623
+ this.refused.add(contextId);
8624
+ this.stop(contextId);
8625
+ throw err;
8626
+ }
8627
+ }
8628
+ };
8629
+
8470
8630
  // src/transport/mero-client.ts
8471
8631
  function relayHasNo(surface, why) {
8472
8632
  return new Error(
@@ -8510,6 +8670,7 @@ var MeroClient = class {
8510
8670
  this.proofAuthorizer = null;
8511
8671
  this.relayUrl = null;
8512
8672
  this.proofEvents = null;
8673
+ this.relayPresence = null;
8513
8674
  if (config.transport === "relay") {
8514
8675
  this.transport = "relay";
8515
8676
  this.nodeClient = null;
@@ -8664,26 +8825,19 @@ var MeroClient = class {
8664
8825
  /**
8665
8826
  * Ephemeral presence. Node transport only.
8666
8827
  *
8667
- * Not extended to the relay even though a logged-in session could reach both
8668
- * halves of it mechanically. Publishing resolves the author from an *owned
8669
- * context identity on the node*, and whether a delegated session has one has
8670
- * not been established — a presence client that silently published nothing,
8671
- * or published as the wrong identity, is worse than one that says it is not
8672
- * available. The read half is not lost: presence arrives on `client.events`
8673
- * like any other context event, and can be filtered there.
8674
- *
8675
- * The rejected alternative was to expose it over the relay session and let
8676
- * `set` fail at the node. That trades a clear construction-time answer for a
8677
- * runtime failure inside a UI that has already rendered.
8828
+ * On a relay client this is an account's presence client
8829
+ * ({@link RelayPresenceClient}): `set` signs each update with the device key
8830
+ * and posts it to the relay's `presence-intents`, resending every 2.5 s, and
8831
+ * `subscribe` reads the relay's event stream. The relay checks and forwards
8832
+ * the update; other members verify the device's signature and certificate
8833
+ * themselves, so it can drop or delay an account's presence but not invent or
8834
+ * alter it. Only `subscribe` needs the relay's node key (for the event
8835
+ * stream), so publishing works on any relay client.
8678
8836
  */
8679
8837
  get ephemeral() {
8680
- if (!this.nodeClient) {
8681
- throw relayHasNo(
8682
- "ephemeral presence",
8683
- "publishing resolves the author from an owned context identity on the node, which a delegated session is not known to have \u2014 read presence off `client.events` instead"
8684
- );
8685
- }
8686
- return this.nodeClient.ephemeral;
8838
+ if (this.nodeClient) return this.nodeClient.ephemeral;
8839
+ this.relayPresence ?? (this.relayPresence = new RelayPresenceClient({ relay: this.relay, events: () => this.events }));
8840
+ return this.relayPresence;
8687
8841
  }
8688
8842
  /**
8689
8843
  * Calimero Cloud.
@@ -10488,7 +10642,7 @@ function optionalBytes32(value, label2) {
10488
10642
  }
10489
10643
  return concat(new Uint8Array([1]), new Uint8Array(value));
10490
10644
  }
10491
- function borshString2(value) {
10645
+ function borshString3(value) {
10492
10646
  const bytes = new TextEncoder().encode(value);
10493
10647
  return concat(u32le(bytes.length), bytes);
10494
10648
  }
@@ -10502,7 +10656,7 @@ function encodeSignedInvitation(signed) {
10502
10656
  // ...then the enclosing SignedGroupOpenInvitation, in declaration order.
10503
10657
  // `inviter_account` sits between the signature and the addresses; putting it
10504
10658
  // anywhere else still encodes 32 bytes and still verifies as nothing.
10505
- borshString2(signed.inviter_signature),
10659
+ borshString3(signed.inviter_signature),
10506
10660
  signed.inviter_account ? concat(new Uint8Array([1]), fromHex(signed.inviter_account, "inviter_account", 32)) : new Uint8Array([0]),
10507
10661
  // A `Vec<String>`, so each entry is a bare borsh string. This carried an
10508
10662
  // enum until core dropped the URL variant, and an enum writes a
@@ -10510,7 +10664,7 @@ function encodeSignedInvitation(signed) {
10510
10664
  // every following byte and fail as `invalid invitation signature`, pointing
10511
10665
  // nowhere near this line.
10512
10666
  u32le(admitterAddrs.length),
10513
- ...admitterAddrs.map(borshString2),
10667
+ ...admitterAddrs.map(borshString3),
10514
10668
  optionalBytes32(signed.application_id, "application_id"),
10515
10669
  // Borsh order follows core's field order, where this is `bytecode_id`; the
10516
10670
  // JSON key is `app_key`, a rename covering both directions that core pins in
@@ -10583,12 +10737,12 @@ var te = new TextEncoder();
10583
10737
  function tag2(byte) {
10584
10738
  return new Uint8Array([byte]);
10585
10739
  }
10586
- function borshString3(value) {
10740
+ function borshString4(value) {
10587
10741
  const bytes = te.encode(value);
10588
10742
  return concat(u32le(bytes.length), bytes);
10589
10743
  }
10590
10744
  function borshStrings(values) {
10591
- return concat(u32le(values.length), ...values.map(borshString3));
10745
+ return concat(u32le(values.length), ...values.map(borshString4));
10592
10746
  }
10593
10747
  function borshBool(value) {
10594
10748
  return tag2(value ? 1 : 0);
@@ -10642,7 +10796,7 @@ function teeAdmissionPolicyOp(input) {
10642
10796
  };
10643
10797
  }
10644
10798
  function teeReleaseAdmissionPolicyOp(input) {
10645
- const minRelease = input.minReleaseVersion === void 0 ? tag2(0) : concat(tag2(1), borshString3(input.minReleaseVersion));
10799
+ const minRelease = input.minReleaseVersion === void 0 ? tag2(0) : concat(tag2(1), borshString4(input.minReleaseVersion));
10646
10800
  return {
10647
10801
  kind: "teeReleaseAdmissionPolicy",
10648
10802
  plane: "group",
@@ -10899,9 +11053,11 @@ export {
10899
11053
  MeroJs,
10900
11054
  NODE_RELEASE_SIGNER,
10901
11055
  OWNER_OP_KIND,
11056
+ PRESENCE_DOMAIN,
10902
11057
  REQUEST_PROOF_HEADER,
10903
11058
  RelayClient,
10904
11059
  RelayObserver,
11060
+ RelayPresenceClient,
10905
11061
  RelayTransport,
10906
11062
  RpcClient,
10907
11063
  RpcError,
@@ -11021,6 +11177,7 @@ export {
11021
11177
  parseDeviceCredential,
11022
11178
  parseGovernanceWarrant,
11023
11179
  parseWarrantNonce,
11180
+ presenceStatementBytes,
11024
11181
  probeNodeHealth,
11025
11182
  readCloudLinkCallback,
11026
11183
  readEnrolmentCallback,
@@ -11050,8 +11207,11 @@ export {
11050
11207
  signedPath,
11051
11208
  signerFromCryptoKey,
11052
11209
  signerFromSecret,
11210
+ stateHash,
11053
11211
  subgroupCreation,
11054
11212
  subgroupVisibilitySetOp,
11213
+ subscribePresence,
11214
+ targetApplicationSetOp,
11055
11215
  teeAdmissionPolicyOp,
11056
11216
  teeAuthoringPolicyOp,
11057
11217
  teeReleaseAdmissionPolicyOp,