@t402/extensions 2.0.0 → 2.3.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.
@@ -1,2 +1,361 @@
1
+ /**
2
+ * Sign-In-With-X (SIWx) Type Definitions
3
+ *
4
+ * CAIP-122 compliant wallet-based identity assertions for t402 protocol.
5
+ */
6
+ /**
7
+ * Supported signature schemes for SIWx.
8
+ */
9
+ type SignatureScheme = "eip191" | "eip712" | "eip1271" | "eip6492" | "siws" | "sep10";
10
+ /**
11
+ * Information provided by server about SIWx requirements.
12
+ */
13
+ interface SIWxExtensionInfo {
14
+ /** Domain derived from resourceUri (without protocol) */
15
+ domain: string;
16
+ /** Full resource URI */
17
+ uri: string;
18
+ /** Optional statement explaining what the signature is for */
19
+ statement?: string;
20
+ /** SIWx version (default: "1") */
21
+ version: string;
22
+ /** Chain ID in CAIP-2 format (e.g., "eip155:8453") */
23
+ chainId: string;
24
+ /** Cryptographically secure nonce */
25
+ nonce: string;
26
+ /** ISO 8601 timestamp when message was issued */
27
+ issuedAt: string;
28
+ /** ISO 8601 timestamp when signature expires */
29
+ expirationTime?: string;
30
+ /** ISO 8601 timestamp before which signature is not valid */
31
+ notBefore?: string;
32
+ /** Optional request ID for session correlation */
33
+ requestId?: string;
34
+ /** Resources being authenticated for */
35
+ resources: string[];
36
+ /** Preferred signature scheme */
37
+ signatureScheme?: SignatureScheme;
38
+ }
39
+ /**
40
+ * SIWx extension declaration for server responses.
41
+ */
42
+ interface SIWxExtension {
43
+ /** Extension information */
44
+ info: SIWxExtensionInfo;
45
+ /** JSON Schema for validation */
46
+ schema: object;
47
+ }
48
+ /**
49
+ * Complete SIWx payload including signature.
50
+ */
51
+ interface SIWxPayload {
52
+ /** Domain from the server */
53
+ domain: string;
54
+ /** Wallet address making the assertion */
55
+ address: string;
56
+ /** Optional statement */
57
+ statement?: string;
58
+ /** Resource URI */
59
+ uri: string;
60
+ /** SIWx version */
61
+ version: string;
62
+ /** Chain ID in CAIP-2 format */
63
+ chainId: string;
64
+ /** Nonce from server */
65
+ nonce: string;
66
+ /** ISO 8601 timestamp when message was issued */
67
+ issuedAt: string;
68
+ /** ISO 8601 timestamp when signature expires */
69
+ expirationTime?: string;
70
+ /** ISO 8601 timestamp before which signature is not valid */
71
+ notBefore?: string;
72
+ /** Optional request ID */
73
+ requestId?: string;
74
+ /** Resources array */
75
+ resources?: string[];
76
+ /** Cryptographic signature */
77
+ signature: string;
78
+ }
79
+ /**
80
+ * Options for declaring SIWx extension on server.
81
+ */
82
+ interface DeclareSIWxOptions {
83
+ /** Full URI of the resource (domain derived from this) */
84
+ resourceUri: string;
85
+ /** Optional statement explaining the sign-in purpose */
86
+ statement?: string;
87
+ /** SIWx version (defaults to "1") */
88
+ version?: string;
89
+ /** Network in CAIP-2 format (e.g., "eip155:8453") */
90
+ network: `${string}:${string}`;
91
+ /** Expiration time (auto-set to +5 minutes if not provided) */
92
+ expirationTime?: string;
93
+ /** Preferred signature scheme */
94
+ signatureScheme?: SignatureScheme;
95
+ }
96
+ /**
97
+ * Options for validating SIWx messages.
98
+ */
99
+ interface ValidateSIWxOptions {
100
+ /** Maximum age of issuedAt in milliseconds (default: 5 minutes) */
101
+ maxAge?: number;
102
+ /** Custom nonce validation function */
103
+ checkNonce?: (nonce: string) => boolean;
104
+ }
105
+ /**
106
+ * Options for verifying SIWx signatures.
107
+ */
108
+ interface VerifySIWxOptions {
109
+ /** Web3 provider for on-chain verification */
110
+ provider?: unknown;
111
+ /** Enable EIP-1271/6492 smart wallet verification */
112
+ checkSmartWallet?: boolean;
113
+ }
114
+ /**
115
+ * Result of SIWx message validation.
116
+ */
117
+ interface SIWxValidationResult {
118
+ /** Whether the message is valid */
119
+ valid: boolean;
120
+ /** Error message if invalid */
121
+ error?: string;
122
+ }
123
+ /**
124
+ * Result of SIWx signature verification.
125
+ */
126
+ interface SIWxVerificationResult {
127
+ /** Whether the signature is valid */
128
+ valid: boolean;
129
+ /** Recovered/verified address */
130
+ address?: string;
131
+ /** Error message if invalid */
132
+ error?: string;
133
+ }
134
+ /**
135
+ * Signer interface for client-side signing.
136
+ */
137
+ interface SIWxSigner {
138
+ /** Wallet address */
139
+ address: string;
140
+ /** Sign a message using personal_sign (EIP-191) */
141
+ signMessage?(message: string): Promise<string>;
142
+ /** Sign typed data (EIP-712) */
143
+ signTypedData?(data: unknown): Promise<string>;
144
+ }
1
145
 
