emblem-vault-ai-signers 0.1.8-experimental.0 → 0.1.8-experimental.1

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.
Files changed (2) hide show
  1. package/README.md +178 -13
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -20,6 +20,9 @@ See the Changelog for release details: CHANGELOG.md
20
20
  npm install emblem-vault-ai-signers
21
21
  # and bring your own peers
22
22
  npm install ethers viem
23
+
24
+ # Optional: for SDK integration
25
+ npm install emblem-auth-sdk
23
26
  ```
24
27
 
25
28
  ## Usage
@@ -31,7 +34,11 @@ import { mainnet } from "viem/chains";
31
34
  import { JsonRpcProvider } from "ethers";
32
35
 
33
36
  const client = createEmblemClient({
34
- apiKey: "your-x-api-key",
37
+ apiKey: "your-x-api-key", // traditional API key auth
38
+ // OR use JWT authentication (see Authentication section below)
39
+ // jwt: "your-jwt-token",
40
+ // OR use SDK integration
41
+ // sdk: yourAuthSDK,
35
42
  // baseUrl: "https://api.emblemvault.ai" // optional (tests use https://dev-api.emblemvault.ai)
36
43
  });
37
44
 
@@ -66,6 +73,142 @@ const solKit = await client.toSolanaKitSigner();
66
73
  console.log(solKit.publicKey);
67
74
  ```
68
75
 
76
+ ## Authentication
77
+
78
+ The library supports multiple authentication methods. You only need to provide **one** of the following:
79
+
80
+ ### API Key Authentication (Traditional)
81
+
82
+ ```ts
83
+ const client = createEmblemClient({
84
+ apiKey: "pk_your_api_key_here"
85
+ });
86
+ ```
87
+
88
+ ### JWT Authentication
89
+
90
+ #### Static JWT Token
91
+ ```ts
92
+ const client = createEmblemClient({
93
+ jwt: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
94
+ });
95
+ ```
96
+
97
+ #### Dynamic JWT Provider
98
+ For tokens that need refreshing or are fetched asynchronously:
99
+ ```ts
100
+ const client = createEmblemClient({
101
+ getJwt: async () => {
102
+ // Fetch from your auth service, refresh if needed
103
+ return await authService.getAccessToken();
104
+ }
105
+ });
106
+
107
+ // Or synchronous
108
+ const client = createEmblemClient({
109
+ getJwt: () => localStorage.getItem('authToken')
110
+ });
111
+ ```
112
+
113
+ ### SDK Integration
114
+
115
+ If you're using an authentication SDK that manages sessions:
116
+ ```ts
117
+ const client = createEmblemClient({
118
+ sdk: myAuthSDK // Must have getSession() method that returns { authToken }
119
+ });
120
+
121
+ // Example with EmblemAuthSDK:
122
+ import { EmblemAuthSDK } from 'emblem-auth-sdk';
123
+
124
+ const authSDK = new EmblemAuthSDK({
125
+ appId: 'your-app-id',
126
+ apiUrl: 'https://api.emblemvault.ai'
127
+ });
128
+
129
+ const client = createEmblemClient({
130
+ sdk: authSDK // EmblemAuthSDK has getSession() that returns { authToken, user, ... }
131
+ });
132
+
133
+ // Example with custom auth SDK:
134
+ const client = createEmblemClient({
135
+ sdk: {
136
+ getSession: () => ({
137
+ authToken: auth0.getIdToken(),
138
+ user: { id: '123' }
139
+ })
140
+ }
141
+ });
142
+ ```
143
+
144
+ ### Custom Auth Headers
145
+
146
+ For advanced authentication schemes:
147
+ ```ts
148
+ const client = createEmblemClient({
149
+ getAuthHeaders: async () => ({
150
+ 'Authorization': 'Custom my-custom-token',
151
+ 'X-API-Version': '2.0',
152
+ 'X-Client-ID': 'my-app'
153
+ })
154
+ });
155
+ ```
156
+
157
+ ### Authentication Priority
158
+
159
+ When multiple auth methods are provided, they're used in this order:
160
+ 1. `getAuthHeaders()` (highest priority)
161
+ 2. `apiKey`
162
+ 3. `jwt` / `getJwt()` / `sdk` (lowest priority)
163
+
164
+ ### Browser vs Server Usage
165
+
166
+ - **Browser**: JWT/SDK authentication is recommended for client-side apps where users authenticate themselves
167
+ - **Server**: API key authentication is recommended for server-side applications with stored credentials
168
+
169
+ ### Complete SDK Integration Example
170
+
171
+ Here's a complete example using the EmblemAuthSDK with the signers library:
172
+
173
+ ```ts
174
+ import { EmblemAuthSDK } from 'emblem-auth-sdk';
175
+ import { createEmblemClient } from 'emblem-vault-ai-signers';
176
+ import { JsonRpcProvider, parseEther } from 'ethers';
177
+
178
+ // 1. Initialize the auth SDK
179
+ const authSDK = new EmblemAuthSDK({
180
+ appId: 'your-app-id',
181
+ apiUrl: 'https://api.emblemvault.ai',
182
+ onSuccess: (session) => {
183
+ console.log('User authenticated:', session.user);
184
+ }
185
+ });
186
+
187
+ // 2. Create the signer client using the SDK
188
+ const client = createEmblemClient({
189
+ sdk: authSDK // Pass the SDK instance directly
190
+ });
191
+
192
+ // 3. Authenticate the user (opens auth modal)
193
+ await authSDK.openAuthModal();
194
+
195
+ // 4. Once authenticated, create wallets/accounts
196
+ const provider = new JsonRpcProvider(process.env.RPC_URL);
197
+ const wallet = await client.toEthersWallet(provider);
198
+
199
+ // 5. Sign and send transactions
200
+ const txHash = await wallet.signAndBroadcast({
201
+ to: "0x...",
202
+ value: parseEther("0.01")
203
+ });
204
+ ```
205
+
206
+ The SDK integration automatically handles:
207
+ - JWT token management and refresh
208
+ - Session persistence across page reloads
209
+ - Authentication state management
210
+ - Seamless integration with the signers library
211
+
69
212
  ## Replace Private Keys (Examples)
