cautpartener / client / src / lib / orbit-identity.ts
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/**
 * OrbitDB identity provider backed by the persistent Ed25519 seed identity
 * (lib/identity.ts). Log entries chain to the durable identity: the provider
 * id IS the base64url public key peers already TOFU/verify in the roster, so
 * authorship in the replicated log and live presence share one identity.
 *
 * Wire format (OrbitDB contract, verified against @orbitdb/core 3.x source):
 * the device keystore's secp256k1 key signs each entry; the provider links it
 * to the durable key by signing the string `publicKey + signatures.id`.
 * With replication encryption ON, identities and signatures live inside
 * ciphertext — visible to room members only (PROTOCOL.md §7b preserved).
 */

import { useIdentityProvider } from "@orbitdb/core";
import { toB64url, type Bytes } from "./crypto";
import { Identity, verifyRaw } from "./identity";

const te = new TextEncoder();

interface OrbitIdentity {
  id: string;
  publicKey: string;
  signatures: { id: string; publicKey: string };
  type: string;
}

interface ProviderInstance {
  type: string;
  getId(): Promise<string>;
  signIdentity(data: string): Promise<string>;
}

export function SuetaIdentityProvider({ identity }: { identity: Identity }): () => Promise<ProviderInstance> {
  return async () => ({
    type: "sueta",
    getId: async () => identity.publicKeyB64,
    signIdentity: async (data: string) => toB64url(await identity.signRaw(te.encode(data) as Bytes)),
  });
}
SuetaIdentityProvider.type = "sueta";
SuetaIdentityProvider.verifyIdentity = async (identity: OrbitIdentity): Promise<boolean> => {
  return verifyRaw(
    identity.id,
    identity.signatures.publicKey,
    te.encode(identity.publicKey + identity.signatures.id) as Bytes,
  );
};

let registered = false;

/** Idempotent registration with OrbitDB's provider registry. */
export function registerSuetaProvider(): void {
  if (registered) return;
  registered = true;
  useIdentityProvider(SuetaIdentityProvider as never);
}

static mirror of HEAD · about · clone: git clone https://cod-sursa.cautpartener.ro/cautpartener.git