@dexterai/x402 4.0.0 → 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/README.md CHANGED
@@ -38,9 +38,11 @@ The closest familiar shape is an auth-and-capture card hold, with the hold enfor
38
38
  ## Install
39
39
 
40
40
  ```bash
41
- npm install @dexterai/x402
41
+ npm install @dexterai/x402 @dexterai/vault
42
42
  ```
43
43
 
44
+ `@dexterai/vault` is a **peer dependency** (`>=0.19`): the tab adapter and your app share ONE vault instance — the passkey signer it consumes (`signOperation`) is the same type your app builds, with no bridge shim. Install it alongside.
45
+
44
46
  One install is both sides: the buyer surface at `@dexterai/x402/tab`, the seller surface at `@dexterai/x402/tab/seller`.
45
47
 
46
48
  ## Open a tab and pay (buyer)
@@ -54,7 +56,7 @@ const vault = createSolanaVaultAdapter({
54
56
  connection, // your Solana Connection (any RPC)
55
57
  swigAddress, // the vault's Swig state account, from enrollment
56
58
  vaultPda, // the vault's gate PDA, from enrollment
57
- passkeySigner, // browser: WebAuthnAssertion; server agent: passkeySignerFromP256Keypair(kp)
59
+ passkeySigner, // signOperation signer — browser: vault's DexterApiBrowserPasskeySigner; server agent: passkeySignerFromP256Keypair(kp)
58
60
  feePayer, // lamport fee payer (a Signer)
59
61
  });