70
213
 
71
214
  Below are quick swaps showing how to remove local private keys and route signing through Emblem.
@@ -175,7 +318,13 @@ console.log(solWeb3.publicKey);
175
318
 
176
319
  ```ts
177
320
  type EmblemRemoteConfig = {
178
- apiKey: string;
321
+ // Authentication (pick one method):
322
+ apiKey?: string; // traditional x-api-key header
323
+ jwt?: string; // static JWT for Authorization: Bearer
324
+ getJwt?: () => Promise<string> | string; // dynamic JWT provider
325
+ getAuthHeaders?: () => Promise<Record<string, string>> | Record<string, string>; // custom auth headers
326
+ sdk?: { getSession: () => { authToken?: string } | null }; // SDK integration (e.g., EmblemAuthSDK)
327
+
179
328
  baseUrl?: string; // default https://api.emblemvault.ai
180
329
  };
181
330
 
@@ -200,7 +349,7 @@ Adapters POST to the Emblem API endpoints:
200
349
  - `POST /sign-typed-message` – `{ vaultId, domain, types, message }`
201
350
  - `POST /sign-eth-tx` – `{ vaultId, transaction }` (expects ethers-serializable fields)
202
351
 
203
- On first use, both adapters query `GET /vault/info` with header `x-api-key` to obtain:
352
+ On first use, both adapters query `POST /vault/info` with authentication headers to obtain:
204
353
 
205
354
  - Vault ID
206
355
  - Solana Address
@@ -222,15 +371,20 @@ This library is designed for environments where **users provide their own API ke
222
371
 
223
372
  #### What This Means
224
373
  ```javascript
