@armory-sh/middleware-hono 0.3.29 → 0.3.30
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 +30 -6
- package/dist/index.d.ts +1 -0
- package/dist/index.js +60 -14
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -14,24 +14,47 @@ bun add @armory-sh/middleware-hono
|
|
|
14
14
|
|
|
15
15
|
Armory enables HTTP API payments via EIP-3009 `transferWithAuthorization`. Accept payments from any x402-compatible client—Coinbase SDK, Armory SDK, or your own implementation.
|
|
16
16
|
|
|
17
|
-
##
|
|
17
|
+
## API Reference
|
|
18
|
+
|
|
19
|
+
### Middleware
|
|
18
20
|
|
|
19
21
|
```typescript
|
|
20
22
|
import {
|
|
21
|
-
// Middleware
|
|
22
23
|
paymentMiddleware,
|
|
23
24
|
routeAwarePaymentMiddleware,
|
|
24
25
|
|
|
25
|
-
// Requirements
|
|
26
|
-
createPaymentRequirements,
|
|
27
|
-
|
|
28
26
|
// Types
|
|
29
27
|
type PaymentConfig,
|
|
30
28
|
type RouteAwarePaymentConfig,
|
|
31
|
-
type
|
|
29
|
+
type AugmentedContext,
|
|
32
30
|
} from '@armory-sh/middleware-hono';
|
|
33
31
|
```
|
|
34
32
|
|
|
33
|
+
### Payment Requirements
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import {
|
|
37
|
+
createPaymentRequirements,
|
|
38
|
+
|
|
39
|
+
// Types
|
|
40
|
+
type ResolvedRequirementsConfig,
|
|
41
|
+
} from '@armory-sh/middleware-hono';
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Extensions
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import {
|
|
48
|
+
buildExtensions,
|
|
49
|
+
extractExtension,
|
|
50
|
+
|
|
51
|
+
// Types
|
|
52
|
+
type ExtensionConfig,
|
|
53
|
+
} from '@armory-sh/middleware-hono';
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
---
|
|
57
|
+
|
|
35
58
|
## Quick Start
|
|
36
59
|
|
|
37
60
|
### Basic Middleware
|
|
@@ -168,6 +191,7 @@ interface RouteAwarePaymentConfig extends PaymentConfig {
|
|
|
168
191
|
| Base Sepolia | 84532 |
|
|
169
192
|
| SKALE Base | 1187947933 |
|
|
170
193
|
| SKALE Base Sepolia | 324705682 |
|
|
194
|
+
| Ethereum Sepolia | 11155111 |
|
|
171
195
|
|
|
172
196
|
## License
|
|
173
197
|
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ interface PaymentConfig {
|
|
|
23
23
|
facilitatorUrl?: string;
|
|
24
24
|
facilitatorUrlByChain?: Record<string, string>;
|
|
25
25
|
facilitatorUrlByToken?: Record<string, Record<string, string>>;
|
|
26
|
+
extensions?: Record<string, unknown>;
|
|
26
27
|
}
|
|
27
28
|
interface ResolvedRequirementsConfig {
|
|
28
29
|
requirements: PaymentRequirementsV2[];
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { buildExtensions, extractExtension } from './chunk-XYM6YXAQ.js';
|
|
2
|
-
import { matchRoute, V2_HEADERS, safeBase64Encode, decodePayloadHeader, findRequirementByAccepted, verifyPayment, createPaymentRequiredHeaders, settlePayment, createSettlementHeaders, resolveNetwork, isValidationError, resolveToken, createPaymentRequirements as createPaymentRequirements$1, PAYMENT_SIGNATURE_HEADER, PAYMENT_REQUIRED_HEADER, validateRouteConfig, TOKENS, registerToken } from '@armory-sh/base';
|
|
2
|
+
import { matchRoute, V2_HEADERS, safeBase64Encode, decodePayloadHeader, findRequirementByAccepted, verifyPayment, createPaymentRequiredHeaders, settlePayment, createSettlementHeaders, resolveNetwork, isValidationError, resolveToken, createPaymentRequirements as createPaymentRequirements$1, PAYMENT_SIGNATURE_HEADER, PAYMENT_REQUIRED_HEADER, validateRouteConfig, TOKENS, registerToken, getSupported } from '@armory-sh/base';
|
|
3
3
|
|
|
4
4
|
var resolveRouteConfig = (config) => {
|
|
5
5
|
const validationError = validateRouteConfig(config);
|
|
@@ -155,6 +155,8 @@ var routeAwarePaymentMiddleware = (config) => {
|
|
|
155
155
|
};
|
|
156
156
|
|
|
157
157
|
// src/index.ts
|
|
158
|
+
var extensionCapabilityCache = /* @__PURE__ */ new Map();
|
|
159
|
+
var EXTENSION_CAPABILITY_TTL_MS = 5 * 60 * 1e3;
|
|
158
160
|
function ensureTokensRegistered() {
|
|
159
161
|
for (const token of Object.values(TOKENS)) {
|
|
160
162
|
try {
|
|
@@ -171,17 +173,13 @@ function resolveFacilitatorUrlFromRequirement(config, requirement) {
|
|
|
171
173
|
config.facilitatorUrlByToken
|
|
172
174
|
)) {
|
|
173
175
|
const resolvedChain = resolveNetwork(chainKey);
|
|
174
|
-
if (
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
return url;
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
}
|
|
176
|
+
if (isValidationError(resolvedChain) || resolvedChain.config.chainId !== chainId) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
for (const [tokenKey, url] of Object.entries(tokenMap)) {
|
|
180
|
+
const resolvedToken = resolveToken(tokenKey, resolvedChain);
|
|
181
|
+
if (!isValidationError(resolvedToken) && resolvedToken.config.contractAddress.toLowerCase() === assetAddress) {
|
|
182
|
+
return url;
|
|
185
183
|
}
|
|
186
184
|
}
|
|
187
185
|
}
|
|
@@ -216,8 +214,56 @@ function createPaymentRequirements(config) {
|
|
|
216
214
|
ensureTokensRegistered();
|
|
217
215
|
return createPaymentRequirements$1(config);
|
|
218
216
|
}
|
|
217
|
+
async function resolvePaymentRequiredExtensions(config, requirements) {
|
|
218
|
+
if (!config.extensions) {
|
|
219
|
+
return {};
|
|
220
|
+
}
|
|
221
|
+
let filtered = { ...config.extensions };
|
|
222
|
+
for (const requirement of requirements) {
|
|
223
|
+
const facilitatorUrl = resolveFacilitatorUrlFromRequirement(config, requirement);
|
|
224
|
+
if (!facilitatorUrl) {
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
const cacheKey = `${facilitatorUrl}|${requirement.network.toLowerCase()}`;
|
|
228
|
+
const now = Date.now();
|
|
229
|
+
let keys = extensionCapabilityCache.get(cacheKey);
|
|
230
|
+
if (!keys || keys.expiresAt <= now) {
|
|
231
|
+
try {
|
|
232
|
+
const supported = await getSupported({ url: facilitatorUrl });
|
|
233
|
+
const nextKeys = /* @__PURE__ */ new Set();
|
|
234
|
+
for (const kind of supported.kinds) {
|
|
235
|
+
if (kind.network.toLowerCase() !== requirement.network.toLowerCase()) {
|
|
236
|
+
continue;
|
|
237
|
+
}
|
|
238
|
+
if (kind.extra && typeof kind.extra === "object") {
|
|
239
|
+
for (const key of Object.keys(kind.extra)) {
|
|
240
|
+
nextKeys.add(key);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
keys = { expiresAt: now + EXTENSION_CAPABILITY_TTL_MS, keys: nextKeys };
|
|
245
|
+
} catch {
|
|
246
|
+
keys = { expiresAt: now + EXTENSION_CAPABILITY_TTL_MS, keys: /* @__PURE__ */ new Set() };
|
|
247
|
+
}
|
|
248
|
+
extensionCapabilityCache.set(cacheKey, keys);
|
|
249
|
+
}
|
|
250
|
+
filtered = Object.fromEntries(
|
|
251
|
+
Object.entries(filtered).filter(([key]) => keys.keys.has(key))
|
|
252
|
+
);
|
|
253
|
+
if (Object.keys(filtered).length === 0) {
|
|
254
|
+
return {};
|
|
255
|
+
}
|
|
256
|
+
}
|
|
257
|
+
return filtered;
|
|
258
|
+
}
|
|
219
259
|
function paymentMiddleware(config) {
|
|
220
260
|
const { requirements, error } = createPaymentRequirements(config);
|
|
261
|
+
const resolvePaymentRequiredHeader = async () => createPaymentRequiredHeaders(requirements, {
|
|
262
|
+
extensions: await resolvePaymentRequiredExtensions(
|
|
263
|
+
config,
|
|
264
|
+
requirements
|
|
265
|
+
)
|
|
266
|
+
})[PAYMENT_REQUIRED_HEADER];
|
|
221
267
|
return async (c, next) => {
|
|
222
268
|
if (error) {
|
|
223
269
|
c.status(500);
|
|
@@ -250,7 +296,7 @@ function paymentMiddleware(config) {
|
|
|
250
296
|
c.status(402);
|
|
251
297
|
c.header(
|
|
252
298
|
PAYMENT_REQUIRED_HEADER,
|
|
253
|
-
safeBase64Encode(JSON.stringify(paymentRequired))
|
|
299
|
+
await resolvePaymentRequiredHeader() ?? safeBase64Encode(JSON.stringify(paymentRequired))
|
|
254
300
|
);
|
|
255
301
|
return c.json({
|
|
256
302
|
error: "Payment required",
|
|
@@ -297,7 +343,7 @@ function paymentMiddleware(config) {
|
|
|
297
343
|
c.status(402);
|
|
298
344
|
c.header(
|
|
299
345
|
PAYMENT_REQUIRED_HEADER,
|
|
300
|
-
|
|
346
|
+
await resolvePaymentRequiredHeader()
|
|
301
347
|
);
|
|
302
348
|
return c.json({
|
|
303
349
|
error: "Payment verification failed",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@armory-sh/middleware-hono",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.30",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"author": "Sawyer Cutler <sawyer@dirtroad.dev>",
|
|
6
6
|
"keywords": [
|
|
@@ -52,8 +52,8 @@
|
|
|
52
52
|
"hono": "^4"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@armory-sh/base": "0.2.
|
|
56
|
-
"@armory-sh/extensions": "0.1.
|
|
55
|
+
"@armory-sh/base": "0.2.30",
|
|
56
|
+
"@armory-sh/extensions": "0.1.11"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
59
|
"bun-types": "latest",
|