@evvm/x402 0.0.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.
- package/README.md +228 -0
- package/bun.lock +370 -0
- package/index.ts +1 -0
- package/package.json +26 -0
- package/src/index.ts +3 -0
- package/src/lib/index.ts +3 -0
- package/src/lib/local-facilitator.ts +106 -0
- package/src/lib/parse-header.ts +29 -0
- package/src/lib/payment-responses.ts +64 -0
- package/src/middleware/express.ts +92 -0
- package/src/middleware/index.ts +2 -0
- package/src/middleware/next.ts +79 -0
- package/src/types/evvm-schema.type.ts +19 -0
- package/src/types/facilitator.type.ts +15 -0
- package/src/types/index.ts +3 -0
- package/src/types/payment-payload.type.ts +9 -0
- package/tsconfig.json +29 -0
package/README.md
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
# @evvm/x402
|
|
2
|
+
|
|
3
|
+
A TypeScript library for integrating [EVVM](https://evvm.org) payments into Node.js applications. This package provides middleware for Express.js and Next.js, along with facilitator utilities for handling payment verification and settlement.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @evvm/x402
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
or with bun:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bun add @evvm/x402
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Peer Dependencies
|
|
18
|
+
|
|
19
|
+
This package requires Next.js (>=15) as a peer dependency when using the Next.js middleware:
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install next@>=15
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Setup
|
|
26
|
+
|
|
27
|
+
Create the facilitator once in a separate file and import it wherever needed:
|
|
28
|
+
|
|
29
|
+
```typescript
|
|
30
|
+
// src/facilitator.ts
|
|
31
|
+
import { LocalFacilitator } from "@evvm/x402";
|
|
32
|
+
import { createSignerWithEthers } from "@evvm/evvm-js";
|
|
33
|
+
import { ethers } from "ethers";
|
|
34
|
+
|
|
35
|
+
const provider = new ethers.JsonRpcProvider(process.env.RPC_URL!);
|
|
36
|
+
const wallet = new ethers.Wallet(process.env.PRIVATE_KEY!, provider);
|
|
37
|
+
const signer = await createSignerWithEthers(wallet);
|
|
38
|
+
|
|
39
|
+
export const facilitator = new LocalFacilitator(signer);
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
// src/offers.ts
|
|
44
|
+
import { IEvvmSchema } from "@evvm/x402";
|
|
45
|
+
|
|
46
|
+
export const offers: IEvvmSchema[] = [
|
|
47
|
+
{
|
|
48
|
+
scheme: "evvm",
|
|
49
|
+
network: "eip155:11155111",
|
|
50
|
+
amount: "1000000000000000",
|
|
51
|
+
asset: "0x0000000000000000000000000000000000000000",
|
|
52
|
+
payTo: "0xReceiverAccount",
|
|
53
|
+
maxTimeoutSeconds: 300,
|
|
54
|
+
extra: {
|
|
55
|
+
coreContractAddress: "0xYourCoreContractAddress",
|
|
56
|
+
evvmId: 1,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
];
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
## Quick Start
|
|
63
|
+
|
|
64
|
+
```typescript
|
|
65
|
+
// src/index.ts
|
|
66
|
+
import { requireEvvmPaymentExpress } from "@evvm/x402";
|
|
67
|
+
import { facilitator } from "./facilitator";
|
|
68
|
+
import { offers } from "./offers";
|
|
69
|
+
import express from "express";
|
|
70
|
+
|
|
71
|
+
const app = express();
|
|
72
|
+
|
|
73
|
+
app.get(
|
|
74
|
+
"/api/protected",
|
|
75
|
+
requireEvvmPaymentExpress(facilitator, offers),
|
|
76
|
+
(req, res) => {
|
|
77
|
+
res.json({ message: "Hello, paid user!" });
|
|
78
|
+
},
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Middlewares
|
|
83
|
+
|
|
84
|
+
### Express.js
|
|
85
|
+
|
|
86
|
+
The Express middleware validates incoming payment headers and settles payments before passing requests to your route handlers.
|
|
87
|
+
|
|
88
|
+
```typescript
|
|
89
|
+
import { requireEvvmPaymentExpress } from "@evvm/x402";
|
|
90
|
+
import { facilitator } from "./facilitator";
|
|
91
|
+
import { offers } from "./offers";
|
|
92
|
+
|
|
93
|
+
const app = express();
|
|
94
|
+
|
|
95
|
+
app.get("/api/secure", requireEvvmPaymentExpress(facilitator, offers), (req, res) => {
|
|
96
|
+
// Payment was verified and settled
|
|
97
|
+
res.json({ data: "Access granted" });
|
|
98
|
+
});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
#### How it works:
|
|
102
|
+
|
|
103
|
+
1. **Check for Payment Header**: Looks for `PAYMENT-SIGNATURE` header
|
|
104
|
+
2. **Return 402 if Missing**: If not present, returns HTTP 402 with payment requirements
|
|
105
|
+
3. **Parse & Validate**: Parses the payment payload and validates the EVVM schema
|
|
106
|
+
4. **Verify Signature**: Uses the facilitator to verify the payment signature on-chain
|
|
107
|
+
5. **Settle Payment**: Executes the payment transaction
|
|
108
|
+
6. **Pass to Handler**: Adds `PAYMENT-RESPONSE` header and continues to your route
|
|
109
|
+
|
|
110
|
+
### Next.js
|
|
111
|
+
|
|
112
|
+
The Next.js middleware works with Next.js 15+ App Router:
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
// middleware.ts
|
|
116
|
+
import { createEvvmMiddlewareNext } from "@evvm/x402";
|
|
117
|
+
import { facilitator } from "./facilitator";
|
|
118
|
+
import { offers } from "./offers";
|
|
119
|
+
|
|
120
|
+
export default createEvvmMiddlewareNext(facilitator, offers);
|
|
121
|
+
|
|
122
|
+
export const config = {
|
|
123
|
+
matcher: "/api/:path*",
|
|
124
|
+
};
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Facilitators
|
|
128
|
+
|
|
129
|
+
Facilitators handle payment verification and settlement. The package includes a built-in `LocalFacilitator` (for local verification and execution of transactions). You can also implement custom facilitators by using the `IFacilitator`; this is useful for cases where the facilitator lives in a different service or location.
|
|
130
|
+
|
|
131
|
+
### LocalFacilitator
|
|
132
|
+
|
|
133
|
+
The `LocalFacilitator` verifies signatures and settles payments using a local signer.
|
|
134
|
+
|
|
135
|
+
#### Features:
|
|
136
|
+
|
|
137
|
+
- **Signature Verification**: Recovers the signer from the signature and validates it matches the payer
|
|
138
|
+
- **Nonce Validation**: Ensures the transaction nonce is correct (for both sync and async executions)
|
|
139
|
+
- **Balance Checks**: Verifies the payer has sufficient balance
|
|
140
|
+
- **Payment Settlement**: Executes the EVVM payment transaction
|
|
141
|
+
|
|
142
|
+
### Custom Facilitator
|
|
143
|
+
|
|
144
|
+
Implement the `IFacilitator` interface for custom payment handling:
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import type { IFacilitator } from "@evvm/x402";
|
|
148
|
+
import type {
|
|
149
|
+
ISerializableSignedAction,
|
|
150
|
+
IPayData,
|
|
151
|
+
HexString,
|
|
152
|
+
} from "@evvm/evvm-js";
|
|
153
|
+
|
|
154
|
+
class CustomFacilitator implements IFacilitator {
|
|
155
|
+
async verifyPaySignature(
|
|
156
|
+
signedAction: ISerializableSignedAction<IPayData>,
|
|
157
|
+
): Promise<boolean> {
|
|
158
|
+
// Custom verification logic
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
async settlePayment(
|
|
163
|
+
signedAction: ISerializableSignedAction<IPayData>,
|
|
164
|
+
): Promise<HexString | null> {
|
|
165
|
+
// Custom settlement logic
|
|
166
|
+
return "0xTransactionHash";
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Payment Offers
|
|
172
|
+
|
|
173
|
+
Define payment requirements using the `IEvvmSchema` interface. Create an `offers` file and import it wherever needed (see [Setup](#setup) for the full example):
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
import { IEvvmSchema } from "@evvm/x402";
|
|
177
|
+
|
|
178
|
+
export const offers: IEvvmSchema[] = [
|
|
179
|
+
{
|
|
180
|
+
scheme: "evvm",
|
|
181
|
+
network: "eip155:1", // Ethereum mainnet
|
|
182
|
+
amount: "1000000000000000", // 0.001 ETH in wei
|
|
183
|
+
asset: "0x0000...", // Token address (ETH = zeros)
|
|
184
|
+
payTo: "0xRecipientAddress", // Payment recipient
|
|
185
|
+
maxTimeoutSeconds: 300, // Max payment timeout
|
|
186
|
+
extra: {
|
|
187
|
+
coreContractAddress: "0xCoreContract",
|
|
188
|
+
evvmId: 1, // EVVM identifier
|
|
189
|
+
originExecutor: "0xExecutor", // Optional executor
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
];
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## Response Headers
|
|
196
|
+
|
|
197
|
+
The middleware adds the following headers:
|
|
198
|
+
|
|
199
|
+
| Header | Description |
|
|
200
|
+
| ------------------- | -------------------------------------------------- |
|
|
201
|
+
| `PAYMENT-REQUIRED` | Base64-encoded payment requirements (402 response) |
|
|
202
|
+
| `PAYMENT-RESPONSE` | Base64-encoded settlement result |
|
|
203
|
+
| `PAYMENT-SIGNATURE` | Client-provided payment signature |
|
|
204
|
+
|
|
205
|
+
## API Reference
|
|
206
|
+
|
|
207
|
+
### Middlewares
|
|
208
|
+
|
|
209
|
+
- `requireEvvmPaymentExpress(facilitator, offers)` - Express.js middleware
|
|
210
|
+
- `createEvvmMiddlewareNext(facilitator, offers)` - Next.js middleware factory
|
|
211
|
+
|
|
212
|
+
### Utilities
|
|
213
|
+
|
|
214
|
+
- `parseHeader(header)` - Parse PAYMENT-SIGNATURE header
|
|
215
|
+
- `paymentRequiredResponse(offers)` - Create 402 response
|
|
216
|
+
- `invalidPaymentResponse(reason)` - Create 400 response for invalid payments
|
|
217
|
+
|
|
218
|
+
### Types
|
|
219
|
+
|
|
220
|
+
- `IFacilitator` - Facilitator interface
|
|
221
|
+
- `IEvvmSchema` - EVVM payment offer schema
|
|
222
|
+
- `LocalFacilitator` - Built-in local facilitator implementation
|
|
223
|
+
|
|
224
|
+
## Related Links
|
|
225
|
+
|
|
226
|
+
- [EVVM Official Site](https://evvm.org)
|
|
227
|
+
- [EVVM Documentation](https://evvm.info)
|
|
228
|
+
- [@evvm/evvm-js](https://github.com/evvm/evvm-js) - JavaScript SDK for EVVM
|
package/bun.lock
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "@evvm/x402",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@evvm/evvm-js": "0.1.27",
|
|
9
|
+
"@x402/core": "^2.6.0",
|
|
10
|
+
"viem": "^2.47.2",
|
|
11
|
+
"zod": "^4.3.6",
|
|
12
|
+
},
|
|
13
|
+
"devDependencies": {
|
|
14
|
+
"@types/bun": "latest",
|
|
15
|
+
"@types/express": "^5.0.6",
|
|
16
|
+
"next": "^15.0.0",
|
|
17
|
+
"typescript": "^5",
|
|
18
|
+
},
|
|
19
|
+
"peerDependencies": {
|
|
20
|
+
"next": ">=15",
|
|
21
|
+
},
|
|
22
|
+
"optionalPeers": [
|
|
23
|
+
"next",
|
|
24
|
+
],
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
"packages": {
|
|
28
|
+
"@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.10.1", "", {}, "sha512-96Z2IP3mYmF1Xg2cDm8f1gWGf/HUVedQ3FMifV4kG/PQ4yEP51xDtRAEfhVNt5f/uzpNkZHwWQuUcu6D6K+Ekw=="],
|
|
29
|
+
|
|
30
|
+
"@emnapi/runtime": ["@emnapi/runtime@1.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw=="],
|
|
31
|
+
|
|
32
|
+
"@evvm/evvm-js": ["@evvm/evvm-js@0.1.27", "", { "dependencies": { "crypto-browserify": "^3.12.1", "ethers": "^6.16.0", "viem": "2.45.0", "zod": "^4.3.6" }, "peerDependencies": { "typescript": "^5" } }, "sha512-F/lE/UeWfEKQzROmWh3jByPwRNimwzEi+a64ZiK7QE02pGpP8FHkDW1bbazfLPD/6iAjg45EApi+6PyvpzRXrw=="],
|
|
33
|
+
|
|
34
|
+
"@img/colour": ["@img/colour@1.1.0", "", {}, "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ=="],
|
|
35
|
+
|
|
36
|
+
"@img/sharp-darwin-arm64": ["@img/sharp-darwin-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-arm64": "1.2.4" }, "os": "darwin", "cpu": "arm64" }, "sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w=="],
|
|
37
|
+
|
|
38
|
+
"@img/sharp-darwin-x64": ["@img/sharp-darwin-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-darwin-x64": "1.2.4" }, "os": "darwin", "cpu": "x64" }, "sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw=="],
|
|
39
|
+
|
|
40
|
+
"@img/sharp-libvips-darwin-arm64": ["@img/sharp-libvips-darwin-arm64@1.2.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g=="],
|
|
41
|
+
|
|
42
|
+
"@img/sharp-libvips-darwin-x64": ["@img/sharp-libvips-darwin-x64@1.2.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg=="],
|
|
43
|
+
|
|
44
|
+
"@img/sharp-libvips-linux-arm": ["@img/sharp-libvips-linux-arm@1.2.4", "", { "os": "linux", "cpu": "arm" }, "sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A=="],
|
|
45
|
+
|
|
46
|
+
"@img/sharp-libvips-linux-arm64": ["@img/sharp-libvips-linux-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw=="],
|
|
47
|
+
|
|
48
|
+
"@img/sharp-libvips-linux-ppc64": ["@img/sharp-libvips-linux-ppc64@1.2.4", "", { "os": "linux", "cpu": "ppc64" }, "sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA=="],
|
|
49
|
+
|
|
50
|
+
"@img/sharp-libvips-linux-riscv64": ["@img/sharp-libvips-linux-riscv64@1.2.4", "", { "os": "linux", "cpu": "none" }, "sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA=="],
|
|
51
|
+
|
|
52
|
+
"@img/sharp-libvips-linux-s390x": ["@img/sharp-libvips-linux-s390x@1.2.4", "", { "os": "linux", "cpu": "s390x" }, "sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ=="],
|
|
53
|
+
|
|
54
|
+
"@img/sharp-libvips-linux-x64": ["@img/sharp-libvips-linux-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw=="],
|
|
55
|
+
|
|
56
|
+
"@img/sharp-libvips-linuxmusl-arm64": ["@img/sharp-libvips-linuxmusl-arm64@1.2.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw=="],
|
|
57
|
+
|
|
58
|
+
"@img/sharp-libvips-linuxmusl-x64": ["@img/sharp-libvips-linuxmusl-x64@1.2.4", "", { "os": "linux", "cpu": "x64" }, "sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg=="],
|
|
59
|
+
|
|
60
|
+
"@img/sharp-linux-arm": ["@img/sharp-linux-arm@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm": "1.2.4" }, "os": "linux", "cpu": "arm" }, "sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw=="],
|
|
61
|
+
|
|
62
|
+
"@img/sharp-linux-arm64": ["@img/sharp-linux-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg=="],
|
|
63
|
+
|
|
64
|
+
"@img/sharp-linux-ppc64": ["@img/sharp-linux-ppc64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-ppc64": "1.2.4" }, "os": "linux", "cpu": "ppc64" }, "sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA=="],
|
|
65
|
+
|
|
66
|
+
"@img/sharp-linux-riscv64": ["@img/sharp-linux-riscv64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-riscv64": "1.2.4" }, "os": "linux", "cpu": "none" }, "sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw=="],
|
|
67
|
+
|
|
68
|
+
"@img/sharp-linux-s390x": ["@img/sharp-linux-s390x@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-s390x": "1.2.4" }, "os": "linux", "cpu": "s390x" }, "sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg=="],
|
|
69
|
+
|
|
70
|
+
"@img/sharp-linux-x64": ["@img/sharp-linux-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linux-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ=="],
|
|
71
|
+
|
|
72
|
+
"@img/sharp-linuxmusl-arm64": ["@img/sharp-linuxmusl-arm64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-arm64": "1.2.4" }, "os": "linux", "cpu": "arm64" }, "sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg=="],
|
|
73
|
+
|
|
74
|
+
"@img/sharp-linuxmusl-x64": ["@img/sharp-linuxmusl-x64@0.34.5", "", { "optionalDependencies": { "@img/sharp-libvips-linuxmusl-x64": "1.2.4" }, "os": "linux", "cpu": "x64" }, "sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q=="],
|
|
75
|
+
|
|
76
|
+
"@img/sharp-wasm32": ["@img/sharp-wasm32@0.34.5", "", { "dependencies": { "@emnapi/runtime": "^1.7.0" }, "cpu": "none" }, "sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw=="],
|
|
77
|
+
|
|
78
|
+
"@img/sharp-win32-arm64": ["@img/sharp-win32-arm64@0.34.5", "", { "os": "win32", "cpu": "arm64" }, "sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g=="],
|
|
79
|
+
|
|
80
|
+
"@img/sharp-win32-ia32": ["@img/sharp-win32-ia32@0.34.5", "", { "os": "win32", "cpu": "ia32" }, "sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg=="],
|
|
81
|
+
|
|
82
|
+
"@img/sharp-win32-x64": ["@img/sharp-win32-x64@0.34.5", "", { "os": "win32", "cpu": "x64" }, "sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw=="],
|
|
83
|
+
|
|
84
|
+
"@next/env": ["@next/env@15.5.12", "", {}, "sha512-pUvdJN1on574wQHjaBfNGDt9Mz5utDSZFsIIQkMzPgNS8ZvT4H2mwOrOIClwsQOb6EGx5M76/CZr6G8i6pSpLg=="],
|
|
85
|
+
|
|
86
|
+
"@next/swc-darwin-arm64": ["@next/swc-darwin-arm64@15.5.12", "", { "os": "darwin", "cpu": "arm64" }, "sha512-RnRjBtH8S8eXCpUNkQ+543DUc7ys8y15VxmFU9HRqlo9BG3CcBUiwNtF8SNoi2xvGCVJq1vl2yYq+3oISBS0Zg=="],
|
|
87
|
+
|
|
88
|
+
"@next/swc-darwin-x64": ["@next/swc-darwin-x64@15.5.12", "", { "os": "darwin", "cpu": "x64" }, "sha512-nqa9/7iQlboF1EFtNhWxQA0rQstmYRSBGxSM6g3GxvxHxcoeqVXfGNr9stJOme674m2V7r4E3+jEhhGvSQhJRA=="],
|
|
89
|
+
|
|
90
|
+
"@next/swc-linux-arm64-gnu": ["@next/swc-linux-arm64-gnu@15.5.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-dCzAjqhDHwmoB2M4eYfVKqXs99QdQxNQVpftvP1eGVppamXh/OkDAwV737Zr0KPXEqRUMN4uCjh6mjO+XtF3Mw=="],
|
|
91
|
+
|
|
92
|
+
"@next/swc-linux-arm64-musl": ["@next/swc-linux-arm64-musl@15.5.12", "", { "os": "linux", "cpu": "arm64" }, "sha512-+fpGWvQiITgf7PUtbWY1H7qUSnBZsPPLyyq03QuAKpVoTy/QUx1JptEDTQMVvQhvizCEuNLEeghrQUyXQOekuw=="],
|
|
93
|
+
|
|
94
|
+
"@next/swc-linux-x64-gnu": ["@next/swc-linux-x64-gnu@15.5.12", "", { "os": "linux", "cpu": "x64" }, "sha512-jSLvgdRRL/hrFAPqEjJf1fFguC719kmcptjNVDJl26BnJIpjL3KH5h6mzR4mAweociLQaqvt4UyzfbFjgAdDcw=="],
|
|
95
|
+
|
|
96
|
+
"@next/swc-linux-x64-musl": ["@next/swc-linux-x64-musl@15.5.12", "", { "os": "linux", "cpu": "x64" }, "sha512-/uaF0WfmYqQgLfPmN6BvULwxY0dufI2mlN2JbOKqqceZh1G4hjREyi7pg03zjfyS6eqNemHAZPSoP84x17vo6w=="],
|
|
97
|
+
|
|
98
|
+
"@next/swc-win32-arm64-msvc": ["@next/swc-win32-arm64-msvc@15.5.12", "", { "os": "win32", "cpu": "arm64" }, "sha512-xhsL1OvQSfGmlL5RbOmU+FV120urrgFpYLq+6U8C6KIym32gZT6XF/SDE92jKzzlPWskkbjOKCpqk5m4i8PEfg=="],
|
|
99
|
+
|
|
100
|
+
"@next/swc-win32-x64-msvc": ["@next/swc-win32-x64-msvc@15.5.12", "", { "os": "win32", "cpu": "x64" }, "sha512-Z1Dh6lhFkxvBDH1FoW6OU/L6prYwPSlwjLiZkExIAh8fbP6iI/M7iGTQAJPYJ9YFlWobCZ1PHbchFhFYb2ADkw=="],
|
|
101
|
+
|
|
102
|
+
"@noble/ciphers": ["@noble/ciphers@1.3.0", "", {}, "sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw=="],
|
|
103
|
+
|
|
104
|
+
"@noble/curves": ["@noble/curves@1.9.1", "", { "dependencies": { "@noble/hashes": "1.8.0" } }, "sha512-k11yZxZg+t+gWvBbIswW0yoJlu8cHOC7dhunwOzoWH/mXGBiYyR4YY6hAEK/3EUs4UpB8la1RfdRpeGsFHkWsA=="],
|
|
105
|
+
|
|
106
|
+
"@noble/hashes": ["@noble/hashes@1.8.0", "", {}, "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A=="],
|
|
107
|
+
|
|
108
|
+
"@scure/base": ["@scure/base@1.2.6", "", {}, "sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg=="],
|
|
109
|
+
|
|
110
|
+
"@scure/bip32": ["@scure/bip32@1.7.0", "", { "dependencies": { "@noble/curves": "~1.9.0", "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-E4FFX/N3f4B80AKWp5dP6ow+flD1LQZo/w8UnLGYZO674jS6YnYeepycOOksv+vLPSpgN35wgKgy+ybfTb2SMw=="],
|
|
111
|
+
|
|
112
|
+
"@scure/bip39": ["@scure/bip39@1.6.0", "", { "dependencies": { "@noble/hashes": "~1.8.0", "@scure/base": "~1.2.5" } }, "sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A=="],
|
|
113
|
+
|
|
114
|
+
"@swc/helpers": ["@swc/helpers@0.5.15", "", { "dependencies": { "tslib": "^2.8.0" } }, "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g=="],
|
|
115
|
+
|
|
116
|
+
"@types/body-parser": ["@types/body-parser@1.19.6", "", { "dependencies": { "@types/connect": "*", "@types/node": "*" } }, "sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g=="],
|
|
117
|
+
|
|
118
|
+
"@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="],
|
|
119
|
+
|
|
120
|
+
"@types/connect": ["@types/connect@3.4.38", "", { "dependencies": { "@types/node": "*" } }, "sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug=="],
|
|
121
|
+
|
|
122
|
+
"@types/express": ["@types/express@5.0.6", "", { "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^5.0.0", "@types/serve-static": "^2" } }, "sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA=="],
|
|
123
|
+
|
|
124
|
+
"@types/express-serve-static-core": ["@types/express-serve-static-core@5.1.1", "", { "dependencies": { "@types/node": "*", "@types/qs": "*", "@types/range-parser": "*", "@types/send": "*" } }, "sha512-v4zIMr/cX7/d2BpAEX3KNKL/JrT1s43s96lLvvdTmza1oEvDudCqK9aF/djc/SWgy8Yh0h30TZx5VpzqFCxk5A=="],
|
|
125
|
+
|
|
126
|
+
"@types/http-errors": ["@types/http-errors@2.0.5", "", {}, "sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg=="],
|
|
127
|
+
|
|
128
|
+
"@types/node": ["@types/node@25.4.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-9wLpoeWuBlcbBpOY3XmzSTG3oscB6xjBEEtn+pYXTfhyXhIxC5FsBer2KTopBlvKEiW9l13po9fq+SJY/5lkhw=="],
|
|
129
|
+
|
|
130
|
+
"@types/qs": ["@types/qs@6.15.0", "", {}, "sha512-JawvT8iBVWpzTrz3EGw9BTQFg3BQNmwERdKE22vlTxawwtbyUSlMppvZYKLZzB5zgACXdXxbD3m1bXaMqP/9ow=="],
|
|
131
|
+
|
|
132
|
+
"@types/range-parser": ["@types/range-parser@1.2.7", "", {}, "sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ=="],
|
|
133
|
+
|
|
134
|
+
"@types/send": ["@types/send@1.2.1", "", { "dependencies": { "@types/node": "*" } }, "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ=="],
|
|
135
|
+
|
|
136
|
+
"@types/serve-static": ["@types/serve-static@2.2.0", "", { "dependencies": { "@types/http-errors": "*", "@types/node": "*" } }, "sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ=="],
|
|
137
|
+
|
|
138
|
+
"@x402/core": ["@x402/core@2.6.0", "", { "dependencies": { "zod": "^3.24.2" } }, "sha512-ISC/JeVss6xlKvor2rp18tJf9K5OQlIDDfZW1VZJQGDI2F4gy+HWxxkFfcQalCsPp4YUlwqh0YOkUxP+LTZWVg=="],
|
|
139
|
+
|
|
140
|
+
"abitype": ["abitype@1.2.3", "", { "peerDependencies": { "typescript": ">=5.0.4", "zod": "^3.22.0 || ^4.0.0" }, "optionalPeers": ["typescript", "zod"] }, "sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg=="],
|
|
141
|
+
|
|
142
|
+
"aes-js": ["aes-js@4.0.0-beta.5", "", {}, "sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q=="],
|
|
143
|
+
|
|
144
|
+
"asn1.js": ["asn1.js@4.10.1", "", { "dependencies": { "bn.js": "^4.0.0", "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" } }, "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw=="],
|
|
145
|
+
|
|
146
|
+
"available-typed-arrays": ["available-typed-arrays@1.0.7", "", { "dependencies": { "possible-typed-array-names": "^1.0.0" } }, "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ=="],
|
|
147
|
+
|
|
148
|
+
"bn.js": ["bn.js@5.2.3", "", {}, "sha512-EAcmnPkxpntVL+DS7bO1zhcZNvCkxqtkd0ZY53h06GNQ3DEkkGZ/gKgmDv6DdZQGj9BgfSPKtJJ7Dp1GPP8f7w=="],
|
|
149
|
+
|
|
150
|
+
"brorand": ["brorand@1.1.0", "", {}, "sha512-cKV8tMCEpQs4hK/ik71d6LrPOnpkpGBR0wzxqr68g2m/LB2GxVYQroAjMJZRVM1Y4BCjCKc3vAamxSzOY2RP+w=="],
|
|
151
|
+
|
|
152
|
+
"browserify-aes": ["browserify-aes@1.2.0", "", { "dependencies": { "buffer-xor": "^1.0.3", "cipher-base": "^1.0.0", "create-hash": "^1.1.0", "evp_bytestokey": "^1.0.3", "inherits": "^2.0.1", "safe-buffer": "^5.0.1" } }, "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA=="],
|
|
153
|
+
|
|
154
|
+
"browserify-cipher": ["browserify-cipher@1.0.1", "", { "dependencies": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", "evp_bytestokey": "^1.0.0" } }, "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w=="],
|
|
155
|
+
|
|
156
|
+
"browserify-des": ["browserify-des@1.0.2", "", { "dependencies": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" } }, "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A=="],
|
|
157
|
+
|
|
158
|
+
"browserify-rsa": ["browserify-rsa@4.1.1", "", { "dependencies": { "bn.js": "^5.2.1", "randombytes": "^2.1.0", "safe-buffer": "^5.2.1" } }, "sha512-YBjSAiTqM04ZVei6sXighu679a3SqWORA3qZTEqZImnlkDIFtKc6pNutpjyZ8RJTjQtuYfeetkxM11GwoYXMIQ=="],
|
|
159
|
+
|
|
160
|
+
"browserify-sign": ["browserify-sign@4.2.5", "", { "dependencies": { "bn.js": "^5.2.2", "browserify-rsa": "^4.1.1", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "elliptic": "^6.6.1", "inherits": "^2.0.4", "parse-asn1": "^5.1.9", "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1" } }, "sha512-C2AUdAJg6rlM2W5QMp2Q4KGQMVBwR1lIimTsUnutJ8bMpW5B52pGpR2gEnNBNwijumDo5FojQ0L9JrXA8m4YEw=="],
|
|
161
|
+
|
|
162
|
+
"buffer-xor": ["buffer-xor@1.0.3", "", {}, "sha512-571s0T7nZWK6vB67HI5dyUF7wXiNcfaPPPTl6zYCNApANjIvYJTg7hlud/+cJpdAhS7dVzqMLmfhfHR3rAcOjQ=="],
|
|
163
|
+
|
|
164
|
+
"bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="],
|
|
165
|
+
|
|
166
|
+
"call-bind": ["call-bind@1.0.8", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.0", "es-define-property": "^1.0.0", "get-intrinsic": "^1.2.4", "set-function-length": "^1.2.2" } }, "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww=="],
|
|
167
|
+
|
|
168
|
+
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
|
169
|
+
|
|
170
|
+
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
|
|
171
|
+
|
|
172
|
+
"caniuse-lite": ["caniuse-lite@1.0.30001778", "", {}, "sha512-PN7uxFL+ExFJO61aVmP1aIEG4i9whQd4eoSCebav62UwDyp5OHh06zN4jqKSMePVgxHifCw1QJxdRkA1Pisekg=="],
|
|
173
|
+
|
|
174
|
+
"cipher-base": ["cipher-base@1.0.7", "", { "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.2" } }, "sha512-Mz9QMT5fJe7bKI7MH31UilT5cEK5EHHRCccw/YRFsRY47AuNgaV6HY3rscp0/I4Q+tTW/5zoqpSeRRI54TkDWA=="],
|
|
175
|
+
|
|
176
|
+
"client-only": ["client-only@0.0.1", "", {}, "sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA=="],
|
|
177
|
+
|
|
178
|
+
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
|
|
179
|
+
|
|
180
|
+
"create-ecdh": ["create-ecdh@4.0.4", "", { "dependencies": { "bn.js": "^4.1.0", "elliptic": "^6.5.3" } }, "sha512-mf+TCx8wWc9VpuxfP2ht0iSISLZnt0JgWlrOKZiNqyUZWnjIaCIVNQArMHnCZKfEYRg6IM7A+NeJoN8gf/Ws0A=="],
|
|
181
|
+
|
|
182
|
+
"create-hash": ["create-hash@1.2.0", "", { "dependencies": { "cipher-base": "^1.0.1", "inherits": "^2.0.1", "md5.js": "^1.3.4", "ripemd160": "^2.0.1", "sha.js": "^2.4.0" } }, "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg=="],
|
|
183
|
+
|
|
184
|
+
"create-hmac": ["create-hmac@1.1.7", "", { "dependencies": { "cipher-base": "^1.0.3", "create-hash": "^1.1.0", "inherits": "^2.0.1", "ripemd160": "^2.0.0", "safe-buffer": "^5.0.1", "sha.js": "^2.4.8" } }, "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg=="],
|
|
185
|
+
|
|
186
|
+
"crypto-browserify": ["crypto-browserify@3.12.1", "", { "dependencies": { "browserify-cipher": "^1.0.1", "browserify-sign": "^4.2.3", "create-ecdh": "^4.0.4", "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "diffie-hellman": "^5.0.3", "hash-base": "~3.0.4", "inherits": "^2.0.4", "pbkdf2": "^3.1.2", "public-encrypt": "^4.0.3", "randombytes": "^2.1.0", "randomfill": "^1.0.4" } }, "sha512-r4ESw/IlusD17lgQi1O20Fa3qNnsckR126TdUuBgAu7GBYSIPvdNyONd3Zrxh0xCwA4+6w/TDArBPsMvhur+KQ=="],
|
|
187
|
+
|
|
188
|
+
"define-data-property": ["define-data-property@1.1.4", "", { "dependencies": { "es-define-property": "^1.0.0", "es-errors": "^1.3.0", "gopd": "^1.0.1" } }, "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A=="],
|
|
189
|
+
|
|
190
|
+
"des.js": ["des.js@1.1.0", "", { "dependencies": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" } }, "sha512-r17GxjhUCjSRy8aiJpr8/UadFIzMzJGexI3Nmz4ADi9LYSFx4gTBp80+NaX/YsXWWLhpZ7v/v/ubEc/bCNfKwg=="],
|
|
191
|
+
|
|
192
|
+
"detect-libc": ["detect-libc@2.1.2", "", {}, "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ=="],
|
|
193
|
+
|
|
194
|
+
"diffie-hellman": ["diffie-hellman@5.0.3", "", { "dependencies": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", "randombytes": "^2.0.0" } }, "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg=="],
|
|
195
|
+
|
|
196
|
+
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
|
197
|
+
|
|
198
|
+
"elliptic": ["elliptic@6.6.1", "", { "dependencies": { "bn.js": "^4.11.9", "brorand": "^1.1.0", "hash.js": "^1.0.0", "hmac-drbg": "^1.0.1", "inherits": "^2.0.4", "minimalistic-assert": "^1.0.1", "minimalistic-crypto-utils": "^1.0.1" } }, "sha512-RaddvvMatK2LJHqFJ+YA4WysVN5Ita9E35botqIYspQ4TkRAlCicdzKOjlyv/1Za5RyTNn7di//eEV0uTAfe3g=="],
|
|
199
|
+
|
|
200
|
+
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
|
201
|
+
|
|
202
|
+
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
|
203
|
+
|
|
204
|
+
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
|
|
205
|
+
|
|
206
|
+
"ethers": ["ethers@6.16.0", "", { "dependencies": { "@adraffy/ens-normalize": "1.10.1", "@noble/curves": "1.2.0", "@noble/hashes": "1.3.2", "@types/node": "22.7.5", "aes-js": "4.0.0-beta.5", "tslib": "2.7.0", "ws": "8.17.1" } }, "sha512-U1wulmetNymijEhpSEQ7Ct/P/Jw9/e7R1j5XIbPRydgV2DjLVMsULDlNksq3RQnFgKoLlZf88ijYtWEXcPa07A=="],
|
|
207
|
+
|
|
208
|
+
"eventemitter3": ["eventemitter3@5.0.1", "", {}, "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA=="],
|
|
209
|
+
|
|
210
|
+
"evp_bytestokey": ["evp_bytestokey@1.0.3", "", { "dependencies": { "md5.js": "^1.3.4", "safe-buffer": "^5.1.1" } }, "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA=="],
|
|
211
|
+
|
|
212
|
+
"for-each": ["for-each@0.3.5", "", { "dependencies": { "is-callable": "^1.2.7" } }, "sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg=="],
|
|
213
|
+
|
|
214
|
+
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
|
215
|
+
|
|
216
|
+
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
|
217
|
+
|
|
218
|
+
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
|
219
|
+
|
|
220
|
+
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
|
221
|
+
|
|
222
|
+
"has-property-descriptors": ["has-property-descriptors@1.0.2", "", { "dependencies": { "es-define-property": "^1.0.0" } }, "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg=="],
|
|
223
|
+
|
|
224
|
+
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
|
|
225
|
+
|
|
226
|
+
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
|
|
227
|
+
|
|
228
|
+
"hash-base": ["hash-base@3.0.5", "", { "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1" } }, "sha512-vXm0l45VbcHEVlTCzs8M+s0VeYsB2lnlAaThoLKGXr3bE/VWDOelNUnycUPEhKEaXARL2TEFjBOyUiM6+55KBg=="],
|
|
229
|
+
|
|
230
|
+
"hash.js": ["hash.js@1.1.7", "", { "dependencies": { "inherits": "^2.0.3", "minimalistic-assert": "^1.0.1" } }, "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA=="],
|
|
231
|
+
|
|
232
|
+
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
|
233
|
+
|
|
234
|
+
"hmac-drbg": ["hmac-drbg@1.0.1", "", { "dependencies": { "hash.js": "^1.0.3", "minimalistic-assert": "^1.0.0", "minimalistic-crypto-utils": "^1.0.1" } }, "sha512-Tti3gMqLdZfhOQY1Mzf/AanLiqh1WTiJgEj26ZuYQ9fbkLomzGchCws4FyrSd4VkpBfiNhaE1On+lOz894jvXg=="],
|
|
235
|
+
|
|
236
|
+
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
|
|
237
|
+
|
|
238
|
+
"is-callable": ["is-callable@1.2.7", "", {}, "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA=="],
|
|
239
|
+
|
|
240
|
+
"is-typed-array": ["is-typed-array@1.1.15", "", { "dependencies": { "which-typed-array": "^1.1.16" } }, "sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ=="],
|
|
241
|
+
|
|
242
|
+
"isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
|
|
243
|
+
|
|
244
|
+
"isows": ["isows@1.0.7", "", { "peerDependencies": { "ws": "*" } }, "sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg=="],
|
|
245
|
+
|
|
246
|
+
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
|
247
|
+
|
|
248
|
+
"md5.js": ["md5.js@1.3.5", "", { "dependencies": { "hash-base": "^3.0.0", "inherits": "^2.0.1", "safe-buffer": "^5.1.2" } }, "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg=="],
|
|
249
|
+
|
|
250
|
+
"miller-rabin": ["miller-rabin@4.0.1", "", { "dependencies": { "bn.js": "^4.0.0", "brorand": "^1.0.1" }, "bin": { "miller-rabin": "bin/miller-rabin" } }, "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA=="],
|
|
251
|
+
|
|
252
|
+
"minimalistic-assert": ["minimalistic-assert@1.0.1", "", {}, "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A=="],
|
|
253
|
+
|
|
254
|
+
"minimalistic-crypto-utils": ["minimalistic-crypto-utils@1.0.1", "", {}, "sha512-JIYlbt6g8i5jKfJ3xz7rF0LXmv2TkDxBLUkiBeZ7bAx4GnnNMr8xFpGnOxn6GhTEHx3SjRrZEoU+j04prX1ktg=="],
|
|
255
|
+
|
|
256
|
+
"nanoid": ["nanoid@3.3.11", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w=="],
|
|
257
|
+
|
|
258
|
+
"next": ["next@15.5.12", "", { "dependencies": { "@next/env": "15.5.12", "@swc/helpers": "0.5.15", "caniuse-lite": "^1.0.30001579", "postcss": "8.4.31", "styled-jsx": "5.1.6" }, "optionalDependencies": { "@next/swc-darwin-arm64": "15.5.12", "@next/swc-darwin-x64": "15.5.12", "@next/swc-linux-arm64-gnu": "15.5.12", "@next/swc-linux-arm64-musl": "15.5.12", "@next/swc-linux-x64-gnu": "15.5.12", "@next/swc-linux-x64-musl": "15.5.12", "@next/swc-win32-arm64-msvc": "15.5.12", "@next/swc-win32-x64-msvc": "15.5.12", "sharp": "^0.34.3" }, "peerDependencies": { "@opentelemetry/api": "^1.1.0", "@playwright/test": "^1.51.1", "babel-plugin-react-compiler": "*", "react": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "react-dom": "^18.2.0 || 19.0.0-rc-de68d2f4-20241204 || ^19.0.0", "sass": "^1.3.0" }, "optionalPeers": ["@opentelemetry/api", "@playwright/test", "babel-plugin-react-compiler", "sass"], "bin": { "next": "dist/bin/next" } }, "sha512-Fi/wQ4Etlrn60rz78bebG1i1SR20QxvV8tVp6iJspjLUSHcZoeUXCt+vmWoEcza85ElZzExK/jJ/F6SvtGktjA=="],
|
|
259
|
+
|
|
260
|
+
"ox": ["ox@0.14.0", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.2.3", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-WLOB7IKnmI3Ol6RAqY7CJdZKl8QaI44LN91OGF1061YIeN6bL5IsFcdp7+oQShRyamE/8fW/CBRWhJAOzI35Dw=="],
|
|
261
|
+
|
|
262
|
+
"parse-asn1": ["parse-asn1@5.1.9", "", { "dependencies": { "asn1.js": "^4.10.1", "browserify-aes": "^1.2.0", "evp_bytestokey": "^1.0.3", "pbkdf2": "^3.1.5", "safe-buffer": "^5.2.1" } }, "sha512-fIYNuZ/HastSb80baGOuPRo1O9cf4baWw5WsAp7dBuUzeTD/BoaG8sVTdlPFksBE2lF21dN+A1AnrpIjSWqHHg=="],
|
|
263
|
+
|
|
264
|
+
"pbkdf2": ["pbkdf2@3.1.5", "", { "dependencies": { "create-hash": "^1.2.0", "create-hmac": "^1.1.7", "ripemd160": "^2.0.3", "safe-buffer": "^5.2.1", "sha.js": "^2.4.12", "to-buffer": "^1.2.1" } }, "sha512-Q3CG/cYvCO1ye4QKkuH7EXxs3VC/rI1/trd+qX2+PolbaKG0H+bgcZzrTt96mMyRtejk+JMCiLUn3y29W8qmFQ=="],
|
|
265
|
+
|
|
266
|
+
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
|
267
|
+
|
|
268
|
+
"possible-typed-array-names": ["possible-typed-array-names@1.1.0", "", {}, "sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg=="],
|
|
269
|
+
|
|
270
|
+
"postcss": ["postcss@8.4.31", "", { "dependencies": { "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } }, "sha512-PS08Iboia9mts/2ygV3eLpY5ghnUcfLV/EXTOW1E2qYxJKGGBUtNjN76FYHnMs36RmARn41bC0AZmn+rR0OVpQ=="],
|
|
271
|
+
|
|
272
|
+
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
|
|
273
|
+
|
|
274
|
+
"public-encrypt": ["public-encrypt@4.0.3", "", { "dependencies": { "bn.js": "^4.1.0", "browserify-rsa": "^4.0.0", "create-hash": "^1.1.0", "parse-asn1": "^5.0.0", "randombytes": "^2.0.1", "safe-buffer": "^5.1.2" } }, "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q=="],
|
|
275
|
+
|
|
276
|
+
"randombytes": ["randombytes@2.1.0", "", { "dependencies": { "safe-buffer": "^5.1.0" } }, "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ=="],
|
|
277
|
+
|
|
278
|
+
"randomfill": ["randomfill@1.0.4", "", { "dependencies": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" } }, "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw=="],
|
|
279
|
+
|
|
280
|
+
"react": ["react@19.2.4", "", {}, "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ=="],
|
|
281
|
+
|
|
282
|
+
"react-dom": ["react-dom@19.2.4", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
|
|
283
|
+
|
|
284
|
+
"readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
|
|
285
|
+
|
|
286
|
+
"ripemd160": ["ripemd160@2.0.3", "", { "dependencies": { "hash-base": "^3.1.2", "inherits": "^2.0.4" } }, "sha512-5Di9UC0+8h1L6ZD2d7awM7E/T4uA1fJRlx6zk/NvdCCVEoAnFqvHmCuNeIKoCeIixBX/q8uM+6ycDvF8woqosA=="],
|
|
287
|
+
|
|
288
|
+
"safe-buffer": ["safe-buffer@5.2.1", "", {}, "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ=="],
|
|
289
|
+
|
|
290
|
+
"scheduler": ["scheduler@0.27.0", "", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
|
291
|
+
|
|
292
|
+
"semver": ["semver@7.7.4", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA=="],
|
|
293
|
+
|
|
294
|
+
"set-function-length": ["set-function-length@1.2.2", "", { "dependencies": { "define-data-property": "^1.1.4", "es-errors": "^1.3.0", "function-bind": "^1.1.2", "get-intrinsic": "^1.2.4", "gopd": "^1.0.1", "has-property-descriptors": "^1.0.2" } }, "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg=="],
|
|
295
|
+
|
|
296
|
+
"sha.js": ["sha.js@2.4.12", "", { "dependencies": { "inherits": "^2.0.4", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.0" }, "bin": { "sha.js": "bin.js" } }, "sha512-8LzC5+bvI45BjpfXU8V5fdU2mfeKiQe1D1gIMn7XUlF3OTUrpdJpPPH4EMAnF0DsHHdSZqCdSss5qCmJKuiO3w=="],
|
|
297
|
+
|
|
298
|
+
"sharp": ["sharp@0.34.5", "", { "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", "semver": "^7.7.3" }, "optionalDependencies": { "@img/sharp-darwin-arm64": "0.34.5", "@img/sharp-darwin-x64": "0.34.5", "@img/sharp-libvips-darwin-arm64": "1.2.4", "@img/sharp-libvips-darwin-x64": "1.2.4", "@img/sharp-libvips-linux-arm": "1.2.4", "@img/sharp-libvips-linux-arm64": "1.2.4", "@img/sharp-libvips-linux-ppc64": "1.2.4", "@img/sharp-libvips-linux-riscv64": "1.2.4", "@img/sharp-libvips-linux-s390x": "1.2.4", "@img/sharp-libvips-linux-x64": "1.2.4", "@img/sharp-libvips-linuxmusl-arm64": "1.2.4", "@img/sharp-libvips-linuxmusl-x64": "1.2.4", "@img/sharp-linux-arm": "0.34.5", "@img/sharp-linux-arm64": "0.34.5", "@img/sharp-linux-ppc64": "0.34.5", "@img/sharp-linux-riscv64": "0.34.5", "@img/sharp-linux-s390x": "0.34.5", "@img/sharp-linux-x64": "0.34.5", "@img/sharp-linuxmusl-arm64": "0.34.5", "@img/sharp-linuxmusl-x64": "0.34.5", "@img/sharp-wasm32": "0.34.5", "@img/sharp-win32-arm64": "0.34.5", "@img/sharp-win32-ia32": "0.34.5", "@img/sharp-win32-x64": "0.34.5" } }, "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg=="],
|
|
299
|
+
|
|
300
|
+
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
|
|
301
|
+
|
|
302
|
+
"string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
|
|
303
|
+
|
|
304
|
+
"styled-jsx": ["styled-jsx@5.1.6", "", { "dependencies": { "client-only": "0.0.1" }, "peerDependencies": { "react": ">= 16.8.0 || 17.x.x || ^18.0.0-0 || ^19.0.0-0" } }, "sha512-qSVyDTeMotdvQYoHWLNGwRFJHC+i+ZvdBRYosOFgC+Wg1vx4frN2/RG/NA7SYqqvKNLf39P2LSRA2pu6n0XYZA=="],
|
|
305
|
+
|
|
306
|
+
"to-buffer": ["to-buffer@1.2.2", "", { "dependencies": { "isarray": "^2.0.5", "safe-buffer": "^5.2.1", "typed-array-buffer": "^1.0.3" } }, "sha512-db0E3UJjcFhpDhAF4tLo03oli3pwl3dbnzXOUIlRKrp+ldk/VUxzpWYZENsw2SZiuBjHAk7DfB0VU7NKdpb6sw=="],
|
|
307
|
+
|
|
308
|
+
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
|
309
|
+
|
|
310
|
+
"typed-array-buffer": ["typed-array-buffer@1.0.3", "", { "dependencies": { "call-bound": "^1.0.3", "es-errors": "^1.3.0", "is-typed-array": "^1.1.14" } }, "sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw=="],
|
|
311
|
+
|
|
312
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
313
|
+
|
|
314
|
+
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
|
315
|
+
|
|
316
|
+
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
|
|
317
|
+
|
|
318
|
+
"viem": ["viem@2.47.2", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", "ox": "0.14.0", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-etDIwDgmDiGaPg8rUbJtUFuC3/nAJCbhMYyfh5dOcqNNkzBWTNcS2VluPSM5JVo+9U3b2hle2RkBEq3+xyvlvg=="],
|
|
319
|
+
|
|
320
|
+
"which-typed-array": ["which-typed-array@1.1.20", "", { "dependencies": { "available-typed-arrays": "^1.0.7", "call-bind": "^1.0.8", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2" } }, "sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg=="],
|
|
321
|
+
|
|
322
|
+
"ws": ["ws@8.18.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg=="],
|
|
323
|
+
|
|
324
|
+
"zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
|
|
325
|
+
|
|
326
|
+
"@evvm/evvm-js/viem": ["viem@2.45.0", "", { "dependencies": { "@noble/curves": "1.9.1", "@noble/hashes": "1.8.0", "@scure/bip32": "1.7.0", "@scure/bip39": "1.6.0", "abitype": "1.2.3", "isows": "1.0.7", "ox": "0.11.3", "ws": "8.18.3" }, "peerDependencies": { "typescript": ">=5.0.4" }, "optionalPeers": ["typescript"] }, "sha512-iVA9qrAgRdtpWa80lCZ6Jri6XzmLOwwA1wagX2HnKejKeliFLpON0KOdyfqvcy+gUpBVP59LBxP2aKiL3aj8fg=="],
|
|
327
|
+
|
|
328
|
+
"@x402/core/zod": ["zod@3.25.76", "", {}, "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ=="],
|
|
329
|
+
|
|
330
|
+
"asn1.js/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="],
|
|
331
|
+
|
|
332
|
+
"create-ecdh/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="],
|
|
333
|
+
|
|
334
|
+
"diffie-hellman/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="],
|
|
335
|
+
|
|
336
|
+
"elliptic/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="],
|
|
337
|
+
|
|
338
|
+
"ethers/@noble/curves": ["@noble/curves@1.2.0", "", { "dependencies": { "@noble/hashes": "1.3.2" } }, "sha512-oYclrNgRaM9SsBUBVbb8M6DTV7ZHRTKugureoYEncY5c65HOmRzvSiTE3y5CYaPYJA/GVkrhXEoF0M3Ya9PMnw=="],
|
|
339
|
+
|
|
340
|
+
"ethers/@noble/hashes": ["@noble/hashes@1.3.2", "", {}, "sha512-MVC8EAQp7MvEcm30KWENFjgR+Mkmf+D189XJTkFIlwohU5hcBbn1ZkKq7KVTi2Hme3PMGF390DaL52beVrIihQ=="],
|
|
341
|
+
|
|
342
|
+
"ethers/@types/node": ["@types/node@22.7.5", "", { "dependencies": { "undici-types": "~6.19.2" } }, "sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ=="],
|
|
343
|
+
|
|
344
|
+
"ethers/tslib": ["tslib@2.7.0", "", {}, "sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA=="],
|
|
345
|
+
|
|
346
|
+
"ethers/ws": ["ws@8.17.1", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ=="],
|
|
347
|
+
|
|
348
|
+
"md5.js/hash-base": ["hash-base@3.1.2", "", { "dependencies": { "inherits": "^2.0.4", "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.1" } }, "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg=="],
|
|
349
|
+
|
|
350
|
+
"miller-rabin/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="],
|
|
351
|
+
|
|
352
|
+
"ox/@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="],
|
|
353
|
+
|
|
354
|
+
"public-encrypt/bn.js": ["bn.js@4.12.3", "", {}, "sha512-fGTi3gxV/23FTYdAoUtLYp6qySe2KE3teyZitipKNRuVYcBkoP/bB3guXN/XVKUe9mxCHXnc9C4ocyz8OmgN0g=="],
|
|
355
|
+
|
|
356
|
+
"readable-stream/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
|
|
357
|
+
|
|
358
|
+
"ripemd160/hash-base": ["hash-base@3.1.2", "", { "dependencies": { "inherits": "^2.0.4", "readable-stream": "^2.3.8", "safe-buffer": "^5.2.1", "to-buffer": "^1.2.1" } }, "sha512-Bb33KbowVTIj5s7Ked1OsqHUeCpz//tPwR+E2zJgJKo9Z5XolZ9b6bdUgjmYlwnWhoOQKoTd1TYToZGn5mAYOg=="],
|
|
359
|
+
|
|
360
|
+
"string_decoder/safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
|
|
361
|
+
|
|
362
|
+
"to-buffer/isarray": ["isarray@2.0.5", "", {}, "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw=="],
|
|
363
|
+
|
|
364
|
+
"@evvm/evvm-js/viem/ox": ["ox@0.11.3", "", { "dependencies": { "@adraffy/ens-normalize": "^1.11.0", "@noble/ciphers": "^1.3.0", "@noble/curves": "1.9.1", "@noble/hashes": "^1.8.0", "@scure/bip32": "^1.7.0", "@scure/bip39": "^1.6.0", "abitype": "^1.2.3", "eventemitter3": "5.0.1" }, "peerDependencies": { "typescript": ">=5.4.0" }, "optionalPeers": ["typescript"] }, "sha512-1bWYGk/xZel3xro3l8WGg6eq4YEKlaqvyMtVhfMFpbJzK2F6rj4EDRtqDCWVEJMkzcmEi9uW2QxsqELokOlarw=="],
|
|
365
|
+
|
|
366
|
+
"ethers/@types/node/undici-types": ["undici-types@6.19.8", "", {}, "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw=="],
|
|
367
|
+
|
|
368
|
+
"@evvm/evvm-js/viem/ox/@adraffy/ens-normalize": ["@adraffy/ens-normalize@1.11.1", "", {}, "sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ=="],
|
|
369
|
+
}
|
|
370
|
+
}
|
package/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
console.log("Hello via Bun!");
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@evvm/x402",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"module": "index.ts",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"devDependencies": {
|
|
7
|
+
"@types/bun": "latest",
|
|
8
|
+
"@types/express": "^5.0.6",
|
|
9
|
+
"next": "^15.0.0",
|
|
10
|
+
"typescript": "^5"
|
|
11
|
+
},
|
|
12
|
+
"peerDependencies": {
|
|
13
|
+
"next": ">=15"
|
|
14
|
+
},
|
|
15
|
+
"peerDependenciesMeta": {
|
|
16
|
+
"next": {
|
|
17
|
+
"optional": true
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"dependencies": {
|
|
21
|
+
"@evvm/evvm-js": "0.1.27",
|
|
22
|
+
"@x402/core": "^2.6.0",
|
|
23
|
+
"viem": "^2.47.2",
|
|
24
|
+
"zod": "^4.3.6"
|
|
25
|
+
}
|
|
26
|
+
}
|
package/src/index.ts
ADDED
package/src/lib/index.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Core,
|
|
3
|
+
execute,
|
|
4
|
+
type HexString,
|
|
5
|
+
type IPayData,
|
|
6
|
+
type ISerializableSignedAction,
|
|
7
|
+
type ISigner,
|
|
8
|
+
} from "@evvm/evvm-js";
|
|
9
|
+
import { recoverMessageAddress } from "viem";
|
|
10
|
+
import type { IFacilitator } from "../types";
|
|
11
|
+
|
|
12
|
+
export class LocalFacilitator implements IFacilitator {
|
|
13
|
+
constructor(public signer: ISigner) {}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Reconstructs the signed message and recovers the signer from the signature provided
|
|
17
|
+
* to validate it. Asserts the nonce provided is valid.
|
|
18
|
+
* @returns true if the recovered address match signedAction.data.from; false otherwise
|
|
19
|
+
*/
|
|
20
|
+
async verifyPaySignature(
|
|
21
|
+
signedAction: ISerializableSignedAction<IPayData>,
|
|
22
|
+
): Promise<boolean> {
|
|
23
|
+
if (signedAction.functionName !== "pay")
|
|
24
|
+
throw new Error("verifyPaySignature can only verify core.pay signatures");
|
|
25
|
+
|
|
26
|
+
const core = new Core({
|
|
27
|
+
address: signedAction.contractAddress as HexString,
|
|
28
|
+
signer: this.signer,
|
|
29
|
+
chainId: signedAction.chainId,
|
|
30
|
+
});
|
|
31
|
+
// replicate signed message
|
|
32
|
+
const evvmId = await core.getEvvmID();
|
|
33
|
+
const hashPayload = core.buildHashPayload(signedAction.functionName, {
|
|
34
|
+
to_address: signedAction.data.to_address,
|
|
35
|
+
to_identity: signedAction.data.to_identity,
|
|
36
|
+
token: signedAction.data.token,
|
|
37
|
+
amount: signedAction.data.amount,
|
|
38
|
+
priorityFee: signedAction.data.priorityFee,
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const message = core.buildMessageToSign(
|
|
42
|
+
evvmId,
|
|
43
|
+
signedAction.data.senderExecutor,
|
|
44
|
+
hashPayload,
|
|
45
|
+
signedAction.data.originExecutor,
|
|
46
|
+
signedAction.data.nonce,
|
|
47
|
+
signedAction.data.isAsyncExec,
|
|
48
|
+
);
|
|
49
|
+
|
|
50
|
+
// recover signer of the message
|
|
51
|
+
const address = await recoverMessageAddress({
|
|
52
|
+
message,
|
|
53
|
+
signature: signedAction.data.signature as HexString,
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
if (address !== signedAction.data.from) {
|
|
57
|
+
console.error("Couldn't recover address from signature");
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// verify nonces are ok
|
|
62
|
+
if (signedAction.data.isAsyncExec) {
|
|
63
|
+
// async execution, assert nonce hasn't been used before
|
|
64
|
+
const used = await core.getIfUsedAsyncNonce(signedAction.data.nonce);
|
|
65
|
+
if (used) {
|
|
66
|
+
console.error("Invalid async nonce");
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
} else {
|
|
70
|
+
const nextExpectedNonce = await core.getNextCurrentSyncNonce();
|
|
71
|
+
if (nextExpectedNonce.toString() != signedAction.data.nonce.toString()) {
|
|
72
|
+
console.error("Invalid sync nonce");
|
|
73
|
+
return false;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// assert balances
|
|
78
|
+
const balance = await core.getBalance(
|
|
79
|
+
signedAction.data.from,
|
|
80
|
+
signedAction.data.token,
|
|
81
|
+
);
|
|
82
|
+
if (balance <= signedAction.data.amount) {
|
|
83
|
+
console.error("Insufficient balance");
|
|
84
|
+
return false;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return true;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Executes the evvm transaction.
|
|
92
|
+
* @returns tx hash
|
|
93
|
+
*/
|
|
94
|
+
async settlePayment(
|
|
95
|
+
signedAction: ISerializableSignedAction<IPayData>,
|
|
96
|
+
): Promise<HexString | null> {
|
|
97
|
+
try {
|
|
98
|
+
const txHash = await execute(this.signer, signedAction);
|
|
99
|
+
return txHash;
|
|
100
|
+
} catch (error) {
|
|
101
|
+
console.error("Failed to settle payment");
|
|
102
|
+
console.error(error);
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PaymentPayloadV2Schema,
|
|
3
|
+
type PaymentPayloadV2,
|
|
4
|
+
} from "@x402/core/schemas";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Parses the PAYMENT-SIGNATURE header into PaymentPayloadV2 from x402/core
|
|
8
|
+
* @returns PaymentPayloadV2 if it's a valid payload, null otherwise
|
|
9
|
+
*/
|
|
10
|
+
export const parseHeader = (
|
|
11
|
+
paymentSignatureHeader: string,
|
|
12
|
+
): PaymentPayloadV2 | null => {
|
|
13
|
+
// decode header (it's a base64 encoded string)
|
|
14
|
+
const decodedString = Buffer.from(paymentSignatureHeader, "base64").toString(
|
|
15
|
+
"utf-8",
|
|
16
|
+
);
|
|
17
|
+
|
|
18
|
+
// assert it has the correct schema
|
|
19
|
+
let payload = null;
|
|
20
|
+
try {
|
|
21
|
+
payload = PaymentPayloadV2Schema.parse(JSON.parse(decodedString));
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error("Failed to parse payment payload");
|
|
24
|
+
console.error(error);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return payload;
|
|
29
|
+
};
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { type SettleResponse } from "@x402/core/types";
|
|
2
|
+
import { type PaymentRequirementsV2 } from "@x402/core/schemas";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Creates the 402 payment required response, with headers, amounts and
|
|
6
|
+
* everything else needed, returns the actual response (this should go directly to
|
|
7
|
+
* the user)
|
|
8
|
+
*/
|
|
9
|
+
export const paymentRequiredResponse = (
|
|
10
|
+
offers: PaymentRequirementsV2[],
|
|
11
|
+
): Response => {
|
|
12
|
+
const jsonString = JSON.stringify({ offers });
|
|
13
|
+
const base64Payload = Buffer.from(jsonString).toString("base64");
|
|
14
|
+
|
|
15
|
+
const headers = new Headers();
|
|
16
|
+
headers.set("PAYMENT-REQUIRED", base64Payload);
|
|
17
|
+
headers.set("Access-Control-Expose-Headers", "PAYMENT-REQUIRED"); // Vital for CORS
|
|
18
|
+
headers.set("Content-Type", "application/json");
|
|
19
|
+
|
|
20
|
+
console.log("Payment required");
|
|
21
|
+
|
|
22
|
+
return new Response("Payment Required", { headers, status: 402 });
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Returned when an invalid response is received
|
|
27
|
+
*/
|
|
28
|
+
export const invalidPaymentResponse = (reason: string): Response => {
|
|
29
|
+
const settleResponse: SettleResponse = {
|
|
30
|
+
success: false,
|
|
31
|
+
errorMessage: "Invalid Payment",
|
|
32
|
+
errorReason: reason,
|
|
33
|
+
transaction: "",
|
|
34
|
+
network: ":",
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
const jsonString = JSON.stringify(settleResponse);
|
|
38
|
+
const base64Payload = Buffer.from(jsonString).toString("base64");
|
|
39
|
+
|
|
40
|
+
const headers = new Headers();
|
|
41
|
+
headers.set("PAYMENT-RESPONSE", base64Payload);
|
|
42
|
+
|
|
43
|
+
console.log("Payment invalid");
|
|
44
|
+
return new Response(`Payment Invalid: ${reason}`, { status: 400, headers });
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
// export const successfulPaymentResponse = (
|
|
48
|
+
// txHash: HexString,
|
|
49
|
+
// payload: IPaymentPayload,
|
|
50
|
+
// ) => {
|
|
51
|
+
// const settleResponse: SettleResponse = {
|
|
52
|
+
// success: true,
|
|
53
|
+
// payer: payload.payload.data.from,
|
|
54
|
+
// transaction: txHash,
|
|
55
|
+
// network: payload.accepted.network as "${string}:${string}",
|
|
56
|
+
// };
|
|
57
|
+
//
|
|
58
|
+
// const jsonString = JSON.stringify(settleResponse);
|
|
59
|
+
// const base64Payload = Buffer.from(jsonString).toString("base64");
|
|
60
|
+
// const headers = new Headers();
|
|
61
|
+
// headers.set("PAYMENT-REQUIRED", base64Payload);
|
|
62
|
+
//
|
|
63
|
+
// return new Response("Payment Required", { headers, status: 402 });
|
|
64
|
+
// };
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
NextFunction,
|
|
3
|
+
Request as ExpressRequest,
|
|
4
|
+
Response as ExpressResponse,
|
|
5
|
+
} from "express";
|
|
6
|
+
import type { IEvvmSchema, IFacilitator } from "../types";
|
|
7
|
+
import {
|
|
8
|
+
invalidPaymentResponse,
|
|
9
|
+
parseHeader,
|
|
10
|
+
paymentRequiredResponse,
|
|
11
|
+
} from "../lib";
|
|
12
|
+
import {
|
|
13
|
+
getSerializableSignedActionSchema,
|
|
14
|
+
PayDataSchema,
|
|
15
|
+
} from "@evvm/evvm-js";
|
|
16
|
+
import type { SettleResponse } from "@x402/core/types";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* This is used to parse Web API Response objects to express compatible
|
|
20
|
+
* responses
|
|
21
|
+
*/
|
|
22
|
+
const handleWebResponse = async (res: ExpressResponse, webRes: Response) => {
|
|
23
|
+
res.status(webRes.status);
|
|
24
|
+
webRes.headers.forEach((value, key) => {
|
|
25
|
+
res.setHeader(key, value);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
const body = await webRes.text();
|
|
29
|
+
res.send(body);
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* ExpressJS middleware that expects EVVM payments
|
|
34
|
+
*/
|
|
35
|
+
export const requireEvvmPaymentExpress =
|
|
36
|
+
(facilitator: IFacilitator, offers: IEvvmSchema[]) =>
|
|
37
|
+
async (req: ExpressRequest, res: ExpressResponse, next: NextFunction) => {
|
|
38
|
+
// assert payment is present
|
|
39
|
+
const paymentHeader = req.header("PAYMENT-SIGNATURE");
|
|
40
|
+
// if not present, return payment required
|
|
41
|
+
if (!paymentHeader)
|
|
42
|
+
return handleWebResponse(res, paymentRequiredResponse(offers));
|
|
43
|
+
|
|
44
|
+
// if present, parse and validate it
|
|
45
|
+
const parsed = parseHeader(paymentHeader);
|
|
46
|
+
if (!parsed) {
|
|
47
|
+
return handleWebResponse(res, invalidPaymentResponse("Invalid payment"));
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const { success, data: signedAction } = getSerializableSignedActionSchema(
|
|
51
|
+
PayDataSchema,
|
|
52
|
+
).safeParse(parsed.payload);
|
|
53
|
+
|
|
54
|
+
if (!success) {
|
|
55
|
+
return handleWebResponse(
|
|
56
|
+
res,
|
|
57
|
+
invalidPaymentResponse("Not an evvm payment"),
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// verify it
|
|
62
|
+
if (!(await facilitator.verifyPaySignature(signedAction))) {
|
|
63
|
+
return handleWebResponse(
|
|
64
|
+
res,
|
|
65
|
+
invalidPaymentResponse("Invalid signature"),
|
|
66
|
+
);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// settle it
|
|
70
|
+
const txHash = await facilitator.settlePayment(signedAction);
|
|
71
|
+
|
|
72
|
+
if (!txHash) {
|
|
73
|
+
return handleWebResponse(
|
|
74
|
+
res,
|
|
75
|
+
invalidPaymentResponse("Settlement failed"),
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const settleResponse: SettleResponse = {
|
|
80
|
+
success: true,
|
|
81
|
+
payer: signedAction.data.from,
|
|
82
|
+
transaction: txHash,
|
|
83
|
+
network: parsed.accepted.network as `${string}:${string}`,
|
|
84
|
+
};
|
|
85
|
+
|
|
86
|
+
const jsonString = JSON.stringify(settleResponse);
|
|
87
|
+
const base64Payload = Buffer.from(jsonString).toString("base64");
|
|
88
|
+
|
|
89
|
+
res.setHeader("PAYMENT-RESPONSE", base64Payload);
|
|
90
|
+
|
|
91
|
+
next();
|
|
92
|
+
};
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import type { NextRequest } from "next/server";
|
|
2
|
+
import type { IEvvmSchema, IFacilitator } from "../types";
|
|
3
|
+
import { invalidPaymentResponse, paymentRequiredResponse } from "../lib";
|
|
4
|
+
import {
|
|
5
|
+
getSerializableSignedActionSchema,
|
|
6
|
+
PayDataSchema,
|
|
7
|
+
} from "@evvm/evvm-js";
|
|
8
|
+
import type { SettleResponse } from "@x402/core/types";
|
|
9
|
+
import {
|
|
10
|
+
PaymentPayloadV2Schema,
|
|
11
|
+
type PaymentPayloadV2,
|
|
12
|
+
} from "@x402/core/schemas";
|
|
13
|
+
|
|
14
|
+
const parseHeaderEdge = (
|
|
15
|
+
paymentSignatureHeader: string,
|
|
16
|
+
): PaymentPayloadV2 | null => {
|
|
17
|
+
const decodedString = atob(paymentSignatureHeader);
|
|
18
|
+
|
|
19
|
+
let payload = null;
|
|
20
|
+
try {
|
|
21
|
+
payload = PaymentPayloadV2Schema.parse(JSON.parse(decodedString));
|
|
22
|
+
} catch (error) {
|
|
23
|
+
console.error("Failed to parse payment payload");
|
|
24
|
+
console.error(error);
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return payload;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Creates a payment required middleware for nextjs
|
|
33
|
+
*/
|
|
34
|
+
export const createEvvmMiddlewareNext =
|
|
35
|
+
(facilitator: IFacilitator, offers: IEvvmSchema[]) =>
|
|
36
|
+
async (req: NextRequest) => {
|
|
37
|
+
const paymentHeader = req.headers.get("PAYMENT-SIGNATURE");
|
|
38
|
+
|
|
39
|
+
if (!paymentHeader) {
|
|
40
|
+
return paymentRequiredResponse(offers);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
const parsed = parseHeaderEdge(paymentHeader);
|
|
44
|
+
if (!parsed) {
|
|
45
|
+
return invalidPaymentResponse("Invalid payment");
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const { success, data: signedAction } = getSerializableSignedActionSchema(
|
|
49
|
+
PayDataSchema,
|
|
50
|
+
).safeParse(parsed.payload);
|
|
51
|
+
|
|
52
|
+
if (!success) {
|
|
53
|
+
return invalidPaymentResponse("Not an evvm payment");
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (!(await facilitator.verifyPaySignature(signedAction))) {
|
|
57
|
+
return invalidPaymentResponse("Invalid signature");
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
const txHash = await facilitator.settlePayment(signedAction);
|
|
61
|
+
|
|
62
|
+
if (!txHash) {
|
|
63
|
+
return invalidPaymentResponse("Settlement failed");
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const settleResponse: SettleResponse = {
|
|
67
|
+
success: true,
|
|
68
|
+
payer: signedAction.data.from,
|
|
69
|
+
transaction: txHash,
|
|
70
|
+
network: parsed.accepted.network as `${string}:${string}`,
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
const jsonString = JSON.stringify(settleResponse);
|
|
74
|
+
const base64Payload = btoa(jsonString);
|
|
75
|
+
|
|
76
|
+
req.headers.set("PAYMENT-RESPONSE", base64Payload);
|
|
77
|
+
};
|
|
78
|
+
|
|
79
|
+
export default createEvvmMiddlewareNext;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { type HexString } from "@evvm/evvm-js";
|
|
2
|
+
import { type PaymentRequirements } from "@x402/core/types";
|
|
3
|
+
|
|
4
|
+
export interface IEvvmSchema extends PaymentRequirements {
|
|
5
|
+
scheme: "evvm";
|
|
6
|
+
network: `eip155:${number}`;
|
|
7
|
+
amount: string;
|
|
8
|
+
asset: HexString;
|
|
9
|
+
payTo: string;
|
|
10
|
+
maxTimeoutSeconds: number;
|
|
11
|
+
/**
|
|
12
|
+
* Custom metadata for successful evvm signature construction
|
|
13
|
+
*/
|
|
14
|
+
extra: {
|
|
15
|
+
coreContractAddress: HexString;
|
|
16
|
+
evvmId?: number;
|
|
17
|
+
originExecutor?: HexString;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
HexString,
|
|
3
|
+
IPayData,
|
|
4
|
+
ISerializableSignedAction,
|
|
5
|
+
} from "@evvm/evvm-js";
|
|
6
|
+
|
|
7
|
+
export interface IFacilitator {
|
|
8
|
+
verifyPaySignature(
|
|
9
|
+
signedAction: ISerializableSignedAction<IPayData>,
|
|
10
|
+
): Promise<boolean>;
|
|
11
|
+
|
|
12
|
+
settlePayment(
|
|
13
|
+
signedAction: ISerializableSignedAction<IPayData>,
|
|
14
|
+
): Promise<HexString | null>;
|
|
15
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { IPayData, ISerializableSignedAction } from "@evvm/evvm-js";
|
|
2
|
+
import type { IEvvmSchema } from "./evvm-schema.type";
|
|
3
|
+
import { type PaymentPayloadV2 } from "@x402/core/schemas";
|
|
4
|
+
|
|
5
|
+
export interface IPaymentPayload extends PaymentPayloadV2 {
|
|
6
|
+
accepted: IEvvmSchema;
|
|
7
|
+
// crucial, this includes everything needed to execute a pay transaction
|
|
8
|
+
payload: ISerializableSignedAction<IPayData>;
|
|
9
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// Environment setup & latest features
|
|
4
|
+
"lib": ["ESNext"],
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "Preserve",
|
|
7
|
+
"moduleDetection": "force",
|
|
8
|
+
"jsx": "react-jsx",
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
|
|
11
|
+
// Bundler mode
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
|
|
17
|
+
// Best practices
|
|
18
|
+
"strict": true,
|
|
19
|
+
"skipLibCheck": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"noUncheckedIndexedAccess": true,
|
|
22
|
+
"noImplicitOverride": true,
|
|
23
|
+
|
|
24
|
+
// Some stricter flags (disabled by default)
|
|
25
|
+
"noUnusedLocals": false,
|
|
26
|
+
"noUnusedParameters": false,
|
|
27
|
+
"noPropertyAccessFromIndexSignature": false
|
|
28
|
+
}
|
|
29
|
+
}
|