@insumermodel/mppx-condition-gate 2.0.2 → 3.0.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 CHANGED
@@ -6,16 +6,23 @@ Condition-based access for [mppx](https://github.com/wevm/mppx) routes. One sign
6
6
 
7
7
  ## How it works
8
8
 
9
- mppx embeds the payer's identity in every payment credential as a DID string (`credential.source: "did:pkh:eip155:8453:0xABC..."`). `conditionGate` reads that address, calls [InsumerAPI](https://insumermodel.com) to evaluate the configured conditions, and short-circuits the payment flow for wallets that pass.
9
+ Free access requires a payer your payment method has **proven** controls the request. You supply that payer through `provenPayer`; the gate never infers one.
10
10
 
11
11
  1. Request arrives with a payment credential
12
- 2. `conditionGate` extracts the payer address from `credential.source`
13
- 3. [InsumerAPI](https://insumermodel.com/developers/api-reference/) evaluates the conditions and returns an ECDSA P-256 signed attestation
14
- 4. **Pass** → free receipt returned (`reference: "condition-gate:free:{attestationId}"`)
15
- 5. **Fail** → delegates to the original `verify` (normal payment proceeds)
12
+ 2. The gate calls the method's non-mutating `validate` hook
13
+ 3. Your `provenPayer` resolver receives mppx's method-specific validation `details` and returns the proven payer, or `null`
14
+ 4. [InsumerAPI](https://insumermodel.com/developers/api-reference/) evaluates the conditions for that payer and returns an ECDSA P-256 signed attestation
15
+ 5. **Pass** → free receipt returned (`reference: "condition-gate:free:{attestationId}"`)
16
+ 6. **Fail, or no proven payer** → the normal paid path runs
16
17
 
17
18
  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.
18
19
 
20
+ ### Why you must supply the payer
21
+
22
+ mppx credentials carry an optional `source` DID, but mppx documents it as *"an asserted identity, not independent proof of control"* — it is a claim by the caller, not a proof. Versions before 3.0.0 granted free access on it, which let anyone name a qualifying wallet and skip payment ([GHSA-jg6q-3qfh-r9f8](https://github.com/douglasborthwick-crypto/mppx-condition-gate/security/advisories/GHSA-jg6q-3qfh-r9f8)). The gate now refuses to guess.
23
+
24
+ `provenPayer` receives **only** the validation `details` — never the credential and never `source` — so the unproven identity is not reachable from it. Return a payer only if the payment method has actually established control of it. **Every path that cannot justify free access falls through to payment:** no resolver, no `validate` hook on the method, a resolver returning `null` or throwing, a credential that fails validation, conditions not met, or an attestation error.
25
+
19
26
  ## Install
20
27
 
21
28
  ```bash
@@ -35,6 +42,9 @@ const tempoCharge = tempo({
35
42
 
36
43
  const gatedCharge = conditionGate(tempoCharge, {
37
44
  apiKey: process.env.INSUMER_API_KEY,
45
+ // Return only a payer this method has PROVEN for this request, else null.
46
+ // The argument is mppx's method-specific validation `details`.
47
+ provenPayer: (details) => (details as { payer?: string }).payer ?? null,
38
48
  conditions: [{
39
49
  type: 'nft_ownership',
40
50
  contractAddress: '0xYourNFT',
@@ -176,7 +186,7 @@ Either way, set `INSUMER_API_KEY` as an environment variable in your runtime.
176
186
 
177
187
  ## Supported chains
178
188
 
179
- 30 EVM chains (Ethereum, Base, Polygon, Arbitrum, Optimism, BNB, Avalanche, and 23 more) + Solana + XRPL + Bitcoin. EAS conditions evaluate on EVM chains only. Farcaster always on Optimism.
189
+ 32 EVM chains (Ethereum, Base, Polygon, Arbitrum, Optimism, BNB, Avalanche, Robinhood Chain, and 24 more) + Solana + XRPL + Bitcoin — the 35 chains this adapter's wallet handling reaches. The engine itself covers 38 (adding Tron, Stellar, and Sui via InsumerAPI directly). EAS conditions evaluate on EVM chains only. Farcaster always on Optimism.
180
190
 
181
191
  [Full chain list](https://insumermodel.com/developers/api-reference/)
182
192
 
@@ -222,6 +232,24 @@ The condition shapes for `token_balance` and `nft_ownership` are unchanged. `eas
222
232
 
223
233
  The `parsXrplDid` typo from v1 is fixed: use `parseXrplDid`. The cache helper renamed: `clearTokenGateCache` is now `clearConditionGateCache`.
224
234
 
235
+ ## Migrating from 2.x (security release)
236
+
237
+ 3.0.0 fixes an authentication bypass ([GHSA-jg6q-3qfh-r9f8](https://github.com/douglasborthwick-crypto/mppx-condition-gate/security/advisories/GHSA-jg6q-3qfh-r9f8)). All 2.x versions, and all versions of the predecessor `@insumermodel/mppx-token-gate`, are affected.
238
+
239
+ Add a `provenPayer` resolver:
240
+
241
+ ```diff
242
+ const gated = conditionGate(server, {
243
+ apiKey: process.env.INSUMER_API_KEY,
244
+ + provenPayer: (details) => (details as { payer?: string }).payer ?? null,
245
+ conditions: [ ... ],
246
+ })
247
+ ```
248
+
249
+ Without it the gate compiles and runs, but never grants free access — every request takes the paid path. That is deliberate: the insecure default is gone, and the safe default is to charge.
250
+
251
+ Your method must expose mppx's `validate` hook. Legacy `verify`-only methods have no non-mutating pre-check, so they are never gated.
252
+
225
253
  ## License
226
254
 
227
255
  MIT
package/dist/index.d.ts CHANGED
@@ -77,9 +77,42 @@ export type RatioToSupplyCondition = {
77
77
  };
78
78
  /** Any condition accepted by /v1/attest */
79
79
  export type Condition = TokenBalanceCondition | NftOwnershipCondition | EasAttestationCondition | FarcasterIdCondition | RatioToAmountCondition | RatioToSupplyCondition;
80
+ /** Wallet family for a proven payer. */
81
+ export type WalletType = 'evm' | 'solana' | 'xrpl' | 'bitcoin';
82
+ /**
83
+ * A payer the caller has cryptographically proven for this request.
84
+ *
85
+ * Accepts a `did:pkh:...` string, a bare `0x` EVM address, or an explicit
86
+ * `{ address, type }` pair. Bare non-EVM addresses are rejected because their
87
+ * wallet family cannot be inferred unambiguously — pass the object form.
88
+ */
89
+ export type ProvenPayer = string | {
90
+ address: string;
91
+ type: WalletType;
92
+ } | null | undefined;
80
93
  export type ConditionGateOptions = {
81
94
  /** InsumerAPI key. Falls back to INSUMER_API_KEY env var. */
82
95
  apiKey?: string;
96
+ /**
97
+ * Resolves the payer that the payment method has PROVEN controls this
98
+ * request. Required for free access — without it every request takes the
99
+ * paid path.
100
+ *
101
+ * It receives only mppx's method-specific validation `details` (for example
102
+ * a recovered payer address). It is deliberately NOT given the credential or
103
+ * the declared `source`: mppx documents `source` as "an asserted identity,
104
+ * not independent proof of control", and granting on it is the vulnerability
105
+ * fixed in 3.0.0 (GHSA-jg6q-3qfh-r9f8).
106
+ *
107
+ * Return `null` when no payer has been proven. Returning an address you have
108
+ * not proven reintroduces that vulnerability.
109
+ *
110
+ * @example
111
+ * ```ts
112
+ * provenPayer: (details) => (details as { payer?: string }).payer ?? null
113
+ * ```
114
+ */
115
+ provenPayer?: (details: unknown) => ProvenPayer | Promise<ProvenPayer>;
83
116
  /** One or more conditions to evaluate. Mix any of the six types. */
84
117
  conditions: Condition[];
85
118
  /** Whether the wallet must satisfy "any" (default) or "all" conditions. */
@@ -142,18 +175,37 @@ export declare function parseSolanaDid(source: string): string | null;
142
175
  export declare function parseXrplDid(source: string): string | null;
143
176
  /** Extracts a Bitcoin address from a `did:pkh:bip122:{chainId}:{address}` string. */
144
177
  export declare function parseBitcoinDid(source: string): string | null;
178
+ /**
179
+ * Normalizes a caller-supplied proven payer into an address + wallet family.
180
+ *
181
+ * Fail-closed: anything it cannot resolve unambiguously returns null, which
182
+ * sends the request to the paid path.
183
+ */
184
+ export declare function normalizeProvenPayer(payer: ProvenPayer): {
185
+ address: string;
186
+ type: WalletType;
187
+ } | null;
145
188
  /**
146
189
  * Wraps an mppx Method.Server with condition-based access using signed attestations.
147
190
  *
148
- * Extracts the payer address from credential.source (DID), calls /v1/attest to
149
- * evaluate conditions across 33 chains, and returns a free-access receipt for
150
- * wallets that meet the conditions. Wallets that do not meet them fall through
151
- * to the original payment method.
191
+ * Free access requires a PROVEN payer. The gate calls the method's non-mutating
192
+ * `validate` hook, hands the resulting method-specific `details` to your
193
+ * `provenPayer` resolver, and only then evaluates conditions. It never reads
194
+ * `credential.source` — mppx documents that field as an asserted identity
195
+ * rather than proof of control.
196
+ *
197
+ * The gate falls through to the paid path whenever free access cannot be
198
+ * justified: no `provenPayer` resolver, no `validate` hook on the method
199
+ * (legacy `verify`-only methods included), a resolver returning null, a
200
+ * credential that fails validation, conditions not met, or an attestation
201
+ * error. There is no path from an unproven wallet to a free receipt.
152
202
  *
153
- * Supports six condition types: token_balance, nft_ownership, eas_attestation,
154
- * farcaster_id, ratio_to_amount (balance >= multiple * amount), and ratio_to_supply
155
- * (balance / totalSupply >= minFraction; EVM + ERC-20 only). Conditions can be mixed
156
- * in a single call.
203
+ * Conditions are evaluated across the 35 chains this adapter reaches (32 EVM +
204
+ * Solana + XRPL + Bitcoin; the engine itself covers 38). Six condition types
205
+ * are typed here: token_balance, nft_ownership, eas_attestation, farcaster_id,
206
+ * ratio_to_amount, and ratio_to_supply. InsumerAPI also offers evm_view_call,
207
+ * erc8004_agent, and erc7710_delegation; those are not typed or normalized
208
+ * here, so call /v1/attest directly if you need them.
157
209
  *
158
210
  * The attestation is ECDSA P-256 signed and verifiable offline via the public
159
211
  * JWKS at https://insumermodel.com/.well-known/jwks.json.
@@ -163,6 +215,8 @@ export declare function parseBitcoinDid(source: string): string | null;
163
215
  * import { conditionGate } from '@insumermodel/mppx-condition-gate'
164
216
  *
165
217
  * const gated = conditionGate(tempoCharge, {
218
+ * // Return only a payer this method has proven for THIS request.
219
+ * provenPayer: (details) => (details as { payer?: string }).payer ?? null,
166
220
  * conditions: [
167
221
  * { type: 'eas_attestation', template: 'coinbase_verified_account', chainId: 8453 },
168
222
  * { type: 'farcaster_id' },
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -177,18 +177,61 @@ async function callAttest(wallet, walletType, conditions, options) {
177
177
  // ---------------------------------------------------------------------------
178
178
  // conditionGate adapter
179
179
  // ---------------------------------------------------------------------------
180
+ /**
181
+ * Normalizes a caller-supplied proven payer into an address + wallet family.
182
+ *
183
+ * Fail-closed: anything it cannot resolve unambiguously returns null, which
184
+ * sends the request to the paid path.
185
+ */
186
+ export function normalizeProvenPayer(payer) {
187
+ if (!payer)
188
+ return null;
189
+ if (typeof payer === 'object') {
190
+ const { address, type } = payer;
191
+ if (!address || !type)
192
+ return null;
193
+ return { address, type };
194
+ }
195
+ if (typeof payer !== 'string')
196
+ return null;
197
+ const evm = parseDid(payer);
198
+ if (evm)
199
+ return { address: evm, type: 'evm' };
200
+ const sol = parseSolanaDid(payer);
201
+ if (sol)
202
+ return { address: sol, type: 'solana' };
203
+ const xrpl = parseXrplDid(payer);
204
+ if (xrpl)
205
+ return { address: xrpl, type: 'xrpl' };
206
+ const btc = parseBitcoinDid(payer);
207
+ if (btc)
208
+ return { address: btc, type: 'bitcoin' };
209
+ // Bare EVM address is unambiguous; anything else needs the object form.
210
+ if (payer.startsWith('0x'))
211
+ return { address: payer, type: 'evm' };
212
+ return null;
213
+ }
180
214
  /**
181
215
  * Wraps an mppx Method.Server with condition-based access using signed attestations.
182
216
  *
183
- * Extracts the payer address from credential.source (DID), calls /v1/attest to
184
- * evaluate conditions across 33 chains, and returns a free-access receipt for
185
- * wallets that meet the conditions. Wallets that do not meet them fall through
186
- * to the original payment method.
217
+ * Free access requires a PROVEN payer. The gate calls the method's non-mutating
218
+ * `validate` hook, hands the resulting method-specific `details` to your
219
+ * `provenPayer` resolver, and only then evaluates conditions. It never reads
220
+ * `credential.source` — mppx documents that field as an asserted identity
221
+ * rather than proof of control.
222
+ *
223
+ * The gate falls through to the paid path whenever free access cannot be
224
+ * justified: no `provenPayer` resolver, no `validate` hook on the method
225
+ * (legacy `verify`-only methods included), a resolver returning null, a
226
+ * credential that fails validation, conditions not met, or an attestation
227
+ * error. There is no path from an unproven wallet to a free receipt.
187
228
  *
188
- * Supports six condition types: token_balance, nft_ownership, eas_attestation,
189
- * farcaster_id, ratio_to_amount (balance >= multiple * amount), and ratio_to_supply
190
- * (balance / totalSupply >= minFraction; EVM + ERC-20 only). Conditions can be mixed
191
- * in a single call.
229
+ * Conditions are evaluated across the 35 chains this adapter reaches (32 EVM +
230
+ * Solana + XRPL + Bitcoin; the engine itself covers 38). Six condition types
231
+ * are typed here: token_balance, nft_ownership, eas_attestation, farcaster_id,
232
+ * ratio_to_amount, and ratio_to_supply. InsumerAPI also offers evm_view_call,
233
+ * erc8004_agent, and erc7710_delegation; those are not typed or normalized
234
+ * here, so call /v1/attest directly if you need them.
192
235
  *
193
236
  * The attestation is ECDSA P-256 signed and verifiable offline via the public
194
237
  * JWKS at https://insumermodel.com/.well-known/jwks.json.
@@ -198,6 +241,8 @@ async function callAttest(wallet, walletType, conditions, options) {
198
241
  * import { conditionGate } from '@insumermodel/mppx-condition-gate'
199
242
  *
200
243
  * const gated = conditionGate(tempoCharge, {
244
+ * // Return only a payer this method has proven for THIS request.
245
+ * provenPayer: (details) => (details as { payer?: string }).payer ?? null,
201
246
  * conditions: [
202
247
  * { type: 'eas_attestation', template: 'coinbase_verified_account', chainId: 8453 },
203
248
  * { type: 'farcaster_id' },
@@ -209,87 +254,81 @@ async function callAttest(wallet, walletType, conditions, options) {
209
254
  * ```
210
255
  */
211
256
  export function conditionGate(server, options) {
212
- const { conditions, matchMode = 'any', cacheTtlSeconds = 300 } = options;
213
- const originalVerify = server.verify;
214
- const gatedVerify = async (params) => {
215
- const credential = params.credential;
216
- const source = credential.source;
217
- // No DID → fall through to payment
218
- if (!source)
219
- return originalVerify(params);
220
- // Determine wallet type and address
221
- let wallet = null;
222
- let walletType = 'evm';
223
- wallet = parseDid(source);
224
- if (!wallet) {
225
- wallet = parseSolanaDid(source);
226
- if (wallet)
227
- walletType = 'solana';
257
+ const { conditions, matchMode = 'any', cacheTtlSeconds = 300, provenPayer } = options;
258
+ const anyServer = server;
259
+ const originalVerify = anyServer.verify;
260
+ const originalBroadcast = anyServer.broadcast;
261
+ const originalValidate = anyServer.validate;
262
+ // Free access is only reachable when BOTH exist: a resolver to supply the
263
+ // proven payer, and a non-mutating validate hook to derive it from. A method
264
+ // without `validate` (legacy verify-only, or broadcast-without-validate) has
265
+ // no safe pre-check, so it is never gated.
266
+ const canGate = typeof provenPayer === 'function' && typeof originalValidate === 'function';
267
+ /** Returns a free receipt, or null to take the paid path. */
268
+ async function tryFree(params) {
269
+ if (!canGate)
270
+ return null;
271
+ let details;
272
+ try {
273
+ const validation = await originalValidate(params);
274
+ details = validation?.details;
228
275
  }
229
- if (!wallet) {
230
- wallet = parseXrplDid(source);
231
- if (wallet)
232
- walletType = 'xrpl';
276
+ catch {
277
+ // Credential is not currently acceptable → let the payment method decide.
278
+ return null;
233
279
  }
234
- if (!wallet) {
235
- wallet = parseBitcoinDid(source);
236
- if (wallet)
237
- walletType = 'bitcoin';
280
+ let resolved;
281
+ try {
282
+ resolved = await provenPayer(details);
283
+ }
284
+ catch {
285
+ return null;
238
286
  }
239
- // Unparseable DID → fall through to payment
240
- if (!wallet)
241
- return originalVerify(params);
242
- // Check cache
243
- const key = cacheKey(wallet, conditions);
287
+ const payer = normalizeProvenPayer(resolved);
288
+ if (!payer)
289
+ return null;
290
+ const key = cacheKey(payer.address, conditions);
244
291
  const cached = cache.get(key);
245
292
  if (cached && cached.expiresAt > Date.now()) {
246
- if (cached.pass) {
247
- return {
248
- method: server.name,
249
- reference: `condition-gate:free:${cached.attestationId}`,
250
- status: 'success',
251
- timestamp: new Date().toISOString(),
252
- };
253
- }
254
- // Cached non-holder → fall through
255
- return originalVerify(params);
293
+ if (!cached.pass)
294
+ return null;
295
+ return {
296
+ method: server.name,
297
+ reference: `condition-gate:free:${cached.attestationId}`,
298
+ status: 'success',
299
+ timestamp: new Date().toISOString(),
300
+ };
256
301
  }
257
- // Call InsumerAPI
258
302
  try {
259
- const result = await callAttest(wallet, walletType, conditions, options);
303
+ const result = await callAttest(payer.address, payer.type, conditions, options);
260
304
  const attestation = result.data.attestation;
261
- // Determine pass based on matchMode
262
- let pass;
263
- if (matchMode === 'all') {
264
- pass = attestation.pass; // all conditions must be met
265
- }
266
- else {
267
- // "any" — at least one condition met
268
- pass = attestation.results.some((r) => r.met);
269
- }
270
- // Cache the result
305
+ const pass = matchMode === 'all'
306
+ ? attestation.pass
307
+ : attestation.results.some((r) => r.met);
271
308
  cache.set(key, {
272
309
  pass,
273
310
  attestationId: attestation.id,
274
311
  expiresAt: Date.now() + cacheTtlSeconds * 1000,
275
312
  });
276
- if (pass) {
277
- return {
278
- method: server.name,
279
- reference: `condition-gate:free:${attestation.id}`,
280
- status: 'success',
281
- timestamp: new Date().toISOString(),
282
- };
283
- }
313
+ if (!pass)
314
+ return null;
315
+ return {
316
+ method: server.name,
317
+ reference: `condition-gate:free:${attestation.id}`,
318
+ status: 'success',
319
+ timestamp: new Date().toISOString(),
320
+ };
284
321
  }
285
322
  catch {
286
- // Attestation API error → fall through to payment (fail open)
323
+ // Attestation error → paid path.
324
+ return null;
287
325
  }
288
- return originalVerify(params);
289
- };
290
- return {
291
- ...server,
292
- verify: gatedVerify,
293
- };
326
+ }
327
+ const wrapped = { ...server };
328
+ if (typeof originalBroadcast === 'function') {
329
+ wrapped.broadcast = async (params) => (await tryFree(params)) ?? originalBroadcast(params);
330
+ }
331
+ wrapped.verify = async (params) => (await tryFree(params)) ?? originalVerify(params);
332
+ return wrapped;
294
333
  }
295
334
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@insumermodel/mppx-condition-gate",
3
- "version": "2.0.2",
3
+ "version": "3.0.0",
4
4
  "description": "Condition-based access for mppx routes. Wallet auth via signed attestations. Six condition types: token balance, NFT ownership, EAS attestation, Farcaster ID, ratio_to_amount, ratio_to_supply.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -17,7 +17,8 @@
17
17
  ],
18
18
  "scripts": {
19
19
  "build": "tsc",
20
- "prepublishOnly": "npm run build"
20
+ "prepublishOnly": "npm run build",
21
+ "test": "tsc && node --test test/*.test.mjs"
21
22
  },
22
23
  "keywords": [
23
24
  "condition-based-access",
package/src/index.ts CHANGED
@@ -101,9 +101,45 @@ export type Condition =
101
101
  | RatioToAmountCondition
102
102
  | RatioToSupplyCondition
103
103
 
104
+ /** Wallet family for a proven payer. */
105
+ export type WalletType = 'evm' | 'solana' | 'xrpl' | 'bitcoin'
106
+
107
+ /**
108
+ * A payer the caller has cryptographically proven for this request.
109
+ *
110
+ * Accepts a `did:pkh:...` string, a bare `0x` EVM address, or an explicit
111
+ * `{ address, type }` pair. Bare non-EVM addresses are rejected because their
112
+ * wallet family cannot be inferred unambiguously — pass the object form.
113
+ */
114
+ export type ProvenPayer =
115
+ | string
116
+ | { address: string; type: WalletType }
117
+ | null
118
+ | undefined
119
+
104
120
  export type ConditionGateOptions = {
105
121
  /** InsumerAPI key. Falls back to INSUMER_API_KEY env var. */
106
122
  apiKey?: string
123
+ /**
124
+ * Resolves the payer that the payment method has PROVEN controls this
125
+ * request. Required for free access — without it every request takes the
126
+ * paid path.
127
+ *
128
+ * It receives only mppx's method-specific validation `details` (for example
129
+ * a recovered payer address). It is deliberately NOT given the credential or
130
+ * the declared `source`: mppx documents `source` as "an asserted identity,
131
+ * not independent proof of control", and granting on it is the vulnerability
132
+ * fixed in 3.0.0 (GHSA-jg6q-3qfh-r9f8).
133
+ *
134
+ * Return `null` when no payer has been proven. Returning an address you have
135
+ * not proven reintroduces that vulnerability.
136
+ *
137
+ * @example
138
+ * ```ts
139
+ * provenPayer: (details) => (details as { payer?: string }).payer ?? null
140
+ * ```
141
+ */
142
+ provenPayer?: (details: unknown) => ProvenPayer | Promise<ProvenPayer>
107
143
  /** One or more conditions to evaluate. Mix any of the six types. */
108
144
  conditions: Condition[]
109
145
  /** Whether the wallet must satisfy "any" (default) or "all" conditions. */
@@ -343,18 +379,60 @@ async function callAttest(
343
379
  // conditionGate adapter
344
380
  // ---------------------------------------------------------------------------
345
381
 
382
+ /**
383
+ * Normalizes a caller-supplied proven payer into an address + wallet family.
384
+ *
385
+ * Fail-closed: anything it cannot resolve unambiguously returns null, which
386
+ * sends the request to the paid path.
387
+ */
388
+ export function normalizeProvenPayer(
389
+ payer: ProvenPayer,
390
+ ): { address: string; type: WalletType } | null {
391
+ if (!payer) return null
392
+
393
+ if (typeof payer === 'object') {
394
+ const { address, type } = payer
395
+ if (!address || !type) return null
396
+ return { address, type }
397
+ }
398
+
399
+ if (typeof payer !== 'string') return null
400
+
401
+ const evm = parseDid(payer)
402
+ if (evm) return { address: evm, type: 'evm' }
403
+ const sol = parseSolanaDid(payer)
404
+ if (sol) return { address: sol, type: 'solana' }
405
+ const xrpl = parseXrplDid(payer)
406
+ if (xrpl) return { address: xrpl, type: 'xrpl' }
407
+ const btc = parseBitcoinDid(payer)
408
+ if (btc) return { address: btc, type: 'bitcoin' }
409
+
410
+ // Bare EVM address is unambiguous; anything else needs the object form.
411
+ if (payer.startsWith('0x')) return { address: payer, type: 'evm' }
412
+ return null
413
+ }
414
+
346
415
  /**
347
416
  * Wraps an mppx Method.Server with condition-based access using signed attestations.
348
417
  *
349
- * Extracts the payer address from credential.source (DID), calls /v1/attest to
350
- * evaluate conditions across 33 chains, and returns a free-access receipt for
351
- * wallets that meet the conditions. Wallets that do not meet them fall through
352
- * to the original payment method.
418
+ * Free access requires a PROVEN payer. The gate calls the method's non-mutating
419
+ * `validate` hook, hands the resulting method-specific `details` to your
420
+ * `provenPayer` resolver, and only then evaluates conditions. It never reads
421
+ * `credential.source` — mppx documents that field as an asserted identity
422
+ * rather than proof of control.
423
+ *
424
+ * The gate falls through to the paid path whenever free access cannot be
425
+ * justified: no `provenPayer` resolver, no `validate` hook on the method
426
+ * (legacy `verify`-only methods included), a resolver returning null, a
427
+ * credential that fails validation, conditions not met, or an attestation
428
+ * error. There is no path from an unproven wallet to a free receipt.
353
429
  *
354
- * Supports six condition types: token_balance, nft_ownership, eas_attestation,
355
- * farcaster_id, ratio_to_amount (balance >= multiple * amount), and ratio_to_supply
356
- * (balance / totalSupply >= minFraction; EVM + ERC-20 only). Conditions can be mixed
357
- * in a single call.
430
+ * Conditions are evaluated across the 35 chains this adapter reaches (32 EVM +
431
+ * Solana + XRPL + Bitcoin; the engine itself covers 38). Six condition types
432
+ * are typed here: token_balance, nft_ownership, eas_attestation, farcaster_id,
433
+ * ratio_to_amount, and ratio_to_supply. InsumerAPI also offers evm_view_call,
434
+ * erc8004_agent, and erc7710_delegation; those are not typed or normalized
435
+ * here, so call /v1/attest directly if you need them.
358
436
  *
359
437
  * The attestation is ECDSA P-256 signed and verifiable offline via the public
360
438
  * JWKS at https://insumermodel.com/.well-known/jwks.json.
@@ -364,6 +442,8 @@ async function callAttest(
364
442
  * import { conditionGate } from '@insumermodel/mppx-condition-gate'
365
443
  *
366
444
  * const gated = conditionGate(tempoCharge, {
445
+ * // Return only a payer this method has proven for THIS request.
446
+ * provenPayer: (details) => (details as { payer?: string }).payer ?? null,
367
447
  * conditions: [
368
448
  * { type: 'eas_attestation', template: 'coinbase_verified_account', chainId: 8453 },
369
449
  * { type: 'farcaster_id' },
@@ -378,92 +458,97 @@ export function conditionGate(
378
458
  server: Method.AnyServer,
379
459
  options: ConditionGateOptions,
380
460
  ): Method.AnyServer {
381
- const { conditions, matchMode = 'any', cacheTtlSeconds = 300 } = options
461
+ const { conditions, matchMode = 'any', cacheTtlSeconds = 300, provenPayer } = options
382
462
 
383
- const originalVerify = server.verify
463
+ const anyServer = server as unknown as {
464
+ verify: (params: any) => Promise<any>
465
+ broadcast?: (params: any) => Promise<any>
466
+ validate?: (params: any) => Promise<any>
467
+ }
384
468
 
385
- const gatedVerify: typeof originalVerify = async (params: any) => {
386
- const credential = params.credential as { source?: string }
387
- const source = credential.source
469
+ const originalVerify = anyServer.verify
470
+ const originalBroadcast = anyServer.broadcast
471
+ const originalValidate = anyServer.validate
388
472
 
389
- // No DID → fall through to payment
390
- if (!source) return originalVerify(params)
473
+ // Free access is only reachable when BOTH exist: a resolver to supply the
474
+ // proven payer, and a non-mutating validate hook to derive it from. A method
475
+ // without `validate` (legacy verify-only, or broadcast-without-validate) has
476
+ // no safe pre-check, so it is never gated.
477
+ const canGate =
478
+ typeof provenPayer === 'function' && typeof originalValidate === 'function'
391
479
 
392
- // Determine wallet type and address
393
- let wallet: string | null = null
394
- let walletType: 'evm' | 'solana' | 'xrpl' | 'bitcoin' = 'evm'
480
+ /** Returns a free receipt, or null to take the paid path. */
481
+ async function tryFree(params: any): Promise<any | null> {
482
+ if (!canGate) return null
395
483
 
396
- wallet = parseDid(source)
397
- if (!wallet) {
398
- wallet = parseSolanaDid(source)
399
- if (wallet) walletType = 'solana'
400
- }
401
- if (!wallet) {
402
- wallet = parseXrplDid(source)
403
- if (wallet) walletType = 'xrpl'
484
+ let details: unknown
485
+ try {
486
+ const validation = await originalValidate!(params)
487
+ details = (validation as { details?: unknown } | undefined)?.details
488
+ } catch {
489
+ // Credential is not currently acceptable → let the payment method decide.
490
+ return null
404
491
  }
405
- if (!wallet) {
406
- wallet = parseBitcoinDid(source)
407
- if (wallet) walletType = 'bitcoin'
492
+
493
+ let resolved: ProvenPayer
494
+ try {
495
+ resolved = await provenPayer!(details)
496
+ } catch {
497
+ return null
408
498
  }
409
499
 
410
- // Unparseable DID → fall through to payment
411
- if (!wallet) return originalVerify(params)
500
+ const payer = normalizeProvenPayer(resolved)
501
+ if (!payer) return null
412
502
 
413
- // Check cache
414
- const key = cacheKey(wallet, conditions)
503
+ const key = cacheKey(payer.address, conditions)
415
504
  const cached = cache.get(key)
416
505
  if (cached && cached.expiresAt > Date.now()) {
417
- if (cached.pass) {
418
- return {
419
- method: server.name,
420
- reference: `condition-gate:free:${cached.attestationId}`,
421
- status: 'success' as const,
422
- timestamp: new Date().toISOString(),
423
- }
506
+ if (!cached.pass) return null
507
+ return {
508
+ method: server.name,
509
+ reference: `condition-gate:free:${cached.attestationId}`,
510
+ status: 'success' as const,
511
+ timestamp: new Date().toISOString(),
424
512
  }
425
- // Cached non-holder → fall through
426
- return originalVerify(params)
427
513
  }
428
514
 
429
- // Call InsumerAPI
430
515
  try {
431
- const result = await callAttest(wallet, walletType, conditions, options)
516
+ const result = await callAttest(payer.address, payer.type, conditions, options)
432
517
  const attestation = result.data.attestation
433
518
 
434
- // Determine pass based on matchMode
435
- let pass: boolean
436
- if (matchMode === 'all') {
437
- pass = attestation.pass // all conditions must be met
438
- } else {
439
- // "any" — at least one condition met
440
- pass = attestation.results.some((r) => r.met)
441
- }
519
+ const pass =
520
+ matchMode === 'all'
521
+ ? attestation.pass
522
+ : attestation.results.some((r) => r.met)
442
523
 
443
- // Cache the result
444
524
  cache.set(key, {
445
525
  pass,
446
526
  attestationId: attestation.id,
447
527
  expiresAt: Date.now() + cacheTtlSeconds * 1000,
448
528
  })
449
529
 
450
- if (pass) {
451
- return {
452
- method: server.name,
453
- reference: `condition-gate:free:${attestation.id}`,
454
- status: 'success' as const,
455
- timestamp: new Date().toISOString(),
456
- }
530
+ if (!pass) return null
531
+ return {
532
+ method: server.name,
533
+ reference: `condition-gate:free:${attestation.id}`,
534
+ status: 'success' as const,
535
+ timestamp: new Date().toISOString(),
457
536
  }
458
537
  } catch {
459
- // Attestation API error → fall through to payment (fail open)
538
+ // Attestation error → paid path.
539
+ return null
460
540
  }
461
-
462
- return originalVerify(params)
463
541
  }
464
542
 
465
- return {
466
- ...server,
467
- verify: gatedVerify,
543
+ const wrapped = { ...server } as unknown as Record<string, unknown>
544
+
545
+ if (typeof originalBroadcast === 'function') {
546
+ wrapped.broadcast = async (params: any) =>
547
+ (await tryFree(params)) ?? originalBroadcast(params)
468
548
  }
549
+
550
+ wrapped.verify = async (params: any) =>
551
+ (await tryFree(params)) ?? originalVerify(params)
552
+
553
+ return wrapped as unknown as Method.AnyServer
469
554
  }