2
- export { }
146
+ /**
147
+ * Sign-In-With-X (SIWx) Server-Side Implementation
148
+ *
149
+ * Provides functions for servers to declare SIWx requirements,
150
+ * parse client headers, and verify signatures.
151
+ */
152
+
153
+ /**
154
+ * Declares a SIWx extension for server responses.
155
+ *
156
+ * @param options - Extension declaration options
157
+ * @returns SIWx extension object ready for response
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * const extension = declareSIWxExtension({
162
+ * resourceUri: "https://api.example.com/premium",
163
+ * network: "eip155:8453",
164
+ * statement: "Sign in to access premium content",
165
+ * });
166
+ * ```
167
+ */
168
+ declare function declareSIWxExtension(options: DeclareSIWxOptions): SIWxExtension;
169
+ /**
170
+ * Parses a SIWx header from client request.
171
+ *
172
+ * The header format is base64-encoded JSON.
173
+ *
174
+ * @param header - Base64-encoded SIWx header value
175
+ * @returns Parsed SIWx payload
176
+ * @throws Error if header is invalid
177
+ *
178
+ * @example
179
+ * ```typescript
180
+ * const payload = parseSIWxHeader(request.headers['x-t402-siwx']);
181
+ * ```
182
+ */
183
+ declare function parseSIWxHeader(header: string): SIWxPayload;
184
+ /**
185
+ * Validates a SIWx message against expected values.
186
+ *
187
+ * @param message - The SIWx payload to validate
188
+ * @param expectedResourceUri - Expected resource URI (domain validated from this)
189
+ * @param options - Validation options
190
+ * @returns Validation result
191
+ *
192
+ * @example
193
+ * ```typescript
194
+ * const result = validateSIWxMessage(payload, "https://api.example.com/premium", {
195
+ * maxAge: 5 * 60 * 1000, // 5 minutes
196
+ * checkNonce: (nonce) => usedNonces.has(nonce) === false,
197
+ * });
198
+ * ```
199
+ */
200
+ declare function validateSIWxMessage(message: SIWxPayload, expectedResourceUri: string, options?: ValidateSIWxOptions): SIWxValidationResult;
201
+ /**
202
+ * Verifies a SIWx signature.
203
+ *
204
+ * Supports EIP-191 personal signatures and can optionally verify
205
+ * smart wallet signatures via EIP-1271/6492.
206
+ *
207
+ * @param message - The SIWx payload to verify
208
+ * @param signature - The signature to verify (hex-encoded)
209
+ * @param options - Verification options
210
+ * @returns Verification result with recovered address
211
+ *
212
+ * @example
213
+ * ```typescript
214
+ * const result = await verifySIWxSignature(payload, payload.signature, {
215
+ * checkSmartWallet: true,
216
+ * provider: web3Provider,
217
+ * });
218
+ * ```
219
+ */
220
+ declare function verifySIWxSignature(message: SIWxPayload, signature: string, options?: VerifySIWxOptions): Promise<SIWxVerificationResult>;
221
+ /**
222
+ * Constructs the CAIP-122 message string from payload.
223
+ *
224
+ * @param payload - SIWx payload
225
+ * @returns CAIP-122 formatted message string
226
+ */
227
+ declare function constructMessage(payload: SIWxPayload): string;
228
+ /**
229
+ * Hashes a message with the Ethereum signed message prefix (EIP-191).
230
+ *
231
+ * @param message - Message to hash
232
+ * @returns Hex-encoded keccak256 hash with 0x prefix
233
+ */
234
+ declare function hashMessage(message: string): string;
235
+ /**
236
+ * Verifies a signature using EIP-6492 (universal signature verification).
237
+ *
238
+ * This supports both deployed and undeployed smart wallets.
239
+ *
240
+ * @param walletAddress - Wallet address (may be counterfactual)
241
+ * @param messageHash - Hash of the message that was signed
242
+ * @param signature - The signature (may include deployment data)
243
+ * @param provider - Ethereum provider
244
+ * @returns True if signature is valid
245
+ */
246
+ declare function verifyEIP6492Signature(walletAddress: string, messageHash: string, signature: string, provider: unknown): Promise<boolean>;
247
+
248
+ /**
249
+ * Sign-In-With-X (SIWx) Client-Side Implementation
250
+ *
251
+ * Provides functions for clients to create and sign SIWx messages.
252
+ */
253
+
254
+ /**
255
+ * Encodes a SIWx payload for transmission in HTTP header.
256
+ *
257
+ * @param payload - The SIWx payload to encode
258
+ * @returns Base64-encoded JSON string
259
+ *
260
+ * @example
261
+ * ```typescript
262
+ * const header = encodeSIWxHeader(payload);
263
+ * fetch(url, {
264
+ * headers: { 'X-T402-SIWx': header }
265
+ * });
266
+ * ```
267
+ */
268
+ declare function encodeSIWxHeader(payload: SIWxPayload): string;
269
+ /**
270
+ * Creates a CAIP-122 formatted message string from server info.
271
+ *
272
+ * @param serverInfo - Extension info from server
273
+ * @param address - Wallet address signing the message
274
+ * @returns CAIP-122 formatted message string ready for signing
275
+ *
276
+ * @example
277
+ * ```typescript
278
+ * const message = createSIWxMessage(extension.info, wallet.address);
279
+ * const signature = await wallet.signMessage(message);
280
+ * ```
281
+ */
282
+ declare function createSIWxMessage(serverInfo: SIWxExtensionInfo, address: string): string;
283
+ /**
284
+ * Creates EIP-712 typed data for SIWx signing.
285
+ *
286
+ * @param serverInfo - Extension info from server
287
+ * @param address - Wallet address signing the message
288
+ * @returns EIP-712 typed data object
289
+ */
290
+ declare function createSIWxTypedData(serverInfo: SIWxExtensionInfo, address: string): {
291
+ domain: {
292
+ name: string;
293
+ version: string;
294
+ chainId: number;
295
+ };
296
+ types: {
297
+ SIWx: Array<{
298
+ name: string;
299
+ type: string;
300
+ }>;
301
+ };
302
+ primaryType: "SIWx";
303
+ message: Record<string, unknown>;
304
+ };
305
+ /**
306
+ * Signs a SIWx message using the provided signer.
307
+ *
308
+ * @param message - CAIP-122 formatted message to sign
309
+ * @param signer - Wallet/signer interface with signMessage
310
+ * @param options - Signing options
311
+ * @param options.signatureScheme - Signature scheme to use
312
+ * @param options.serverInfo - Server info for verification
313
+ * @returns Hex-encoded signature
314
+ *
315
+ * @example
316
+ * ```typescript
317
+ * const signature = await signSIWxMessage(message, wallet, {
318
+ * signatureScheme: 'eip191'
319
+ * });
320
+ * ```
321
+ */
322
+ declare function signSIWxMessage(message: string, signer: SIWxSigner, options?: {
323
+ signatureScheme?: SignatureScheme;
324
+ serverInfo?: SIWxExtensionInfo;
325
+ }): Promise<string>;
326
+ /**
327
+ * Creates a complete SIWx payload from server extension and signer.
328
+ *
329
+ * This is the main entry point for clients - it handles message construction,
330
+ * signing, and payload assembly.
331
+ *
332
+ * @param serverExtension - Extension from server's 402 response
333
+ * @param signer - Wallet/signer interface
334
+ * @returns Complete signed SIWx payload ready for header encoding
335
+ *
336
+ * @example
337
+ * ```typescript
338
+ * // Get extension from server 402 response
339
+ * const extension = paymentRequirements.extensions?.siwx;
340
+ *
341
+ * // Create signed payload
342
+ * const payload = await createSIWxPayload(extension, wallet);
343
+ *
344
+ * // Encode and send with retry
345
+ * const header = encodeSIWxHeader(payload);
346
+ * fetch(url, {
347
+ * headers: { 'X-T402-SIWx': header }
348
+ * });
349
+ * ```
350
+ */
351
+ declare function createSIWxPayload(serverExtension: SIWxExtension, signer: SIWxSigner): Promise<SIWxPayload>;
352
+ /**
353
+ * Extension key for SIWx in payment requirements.
354
+ */
355
+ declare const SIWX_EXTENSION_KEY = "siwx";
356
+ /**
357
+ * HTTP header name for SIWx payload.
358
+ */
359
+ declare const SIWX_HEADER_NAME = "X-T402-SIWx";
360
+
361
+ export { type DeclareSIWxOptions, SIWX_EXTENSION_KEY, SIWX_HEADER_NAME, type SIWxExtension, type SIWxExtensionInfo, type SIWxPayload, type SIWxSigner, type SIWxValidationResult, type SIWxVerificationResult, type SignatureScheme, type ValidateSIWxOptions, type VerifySIWxOptions, constructMessage, createSIWxMessage, createSIWxPayload, createSIWxTypedData, declareSIWxExtension, encodeSIWxHeader, hashMessage, parseSIWxHeader, signSIWxMessage, validateSIWxMessage, verifyEIP6492Signature, verifySIWxSignature };
@@ -1,2 +1,33 @@
1
- import "../chunk-MKFJ5AA3.mjs";
1
+ import {
2
+ SIWX_EXTENSION_KEY,
3
+ SIWX_HEADER_NAME,
4
+ constructMessage,
5
+ createSIWxMessage,
6
+ createSIWxPayload,
7
+ createSIWxTypedData,
8
+ declareSIWxExtension,
9
+ encodeSIWxHeader,
10
+ hashMessage,
11
+ parseSIWxHeader,
12
+ signSIWxMessage,
13
+ validateSIWxMessage,
14
+ verifyEIP6492Signature,
15
+ verifySIWxSignature
16
+ } from "../chunk-D7SENN2L.mjs";
17
+ export {
18
+ SIWX_EXTENSION_KEY,
19
+ SIWX_HEADER_NAME,
20
+ constructMessage,
21
+ createSIWxMessage,
22
+ createSIWxPayload,
23
+ createSIWxTypedData,
24
+ declareSIWxExtension,
25
+ encodeSIWxHeader,
26
+ hashMessage,
27
+ parseSIWxHeader,
28
+ signSIWxMessage,
29
+ validateSIWxMessage,
30
+ verifyEIP6492Signature,
31
+ verifySIWxSignature
32
+ };
2
33
  //# sourceMappingURL=index.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@t402/extensions",
