@openvtc/pnm-core 0.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/README.md +129 -0
- package/dist/did/derive-signing-key.d.ts +19 -0
- package/dist/did/derive-signing-key.d.ts.map +1 -0
- package/dist/did/derive-signing-key.js +96 -0
- package/dist/did/derive-signing-key.js.map +1 -0
- package/dist/did/index.d.ts +5 -0
- package/dist/did/index.d.ts.map +1 -0
- package/dist/did/index.js +5 -0
- package/dist/did/index.js.map +1 -0
- package/dist/did/peer.d.ts +37 -0
- package/dist/did/peer.d.ts.map +1 -0
- package/dist/did/peer.js +49 -0
- package/dist/did/peer.js.map +1 -0
- package/dist/did/verification-method.d.ts +43 -0
- package/dist/did/verification-method.d.ts.map +1 -0
- package/dist/did/verification-method.js +32 -0
- package/dist/did/verification-method.js.map +1 -0
- package/dist/did/verify.d.ts +49 -0
- package/dist/did/verify.d.ts.map +1 -0
- package/dist/did/verify.js +89 -0
- package/dist/did/verify.js.map +1 -0
- package/dist/didcomm/index.d.ts +235 -0
- package/dist/didcomm/index.d.ts.map +1 -0
- package/dist/didcomm/index.js +415 -0
- package/dist/didcomm/index.js.map +1 -0
- package/dist/inbound/confirm.d.ts +50 -0
- package/dist/inbound/confirm.d.ts.map +1 -0
- package/dist/inbound/confirm.js +64 -0
- package/dist/inbound/confirm.js.map +1 -0
- package/dist/inbound/dedup.d.ts +9 -0
- package/dist/inbound/dedup.d.ts.map +1 -0
- package/dist/inbound/dedup.js +31 -0
- package/dist/inbound/dedup.js.map +1 -0
- package/dist/inbound/index.d.ts +3 -0
- package/dist/inbound/index.d.ts.map +1 -0
- package/dist/inbound/index.js +3 -0
- package/dist/inbound/index.js.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/onboarding/index.d.ts +2 -0
- package/dist/onboarding/index.d.ts.map +1 -0
- package/dist/onboarding/index.js +2 -0
- package/dist/onboarding/index.js.map +1 -0
- package/dist/onboarding/swap.d.ts +60 -0
- package/dist/onboarding/swap.d.ts.map +1 -0
- package/dist/onboarding/swap.js +148 -0
- package/dist/onboarding/swap.js.map +1 -0
- package/dist/provision/adopt.d.ts +31 -0
- package/dist/provision/adopt.d.ts.map +1 -0
- package/dist/provision/adopt.js +114 -0
- package/dist/provision/adopt.js.map +1 -0
- package/dist/provision/armor.d.ts +19 -0
- package/dist/provision/armor.d.ts.map +1 -0
- package/dist/provision/armor.js +243 -0
- package/dist/provision/armor.js.map +1 -0
- package/dist/provision/crc24.d.ts +5 -0
- package/dist/provision/crc24.d.ts.map +1 -0
- package/dist/provision/crc24.js +30 -0
- package/dist/provision/crc24.js.map +1 -0
- package/dist/provision/hpke.d.ts +17 -0
- package/dist/provision/hpke.d.ts.map +1 -0
- package/dist/provision/hpke.js +60 -0
- package/dist/provision/hpke.js.map +1 -0
- package/dist/provision/index.d.ts +10 -0
- package/dist/provision/index.d.ts.map +1 -0
- package/dist/provision/index.js +16 -0
- package/dist/provision/index.js.map +1 -0
- package/dist/provision/open.d.ts +28 -0
- package/dist/provision/open.d.ts.map +1 -0
- package/dist/provision/open.js +224 -0
- package/dist/provision/open.js.map +1 -0
- package/dist/provision/request.d.ts +65 -0
- package/dist/provision/request.d.ts.map +1 -0
- package/dist/provision/request.js +53 -0
- package/dist/provision/request.js.map +1 -0
- package/dist/provision/run.d.ts +76 -0
- package/dist/provision/run.d.ts.map +1 -0
- package/dist/provision/run.js +110 -0
- package/dist/provision/run.js.map +1 -0
- package/dist/provision/send.d.ts +85 -0
- package/dist/provision/send.d.ts.map +1 -0
- package/dist/provision/send.js +87 -0
- package/dist/provision/send.js.map +1 -0
- package/dist/provision/types.d.ts +110 -0
- package/dist/provision/types.d.ts.map +1 -0
- package/dist/provision/types.js +17 -0
- package/dist/provision/types.js.map +1 -0
- package/dist/rp-login/didcomm.d.ts +34 -0
- package/dist/rp-login/didcomm.d.ts.map +1 -0
- package/dist/rp-login/didcomm.js +72 -0
- package/dist/rp-login/didcomm.js.map +1 -0
- package/dist/rp-login/index.d.ts +3 -0
- package/dist/rp-login/index.d.ts.map +1 -0
- package/dist/rp-login/index.js +3 -0
- package/dist/rp-login/index.js.map +1 -0
- package/dist/rp-login/step-up.d.ts +43 -0
- package/dist/rp-login/step-up.d.ts.map +1 -0
- package/dist/rp-login/step-up.js +118 -0
- package/dist/rp-login/step-up.js.map +1 -0
- package/dist/siop/index.d.ts +3 -0
- package/dist/siop/index.d.ts.map +1 -0
- package/dist/siop/index.js +3 -0
- package/dist/siop/index.js.map +1 -0
- package/dist/siop/login-client.d.ts +29 -0
- package/dist/siop/login-client.d.ts.map +1 -0
- package/dist/siop/login-client.js +79 -0
- package/dist/siop/login-client.js.map +1 -0
- package/dist/siop/self-issued.d.ts +96 -0
- package/dist/siop/self-issued.d.ts.map +1 -0
- package/dist/siop/self-issued.js +162 -0
- package/dist/siop/self-issued.js.map +1 -0
- package/dist/store/holder-identity.d.ts +241 -0
- package/dist/store/holder-identity.d.ts.map +1 -0
- package/dist/store/holder-identity.js +441 -0
- package/dist/store/holder-identity.js.map +1 -0
- package/dist/store/index.d.ts +4 -0
- package/dist/store/index.d.ts.map +1 -0
- package/dist/store/index.js +4 -0
- package/dist/store/index.js.map +1 -0
- package/dist/store/kv-store.d.ts +51 -0
- package/dist/store/kv-store.d.ts.map +1 -0
- package/dist/store/kv-store.js +100 -0
- package/dist/store/kv-store.js.map +1 -0
- package/dist/store/secret-wrap.d.ts +109 -0
- package/dist/store/secret-wrap.d.ts.map +1 -0
- package/dist/store/secret-wrap.js +85 -0
- package/dist/store/secret-wrap.js.map +1 -0
- package/dist/trust-tasks/index.d.ts +2 -0
- package/dist/trust-tasks/index.d.ts.map +1 -0
- package/dist/trust-tasks/index.js +2 -0
- package/dist/trust-tasks/index.js.map +1 -0
- package/dist/trust-tasks/sign.d.ts +31 -0
- package/dist/trust-tasks/sign.d.ts.map +1 -0
- package/dist/trust-tasks/sign.js +141 -0
- package/dist/trust-tasks/sign.js.map +1 -0
- package/dist/util/timing.d.ts +14 -0
- package/dist/util/timing.d.ts.map +1 -0
- package/dist/util/timing.js +20 -0
- package/dist/util/timing.js.map +1 -0
- package/dist/vault/delete.d.ts +19 -0
- package/dist/vault/delete.d.ts.map +1 -0
- package/dist/vault/delete.js +35 -0
- package/dist/vault/delete.js.map +1 -0
- package/dist/vault/index.d.ts +8 -0
- package/dist/vault/index.d.ts.map +1 -0
- package/dist/vault/index.js +7 -0
- package/dist/vault/index.js.map +1 -0
- package/dist/vault/list.d.ts +96 -0
- package/dist/vault/list.d.ts.map +1 -0
- package/dist/vault/list.js +106 -0
- package/dist/vault/list.js.map +1 -0
- package/dist/vault/proxy-login.d.ts +100 -0
- package/dist/vault/proxy-login.d.ts.map +1 -0
- package/dist/vault/proxy-login.js +106 -0
- package/dist/vault/proxy-login.js.map +1 -0
- package/dist/vault/release.d.ts +33 -0
- package/dist/vault/release.d.ts.map +1 -0
- package/dist/vault/release.js +83 -0
- package/dist/vault/release.js.map +1 -0
- package/dist/vault/sign-trust-task.d.ts +26 -0
- package/dist/vault/sign-trust-task.d.ts.map +1 -0
- package/dist/vault/sign-trust-task.js +53 -0
- package/dist/vault/sign-trust-task.js.map +1 -0
- package/dist/vault/transport.d.ts +50 -0
- package/dist/vault/transport.d.ts.map +1 -0
- package/dist/vault/transport.js +118 -0
- package/dist/vault/transport.js.map +1 -0
- package/dist/vault/upsert.d.ts +102 -0
- package/dist/vault/upsert.d.ts.map +1 -0
- package/dist/vault/upsert.js +92 -0
- package/dist/vault/upsert.js.map +1 -0
- package/dist/vta/bridge-mediator-session.d.ts +26 -0
- package/dist/vta/bridge-mediator-session.d.ts.map +1 -0
- package/dist/vta/bridge-mediator-session.js +37 -0
- package/dist/vta/bridge-mediator-session.js.map +1 -0
- package/dist/vta/bridge-memory.d.ts +80 -0
- package/dist/vta/bridge-memory.d.ts.map +1 -0
- package/dist/vta/bridge-memory.js +162 -0
- package/dist/vta/bridge-memory.js.map +1 -0
- package/dist/vta/client.d.ts +40 -0
- package/dist/vta/client.d.ts.map +1 -0
- package/dist/vta/client.js +91 -0
- package/dist/vta/client.js.map +1 -0
- package/dist/vta/contexts.d.ts +60 -0
- package/dist/vta/contexts.d.ts.map +1 -0
- package/dist/vta/contexts.js +118 -0
- package/dist/vta/contexts.js.map +1 -0
- package/dist/vta/didcomm.d.ts +57 -0
- package/dist/vta/didcomm.d.ts.map +1 -0
- package/dist/vta/didcomm.js +138 -0
- package/dist/vta/didcomm.js.map +1 -0
- package/dist/vta/errors.d.ts +20 -0
- package/dist/vta/errors.d.ts.map +1 -0
- package/dist/vta/errors.js +64 -0
- package/dist/vta/errors.js.map +1 -0
- package/dist/vta/index.d.ts +15 -0
- package/dist/vta/index.d.ts.map +1 -0
- package/dist/vta/index.js +15 -0
- package/dist/vta/index.js.map +1 -0
- package/dist/vta/mediation.d.ts +80 -0
- package/dist/vta/mediation.d.ts.map +1 -0
- package/dist/vta/mediation.js +29 -0
- package/dist/vta/mediation.js.map +1 -0
- package/dist/vta/mediator-client.d.ts +66 -0
- package/dist/vta/mediator-client.d.ts.map +1 -0
- package/dist/vta/mediator-client.js +139 -0
- package/dist/vta/mediator-client.js.map +1 -0
- package/dist/vta/pickup.d.ts +81 -0
- package/dist/vta/pickup.d.ts.map +1 -0
- package/dist/vta/pickup.js +30 -0
- package/dist/vta/pickup.js.map +1 -0
- package/dist/vta/protocol.d.ts +76 -0
- package/dist/vta/protocol.d.ts.map +1 -0
- package/dist/vta/protocol.js +30 -0
- package/dist/vta/protocol.js.map +1 -0
- package/dist/vta/smoke.d.ts +59 -0
- package/dist/vta/smoke.d.ts.map +1 -0
- package/dist/vta/smoke.js +408 -0
- package/dist/vta/smoke.js.map +1 -0
- package/dist/vta/transport.d.ts +55 -0
- package/dist/vta/transport.d.ts.map +1 -0
- package/dist/vta/transport.js +2 -0
- package/dist/vta/transport.js.map +1 -0
- package/dist/vta/types.d.ts +50 -0
- package/dist/vta/types.d.ts.map +1 -0
- package/dist/vta/types.js +2 -0
- package/dist/vta/types.js.map +1 -0
- package/dist/vta/wallet-session.d.ts +87 -0
- package/dist/vta/wallet-session.d.ts.map +1 -0
- package/dist/vta/wallet-session.js +106 -0
- package/dist/vta/wallet-session.js.map +1 -0
- package/dist/webauthn/base64url.d.ts +3 -0
- package/dist/webauthn/base64url.d.ts.map +1 -0
- package/dist/webauthn/base64url.js +17 -0
- package/dist/webauthn/base64url.js.map +1 -0
- package/dist/webauthn/index.d.ts +4 -0
- package/dist/webauthn/index.d.ts.map +1 -0
- package/dist/webauthn/index.js +4 -0
- package/dist/webauthn/index.js.map +1 -0
- package/dist/webauthn/multikey.d.ts +26 -0
- package/dist/webauthn/multikey.d.ts.map +1 -0
- package/dist/webauthn/multikey.js +91 -0
- package/dist/webauthn/multikey.js.map +1 -0
- package/dist/webauthn/register.d.ts +36 -0
- package/dist/webauthn/register.d.ts.map +1 -0
- package/dist/webauthn/register.js +77 -0
- package/dist/webauthn/register.js.map +1 -0
- package/package.json +56 -0
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// SIOPv2 login client for a Trust-Tasks Relying Party (the DID hosting
|
|
2
|
+
// service). Drives the RP's challenge → authenticate flow: fetch a
|
|
3
|
+
// nonce, self-issue an `id_token` signed by the holder's Ed25519
|
|
4
|
+
// `did:key`, wrap it in the RP's authenticate Trust-Task envelope, and
|
|
5
|
+
// exchange it for a session JWT. No passkey, no DIDComm to the RP — the
|
|
6
|
+
// RP verifies by resolving the holder DID.
|
|
7
|
+
import { createStopwatch } from "../util/timing.js";
|
|
8
|
+
import { issueIdToken } from "./self-issued.js";
|
|
9
|
+
/** The canonical authenticate Trust-Task type from trusttasks-tf.
|
|
10
|
+
* did-hosting + VTA + VTC all dispatch on this same URI. */
|
|
11
|
+
const TASK_AUTH_AUTHENTICATE = "https://trusttasks.org/spec/auth/authenticate/0.1";
|
|
12
|
+
/**
|
|
13
|
+
* Log into a Trust-Tasks RP via SIOPv2 self-issuance. Returns the
|
|
14
|
+
* RP-issued session tokens. Throws on a transport error or an RP
|
|
15
|
+
* rejection (the error message carries the RP's response body).
|
|
16
|
+
*/
|
|
17
|
+
export async function loginViaSiop(opts) {
|
|
18
|
+
const fetchFn = opts.fetch ?? fetch.bind(globalThis);
|
|
19
|
+
const base = opts.baseUrl.replace(/\/+$/, "");
|
|
20
|
+
const sw = createStopwatch();
|
|
21
|
+
// 1. Request a challenge nonce for the holder DID.
|
|
22
|
+
const challengeRes = await fetchFn(`${base}/auth/challenge`, {
|
|
23
|
+
method: "POST",
|
|
24
|
+
headers: { "content-type": "application/json" },
|
|
25
|
+
body: JSON.stringify({ did: opts.signing.did }),
|
|
26
|
+
});
|
|
27
|
+
if (!challengeRes.ok) {
|
|
28
|
+
throw new Error(`siop login: challenge failed (${challengeRes.status}): ${await challengeRes.text()}`);
|
|
29
|
+
}
|
|
30
|
+
// Canonical wire (spec/auth/challenge/0.1#response): flat
|
|
31
|
+
// { challenge, sessionId, expiresAt }. No `data` envelope.
|
|
32
|
+
const challenge = (await challengeRes.json());
|
|
33
|
+
sw.mark("challenge");
|
|
34
|
+
// 2. Self-issue the id_token — aud = the RP's DID, nonce = the challenge.
|
|
35
|
+
const idToken = issueIdToken({
|
|
36
|
+
identity: opts.signing,
|
|
37
|
+
audience: opts.rpDid,
|
|
38
|
+
nonce: challenge.challenge,
|
|
39
|
+
});
|
|
40
|
+
sw.mark("id_token signed");
|
|
41
|
+
// 3. Wrap in the RP's authenticate Trust-Task envelope.
|
|
42
|
+
const envelope = {
|
|
43
|
+
id: `urn:uuid:${globalThis.crypto.randomUUID()}`,
|
|
44
|
+
type: TASK_AUTH_AUTHENTICATE,
|
|
45
|
+
issuer: opts.signing.did,
|
|
46
|
+
issuedAt: new Date().toISOString(),
|
|
47
|
+
payload: {
|
|
48
|
+
id_token: idToken,
|
|
49
|
+
session_id: challenge.sessionId,
|
|
50
|
+
...(opts.sessionPubkeyB58btc
|
|
51
|
+
? { session_pubkey_b58btc: opts.sessionPubkeyB58btc }
|
|
52
|
+
: {}),
|
|
53
|
+
},
|
|
54
|
+
};
|
|
55
|
+
// 4. Exchange for a session JWT.
|
|
56
|
+
const authRes = await fetchFn(`${base}/auth/`, {
|
|
57
|
+
method: "POST",
|
|
58
|
+
headers: { "content-type": "application/json" },
|
|
59
|
+
body: JSON.stringify(envelope),
|
|
60
|
+
});
|
|
61
|
+
if (!authRes.ok) {
|
|
62
|
+
throw new Error(`siop login: authenticate failed (${authRes.status}): ${await authRes.text()}`);
|
|
63
|
+
}
|
|
64
|
+
// Canonical wire (spec/auth/authenticate/0.1#response):
|
|
65
|
+
// { session: Session, tokens: TokenBundle }. Session.id is the
|
|
66
|
+
// session identifier; tokens.{accessToken, refreshToken} carry
|
|
67
|
+
// the bearer material. `expiresIn` is seconds-from-issuance per
|
|
68
|
+
// RFC 6749 §5.1 — clients compute the absolute moment as
|
|
69
|
+
// Date.parse(session.issuedAt) + tokens.expiresIn * 1000.
|
|
70
|
+
const r = (await authRes.json());
|
|
71
|
+
sw.mark("authenticate");
|
|
72
|
+
return {
|
|
73
|
+
timings: sw.marks,
|
|
74
|
+
accessToken: r.tokens.accessToken,
|
|
75
|
+
refreshToken: r.tokens.refreshToken ?? "",
|
|
76
|
+
sessionId: r.session.id,
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=login-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"login-client.js","sourceRoot":"","sources":["../../src/siop/login-client.ts"],"names":[],"mappings":"AAAA,uEAAuE;AACvE,mEAAmE;AACnE,iEAAiE;AACjE,uEAAuE;AACvE,wEAAwE;AACxE,2CAA2C;AAE3C,OAAO,EAAE,eAAe,EAAmB,MAAM,mBAAmB,CAAC;AACrE,OAAO,EAAE,YAAY,EAAwB,MAAM,kBAAkB,CAAC;AAEtE;6DAC6D;AAC7D,MAAM,sBAAsB,GAAG,mDAAmD,CAAC;AAwBnF;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAsB;IAEtB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IACrD,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC9C,MAAM,EAAE,GAAG,eAAe,EAAE,CAAC;IAE7B,mDAAmD;IACnD,MAAM,YAAY,GAAG,MAAM,OAAO,CAAC,GAAG,IAAI,iBAAiB,EAAE;QAC3D,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;KAChD,CAAC,CAAC;IACH,IAAI,CAAC,YAAY,CAAC,EAAE,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,iCAAiC,YAAY,CAAC,MAAM,MAAM,MAAM,YAAY,CAAC,IAAI,EAAE,EAAE,CACtF,CAAC;IACJ,CAAC;IACD,0DAA0D;IAC1D,2DAA2D;IAC3D,MAAM,SAAS,GAAG,CAAC,MAAM,YAAY,CAAC,IAAI,EAAE,CAI3C,CAAC;IACF,EAAE,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAErB,0EAA0E;IAC1E,MAAM,OAAO,GAAG,YAAY,CAAC;QAC3B,QAAQ,EAAE,IAAI,CAAC,OAAO;QACtB,QAAQ,EAAE,IAAI,CAAC,KAAK;QACpB,KAAK,EAAE,SAAS,CAAC,SAAS;KAC3B,CAAC,CAAC;IACH,EAAE,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;IAE3B,wDAAwD;IACxD,MAAM,QAAQ,GAAG;QACf,EAAE,EAAE,YAAY,UAAU,CAAC,MAAM,CAAC,UAAU,EAAE,EAAE;QAChD,IAAI,EAAE,sBAAsB;QAC5B,MAAM,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG;QACxB,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QAClC,OAAO,EAAE;YACP,QAAQ,EAAE,OAAO;YACjB,UAAU,EAAE,SAAS,CAAC,SAAS;YAC/B,GAAG,CAAC,IAAI,CAAC,mBAAmB;gBAC1B,CAAC,CAAC,EAAE,qBAAqB,EAAE,IAAI,CAAC,mBAAmB,EAAE;gBACrD,CAAC,CAAC,EAAE,CAAC;SACR;KACF,CAAC;IAEF,iCAAiC;IACjC,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,IAAI,QAAQ,EAAE;QAC7C,MAAM,EAAE,MAAM;QACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;QAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC;KAC/B,CAAC,CAAC;IACH,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,oCAAoC,OAAO,CAAC,MAAM,MAAM,MAAM,OAAO,CAAC,IAAI,EAAE,EAAE,CAC/E,CAAC;IACJ,CAAC;IACD,wDAAwD;IACxD,+DAA+D;IAC/D,+DAA+D;IAC/D,gEAAgE;IAChE,yDAAyD;IACzD,0DAA0D;IAC1D,MAAM,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,IAAI,EAAE,CAgB9B,CAAC;IACF,EAAE,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACxB,OAAO;QACL,OAAO,EAAE,EAAE,CAAC,KAAK;QACjB,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,WAAW;QACjC,YAAY,EAAE,CAAC,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE;QACzC,SAAS,EAAE,CAAC,CAAC,OAAO,CAAC,EAAE;KACxB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/** An Ed25519 `did:key` signing identity. `privateKey` is held in JS
|
|
2
|
+
* memory (the accepted trade-off for the no-passkey path — see the
|
|
3
|
+
* step-up flow for hardware-backed signing). */
|
|
4
|
+
export interface SigningIdentity {
|
|
5
|
+
/** `did:key:z6Mk…` */
|
|
6
|
+
did: string;
|
|
7
|
+
/** Verification-method id for the signing key (`<did>#z6Mk…`). */
|
|
8
|
+
kid: string;
|
|
9
|
+
privateKey: Uint8Array;
|
|
10
|
+
publicKey: Uint8Array;
|
|
11
|
+
}
|
|
12
|
+
/** Mint a fresh Ed25519 `did:key` signing identity. */
|
|
13
|
+
export declare function generateSigningIdentity(): SigningIdentity;
|
|
14
|
+
/** Reconstruct a signing identity from a stored Ed25519 private key. */
|
|
15
|
+
export declare function signingIdentityFromSecret(privateKey: Uint8Array): SigningIdentity;
|
|
16
|
+
export interface IssueIdTokenOptions {
|
|
17
|
+
identity: SigningIdentity;
|
|
18
|
+
/** RP identifier the token is bound to (`aud`) — its DID or client_id. */
|
|
19
|
+
audience: string;
|
|
20
|
+
/** RP-supplied nonce echoed in the token (replay protection). */
|
|
21
|
+
nonce: string;
|
|
22
|
+
/** Token lifetime in seconds (default 300). */
|
|
23
|
+
ttlSeconds?: number;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Issue a self-issued `id_token` (compact EdDSA JWS). `iss` and `sub`
|
|
27
|
+
* are the holder DID; the RP verifies by resolving that DID and checking
|
|
28
|
+
* the signature against its authentication key.
|
|
29
|
+
*/
|
|
30
|
+
export declare function issueIdToken(opts: IssueIdTokenOptions): string;
|
|
31
|
+
export interface IssueSwapPresentationOptions {
|
|
32
|
+
/** The signing identity proving control of the **new** DID (the wallet's
|
|
33
|
+
* long-term holder did:peer, `#key-2`). The presentation's `holder` is its
|
|
34
|
+
* DID — what the swap creates the new ACL entry for. */
|
|
35
|
+
holder: SigningIdentity;
|
|
36
|
+
/** The VTA's DID — bound as `aud` so the proof can't be replayed elsewhere. */
|
|
37
|
+
audience: string;
|
|
38
|
+
/** Lifetime in seconds (default 300). */
|
|
39
|
+
ttlSeconds?: number;
|
|
40
|
+
/** Optional explicit nonce; a random one is generated when omitted. */
|
|
41
|
+
nonce?: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Issue a swap-acl presentation: a W3C Verifiable Presentation secured as a
|
|
45
|
+
* compact EdDSA JWS (VP-JWT), proving control of the holder DID. The VTA's
|
|
46
|
+
* `swap-acl` handler resolves `iss` and verifies this signature against the
|
|
47
|
+
* holder's key, then moves the caller's ACL entry onto it. Same signing
|
|
48
|
+
* primitive as {@link issueIdToken} — just a VP envelope instead of an
|
|
49
|
+
* id_token.
|
|
50
|
+
*/
|
|
51
|
+
export declare function issueSwapPresentation(opts: IssueSwapPresentationOptions): string;
|
|
52
|
+
export interface VerifiedIdToken {
|
|
53
|
+
/** The holder DID that signed the token (`iss`/`sub`). */
|
|
54
|
+
did: string;
|
|
55
|
+
claims: {
|
|
56
|
+
iss: string;
|
|
57
|
+
sub: string;
|
|
58
|
+
aud: string;
|
|
59
|
+
nonce: string;
|
|
60
|
+
iat: number;
|
|
61
|
+
exp: number;
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Verify a self-issued `id_token`: resolve the `did:key`, check the
|
|
66
|
+
* EdDSA signature against its authentication VM, and enforce
|
|
67
|
+
* `aud` / `nonce` / `exp`. Throws on any failure.
|
|
68
|
+
*/
|
|
69
|
+
export declare function verifyIdToken(jwt: string, expect: {
|
|
70
|
+
audience: string;
|
|
71
|
+
nonce: string;
|
|
72
|
+
now?: number;
|
|
73
|
+
}): VerifiedIdToken;
|
|
74
|
+
/** The X25519 keyAgreement material derived from an Ed25519 signing
|
|
75
|
+
* identity, ready to build a DIDComm `Identity`. */
|
|
76
|
+
export interface DidcommKeyAgreement {
|
|
77
|
+
/** keyAgreement VM id (`<did>#<x25519-multibase>`), as the did:key resolver emits it. */
|
|
78
|
+
keyAgreementKid: string;
|
|
79
|
+
/** X25519 secret JWK ({kty:OKP, crv:X25519, x, d}). */
|
|
80
|
+
secretJwk: {
|
|
81
|
+
kty: "OKP";
|
|
82
|
+
crv: "X25519";
|
|
83
|
+
x: string;
|
|
84
|
+
d: string;
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Derive the DIDComm X25519 keyAgreement material from an Ed25519
|
|
89
|
+
* {@link SigningIdentity}. The X25519 key is the Montgomery form of the
|
|
90
|
+
* same key — exactly as the `did:key` resolver derives the keyAgreement
|
|
91
|
+
* VM — so one Ed25519 `did:key` serves both login (signing) and DIDComm
|
|
92
|
+
* (authcrypt) under a single DID. The kid is taken from the resolver so
|
|
93
|
+
* it matches byte-for-byte what counterparties address replies to.
|
|
94
|
+
*/
|
|
95
|
+
export declare function didcommKeyAgreementFromSigning(identity: SigningIdentity): DidcommKeyAgreement;
|
|
96
|
+
//# sourceMappingURL=self-issued.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-issued.d.ts","sourceRoot":"","sources":["../../src/siop/self-issued.ts"],"names":[],"mappings":"AAkBA;;iDAEiD;AACjD,MAAM,WAAW,eAAe;IAC9B,sBAAsB;IACtB,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,UAAU,EAAE,UAAU,CAAC;IACvB,SAAS,EAAE,UAAU,CAAC;CACvB;AAED,uDAAuD;AACvD,wBAAgB,uBAAuB,IAAI,eAAe,CAIzD;AAED,wEAAwE;AACxE,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,UAAU,GAAG,eAAe,CAEjF;AAWD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,eAAe,CAAC;IAC1B,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAC;IACjB,iEAAiE;IACjE,KAAK,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,mBAAmB,GAAG,MAAM,CAc9D;AAED,MAAM,WAAW,4BAA4B;IAC3C;;6DAEyD;IACzD,MAAM,EAAE,eAAe,CAAC;IACxB,+EAA+E;IAC/E,QAAQ,EAAE,MAAM,CAAC;IACjB,yCAAyC;IACzC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;GAOG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,4BAA4B,GAAG,MAAM,CAoBhF;AAED,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE;QACN,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;QACZ,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,MAAM,EACX,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,CAAC,EAAE,MAAM,CAAA;CAAE,GACxD,eAAe,CAkCjB;AAqBD;qDACqD;AACrD,MAAM,WAAW,mBAAmB;IAClC,yFAAyF;IACzF,eAAe,EAAE,MAAM,CAAC;IACxB,uDAAuD;IACvD,SAAS,EAAE;QAAE,GAAG,EAAE,KAAK,CAAC;QAAC,GAAG,EAAE,QAAQ,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChE;AAED;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,eAAe,GACxB,mBAAmB,CAmBrB"}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// Self-Issued OpenID Provider v2 (SIOPv2) — the wallet self-issues an
|
|
2
|
+
// `id_token` proving control of its `did:key`, which a Relying Party
|
|
3
|
+
// verifies by resolving the DID. No passwords, no per-site passkey, no
|
|
4
|
+
// round-trip to the VTA: the holder key signs locally and the DID is
|
|
5
|
+
// self-certifying (resolvable without any server).
|
|
6
|
+
//
|
|
7
|
+
// This is the base login primitive. A `did:key` here is an **Ed25519**
|
|
8
|
+
// key (multicodec 0xed01) because the credential must SIGN — an
|
|
9
|
+
// X25519-only `did:key` can only do ECDH (DIDComm authcrypt) and cannot
|
|
10
|
+
// produce a JWS. The same Ed25519 key also yields a derived X25519
|
|
11
|
+
// keyAgreement key for DIDComm (see did:key resolution), so one identity
|
|
12
|
+
// covers both login and DIDComm.
|
|
13
|
+
import { ed25519, x25519 } from "@noble/curves/ed25519.js";
|
|
14
|
+
import { base64url, didKey, multibase } from "@openvtc/vti-didcomm-js";
|
|
15
|
+
const ED25519_PUB = multibase.MULTICODEC.ED25519_PUB;
|
|
16
|
+
/** Mint a fresh Ed25519 `did:key` signing identity. */
|
|
17
|
+
export function generateSigningIdentity() {
|
|
18
|
+
const privateKey = ed25519.utils.randomSecretKey();
|
|
19
|
+
const publicKey = ed25519.getPublicKey(privateKey);
|
|
20
|
+
return signingIdentityFromKeys(privateKey, publicKey);
|
|
21
|
+
}
|
|
22
|
+
/** Reconstruct a signing identity from a stored Ed25519 private key. */
|
|
23
|
+
export function signingIdentityFromSecret(privateKey) {
|
|
24
|
+
return signingIdentityFromKeys(privateKey, ed25519.getPublicKey(privateKey));
|
|
25
|
+
}
|
|
26
|
+
function signingIdentityFromKeys(privateKey, publicKey) {
|
|
27
|
+
const mb = multibase.encodeMultikey(ED25519_PUB, publicKey);
|
|
28
|
+
const did = `did:key:${mb}`;
|
|
29
|
+
return { did, kid: `${did}#${mb}`, privateKey, publicKey };
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Issue a self-issued `id_token` (compact EdDSA JWS). `iss` and `sub`
|
|
33
|
+
* are the holder DID; the RP verifies by resolving that DID and checking
|
|
34
|
+
* the signature against its authentication key.
|
|
35
|
+
*/
|
|
36
|
+
export function issueIdToken(opts) {
|
|
37
|
+
const now = Math.floor(Date.now() / 1000);
|
|
38
|
+
const header = { alg: "EdDSA", typ: "JWT", kid: opts.identity.kid };
|
|
39
|
+
const payload = {
|
|
40
|
+
iss: opts.identity.did,
|
|
41
|
+
sub: opts.identity.did,
|
|
42
|
+
aud: opts.audience,
|
|
43
|
+
nonce: opts.nonce,
|
|
44
|
+
iat: now,
|
|
45
|
+
exp: now + (opts.ttlSeconds ?? 300),
|
|
46
|
+
};
|
|
47
|
+
const signingInput = `${b64uJson(header)}.${b64uJson(payload)}`;
|
|
48
|
+
const sig = ed25519.sign(new TextEncoder().encode(signingInput), opts.identity.privateKey);
|
|
49
|
+
return `${signingInput}.${base64url.encode(sig)}`;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Issue a swap-acl presentation: a W3C Verifiable Presentation secured as a
|
|
53
|
+
* compact EdDSA JWS (VP-JWT), proving control of the holder DID. The VTA's
|
|
54
|
+
* `swap-acl` handler resolves `iss` and verifies this signature against the
|
|
55
|
+
* holder's key, then moves the caller's ACL entry onto it. Same signing
|
|
56
|
+
* primitive as {@link issueIdToken} — just a VP envelope instead of an
|
|
57
|
+
* id_token.
|
|
58
|
+
*/
|
|
59
|
+
export function issueSwapPresentation(opts) {
|
|
60
|
+
const now = Math.floor(Date.now() / 1000);
|
|
61
|
+
const nonce = opts.nonce ?? base64url.encode(globalThis.crypto.getRandomValues(new Uint8Array(16)));
|
|
62
|
+
const header = { alg: "EdDSA", typ: "JWT", kid: opts.holder.kid };
|
|
63
|
+
const payload = {
|
|
64
|
+
iss: opts.holder.did,
|
|
65
|
+
aud: opts.audience,
|
|
66
|
+
iat: now,
|
|
67
|
+
exp: now + (opts.ttlSeconds ?? 300),
|
|
68
|
+
nonce,
|
|
69
|
+
vp: {
|
|
70
|
+
"@context": ["https://www.w3.org/ns/credentials/v2"],
|
|
71
|
+
type: ["VerifiablePresentation", "AclSwapRequest"],
|
|
72
|
+
holder: opts.holder.did,
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
const signingInput = `${b64uJson(header)}.${b64uJson(payload)}`;
|
|
76
|
+
const sig = ed25519.sign(new TextEncoder().encode(signingInput), opts.holder.privateKey);
|
|
77
|
+
return `${signingInput}.${base64url.encode(sig)}`;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Verify a self-issued `id_token`: resolve the `did:key`, check the
|
|
81
|
+
* EdDSA signature against its authentication VM, and enforce
|
|
82
|
+
* `aud` / `nonce` / `exp`. Throws on any failure.
|
|
83
|
+
*/
|
|
84
|
+
export function verifyIdToken(jwt, expect) {
|
|
85
|
+
const parts = jwt.split(".");
|
|
86
|
+
if (parts.length !== 3)
|
|
87
|
+
throw new Error("siop: malformed JWS (expected 3 parts)");
|
|
88
|
+
const [h, p, s] = parts;
|
|
89
|
+
const header = jsonFromB64u(h);
|
|
90
|
+
if (header.alg !== "EdDSA") {
|
|
91
|
+
throw new Error(`siop: unsupported alg ${JSON.stringify(header.alg)}; expected EdDSA`);
|
|
92
|
+
}
|
|
93
|
+
const claims = jsonFromB64u(p);
|
|
94
|
+
if (typeof claims.iss !== "string" || claims.iss !== claims.sub) {
|
|
95
|
+
throw new Error("siop: iss/sub missing or mismatched (must be the self-issued DID)");
|
|
96
|
+
}
|
|
97
|
+
// Resolve the DID and pull its authentication signing key.
|
|
98
|
+
const signingKey = ed25519AuthKey(claims.iss);
|
|
99
|
+
const ok = ed25519.verify(base64url.decode(s), new TextEncoder().encode(`${h}.${p}`), signingKey);
|
|
100
|
+
if (!ok)
|
|
101
|
+
throw new Error("siop: signature does not verify against the DID's key");
|
|
102
|
+
if (claims.aud !== expect.audience) {
|
|
103
|
+
throw new Error(`siop: aud ${JSON.stringify(claims.aud)} != ${JSON.stringify(expect.audience)}`);
|
|
104
|
+
}
|
|
105
|
+
if (claims.nonce !== expect.nonce) {
|
|
106
|
+
throw new Error("siop: nonce mismatch (possible replay)");
|
|
107
|
+
}
|
|
108
|
+
const now = expect.now ?? Math.floor(Date.now() / 1000);
|
|
109
|
+
if (typeof claims.exp !== "number" || claims.exp < now) {
|
|
110
|
+
throw new Error("siop: token expired");
|
|
111
|
+
}
|
|
112
|
+
return { did: claims.iss, claims };
|
|
113
|
+
}
|
|
114
|
+
/** Resolve a `did:key` and return its Ed25519 authentication key bytes. */
|
|
115
|
+
function ed25519AuthKey(did) {
|
|
116
|
+
const doc = didKey.resolve(did).didDocument;
|
|
117
|
+
const authId = doc.authentication?.[0];
|
|
118
|
+
if (!authId)
|
|
119
|
+
throw new Error(`siop: ${did} has no authentication method (not a signing DID)`);
|
|
120
|
+
const vm = (doc.verificationMethod ?? []).find((v) => v.id === authId);
|
|
121
|
+
if (!vm?.publicKeyMultibase) {
|
|
122
|
+
throw new Error("siop: authentication VM missing publicKeyMultibase");
|
|
123
|
+
}
|
|
124
|
+
const { codec, key } = multibase.decodeMultikey(vm.publicKeyMultibase);
|
|
125
|
+
if (codec[0] !== ED25519_PUB[0] || codec[1] !== ED25519_PUB[1]) {
|
|
126
|
+
throw new Error("siop: authentication key is not Ed25519");
|
|
127
|
+
}
|
|
128
|
+
return key;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Derive the DIDComm X25519 keyAgreement material from an Ed25519
|
|
132
|
+
* {@link SigningIdentity}. The X25519 key is the Montgomery form of the
|
|
133
|
+
* same key — exactly as the `did:key` resolver derives the keyAgreement
|
|
134
|
+
* VM — so one Ed25519 `did:key` serves both login (signing) and DIDComm
|
|
135
|
+
* (authcrypt) under a single DID. The kid is taken from the resolver so
|
|
136
|
+
* it matches byte-for-byte what counterparties address replies to.
|
|
137
|
+
*/
|
|
138
|
+
export function didcommKeyAgreementFromSigning(identity) {
|
|
139
|
+
const xPriv = ed25519.utils.toMontgomerySecret(identity.privateKey);
|
|
140
|
+
const xPub = x25519.getPublicKey(xPriv);
|
|
141
|
+
const doc = didKey.resolve(identity.did).didDocument;
|
|
142
|
+
const keyAgreementKid = doc.keyAgreement?.[0];
|
|
143
|
+
if (!keyAgreementKid) {
|
|
144
|
+
throw new Error("siop: Ed25519 did:key has no keyAgreement VM");
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
keyAgreementKid,
|
|
148
|
+
secretJwk: {
|
|
149
|
+
kty: "OKP",
|
|
150
|
+
crv: "X25519",
|
|
151
|
+
x: base64url.encode(xPub),
|
|
152
|
+
d: base64url.encode(xPriv),
|
|
153
|
+
},
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
function b64uJson(value) {
|
|
157
|
+
return base64url.encode(new TextEncoder().encode(JSON.stringify(value)));
|
|
158
|
+
}
|
|
159
|
+
function jsonFromB64u(segment) {
|
|
160
|
+
return JSON.parse(new TextDecoder().decode(base64url.decode(segment)));
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=self-issued.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"self-issued.js","sourceRoot":"","sources":["../../src/siop/self-issued.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { Identity } from "../didcomm/index.js";
|
|
2
|
+
import type { SigningIdentity } from "../siop/index.js";
|
|
3
|
+
import type { KVStore } from "./kv-store.js";
|
|
4
|
+
import { type SecretWrap } from "./secret-wrap.js";
|
|
5
|
+
export interface HolderIdentityResult {
|
|
6
|
+
/** DIDComm key-agreement identity (X25519, `#key-1`) — used for authcrypt. */
|
|
7
|
+
identity: Identity;
|
|
8
|
+
/** Signing identity (Ed25519, `#key-2`) — self-issues SIOPv2 login
|
|
9
|
+
* `id_token`s and signs trust-task proofs. `.did` is the did:peer. */
|
|
10
|
+
signing: SigningIdentity;
|
|
11
|
+
/** True if this run minted a fresh identity (first launch); false if loaded. */
|
|
12
|
+
freshlyMinted: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface HolderIdentityOptions {
|
|
15
|
+
/** When set, the minted DID advertises a `DIDCommMessaging` service whose
|
|
16
|
+
* endpoint is this mediator DID — making the wallet reachable for inbound
|
|
17
|
+
* DIDComm. Only honoured on a FRESH mint (the persisted DID is immutable).
|
|
18
|
+
* Omit to mint a keys-only did:peer (sufficient for outbound login). */
|
|
19
|
+
mediatorDid?: string;
|
|
20
|
+
/**
|
|
21
|
+
* H1: encryption wrapper for the persisted Ed25519 secret.
|
|
22
|
+
* When supplied, fresh mints write `wrappedSecret` instead of
|
|
23
|
+
* `edSecretB64u`, and existing wallets stored with a matching
|
|
24
|
+
* wrap require the wrap on load to decrypt.
|
|
25
|
+
*
|
|
26
|
+
* Omit (or supply `PassthroughWrap`) for tests and legacy
|
|
27
|
+
* callers. Production extension wrappers supply a
|
|
28
|
+
* `WebAuthnPrfSecretWrap` so an exfiltrated IndexedDB row is
|
|
29
|
+
* useless without the operator's authenticator.
|
|
30
|
+
*
|
|
31
|
+
* Backward compatibility: a record written before this option
|
|
32
|
+
* landed (no `wrappedSecret`, plaintext `edSecretB64u`) loads
|
|
33
|
+
* regardless of whether a wrap is supplied — the loader
|
|
34
|
+
* detects the legacy shape and reads the plaintext. The
|
|
35
|
+
* **next save** (e.g. mediator-DID rotation, future schema
|
|
36
|
+
* upgrade) will re-persist using the wrap, migrating the
|
|
37
|
+
* record forward.
|
|
38
|
+
*/
|
|
39
|
+
secretWrap?: SecretWrap;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Generate-or-load the wallet's holder identity (a `did:peer:2`) from a
|
|
43
|
+
* `KVStore`. Only the Ed25519 secret is persisted; the DID + kids are
|
|
44
|
+
* persisted alongside it (the DID is immutable once minted), and the X25519
|
|
45
|
+
* keyAgreement key is re-derived on every load.
|
|
46
|
+
*
|
|
47
|
+
* Persistence is wrapped via the optional [`HolderIdentityOptions.secretWrap`]
|
|
48
|
+
* — production extensions supply a `WebAuthnPrfSecretWrap` so storage
|
|
49
|
+
* exfil yields ciphertext, not the wallet's signing key. Callers that
|
|
50
|
+
* omit the wrap fall back to plaintext (legacy behaviour); the
|
|
51
|
+
* loader handles both shapes for backward compatibility.
|
|
52
|
+
*/
|
|
53
|
+
export declare function generateOrLoadHolderIdentity(store: KVStore, opts?: HolderIdentityOptions): Promise<HolderIdentityResult>;
|
|
54
|
+
/** Forget every persisted holder identity. Mostly for tests / hard
|
|
55
|
+
* reset (the options page "wipe wallet" button). Clears the v3 row,
|
|
56
|
+
* the legacy single-VTA v4 row, AND every per-vta v4 record. After
|
|
57
|
+
* this the wallet looks freshly installed at every VTA. */
|
|
58
|
+
export declare function clearHolderIdentity(store: KVStore): Promise<void>;
|
|
59
|
+
/** Thrown by `loadHolderStrict` when neither a v3 nor a v4 holder record
|
|
60
|
+
* exists — the wallet is on a fresh install and the operator should
|
|
61
|
+
* proceed with onboarding. */
|
|
62
|
+
export declare class NoHolderError extends Error {
|
|
63
|
+
constructor();
|
|
64
|
+
}
|
|
65
|
+
/** Thrown by `loadHolderStrict` when a v3 (self-derived did:peer) record
|
|
66
|
+
* exists but no v4 (VTA-minted did:key) record. The wallet was built
|
|
67
|
+
* before the M2C identity migration; the operator must re-onboard so the
|
|
68
|
+
* VTA mints a fresh long-term DID. The old did:peer is unusable as the
|
|
69
|
+
* wallet's holder going forward — every RP that recognised it must be
|
|
70
|
+
* re-granted with the new VTA-minted DID.
|
|
71
|
+
*
|
|
72
|
+
* `previousDid` is the v3 DID, surfaced for the migration UI so the
|
|
73
|
+
* operator can audit what they're abandoning. */
|
|
74
|
+
export declare class RequiresReonboardError extends Error {
|
|
75
|
+
readonly previousDid: string;
|
|
76
|
+
constructor(previousDid: string);
|
|
77
|
+
}
|
|
78
|
+
export interface LoadHolderStrictOptions {
|
|
79
|
+
/** Which VTA's holder identity to load. Each VTA the wallet has been
|
|
80
|
+
* onboarded at has its own per-VTA holder record (the v4 schema is
|
|
81
|
+
* multi-instance — one record per VTA). Pass the VTA DID the
|
|
82
|
+
* operation is targeting; the store contains exactly one v4 record
|
|
83
|
+
* per `(vtaDid)` pair. */
|
|
84
|
+
vtaDid: string;
|
|
85
|
+
/** Wrap that decrypts the persisted Ed25519 seed. Same semantics as
|
|
86
|
+
* `HolderIdentityOptions.secretWrap` — omit for plaintext (tests /
|
|
87
|
+
* legacy), supply a `WebAuthnPrfSecretWrap` in production. */
|
|
88
|
+
secretWrap?: SecretWrap;
|
|
89
|
+
}
|
|
90
|
+
/** Load the wallet's holder identity for the given VTA, strictly
|
|
91
|
+
* preferring v4.
|
|
92
|
+
*
|
|
93
|
+
* - v4 record for `vtaDid` present → return the VTA-minted holder.
|
|
94
|
+
* - no v4 record for `vtaDid` but a legacy single-VTA v4 record
|
|
95
|
+
* exists → migrate it to the per-vta path (transparently) and
|
|
96
|
+
* return if its `vtaDid` matches the requested one.
|
|
97
|
+
* - no v4 (for `vtaDid` or legacy) but v3 present → throw
|
|
98
|
+
* `RequiresReonboardError` (the operator needs to re-onboard so the
|
|
99
|
+
* VTA mints a v4 identity).
|
|
100
|
+
* - none of the above → throw `NoHolderError` (fresh install). */
|
|
101
|
+
export declare function loadHolderStrict(store: KVStore, opts: LoadHolderStrictOptions): Promise<HolderIdentityResult>;
|
|
102
|
+
export interface InstallVtaMintedHolderOptions {
|
|
103
|
+
/** The freshly-minted did:key the VTA shipped (e.g. `did:key:z6Mk…`). */
|
|
104
|
+
did: string;
|
|
105
|
+
/** Ed25519 verification-method id (`<did>#<ed-mb>`). The VTA's
|
|
106
|
+
* template renderer emits this; for `vta-admin` the fragment is the
|
|
107
|
+
* Ed25519 public-key multibase. */
|
|
108
|
+
signingKid: string;
|
|
109
|
+
/** X25519 keyAgreement verification-method id (`<did>#<x-mb>`).
|
|
110
|
+
* Derived from the Ed25519 pubkey via Montgomery clamping; the VTA
|
|
111
|
+
* also emits this in the sealed bundle. */
|
|
112
|
+
keyAgreementKid: string;
|
|
113
|
+
/** 32-byte Ed25519 seed the VTA minted and shipped sealed. The wallet
|
|
114
|
+
* decoded it from the bundle's `admin.signing_key.private_key_multibase`. */
|
|
115
|
+
edSeed: Uint8Array;
|
|
116
|
+
/** Provenance — the VTA that minted this identity. */
|
|
117
|
+
vtaDid: string;
|
|
118
|
+
/** VTA's REST base URL, if advertised. */
|
|
119
|
+
vtaUrl?: string;
|
|
120
|
+
/** Optional secret wrap. Production extensions supply a
|
|
121
|
+
* WebAuthnPrfSecretWrap; tests omit. */
|
|
122
|
+
secretWrap?: SecretWrap;
|
|
123
|
+
}
|
|
124
|
+
/** Persist a freshly-minted VTA holder as the wallet's v4 identity.
|
|
125
|
+
*
|
|
126
|
+
* Returns the rebuilt `HolderIdentityResult` so the caller can use the
|
|
127
|
+
* identity immediately without an extra load. Clears any pre-existing
|
|
128
|
+
* v3 record on a successful install — the migration is a one-way move
|
|
129
|
+
* and a stale v3 record sitting alongside v4 is just a footgun for a
|
|
130
|
+
* future loader. */
|
|
131
|
+
export declare function installVtaMintedHolder(store: KVStore, opts: InstallVtaMintedHolderOptions): Promise<HolderIdentityResult>;
|
|
132
|
+
export interface RewrapHolderV4Options {
|
|
133
|
+
/** Which VTA's holder record to re-wrap. Multi-VTA: each VTA has
|
|
134
|
+
* its own v4 record; the rewrap targets exactly one. */
|
|
135
|
+
vtaDid: string;
|
|
136
|
+
/** Wrap that DECRYPTS the currently-persisted v4 record. Pass the
|
|
137
|
+
* wrap the wallet was using before the migration. Pass `undefined`
|
|
138
|
+
* when the existing record uses `PassthroughWrap` (plaintext),
|
|
139
|
+
* which is the typical post-onboard state. */
|
|
140
|
+
fromWrap?: SecretWrap;
|
|
141
|
+
/** Wrap to apply on the re-persisted record. Pass the wrap the
|
|
142
|
+
* wallet should use going forward (e.g. a `WebAuthnPrfSecretWrap`
|
|
143
|
+
* in the popup's visible context). Pass `undefined` to switch
|
|
144
|
+
* back to plaintext. */
|
|
145
|
+
toWrap?: SecretWrap;
|
|
146
|
+
}
|
|
147
|
+
/** Re-wrap the persisted v4 holder secret in place, preserving the
|
|
148
|
+
* wallet's DID + verification-method ids + VTA provenance.
|
|
149
|
+
*
|
|
150
|
+
* The canonical caller is the popup's post-onboard "Encrypt your
|
|
151
|
+
* wallet?" prompt: the operator clicks the button, the popup runs
|
|
152
|
+
* `navigator.credentials.create` (visible context, fresh user
|
|
153
|
+
* gesture), and re-wraps the existing passthrough record under
|
|
154
|
+
* the PRF-derived AES-GCM key. The wallet DID stays the same — no
|
|
155
|
+
* re-grant in any RP ACL, no re-onboarding.
|
|
156
|
+
*
|
|
157
|
+
* Mirrors the v3 `rewrapHolderSecret` but reads + writes the v4
|
|
158
|
+
* record (`STORE_KEY_V4`). Future cleanup could consolidate the
|
|
159
|
+
* two into one schema-version-aware function; kept separate for
|
|
160
|
+
* now so the v3 path's legacy `edSecretB64u` fallback doesn't
|
|
161
|
+
* leak into v4's cleaner shape.
|
|
162
|
+
*
|
|
163
|
+
* Throws if no v4 record exists. The popup should only invoke this
|
|
164
|
+
* AFTER `installVtaMintedHolder` has run. */
|
|
165
|
+
export declare function rewrapHolderV4Secret(store: KVStore, opts: RewrapHolderV4Options): Promise<HolderIdentityResult>;
|
|
166
|
+
export type HolderIdentityStateResult = {
|
|
167
|
+
kind: "none";
|
|
168
|
+
} | {
|
|
169
|
+
kind: "v3";
|
|
170
|
+
did: string;
|
|
171
|
+
} | {
|
|
172
|
+
kind: "v4";
|
|
173
|
+
did: string;
|
|
174
|
+
vtaDid: string;
|
|
175
|
+
wrapAlgorithm: string;
|
|
176
|
+
};
|
|
177
|
+
/** Inspect the persisted state without throwing. Used by the popup to
|
|
178
|
+
* decide which onboarding screen to show.
|
|
179
|
+
*
|
|
180
|
+
* For v4 records, `wrapAlgorithm` reveals whether the secret is
|
|
181
|
+
* encrypted at rest. `"passthrough"` means plaintext (the operator
|
|
182
|
+
* hasn't enabled encryption); anything else (currently only
|
|
183
|
+
* `"webauthn-prf-aes-gcm"`) means the popup needs to run an
|
|
184
|
+
* unlock ceremony before offscreen can load the holder identity.
|
|
185
|
+
*
|
|
186
|
+
* When `vtaDid` is passed: returns the state for that specific
|
|
187
|
+
* VTA's holder record. Used by the popup's active-VTA probe.
|
|
188
|
+
* When `vtaDid` is omitted: returns the first v4 record found
|
|
189
|
+
* (after migrating any legacy single-VTA row), else falls back to
|
|
190
|
+
* v3 / none. Used for the initial fresh-install / migration-banner
|
|
191
|
+
* decision before an active VTA has been selected. */
|
|
192
|
+
export declare function holderIdentityState(store: KVStore, vtaDid?: string): Promise<HolderIdentityStateResult>;
|
|
193
|
+
export interface HolderRecordSummary {
|
|
194
|
+
vtaDid: string;
|
|
195
|
+
did: string;
|
|
196
|
+
/** Encryption algorithm of the persisted secret. `"passthrough"` =
|
|
197
|
+
* plaintext at rest. */
|
|
198
|
+
wrapAlgorithm: string;
|
|
199
|
+
}
|
|
200
|
+
/** Enumerate every v4 holder record on disk — one per VTA the wallet
|
|
201
|
+
* has been onboarded at. Powers the popup's multi-VTA dropdown
|
|
202
|
+
* (PR 2). Migrates the legacy single-VTA row inline so a wallet
|
|
203
|
+
* upgraded from a single-VTA build surfaces its one wallet here. */
|
|
204
|
+
export declare function listHolderRecords(store: KVStore): Promise<HolderRecordSummary[]>;
|
|
205
|
+
/** Delete the v4 holder record for a specific VTA. Companion to
|
|
206
|
+
* `installVtaMintedHolder`. Idempotent: a no-op when the record is
|
|
207
|
+
* already gone. Other VTAs' records are left alone — call
|
|
208
|
+
* `clearHolderIdentity` to wipe every wallet on this device. */
|
|
209
|
+
export declare function forgetHolderRecord(store: KVStore, vtaDid: string): Promise<void>;
|
|
210
|
+
export interface RewrapOptions {
|
|
211
|
+
/**
|
|
212
|
+
* Wrap that decrypts the currently-persisted secret. Pass the
|
|
213
|
+
* wrap the wallet was using before the migration (or `undefined`
|
|
214
|
+
* if it was plaintext).
|
|
215
|
+
*/
|
|
216
|
+
fromWrap?: SecretWrap;
|
|
217
|
+
/**
|
|
218
|
+
* Wrap to apply on the re-persisted record. Pass the wrap the
|
|
219
|
+
* wallet should use going forward (or `undefined` to switch back
|
|
220
|
+
* to plaintext).
|
|
221
|
+
*/
|
|
222
|
+
toWrap?: SecretWrap;
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Re-wrap the persisted holder secret in place, preserving the
|
|
226
|
+
* wallet's DID + verification-method ids + mediator endpoint.
|
|
227
|
+
*
|
|
228
|
+
* Used by the extension's settings UI when the operator flips
|
|
229
|
+
* the `encryptHolderSecret` toggle — the existing wallet keeps
|
|
230
|
+
* its identity (no re-grant in any RP ACL) but the on-disk
|
|
231
|
+
* secret transitions between plaintext and wrap-encrypted.
|
|
232
|
+
*
|
|
233
|
+
* Returns the rebuilt `HolderIdentityResult` so the caller can
|
|
234
|
+
* report the (unchanged) DID back to the operator immediately.
|
|
235
|
+
*
|
|
236
|
+
* Errors if no persisted record exists — caller should check
|
|
237
|
+
* `freshlyMinted` semantics first (a fresh-mint wallet has no
|
|
238
|
+
* pre-existing secret to re-wrap).
|
|
239
|
+
*/
|
|
240
|
+
export declare function rewrapHolderSecret(store: KVStore, opts: RewrapOptions): Promise<HolderIdentityResult>;
|
|
241
|
+
//# sourceMappingURL=holder-identity.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"holder-identity.d.ts","sourceRoot":"","sources":["../../src/store/holder-identity.ts"],"names":[],"mappings":"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"}
|