@veridex/sdk 1.0.0-beta.18 → 1.0.0-beta.21
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 +321 -74
- package/dist/auth/prepareAuth.d.mts +25 -0
- package/dist/auth/prepareAuth.d.ts +25 -0
- package/dist/auth/prepareAuth.js +1553 -0
- package/dist/auth/prepareAuth.js.map +1 -0
- package/dist/auth/prepareAuth.mjs +1530 -0
- package/dist/auth/prepareAuth.mjs.map +1 -0
- package/dist/index.d.mts +1 -25
- package/dist/index.d.ts +1 -25
- package/dist/index.js +0 -24
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +0 -16
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -1
package/README.md
CHANGED
|
@@ -14,20 +14,25 @@ npm install @veridex/sdk ethers
|
|
|
14
14
|
```typescript
|
|
15
15
|
import { createSDK } from '@veridex/sdk';
|
|
16
16
|
|
|
17
|
+
// Initialize — returns synchronously, defaults to testnet
|
|
17
18
|
const sdk = createSDK('base');
|
|
18
19
|
|
|
19
20
|
// Register a passkey (biometric prompt)
|
|
20
21
|
const credential = await sdk.passkey.register('user@example.com', 'My Wallet');
|
|
21
22
|
|
|
22
|
-
//
|
|
23
|
+
// Deterministic vault address derived from your passkey
|
|
23
24
|
const vault = sdk.getVaultAddress();
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
25
|
+
console.log('Your vault:', vault);
|
|
26
|
+
|
|
27
|
+
// Prepare and execute a transfer (requires a signer to pay gas)
|
|
28
|
+
const prepared = await sdk.prepareTransfer({
|
|
29
|
+
targetChain: 10004, // Base Sepolia Wormhole chain ID
|
|
30
|
+
token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // USDC
|
|
31
|
+
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f5A234',
|
|
32
|
+
amount: 1000000n, // 1 USDC (6 decimals)
|
|
30
33
|
});
|
|
34
|
+
const result = await sdk.executeTransfer(prepared, signer);
|
|
35
|
+
console.log('Tx hash:', result.transactionHash);
|
|
31
36
|
```
|
|
32
37
|
|
|
33
38
|
## Architecture
|
|
@@ -61,6 +66,7 @@ await sdk.transferViaRelayer({
|
|
|
61
66
|
| **Optimism** | Spoke (EVM) | 24 | secp256r1 + secp256k1 | Sepolia + Mainnet |
|
|
62
67
|
| **Arbitrum** | Spoke (EVM) | 23 | secp256r1 + secp256k1 | Sepolia + Mainnet |
|
|
63
68
|
| **Polygon** | Spoke (EVM) | 5 | secp256r1 + secp256k1 | Amoy + Mainnet |
|
|
69
|
+
| **Monad** | Spoke (EVM) | 10048 | secp256r1 (EIP-7951) + secp256k1 | Testnet + Mainnet |
|
|
64
70
|
| **Solana** | Spoke | 1 | Ed25519 | Devnet + Mainnet |
|
|
65
71
|
| **Aptos** | Spoke | 22 | Ed25519 | Testnet + Mainnet |
|
|
66
72
|
| **Sui** | Spoke | 21 | secp256k1 | Testnet + Mainnet |
|
|
@@ -69,19 +75,39 @@ await sdk.transferViaRelayer({
|
|
|
69
75
|
|
|
70
76
|
## Key Features
|
|
71
77
|
|
|
72
|
-
### Passkey
|
|
78
|
+
### Passkey Registration & Authentication
|
|
73
79
|
|
|
74
80
|
```typescript
|
|
75
|
-
|
|
76
|
-
|
|
81
|
+
import { createSDK } from '@veridex/sdk';
|
|
82
|
+
|
|
83
|
+
const sdk = createSDK('base');
|
|
77
84
|
|
|
78
|
-
//
|
|
79
|
-
const
|
|
85
|
+
// Register — triggers biometric prompt, returns credential
|
|
86
|
+
const credential = await sdk.passkey.register('user@example.com', 'My Wallet');
|
|
87
|
+
console.log('Key hash:', credential.keyHash);
|
|
88
|
+
console.log('Credential ID:', credential.credentialId);
|
|
89
|
+
|
|
90
|
+
// Check for existing passkeys
|
|
91
|
+
const stored = sdk.passkey.getAllStoredCredentials();
|
|
92
|
+
if (stored.length > 0) {
|
|
93
|
+
// Authenticate with a discoverable credential (shows passkey picker)
|
|
94
|
+
const { credential, signature } = await sdk.passkey.authenticate();
|
|
95
|
+
console.log('Authenticated as:', credential.keyHash);
|
|
96
|
+
} else {
|
|
97
|
+
// Or set a known credential directly
|
|
98
|
+
sdk.passkey.setCredential({
|
|
99
|
+
credentialId: 'abc123',
|
|
100
|
+
publicKeyX: BigInt('0x...'),
|
|
101
|
+
publicKeyY: BigInt('0x...'),
|
|
102
|
+
keyHash: '0x...',
|
|
103
|
+
});
|
|
104
|
+
}
|
|
80
105
|
```
|
|
81
106
|
|
|
82
107
|
- **RIP-7212** native P-256 verification on EVM (~3,450 gas)
|
|
83
108
|
- **FCL fallback** for chains without precompile
|
|
84
109
|
- **Stacks** has native `secp256r1-verify` in Clarity — no workarounds needed
|
|
110
|
+
- **Monad** has EIP-7951 P-256 precompile at `0x0100` (6,900 gas)
|
|
85
111
|
|
|
86
112
|
### Deterministic Vaults
|
|
87
113
|
|
|
@@ -89,56 +115,213 @@ const signature = await sdk.passkey.sign(challenge);
|
|
|
89
115
|
// Same address on Base, Optimism, Arbitrum, Ethereum, Polygon
|
|
90
116
|
const vault = sdk.getVaultAddress();
|
|
91
117
|
|
|
92
|
-
//
|
|
93
|
-
|
|
118
|
+
// Get vault address for a specific chain
|
|
119
|
+
const opVault = sdk.getVaultAddressForChain(24); // Optimism
|
|
94
120
|
|
|
95
|
-
|
|
121
|
+
// Check if vault exists on-chain
|
|
122
|
+
const info = await sdk.getVaultInfo();
|
|
123
|
+
console.log('Deployed:', info?.exists);
|
|
96
124
|
|
|
97
|
-
|
|
125
|
+
// Create vault (user pays gas)
|
|
126
|
+
const result = await sdk.createVault(signer);
|
|
127
|
+
console.log('Vault created:', result.address);
|
|
128
|
+
|
|
129
|
+
// Or create with sponsored gas (Veridex pays)
|
|
130
|
+
const sponsored = await sdk.createVaultSponsored();
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### Transfers
|
|
98
134
|
|
|
99
135
|
```typescript
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
maxValue: parseEther('0.1'),
|
|
103
|
-
allowedChains: [30, 1], // Base + Solana
|
|
104
|
-
});
|
|
136
|
+
import { createSDK } from '@veridex/sdk';
|
|
137
|
+
import { ethers } from 'ethers';
|
|
105
138
|
|
|
106
|
-
|
|
107
|
-
await sdk.sessions.transfer(session, { token, recipient, amount });
|
|
108
|
-
await sdk.sessions.transfer(session, { token, recipient, amount });
|
|
139
|
+
const sdk = createSDK('base', { network: 'testnet' });
|
|
109
140
|
|
|
110
|
-
//
|
|
111
|
-
await sdk.
|
|
141
|
+
// After registering or setting a credential...
|
|
142
|
+
await sdk.passkey.register('user@example.com', 'My Wallet');
|
|
143
|
+
|
|
144
|
+
// 1. Prepare transfer (shows gas estimate before signing)
|
|
145
|
+
const prepared = await sdk.prepareTransfer({
|
|
146
|
+
targetChain: 10004, // Base Sepolia
|
|
147
|
+
token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e', // USDC
|
|
148
|
+
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f5A234',
|
|
149
|
+
amount: 1000000n, // 1 USDC
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
// 2. Show human-readable summary
|
|
153
|
+
const summary = await sdk.getTransactionSummary(prepared);
|
|
154
|
+
console.log(summary.title); // "Transfer"
|
|
155
|
+
console.log(summary.description); // "Send 1.0 USDC to 0x742d...5A234"
|
|
156
|
+
console.log('Gas cost:', prepared.formattedCost);
|
|
157
|
+
|
|
158
|
+
// 3. Execute (signs with passkey, then dispatches)
|
|
159
|
+
const provider = new ethers.JsonRpcProvider('https://sepolia.base.org');
|
|
160
|
+
const signer = new ethers.Wallet(PRIVATE_KEY, provider);
|
|
161
|
+
const result = await sdk.executeTransfer(prepared, signer);
|
|
162
|
+
console.log('Tx hash:', result.transactionHash);
|
|
163
|
+
|
|
164
|
+
// 4. Wait for confirmation
|
|
165
|
+
const state = await sdk.waitForTransaction(result.transactionHash);
|
|
166
|
+
console.log('Confirmed in block:', state.blockNumber);
|
|
112
167
|
```
|
|
113
168
|
|
|
114
|
-
### Gasless
|
|
169
|
+
### Gasless Transfers (via Relayer)
|
|
115
170
|
|
|
116
171
|
```typescript
|
|
117
172
|
const sdk = createSDK('base', {
|
|
173
|
+
network: 'testnet',
|
|
118
174
|
relayerUrl: 'https://relayer.veridex.network',
|
|
119
175
|
relayerApiKey: 'your-api-key',
|
|
120
176
|
});
|
|
121
177
|
|
|
178
|
+
await sdk.passkey.register('user@example.com', 'My Wallet');
|
|
179
|
+
|
|
122
180
|
// Relayer sponsors gas — user pays nothing
|
|
123
|
-
await sdk.transferViaRelayer({
|
|
124
|
-
|
|
125
|
-
|
|
181
|
+
const result = await sdk.transferViaRelayer({
|
|
182
|
+
targetChain: 10004,
|
|
183
|
+
token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
|
|
184
|
+
recipient: '0x742d35Cc6634C0532925a3b844Bc9e7595f5A234',
|
|
126
185
|
amount: 1000000n,
|
|
127
186
|
});
|
|
187
|
+
console.log('Tx hash:', result.transactionHash);
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### Session Keys
|
|
191
|
+
|
|
192
|
+
Session keys are managed via the `SessionManager` class, separate from the main SDK:
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { createSDK, SessionManager } from '@veridex/sdk';
|
|
196
|
+
|
|
197
|
+
const sdk = createSDK('base');
|
|
198
|
+
await sdk.passkey.register('user@example.com', 'My Wallet');
|
|
199
|
+
|
|
200
|
+
// SessionManager wraps the SDK for session operations
|
|
201
|
+
const sessionManager = new SessionManager({ sdk });
|
|
202
|
+
|
|
203
|
+
// Create a session (one passkey auth)
|
|
204
|
+
const session = await sessionManager.createSession({
|
|
205
|
+
duration: 3600, // 1 hour
|
|
206
|
+
maxValue: BigInt(1e18), // Max 1 token per tx
|
|
207
|
+
allowedChains: [10004], // Base Sepolia only
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
// Execute transactions with session key (no biometric prompts)
|
|
211
|
+
await sessionManager.executeWithSession({
|
|
212
|
+
targetChain: 10004,
|
|
213
|
+
token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
|
|
214
|
+
recipient: '0x...',
|
|
215
|
+
amount: 1000000n,
|
|
216
|
+
}, session);
|
|
217
|
+
|
|
218
|
+
// Revoke anytime
|
|
219
|
+
await sessionManager.revokeSession(session);
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
### Session Key Cryptography (Low-Level)
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
import {
|
|
226
|
+
generateSecp256k1KeyPair,
|
|
227
|
+
computeSessionKeyHash,
|
|
228
|
+
deriveEncryptionKey,
|
|
229
|
+
encrypt,
|
|
230
|
+
decrypt,
|
|
231
|
+
} from '@veridex/sdk';
|
|
232
|
+
|
|
233
|
+
// Generate a session key pair
|
|
234
|
+
const keyPair = generateSecp256k1KeyPair();
|
|
235
|
+
console.log('Public key:', keyPair.publicKey);
|
|
236
|
+
|
|
237
|
+
// Compute on-chain key hash
|
|
238
|
+
const keyHash = computeSessionKeyHash(keyPair.publicKey);
|
|
239
|
+
|
|
240
|
+
// Encrypt private key (only passkey owner can decrypt)
|
|
241
|
+
const encryptionKey = await deriveEncryptionKey(credential.credentialId);
|
|
242
|
+
const encrypted = await encrypt(keyPair.privateKey, encryptionKey);
|
|
243
|
+
const decrypted = await decrypt(encrypted, encryptionKey);
|
|
128
244
|
```
|
|
129
245
|
|
|
130
246
|
### Cross-Chain Bridging
|
|
131
247
|
|
|
132
248
|
```typescript
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
249
|
+
const sdk = createSDK('base', { network: 'testnet' });
|
|
250
|
+
await sdk.passkey.register('user@example.com', 'My Wallet');
|
|
251
|
+
|
|
252
|
+
// Prepare bridge with fee estimation
|
|
253
|
+
const prepared = await sdk.prepareBridge({
|
|
254
|
+
sourceChain: 10004, // Base Sepolia
|
|
255
|
+
destinationChain: 10005, // Optimism Sepolia
|
|
256
|
+
token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
|
|
257
|
+
amount: 1000000n,
|
|
141
258
|
});
|
|
259
|
+
console.log('Bridge fees:', prepared.fees.formattedTotal);
|
|
260
|
+
|
|
261
|
+
// Execute with progress tracking
|
|
262
|
+
const result = await sdk.executeBridge(prepared, signer, (progress) => {
|
|
263
|
+
console.log(`Step ${progress.step}/${progress.totalSteps}: ${progress.message}`);
|
|
264
|
+
});
|
|
265
|
+
console.log('Source tx:', result.transactionHash);
|
|
266
|
+
console.log('VAA ready:', !!result.vaa);
|
|
267
|
+
|
|
268
|
+
// Or bridge gaslessly via relayer
|
|
269
|
+
const gaslessResult = await sdk.bridgeViaRelayer({
|
|
270
|
+
sourceChain: 10004,
|
|
271
|
+
destinationChain: 10005,
|
|
272
|
+
token: '0x036CbD53842c5426634e7929541eC2318f3dCF7e',
|
|
273
|
+
amount: 1000000n,
|
|
274
|
+
});
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### Balances
|
|
278
|
+
|
|
279
|
+
```typescript
|
|
280
|
+
const sdk = createSDK('base', { network: 'testnet' });
|
|
281
|
+
await sdk.passkey.register('user@example.com', 'My Wallet');
|
|
282
|
+
|
|
283
|
+
// Native token balance
|
|
284
|
+
const native = await sdk.getVaultNativeBalance();
|
|
285
|
+
console.log(`${native.token.symbol}: ${native.formatted}`);
|
|
286
|
+
|
|
287
|
+
// All token balances on current chain
|
|
288
|
+
const portfolio = await sdk.getVaultBalances();
|
|
289
|
+
for (const entry of portfolio.tokens) {
|
|
290
|
+
console.log(`${entry.token.symbol}: ${entry.formatted}`);
|
|
291
|
+
}
|
|
292
|
+
console.log('Total USD:', portfolio.totalUsdValue);
|
|
293
|
+
|
|
294
|
+
// Multi-chain balances
|
|
295
|
+
const multiChain = await sdk.getMultiChainBalances([10004, 10005, 10003]);
|
|
296
|
+
for (const chain of multiChain) {
|
|
297
|
+
console.log(`${chain.chainName}: ${chain.tokens.length} tokens`);
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
### Spending Limits
|
|
302
|
+
|
|
303
|
+
```typescript
|
|
304
|
+
import { ethers } from 'ethers';
|
|
305
|
+
|
|
306
|
+
// Check current on-chain spending limits
|
|
307
|
+
const limits = await sdk.getSpendingLimits();
|
|
308
|
+
console.log('Daily remaining:', limits.dailyRemaining);
|
|
309
|
+
|
|
310
|
+
// Check if a specific amount is allowed
|
|
311
|
+
const check = await sdk.checkSpendingLimit(ethers.parseEther('1.0'));
|
|
312
|
+
if (!check.allowed) {
|
|
313
|
+
console.log('Blocked:', check.message);
|
|
314
|
+
console.log('Suggestions:', check.suggestions);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
// Get formatted limits for UI display
|
|
318
|
+
const formatted = await sdk.getFormattedSpendingLimits();
|
|
319
|
+
console.log(`${formatted.dailyUsedPercentage}% of daily limit used`);
|
|
320
|
+
console.log(`Resets in: ${formatted.timeUntilReset}`);
|
|
321
|
+
|
|
322
|
+
// Update daily limit (requires passkey signature)
|
|
323
|
+
const prepared = await sdk.prepareSetDailyLimit(ethers.parseEther('5.0'));
|
|
324
|
+
await sdk.executeTransfer(prepared, signer);
|
|
142
325
|
```
|
|
143
326
|
|
|
144
327
|
## Chain Clients
|
|
@@ -146,11 +329,15 @@ await sdk.bridge({
|
|
|
146
329
|
Each chain has a dedicated client implementing the `ChainClient` interface:
|
|
147
330
|
|
|
148
331
|
```typescript
|
|
332
|
+
import { EVMClient } from '@veridex/sdk';
|
|
333
|
+
import { SolanaClient } from '@veridex/sdk';
|
|
334
|
+
import { AptosClient } from '@veridex/sdk';
|
|
335
|
+
import { SuiClient } from '@veridex/sdk';
|
|
336
|
+
import { StarknetClient } from '@veridex/sdk';
|
|
337
|
+
import { StacksClient } from '@veridex/sdk';
|
|
338
|
+
|
|
339
|
+
// Or use subpath imports
|
|
149
340
|
import { EVMClient } from '@veridex/sdk/chains/evm';
|
|
150
|
-
import { SolanaClient } from '@veridex/sdk/chains/solana';
|
|
151
|
-
import { AptosClient } from '@veridex/sdk/chains/aptos';
|
|
152
|
-
import { SuiClient } from '@veridex/sdk/chains/sui';
|
|
153
|
-
import { StarknetClient } from '@veridex/sdk/chains/starknet';
|
|
154
341
|
import { StacksClient } from '@veridex/sdk/chains/stacks';
|
|
155
342
|
```
|
|
156
343
|
|
|
@@ -158,55 +345,57 @@ All clients support:
|
|
|
158
345
|
- `buildTransferPayload()` — Build token transfer payloads
|
|
159
346
|
- `buildExecutePayload()` — Build arbitrary execution payloads
|
|
160
347
|
- `buildBridgePayload()` — Build cross-chain bridge payloads
|
|
161
|
-
- `dispatch()`
|
|
162
|
-
- `
|
|
163
|
-
- `
|
|
348
|
+
- `dispatch()` — Submit signed actions with a signer
|
|
349
|
+
- `computeVaultAddress()` — Derive deterministic vault address
|
|
350
|
+
- `vaultExists()` — Check if vault is deployed
|
|
351
|
+
- `createVault()` — Deploy a vault
|
|
352
|
+
- `getNonce()` — Get replay-protection nonce
|
|
353
|
+
- `getMessageFee()` — Get Wormhole message fee
|
|
164
354
|
|
|
165
355
|
### Stacks-Specific
|
|
166
356
|
|
|
167
357
|
Stacks has unique capabilities leveraged by the SDK:
|
|
168
358
|
|
|
169
359
|
```typescript
|
|
170
|
-
import { StacksClient } from '@veridex/sdk/chains/stacks';
|
|
171
360
|
import {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
361
|
+
StacksClient,
|
|
362
|
+
stacksCompressPublicKey,
|
|
363
|
+
stacksRsToCompactSignature,
|
|
364
|
+
stacksDerToCompactSignature,
|
|
365
|
+
stacksComputeKeyHash,
|
|
366
|
+
buildStxWithdrawalPostConditions,
|
|
367
|
+
isValidStacksPrincipal,
|
|
368
|
+
getStacksExplorerTxUrl,
|
|
369
|
+
} from '@veridex/sdk';
|
|
176
370
|
|
|
177
371
|
// Native secp256r1 verification (no ZK proofs needed)
|
|
178
372
|
// Native sponsored transactions (gasless built-in)
|
|
179
373
|
// Post-conditions for protocol-level spending safety
|
|
180
374
|
```
|
|
181
375
|
|
|
182
|
-
##
|
|
183
|
-
|
|
184
|
-
### Core Exports
|
|
185
|
-
|
|
186
|
-
| Export | Description |
|
|
187
|
-
|--------|-------------|
|
|
188
|
-
| `createSDK(chain, config?)` | Create SDK instance for a chain |
|
|
189
|
-
| `VeridexSDK` | Main SDK class |
|
|
190
|
-
| `PasskeyManager` | WebAuthn credential management |
|
|
191
|
-
| `WalletManager` | Deterministic vault address derivation |
|
|
192
|
-
| `SessionManager` | Session key lifecycle management |
|
|
193
|
-
|
|
194
|
-
### Utilities
|
|
376
|
+
## Factory Functions
|
|
195
377
|
|
|
196
378
|
```typescript
|
|
197
379
|
import {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
WORMHOLE_CHAIN_IDS,
|
|
204
|
-
TESTNET_CHAINS,
|
|
205
|
-
MAINNET_CHAINS,
|
|
380
|
+
createSDK, // Main factory — createSDK('base', { network: 'testnet' })
|
|
381
|
+
createHubSDK, // Shortcut for Base hub — createHubSDK()
|
|
382
|
+
createTestnetSDK, // Force testnet — createTestnetSDK('optimism')
|
|
383
|
+
createMainnetSDK, // Force mainnet — createMainnetSDK('base')
|
|
384
|
+
createSessionSDK, // Session-enabled — createSessionSDK('base')
|
|
206
385
|
} from '@veridex/sdk';
|
|
386
|
+
|
|
387
|
+
// Check supported chains
|
|
388
|
+
import { getSupportedChains, getChainConfig, isChainSupported } from '@veridex/sdk';
|
|
389
|
+
|
|
390
|
+
const chains = getSupportedChains('testnet');
|
|
391
|
+
console.log('Supported:', chains); // ['base', 'ethereum', 'optimism', ...]
|
|
392
|
+
|
|
393
|
+
const config = getChainConfig('base', 'testnet');
|
|
394
|
+
console.log('RPC:', config.rpcUrl);
|
|
395
|
+
console.log('Chain ID:', config.chainId);
|
|
207
396
|
```
|
|
208
397
|
|
|
209
|
-
|
|
398
|
+
## Types
|
|
210
399
|
|
|
211
400
|
```typescript
|
|
212
401
|
import type {
|
|
@@ -219,9 +408,21 @@ import type {
|
|
|
219
408
|
ExecuteParams,
|
|
220
409
|
BridgeParams,
|
|
221
410
|
SessionKey,
|
|
411
|
+
SessionConfig,
|
|
222
412
|
WebAuthnSignature,
|
|
413
|
+
PasskeyCredential,
|
|
223
414
|
DispatchResult,
|
|
224
415
|
VaultCreationResult,
|
|
416
|
+
PreparedTransfer,
|
|
417
|
+
TransferResult,
|
|
418
|
+
PreparedBridge,
|
|
419
|
+
BridgeResult,
|
|
420
|
+
PortfolioBalance,
|
|
421
|
+
TokenBalance,
|
|
422
|
+
SpendingLimits,
|
|
423
|
+
LimitCheckResult,
|
|
424
|
+
IdentityState,
|
|
425
|
+
UnifiedIdentity,
|
|
225
426
|
} from '@veridex/sdk';
|
|
226
427
|
```
|
|
227
428
|
|
|
@@ -235,6 +436,52 @@ import type {
|
|
|
235
436
|
- **Replay protection** — Nonce-based action deduplication on all chains
|
|
236
437
|
- **Post-conditions** — Protocol-level spending caps on Stacks
|
|
237
438
|
|
|
439
|
+
## Frontend Requirement
|
|
440
|
+
|
|
441
|
+
> **Important:** This SDK requires a **browser frontend** for passkey operations. WebAuthn (passkeys) can only be created and used in a secure browser context — `sdk.passkey.register()` and `sdk.passkey.authenticate()` trigger native OS biometric prompts (FaceID, TouchID, Windows Hello) that cannot run in Node.js or server-side environments.
|
|
442
|
+
|
|
443
|
+
**You need a frontend to:**
|
|
444
|
+
- **Register passkeys** — `sdk.passkey.register()` must be called from a user-initiated browser event (e.g., button click)
|
|
445
|
+
- **Authenticate** — `sdk.passkey.authenticate()` shows the platform passkey picker in the browser
|
|
446
|
+
- **Store credentials** — Passkey credentials are stored in the browser's platform authenticator (iCloud Keychain, Google Password Manager, etc.)
|
|
447
|
+
|
|
448
|
+
**What can run server-side:**
|
|
449
|
+
- Verifying transactions on-chain
|
|
450
|
+
- Querying balances (`sdk.getVaultBalances()`)
|
|
451
|
+
- Relayer API calls
|
|
452
|
+
- Session key operations (after initial passkey-based creation on the frontend)
|
|
453
|
+
|
|
454
|
+
**Minimal frontend example (React):**
|
|
455
|
+
|
|
456
|
+
```tsx
|
|
457
|
+
'use client';
|
|
458
|
+
import { createSDK } from '@veridex/sdk';
|
|
459
|
+
|
|
460
|
+
const sdk = createSDK('base', { network: 'testnet' });
|
|
461
|
+
|
|
462
|
+
export function PasskeyWallet() {
|
|
463
|
+
const handleCreate = async () => {
|
|
464
|
+
// Must be triggered by user interaction (button click)
|
|
465
|
+
const credential = await sdk.passkey.register('user@example.com', 'My Wallet');
|
|
466
|
+
console.log('Vault:', sdk.getVaultAddress());
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
const handleLogin = async () => {
|
|
470
|
+
const { credential } = await sdk.passkey.authenticate();
|
|
471
|
+
console.log('Authenticated:', credential.keyHash);
|
|
472
|
+
};
|
|
473
|
+
|
|
474
|
+
return (
|
|
475
|
+
<div>
|
|
476
|
+
<button onClick={handleCreate}>Create Wallet</button>
|
|
477
|
+
<button onClick={handleLogin}>Login</button>
|
|
478
|
+
</div>
|
|
479
|
+
);
|
|
480
|
+
}
|
|
481
|
+
```
|
|
482
|
+
|
|
483
|
+
For a complete frontend example, see the [test-app](https://github.com/Veridex-Protocol/demo/tree/main/test-app) or the [React integration guide](https://docs.veridex.network/integrations/react).
|
|
484
|
+
|
|
238
485
|
## Browser Support
|
|
239
486
|
|
|
240
487
|
WebAuthn requires HTTPS and a compatible browser:
|
|
@@ -244,13 +491,13 @@ WebAuthn requires HTTPS and a compatible browser:
|
|
|
244
491
|
| Chrome | 67+ |
|
|
245
492
|
| Firefox | 60+ |
|
|
246
493
|
| Safari | 14+ |
|
|
247
|
-
| Edge |
|
|
494
|
+
| Edge | 79+ |
|
|
248
495
|
|
|
249
496
|
## Related Packages
|
|
250
497
|
|
|
251
498
|
| Package | Description |
|
|
252
499
|
|---------|-------------|
|
|
253
|
-
| [`@veridex/agentic-payments`](https://www.npmjs.com/package/@veridex/agentic-payments) | Agent payment SDK — x402, UCP, ACP, AP2 |
|
|
500
|
+
| [`@veridex/agentic-payments`](https://www.npmjs.com/package/@veridex/agentic-payments) | Agent payment SDK — x402, UCP, ACP, AP2, ERC-8004 identity |
|
|
254
501
|
| `@veridex/relayer` | Transaction relayer for gasless execution |
|
|
255
502
|
| `@veridex/contracts` | Smart contracts (EVM, Solana, Aptos, Sui, Starknet, Stacks) |
|
|
256
503
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { P as PasskeyCredential, T as TransferParams, E as ExecuteParams, B as BridgeParams } from '../types-DakHNZIP.mjs';
|
|
2
|
+
|
|
3
|
+
type AuthenticateAndPrepareParams = {
|
|
4
|
+
credential: PasskeyCredential;
|
|
5
|
+
action?: TransferParams | ExecuteParams | BridgeParams;
|
|
6
|
+
/** Pre-encoded Hub action payload (hex string). If provided, `action` is ignored. */
|
|
7
|
+
actionPayload?: string;
|
|
8
|
+
targetChain: number;
|
|
9
|
+
};
|
|
10
|
+
type AuthenticateAndPrepareResult = {
|
|
11
|
+
serializedTx: Uint8Array;
|
|
12
|
+
queryProof: Uint8Array<ArrayBufferLike>;
|
|
13
|
+
estimatedLatency: number;
|
|
14
|
+
fallbackAvailable: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Client-first authentication preparation:
|
|
18
|
+
* - user signs locally (FaceID/TouchID)
|
|
19
|
+
* - client queries Wormhole Query Proxy for Guardian-attested nonce/state
|
|
20
|
+
* - client returns a ready-to-submit relayer payload (JSON bytes)
|
|
21
|
+
* - falls back to RPC nonce if Queries fails
|
|
22
|
+
*/
|
|
23
|
+
declare function authenticateAndPrepare(userParams: AuthenticateAndPrepareParams, apiKey: string): Promise<AuthenticateAndPrepareResult>;
|
|
24
|
+
|
|
25
|
+
export { type AuthenticateAndPrepareParams, type AuthenticateAndPrepareResult, authenticateAndPrepare };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { P as PasskeyCredential, T as TransferParams, E as ExecuteParams, B as BridgeParams } from '../types-DakHNZIP.js';
|
|
2
|
+
|
|
3
|
+
type AuthenticateAndPrepareParams = {
|
|
4
|
+
credential: PasskeyCredential;
|
|
5
|
+
action?: TransferParams | ExecuteParams | BridgeParams;
|
|
6
|
+
/** Pre-encoded Hub action payload (hex string). If provided, `action` is ignored. */
|
|
7
|
+
actionPayload?: string;
|
|
8
|
+
targetChain: number;
|
|
9
|
+
};
|
|
10
|
+
type AuthenticateAndPrepareResult = {
|
|
11
|
+
serializedTx: Uint8Array;
|
|
12
|
+
queryProof: Uint8Array<ArrayBufferLike>;
|
|
13
|
+
estimatedLatency: number;
|
|
14
|
+
fallbackAvailable: boolean;
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* Client-first authentication preparation:
|
|
18
|
+
* - user signs locally (FaceID/TouchID)
|
|
19
|
+
* - client queries Wormhole Query Proxy for Guardian-attested nonce/state
|
|
20
|
+
* - client returns a ready-to-submit relayer payload (JSON bytes)
|
|
21
|
+
* - falls back to RPC nonce if Queries fails
|
|
22
|
+
*/
|
|
23
|
+
declare function authenticateAndPrepare(userParams: AuthenticateAndPrepareParams, apiKey: string): Promise<AuthenticateAndPrepareResult>;
|
|
24
|
+
|
|
25
|
+
export { type AuthenticateAndPrepareParams, type AuthenticateAndPrepareResult, authenticateAndPrepare };
|