x402z-server 0.0.2 → 0.0.3
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/dist/index.d.mts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +55 -0
- package/dist/index.mjs +55 -0
- package/package.json +2 -2
package/dist/index.d.mts
CHANGED
|
@@ -3,6 +3,7 @@ export * from '@x402/core/types';
|
|
|
3
3
|
import { x402ResourceServer } from '@x402/core/server';
|
|
4
4
|
export { x402ResourceServer } from '@x402/core/server';
|
|
5
5
|
import * as http from 'http';
|
|
6
|
+
import { RelayerSigner, RelayerInstance } from 'x402z-shared';
|
|
6
7
|
export { CompiledRoute, DynamicPayTo, DynamicPrice, FacilitatorClient, FacilitatorConfig, HTTPAdapter, HTTPFacilitatorClient, HTTPProcessResult, HTTPRequestContext, HTTPResponseInstructions, PaymentOption, PaywallConfig, PaywallProvider, ProcessSettleFailureResponse, ProcessSettleResultResponse, ProcessSettleSuccessResponse, RouteConfig, RouteConfigurationError, RouteValidationError, RoutesConfig, UnpaidResponseBody, UnpaidResponseResult, x402HTTPResourceServer } from '@x402/core/http';
|
|
7
8
|
|
|
8
9
|
type ConfidentialServerNetworkConfig = {
|
|
@@ -60,6 +61,8 @@ type X402zServerConfig = ConfidentialServerRegisterConfig & {
|
|
|
60
61
|
facilitatorUrl: string;
|
|
61
62
|
routes: Record<string, X402zRouteConfig>;
|
|
62
63
|
onPaid: X402zRouteHandler;
|
|
64
|
+
signer: RelayerSigner;
|
|
65
|
+
relayer: RelayerInstance;
|
|
63
66
|
debug?: boolean;
|
|
64
67
|
};
|
|
65
68
|
declare function createX402zServer(config: X402zServerConfig): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
|
package/dist/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export * from '@x402/core/types';
|
|
|
3
3
|
import { x402ResourceServer } from '@x402/core/server';
|
|
4
4
|
export { x402ResourceServer } from '@x402/core/server';
|
|
5
5
|
import * as http from 'http';
|
|
6
|
+
import { RelayerSigner, RelayerInstance } from 'x402z-shared';
|
|
6
7
|
export { CompiledRoute, DynamicPayTo, DynamicPrice, FacilitatorClient, FacilitatorConfig, HTTPAdapter, HTTPFacilitatorClient, HTTPProcessResult, HTTPRequestContext, HTTPResponseInstructions, PaymentOption, PaywallConfig, PaywallProvider, ProcessSettleFailureResponse, ProcessSettleResultResponse, ProcessSettleSuccessResponse, RouteConfig, RouteConfigurationError, RouteValidationError, RoutesConfig, UnpaidResponseBody, UnpaidResponseResult, x402HTTPResourceServer } from '@x402/core/http';
|
|
7
8
|
|
|
8
9
|
type ConfidentialServerNetworkConfig = {
|
|
@@ -60,6 +61,8 @@ type X402zServerConfig = ConfidentialServerRegisterConfig & {
|
|
|
60
61
|
facilitatorUrl: string;
|
|
61
62
|
routes: Record<string, X402zRouteConfig>;
|
|
62
63
|
onPaid: X402zRouteHandler;
|
|
64
|
+
signer: RelayerSigner;
|
|
65
|
+
relayer: RelayerInstance;
|
|
63
66
|
debug?: boolean;
|
|
64
67
|
};
|
|
65
68
|
declare function createX402zServer(config: X402zServerConfig): Promise<http.Server<typeof http.IncomingMessage, typeof http.ServerResponse>>;
|
package/dist/index.js
CHANGED
|
@@ -124,6 +124,15 @@ var import_node_url = require("url");
|
|
|
124
124
|
var import_server = require("@x402/core/server");
|
|
125
125
|
var import_http = require("@x402/core/http");
|
|
126
126
|
var import_http2 = require("@x402/core/http");
|
|
127
|
+
var import_x402z_shared = require("x402z-shared");
|
|
128
|
+
var import_viem = require("viem");
|
|
129
|
+
function getRelayerRpcUrl(relayer) {
|
|
130
|
+
const network = relayer.network;
|
|
131
|
+
if (typeof network === "string") {
|
|
132
|
+
return network;
|
|
133
|
+
}
|
|
134
|
+
throw new Error("relayer.network must be a string RPC URL");
|
|
135
|
+
}
|
|
127
136
|
function buildAdapter(req) {
|
|
128
137
|
const url = new import_node_url.URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
129
138
|
return {
|
|
@@ -148,6 +157,8 @@ async function createX402zServer(config) {
|
|
|
148
157
|
const facilitatorClient = new import_http2.HTTPFacilitatorClient({ url: config.facilitatorUrl });
|
|
149
158
|
const resourceServer = new import_server.x402ResourceServer(facilitatorClient);
|
|
150
159
|
registerConfidentialEvmScheme(resourceServer, config);
|
|
160
|
+
const relayer = config.relayer;
|
|
161
|
+
const rpcUrl = getRelayerRpcUrl(relayer);
|
|
151
162
|
const routes = {};
|
|
152
163
|
for (const [path, route] of Object.entries(config.routes)) {
|
|
153
164
|
routes[path] = {
|
|
@@ -188,6 +199,50 @@ async function createX402zServer(config) {
|
|
|
188
199
|
console.log(`[server] ${method} ${path} -> 500 settlement_failed`);
|
|
189
200
|
return;
|
|
190
201
|
}
|
|
202
|
+
try {
|
|
203
|
+
const observerClient = (0, import_viem.createPublicClient)({
|
|
204
|
+
transport: (0, import_viem.http)(rpcUrl)
|
|
205
|
+
});
|
|
206
|
+
const payTo = (0, import_viem.getAddress)(result.paymentRequirements.payTo);
|
|
207
|
+
const observer = await observerClient.readContract({
|
|
208
|
+
address: (0, import_viem.getAddress)(result.paymentRequirements.asset),
|
|
209
|
+
abi: import_x402z_shared.confidentialTokenAbi,
|
|
210
|
+
functionName: "observer",
|
|
211
|
+
args: [payTo]
|
|
212
|
+
});
|
|
213
|
+
const signerAddress = (0, import_viem.getAddress)(config.signer.address);
|
|
214
|
+
if (!observer || !(0, import_viem.isAddressEqual)(observer, signerAddress)) {
|
|
215
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
216
|
+
res.end(JSON.stringify({ error: "observer_required" }));
|
|
217
|
+
console.log(`[server] ${method} ${path} -> 500 observer_required`);
|
|
218
|
+
return;
|
|
219
|
+
}
|
|
220
|
+
const transfers = await (0, import_x402z_shared.viewConfidentialTransferAmounts)({
|
|
221
|
+
rpcUrl,
|
|
222
|
+
tokenAddress: result.paymentRequirements.asset,
|
|
223
|
+
txHash: settle.transaction,
|
|
224
|
+
from: settle.payer,
|
|
225
|
+
to: result.paymentRequirements.payTo,
|
|
226
|
+
relayer,
|
|
227
|
+
signer: config.signer
|
|
228
|
+
});
|
|
229
|
+
const expected = BigInt(result.paymentRequirements.amount);
|
|
230
|
+
const matched = transfers.some((transfer) => transfer.amount === expected);
|
|
231
|
+
if (!matched) {
|
|
232
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
233
|
+
res.end(JSON.stringify({ error: "settlement_amount_mismatch" }));
|
|
234
|
+
console.log(`[server] ${method} ${path} -> 500 settlement_amount_mismatch`);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
} catch (error) {
|
|
238
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
239
|
+
res.end(JSON.stringify({ error: "settlement_verification_failed" }));
|
|
240
|
+
console.log(`[server] ${method} ${path} -> 500 settlement_verification_failed`);
|
|
241
|
+
if (debugEnabled) {
|
|
242
|
+
console.debug("[x402z-server] settlement verification error", error);
|
|
243
|
+
}
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
191
246
|
const payload = await config.onPaid({
|
|
192
247
|
paymentRequirements: result.paymentRequirements,
|
|
193
248
|
settleHeaders: settle.headers
|
package/dist/index.mjs
CHANGED
|
@@ -93,6 +93,15 @@ import { URL } from "url";
|
|
|
93
93
|
import { x402ResourceServer } from "@x402/core/server";
|
|
94
94
|
import { x402HTTPResourceServer } from "@x402/core/http";
|
|
95
95
|
import { HTTPFacilitatorClient } from "@x402/core/http";
|
|
96
|
+
import { confidentialTokenAbi, viewConfidentialTransferAmounts } from "x402z-shared";
|
|
97
|
+
import { createPublicClient, getAddress, http, isAddressEqual } from "viem";
|
|
98
|
+
function getRelayerRpcUrl(relayer) {
|
|
99
|
+
const network = relayer.network;
|
|
100
|
+
if (typeof network === "string") {
|
|
101
|
+
return network;
|
|
102
|
+
}
|
|
103
|
+
throw new Error("relayer.network must be a string RPC URL");
|
|
104
|
+
}
|
|
96
105
|
function buildAdapter(req) {
|
|
97
106
|
const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
|
|
98
107
|
return {
|
|
@@ -117,6 +126,8 @@ async function createX402zServer(config) {
|
|
|
117
126
|
const facilitatorClient = new HTTPFacilitatorClient({ url: config.facilitatorUrl });
|
|
118
127
|
const resourceServer = new x402ResourceServer(facilitatorClient);
|
|
119
128
|
registerConfidentialEvmScheme(resourceServer, config);
|
|
129
|
+
const relayer = config.relayer;
|
|
130
|
+
const rpcUrl = getRelayerRpcUrl(relayer);
|
|
120
131
|
const routes = {};
|
|
121
132
|
for (const [path, route] of Object.entries(config.routes)) {
|
|
122
133
|
routes[path] = {
|
|
@@ -157,6 +168,50 @@ async function createX402zServer(config) {
|
|
|
157
168
|
console.log(`[server] ${method} ${path} -> 500 settlement_failed`);
|
|
158
169
|
return;
|
|
159
170
|
}
|
|
171
|
+
try {
|
|
172
|
+
const observerClient = createPublicClient({
|
|
173
|
+
transport: http(rpcUrl)
|
|
174
|
+
});
|
|
175
|
+
const payTo = getAddress(result.paymentRequirements.payTo);
|
|
176
|
+
const observer = await observerClient.readContract({
|
|
177
|
+
address: getAddress(result.paymentRequirements.asset),
|
|
178
|
+
abi: confidentialTokenAbi,
|
|
179
|
+
functionName: "observer",
|
|
180
|
+
args: [payTo]
|
|
181
|
+
});
|
|
182
|
+
const signerAddress = getAddress(config.signer.address);
|
|
183
|
+
if (!observer || !isAddressEqual(observer, signerAddress)) {
|
|
184
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
185
|
+
res.end(JSON.stringify({ error: "observer_required" }));
|
|
186
|
+
console.log(`[server] ${method} ${path} -> 500 observer_required`);
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const transfers = await viewConfidentialTransferAmounts({
|
|
190
|
+
rpcUrl,
|
|
191
|
+
tokenAddress: result.paymentRequirements.asset,
|
|
192
|
+
txHash: settle.transaction,
|
|
193
|
+
from: settle.payer,
|
|
194
|
+
to: result.paymentRequirements.payTo,
|
|
195
|
+
relayer,
|
|
196
|
+
signer: config.signer
|
|
197
|
+
});
|
|
198
|
+
const expected = BigInt(result.paymentRequirements.amount);
|
|
199
|
+
const matched = transfers.some((transfer) => transfer.amount === expected);
|
|
200
|
+
if (!matched) {
|
|
201
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
202
|
+
res.end(JSON.stringify({ error: "settlement_amount_mismatch" }));
|
|
203
|
+
console.log(`[server] ${method} ${path} -> 500 settlement_amount_mismatch`);
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
} catch (error) {
|
|
207
|
+
res.writeHead(500, { "Content-Type": "application/json" });
|
|
208
|
+
res.end(JSON.stringify({ error: "settlement_verification_failed" }));
|
|
209
|
+
console.log(`[server] ${method} ${path} -> 500 settlement_verification_failed`);
|
|
210
|
+
if (debugEnabled) {
|
|
211
|
+
console.debug("[x402z-server] settlement verification error", error);
|
|
212
|
+
}
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
160
215
|
const payload = await config.onPaid({
|
|
161
216
|
paymentRequirements: result.paymentRequirements,
|
|
162
217
|
settleHeaders: settle.headers
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "x402z-server",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"module": "./dist/index.mjs",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@x402/core": "^2.0.0",
|
|
12
12
|
"viem": "^2.43.3",
|
|
13
|
-
"x402z-shared": "0.0.
|
|
13
|
+
"x402z-shared": "0.0.3"
|
|
14
14
|
},
|
|
15
15
|
"devDependencies": {
|
|
16
16
|
"jest": "^29.7.0",
|