225
- // Users provide their OWN API keys to YOUR dApp
374
+ // Users provide their OWN credentials to YOUR dApp
226
375
  const client = createEmblemClient({
376
+ // Traditional API key
227
377
  apiKey: userApiKey, // User's key, not yours
378
+ // OR JWT token from user's authentication
379
+ jwt: userJwtToken, // User's JWT, not yours
380
+ // OR SDK integration
381
+ sdk: userAuthSDK, // User's auth SDK
228
382
  baseUrl: "https://api.emblemvault.ai"
229
383
  });
230
384
  ```
231
385
 
232
- If a user runs your dApp code, they are trusting it with their API key and signing authority. There is no way to prevent malicious dApp code from:
233
- - Logging API keys
386
+ If a user runs your dApp code, they are trusting it with their authentication credentials and signing authority. There is no way to prevent malicious dApp code from:
387
+ - Logging API keys or JWT tokens
234
388
  - Intercepting `fetch()` calls
235
389
  - Changing the `baseUrl`
236
390
  - Making unauthorized signing requests
@@ -241,9 +395,10 @@ If a user runs your dApp code, they are trusting it with their API key and signi
241
395
 
242
396
  1. **Only use trusted dApps** - Verify the source and reputation
243
397
  2. **Review open source code** when possible
244
- 3. **Use separate API keys** for different dApps
398
+ 3. **Use separate credentials** for different dApps (API keys, JWT tokens)
245
399
  4. **Monitor signing activity** in your Emblem dashboard
246
- 5. **Test with staging keys first** before using production
400
+ 5. **Test with staging credentials first** before using production
401
+ 6. **Understand token expiration** - JWT tokens expire and may need refresh
247
402
 
248
403
  ### Best Practices for Implementers
249
404
 
@@ -251,16 +406,20 @@ If a user runs your dApp code, they are trusting it with their API key and signi
251
406
  2. **Document your security model** - Be transparent about API key handling
252
407
  3. **Minimize dependencies** - Reduce supply chain attack surface
253
408
  4. **Use Content Security Policy** - Add CSP headers to protect against XSS
254
- 5. **Never log or store user API keys** - Only use them in-memory for signing
255
- 6. **Implement proper error handling** - Don't expose API keys in error messages
409
+ 5. **Never log or store user credentials** - Only use API keys/JWTs in-memory for signing
410
+ 6. **Implement proper error handling** - Don't expose credentials in error messages
411
+ 7. **Handle JWT expiration gracefully** - Implement token refresh when using dynamic JWTs
412
+ 8. **Prefer JWT auth for client-side apps** - More secure than exposing long-lived API keys
256
413
 
257
414
  ### Server-Side Usage
258
415
 
259
416
  When used server-side (Node.js):
260
417
  - Store API keys in environment variables
261
- - Never expose keys to client-side code
418
+ - Never expose credentials to client-side code
262
419
  - Use proper access controls and authentication
263
420
  - Implement rate limiting if exposing signing endpoints
421
+ - Consider API key auth for server-to-server communication
422
+ - Use JWT auth when proxying user authentication
264
423
 
265
424
  ### Development vs Production
266
425
 
@@ -273,14 +432,20 @@ const devClient = createEmblemClient({
273
432
  baseUrl: "https://dev-api.emblemvault.ai"
274
433
  });
275
434
 
276
- // Production
435
+ // Production with API key
277
436
  const prodClient = createEmblemClient({
278
437
  apiKey: process.env.PROD_API_KEY,
279
438
  baseUrl: "https://api.emblemvault.ai"
280
439
  });
440
+
441
+ // Production with JWT (client-side)
442
+ const jwtClient = createEmblemClient({
443
+ getJwt: async () => await auth.getAccessToken(),
444
+ baseUrl: "https://api.emblemvault.ai"
445
+ });
281
446
  ```
282
447
 
283
- API keys from one environment do not work in another, providing natural isolation.
448
+ Credentials from one environment do not work in another, providing natural isolation.
284
449
 
285
450
  ---
286
451
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "emblem-vault-ai-signers",
3
- "version": "0.1.8-experimental.0",
3
+ "version": "0.1.8-experimental.1",
4
4
  "description": "Emblem Vault remote signer adapters for viem and ethers",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",