@insumermodel/mppx-condition-gate 3.0.1 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +78 -11
- package/dist/index.d.ts +65 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +321 -40
- package/dist/index.js.map +1 -1
- package/package.json +5 -9
- package/src/index.ts +392 -45
package/README.md
CHANGED
|
@@ -15,7 +15,9 @@ Free access requires a payer your payment method has **proven** controls the req
|
|
|
15
15
|
5. **Pass** → free receipt returned (`reference: "condition-gate:free:{attestationId}"`)
|
|
16
16
|
6. **Fail, or no proven payer** → the normal paid path runs
|
|
17
17
|
|
|
18
|
-
|
|
18
|
+
Each credential gets free access at most once. See [Single-use credentials](#single-use-credentials) for what the gate records and the limits of that guarantee.
|
|
19
|
+
|
|
20
|
+
The signed attestation is verifiable offline via [JWKS](https://insumermodel.com/.well-known/jwks.json). The adapter does not re-sign or wrap the result; the signature on the attestation is the one InsumerAPI produced. Since 2026-09-01 every attest response also carries an ML-DSA-65 post-quantum companion (`pqSig`, `pqKid`) beside `sig` and `kid`, added without changing them; the `InsumerAttestation` type declares `pqSig` and `pqKid` beside `sig` and `kid`, and `insumer-verify` 1.8.1+ reports the companion as a fifth verdict.
|
|
19
21
|
|
|
20
22
|
### Why you must supply the payer
|
|
21
23
|
|
|
@@ -32,18 +34,19 @@ npm install @insumermodel/mppx-condition-gate
|
|
|
32
34
|
## Usage
|
|
33
35
|
|
|
34
36
|
```ts
|
|
35
|
-
import { Mppx,
|
|
37
|
+
import { Mppx, evm } from 'mppx/server'
|
|
36
38
|
import { conditionGate } from '@insumermodel/mppx-condition-gate'
|
|
37
39
|
|
|
38
|
-
const
|
|
39
|
-
currency:
|
|
40
|
-
recipient: '0xYourAddress',
|
|
40
|
+
const evmCharge = evm.charge({
|
|
41
|
+
currency: evm.assets.base.USDC,
|
|
42
|
+
recipient: '0xYourAddress', // your checksummed receiving address
|
|
43
|
+
x402: { facilitator: 'https://your-facilitator.example' },
|
|
41
44
|
})
|
|
42
45
|
|
|
43
|
-
const gatedCharge = conditionGate(
|
|
46
|
+
const gatedCharge = conditionGate(evmCharge, {
|
|
44
47
|
apiKey: process.env.INSUMER_API_KEY,
|
|
45
48
|
// Return only a payer this method has PROVEN for this request, else null.
|
|
46
|
-
//
|
|
49
|
+
// mppx's EVM charge reports the signer it recovered as `payer`.
|
|
47
50
|
provenPayer: (details) => (details as { payer?: string }).payer ?? null,
|
|
48
51
|
conditions: [{
|
|
49
52
|
type: 'nft_ownership',
|
|
@@ -52,10 +55,69 @@ const gatedCharge = conditionGate(tempoCharge, {
|
|
|
52
55
|
}],
|
|
53
56
|
})
|
|
54
57
|
|
|
55
|
-
const mppx = Mppx.create({ methods: [gatedCharge] })
|
|
58
|
+
const mppx = Mppx.create({ methods: [gatedCharge], secretKey: process.env.MPP_SECRET_KEY })
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Works with any framework (Hono, Express, Elysia, Next.js). The adapter wraps `Method.Server`, so no middleware changes needed.
|
|
62
|
+
|
|
63
|
+
### Which credentials can get free access
|
|
64
|
+
|
|
65
|
+
Free access needs a method that exposes mppx's `validate` hook, a resolver that returns the payer that method proved, and a credential the gate can identify. mppx added `validate` in 0.8.14 for the Tempo charge and in 0.9.3 for the EVM charge; on older versions every request pays. In mppx 0.9.3:
|
|
66
|
+
|
|
67
|
+
- **EVM charge**, native and x402: EIP-3009 authorizations. The payer is the recovered signer, `details.payer`.
|
|
68
|
+
- **Tempo charge, proof credentials**: the payer is `details.sender`, checked against a signature over the challenge. Tempo accepts proofs only on zero-amount challenges.
|
|
69
|
+
- **Tempo hash and transaction credentials** are payments in their own right, a transfer already on chain or one waiting to be sent. They take the paid path, where the Tempo method's own replay protection applies.
|
|
70
|
+
- **Stripe** exposes no `validate` hook, so it is never gated.
|
|
71
|
+
|
|
72
|
+
## Single-use credentials
|
|
73
|
+
|
|
74
|
+
When a payment settles, mppx spends the credential: the on-chain nonce is used, or the method records it. A free grant never settles, so the gate keeps its own record:
|
|
75
|
+
|
|
76
|
+
- It records a credential when it grants free access. It also records an EIP-3009 authorization just before the paid path settles it, so a copy presented while that payment is in flight is refused.
|
|
77
|
+
- A recorded credential is refused with a verification error. It is not passed on to payment, which would charge the original holder for someone else's request.
|
|
78
|
+
- If settlement throws, that record is released, so the holder can retry with the same credential.
|
|
79
|
+
- An EIP-3009 authorization is identified by its signer and nonce, and a Tempo proof by its challenge and payer. Neither changes when a signature is re-encoded or the challenge is rebuilt, and two users never share one. A native credential signs its challenge, so the same wallet signing the same native challenge twice (in the same millisecond, or on a route with a fixed `expires`) produces one credential, and the second is refused. x402 clients choose a fresh nonce each time.
|
|
80
|
+
- A Tempo proof gets free access once, but a repeated proof is not refused, and a proof that takes the paid path is not recorded. Proofs are only accepted on zero-amount routes, which move no value, so the Tempo method and its own replay rules (its `store` option) decide whether it may be presented again.
|
|
81
|
+
|
|
82
|
+
A record is kept until the credential expires, plus 60 seconds. A credential whose remaining validity is longer than `maxCredentialLifetimeSeconds` (600 by default) gets no free access and takes the paid path:
|
|
83
|
+
|
|
84
|
+
- **EIP-3009 authorization:** its `validBefore`. An x402 client sets it from the route's `maxTimeoutSeconds` (300 by default), whatever the challenge expiry, but a client can sign a longer one. An x402 route whose `maxTimeoutSeconds` is above the cap gives qualifying visitors no free access unless you raise the option. A native client sets it to the challenge's `expires` (5 minutes by default), so a native route configured with an `expires` longer than the cap gives no free access unless you raise the option.
|
|
85
|
+
- **Tempo proof:** the challenge's `expires`.
|
|
86
|
+
|
|
87
|
+
### Limits of the guarantee
|
|
88
|
+
|
|
89
|
+
Each case below allows at most one extra use of a credential:
|
|
90
|
+
|
|
91
|
+
- **Settlement throws after the transfer actually happened.** The record is released, so the credential can be presented again. If its payer now meets the conditions, that presentation is free.
|
|
92
|
+
- **The default store's payment records are full** (100,000 live). Later payments are not recorded, so a settled credential can come back once for free access.
|
|
93
|
+
- **A caller-supplied store cannot be read or written.** The request gets no free access and pays without a record. A credential that already got free access can then be settled for a copy's request, charging its holder once, which is what bare mppx does with any credential that has not settled.
|
|
94
|
+
|
|
95
|
+
Concurrent copies of one credential may each spend an attestation before one of them is granted.
|
|
96
|
+
|
|
97
|
+
### The default store
|
|
98
|
+
|
|
99
|
+
The default record lives in memory and is **shared by every gated route in the process**. It holds up to 100,000 live free grants, at most 5,000 per wallet, and up to 100,000 payment records. A wallet over its share, or any wallet once the free-grant capacity is full, pays instead.
|
|
100
|
+
|
|
101
|
+
The default store is not a defense against someone determined to deny free access to others. Free credentials cost nothing to sign, so about 20 qualifying addresses can fill the free-grant capacity. So can one qualifying asset moved between 20 addresses, because a passing attestation is cached for `cacheTtlSeconds`. Every other qualifying visitor in that process then pays the route price until those credentials expire, up to `maxCredentialLifetimeSeconds` plus a minute. Use the default store for development and low-stakes routes.
|
|
102
|
+
|
|
103
|
+
**For production traffic, or when the route runs on more than one instance, pass a shared store with its own capacity.** The store must claim atomically and remove expired entries. Options:
|
|
104
|
+
|
|
105
|
+
- `Store.redis`, `Store.upstash` or `Store.cloudflare`, built from a client that exposes an atomic `update`. Confirm that your backend expires keys.
|
|
106
|
+
- Any store with an atomic `tryClaim`.
|
|
107
|
+
|
|
108
|
+
mppx's `Store.memory()` never removes expired entries, so use it only in tests. A store that is not atomic lets concurrent presentations through. Give the store `delete` (or `update`) so a failed payment can be released.
|
|
109
|
+
|
|
110
|
+
```ts
|
|
111
|
+
import { Store } from 'mppx/server'
|
|
112
|
+
|
|
113
|
+
const gatedCharge = conditionGate(evmCharge, {
|
|
114
|
+
provenPayer: (details) => (details as { payer?: string }).payer ?? null,
|
|
115
|
+
conditions: [ ... ],
|
|
116
|
+
replayStore: Store.redis(atomicRedisClient), // the client must provide `update`
|
|
117
|
+
})
|
|
56
118
|
```
|
|
57
119
|
|
|
58
|
-
|
|
120
|
+
Refusals are mppx's own `VerificationFailedError`, returned as HTTP 402. mppx is a peer dependency; if your install ends up with two copies of it, a refusal surfaces as an internal error (HTTP 500) instead.
|
|
59
121
|
|
|
60
122
|
## Condition types
|
|
61
123
|
|
|
@@ -181,8 +243,10 @@ Either way, set `INSUMER_API_KEY` as an environment variable in your runtime.
|
|
|
181
243
|
| `conditions` | `Condition[]` | required | One or more conditions to evaluate |
|
|
182
244
|
| `matchMode` | `'any' \| 'all'` | `'any'` | Wallet must satisfy any or all conditions |
|
|
183
245
|
| `cacheTtlSeconds` | `number` | `300` | In-memory cache TTL |
|
|
184
|
-
| `jwt` | `boolean` | `false` | Request ES256 JWT alongside raw attestation |
|
|
185
246
|
| `apiBaseUrl` | `string` | `https://api.insumermodel.com` | API base URL override |
|
|
247
|
+
| `provenPayer` | `(details) => ProvenPayer` | none | Returns the payer the method proved; required for free access |
|
|
248
|
+
| `replayStore` | `AtomicStore` | bounded in-memory, per process | Records used credentials; must be atomic; share it across instances |
|
|
249
|
+
| `maxCredentialLifetimeSeconds` | `number` | `600` | Longest remaining validity a credential may have and still get free access |
|
|
186
250
|
|
|
187
251
|
## Supported chains
|
|
188
252
|
|
|
@@ -196,7 +260,10 @@ Either way, set `INSUMER_API_KEY` as an environment variable in your runtime.
|
|
|
196
260
|
const receipt = Receipt.fromResponse(response)
|
|
197
261
|
if (receipt.reference.startsWith('condition-gate:free:')) {
|
|
198
262
|
const attestationId = receipt.reference.replace('condition-gate:free:', '')
|
|
199
|
-
// Free access.
|
|
263
|
+
// Free access. attestationId is the `id` of the signed attestation InsumerAPI
|
|
264
|
+
// returned for this payer (from POST /v1/attest). The gate keeps only `id` and
|
|
265
|
+
// `pass` in its in-memory cache and the API has no lookup by id, so record the
|
|
266
|
+
// reference here if you need to correlate it with your own logs.
|
|
200
267
|
} else {
|
|
201
268
|
// Paid access
|
|
202
269
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -126,8 +126,54 @@ export type ConditionGateOptions = {
|
|
|
126
126
|
* Override for self-hosted deployments or testing.
|
|
127
127
|
*/
|
|
128
128
|
apiBaseUrl?: string;
|
|
129
|
-
/**
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated No effect. The gate consumes the attestation internally and
|
|
131
|
+
* returns only an mppx receipt, so a requested JWT never reached the caller.
|
|
132
|
+
* Accepted for type compatibility; not sent to the API. Call POST /v1/attest
|
|
133
|
+
* with `format: "jwt"` directly if you need the `jwt` and `pqJwt` tokens.
|
|
134
|
+
*/
|
|
130
135
|
jwt?: boolean;
|
|
136
|
+
/**
|
|
137
|
+
* Where the gate records credentials it has accepted, so each one gets
|
|
138
|
+
* through at most once. Defaults to a bounded in-process store.
|
|
139
|
+
*
|
|
140
|
+
* Pass a shared store when the route runs on more than one instance, or a
|
|
141
|
+
* credential used on one instance can be presented again on another. The
|
|
142
|
+
* store must claim atomically and remove expired entries: `Store.redis`,
|
|
143
|
+
* `Store.upstash` or `Store.cloudflare` from `mppx/server` built from a client
|
|
144
|
+
* that exposes an atomic `update`, or any store with an atomic `tryClaim`.
|
|
145
|
+
* mppx's `Store.memory()` never removes expired entries; use it only in tests.
|
|
146
|
+
*/
|
|
147
|
+
replayStore?: ReplayStore;
|
|
148
|
+
/**
|
|
149
|
+
* Longest remaining validity, in seconds, a credential may have and still be
|
|
150
|
+
* given free access. Defaults to 600. The gate has to remember a credential
|
|
151
|
+
* until it expires, and x402 clients choose their own expiry, so longer-lived
|
|
152
|
+
* credentials take the paid path instead.
|
|
153
|
+
*/
|
|
154
|
+
maxCredentialLifetimeSeconds?: number;
|
|
155
|
+
};
|
|
156
|
+
/**
|
|
157
|
+
* An atomic claim store. Structurally compatible with mppx's `AtomicStore`:
|
|
158
|
+
* `tryClaim` is used when present, otherwise `update`. `get`, when present,
|
|
159
|
+
* lets the gate refuse a repeat before spending an attestation on it, and
|
|
160
|
+
* `delete` (or `update`) lets it release a credential whose payment failed.
|
|
161
|
+
*/
|
|
162
|
+
export type ReplayStore = {
|
|
163
|
+
get?: (key: string) => unknown | Promise<unknown>;
|
|
164
|
+
delete?: (key: string) => void | Promise<void>;
|
|
165
|
+
tryClaim?: (key: string, expires: number) => boolean | Promise<boolean>;
|
|
166
|
+
update?: <result>(key: string, fn: (current: any) => {
|
|
167
|
+
op: 'noop';
|
|
168
|
+
result: result;
|
|
169
|
+
} | {
|
|
170
|
+
op: 'set';
|
|
171
|
+
value: any;
|
|
172
|
+
result: result;
|
|
173
|
+
} | {
|
|
174
|
+
op: 'delete';
|
|
175
|
+
result: result;
|
|
176
|
+
}) => Promise<result>;
|
|
131
177
|
};
|
|
132
178
|
export type InsumerAttestation = {
|
|
133
179
|
ok: boolean;
|
|
@@ -155,7 +201,12 @@ export type InsumerAttestation = {
|
|
|
155
201
|
};
|
|
156
202
|
sig: string;
|
|
157
203
|
kid: string;
|
|
204
|
+
/** ML-DSA-65 post-quantum companion signature (since 2026-09-01, additive). */
|
|
205
|
+
pqSig?: string;
|
|
206
|
+
/** Post-quantum key id, insumer-attest-pq1 (resolved in the JWKS as an RFC 9964 AKP entry). */
|
|
207
|
+
pqKid?: string;
|
|
158
208
|
jwt?: string;
|
|
209
|
+
pqJwt?: string;
|
|
159
210
|
};
|
|
160
211
|
meta: {
|
|
161
212
|
version: string;
|
|
@@ -164,7 +215,7 @@ export type InsumerAttestation = {
|
|
|
164
215
|
creditsCharged: number;
|
|
165
216
|
};
|
|
166
217
|
};
|
|
167
|
-
/** Clear the in-memory ownership cache. Useful in tests. */
|
|
218
|
+
/** Clear the in-memory ownership cache and the default replay store. Useful in tests. */
|
|
168
219
|
export declare function clearConditionGateCache(): void;
|
|
169
220
|
/**
|
|
170
221
|
* Extracts an EVM address from a `did:pkh:eip155:{chainId}:{address}` string.
|
|
@@ -202,6 +253,16 @@ export declare function normalizeProvenPayer(payer: ProvenPayer): {
|
|
|
202
253
|
* credential that fails validation, conditions not met, or an attestation
|
|
203
254
|
* error. There is no path from an unproven wallet to a free receipt.
|
|
204
255
|
*
|
|
256
|
+
* Each credential gets free access at most once. The gate records a
|
|
257
|
+
* credential when it grants free access, and records an authorization just
|
|
258
|
+
* before the paid path settles it; a recorded credential is refused with a
|
|
259
|
+
* verification error rather than passed on to payment. A payment that fails is
|
|
260
|
+
* released, so it can be retried. See the README for the limits of this. Free access is given only to credentials the gate can identify
|
|
261
|
+
* (EIP-3009 authorizations and Tempo proofs) whose remaining validity is within
|
|
262
|
+
* `maxCredentialLifetimeSeconds`. The default store is bounded and shared by
|
|
263
|
+
* every gated route in the process; pass a shared `replayStore` for production
|
|
264
|
+
* traffic or when the route runs on more than one instance.
|
|
265
|
+
*
|
|
205
266
|
* Conditions are evaluated across the 35 chains this adapter reaches (32 EVM +
|
|
206
267
|
* Solana + XRPL + Bitcoin; the engine itself covers 38). Six condition types
|
|
207
268
|
* are typed here: token_balance, nft_ownership, eas_attestation, farcaster_id,
|
|
@@ -216,8 +277,9 @@ export declare function normalizeProvenPayer(payer: ProvenPayer): {
|
|
|
216
277
|
* ```ts
|
|
217
278
|
* import { conditionGate } from '@insumermodel/mppx-condition-gate'
|
|
218
279
|
*
|
|
219
|
-
* const gated = conditionGate(
|
|
280
|
+
* const gated = conditionGate(evmCharge, {
|
|
220
281
|
* // Return only a payer this method has proven for THIS request.
|
|
282
|
+
* // mppx's EVM charge reports the recovered signer as `payer`.
|
|
221
283
|
* provenPayer: (details) => (details as { payer?: string }).payer ?? null,
|
|
222
284
|
* conditions: [
|
|
223
285
|
* { type: 'eas_attestation', template: 'coinbase_verified_account', chainId: 8453 },
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAW,MAAM,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|