@armory-sh/middleware-elysia 0.3.12 → 0.3.13
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.ts +1 -25
- package/dist/index.js +22 -44
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,38 +1,14 @@
|
|
|
1
1
|
import { Elysia } from 'elysia';
|
|
2
2
|
import { X402PaymentPayload, X402PaymentRequirements } from '@armory-sh/base';
|
|
3
3
|
|
|
4
|
-
interface LegacyPaymentPayloadV1 {
|
|
5
|
-
amount: string;
|
|
6
|
-
network: string;
|
|
7
|
-
contractAddress: string;
|
|
8
|
-
payTo: string;
|
|
9
|
-
from: string;
|
|
10
|
-
expiry: number;
|
|
11
|
-
signature: string;
|
|
12
|
-
}
|
|
13
|
-
interface LegacyPaymentPayloadV2 {
|
|
14
|
-
to: string;
|
|
15
|
-
from: string;
|
|
16
|
-
amount: string;
|
|
17
|
-
chainId: string;
|
|
18
|
-
assetId: string;
|
|
19
|
-
nonce: string;
|
|
20
|
-
expiry: number;
|
|
21
|
-
signature: string;
|
|
22
|
-
}
|
|
23
|
-
type AnyPaymentPayload = X402PaymentPayload | LegacyPaymentPayloadV1 | LegacyPaymentPayloadV2;
|
|
24
|
-
type PaymentPayload = AnyPaymentPayload;
|
|
25
|
-
|
|
26
4
|
interface PaymentMiddlewareConfig {
|
|
27
5
|
requirements: X402PaymentRequirements;
|
|
28
6
|
facilitatorUrl?: string;
|
|
29
7
|
skipVerification?: boolean;
|
|
30
|
-
defaultVersion?: 1 | 2;
|
|
31
8
|
}
|
|
32
9
|
interface PaymentInfo {
|
|
33
|
-
payload:
|
|
10
|
+
payload: X402PaymentPayload;
|
|
34
11
|
payerAddress: string;
|
|
35
|
-
version: 1 | 2;
|
|
36
12
|
verified: boolean;
|
|
37
13
|
}
|
|
38
14
|
interface PaymentContext {
|
package/dist/index.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
import { Elysia } from "elysia";
|
|
3
3
|
|
|
4
4
|
// src/payment-utils.ts
|
|
5
|
-
import { extractPaymentFromHeaders,
|
|
6
|
-
var
|
|
7
|
-
|
|
5
|
+
import { extractPaymentFromHeaders, PAYMENT_SIGNATURE_HEADER } from "@armory-sh/base";
|
|
6
|
+
var PAYMENT_HEADERS = {
|
|
7
|
+
PAYMENT: "PAYMENT-SIGNATURE",
|
|
8
|
+
REQUIRED: "PAYMENT-REQUIRED",
|
|
9
|
+
RESPONSE: "PAYMENT-RESPONSE"
|
|
10
|
+
};
|
|
8
11
|
var encodeRequirements = (requirements) => JSON.stringify(requirements);
|
|
9
|
-
function isLegacyV1(payload) {
|
|
10
|
-
return typeof payload === "object" && payload !== null && "contractAddress" in payload && "network" in payload && "signature" in payload && typeof payload.signature === "string";
|
|
11
|
-
}
|
|
12
12
|
function isLegacyV2(payload) {
|
|
13
13
|
return typeof payload === "object" && payload !== null && "chainId" in payload && "assetId" in payload && "signature" in payload && typeof payload.signature === "string";
|
|
14
14
|
}
|
|
@@ -27,16 +27,13 @@ var decodePayload = (headerValue) => {
|
|
|
27
27
|
}
|
|
28
28
|
const base64Value = isJsonString ? Buffer.from(headerValue).toString("base64") : headerValue;
|
|
29
29
|
const headers = new Headers();
|
|
30
|
-
headers.set(
|
|
30
|
+
headers.set(PAYMENT_SIGNATURE_HEADER, base64Value);
|
|
31
31
|
const x402Payload = extractPaymentFromHeaders(headers);
|
|
32
32
|
if (x402Payload) {
|
|
33
|
-
return { payload: x402Payload
|
|
34
|
-
}
|
|
35
|
-
if (isLegacyV1(parsed)) {
|
|
36
|
-
return { payload: parsed, version: 1 };
|
|
33
|
+
return { payload: x402Payload };
|
|
37
34
|
}
|
|
38
35
|
if (isLegacyV2(parsed)) {
|
|
39
|
-
return { payload: parsed
|
|
36
|
+
return { payload: parsed };
|
|
40
37
|
}
|
|
41
38
|
throw new Error("Unrecognized payment payload format");
|
|
42
39
|
};
|
|
@@ -64,10 +61,10 @@ var verifyWithFacilitator = async (facilitatorUrl, payload, requirements) => {
|
|
|
64
61
|
}
|
|
65
62
|
};
|
|
66
63
|
var verifyLocally = async (payload, requirements) => {
|
|
67
|
-
if (
|
|
64
|
+
if (isLegacyV2(payload)) {
|
|
68
65
|
return {
|
|
69
66
|
success: false,
|
|
70
|
-
error: "Local verification not supported for legacy payload
|
|
67
|
+
error: "Local verification not supported for legacy payload format. Use a facilitator."
|
|
71
68
|
};
|
|
72
69
|
}
|
|
73
70
|
return {
|
|
@@ -88,11 +85,10 @@ var extractPayerAddress = (payload) => {
|
|
|
88
85
|
}
|
|
89
86
|
throw new Error("Unable to extract payer address from payload");
|
|
90
87
|
};
|
|
91
|
-
var createResponseHeaders = (payerAddress
|
|
92
|
-
[
|
|
88
|
+
var createResponseHeaders = (payerAddress) => ({
|
|
89
|
+
[PAYMENT_HEADERS.RESPONSE]: JSON.stringify({
|
|
93
90
|
status: "verified",
|
|
94
|
-
payerAddress
|
|
95
|
-
version
|
|
91
|
+
payerAddress
|
|
96
92
|
})
|
|
97
93
|
});
|
|
98
94
|
|
|
@@ -102,56 +98,38 @@ var errorResponse = (error, status, headers) => new Response(JSON.stringify(erro
|
|
|
102
98
|
headers: { "Content-Type": "application/json", ...headers }
|
|
103
99
|
});
|
|
104
100
|
var paymentMiddleware = (config) => {
|
|
105
|
-
const { requirements, facilitatorUrl, skipVerification = false
|
|
106
|
-
const version = defaultVersion ?? getRequirementsVersion(requirements);
|
|
107
|
-
const headers = getHeadersForVersion(version);
|
|
101
|
+
const { requirements, facilitatorUrl, skipVerification = false } = config;
|
|
108
102
|
return new Elysia({ name: "armory-payment" }).derive(() => ({
|
|
109
103
|
payment: void 0
|
|
110
104
|
})).onBeforeHandle(async ({ payment, request }) => {
|
|
111
105
|
try {
|
|
112
|
-
const paymentHeader = request.headers.get(
|
|
106
|
+
const paymentHeader = request.headers.get(PAYMENT_HEADERS.PAYMENT);
|
|
113
107
|
if (!paymentHeader) {
|
|
114
|
-
const requiredValue = version === 1 ? Buffer.from(JSON.stringify(requirements)).toString("base64") : JSON.stringify({
|
|
115
|
-
x402Version: version,
|
|
116
|
-
resource: {
|
|
117
|
-
url: request.url,
|
|
118
|
-
description: "API Access"
|
|
119
|
-
},
|
|
120
|
-
accepts: [requirements]
|
|
121
|
-
});
|
|
122
108
|
return errorResponse(
|
|
123
109
|
{ error: "Payment required", accepts: [requirements] },
|
|
124
110
|
402,
|
|
125
|
-
{ [
|
|
111
|
+
{ [PAYMENT_HEADERS.REQUIRED]: encodeRequirements(requirements) }
|
|
126
112
|
);
|
|
127
113
|
}
|
|
128
114
|
let payload;
|
|
129
|
-
let payloadVersion;
|
|
130
115
|
try {
|
|
131
|
-
({ payload
|
|
116
|
+
({ payload } = decodePayload(paymentHeader));
|
|
132
117
|
} catch (error) {
|
|
133
118
|
return errorResponse({
|
|
134
119
|
error: "Invalid payment payload",
|
|
135
120
|
message: error instanceof Error ? error.message : "Unknown error"
|
|
136
121
|
}, 400);
|
|
137
122
|
}
|
|
138
|
-
if (payloadVersion !== version) {
|
|
139
|
-
return errorResponse({
|
|
140
|
-
error: "Payment version mismatch",
|
|
141
|
-
expected: version,
|
|
142
|
-
received: payloadVersion
|
|
143
|
-
}, 400);
|
|
144
|
-
}
|
|
145
123
|
const verifyResult = skipVerification ? { success: true, payerAddress: extractPayerAddress(payload) } : await verifyPaymentWithRetry(payload, requirements, facilitatorUrl);
|
|
146
124
|
if (!verifyResult.success) {
|
|
147
125
|
return errorResponse(
|
|
148
126
|
{ error: verifyResult.error },
|
|
149
127
|
402,
|
|
150
|
-
{ [
|
|
128
|
+
{ [PAYMENT_HEADERS.REQUIRED]: encodeRequirements(requirements) }
|
|
151
129
|
);
|
|
152
130
|
}
|
|
153
131
|
const payerAddress = verifyResult.payerAddress;
|
|
154
|
-
payment = { payload, payerAddress,
|
|
132
|
+
payment = { payload, payerAddress, verified: !skipVerification };
|
|
155
133
|
} catch (error) {
|
|
156
134
|
return errorResponse({
|
|
157
135
|
error: "Payment middleware error",
|
|
@@ -160,9 +138,9 @@ var paymentMiddleware = (config) => {
|
|
|
160
138
|
}
|
|
161
139
|
}).onAfterHandle(({ payment }) => {
|
|
162
140
|
if (payment) {
|
|
163
|
-
const { payerAddress
|
|
141
|
+
const { payerAddress } = payment;
|
|
164
142
|
return {
|
|
165
|
-
headers: createResponseHeaders(payerAddress
|
|
143
|
+
headers: createResponseHeaders(payerAddress)
|
|
166
144
|
};
|
|
167
145
|
}
|
|
168
146
|
});
|