@idos-network/kwil-infra 3.0.1 → 5.0.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/CHANGELOG.md +42 -0
- package/README.md +1 -46
- package/dist/actions/index.d.mts +2 -2
- package/dist/actions/index.mjs +1 -1
- package/dist/actions/index.mjs.map +1 -1
- package/dist/{index-Bk8YCFlx.d.mts → index-Dc_rffi1.d.mts} +149 -69
- package/dist/index-Dc_rffi1.d.mts.map +1 -0
- package/dist/index.d.mts +2 -2
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/signature-verification/index.d.mts +1 -1
- package/package.json +2 -2
- package/src/actions/actions.test.ts +23 -5
- package/src/actions/actions.ts +389 -42
- package/src/create-kgw-authenticated-fetch.test.ts +46 -26
- package/src/create-kgw-authenticated-fetch.ts +14 -18
- package/src/create-kwil-client.test.ts +40 -0
- package/src/create-kwil-client.ts +25 -0
- package/src/create-kwil-signer.test.ts +2 -67
- package/src/create-kwil-signer.ts +2 -27
- package/src/index.ts +0 -1
- package/dist/index-Bk8YCFlx.d.mts.map +0 -1
- package/src/mm-token/create-mm-token-kwil-signer.test.ts +0 -148
- package/src/mm-token/create-mm-token-kwil-signer.ts +0 -166
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
import { KwilSigner } from "@idos-network/kwil-js";
|
|
2
|
-
import { createUkycContentUri } from "@idos-network/utils/blob-gateway";
|
|
3
|
-
import {
|
|
4
|
-
base64UrlDecode,
|
|
5
|
-
base64UrlEncode,
|
|
6
|
-
utf8Decode,
|
|
7
|
-
utf8Encode,
|
|
8
|
-
} from "@idos-network/utils/codecs";
|
|
9
|
-
|
|
10
|
-
const ED25519_PUBLIC_KEY_BYTES = 32;
|
|
11
|
-
const ED25519_SIGNATURE_BYTES = 64;
|
|
12
|
-
|
|
13
|
-
/** Decoded UKYC capability envelope. KGW signature data is base64url(JSON of this). */
|
|
14
|
-
export interface MmTokenEnvelope {
|
|
15
|
-
payload: MmTokenPayload | Record<string, unknown>;
|
|
16
|
-
signature: string;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export interface MmTokenPayload {
|
|
20
|
-
signing_public_key: string;
|
|
21
|
-
storage_id?: string;
|
|
22
|
-
[key: string]: unknown;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* One MM/UKYC capability, valid both as a KGW `mm_token` signer and as the
|
|
27
|
-
* `Authorization: AccessToken …` credential for UKYC blob requests.
|
|
28
|
-
*/
|
|
29
|
-
export type MmTokenAuth = KwilSigner & {
|
|
30
|
-
readonly mmTokenPayload: MmTokenPayload | Record<string, unknown>;
|
|
31
|
-
/** Exact encoded envelope KGW and UKYC storage verify. Non-enumerable, so it stays out of logs. */
|
|
32
|
-
readonly accessToken: string;
|
|
33
|
-
/**
|
|
34
|
-
* A capability signs its own envelope, never an arbitrary message. Declared so callers
|
|
35
|
-
* handling a `Wallet` union can keep asking wallets for a message signature.
|
|
36
|
-
*/
|
|
37
|
-
readonly signMessage?: undefined;
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export function isMmTokenAuth(value: unknown): value is MmTokenAuth {
|
|
41
|
-
return (
|
|
42
|
-
value !== null &&
|
|
43
|
-
typeof value === "object" &&
|
|
44
|
-
"signatureType" in value &&
|
|
45
|
-
value.signatureType === "mm_token" &&
|
|
46
|
-
"identifier" in value &&
|
|
47
|
-
"signer" in value &&
|
|
48
|
-
typeof (value as Partial<MmTokenAuth>).accessToken === "string"
|
|
49
|
-
);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/** `storage_id` from the capability token used to construct this signer. */
|
|
53
|
-
export function mmTokenStorageId(signer: KwilSigner): string {
|
|
54
|
-
const storageId = (signer as Partial<MmTokenAuth>).mmTokenPayload?.storage_id;
|
|
55
|
-
if (typeof storageId !== "string" || !storageId.trim()) {
|
|
56
|
-
throw new Error("mm_token payload is missing storage_id");
|
|
57
|
-
}
|
|
58
|
-
return storageId.trim();
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export function mmTokenCredentialContentUri(signer: KwilSigner, credentialId: string): string {
|
|
62
|
-
return createUkycContentUri(mmTokenStorageId(signer), credentialId);
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function isMmTokenEnvelope(value: unknown): value is MmTokenEnvelope {
|
|
66
|
-
return (
|
|
67
|
-
value !== null &&
|
|
68
|
-
typeof value === "object" &&
|
|
69
|
-
"payload" in value &&
|
|
70
|
-
value.payload !== null &&
|
|
71
|
-
typeof value.payload === "object" &&
|
|
72
|
-
!Array.isArray(value.payload) &&
|
|
73
|
-
"signature" in value &&
|
|
74
|
-
typeof value.signature === "string"
|
|
75
|
-
);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
function parseJson<T>(bytes: Uint8Array, errorMessage: string): T {
|
|
79
|
-
try {
|
|
80
|
-
return JSON.parse(utf8Decode(bytes)) as T;
|
|
81
|
-
} catch (error) {
|
|
82
|
-
throw new Error(errorMessage, { cause: error });
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function decodeBase64Url(value: string, errorMessage: string): Uint8Array {
|
|
87
|
-
try {
|
|
88
|
-
return base64UrlDecode(value);
|
|
89
|
-
} catch (error) {
|
|
90
|
-
throw new Error(errorMessage, { cause: error });
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Build the MM authentication object for one UKYC capability.
|
|
96
|
-
*
|
|
97
|
-
* Pass the MetaMask-issued capability token as a **base64url-encoded** envelope string
|
|
98
|
-
* (what KGW verifies). A decoded `{ payload, signature }` object is also accepted and
|
|
99
|
-
* will be re-encoded.
|
|
100
|
-
*
|
|
101
|
-
* `signMessage` always returns the UTF-8 bytes of that encoded string — KGW ignores the
|
|
102
|
-
* request message and only verifies the envelope.
|
|
103
|
-
*/
|
|
104
|
-
export function createMmTokenAuth(encodedEnvelope: string | MmTokenEnvelope): MmTokenAuth {
|
|
105
|
-
let encodedToken: string;
|
|
106
|
-
let envelope: MmTokenEnvelope;
|
|
107
|
-
|
|
108
|
-
if (typeof encodedEnvelope === "string") {
|
|
109
|
-
const trimmed = encodedEnvelope.trim();
|
|
110
|
-
if (!trimmed) {
|
|
111
|
-
throw new Error("Invalid mm_token envelope: empty");
|
|
112
|
-
}
|
|
113
|
-
encodedToken = trimmed;
|
|
114
|
-
const envelopeBytes = decodeBase64Url(trimmed, "Invalid mm_token envelope encoding");
|
|
115
|
-
const parsed = parseJson<unknown>(envelopeBytes, "Invalid mm_token envelope JSON");
|
|
116
|
-
if (!isMmTokenEnvelope(parsed)) {
|
|
117
|
-
throw new Error("Invalid mm_token envelope: expected payload object and signature string");
|
|
118
|
-
}
|
|
119
|
-
envelope = parsed;
|
|
120
|
-
} else {
|
|
121
|
-
if (!isMmTokenEnvelope(encodedEnvelope)) {
|
|
122
|
-
throw new Error("Invalid mm_token envelope: expected payload object and signature string");
|
|
123
|
-
}
|
|
124
|
-
envelope = encodedEnvelope;
|
|
125
|
-
encodedToken = base64UrlEncode(utf8Encode(JSON.stringify(envelope)));
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
// KGW Verify receives UTF-8 of the base64url string, not the decoded JSON bytes.
|
|
129
|
-
const signatureData = utf8Encode(encodedToken);
|
|
130
|
-
|
|
131
|
-
const tokenSignatureBytes = decodeBase64Url(
|
|
132
|
-
envelope.signature,
|
|
133
|
-
"Invalid mm_token envelope signature encoding",
|
|
134
|
-
);
|
|
135
|
-
if (tokenSignatureBytes.length !== ED25519_SIGNATURE_BYTES) {
|
|
136
|
-
throw new Error(
|
|
137
|
-
`Invalid mm_token signature length: expected ${ED25519_SIGNATURE_BYTES}, got ${tokenSignatureBytes.length}`,
|
|
138
|
-
);
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
const signingPublicKey = envelope.payload.signing_public_key;
|
|
142
|
-
if (typeof signingPublicKey !== "string") {
|
|
143
|
-
throw new Error("Invalid mm_token payload: missing signing_public_key");
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
const signingPublicKeyBytes = decodeBase64Url(
|
|
147
|
-
signingPublicKey,
|
|
148
|
-
"Invalid mm_token signing_public_key encoding",
|
|
149
|
-
);
|
|
150
|
-
|
|
151
|
-
if (signingPublicKeyBytes.length !== ED25519_PUBLIC_KEY_BYTES) {
|
|
152
|
-
throw new Error(
|
|
153
|
-
`Invalid mm_token signing_public_key length: expected ${ED25519_PUBLIC_KEY_BYTES}, got ${signingPublicKeyBytes.length}`,
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
const auth = Object.assign(
|
|
158
|
-
new KwilSigner(async () => signatureData.slice(), signingPublicKeyBytes, "mm_token"),
|
|
159
|
-
{ mmTokenPayload: envelope.payload },
|
|
160
|
-
);
|
|
161
|
-
|
|
162
|
-
return Object.defineProperty(auth, "accessToken", {
|
|
163
|
-
value: encodedToken,
|
|
164
|
-
enumerable: false,
|
|
165
|
-
}) as MmTokenAuth;
|
|
166
|
-
}
|