60
62
  ```
@@ -144,7 +146,7 @@ The full threat model and trust assumptions live in the program's [`SECURITY.md`
144
146
 
145
147
  When a partner's app opens a tab for a user, the approval runs on one Dexter-hosted consent screen, deep-linked from the partner's app. The user sees the counterparty, the cap, and the expiry, taps their passkey once, and control returns to the app. The partner builds no approval UI and never handles a passkey.
146
148
 
147
- The screen is hosted by Dexter for a structural reason, not a stylistic one: the vault's passkey can only sign on Dexter's own origin, so a user cannot be phished into approving on a look-alike page. The safety is a property of where the key will sign. Flow and routing: [docs.dexter.cash/tabs](https://docs.dexter.cash). **[TODO: confirm final docs path once #5 lands.]**
149
+ The screen is hosted by Dexter for a structural reason, not a stylistic one: the vault's passkey can only sign on Dexter's own origin, so a user cannot be phished into approving on a look-alike page. The safety is a property of where the key will sign. Flow and routing: [docs.dexter.cash](https://docs.dexter.cash).
148
150
 
149
151
  ---
150
152
 
@@ -310,6 +312,15 @@ State auto-persists and resumes with `resumeBatchChannel({ wallet, network, salt
310
312
 
311
313
  `bazaarExtension()` plus `declareDiscoveryExtension(config)` attach a spec-compliant `extensions.bazaar` block to a route's 402; extensions are opt-in and failure-isolated, so the payment path is never affected. `sponsoredAccess` injects `_x402_sponsored` into responses; read it with `getSponsoredRecommendations(response)`. Campaign creation is x402-gated at `x402ads.io`.
312
314
 
315
+ ### Migrating to 5.0.0 (breaking)
316
+
317
+ Two changes, both about packaging and the passkey signer — the payment path itself is unchanged.
318
+
319
+ 1. **`@dexterai/vault` is now a peer dependency** (`>=0.19`), not bundled. The tab adapter and your app share ONE vault instance, so there are no duplicate copies and no `instanceof`/type mismatches across packages. Install it alongside: `npm install @dexterai/x402 @dexterai/vault`.
320
+ 2. **The passkey signer contract is `signOperation(operationMessage)`**, replacing the old `sign(challenge)`. The adapter now hands the signer the RAW operation message and the signer hashes it internally (`challenge = sha256(op)`, the on-chain `webauthn.rs` law). If you wrote a custom signer against `sign(challenge)`, rename the method to `signOperation` and delete your pre-hash — pass the message straight through. Vault's `DexterApiBrowserPasskeySigner` (browser) and this package's `passkeySignerFromP256Keypair` (node/agent) already conform.
321
+
322
+ To pin the old surface, stay on `@dexterai/x402@^4`.
323
+
313
324
  ### Removed in v4.0.0 (migration)
314
325
 
315
326
  The v1-era helpers were removed in `4.0.0`. The payment engine is unchanged — the canonical entrypoints have done their jobs since 3.x:
@@ -334,7 +345,7 @@ The v1-era helpers were removed in `4.0.0`. The payment engine is unchanged —
334
345
  npm run build # ESM + CJS
335
346
  npm run dev # Watch mode
336
347
  npm run typecheck
337
- npm test # 359 vitest tests
348
+ npm test # 364 vitest tests
338
349
  ```
339
350
 
340
351
  ## License
@@ -0,0 +1,385 @@
1
+ Pricing
2
+ =======
3
+
4
+ ###
5
+
6
+ Text tokens
7
+
8
+ Prices per 1M tokens.
9
+
10
+ Batch
11
+
12
+ |Model|Input|Cached input|Output|
13
+ |---|---|---|---|
14
+ |gpt-5.2|$0.875|$0.0875|$7.00|
15
+ |gpt-5.1|$0.625|$0.0625|$5.00|
16
+ |gpt-5|$0.625|$0.0625|$5.00|
17
+ |gpt-5-mini|$0.125|$0.0125|$1.00|
18
+ |gpt-5-nano|$0.025|$0.0025|$0.20|
19
+ |gpt-5.2-pro|$10.50|-|$84.00|
20
+ |gpt-5-pro|$7.50|-|$60.00|
21
+ |gpt-4.1|$1.00|-|$4.00|
22
+ |gpt-4.1-mini|$0.20|-|$0.80|
23
+ |gpt-4.1-nano|$0.05|-|$0.20|
24
+ |gpt-4o|$1.25|-|$5.00|
25
+ |gpt-4o-2024-05-13|$2.50|-|$7.50|
26
+ |gpt-4o-mini|$0.075|-|$0.30|
27
+ |o1|$7.50|-|$30.00|
28
+ |o1-pro|$75.00|-|$300.00|
29
+ |o3-pro|$10.00|-|$40.00|
30
+ |o3|$1.00|-|$4.00|
31
+ |o3-deep-research|$5.00|-|$20.00|
32
+ |o4-mini|$0.55|-|$2.20|
33
+ |o4-mini-deep-research|$1.00|-|$4.00|
34
+ |o3-mini|$0.55|-|$2.20|
35
+ |o1-mini|$0.55|-|$2.20|
36
+ |computer-use-preview|$1.50|-|$6.00|
37
+
38
+ Flex
39
+
40
+ |Model|Input|Cached input|Output|
41
+ |---|---|---|---|
42
+ |gpt-5.2|$0.875|$0.0875|$7.00|
43
+ |gpt-5.1|$0.625|$0.0625|$5.00|
44
+ |gpt-5|$0.625|$0.0625|$5.00|
45
+ |gpt-5-mini|$0.125|$0.0125|$1.00|
46
+ |gpt-5-nano|$0.025|$0.0025|$0.20|
47
+ |o3|$1.00|$0.25|$4.00|
48
+ |o4-mini|$0.55|$0.138|$2.20|
49
+
50
+ Standard
51
+
52
+ |Model|Input|Cached input|Output|
53
+ |---|---|---|---|
54
+ |gpt-5.2|$1.75|$0.175|$14.00|
55
+ |gpt-5.1|$1.25|$0.125|$10.00|
56
+ |gpt-5|$1.25|$0.125|$10.00|
57
+ |gpt-5-mini|$0.25|$0.025|$2.00|
58
+ |gpt-5-nano|$0.05|$0.005|$0.40|
59
+ |gpt-5.2-chat-latest|$1.75|$0.175|$14.00|
60
+ |gpt-5.1-chat-latest|$1.25|$0.125|$10.00|
61
+ |gpt-5-chat-latest|$1.25|$0.125|$10.00|
62
+ |gpt-5.1-codex-max|$1.25|$0.125|$10.00|
63
+ |gpt-5.1-codex|$1.25|$0.125|$10.00|
64
+ |gpt-5-codex|$1.25|$0.125|$10.00|
65
+ |gpt-5.2-pro|$21.00|-|$168.00|
66
+ |gpt-5-pro|$15.00|-|$120.00|
67
+ |gpt-4.1|$2.00|$0.50|$8.00|
68
+ |gpt-4.1-mini|$0.40|$0.10|$1.60|
69
+ |gpt-4.1-nano|$0.10|$0.025|$0.40|
70
+ |gpt-4o|$2.50|$1.25|$10.00|
71
+ |gpt-4o-2024-05-13|$5.00|-|$15.00|
72
+ |gpt-4o-mini|$0.15|$0.075|$0.60|
73
+ |gpt-realtime|$4.00|$0.40|$16.00|
74
+ |gpt-realtime-mini|$0.60|$0.06|$2.40|
75
+ |gpt-4o-realtime-preview|$5.00|$2.50|$20.00|
76
+ |gpt-4o-mini-realtime-preview|$0.60|$0.30|$2.40|
77
+ |gpt-audio|$2.50|-|$10.00|
78
+ |gpt-audio-mini|$0.60|-|$2.40|
79
+ |gpt-4o-audio-preview|$2.50|-|$10.00|
80
+ |gpt-4o-mini-audio-preview|$0.15|-|$0.60|
81
+ |o1|$15.00|$7.50|$60.00|
82
+ |o1-pro|$150.00|-|$600.00|
83
+ |o3-pro|$20.00|-|$80.00|
84
+ |o3|$2.00|$0.50|$8.00|
85
+ |o3-deep-research|$10.00|$2.50|$40.00|
86
+ |o4-mini|$1.10|$0.275|$4.40|
87
+ |o4-mini-deep-research|$2.00|$0.50|$8.00|
88
+ |o3-mini|$1.10|$0.55|$4.40|
89
+ |o1-mini|$1.10|$0.55|$4.40|
90
+ |gpt-5.1-codex-mini|$0.25|$0.025|$2.00|
91
+ |codex-mini-latest|$1.50|$0.375|$6.00|
92
+ |gpt-5-search-api|$1.25|$0.125|$10.00|
93
+ |gpt-4o-mini-search-preview|$0.15|-|$0.60|
94
+ |gpt-4o-search-preview|$2.50|-|$10.00|
95
+ |computer-use-preview|$3.00|-|$12.00|
96
+ |gpt-image-1.5|$5.00|$1.25|$10.00|
97
+ |chatgpt-image-latest|$5.00|$1.25|$10.00|
98
+ |gpt-image-1|$5.00|$1.25|-|
99
+ |gpt-image-1-mini|$2.00|$0.20|-|
100
+
101
+ Priority
102
+
103
+ |Model|Input|Cached input|Output|
104
+ |---|---|---|---|
105
+ |gpt-5.2|$3.50|$0.35|$28.00|
106
+ |gpt-5.1|$2.50|$0.25|$20.00|
107
+ |gpt-5|$2.50|$0.25|$20.00|
108
+ |gpt-5-mini|$0.45|$0.045|$3.60|
109
+ |gpt-5.1-codex-max|$2.50|$0.25|$20.00|
110
+ |gpt-5.1-codex|$2.50|$0.25|$20.00|
111
+ |gpt-5-codex|$2.50|$0.25|$20.00|
112
+ |gpt-4.1|$3.50|$0.875|$14.00|
113
+ |gpt-4.1-mini|$0.70|$0.175|$2.80|
114
+ |gpt-4.1-nano|$0.20|$0.05|$0.80|
115
+ |gpt-4o|$4.25|$2.125|$17.00|
116
+ |gpt-4o-2024-05-13|$8.75|-|$26.25|
117
+ |gpt-4o-mini|$0.25|$0.125|$1.00|
118
+ |o3|$3.50|$0.875|$14.00|
119
+ |o4-mini|$2.00|$0.50|$8.00|
120
+
121
+ For faster processing of API requests, try the [priority processing service tier](https://platform.openai.com/docs/guides/priority-processing). For lower prices with higher latency, try the [flex processing tier](https://platform.openai.com/docs/guides/flex-processing).
122
+
123
+ Large numbers of API requests which are not time-sensitive can use the [Batch API](https://platform.openai.com/docs/guides/batch) for additional savings as well.
124
+
125
+ While reasoning tokens are not visible via the API, they still occupy space in the model's context window and are billed as output tokens.
126
+
127
+ For gpt-image-1.5, Text output tokens include model reasoning tokens.
128
+
129
+
130
+
131
+ ###
132
+
133
+ Image tokens
134
+
135
+ Prices per 1M tokens.
136
+
137
+ |Model|Input|Cached Input|Output|
138
+ |---|---|---|---|
139
+ |gpt-image-1.5|$8.00|$2.00|$32.00|
140
+ |chatgpt-image-latest|$8.00|$2.00|$32.00|
141
+ |gpt-image-1|$10.00|$2.50|$40.00|
142
+ |gpt-image-1-mini|$2.50|$0.25|$8.00|
143
+ |gpt-realtime|$5.00|$0.50|-|
144
+ |gpt-realtime-mini|$0.80|$0.08|-|
145
+
146
+
147
+
148
+ ###
149
+
150
+ Audio tokens
151
+
152
+ Prices per 1M tokens.
153
+
154
+ |Model|Input|Cached Input|Output|
155
+ |---|---|---|---|
156
+ |gpt-realtime|$32.00|$0.40|$64.00|
157
+ |gpt-realtime-mini|$10.00|$0.30|$20.00|
158
+ |gpt-4o-realtime-preview|$40.00|$2.50|$80.00|
159
+ |gpt-4o-mini-realtime-preview|$10.00|$0.30|$20.00|
160
+ |gpt-audio|$32.00|-|$64.00|
161
+ |gpt-audio-mini|$10.00|-|$20.00|
162
+ |gpt-4o-audio-preview|$40.00|-|$80.00|
163
+ |gpt-4o-mini-audio-preview|$10.00|-|$20.00|
164
+
165
+
166
+
167
+ ###
168
+
169
+ Video
170
+
171
+ Prices per second.
172
+
173
+ |Model|Size: Output resolution|Price per second|
174
+ |---|---|---|
175
+ |sora-2|Portrait: 720x1280 Landscape: 1280x720|$0.10|
176
+ |sora-2-pro|Portrait: 720x1280 Landscape: 1280x720|$0.30|
177
+ |sora-2-pro|Portrait: 1024x1792 Landscape: 1792x1024|$0.50|
178
+
179
+
180
+
181
+ ###
182
+
183
+ Fine-tuning
184
+
185
+ Prices per 1M tokens.
186
+
187
+ Batch
188
+
189
+ |Model|Training|Input|Cached Input|Output|
190
+ |---|---|---|---|---|
191
+ |o4-mini-2025-04-16|$100.00 / hour|$2.00|$0.50|$8.00|
192
+ |o4-mini-2025-04-16with data sharing|$100.00 / hour|$1.00|$0.25|$4.00|
193
+ |gpt-4.1-2025-04-14|$25.00|$1.50|$0.50|$6.00|
194
+ |gpt-4.1-mini-2025-04-14|$5.00|$0.40|$0.10|$1.60|
195
+ |gpt-4.1-nano-2025-04-14|$1.50|$0.10|$0.025|$0.40|
196
+ |gpt-4o-2024-08-06|$25.00|$2.225|$0.90|$12.50|
197
+ |gpt-4o-mini-2024-07-18|$3.00|$0.15|$0.075|$0.60|
198
+ |gpt-3.5-turbo|$8.00|$1.50|-|$3.00|
199
+ |davinci-002|$6.00|$6.00|-|$6.00|
200
+ |babbage-002|$0.40|$0.80|-|$0.90|
201
+
202
+ Standard
203
+
204
+ |Model|Training|Input|Cached Input|Output|
205
+ |---|---|---|---|---|
206
+ |o4-mini-2025-04-16|$100.00 / hour|$4.00|$1.00|$16.00|
207
+ |o4-mini-2025-04-16with data sharing|$100.00 / hour|$2.00|$0.50|$8.00|
208
+ |gpt-4.1-2025-04-14|$25.00|$3.00|$0.75|$12.00|
209
+ |gpt-4.1-mini-2025-04-14|$5.00|$0.80|$0.20|$3.20|
210
+ |gpt-4.1-nano-2025-04-14|$1.50|$0.20|$0.05|$0.80|
211
+ |gpt-4o-2024-08-06|$25.00|$3.75|$1.875|$15.00|
212
+ |gpt-4o-mini-2024-07-18|$3.00|$0.30|$0.15|$1.20|
213
+ |gpt-3.5-turbo|$8.00|$3.00|-|$6.00|
214
+ |davinci-002|$6.00|$12.00|-|$12.00|
215
+ |babbage-002|$0.40|$1.60|-|$1.60|
216
+
217
+ Tokens used for model grading in reinforcement fine-tuning are billed at that model's per-token rate. Inference discounts are available if you enable data sharing when creating the fine-tune job. [Learn more](https://help.openai.com/en/articles/10306912-sharing-feedback-evaluation-and-fine-tuning-data-and-api-inputs-and-outputs-with-openai#h_c93188c569).
218
+
219
+
220
+
221
+ ###
222
+
223
+ Built-in tools
224
+
225
+ |Tool|Cost|
226
+ |---|---|
227
+ |Code Interpreter|1 GB (default): $0.03 / container4 GB: $0.12 / container16 GB: $0.48 / container64 GB: $1.92 / container|
228
+ |File search storage|$0.10 / GB per day (1GB free)|
229
+ |File search tool callResponses API only|$2.50 / 1k calls|
230
+ |Web search (all models)[1]|$10.00 / 1k calls + search content tokens billed at model rates|
231
+ |Web search preview (reasoning models, including gpt-5, o-series)|$10.00 / 1k calls + search content tokens billed at model rates|
232
+ |Web search preview (non-reasoning models)|$25.00 / 1k calls + search content tokens are free|
233
+
234
+ The tokens used for built-in tools are billed at the chosen model's per-token rates. GB refers to binary gigabytes of storage (also known as gibibyte), where 1GB is 2^30 bytes.
235
+
236
+ **Web search:** There are two components that contribute to the cost of using the web search tool: (1) tool calls and (2) search content tokens. Tool calls are billed per 1000 calls, according to the tool version and model type. The billing dashboard and invoices will report these line items as “web search tool calls.”
237
+
238
+ Search content tokens are tokens retrieved from the search index and fed to the model alongside your prompt to generate an answer. These are billed at the model’s input token rate, unless otherwise specified.
239
+
240
+ \[1\] For `gpt-4o-mini` and `gpt-4.1-mini` with the web search non-preview tool, search content tokens are charged as a fixed block of 8,000 input tokens per call.
241
+
242
+
243
+
244
+ ###
245
+
246
+ AgentKit
247
+
248
+ Build, deploy, and optimize production-grade agents with Agent Builder, ChatKit, and Evals. You pay only for the compute and data you actually use.
249
+
250
+ |Usage meter|Free tier (per account, per month)|Price beyond free tier|
251
+ |---|---|---|
252
+ |Storage for ChatKit File / Image Uploads|1 GB|$0.10 / GB-day|
253
+
254
+
255
+
256
+ ###
257
+
258
+ Transcription and speech generation
259
+
260
+ Prices per 1M tokens.
261
+
262
+ #### Text tokens
263
+
264
+ |Model|Input|Output|Estimated cost|
265
+ |---|---|---|---|
266
+ |gpt-4o-mini-tts|$0.60|-|$0.015 / minute|
267
+ |gpt-4o-transcribe|$2.50|$10.00|$0.006 / minute|
268
+ |gpt-4o-transcribe-diarize|$2.50|$10.00|$0.006 / minute|
269
+ |gpt-4o-mini-transcribe|$1.25|$5.00|$0.003 / minute|
270
+
271
+ #### Audio tokens
272
+
273
+ |Model|Input|Output|Estimated cost|
274
+ |---|---|---|---|
275
+ |gpt-4o-mini-tts|-|$12.00|$0.015 / minute|
276
+ |gpt-4o-transcribe|$6.00|-|$0.006 / minute|
277
+ |gpt-4o-transcribe-diarize|$6.00|-|$0.006 / minute|
278
+ |gpt-4o-mini-transcribe|$3.00|-|$0.003 / minute|
279
+
280
+ #### Other models
281
+
282
+ |Model|Use case|Cost|
283
+ |---|---|---|
284
+ |Whisper|Transcription|$0.006 / minute|
285
+ |TTS|Speech generation|$15.00 / 1M characters|
286
+ |TTS HD|Speech generation|$30.00 / 1M characters|
287
+
288
+
289
+
290
+ ###
291
+
292
+ Image generation
293
+
294
+ Prices per image.
295
+
296
+ |Model|Quality|1024 x 1024|1024 x 1536|1536 x 1024|
297
+ |---|---|---|---|---|
298
+ |GPT Image 1.5|Low|$0.009|$0.013|$0.013|
299
+ |Medium|$0.034|$0.05|$0.05|
300
+ |High|$0.133|$0.2|$0.2|
301
+ |GPT Image Latest|Low|$0.009|$0.013|$0.013|
302
+ |Medium|$0.034|$0.05|$0.05|
303
+ |High|$0.133|$0.2|$0.2|
304
+ |GPT Image 1|Low|$0.011|$0.016|$0.016|
305
+ |Medium|$0.042|$0.063|$0.063|
306
+ |High|$0.167|$0.25|$0.25|
307
+ |GPT Image 1 Mini|Low|$0.005|$0.006|$0.006|
308
+ |Medium|$0.011|$0.015|$0.015|
309
+ |High|$0.036|$0.052|$0.052|
310
+ ||
311
+ ||
312
+ |DALL·E 3|Standard|$0.04|$0.08|$0.08|
313
+ |HD|$0.08|$0.12|$0.12|
314
+ ||
315
+ ||
316
+ |DALL·E 2|Standard|$0.016|$0.018|$0.02|
317
+
318
+
319
+
320
+ ###
321
+
322
+ Embeddings
323
+
324
+ Prices per 1M tokens.
325
+
326
+ |Model|Cost|Batch cost|
327
+ |---|---|---|
328
+ |text-embedding-3-small|$0.02|$0.01|
329
+ |text-embedding-3-large|$0.13|$0.065|
330
+ |text-embedding-ada-002|$0.10|$0.05|
331
+
332
+
333
+
334
+ ### Moderation
335
+
336
+ Our `omni-moderation` models are made available free of charge ✌️
337
+
338
+
339
+
340
+ ###
341
+
342
+ Legacy models
343
+
344
+ Prices per 1M tokens.
345
+
346
+ Batch
347
+
348
+ |Model|Input|Output|
349
+ |---|---|---|
350
+ |gpt-4-turbo-2024-04-09|$5.00|$15.00|
351
+ |gpt-4-0125-preview|$5.00|$15.00|
352
+ |gpt-4-1106-preview|$5.00|$15.00|
353
+ |gpt-4-1106-vision-preview|$5.00|$15.00|
354
+ |gpt-4-0613|$15.00|$30.00|
355
+ |gpt-4-0314|$15.00|$30.00|
356
+ |gpt-4-32k|$30.00|$60.00|
357
+ |gpt-3.5-turbo-0125|$0.25|$0.75|
358
+ |gpt-3.5-turbo-1106|$1.00|$2.00|
359
+ |gpt-3.5-turbo-0613|$1.50|$2.00|
360
+ |gpt-3.5-0301|$1.50|$2.00|
361
+ |gpt-3.5-turbo-16k-0613|$1.50|$2.00|
362
+ |davinci-002|$1.00|$1.00|
363
+ |babbage-002|$0.20|$0.20|
364
+
365
+ Standard
366
+
367
+ |Model|Input|Output|
368
+ |---|---|---|
369
+ |chatgpt-4o-latest|$5.00|$15.00|
370
+ |gpt-4-turbo-2024-04-09|$10.00|$30.00|
371
+ |gpt-4-0125-preview|$10.00|$30.00|
372
+ |gpt-4-1106-preview|$10.00|$30.00|
373
+ |gpt-4-1106-vision-preview|$10.00|$30.00|
374
+ |gpt-4-0613|$30.00|$60.00|
375
+ |gpt-4-0314|$30.00|$60.00|
376
+ |gpt-4-32k|$60.00|$120.00|
377
+ |gpt-3.5-turbo|$0.50|$1.50|
378
+ |gpt-3.5-turbo-0125|$0.50|$1.50|
379
+ |gpt-3.5-turbo-1106|$1.00|$2.00|
380
+ |gpt-3.5-turbo-0613|$1.50|$2.00|
381
+ |gpt-3.5-0301|$1.50|$2.00|
382
+ |gpt-3.5-turbo-instruct|$1.50|$2.00|
383
+ |gpt-3.5-turbo-16k-0613|$3.00|$4.00|
384
+ |davinci-002|$2.00|$2.00|
385
+ |babbage-002|$0.40|$0.40|
@@ -1 +1 @@
1
- "use strict";var Y=Object.create;var h=Object.defineProperty;var z=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var Z=Object.getPrototypeOf,Q=Object.prototype.hasOwnProperty;var ee=(e,t)=>{for(var n in t)h(e,n,{get:t[n],enumerable:!0})},U=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of j(t))!Q.call(e,s)&&s!==n&&h(e,s,{get:()=>t[s],enumerable:!(i=z(t,s))||i.enumerable});return e};var I=(e,t,n)=>(n=e!=null?Y(Z(e)):{},U(t||!e||!e.__esModule?h(n,"default",{value:e,enumerable:!0}):n,e)),te=e=>U(h({},"__esModule",{value:!0}),e);var ge={};ee(ge,{buildAdapterRegisterInstruction:()=>q,createSolanaVaultAdapter:()=>ue,deriveChannelId:()=>F,passkeySignerFromP256Keypair:()=>le});module.exports=te(ge);var p=require("@solana/web3.js"),$=require("@solana/spl-token");var ne="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",ie="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",se="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var P="eip155:8453",b="eip155:84532",E="eip155:42161",K="eip155:137",v="eip155:10",w="eip155:43114",O="eip155:56",R="eip155:1187947933",C="eip155:324705682",T="eip155:1";var k="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var re="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",oe="0x55d398326f99059fF775485246999027B3197955",B="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",he={[O]:B,[P]:re,[b]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[E]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[K]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[v]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[w]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[R]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[C]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[T]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Se={[oe]:{symbol:"USDT",decimals:18},[B]:{symbol:"USDC",decimals:18}};var fe={[O]:56,[P]:8453,[b]:84532,[E]:42161,[K]:137,[v]:10,[w]:43114,[R]:1187947933,[C]:324705682,[T]:1},xe={[ne]:"https://api.dexter.cash/api/solana/rpc",[ie]:"https://api.devnet.solana.com",[se]:"https://api.testnet.solana.com"},Pe={[O]:"https://api.dexter.cash/api/evm/bsc/rpc",[P]:"https://api.dexter.cash/api/base/rpc",[b]:"https://sepolia.base.org",[E]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[K]:"https://api.dexter.cash/api/evm/polygon/rpc",[v]:"https://api.dexter.cash/api/evm/optimism/rpc",[w]:"https://api.dexter.cash/api/evm/avalanche/rpc",[R]:"https://skale-base.skalenodes.com/v1/base",[C]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[T]:"https://eth.llamarpc.com"};var c=require("@dexterai/vault/instructions"),S=require("@dexterai/vault/precompile"),m=require("@dexterai/vault/constants");var o=require("@dexterai/vault/messages");var _=I(require("tweetnacl"),1);var W=require("@noble/hashes/sha256");function M(){let e=_.default.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function V(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function L(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let i=BigInt(t.cumulativeAmount),s=BigInt(e.scope.maxAmountAtomic);if(i>s)throw new Error(`voucher cumulative ${i} exceeds session cap ${s}`);let r=Math.floor(Date.now()/1e3);if(r>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${r}`);let l=(0,o.voucherPayloadMessage)({channelId:n,cumulativeAmount:i,sequenceNumber:t.sequenceNumber}),a=_.default.sign.detached(l,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:a}}function f(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function F(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),i=W.sha256.create();return i.update(e.vaultPda.toBytes()),i.update(n),i.update(t),i.digest()}var d=require("@dexterai/vault/session");var J=require("@noble/curves/p256"),g=require("@noble/hashes/sha256"),H="dexter.cash";function ae(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function ce(e,t=`https://${H}`){let i={type:"webauthn.get",challenge:ae(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(i))}function pe(e=1){let t=(0,g.sha256)(new TextEncoder().encode(H)),n=new Uint8Array(37);return n.set(t,0),n[32]=5,new DataView(n.buffer).setUint32(33,e,!1),n}function G(e,t){let n=(0,g.sha256)(t),i=ce(n),s=pe(1),r=new Uint8Array(s.length+32);r.set(s,0),r.set((0,g.sha256)(i),s.length);let l=(0,g.sha256)(r),u=J.p256.sign(l,e.privateKey,{lowS:!0}).toCompactRawBytes();return{clientDataJSON:i,authenticatorData:s,precompileMessage:r,signature:u}}function le(e){return{publicKey:e.publicKey,signOperation:async t=>G(e,t)}}function q(e){let t=(0,c.deriveSwigWalletAddress)(e.swigAddress),n=(0,$.getAssociatedTokenAddressSync)(new p.PublicKey(k),t,!0);return(0,c.buildRegisterSessionKeyInstruction)({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:n,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var N=class{network="solana:mainnet";swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new p.PublicKey(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"}}async authorizeSession(t){let n=new p.PublicKey(t.allowedCounterparty),i=f(t.revolvingCapacityAtomic??t.maxAmountAtomic),s=M(),r=ye(),l=(0,o.sessionRegisterMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:s.publicKey,maxAmount:f(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r}),a=await this.passkey.signOperation(l),u=(0,S.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,a.signature,a.precompileMessage),A=(0,d.sessionPdasOf)(await(0,d.fetchVaultSessionAccounts)(this.connection,this.vaultPdaKey)),x=q({vaultPda:this.vaultPdaKey,swigAddress:new p.PublicKey(this.swigAddress),sessionPubkey:s.publicKey,maxAmount:f(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r,clientDataJSON:a.clientDataJSON,authenticatorData:a.authenticatorData,payer:this.feePayer.publicKey,siblingSessionPdas:A}),y=new p.Transaction().add(u,x);y.feePayer=this.feePayer.publicKey;let{blockhash:D}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);y.recentBlockhash=D,y.sign(this.feePayer);let X=await this.connection.sendRawTransaction(y.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:X,blockhash:D,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment),await(0,d.waitForSession)(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:s.publicKey,timeoutMs:2e4}),V(s,t,l)}async signWithSession(t,n){let i=await me(n.channelId);return L(t,n,i)}async signOpenTab(t,n){return t.registration}async signCloseTab(t,n,i){let s=(0,o.sessionRevokeMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:t.publicKey}),r=await this.passkey.signOperation(s),l=(0,S.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,r.signature,r.precompileMessage),a=(0,c.buildRevokeSessionKeyInstruction)({vaultPda:this.vaultPdaKey,allowedCounterparty:new p.PublicKey(t.scope.allowedCounterparty),clientDataJSON:r.clientDataJSON,authenticatorData:r.authenticatorData}),u=new p.Transaction().add(l,a);u.feePayer=this.feePayer.publicKey;let{blockhash:A,lastValidBlockHeight:x}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);u.recentBlockhash=A,u.sign(this.feePayer);let y=await this.connection.sendRawTransaction(u.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:y,blockhash:A,lastValidBlockHeight:x},this.confirmOptions.commitment),s}};function ue(e){return new N(e)}function ye(){return Math.floor(Math.random()*4294967295)>>>0}async function me(e){if(/^[0-9a-f]{64}$/i.test(e))return de(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function de(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}0&&(module.exports={buildAdapterRegisterInstruction,createSolanaVaultAdapter,deriveChannelId,passkeySignerFromP256Keypair});
1
+ "use strict";var ee=Object.create;var x=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ne=Object.getOwnPropertyNames;var ie=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty;var se=(e,t)=>{for(var n in t)x(e,n,{get:t[n],enumerable:!0})},M=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ne(t))!re.call(e,r)&&r!==n&&x(e,r,{get:()=>t[r],enumerable:!(i=te(t,r))||i.enumerable});return e};var V=(e,t,n)=>(n=e!=null?ee(ie(e)):{},M(t||!e||!e.__esModule?x(n,"default",{value:e,enumerable:!0}):n,e)),oe=e=>M(x({},"__esModule",{value:!0}),e);var fe={};se(fe,{buildAdapterRegisterInstruction:()=>Z,createSolanaVaultAdapter:()=>Ae,deriveChannelId:()=>$,passkeySignerFromP256Keypair:()=>Y});module.exports=oe(fe);var c=require("@solana/web3.js"),j=require("@solana/spl-token");var ae="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",ce="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",pe="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var K="eip155:8453",v="eip155:84532",w="eip155:42161",C="eip155:137",R="eip155:10",O="eip155:43114",U="eip155:56",T="eip155:1187947933",_="eip155:324705682",N="eip155:1";var L="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var ue="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",le="0x55d398326f99059fF775485246999027B3197955",W="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",be={[U]:W,[K]:ue,[v]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[w]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[C]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[R]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[O]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[T]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[_]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[N]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},Ee={[le]:{symbol:"USDT",decimals:18},[W]:{symbol:"USDC",decimals:18}};var Ke={[U]:56,[K]:8453,[v]:84532,[w]:42161,[C]:137,[R]:10,[O]:43114,[T]:1187947933,[_]:324705682,[N]:1},ve={[ae]:"https://api.dexter.cash/api/solana/rpc",[ce]:"https://api.devnet.solana.com",[pe]:"https://api.testnet.solana.com"},we={[U]:"https://api.dexter.cash/api/evm/bsc/rpc",[K]:"https://api.dexter.cash/api/base/rpc",[v]:"https://sepolia.base.org",[w]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[C]:"https://api.dexter.cash/api/evm/polygon/rpc",[R]:"https://api.dexter.cash/api/evm/optimism/rpc",[O]:"https://api.dexter.cash/api/evm/avalanche/rpc",[T]:"https://skale-base.skalenodes.com/v1/base",[_]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[N]:"https://eth.llamarpc.com"};var a=require("@dexterai/vault/instructions"),f=require("@dexterai/vault/precompile"),m=require("@dexterai/vault/constants");var s=require("@dexterai/vault/messages");var D=V(require("tweetnacl"),1);var G=require("@noble/hashes/sha256");function F(){let e=D.default.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function J(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function H(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let i=BigInt(t.cumulativeAmount),r=BigInt(e.scope.maxAmountAtomic);if(i>r)throw new Error(`voucher cumulative ${i} exceeds session cap ${r}`);let o=Math.floor(Date.now()/1e3);if(o>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${o}`);let p=(0,s.voucherPayloadMessage)({channelId:n,cumulativeAmount:i,sequenceNumber:t.sequenceNumber}),u=D.default.sign.detached(p,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:u}}function P(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function $(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),i=G.sha256.create();return i.update(e.vaultPda.toBytes()),i.update(n),i.update(t),i.digest()}var d=require("@dexterai/vault/session"),I=require("@noble/hashes/sha256");var q=require("@noble/curves/p256"),g=require("@noble/hashes/sha256"),X="dexter.cash";function ye(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function me(e,t=`https://${X}`){let i={type:"webauthn.get",challenge:ye(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(i))}function de(e=1){let t=(0,g.sha256)(new TextEncoder().encode(X)),n=new Uint8Array(37);return n.set(t,0),n[32]=5,new DataView(n.buffer).setUint32(33,e,!1),n}function ge(e,t){let n=me(t),i=de(1),r=new Uint8Array(i.length+32);r.set(i,0),r.set((0,g.sha256)(n),i.length);let o=(0,g.sha256)(r);return{signature:q.p256.sign(o,e.privateKey,{lowS:!0}).toCompactRawBytes(),clientDataJSON:n,authenticatorData:i}}function Y(e){return{credentialId:new Uint8Array(0),publicKey:e.publicKey,signOperation:async t=>ge(e,(0,g.sha256)(t))}}function Z(e){let t=(0,a.deriveSwigWalletAddress)(e.swigAddress),n=(0,j.getAssociatedTokenAddressSync)(new c.PublicKey(L),t,!0);return(0,a.buildRegisterSessionKeyInstruction)({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:n,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var k=class{network="solana:mainnet";swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new c.PublicKey(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"}}async authorizeSession(t){let n=new c.PublicKey(t.allowedCounterparty),i=P(t.revolvingCapacityAtomic??t.maxAmountAtomic),r=F(),o=he(),p=(0,s.sessionRegisterMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:r.publicKey,maxAmount:P(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:o}),{signature:u,clientDataJSON:A,authenticatorData:h}=await this.passkey.signOperation(p),b=z(h,(0,I.sha256)(A)),l=(0,f.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,u,b),S=(0,d.sessionPdasOf)(await(0,d.fetchVaultSessionAccounts)(this.connection,this.vaultPdaKey)),E=Z({vaultPda:this.vaultPdaKey,swigAddress:new c.PublicKey(this.swigAddress),sessionPubkey:r.publicKey,maxAmount:P(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:o,clientDataJSON:A,authenticatorData:h,payer:this.feePayer.publicKey,siblingSessionPdas:S}),y=new c.Transaction().add(l,E);y.feePayer=this.feePayer.publicKey;let{blockhash:B}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);y.recentBlockhash=B,y.sign(this.feePayer);let Q=await this.connection.sendRawTransaction(y.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:Q,blockhash:B,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment),await(0,d.waitForSession)(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:r.publicKey,timeoutMs:2e4}),J(r,t,p)}async signWithSession(t,n){let i=await Se(n.channelId);return H(t,n,i)}async signOpenTab(t,n){return t.registration}async signCloseTab(t,n,i){let r=(0,s.sessionRevokeMessage)({programId:m.DEXTER_VAULT_PROGRAM_ID,vaultPda:this.vaultPdaKey,sessionPubkey:t.publicKey}),{signature:o,clientDataJSON:p,authenticatorData:u}=await this.passkey.signOperation(r),A=z(u,(0,I.sha256)(p)),h=(0,f.buildSecp256r1VerifyInstruction)(this.passkey.publicKey,o,A),b=(0,a.buildRevokeSessionKeyInstruction)({vaultPda:this.vaultPdaKey,allowedCounterparty:new c.PublicKey(t.scope.allowedCounterparty),clientDataJSON:p,authenticatorData:u}),l=new c.Transaction().add(h,b);l.feePayer=this.feePayer.publicKey;let{blockhash:S,lastValidBlockHeight:E}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);l.recentBlockhash=S,l.sign(this.feePayer);let y=await this.connection.sendRawTransaction(l.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:y,blockhash:S,lastValidBlockHeight:E},this.confirmOptions.commitment),r}};function Ae(e){return new k(e)}function z(e,t){let n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}function he(){return Math.floor(Math.random()*4294967295)>>>0}async function Se(e){if(/^[0-9a-f]{64}$/i.test(e))return xe(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function xe(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}0&&(module.exports={buildAdapterRegisterInstruction,createSolanaVaultAdapter,deriveChannelId,passkeySignerFromP256Keypair});
@@ -1,6 +1,8 @@
1
1
  import * as _solana_web3_js from '@solana/web3.js';
2
2
  import { PublicKey, Connection, Signer, ConfirmOptions } from '@solana/web3.js';
3
3
  import { V as VaultAdapter } from '../../../types-DuoL3s8n.cjs';
4
+ import { PasskeySignerWithPublicKey } from '@dexterai/vault/signers';
5
+ export { PasskeySignerWithPublicKey as PasskeySigner } from '@dexterai/vault/signers';
4
6
  import '@dexterai/vault/types';
5
7
 
6
8
  /**
@@ -47,35 +49,29 @@ declare function deriveChannelId(args: {
47
49
  * dexter-vault/tests/helpers/secp256r1.ts (signOperationWithPasskey).
48
50
  * Keep them in lockstep.
49
51
  */
52
+
50
53
  interface P256Keypair {
51
54
  /** 33-byte SEC1 compressed public key (the form the vault stores). */
52
55
  publicKey: Uint8Array;
53
56
  /** 32-byte raw scalar. NEVER persist this anywhere user-readable. */
54
57
  privateKey: Uint8Array;
55
58
  }
56
- interface SignedPasskeyPayload {
57
- /** Pass straight into the vault instruction's `client_data_json` arg. */
58
- clientDataJSON: Uint8Array;
59
- /** Pass straight into the vault instruction's `authenticator_data` arg. */
60
- authenticatorData: Uint8Array;
61
- /** Pass to buildSecp256r1VerifyInstruction as `message`. */
62
- precompileMessage: Uint8Array;
63
- /** Pass to buildSecp256r1VerifyInstruction as `signature`. */
64
- signature: Uint8Array;
65
- }
59
+ /**
60
+ * Build a unified `PasskeySignerWithPublicKey` (vault's canonical 0.19 shape)
61
+ * from a locally-held P-256 keypair — the node/CLI path. Returns
62
+ * `{ credentialId, publicKey, signOperation(operationMessage) }`. The signer
63
+ * owns the hashing locus: it computes `challenge = sha256(operationMessage)`
64
+ * internally (mirroring vault's `DexterApiBrowserPasskeySigner.signOperation`),
65
+ * so the adapter hands it the RAW operation message and never pre-hashes.
66
+ * The adapter still rebuilds the precompile message from the returned bytes.
67
+ *
68
+ * `credentialId` is empty for the node path — there is no platform
69
+ * authenticator credential; the on-chain verifier authenticates via the
70
+ * secp256r1 precompile over the clientDataJSON/authenticatorData, not the
71
+ * credentialId, so an empty value is correct here.
72
+ */
73
+ declare function passkeySignerFromP256Keypair(kp: P256Keypair): PasskeySignerWithPublicKey;
66
74
 
67
- interface PasskeySigner {
68
- /** 33-byte SEC1 compressed P-256 public key. The vault stores this on
69
- * init; the on-chain verifier compares against it on every passkey-
70
- * signed instruction. */
71
- publicKey: Uint8Array;
72
- /** Sign an arbitrary operation-message bundle in the WebAuthn shape the
73
- * on-chain verifier expects. The CLI path uses noble-curves; the
74
- * browser path will use navigator.credentials.get(). */
75
- signOperation(operationMessage: Uint8Array): Promise<SignedPasskeyPayload>;
76
- }
77
- /** Build a PasskeySigner from a locally-held P-256 keypair (CLI path). */
78
- declare function passkeySignerFromP256Keypair(kp: P256Keypair): PasskeySigner;
79
75
  interface CreateSolanaVaultAdapterOptions {
80
76
  /** RPC the adapter uses to submit txs. The buyer can pass their own
81
77
  * connection (browser wallet RPC, Helius URL, etc.) — the adapter has
@@ -89,7 +85,7 @@ interface CreateSolanaVaultAdapterOptions {
89
85
  /** The buyer's vault PDA (gate account). */
90
86
  vaultPda: string | PublicKey;
91
87
  /** The passkey signing path. */
92
- passkeySigner: PasskeySigner;
88
+ passkeySigner: PasskeySignerWithPublicKey;
93
89
  /** Lamport-fee payer. In Phase 2 this is the buyer; later phases may
94
90
  * route through a facilitator co-signer. Required because the buyer's
95
91
  * vault account is not a signer for register/revoke (the passkey
@@ -121,4 +117,4 @@ declare function buildAdapterRegisterInstruction(p: AdapterRegisterIxParams): _s
121
117
  /** Factory entry point. */
122
118
  declare function createSolanaVaultAdapter(opts: CreateSolanaVaultAdapterOptions): VaultAdapter;
123
119
 
124
- export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions, type PasskeySigner, buildAdapterRegisterInstruction, createSolanaVaultAdapter, deriveChannelId, passkeySignerFromP256Keypair };
120
+ export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions, buildAdapterRegisterInstruction, createSolanaVaultAdapter, deriveChannelId, passkeySignerFromP256Keypair };
@@ -1,6 +1,8 @@
1
1
  import * as _solana_web3_js from '@solana/web3.js';
2
2
  import { PublicKey, Connection, Signer, ConfirmOptions } from '@solana/web3.js';
3
3
  import { V as VaultAdapter } from '../../../types-DuoL3s8n.js';
4
+ import { PasskeySignerWithPublicKey } from '@dexterai/vault/signers';
5
+ export { PasskeySignerWithPublicKey as PasskeySigner } from '@dexterai/vault/signers';
4
6
  import '@dexterai/vault/types';
5
7
 
6
8
  /**
@@ -47,35 +49,29 @@ declare function deriveChannelId(args: {
47
49
  * dexter-vault/tests/helpers/secp256r1.ts (signOperationWithPasskey).
48
50
  * Keep them in lockstep.
49
51
  */
52
+
50
53
  interface P256Keypair {
51
54
  /** 33-byte SEC1 compressed public key (the form the vault stores). */
52
55
  publicKey: Uint8Array;
53
56
  /** 32-byte raw scalar. NEVER persist this anywhere user-readable. */
54
57
  privateKey: Uint8Array;
55
58
  }
56
- interface SignedPasskeyPayload {
57
- /** Pass straight into the vault instruction's `client_data_json` arg. */
58
- clientDataJSON: Uint8Array;
59
- /** Pass straight into the vault instruction's `authenticator_data` arg. */
60
- authenticatorData: Uint8Array;
61
- /** Pass to buildSecp256r1VerifyInstruction as `message`. */
62
- precompileMessage: Uint8Array;
63
- /** Pass to buildSecp256r1VerifyInstruction as `signature`. */
64
- signature: Uint8Array;
65
- }
59
+ /**
60
+ * Build a unified `PasskeySignerWithPublicKey` (vault's canonical 0.19 shape)
61
+ * from a locally-held P-256 keypair — the node/CLI path. Returns
62
+ * `{ credentialId, publicKey, signOperation(operationMessage) }`. The signer
63
+ * owns the hashing locus: it computes `challenge = sha256(operationMessage)`
64
+ * internally (mirroring vault's `DexterApiBrowserPasskeySigner.signOperation`),
65
+ * so the adapter hands it the RAW operation message and never pre-hashes.
66
+ * The adapter still rebuilds the precompile message from the returned bytes.
67
+ *
68
+ * `credentialId` is empty for the node path — there is no platform
69
+ * authenticator credential; the on-chain verifier authenticates via the
70
+ * secp256r1 precompile over the clientDataJSON/authenticatorData, not the
71
+ * credentialId, so an empty value is correct here.
72
+ */
73
+ declare function passkeySignerFromP256Keypair(kp: P256Keypair): PasskeySignerWithPublicKey;
66
74
 
67
- interface PasskeySigner {
68
- /** 33-byte SEC1 compressed P-256 public key. The vault stores this on
69
- * init; the on-chain verifier compares against it on every passkey-
70
- * signed instruction. */
71
- publicKey: Uint8Array;
72
- /** Sign an arbitrary operation-message bundle in the WebAuthn shape the
73
- * on-chain verifier expects. The CLI path uses noble-curves; the
74
- * browser path will use navigator.credentials.get(). */
75
- signOperation(operationMessage: Uint8Array): Promise<SignedPasskeyPayload>;
76
- }
77
- /** Build a PasskeySigner from a locally-held P-256 keypair (CLI path). */
78
- declare function passkeySignerFromP256Keypair(kp: P256Keypair): PasskeySigner;
79
75
  interface CreateSolanaVaultAdapterOptions {
80
76
  /** RPC the adapter uses to submit txs. The buyer can pass their own
81
77
  * connection (browser wallet RPC, Helius URL, etc.) — the adapter has
@@ -89,7 +85,7 @@ interface CreateSolanaVaultAdapterOptions {
89
85
  /** The buyer's vault PDA (gate account). */
90
86
  vaultPda: string | PublicKey;
91
87
  /** The passkey signing path. */
92
- passkeySigner: PasskeySigner;
88
+ passkeySigner: PasskeySignerWithPublicKey;
93
89
  /** Lamport-fee payer. In Phase 2 this is the buyer; later phases may
94
90
  * route through a facilitator co-signer. Required because the buyer's
95
91
  * vault account is not a signer for register/revoke (the passkey
@@ -121,4 +117,4 @@ declare function buildAdapterRegisterInstruction(p: AdapterRegisterIxParams): _s
121
117
  /** Factory entry point. */
122
118
  declare function createSolanaVaultAdapter(opts: CreateSolanaVaultAdapterOptions): VaultAdapter;
123
119
 
124
- export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions, type PasskeySigner, buildAdapterRegisterInstruction, createSolanaVaultAdapter, deriveChannelId, passkeySignerFromP256Keypair };
120
+ export { type AdapterRegisterIxParams, type CreateSolanaVaultAdapterOptions, buildAdapterRegisterInstruction, createSolanaVaultAdapter, deriveChannelId, passkeySignerFromP256Keypair };
@@ -1 +1 @@
1
- import{PublicKey as l,Transaction as J}from"@solana/web3.js";import{getAssociatedTokenAddressSync as ne}from"@solana/spl-token";var G="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",$="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",q="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var g="eip155:8453",A="eip155:84532",h="eip155:42161",S="eip155:137",f="eip155:10",x="eip155:43114",P="eip155:56",b="eip155:1187947933",E="eip155:324705682",K="eip155:1";var C="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var X="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Y="0x55d398326f99059fF775485246999027B3197955",T="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",le={[P]:T,[g]:X,[A]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[h]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[S]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[f]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[x]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[b]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[E]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[K]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},ue={[Y]:{symbol:"USDT",decimals:18},[T]:{symbol:"USDC",decimals:18}};var ye={[P]:56,[g]:8453,[A]:84532,[h]:42161,[S]:137,[f]:10,[x]:43114,[b]:1187947933,[E]:324705682,[K]:1},me={[G]:"https://api.dexter.cash/api/solana/rpc",[$]:"https://api.devnet.solana.com",[q]:"https://api.testnet.solana.com"},de={[P]:"https://api.dexter.cash/api/evm/bsc/rpc",[g]:"https://api.dexter.cash/api/base/rpc",[A]:"https://sepolia.base.org",[h]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[S]:"https://api.dexter.cash/api/evm/polygon/rpc",[f]:"https://api.dexter.cash/api/evm/optimism/rpc",[x]:"https://api.dexter.cash/api/evm/avalanche/rpc",[b]:"https://skale-base.skalenodes.com/v1/base",[E]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[K]:"https://eth.llamarpc.com"};import{buildRegisterSessionKeyInstruction as _,buildRevokeSessionKeyInstruction as N,deriveSwigWalletAddress as D}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as v}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as w,SECP256R1_PROGRAM_ID as xe,INSTRUCTIONS_SYSVAR_ID as Pe}from"@dexterai/vault/constants";import{sessionRegisterMessage as U,sessionRevokeMessage as I,voucherPayloadMessage as k,buildVoucherMessage as Ke}from"@dexterai/vault/messages";import B from"tweetnacl";import{sha256 as z}from"@noble/hashes/sha256";function M(){let e=B.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function V(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function L(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let i=BigInt(t.cumulativeAmount),s=BigInt(e.scope.maxAmountAtomic);if(i>s)throw new Error(`voucher cumulative ${i} exceeds session cap ${s}`);let r=Math.floor(Date.now()/1e3);if(r>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${r}`);let a=k({channelId:n,cumulativeAmount:i,sequenceNumber:t.sequenceNumber}),o=B.sign.detached(a,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:o}}function y(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function j(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),i=z.create();return i.update(e.vaultPda.toBytes()),i.update(n),i.update(t),i.digest()}import{fetchVaultSessionAccounts as ie,sessionPdasOf as se,waitForSession as re}from"@dexterai/vault/session";import{p256 as Z}from"@noble/curves/p256";import{sha256 as m}from"@noble/hashes/sha256";var W="dexter.cash";function Q(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function ee(e,t=`https://${W}`){let i={type:"webauthn.get",challenge:Q(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(i))}function te(e=1){let t=m(new TextEncoder().encode(W)),n=new Uint8Array(37);return n.set(t,0),n[32]=5,new DataView(n.buffer).setUint32(33,e,!1),n}function F(e,t){let n=m(t),i=ee(n),s=te(1),r=new Uint8Array(s.length+32);r.set(s,0),r.set(m(i),s.length);let a=m(r),c=Z.sign(a,e.privateKey,{lowS:!0}).toCompactRawBytes();return{clientDataJSON:i,authenticatorData:s,precompileMessage:r,signature:c}}function We(e){return{publicKey:e.publicKey,signOperation:async t=>F(e,t)}}function oe(e){let t=D(e.swigAddress),n=ne(new l(C),t,!0);return _({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:n,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var O=class{network="solana:mainnet";swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new l(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"}}async authorizeSession(t){let n=new l(t.allowedCounterparty),i=y(t.revolvingCapacityAtomic??t.maxAmountAtomic),s=M(),r=ae(),a=U({programId:w,vaultPda:this.vaultPdaKey,sessionPubkey:s.publicKey,maxAmount:y(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r}),o=await this.passkey.signOperation(a),c=v(this.passkey.publicKey,o.signature,o.precompileMessage),u=se(await ie(this.connection,this.vaultPdaKey)),d=oe({vaultPda:this.vaultPdaKey,swigAddress:new l(this.swigAddress),sessionPubkey:s.publicKey,maxAmount:y(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:r,clientDataJSON:o.clientDataJSON,authenticatorData:o.authenticatorData,payer:this.feePayer.publicKey,siblingSessionPdas:u}),p=new J().add(c,d);p.feePayer=this.feePayer.publicKey;let{blockhash:R}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);p.recentBlockhash=R,p.sign(this.feePayer);let H=await this.connection.sendRawTransaction(p.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:H,blockhash:R,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment),await re(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:s.publicKey,timeoutMs:2e4}),V(s,t,a)}async signWithSession(t,n){let i=await ce(n.channelId);return L(t,n,i)}async signOpenTab(t,n){return t.registration}async signCloseTab(t,n,i){let s=I({programId:w,vaultPda:this.vaultPdaKey,sessionPubkey:t.publicKey}),r=await this.passkey.signOperation(s),a=v(this.passkey.publicKey,r.signature,r.precompileMessage),o=N({vaultPda:this.vaultPdaKey,allowedCounterparty:new l(t.scope.allowedCounterparty),clientDataJSON:r.clientDataJSON,authenticatorData:r.authenticatorData}),c=new J().add(a,o);c.feePayer=this.feePayer.publicKey;let{blockhash:u,lastValidBlockHeight:d}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);c.recentBlockhash=u,c.sign(this.feePayer);let p=await this.connection.sendRawTransaction(c.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:p,blockhash:u,lastValidBlockHeight:d},this.confirmOptions.commitment),s}};function Fe(e){return new O(e)}function ae(){return Math.floor(Math.random()*4294967295)>>>0}async function ce(e){if(/^[0-9a-f]{64}$/i.test(e))return pe(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function pe(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}export{oe as buildAdapterRegisterInstruction,Fe as createSolanaVaultAdapter,j as deriveChannelId,We as passkeySignerFromP256Keypair};
1
+ import{PublicKey as u,Transaction as G}from"@solana/web3.js";import{getAssociatedTokenAddressSync as ce}from"@solana/spl-token";var Y="solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",z="solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1",j="solana:4uhcVJyU9pJkvQyS88uRDiswHXSCkY3z";var S="eip155:8453",x="eip155:84532",f="eip155:42161",P="eip155:137",b="eip155:10",E="eip155:43114",K="eip155:56",v="eip155:1187947933",w="eip155:324705682",C="eip155:1";var _="EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v";var Z="0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",Q="0x55d398326f99059fF775485246999027B3197955",N="0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d",Ae={[K]:N,[S]:Z,[x]:"0x036CbD53842c5426634e7929541eC2318f3dCF7e",[f]:"0xaf88d065e77c8cC2239327C5EDb3A432268e5831",[P]:"0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",[b]:"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85",[E]:"0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E",[v]:"0x85889c8c714505E0c94b30fcfcF64fE3Ac8FCb20",[w]:"0x2e08028E3C4c2356572E096d8EF835cD5C6030bD",[C]:"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"},he={[Q]:{symbol:"USDT",decimals:18},[N]:{symbol:"USDC",decimals:18}};var Se={[K]:56,[S]:8453,[x]:84532,[f]:42161,[P]:137,[b]:10,[E]:43114,[v]:1187947933,[w]:324705682,[C]:1},xe={[Y]:"https://api.dexter.cash/api/solana/rpc",[z]:"https://api.devnet.solana.com",[j]:"https://api.testnet.solana.com"},fe={[K]:"https://api.dexter.cash/api/evm/bsc/rpc",[S]:"https://api.dexter.cash/api/base/rpc",[x]:"https://sepolia.base.org",[f]:"https://api.dexter.cash/api/evm/arbitrum/rpc",[P]:"https://api.dexter.cash/api/evm/polygon/rpc",[b]:"https://api.dexter.cash/api/evm/optimism/rpc",[E]:"https://api.dexter.cash/api/evm/avalanche/rpc",[v]:"https://skale-base.skalenodes.com/v1/base",[w]:"https://base-sepolia-testnet.skalenodes.com/v1/jubilant-horrible-ancha",[C]:"https://eth.llamarpc.com"};import{buildRegisterSessionKeyInstruction as D,buildRevokeSessionKeyInstruction as I,deriveSwigWalletAddress as k}from"@dexterai/vault/instructions";import{buildSecp256r1VerifyInstruction as R}from"@dexterai/vault/precompile";import{DEXTER_VAULT_PROGRAM_ID as O,SECP256R1_PROGRAM_ID as we,INSTRUCTIONS_SYSVAR_ID as Ce}from"@dexterai/vault/constants";import{sessionRegisterMessage as B,sessionRevokeMessage as M,voucherPayloadMessage as V,buildVoucherMessage as Ue}from"@dexterai/vault/messages";import L from"tweetnacl";import{sha256 as ee}from"@noble/hashes/sha256";function W(){let e=L.sign.keyPair();return{publicKey:e.publicKey,privateKey:e.secretKey}}function F(e,t,n){return{publicKey:e.publicKey,privateKey:e.privateKey,scope:t,registration:n}}function J(e,t,n){if(n.length!==32)throw new Error(`channelIdBytes must be 32 bytes, got ${n.length}`);let i=BigInt(t.cumulativeAmount),r=BigInt(e.scope.maxAmountAtomic);if(i>r)throw new Error(`voucher cumulative ${i} exceeds session cap ${r}`);let s=Math.floor(Date.now()/1e3);if(s>=e.scope.expiresAtUnix)throw new Error(`session expired at ${e.scope.expiresAtUnix}, now ${s}`);let o=V({channelId:n,cumulativeAmount:i,sequenceNumber:t.sequenceNumber}),a=L.sign.detached(o,e.privateKey);return{payload:t,sessionPublicKey:e.publicKey,sessionRegistration:e.registration,sessionSignature:a}}function d(e){if(!/^\d+$/.test(e))throw new Error(`atomic amount must be a non-negative integer string, got "${e}"`);return BigInt(e)}function te(e){let t=new Uint8Array(8);new DataView(t.buffer).setBigUint64(0,e.nonce,!0);let n=new TextEncoder().encode(e.sellerUrl),i=ee.create();return i.update(e.vaultPda.toBytes()),i.update(n),i.update(t),i.digest()}import{fetchVaultSessionAccounts as pe,sessionPdasOf as ue,waitForSession as le}from"@dexterai/vault/session";import{sha256 as $}from"@noble/hashes/sha256";import{p256 as ne}from"@noble/curves/p256";import{sha256 as g}from"@noble/hashes/sha256";var H="dexter.cash";function ie(e){return Buffer.from(e).toString("base64").replace(/\+/g,"-").replace(/\//g,"_").replace(/=+$/,"")}function re(e,t=`https://${H}`){let i={type:"webauthn.get",challenge:ie(e),origin:t,crossOrigin:!1};return new TextEncoder().encode(JSON.stringify(i))}function se(e=1){let t=g(new TextEncoder().encode(H)),n=new Uint8Array(37);return n.set(t,0),n[32]=5,new DataView(n.buffer).setUint32(33,e,!1),n}function oe(e,t){let n=re(t),i=se(1),r=new Uint8Array(i.length+32);r.set(i,0),r.set(g(n),i.length);let s=g(r);return{signature:ne.sign(s,e.privateKey,{lowS:!0}).toCompactRawBytes(),clientDataJSON:n,authenticatorData:i}}function ae(e){return{credentialId:new Uint8Array(0),publicKey:e.publicKey,signOperation:async t=>oe(e,g(t))}}function ye(e){let t=k(e.swigAddress),n=ce(new u(_),t,!0);return D({vaultPda:e.vaultPda,sessionPubkey:e.sessionPubkey,maxAmount:e.maxAmount,maxRevolvingCapacity:e.maxRevolvingCapacity,expiresAt:e.expiresAt,allowedCounterparty:e.allowedCounterparty,nonce:e.nonce,swigAddress:e.swigAddress,vaultUsdcAta:n,clientDataJSON:e.clientDataJSON,authenticatorData:e.authenticatorData,payer:e.payer,siblingSessionPdas:e.siblingSessionPdas})}var U=class{network="solana:mainnet";swigAddress;vaultPda;connection;vaultPdaKey;passkey;feePayer;confirmOptions;constructor(t){this.connection=t.connection,this.swigAddress=typeof t.swigAddress=="string"?t.swigAddress:t.swigAddress.toBase58(),this.vaultPdaKey=typeof t.vaultPda=="string"?new u(t.vaultPda):t.vaultPda,this.vaultPda=this.vaultPdaKey.toBase58(),this.passkey=t.passkeySigner,this.feePayer=t.feePayer,this.confirmOptions=t.confirmOptions??{commitment:"confirmed"}}async authorizeSession(t){let n=new u(t.allowedCounterparty),i=d(t.revolvingCapacityAtomic??t.maxAmountAtomic),r=W(),s=me(),o=B({programId:O,vaultPda:this.vaultPdaKey,sessionPubkey:r.publicKey,maxAmount:d(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:s}),{signature:a,clientDataJSON:l,authenticatorData:y}=await this.passkey.signOperation(o),A=q(y,$(l)),c=R(this.passkey.publicKey,a,A),m=ue(await pe(this.connection,this.vaultPdaKey)),h=ye({vaultPda:this.vaultPdaKey,swigAddress:new u(this.swigAddress),sessionPubkey:r.publicKey,maxAmount:d(t.maxAmountAtomic),maxRevolvingCapacity:i,expiresAt:BigInt(t.expiresAtUnix),allowedCounterparty:n,nonce:s,clientDataJSON:l,authenticatorData:y,payer:this.feePayer.publicKey,siblingSessionPdas:m}),p=new G().add(c,h);p.feePayer=this.feePayer.publicKey;let{blockhash:T}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);p.recentBlockhash=T,p.sign(this.feePayer);let X=await this.connection.sendRawTransaction(p.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:X,blockhash:T,lastValidBlockHeight:(await this.connection.getLatestBlockhash(this.confirmOptions.commitment)).lastValidBlockHeight},this.confirmOptions.commitment),await le(this.connection,this.vaultPdaKey,n,{expectedSessionPubkey:r.publicKey,timeoutMs:2e4}),F(r,t,o)}async signWithSession(t,n){let i=await de(n.channelId);return J(t,n,i)}async signOpenTab(t,n){return t.registration}async signCloseTab(t,n,i){let r=M({programId:O,vaultPda:this.vaultPdaKey,sessionPubkey:t.publicKey}),{signature:s,clientDataJSON:o,authenticatorData:a}=await this.passkey.signOperation(r),l=q(a,$(o)),y=R(this.passkey.publicKey,s,l),A=I({vaultPda:this.vaultPdaKey,allowedCounterparty:new u(t.scope.allowedCounterparty),clientDataJSON:o,authenticatorData:a}),c=new G().add(y,A);c.feePayer=this.feePayer.publicKey;let{blockhash:m,lastValidBlockHeight:h}=await this.connection.getLatestBlockhash(this.confirmOptions.commitment);c.recentBlockhash=m,c.sign(this.feePayer);let p=await this.connection.sendRawTransaction(c.serialize(),{skipPreflight:!1,preflightCommitment:this.confirmOptions.preflightCommitment??this.confirmOptions.commitment});return await this.connection.confirmTransaction({signature:p,blockhash:m,lastValidBlockHeight:h},this.confirmOptions.commitment),r}};function qe(e){return new U(e)}function q(e,t){let n=new Uint8Array(e.length+t.length);return n.set(e,0),n.set(t,e.length),n}function me(){return Math.floor(Math.random()*4294967295)>>>0}async function de(e){if(/^[0-9a-f]{64}$/i.test(e))return ge(e);let{sha256:t}=await import("@noble/hashes/sha256");return t(new TextEncoder().encode(e))}function ge(e){let t=new Uint8Array(e.length/2);for(let n=0;n<t.length;n++)t[n]=parseInt(e.substr(n*2,2),16);return t}export{ye as buildAdapterRegisterInstruction,qe as createSolanaVaultAdapter,te as deriveChannelId,ae as passkeySignerFromP256Keypair};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dexterai/x402",
3
- "version": "4.0.0",
3
+ "version": "5.0.0",
4
4
  "description": "Full-stack x402 SDK - add paid API monetization to any endpoint. Express middleware, React hooks, Access Pass, dynamic pricing. Solana, Base, Polygon, Arbitrum, Optimism, Avalanche, SKALE.",
5
5
  "author": "Dexter",
6
6
  "license": "MIT",
@@ -76,7 +76,6 @@
76
76
  "release:major": "npm version major && npm publish --access public"
77
77
  },
78
78
  "dependencies": {
79
- "@dexterai/vault": "^0.9.0",
80
79
  "@dexterai/x402-ads-types": "^0.2.0",
81
80
  "@dexterai/x402-core": "^1.4.0",
82
81
  "@noble/curves": "^1.9.7",
@@ -89,6 +88,7 @@
89
88
  "tweetnacl": "^1.0.3"
90
89
  },
91
90
  "devDependencies": {
91
+ "@dexterai/vault": "^0.19.0",
92
92
  "@types/aws-lambda": "^8.10.161",
93
93
  "@types/express": "^5.0.6",
94
94
  "@types/node": "^22.10.0",
@@ -103,6 +103,7 @@
103
103
  "vitest": "^2.1.8"
104
104
  },
105
105
  "peerDependencies": {
106
+ "@dexterai/vault": ">=0.19.0",
106
107
  "@solana/wallet-adapter-base": "^0.9.0",
107
108
  "react": "^18.0.0 || ^19.0.0",
108
109
  "stripe": "^20.0.0",