3
- "version": "2.0.0",
3
+ "version": "2.3.0",
4
4
  "main": "./dist/cjs/index.js",
5
5
  "module": "./dist/esm/index.js",
6
6
  "types": "./dist/cjs/index.d.ts",
@@ -23,18 +23,29 @@
23
23
  "eslint-plugin-import": "^2.31.0",
24
24
  "eslint-plugin-jsdoc": "^50.6.9",
25
25
  "eslint-plugin-prettier": "^5.2.6",
26
+ "glob": "^13.0.0",
26
27
  "prettier": "3.5.2",
27
28
  "tsup": "^8.4.0",
28
- "tsx": "^4.19.2",
29
+ "tsx": "^4.21.0",
29
30
  "typescript": "^5.7.3",
30
- "vite": "^6.2.6",
31
+ "vite": "^7.3.1",
31
32
  "vite-tsconfig-paths": "^5.1.4",
32
- "vitest": "^3.0.5"
33
+ "vitest": "^3.2.4"
33
34
  },
34
35
  "dependencies": {
36
+ "@noble/curves": "^1.8.1",
37
+ "@noble/hashes": "^1.7.1",
35
38
  "ajv": "^8.17.1",
36
39
  "zod": "^3.24.2",
37
- "@t402/core": "2.0.0"
40
+ "@t402/core": "2.3.0"
41
+ },
42
+ "peerDependencies": {
43
+ "viem": "^2.0.0"
44
+ },
45
+ "peerDependenciesMeta": {
46
+ "viem": {
47
+ "optional": true
48
+ }
38
49
  },
39
50
  "exports": {
40
51
  ".": {
@@ -1 +0,0 @@
1
- //# sourceMappingURL=chunk-MKFJ5AA3.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}