@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,224 @@
|
|
|
1
|
+
// Orchestrate the sealed-bundle open pipeline.
|
|
2
|
+
//
|
|
3
|
+
// armored text → SealedBundle → (per chunk) CBOR(HpkeSealed) → HPKE open →
|
|
4
|
+
// CBOR(ChunkPlaintext) → reassemble fragments → CBOR(SealedPayloadV1) →
|
|
5
|
+
// AdminRotationPayload | TemplateBootstrapPayload | other variant.
|
|
6
|
+
//
|
|
7
|
+
// Mirrors `open_bundle` in `vta-sdk/src/sealed_transfer/mod.rs`. The wallet
|
|
8
|
+
// only needs the `AdminRotation` variant for M2C; the `TemplateBootstrap`
|
|
9
|
+
// case is typed-through for future integration use (mobile companion, etc.)
|
|
10
|
+
// and any unknown variant lands in the `other` slot for the caller to
|
|
11
|
+
// reject with a clear error.
|
|
12
|
+
import { ed25519 } from "@noble/curves/ed25519.js";
|
|
13
|
+
import { Decoder } from "cbor-x";
|
|
14
|
+
import { buildChunkAad, decodeArmor } from "./armor.js";
|
|
15
|
+
import { hpkeOpen } from "./hpke.js";
|
|
16
|
+
const CHUNK_VERSION = 1;
|
|
17
|
+
// One shared decoder. `copyBuffers: true` so the returned Uint8Arrays own
|
|
18
|
+
// independent storage — we slice into byte fields and don't want surprise
|
|
19
|
+
// aliasing into the original bundle bytes.
|
|
20
|
+
const cbor = new Decoder({ mapsAsObjects: true, copyBuffers: true });
|
|
21
|
+
/** Open the first bundle in `armored` using the recipient's Ed25519 seed.
|
|
22
|
+
*
|
|
23
|
+
* The seed is converted to its X25519 secret via Montgomery clamping
|
|
24
|
+
* (same derivation the Rust side uses; see
|
|
25
|
+
* `affinidi_crypto::ed25519::ed25519_private_to_x25519`). The wallet's
|
|
26
|
+
* ephemeral Ed25519 seed produced at onboarding is what gets passed here.
|
|
27
|
+
*
|
|
28
|
+
* If the armored input contains multiple bundles (different Bundle-Ids),
|
|
29
|
+
* this opens only the first. The provision-integration reply has exactly
|
|
30
|
+
* one bundle today; multi-bundle armored payloads are reserved for future
|
|
31
|
+
* flows.
|
|
32
|
+
*/
|
|
33
|
+
export async function openSealedBundle(armored, edSeed) {
|
|
34
|
+
if (edSeed.length !== 32) {
|
|
35
|
+
throw new Error(`openSealedBundle: edSeed must be 32 bytes (got ${edSeed.length})`);
|
|
36
|
+
}
|
|
37
|
+
const x25519Secret = ed25519.utils.toMontgomerySecret(edSeed);
|
|
38
|
+
const bundles = decodeArmor(armored);
|
|
39
|
+
const first = bundles[0];
|
|
40
|
+
return openBundle(first, x25519Secret);
|
|
41
|
+
}
|
|
42
|
+
/** Lower-level: open a pre-parsed SealedBundle with an X25519 secret. */
|
|
43
|
+
export async function openBundle(bundle, x25519Secret) {
|
|
44
|
+
if (bundle.chunks.length === 0) {
|
|
45
|
+
throw new Error("openBundle: no chunks");
|
|
46
|
+
}
|
|
47
|
+
// 1. Per chunk: CBOR(HpkeSealed) → HPKE open → CBOR(ChunkPlaintext).
|
|
48
|
+
const plaintexts = [];
|
|
49
|
+
for (const chunk of bundle.chunks) {
|
|
50
|
+
const sealed = decodeHpkeSealed(chunk.sealedBytes);
|
|
51
|
+
const aad = buildChunkAad({
|
|
52
|
+
version: CHUNK_VERSION,
|
|
53
|
+
bundleId: bundle.bundleId,
|
|
54
|
+
chunkIndex: chunk.chunkIndex,
|
|
55
|
+
totalChunks: chunk.totalChunks,
|
|
56
|
+
digestAlgo: bundle.digestAlgo,
|
|
57
|
+
});
|
|
58
|
+
const ptBytes = await hpkeOpen({
|
|
59
|
+
recipientSecret: x25519Secret,
|
|
60
|
+
kemEncap: sealed.kem_encap,
|
|
61
|
+
ciphertext: sealed.aead_ciphertext,
|
|
62
|
+
aad,
|
|
63
|
+
});
|
|
64
|
+
const pt = decodeChunkPlaintext(ptBytes);
|
|
65
|
+
if (!bytesEqual(pt.bundle_id, bundle.bundleId) ||
|
|
66
|
+
pt.chunk_index !== chunk.chunkIndex ||
|
|
67
|
+
pt.total_chunks !== chunk.totalChunks ||
|
|
68
|
+
pt.version !== CHUNK_VERSION) {
|
|
69
|
+
throw new Error("openBundle: inner ChunkPlaintext header disagrees with armor header");
|
|
70
|
+
}
|
|
71
|
+
plaintexts.push(pt);
|
|
72
|
+
}
|
|
73
|
+
// 2. Reassemble in chunk-index order. Duplicate/missing detection:
|
|
74
|
+
// after sorting, chunk_index[i] must equal i.
|
|
75
|
+
plaintexts.sort((a, b) => a.chunk_index - b.chunk_index);
|
|
76
|
+
const total = plaintexts[0].total_chunks;
|
|
77
|
+
if (plaintexts.length !== total) {
|
|
78
|
+
throw new Error(`openBundle: have ${plaintexts.length} chunks, expected ${total}`);
|
|
79
|
+
}
|
|
80
|
+
for (let i = 0; i < plaintexts.length; i++) {
|
|
81
|
+
if (plaintexts[i].chunk_index !== i) {
|
|
82
|
+
throw new Error(`openBundle: chunk index gap or duplicate at position ${i}`);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
const totalLen = plaintexts.reduce((sum, p) => sum + p.payload_fragment.length, 0);
|
|
86
|
+
const payloadBytes = new Uint8Array(totalLen);
|
|
87
|
+
let off = 0;
|
|
88
|
+
for (const p of plaintexts) {
|
|
89
|
+
payloadBytes.set(p.payload_fragment, off);
|
|
90
|
+
off += p.payload_fragment.length;
|
|
91
|
+
}
|
|
92
|
+
// 3. CBOR(SealedPayloadV1). External tagging: a 1-key map whose key is
|
|
93
|
+
// the variant tag in snake_case.
|
|
94
|
+
const raw = cbor.decode(payloadBytes);
|
|
95
|
+
const payload = parseSealedPayload(raw);
|
|
96
|
+
return {
|
|
97
|
+
bundleId: bundle.bundleId,
|
|
98
|
+
digestAlgo: bundle.digestAlgo,
|
|
99
|
+
payload,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
/** Convenience: open the bundle and assert it carries an `AdminRotation`
|
|
103
|
+
* variant, returning the typed payload. Throws if any other variant. */
|
|
104
|
+
export async function openAdminRotationBundle(armored, edSeed) {
|
|
105
|
+
const opened = await openSealedBundle(armored, edSeed);
|
|
106
|
+
if (opened.payload.kind !== "admin_rotation") {
|
|
107
|
+
const tag = opened.payload.kind === "other" ? opened.payload.tag : opened.payload.kind;
|
|
108
|
+
throw new Error(`openAdminRotationBundle: expected admin_rotation variant, got '${tag}'`);
|
|
109
|
+
}
|
|
110
|
+
return { bundleId: opened.bundleId, payload: opened.payload.body };
|
|
111
|
+
}
|
|
112
|
+
// ─── CBOR parsing of inner structs ───
|
|
113
|
+
//
|
|
114
|
+
// `cbor-x` returns plain JS objects with the field names from the CBOR map.
|
|
115
|
+
// We assert the field shapes by hand here rather than blanket-cast — a
|
|
116
|
+
// malformed bundle should fail with a clear error, not crash later on a
|
|
117
|
+
// missing field.
|
|
118
|
+
//
|
|
119
|
+
// Byte-field caveat: ciborium serialises `Vec<u8>` and `[u8; N]` through
|
|
120
|
+
// serde's default `serialize_seq` / `serialize_tuple`, which become CBOR
|
|
121
|
+
// **arrays of integers** (major type 4) — NOT CBOR byte strings (major
|
|
122
|
+
// type 2). cbor-x decodes major type 4 to `Array<number>`, not
|
|
123
|
+
// `Uint8Array`. The Rust structs we receive (HpkeSealed, ChunkPlaintext)
|
|
124
|
+
// don't use `#[serde(with = "serde_bytes")]`, so every byte-typed field
|
|
125
|
+
// arrives as a JS number array.
|
|
126
|
+
//
|
|
127
|
+
// `asBytes` is forgiving: it accepts an already-Uint8Array (in case a
|
|
128
|
+
// future Rust change adds `serde_bytes` annotations) AND the canonical
|
|
129
|
+
// number-array shape. That keeps the decoder robust to a wire-shape
|
|
130
|
+
// upgrade without re-shipping the wallet.
|
|
131
|
+
/** Coerce a CBOR-decoded byte-typed field to a `Uint8Array`. Handles
|
|
132
|
+
* both the canonical ciborium shape (CBOR array of u8 → JS number
|
|
133
|
+
* array) and the future byte-string shape (CBOR byte string →
|
|
134
|
+
* Uint8Array). Other shapes throw with a clear field-name in the
|
|
135
|
+
* message. */
|
|
136
|
+
function asBytes(v, label) {
|
|
137
|
+
if (v instanceof Uint8Array)
|
|
138
|
+
return v;
|
|
139
|
+
if (Array.isArray(v)) {
|
|
140
|
+
const out = new Uint8Array(v.length);
|
|
141
|
+
for (let i = 0; i < v.length; i++) {
|
|
142
|
+
const n = v[i];
|
|
143
|
+
if (typeof n !== "number" || !Number.isInteger(n) || n < 0 || n > 255) {
|
|
144
|
+
throw new Error(`${label}: array entry ${i} is not a byte (got ${typeof n} ${String(n)})`);
|
|
145
|
+
}
|
|
146
|
+
out[i] = n;
|
|
147
|
+
}
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
throw new Error(`${label}: expected CBOR bytes or array of u8, got ${typeof v}`);
|
|
151
|
+
}
|
|
152
|
+
function decodeHpkeSealed(bytes) {
|
|
153
|
+
const v = cbor.decode(bytes);
|
|
154
|
+
const kemEncap = asBytes(v["kem_encap"], "HpkeSealed.kem_encap");
|
|
155
|
+
const aeadCiphertext = asBytes(v["aead_ciphertext"], "HpkeSealed.aead_ciphertext");
|
|
156
|
+
if (kemEncap.length !== 32) {
|
|
157
|
+
throw new Error(`HpkeSealed.kem_encap: must be 32 bytes (got ${kemEncap.length})`);
|
|
158
|
+
}
|
|
159
|
+
return { kem_encap: kemEncap, aead_ciphertext: aeadCiphertext };
|
|
160
|
+
}
|
|
161
|
+
function decodeChunkPlaintext(bytes) {
|
|
162
|
+
const v = cbor.decode(bytes);
|
|
163
|
+
const version = v["version"];
|
|
164
|
+
const chunkIndex = v["chunk_index"];
|
|
165
|
+
const totalChunks = v["total_chunks"];
|
|
166
|
+
if (typeof version !== "number")
|
|
167
|
+
throw new Error("ChunkPlaintext: version missing/wrong");
|
|
168
|
+
if (typeof chunkIndex !== "number")
|
|
169
|
+
throw new Error("ChunkPlaintext: chunk_index missing");
|
|
170
|
+
if (typeof totalChunks !== "number")
|
|
171
|
+
throw new Error("ChunkPlaintext: total_chunks missing");
|
|
172
|
+
const bundleId = asBytes(v["bundle_id"], "ChunkPlaintext.bundle_id");
|
|
173
|
+
if (bundleId.length !== 16) {
|
|
174
|
+
throw new Error(`ChunkPlaintext.bundle_id: must be 16 bytes (got ${bundleId.length})`);
|
|
175
|
+
}
|
|
176
|
+
const payloadFragment = asBytes(v["payload_fragment"], "ChunkPlaintext.payload_fragment");
|
|
177
|
+
const out = {
|
|
178
|
+
version,
|
|
179
|
+
bundle_id: bundleId,
|
|
180
|
+
chunk_index: chunkIndex,
|
|
181
|
+
total_chunks: totalChunks,
|
|
182
|
+
payload_fragment: payloadFragment,
|
|
183
|
+
};
|
|
184
|
+
if (typeof v["producer_did"] === "string") {
|
|
185
|
+
out.producer_did = v["producer_did"];
|
|
186
|
+
}
|
|
187
|
+
const pa = v["producer_assertion"];
|
|
188
|
+
if (pa !== undefined) {
|
|
189
|
+
out.producer_assertion = pa;
|
|
190
|
+
}
|
|
191
|
+
return out;
|
|
192
|
+
}
|
|
193
|
+
function parseSealedPayload(raw) {
|
|
194
|
+
const keys = Object.keys(raw);
|
|
195
|
+
if (keys.length !== 1) {
|
|
196
|
+
throw new Error(`SealedPayloadV1: expected externally-tagged map with one key, got ${keys.length}`);
|
|
197
|
+
}
|
|
198
|
+
const tag = keys[0];
|
|
199
|
+
const body = raw[tag];
|
|
200
|
+
if (!body || typeof body !== "object") {
|
|
201
|
+
throw new Error(`SealedPayloadV1: body for tag '${tag}' is not an object`);
|
|
202
|
+
}
|
|
203
|
+
switch (tag) {
|
|
204
|
+
case "admin_rotation":
|
|
205
|
+
return { kind: "admin_rotation", body: body };
|
|
206
|
+
case "template_bootstrap":
|
|
207
|
+
return {
|
|
208
|
+
kind: "template_bootstrap",
|
|
209
|
+
body: body,
|
|
210
|
+
};
|
|
211
|
+
default:
|
|
212
|
+
return { kind: "other", tag, body };
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
function bytesEqual(a, b) {
|
|
216
|
+
if (a.length !== b.length)
|
|
217
|
+
return false;
|
|
218
|
+
for (let i = 0; i < a.length; i++) {
|
|
219
|
+
if (a[i] !== b[i])
|
|
220
|
+
return false;
|
|
221
|
+
}
|
|
222
|
+
return true;
|
|
223
|
+
}
|
|
224
|
+
//# sourceMappingURL=open.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"open.js","sourceRoot":"","sources":["../../src/provision/open.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import type { SigningIdentity } from "../siop/self-issued.js";
|
|
2
|
+
/** A reference to a DID template the maintainer has registered. Inline
|
|
3
|
+
* template definitions are rejected — the operator uploads via
|
|
4
|
+
* `pnm did-templates create` first, then names the template here. */
|
|
5
|
+
export interface DidTemplateRef {
|
|
6
|
+
name: string;
|
|
7
|
+
vars?: Record<string, unknown>;
|
|
8
|
+
}
|
|
9
|
+
/** What the holder is asking the VTA to do. Tagged on `type`.
|
|
10
|
+
*
|
|
11
|
+
* `TemplateBootstrap` is for full integration bootstrap (mediator,
|
|
12
|
+
* did-hosting host, etc.). `AdminRotation` is what the wallet uses — it
|
|
13
|
+
* asks the VTA to mint a fresh long-term admin DID + keys without
|
|
14
|
+
* rendering any integration template. The browser plugin has no
|
|
15
|
+
* integration-side identity to advertise, so AdminRotation is the right
|
|
16
|
+
* ask for M2C. */
|
|
17
|
+
export type BootstrapAsk = {
|
|
18
|
+
type: "TemplateBootstrap";
|
|
19
|
+
contextHint?: string;
|
|
20
|
+
template: DidTemplateRef;
|
|
21
|
+
adminTemplate?: DidTemplateRef;
|
|
22
|
+
note?: string;
|
|
23
|
+
} | {
|
|
24
|
+
type: "AdminRotation";
|
|
25
|
+
contextHint?: string;
|
|
26
|
+
adminTemplate: DidTemplateRef;
|
|
27
|
+
note?: string;
|
|
28
|
+
};
|
|
29
|
+
/** The signed VP the wallet ships in the provision-integration message body. */
|
|
30
|
+
export interface BootstrapRequestVp {
|
|
31
|
+
"@context": string[];
|
|
32
|
+
type: string[];
|
|
33
|
+
id: string;
|
|
34
|
+
holder: string;
|
|
35
|
+
/** 16 random bytes, base64url-no-pad (22 chars). Re-decoded by the VTA
|
|
36
|
+
* and used as the sealed-bundle `bundleId`. */
|
|
37
|
+
nonce: string;
|
|
38
|
+
validUntil: string;
|
|
39
|
+
label?: string;
|
|
40
|
+
ask: BootstrapAsk;
|
|
41
|
+
proof: unknown;
|
|
42
|
+
}
|
|
43
|
+
export interface BuildBootstrapRequestOptions {
|
|
44
|
+
/** Ephemeral signing identity — the operator-granted `did:key` whose
|
|
45
|
+
* Ed25519 private key signs the proof. The matching X25519 derivation
|
|
46
|
+
* is the bundle's HPKE recipient. */
|
|
47
|
+
ephemeral: SigningIdentity;
|
|
48
|
+
/** Tagged-union intent. */
|
|
49
|
+
ask: BootstrapAsk;
|
|
50
|
+
/** Validity window in milliseconds. Default 15 minutes — matches the
|
|
51
|
+
* Rust default; the VTA enforces ±5min skew on validUntil. */
|
|
52
|
+
validityMs?: number;
|
|
53
|
+
/** Optional human-readable label written into the maintainer's audit log. */
|
|
54
|
+
label?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Build a 16-byte nonce + signed BootstrapRequest VP, returning both.
|
|
57
|
+
*
|
|
58
|
+
* The caller persists the nonce alongside the bundle so it can verify
|
|
59
|
+
* `summary.bundleIdHex` (the VTA echoes the nonce back as the bundle id
|
|
60
|
+
* in hex) on the reply. */
|
|
61
|
+
export declare function buildBootstrapRequest(opts: BuildBootstrapRequestOptions): Promise<{
|
|
62
|
+
vp: BootstrapRequestVp;
|
|
63
|
+
nonce: Uint8Array;
|
|
64
|
+
}>;
|
|
65
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/provision/request.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAM9D;;sEAEsE;AACtE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAChC;AAED;;;;;;;mBAOmB;AACnB,MAAM,MAAM,YAAY,GACpB;IACE,IAAI,EAAE,mBAAmB,CAAC;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,cAAc,CAAC;IACzB,aAAa,CAAC,EAAE,cAAc,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IACE,IAAI,EAAE,eAAe,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,cAAc,CAAC;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEN,gFAAgF;AAChF,MAAM,WAAW,kBAAkB;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf;oDACgD;IAChD,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,YAAY,CAAC;IAClB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,4BAA4B;IAC3C;;0CAEsC;IACtC,SAAS,EAAE,eAAe,CAAC;IAC3B,2BAA2B;IAC3B,GAAG,EAAE,YAAY,CAAC;IAClB;mEAC+D;IAC/D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6EAA6E;IAC7E,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;4BAI4B;AAC5B,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,4BAA4B,GACjC,OAAO,CAAC;IAAE,EAAE,EAAE,kBAAkB,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,CAAC,CAiCxD"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
// Build + sign the BootstrapRequest VP the wallet hands the VTA when
|
|
2
|
+
// onboarding. The VP is a W3C VC Data Model 2.0 Verifiable Presentation
|
|
3
|
+
// with `nonce` / `validUntil` / `label` / `ask` carried alongside the
|
|
4
|
+
// standard VP fields and covered by the same `eddsa-jcs-2022` Data
|
|
5
|
+
// Integrity proof.
|
|
6
|
+
//
|
|
7
|
+
// Wire shape mirrors
|
|
8
|
+
// `verifiable-trust-infrastructure/vta-sdk/src/provision_integration/request.rs`
|
|
9
|
+
// (`BootstrapRequest::sign`). Verifying against the existing FPN-private
|
|
10
|
+
// URI works today; the canonical Trust Task URI
|
|
11
|
+
// `https://trusttasks.org/spec/provision/integration/0.1` will start
|
|
12
|
+
// validating once the VTA implementation migrates (separate downstream
|
|
13
|
+
// work — this client targets the FPN URI for now).
|
|
14
|
+
import { base64url } from "@openvtc/vti-didcomm-js";
|
|
15
|
+
import { signTrustTask } from "../trust-tasks/sign.js";
|
|
16
|
+
const VC_V2_CONTEXT_URL = "https://www.w3.org/ns/credentials/v2";
|
|
17
|
+
const BOOTSTRAP_CONTEXT_URL = "https://openvtc.org/contexts/bootstrap-v1";
|
|
18
|
+
/** Build a 16-byte nonce + signed BootstrapRequest VP, returning both.
|
|
19
|
+
*
|
|
20
|
+
* The caller persists the nonce alongside the bundle so it can verify
|
|
21
|
+
* `summary.bundleIdHex` (the VTA echoes the nonce back as the bundle id
|
|
22
|
+
* in hex) on the reply. */
|
|
23
|
+
export async function buildBootstrapRequest(opts) {
|
|
24
|
+
const nonce = new Uint8Array(16);
|
|
25
|
+
crypto.getRandomValues(nonce);
|
|
26
|
+
const now = new Date();
|
|
27
|
+
const validUntil = new Date(now.getTime() + (opts.validityMs ?? 15 * 60_000));
|
|
28
|
+
const vp = {
|
|
29
|
+
"@context": [VC_V2_CONTEXT_URL, BOOTSTRAP_CONTEXT_URL],
|
|
30
|
+
type: ["VerifiablePresentation", "BootstrapRequest"],
|
|
31
|
+
id: `urn:uuid:${crypto.randomUUID()}`,
|
|
32
|
+
holder: opts.ephemeral.did,
|
|
33
|
+
nonce: base64url.encode(nonce),
|
|
34
|
+
validUntil: validUntil.toISOString(),
|
|
35
|
+
...(opts.label ? { label: opts.label } : {}),
|
|
36
|
+
ask: opts.ask,
|
|
37
|
+
proof: null,
|
|
38
|
+
};
|
|
39
|
+
// The wallet's existing eddsa-jcs-2022 signer covers JCS canonicalisation
|
|
40
|
+
// + SHA-256(proofConfig) || SHA-256(doc-minus-proof) + Ed25519 sign +
|
|
41
|
+
// multibase proofValue exactly as the Rust side does. Here we pass
|
|
42
|
+
// `authentication` rather than the default `assertionMethod` because the
|
|
43
|
+
// VP holder is proving CONTROL of the ephemeral did:key, not vouching
|
|
44
|
+
// for a claim about it — same distinction the Rust `BootstrapRequest::
|
|
45
|
+
// sign` makes via `SignOptions::with_proof_purpose("authentication")`.
|
|
46
|
+
await signTrustTask({
|
|
47
|
+
envelope: vp,
|
|
48
|
+
signing: opts.ephemeral,
|
|
49
|
+
proofPurpose: "authentication",
|
|
50
|
+
});
|
|
51
|
+
return { vp, nonce };
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/provision/request.ts"],"names":[],"mappings":"AAAA,qEAAqE;AACrE,wEAAwE;AACxE,sEAAsE;AACtE,mEAAmE;AACnE,mBAAmB;AACnB,EAAE;AACF,qBAAqB;AACrB,iFAAiF;AACjF,yEAAyE;AACzE,gDAAgD;AAChD,qEAAqE;AACrE,uEAAuE;AACvE,mDAAmD;AAEnD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAEvD,MAAM,iBAAiB,GAAG,sCAAsC,CAAC;AACjE,MAAM,qBAAqB,GAAG,2CAA2C,CAAC;AA8D1E;;;;4BAI4B;AAC5B,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,IAAkC;IAElC,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,EAAE,CAAC,CAAC;IACjC,MAAM,CAAC,eAAe,CAAC,KAAK,CAAC,CAAC;IAE9B,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC;IACvB,MAAM,UAAU,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;IAE9E,MAAM,EAAE,GAAuB;QAC7B,UAAU,EAAE,CAAC,iBAAiB,EAAE,qBAAqB,CAAC;QACtD,IAAI,EAAE,CAAC,wBAAwB,EAAE,kBAAkB,CAAC;QACpD,EAAE,EAAE,YAAY,MAAM,CAAC,UAAU,EAAE,EAAE;QACrC,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,GAAG;QAC1B,KAAK,EAAE,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC;QAC9B,UAAU,EAAE,UAAU,CAAC,WAAW,EAAE;QACpC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAC5C,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,KAAK,EAAE,IAAI;KACZ,CAAC;IAEF,0EAA0E;IAC1E,sEAAsE;IACtE,mEAAmE;IACnE,yEAAyE;IACzE,sEAAsE;IACtE,uEAAuE;IACvE,uEAAuE;IACvE,MAAM,aAAa,CAAC;QAClB,QAAQ,EAAE,EAAwC;QAClD,OAAO,EAAE,IAAI,CAAC,SAAS;QACvB,YAAY,EAAE,gBAAgB;KAC/B,CAAC,CAAC;IAEH,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { Identity } from "../didcomm/index.js";
|
|
2
|
+
import type { SigningIdentity } from "../siop/self-issued.js";
|
|
3
|
+
import type { RemoteDidcommEndpoint } from "../vta/didcomm.js";
|
|
4
|
+
import type { DidcommMessageBridge } from "../vta/transport.js";
|
|
5
|
+
import { type ProvisionSummary } from "./send.js";
|
|
6
|
+
import type { AdminRotationPayload } from "./types.js";
|
|
7
|
+
export interface RunProvisionIntegrationOptions {
|
|
8
|
+
/** Mediator-backed DIDComm bridge for the round-trip. */
|
|
9
|
+
bridge: DidcommMessageBridge;
|
|
10
|
+
/** Authcrypt sender X25519 identity for the ephemeral did:key. */
|
|
11
|
+
ephemeral: Identity;
|
|
12
|
+
/** Signing identity for the SAME ephemeral did:key — used to sign the
|
|
13
|
+
* BootstrapRequest VP. The Ed25519 seed in `signing.privateKey` is also
|
|
14
|
+
* the recipient secret the wallet uses to open the sealed bundle. */
|
|
15
|
+
ephemeralSigning: SigningIdentity;
|
|
16
|
+
/** The VTA's DID + keyAgreement key (inner authcrypt recipient and
|
|
17
|
+
* expected `from` on the reply). */
|
|
18
|
+
service: RemoteDidcommEndpoint;
|
|
19
|
+
/** The VTA's mediator (forward target). Omit for direct DIDComm. */
|
|
20
|
+
mediator?: RemoteDidcommEndpoint;
|
|
21
|
+
/** The VTA's DID — passed to send.ts for the reply sender assertion. */
|
|
22
|
+
vtaDid: string;
|
|
23
|
+
/** The maintainer context to provision the admin DID into. **Optional**
|
|
24
|
+
* per the canonical Trust Task spec — when omitted, the VTA infers
|
|
25
|
+
* from the relayer's ACL grant or its own contexts state (single-
|
|
26
|
+
* context grant → that context; super-admin + single-context VTA →
|
|
27
|
+
* that context; ambiguous → error). Wallet-class callers SHOULD
|
|
28
|
+
* omit; integration-class callers SHOULD specify. */
|
|
29
|
+
context?: string;
|
|
30
|
+
/** Admin template the VTA renders. Default `vta-admin` — the built-in
|
|
31
|
+
* no-frills `did:key` admin template every VTA ships with. Override if
|
|
32
|
+
* the operator has uploaded a custom admin template. */
|
|
33
|
+
adminTemplateName?: string;
|
|
34
|
+
/** Free-form note for the VTA's audit log. */
|
|
35
|
+
note?: string;
|
|
36
|
+
/** When `true`, asks the VTA to provision the target context inline if
|
|
37
|
+
* it does not already exist. Requires the relayer (the ephemeral
|
|
38
|
+
* did:key after the operator's grant) to hold **super-admin** role at
|
|
39
|
+
* the VTA — context-admin grants get rejected with
|
|
40
|
+
* `provision/integration:forbidden`. Defaults to `false`; callers
|
|
41
|
+
* that target an established context leave this off. */
|
|
42
|
+
createContext?: boolean;
|
|
43
|
+
/** Send-side timeout. Default 60s (sendProvisionIntegration). */
|
|
44
|
+
timeoutMs?: number;
|
|
45
|
+
}
|
|
46
|
+
/** Minimal admin material the wallet adopts after a successful onboarding.
|
|
47
|
+
*
|
|
48
|
+
* The wallet stores `adminDid` as its new holder identity. The Ed25519
|
|
49
|
+
* private key (multibase-encoded) is what signs subsequent trust tasks
|
|
50
|
+
* + SIOP id_tokens; the X25519 private key is what unpacks DIDComm
|
|
51
|
+
* authcrypt envelopes targeted at the wallet. The auth VC + VTA trust
|
|
52
|
+
* bundle are NOT kept — the steady-state authority is the ACL row the
|
|
53
|
+
* VTA wrote at provisioning, not the VC, and the wallet verifies the
|
|
54
|
+
* VTA's identity via DID resolution on every subsequent connect rather
|
|
55
|
+
* than caching the trust bundle. */
|
|
56
|
+
export interface MinimalAdminReply {
|
|
57
|
+
/** The freshly-minted long-term admin DID (a `did:key:z6Mk…`). */
|
|
58
|
+
adminDid: string;
|
|
59
|
+
/** Multibase-encoded Ed25519 private key (`z`-prefixed multikey).
|
|
60
|
+
* The wallet decodes this and stores it as the new holder's signing key. */
|
|
61
|
+
adminSigningPrivateMultibase: string;
|
|
62
|
+
/** Multibase-encoded X25519 private key. The wallet decodes + stores
|
|
63
|
+
* this as the new holder's keyAgreement key. */
|
|
64
|
+
adminKaPrivateMultibase: string;
|
|
65
|
+
/** Echo of the VTA's own DID (cross-check vs `service.did`). */
|
|
66
|
+
vtaDid: string;
|
|
67
|
+
/** REST base URL the VTA advertised, if any. */
|
|
68
|
+
vtaUrl?: string;
|
|
69
|
+
/** Bundle metadata for audit / debug. */
|
|
70
|
+
summary: ProvisionSummary;
|
|
71
|
+
}
|
|
72
|
+
/** Drive the full provision-integration round-trip and return the minimal
|
|
73
|
+
* admin material the wallet should adopt. */
|
|
74
|
+
export declare function runProvisionIntegration(opts: RunProvisionIntegrationOptions): Promise<MinimalAdminReply>;
|
|
75
|
+
export type { AdminRotationPayload };
|
|
76
|
+
//# sourceMappingURL=run.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/provision/run.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,qBAAqB,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAC/D,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAIhE,OAAO,EAA4B,KAAK,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC5E,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD,MAAM,WAAW,8BAA8B;IAC7C,yDAAyD;IACzD,MAAM,EAAE,oBAAoB,CAAC;IAC7B,kEAAkE;IAClE,SAAS,EAAE,QAAQ,CAAC;IACpB;;0EAEsE;IACtE,gBAAgB,EAAE,eAAe,CAAC;IAClC;yCACqC;IACrC,OAAO,EAAE,qBAAqB,CAAC;IAC/B,oEAAoE;IACpE,QAAQ,CAAC,EAAE,qBAAqB,CAAC;IACjC,wEAAwE;IACxE,MAAM,EAAE,MAAM,CAAC;IACf;;;;;0DAKsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;6DAEyD;IACzD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;;6DAKyD;IACzD,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;qCASqC;AACrC,MAAM,WAAW,iBAAiB;IAChC,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB;iFAC6E;IAC7E,4BAA4B,EAAE,MAAM,CAAC;IACrC;qDACiD;IACjD,uBAAuB,EAAE,MAAM,CAAC;IAChC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,gDAAgD;IAChD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,yCAAyC;IACzC,OAAO,EAAE,gBAAgB,CAAC;CAC3B;AAED;8CAC8C;AAC9C,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,8BAA8B,GACnC,OAAO,CAAC,iBAAiB,CAAC,CA+F5B;AAYD,YAAY,EAAE,oBAAoB,EAAE,CAAC"}
|
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
// Top-level orchestrator for the wallet's provision-integration flow.
|
|
2
|
+
//
|
|
3
|
+
// One call drives the full onboarding round-trip:
|
|
4
|
+
// 1. Build + sign a BootstrapRequest VP for the AdminRotation ask.
|
|
5
|
+
// 2. Ship it via DIDComm (authcrypt → forward via VTA's mediator).
|
|
6
|
+
// 3. Open the HPKE-sealed reply with the wallet's ephemeral Ed25519 seed.
|
|
7
|
+
// 4. Cross-check that the bundle's `bundleIdHex` matches the request nonce.
|
|
8
|
+
// 5. Return the minimal admin reply (DID + private keys) the wallet adopts
|
|
9
|
+
// as its long-term holder identity.
|
|
10
|
+
//
|
|
11
|
+
// The wallet's existing onboarding code (`offscreen.ts`) currently calls
|
|
12
|
+
// `swapAclDidcomm` here — M2C-C swaps that call site to `runProvisionIntegration`.
|
|
13
|
+
import { openAdminRotationBundle } from "./open.js";
|
|
14
|
+
import { buildBootstrapRequest } from "./request.js";
|
|
15
|
+
import { sendProvisionIntegration } from "./send.js";
|
|
16
|
+
/** Drive the full provision-integration round-trip and return the minimal
|
|
17
|
+
* admin material the wallet should adopt. */
|
|
18
|
+
export async function runProvisionIntegration(opts) {
|
|
19
|
+
// 1. Build + sign the VP with an AdminRotation ask. The wallet only
|
|
20
|
+
// needs a long-term admin DID at this VTA; it does NOT need an
|
|
21
|
+
// integration DID minted (TemplateBootstrap), which is what
|
|
22
|
+
// mediator / did-hosting integrations consume.
|
|
23
|
+
const ask = {
|
|
24
|
+
type: "AdminRotation",
|
|
25
|
+
// contextHint is just a hint embedded in the VP — only meaningful
|
|
26
|
+
// when the caller actually knows the context. When omitted, the
|
|
27
|
+
// VTA's authoritative context resolution runs (inference rules).
|
|
28
|
+
...(opts.context ? { contextHint: opts.context } : {}),
|
|
29
|
+
adminTemplate: { name: opts.adminTemplateName ?? "vta-admin", vars: {} },
|
|
30
|
+
...(opts.note ? { note: opts.note } : {}),
|
|
31
|
+
};
|
|
32
|
+
const { vp, nonce } = await buildBootstrapRequest({
|
|
33
|
+
ephemeral: opts.ephemeralSigning,
|
|
34
|
+
ask,
|
|
35
|
+
...(opts.note ? { label: opts.note } : {}),
|
|
36
|
+
});
|
|
37
|
+
// 2. DIDComm round-trip. Body field names are snake_case to match the
|
|
38
|
+
// existing FPN protocol the VTA speaks today (see send.ts header for
|
|
39
|
+
// the migration plan).
|
|
40
|
+
const reply = await sendProvisionIntegration({
|
|
41
|
+
bridge: opts.bridge,
|
|
42
|
+
ephemeral: opts.ephemeral,
|
|
43
|
+
service: opts.service,
|
|
44
|
+
...(opts.mediator ? { mediator: opts.mediator } : {}),
|
|
45
|
+
vtaDid: opts.vtaDid,
|
|
46
|
+
body: {
|
|
47
|
+
request: vp,
|
|
48
|
+
// context is optional on the wire. When omitted, the VTA's
|
|
49
|
+
// inference rules pick the target context (single-context grant
|
|
50
|
+
// → use it; super-admin + single-context VTA → use it;
|
|
51
|
+
// ambiguous → e.p.msg.context_required). Wallet-class callers
|
|
52
|
+
// typically omit; integration-class callers send explicitly.
|
|
53
|
+
...(opts.context ? { context: opts.context } : {}),
|
|
54
|
+
// create_context defaults to false on the wire; only emit when the
|
|
55
|
+
// caller actually asked for inline create so older VTAs that
|
|
56
|
+
// pre-date the field don't have to deal with an unexpected key.
|
|
57
|
+
...(opts.createContext ? { create_context: true } : {}),
|
|
58
|
+
},
|
|
59
|
+
...(opts.timeoutMs !== undefined ? { timeoutMs: opts.timeoutMs } : {}),
|
|
60
|
+
});
|
|
61
|
+
// 3. Cross-check the bundle id BEFORE opening. The maintainer echoes
|
|
62
|
+
// the VP nonce as `summary.bundle_id_hex` (lowercase hex of the 16
|
|
63
|
+
// nonce bytes); a mismatch means the bundle is for a different
|
|
64
|
+
// request, which is a serious wire-shape failure. The HPKE open
|
|
65
|
+
// would also fail (the AAD binds the bundle id), but catching it
|
|
66
|
+
// here gives a cleaner error.
|
|
67
|
+
const expectedHex = toLowerHex(nonce);
|
|
68
|
+
if (reply.summary.bundle_id_hex !== expectedHex) {
|
|
69
|
+
throw new Error(`provision-integration: bundle_id_hex mismatch — expected ${expectedHex}, got ${reply.summary.bundle_id_hex}`);
|
|
70
|
+
}
|
|
71
|
+
// 4. Open the sealed bundle with the wallet's Ed25519 seed. The opener
|
|
72
|
+
// derives the X25519 recipient secret via Montgomery clamping
|
|
73
|
+
// (matching the Rust seal-side `ed25519_seed_to_x25519_secret`).
|
|
74
|
+
if (opts.ephemeralSigning.privateKey.length !== 32) {
|
|
75
|
+
throw new Error("provision-integration: ephemeral Ed25519 seed must be 32 bytes");
|
|
76
|
+
}
|
|
77
|
+
const opened = await openAdminRotationBundle(reply.bundle, opts.ephemeralSigning.privateKey);
|
|
78
|
+
// 5. Extract the minimal admin material the wallet keeps.
|
|
79
|
+
const admin = opened.payload.admin;
|
|
80
|
+
if (!admin || !admin.did) {
|
|
81
|
+
throw new Error("provision-integration: AdminRotation payload missing admin.did");
|
|
82
|
+
}
|
|
83
|
+
if (!admin.signing_key?.private_key_multibase || !admin.ka_key?.private_key_multibase) {
|
|
84
|
+
throw new Error("provision-integration: AdminRotation payload missing admin signing/ka private key");
|
|
85
|
+
}
|
|
86
|
+
// Defence-in-depth: the open-time digest check is the maintainer's
|
|
87
|
+
// contract, but verifying summary.admin_did matches what we extract
|
|
88
|
+
// catches the case where a malicious / buggy maintainer ships a
|
|
89
|
+
// summary that doesn't agree with the sealed bundle.
|
|
90
|
+
if (reply.summary.admin_did && reply.summary.admin_did !== admin.did) {
|
|
91
|
+
throw new Error(`provision-integration: summary.admin_did (${reply.summary.admin_did}) ` +
|
|
92
|
+
`disagrees with sealed admin.did (${admin.did})`);
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
adminDid: admin.did,
|
|
96
|
+
adminSigningPrivateMultibase: admin.signing_key.private_key_multibase,
|
|
97
|
+
adminKaPrivateMultibase: admin.ka_key.private_key_multibase,
|
|
98
|
+
vtaDid: opened.payload.vta_trust?.vta_did ?? opts.vtaDid,
|
|
99
|
+
...(opened.payload.vta_url ? { vtaUrl: opened.payload.vta_url } : {}),
|
|
100
|
+
summary: reply.summary,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
function toLowerHex(bytes) {
|
|
104
|
+
let s = "";
|
|
105
|
+
for (let i = 0; i < bytes.length; i++) {
|
|
106
|
+
s += bytes[i].toString(16).padStart(2, "0");
|
|
107
|
+
}
|
|
108
|
+
return s;
|
|
109
|
+
}
|
|
110
|
+
//# sourceMappingURL=run.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/provision/run.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { type Identity } from "../didcomm/index.js";
|
|
2
|
+
import type { RemoteDidcommEndpoint } from "../vta/didcomm.js";
|
|
3
|
+
import type { DidcommMessageBridge } from "../vta/transport.js";
|
|
4
|
+
import type { BootstrapRequestVp } from "./request.js";
|
|
5
|
+
/** Parsed DIDComm problem-report body. Mirrors the wire shape
|
|
6
|
+
* emitted by the VTA's `app_err_to_response`. */
|
|
7
|
+
export interface ProblemReportPayload {
|
|
8
|
+
code: string;
|
|
9
|
+
comment: string;
|
|
10
|
+
/** Structured arguments — task-specific. For
|
|
11
|
+
* `provision/integration:context_required` this carries the
|
|
12
|
+
* candidates list. */
|
|
13
|
+
args: string[];
|
|
14
|
+
}
|
|
15
|
+
/** Thrown by `sendProvisionIntegration` when the VTA replies with a
|
|
16
|
+
* DIDComm problem-report rather than a success result. Carries the
|
|
17
|
+
* structured fields so callers can branch on the code (e.g. the
|
|
18
|
+
* popup's context-required recovery picker that reads
|
|
19
|
+
* `report.args` as the candidates list). */
|
|
20
|
+
export declare class ProvisionProblemReportError extends Error {
|
|
21
|
+
readonly report: ProblemReportPayload;
|
|
22
|
+
constructor(report: ProblemReportPayload);
|
|
23
|
+
}
|
|
24
|
+
/** Body of the inbound `provision-integration` message. Mirrors
|
|
25
|
+
* `vta_sdk::provision_integration::http::ProvisionIntegrationRequest`. */
|
|
26
|
+
export interface ProvisionIntegrationRequestBody {
|
|
27
|
+
request: BootstrapRequestVp;
|
|
28
|
+
/** Optional per the canonical Trust Task spec. When omitted, the VTA
|
|
29
|
+
* infers the target context from the relayer's ACL grant + its own
|
|
30
|
+
* contexts state. See vta-sdk's `ProvisionIntegrationRequest::context`
|
|
31
|
+
* doc-comment for the full inference rules. */
|
|
32
|
+
context?: string;
|
|
33
|
+
assertion?: "did-signed" | "pinned-only";
|
|
34
|
+
/** Caller-preferred VC validity in seconds. Capped server-side. */
|
|
35
|
+
vc_validity_seconds?: number;
|
|
36
|
+
/** Super-admin only: create the context inline if missing. */
|
|
37
|
+
create_context?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/** Body of the outbound `provision-integration-result` reply. Mirrors
|
|
40
|
+
* `vta_sdk::provision_integration::http::ProvisionIntegrationResponse`. */
|
|
41
|
+
export interface ProvisionIntegrationResponseBody {
|
|
42
|
+
bundle: string;
|
|
43
|
+
digest: string;
|
|
44
|
+
summary: ProvisionSummary;
|
|
45
|
+
}
|
|
46
|
+
export interface ProvisionSummary {
|
|
47
|
+
client_did: string;
|
|
48
|
+
admin_did?: string;
|
|
49
|
+
admin_rolled_over?: boolean;
|
|
50
|
+
integration_did?: string;
|
|
51
|
+
template_name?: string;
|
|
52
|
+
template_kind?: string;
|
|
53
|
+
admin_template_name?: string | null;
|
|
54
|
+
bundle_id_hex: string;
|
|
55
|
+
secret_count: number;
|
|
56
|
+
output_count: number;
|
|
57
|
+
webvh_server_id?: string | null;
|
|
58
|
+
context_created?: boolean;
|
|
59
|
+
}
|
|
60
|
+
export interface SendProvisionIntegrationOptions {
|
|
61
|
+
/** Mediator-backed bridge — ships the JWE and surfaces the decrypted,
|
|
62
|
+
* sender-authenticated reply (keyed by `thid`). */
|
|
63
|
+
bridge: DidcommMessageBridge;
|
|
64
|
+
/** Authcrypt sender = the operator-granted ephemeral did:key (X25519
|
|
65
|
+
* identity matching the BootstrapRequest's `holder`). */
|
|
66
|
+
ephemeral: Identity;
|
|
67
|
+
/** The VTA's DID + keyAgreement key (inner authcrypt recipient). */
|
|
68
|
+
service: RemoteDidcommEndpoint;
|
|
69
|
+
/** The VTA's mediator (forward target). Omit for direct, non-mediated send. */
|
|
70
|
+
mediator?: RemoteDidcommEndpoint;
|
|
71
|
+
/** The VTA's DID — the expected reply `from`. */
|
|
72
|
+
vtaDid: string;
|
|
73
|
+
/** The request body to ship. */
|
|
74
|
+
body: ProvisionIntegrationRequestBody;
|
|
75
|
+
/** Request-side timeout. Default 60s (matches the Rust SDK constant) —
|
|
76
|
+
* the handler renders templates, mints keys, writes the webvh log, and
|
|
77
|
+
* seals the bundle synchronously inside one handler call, so it needs
|
|
78
|
+
* more headroom than a typical authenticate. */
|
|
79
|
+
timeoutMs?: number;
|
|
80
|
+
}
|
|
81
|
+
/** Pack + send the provision-integration request and return the reply
|
|
82
|
+
* body. Throws on timeout, wrong reply type, sender mismatch, or any
|
|
83
|
+
* problem-report from the VTA. */
|
|
84
|
+
export declare function sendProvisionIntegration(opts: SendProvisionIntegrationOptions): Promise<ProvisionIntegrationResponseBody>;
|
|
85
|
+
//# sourceMappingURL=send.d.ts.map
|