@insumermodel/mppx-condition-gate 3.0.2 → 3.1.1
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 +80 -16
- package/dist/index.d.ts +88 -17
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +360 -44
- package/dist/index.js.map +1 -1
- package/package.json +5 -9
- package/src/index.ts +440 -60
package/README.md
CHANGED
|
@@ -15,6 +15,8 @@ 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
|
+
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
|
+
|
|
18
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
|
|
@@ -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
|
|
|
@@ -69,7 +131,6 @@ Mix any of the six in a single call. `matchMode: 'any'` (default) passes when an
|
|
|
69
131
|
contractAddress: '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', // USDC
|
|
70
132
|
chainId: 1,
|
|
71
133
|
threshold: '1000', // decimal string in token units; numbers are converted before sending
|
|
72
|
-
decimals: 6,
|
|
73
134
|
label: 'USDC >= 1000',
|
|
74
135
|
}
|
|
75
136
|
```
|
|
@@ -124,29 +185,29 @@ Always evaluated on Optimism (chain 10). Passes if the wallet has any FID regist
|
|
|
124
185
|
|
|
125
186
|
### Ratio to amount
|
|
126
187
|
|
|
127
|
-
Self-scaling spend rule: passes when the wallet holds at least `multiple` times a per-request `amount`.
|
|
188
|
+
Self-scaling spend rule: passes when the wallet holds at least `multiple` times a per-request `amount`. EVM chains only. `multiple` and `amount` go to the API as decimal strings; pass strings, and a number is converted before sending.
|
|
128
189
|
|
|
129
190
|
```ts
|
|
130
191
|
{
|
|
131
192
|
type: 'ratio_to_amount',
|
|
132
193
|
contractAddress: 'native', // or an ERC-20 address
|
|
133
194
|
chainId: 8453,
|
|
134
|
-
multiple: 10,
|
|
135
|
-
amount: 250,
|
|
195
|
+
multiple: '10',
|
|
196
|
+
amount: '250', // token units, as a decimal string
|
|
136
197
|
label: 'Holds >= 10x the 250-unit spend',
|
|
137
198
|
}
|
|
138
199
|
```
|
|
139
200
|
|
|
140
201
|
### Ratio to supply
|
|
141
202
|
|
|
142
|
-
Share-of-supply rule: passes when the wallet holds at least `minFraction` of the token's on-chain total supply. For project/governance tokens, not stablecoins.
|
|
203
|
+
Share-of-supply rule: passes when the wallet holds at least `minFraction` of the token's on-chain total supply. For project/governance tokens, not stablecoins. EVM chains, ERC-20 contracts only. `minFraction` goes to the API as a decimal string.
|
|
143
204
|
|
|
144
205
|
```ts
|
|
145
206
|
{
|
|
146
207
|
type: 'ratio_to_supply',
|
|
147
208
|
contractAddress: '0x1f9840a85d5aF5bf1D1762F925BdADdC4201F984', // UNI
|
|
148
209
|
chainId: 1,
|
|
149
|
-
minFraction: 0.005, // 0.5% of supply
|
|
210
|
+
minFraction: '0.005', // 0.5% of supply
|
|
150
211
|
label: 'Holds >= 0.5% of UNI supply',
|
|
151
212
|
}
|
|
152
213
|
```
|
|
@@ -182,10 +243,13 @@ Either way, set `INSUMER_API_KEY` as an environment variable in your runtime.
|
|
|
182
243
|
| `matchMode` | `'any' \| 'all'` | `'any'` | Wallet must satisfy any or all conditions |
|
|
183
244
|
| `cacheTtlSeconds` | `number` | `300` | In-memory cache TTL |
|
|
184
245
|
| `apiBaseUrl` | `string` | `https://api.insumermodel.com` | API base URL override |
|
|
246
|
+
| `provenPayer` | `(details) => ProvenPayer` | none | Returns the payer the method proved; required for free access |
|
|
247
|
+
| `replayStore` | `AtomicStore` | bounded in-memory, per process | Records used credentials; must be atomic; share it across instances |
|
|
248
|
+
| `maxCredentialLifetimeSeconds` | `number` | `600` | Longest remaining validity a credential may have and still get free access |
|
|
185
249
|
|
|
186
250
|
## Supported chains
|
|
187
251
|
|
|
188
|
-
|
|
252
|
+
31 EVM chains (Ethereum, Base, Polygon, Arbitrum, Optimism, BNB, Avalanche, Robinhood Chain, and 23 more) + Solana + XRPL + Bitcoin: the 34 chains this adapter's wallet handling reaches. The engine itself covers 37 (adding Tron, Stellar, and Sui via InsumerAPI directly). NFT ownership evaluates on the 31 EVM chains, Solana and XRPL. EAS conditions evaluate on five chains: Ethereum, Optimism, Polygon, Base and Arbitrum. Farcaster always on Optimism.
|
|
189
253
|
|
|
190
254
|
[Full chain list](https://insumermodel.com/developers/api-reference/)
|
|
191
255
|
|
|
@@ -204,7 +268,7 @@ if (receipt.reference.startsWith('condition-gate:free:')) {
|
|
|
204
268
|
}
|
|
205
269
|
```
|
|
206
270
|
|
|
207
|
-
##
|
|
271
|
+
## When the API is unreachable
|
|
208
272
|
|
|
209
273
|
If the attestation API is unreachable, the adapter falls through to the original payment method. Wallets that would have qualified for free access pay normally; everyone else is unaffected.
|
|
210
274
|
|
package/dist/index.d.ts
CHANGED
|
@@ -3,14 +3,18 @@ export type ChainId = number | 'solana' | 'xrpl' | 'bitcoin';
|
|
|
3
3
|
/** ERC-20 / SPL / XRPL trust-line / native balance check */
|
|
4
4
|
export type TokenBalanceCondition = {
|
|
5
5
|
type: 'token_balance';
|
|
6
|
-
/** Token contract address.
|
|
6
|
+
/** Token contract address. Use "native" for the chain's own coin: the EVM native coin
|
|
7
|
+
* (ETH, BNB, ...), XRPL native XRP, SOL or Bitcoin. "native" is for token_balance and
|
|
8
|
+
* ratio_to_amount only; nft_ownership needs the NFT contract address. */
|
|
7
9
|
contractAddress: string;
|
|
8
10
|
chainId: ChainId;
|
|
9
11
|
/** Minimum balance in token units. Pass a decimal string (e.g. "1000") for
|
|
10
12
|
* full precision; keys minted today sign under the v2 scheme and reject a
|
|
11
13
|
* JSON number, so numbers are converted to strings before sending. Defaults to "1". */
|
|
12
14
|
threshold?: number | string;
|
|
13
|
-
/**
|
|
15
|
+
/** Optional. Leave it out: the token's own decimals are always read from the chain.
|
|
16
|
+
* If sent it is only a cross-check, and a value that differs from the token's own
|
|
17
|
+
* decimals is rejected with a 400. */
|
|
14
18
|
decimals?: number;
|
|
15
19
|
/** XRPL currency code (e.g. "USD", "RLUSD") for trust-line tokens. */
|
|
16
20
|
currency?: string;
|
|
@@ -20,6 +24,7 @@ export type TokenBalanceCondition = {
|
|
|
20
24
|
/** ERC-721 / ERC-1155 / Solana cNFT / XRPL NFT ownership check */
|
|
21
25
|
export type NftOwnershipCondition = {
|
|
22
26
|
type: 'nft_ownership';
|
|
27
|
+
/** NFT contract address (0x + 40 hex on EVM). "native" is not accepted here (400). */
|
|
23
28
|
contractAddress: string;
|
|
24
29
|
chainId: ChainId;
|
|
25
30
|
/** XRPL NFToken taxon filter. XRPL only. */
|
|
@@ -29,7 +34,7 @@ export type NftOwnershipCondition = {
|
|
|
29
34
|
/** EAS attestation check (Ethereum Attestation Service) */
|
|
30
35
|
export type EasAttestationCondition = {
|
|
31
36
|
type: 'eas_attestation';
|
|
32
|
-
/**
|
|
37
|
+
/** One of the five EAS chains: Ethereum (1), Optimism (10), Polygon (137), Base (8453), Arbitrum (42161). */
|
|
33
38
|
chainId: number;
|
|
34
39
|
/**
|
|
35
40
|
* Pre-configured compliance template. Mutually exclusive with schemaId.
|
|
@@ -53,28 +58,32 @@ export type FarcasterIdCondition = {
|
|
|
53
58
|
type: 'farcaster_id';
|
|
54
59
|
label?: string;
|
|
55
60
|
};
|
|
56
|
-
/** Self-scaling agent-spend check: met iff balance >= multiple * amount.
|
|
61
|
+
/** Self-scaling agent-spend check: met iff balance >= multiple * amount. EVM chains only. */
|
|
57
62
|
export type RatioToAmountCondition = {
|
|
58
63
|
type: 'ratio_to_amount';
|
|
59
64
|
/** Token contract address, or "native" for the chain's native asset. */
|
|
60
65
|
contractAddress: string;
|
|
61
|
-
/** EVM chain ID (ratio conditions are
|
|
66
|
+
/** EVM chain ID (ratio conditions are EVM only). */
|
|
62
67
|
chainId: number;
|
|
63
|
-
/** Collateralization multiple. Met iff balance >= multiple * amount.
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
amount
|
|
68
|
+
/** Collateralization multiple. Met iff balance >= multiple * amount. Pass a decimal
|
|
69
|
+
* string (e.g. "10"); a number is converted to a decimal string before sending. */
|
|
70
|
+
multiple: string | number;
|
|
71
|
+
/** Per-request reference amount in token/display units (e.g. "100" for 100 USDC, not base
|
|
72
|
+
* units), with no more decimal places than the token has. Pass a decimal string; a number
|
|
73
|
+
* is converted to a decimal string before sending. */
|
|
74
|
+
amount: string | number;
|
|
67
75
|
label?: string;
|
|
68
76
|
};
|
|
69
|
-
/** Share-of-supply check: met iff balance / totalSupply() >= minFraction.
|
|
77
|
+
/** Share-of-supply check: met iff balance / totalSupply() >= minFraction. EVM chains, ERC-20 only. */
|
|
70
78
|
export type RatioToSupplyCondition = {
|
|
71
79
|
type: 'ratio_to_supply';
|
|
72
80
|
/** ERC-20 token contract address (does not accept "native"). */
|
|
73
81
|
contractAddress: string;
|
|
74
|
-
/** EVM chain ID (ratio conditions are
|
|
82
|
+
/** EVM chain ID (ratio conditions are EVM only). */
|
|
75
83
|
chainId: number;
|
|
76
|
-
/** Required share of total supply, a fraction in (0, 1] (e.g. 0.005 for 0.5%).
|
|
77
|
-
|
|
84
|
+
/** Required share of total supply, a fraction in (0, 1] (e.g. "0.005" for 0.5%). Pass a
|
|
85
|
+
* decimal string; a number is converted to a decimal string before sending. */
|
|
86
|
+
minFraction: string | number;
|
|
78
87
|
label?: string;
|
|
79
88
|
};
|
|
80
89
|
/** Any condition accepted by /v1/attest */
|
|
@@ -133,6 +142,47 @@ export type ConditionGateOptions = {
|
|
|
133
142
|
* with `format: "jwt"` directly if you need the `jwt` and `pqJwt` tokens.
|
|
134
143
|
*/
|
|
135
144
|
jwt?: boolean;
|
|
145
|
+
/**
|
|
146
|
+
* Where the gate records credentials it has accepted, so each one gets
|
|
147
|
+
* through at most once. Defaults to a bounded in-process store.
|
|
148
|
+
*
|
|
149
|
+
* Pass a shared store when the route runs on more than one instance, or a
|
|
150
|
+
* credential used on one instance can be presented again on another. The
|
|
151
|
+
* store must claim atomically and remove expired entries: `Store.redis`,
|
|
152
|
+
* `Store.upstash` or `Store.cloudflare` from `mppx/server` built from a client
|
|
153
|
+
* that exposes an atomic `update`, or any store with an atomic `tryClaim`.
|
|
154
|
+
* mppx's `Store.memory()` never removes expired entries; use it only in tests.
|
|
155
|
+
*/
|
|
156
|
+
replayStore?: ReplayStore;
|
|
157
|
+
/**
|
|
158
|
+
* Longest remaining validity, in seconds, a credential may have and still be
|
|
159
|
+
* given free access. Defaults to 600. The gate has to remember a credential
|
|
160
|
+
* until it expires, and x402 clients choose their own expiry, so longer-lived
|
|
161
|
+
* credentials take the paid path instead.
|
|
162
|
+
*/
|
|
163
|
+
maxCredentialLifetimeSeconds?: number;
|
|
164
|
+
};
|
|
165
|
+
/**
|
|
166
|
+
* An atomic claim store. Structurally compatible with mppx's `AtomicStore`:
|
|
167
|
+
* `tryClaim` is used when present, otherwise `update`. `get`, when present,
|
|
168
|
+
* lets the gate refuse a repeat before spending an attestation on it, and
|
|
169
|
+
* `delete` (or `update`) lets it release a credential whose payment failed.
|
|
170
|
+
*/
|
|
171
|
+
export type ReplayStore = {
|
|
172
|
+
get?: (key: string) => unknown | Promise<unknown>;
|
|
173
|
+
delete?: (key: string) => void | Promise<void>;
|
|
174
|
+
tryClaim?: (key: string, expires: number) => boolean | Promise<boolean>;
|
|
175
|
+
update?: <result>(key: string, fn: (current: any) => {
|
|
176
|
+
op: 'noop';
|
|
177
|
+
result: result;
|
|
178
|
+
} | {
|
|
179
|
+
op: 'set';
|
|
180
|
+
value: any;
|
|
181
|
+
result: result;
|
|
182
|
+
} | {
|
|
183
|
+
op: 'delete';
|
|
184
|
+
result: result;
|
|
185
|
+
}) => Promise<result>;
|
|
136
186
|
};
|
|
137
187
|
export type InsumerAttestation = {
|
|
138
188
|
ok: boolean;
|
|
@@ -174,7 +224,7 @@ export type InsumerAttestation = {
|
|
|
174
224
|
creditsCharged: number;
|
|
175
225
|
};
|
|
176
226
|
};
|
|
177
|
-
/** Clear the in-memory ownership cache. Useful in tests. */
|
|
227
|
+
/** Clear the in-memory ownership cache and the default replay store. Useful in tests. */
|
|
178
228
|
export declare function clearConditionGateCache(): void;
|
|
179
229
|
/**
|
|
180
230
|
* Extracts an EVM address from a `did:pkh:eip155:{chainId}:{address}` string.
|
|
@@ -187,6 +237,16 @@ export declare function parseSolanaDid(source: string): string | null;
|
|
|
187
237
|
export declare function parseXrplDid(source: string): string | null;
|
|
188
238
|
/** Extracts a Bitcoin address from a `did:pkh:bip122:{chainId}:{address}` string. */
|
|
189
239
|
export declare function parseBitcoinDid(source: string): string | null;
|
|
240
|
+
/**
|
|
241
|
+
* Returns a quantity as a plain decimal string, the form the API takes for
|
|
242
|
+
* `threshold`, `multiple`, `amount` and `minFraction`.
|
|
243
|
+
*
|
|
244
|
+
* A string is returned trimmed and otherwise unchanged. A number is written
|
|
245
|
+
* without exponent notation: `String(1e-7)` is "1e-7" and `String(1e21)` is
|
|
246
|
+
* "1e+21", neither of which is a decimal string, so those are expanded to
|
|
247
|
+
* "0.0000001" and "1000000000000000000000". NaN and Infinity throw.
|
|
248
|
+
*/
|
|
249
|
+
export declare function toDecimalString(v: string | number): string;
|
|
190
250
|
/**
|
|
191
251
|
* Normalizes a caller-supplied proven payer into an address + wallet family.
|
|
192
252
|
*
|
|
@@ -212,8 +272,18 @@ export declare function normalizeProvenPayer(payer: ProvenPayer): {
|
|
|
212
272
|
* credential that fails validation, conditions not met, or an attestation
|
|
213
273
|
* error. There is no path from an unproven wallet to a free receipt.
|
|
214
274
|
*
|
|
215
|
-
*
|
|
216
|
-
*
|
|
275
|
+
* Each credential gets free access at most once. The gate records a
|
|
276
|
+
* credential when it grants free access, and records an authorization just
|
|
277
|
+
* before the paid path settles it; a recorded credential is refused with a
|
|
278
|
+
* verification error rather than passed on to payment. A payment that fails is
|
|
279
|
+
* 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
|
|
280
|
+
* (EIP-3009 authorizations and Tempo proofs) whose remaining validity is within
|
|
281
|
+
* `maxCredentialLifetimeSeconds`. The default store is bounded and shared by
|
|
282
|
+
* every gated route in the process; pass a shared `replayStore` for production
|
|
283
|
+
* traffic or when the route runs on more than one instance.
|
|
284
|
+
*
|
|
285
|
+
* Conditions are evaluated across the 34 chains this adapter reaches (31 EVM +
|
|
286
|
+
* Solana + XRPL + Bitcoin; the engine itself covers 37). Six condition types
|
|
217
287
|
* are typed here: token_balance, nft_ownership, eas_attestation, farcaster_id,
|
|
218
288
|
* ratio_to_amount, and ratio_to_supply. InsumerAPI also offers evm_view_call,
|
|
219
289
|
* erc8004_agent, and erc7710_delegation; those are not typed or normalized
|
|
@@ -226,8 +296,9 @@ export declare function normalizeProvenPayer(payer: ProvenPayer): {
|
|
|
226
296
|
* ```ts
|
|
227
297
|
* import { conditionGate } from '@insumermodel/mppx-condition-gate'
|
|
228
298
|
*
|
|
229
|
-
* const gated = conditionGate(
|
|
299
|
+
* const gated = conditionGate(evmCharge, {
|
|
230
300
|
* // Return only a payer this method has proven for THIS request.
|
|
301
|
+
* // mppx's EVM charge reports the recovered signer as `payer`.
|
|
231
302
|
* provenPayer: (details) => (details as { payer?: string }).payer ?? null,
|
|
232
303
|
* conditions: [
|
|
233
304
|
* { 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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"}
|