@metalntwx/metal-pay 0.2.0 → 0.3.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 +104 -38
- package/dist/clearing-abi.d.ts +1836 -0
- package/dist/clearing-abi.js +2361 -0
- package/dist/clearing-client.d.ts +96 -159
- package/dist/clearing-client.js +412 -553
- package/dist/clearing-codec.d.ts +57 -0
- package/dist/clearing-codec.js +173 -0
- package/dist/clearing-custody.d.ts +202 -0
- package/dist/clearing-custody.js +552 -0
- package/dist/clearing-server.d.ts +30 -49
- package/dist/clearing-server.js +87 -67
- package/dist/clearing-x402.d.ts +38 -0
- package/dist/clearing-x402.js +249 -0
- package/dist/client.d.ts +14 -15
- package/dist/client.js +53 -22
- package/dist/index.d.ts +4 -1
- package/dist/index.js +4 -1
- package/dist/mandates/account.d.ts +9 -4
- package/dist/mandates/account.js +15 -11
- package/dist/mandates/binding.d.ts +4 -27
- package/dist/mandates/binding.js +5 -9
- package/dist/mandates/checkout.js +5 -5
- package/dist/mandates/client.js +4 -3
- package/dist/mandates/l3a.d.ts +2 -2
- package/dist/mandates/l3a.js +5 -4
- package/dist/mandates/seller.d.ts +1 -1
- package/dist/mandates/seller.js +4 -4
- package/dist/mandates/verify.d.ts +4 -6
- package/dist/mandates/verify.js +147 -82
- package/dist/mandates/vi/credential.js +4 -4
- package/dist/networks.d.ts +9 -1
- package/dist/networks.js +105 -4
- package/dist/node.d.ts +11 -0
- package/dist/node.js +97 -0
- package/package.json +18 -11
- package/src/clearing-abi.ts +2361 -0
- package/src/clearing-client.test.ts +850 -0
- package/src/clearing-client.ts +612 -0
- package/src/clearing-codec.test.ts +57 -0
- package/src/clearing-codec.ts +251 -0
- package/src/clearing-custody.test.ts +763 -0
- package/src/clearing-custody.ts +743 -0
- package/src/clearing-fixture.json +37 -0
- package/src/clearing-server.test.ts +450 -0
- package/src/clearing-server.ts +123 -0
- package/src/clearing-x402.test.ts +181 -0
- package/src/clearing-x402.ts +328 -0
- package/src/client.test.ts +333 -0
- package/src/client.ts +195 -0
- package/src/index.ts +33 -0
- package/src/mandates/account.ts +95 -0
- package/src/mandates/binding.ts +280 -0
- package/src/mandates/chain.ts +68 -0
- package/src/mandates/checkout.ts +368 -0
- package/src/mandates/client.ts +159 -0
- package/src/mandates/extension.ts +48 -0
- package/src/mandates/index.ts +121 -0
- package/src/mandates/ingest.ts +42 -0
- package/src/mandates/jcs.ts +16 -0
- package/src/mandates/l3a.ts +216 -0
- package/src/mandates/seller.ts +91 -0
- package/src/mandates/verify.ts +625 -0
- package/src/mandates/vi/credential.ts +477 -0
- package/src/mandates/vi/issue.ts +118 -0
- package/src/mandates/vi/sd-jwt.ts +189 -0
- package/src/networks.test.ts +177 -0
- package/src/networks.ts +242 -0
- package/src/node.test.ts +24 -0
- package/src/node.ts +96 -0
- package/src/server.test.ts +223 -0
- package/src/server.ts +77 -0
- package/dist/clearing.d.ts +0 -204
- package/dist/clearing.js +0 -151
- package/dist/file-storage.d.ts +0 -39
- package/dist/file-storage.js +0 -195
package/README.md
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
Agent payments on Metal for the official x402 packages: registers the Metal
|
|
4
4
|
devnet (`eip155:1337`) and testnet (`eip155:63825`) for the `exact` scheme,
|
|
5
|
-
priced in `*USDZ`, for both sides of
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
Metal enforces.
|
|
5
|
+
priced in `*USDZ`, for both sides of an on-chain payment, and mandates,
|
|
6
|
+
which let an agent pay from its owner's account within limits Metal
|
|
7
|
+
enforces.
|
|
9
8
|
|
|
10
9
|
```bash
|
|
11
10
|
npm install @metalntwx/metal-pay @x402/core viem
|
|
@@ -16,11 +15,14 @@ client; `registerMetalNetworks(client, { signer, networks? })`
|
|
|
16
15
|
registers the scheme on an `x402Client` you already have. Both refuse,
|
|
17
16
|
before signing, a Metal `exact` offer in any token but `*USDZ` or under any
|
|
18
17
|
EIP-712 domain but USDZ's. `createMetalPaymentClient` also refuses any offer
|
|
19
|
-
above `maxAmount`, a `bigint` in `*USDZ` base units
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
18
|
+
above `maxAmount`, a `bigint` in `*USDZ` base units, except a clearing
|
|
19
|
+
offer, which its wallet's own `maxAmount` caps. The default is
|
|
20
|
+
`DEFAULT_MAX_PAYMENT`, 1 `*USDZ`. It works with `@x402/core`, `@x402/evm`
|
|
21
|
+
and `@x402/fetch` from 2.28 up to the next major, installed as its peers
|
|
22
|
+
(npm 7+ and pnpm do that themselves). The stock client pays only tokens in
|
|
23
|
+
its own table unless its spend controls list others;
|
|
24
|
+
`createMetalPaymentClient` turns them off on its client, so its own refusals
|
|
25
|
+
name the offer. On a client of your own, add
|
|
24
26
|
`{ network, asset: USDZ.address }` to `setSpendControls({ allowedAssets })`.
|
|
25
27
|
A paid request is never redirected to another origin, so no other site
|
|
26
28
|
receives the payment. `createMandatePaymentClient` does the same.
|
|
@@ -46,42 +48,98 @@ registers `ExactEvmScheme` for other networks, add
|
|
|
46
48
|
`facilitatorUrl` is Metal's x402 facilitator for it:
|
|
47
49
|
`https://x402-testnet.metalntwx.com/x402/facilitator` on testnet, and
|
|
48
50
|
`http://127.0.0.1:7090/x402/facilitator` on devnet, where
|
|
49
|
-
`just x402-facilitator` runs it. It settles
|
|
50
|
-
|
|
51
|
-
the `createAuthHeaders` option, and
|
|
51
|
+
`just x402-facilitator` runs it. It settles payments for any seller, in
|
|
52
|
+
either scheme; a seller Metal issued a token to sends it with
|
|
53
|
+
`sellerToken(token)`, the `createAuthHeaders` option, and `GET
|
|
54
|
+
/settlements` then lists its payments under that label. To also take
|
|
55
|
+
clearing, register `new ClearingServerScheme(network)` on that network
|
|
56
|
+
beside `exact` and list a `bajillion` offer whose `payTo` is the seller's
|
|
57
|
+
clearing key; the offer names the Clearing deployment the facilitator lists
|
|
58
|
+
in `/supported` and binds its invoices to the resource.
|
|
52
59
|
|
|
53
60
|
```typescript
|
|
54
61
|
import { HTTPFacilitatorClient, x402ResourceServer } from "@x402/core/server";
|
|
55
62
|
import { paymentMiddleware } from "@x402/hono";
|
|
56
63
|
import { METAL_NETWORKS, registerMetalScheme } from "@metalntwx/metal-pay";
|
|
57
64
|
|
|
58
|
-
const facilitator = new HTTPFacilitatorClient({
|
|
65
|
+
const facilitator = new HTTPFacilitatorClient({
|
|
66
|
+
url: METAL_NETWORKS.devnet.facilitatorUrl,
|
|
67
|
+
});
|
|
59
68
|
const server = registerMetalScheme(new x402ResourceServer(facilitator));
|
|
60
69
|
app.use(
|
|
61
70
|
paymentMiddleware(
|
|
62
|
-
{
|
|
71
|
+
{
|
|
72
|
+
"GET /quote": {
|
|
73
|
+
accepts: {
|
|
74
|
+
scheme: "exact",
|
|
75
|
+
network: "eip155:1337",
|
|
76
|
+
payTo: "0x…",
|
|
77
|
+
price: "0.01",
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
63
81
|
server,
|
|
64
82
|
),
|
|
65
83
|
);
|
|
66
84
|
```
|
|
67
85
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
`
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
86
|
+
## Native Bajillion payments
|
|
87
|
+
|
|
88
|
+
`createClearingClient` signs cumulative P-256 payments and retains the exact
|
|
89
|
+
pending authorization across transport errors. Supply trusted `serviceUrl`,
|
|
90
|
+
`rpcUrl`, `network`, `settlement`, `asset`, a signer, an atomic store and a
|
|
91
|
+
`maxAmount` limit. In Node 22.13 or later (23.4 or later on Node 23),
|
|
92
|
+
`openClearingWallet(directory)` from `@metalntwx/metal-pay/node` supplies a
|
|
93
|
+
persistent signer and store with exclusive
|
|
94
|
+
process ownership. Preserve that directory across restarts; call `close()` on
|
|
95
|
+
shutdown. A payment the service does not take throws a `ClearingRefusal`,
|
|
96
|
+
whose `reason` is `between_epochs`, `insufficient_deposit`, `answer_lost`
|
|
97
|
+
or `payment_held` and whose `retry` says what to do: wait `retry.ms`
|
|
98
|
+
(again after each further `between_epochs`), deposit, or send the held
|
|
99
|
+
request, `retry.url` at `retry.amount`, again after `retry.ms` before any
|
|
100
|
+
other. If that URL no longer offers clearing at that price, pass the
|
|
101
|
+
client's `pendingInvoice()` to its `pay`. A held payment sent again is
|
|
102
|
+
settled from the service's receipt when it kept one, and released when it
|
|
103
|
+
has none and its epoch has closed or is no longer the service's live one.
|
|
104
|
+
A wallet's record is for one Clearing deployment: open a new wallet for a
|
|
105
|
+
replacement. Through `createMetalPaymentClient`'s `fetchWithPayment` it is
|
|
106
|
+
the thrown error's `cause`.
|
|
107
|
+
|
|
108
|
+
`clearingRequirements` and `clearingInvoice` bind an invoice to a resource,
|
|
109
|
+
recipient, amount and deployment. `registerClearingClient` adds the `bajillion`
|
|
110
|
+
scheme to an official x402 client, which then pays by clearing wherever its
|
|
111
|
+
wallet can pay the offer and refuses any other request on that
|
|
112
|
+
registration's network, unless given `{ exactFallback: true }` to pay it by
|
|
113
|
+
`exact`. Behind the stock middleware,
|
|
114
|
+
Metal's facilitator verifies and deduplicates clearing payments before the
|
|
115
|
+
handler runs. A seller that verifies them itself calls
|
|
116
|
+
`verifyClearingPayment` with its own trusted
|
|
117
|
+
RPC/service configuration and deduplicates `clearingPaymentId` in durable
|
|
118
|
+
storage before delivering. The returned receipt is **preconfirmed**;
|
|
119
|
+
watch `Clearing.finalizedCount` before labeling its epoch finalized. It is not
|
|
120
|
+
an EVM transaction hash.
|
|
121
|
+
|
|
122
|
+
`depositToClearing` funds a clearing account from an EVM account, waiting
|
|
123
|
+
for the contract's deposit window; `clearingSpendable` reads the service's
|
|
124
|
+
estimate of what the account can spend, in token base units, which counts
|
|
125
|
+
a deposit from the epoch after it lands and can read low around an
|
|
126
|
+
epoch's close, and
|
|
127
|
+
`clearingBalance` the finalized balance and its proof, in clearing units
|
|
128
|
+
(`Clearing.unit()` base units each, a millionth of `*USDZ`);
|
|
129
|
+
`withdrawFromClearing` queues a withdrawal of the finalized balance and,
|
|
130
|
+
once its epoch has finalized, claims it, for payer and seller alike; it
|
|
131
|
+
answers `empty` when there is nothing finalized to claim or queue. A
|
|
132
|
+
queue or claim refused because an epoch finalized under its proof moved
|
|
133
|
+
nothing, and its error says to call again after the next epoch.
|
|
134
|
+
`clearingClose` and `clearingLogProof` are the pieces it is built from.
|
|
135
|
+
`recoverFromClearing` takes an account's funds out of a deployment whose
|
|
136
|
+
service has missed a deadline: it faults the deployment, starts recovery,
|
|
137
|
+
and takes the payout of the account's finalized withdrawal, its last
|
|
138
|
+
finalized balance and its uncounted deposits, with proofs from the service
|
|
139
|
+
or the first of several validators that retained the epoch. The clearing
|
|
140
|
+
service's README, `apps/clearing-service/README.md` in the Metal
|
|
141
|
+
repository, describes operator/validator setup, receipt retention and proof
|
|
142
|
+
endpoints.
|
|
85
143
|
|
|
86
144
|
**Mandates.** `@metalntwx/metal-pay/mandates` lets an agent pay from its
|
|
87
145
|
owner's account with a P-256 key of its own, within limits Metal enforces on
|
|
@@ -90,23 +148,31 @@ budget, how many payments, an expiry) as a Verifiable Intent mandate;
|
|
|
90
148
|
`ingestCredential` verifies one against the issuers the owner trusts, and
|
|
91
149
|
`bindCall`, `replaceCall` and `revokeCall` build the owner's transactions to its own
|
|
92
150
|
MetalAccount. Wrap those calls with `authorizeMandateCall(client, trustedFactory,
|
|
93
|
-
call, signQuorum)` to authorize an account self-call, or a list of them as one
|
|
151
|
+
call, validUntil, signQuorum)` to authorize an account self-call, or a list of them as one
|
|
94
152
|
batch that runs whole or not at all, with its existing weighted quorum. The
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
153
|
+
account refuses the signed batch after `validUntil` (unix seconds, a `bigint`), so
|
|
154
|
+
give it a short deadline. The client must name its chain: the digest the quorum
|
|
155
|
+
signs is computed from it, never read from the RPC endpoint. The callback
|
|
156
|
+
supports the same EOA, P-256 and passkey signatures as ordinary account
|
|
157
|
+
execution. Factory-created clones share an immutable VI
|
|
98
158
|
verifier; budgets and replay protection live in each account. `createMandatePaymentClient({ credential, signDigest, network })`
|
|
99
159
|
is the payer, and `MandateExactScheme` the same payer as a scheme for an
|
|
100
160
|
`x402Client` of your own: each payment is an ERC-3009 authorization from the
|
|
101
|
-
owner's account whose signature is the agent's per-payment mandate
|
|
102
|
-
|
|
103
|
-
|
|
161
|
+
owner's account whose signature is the agent's per-payment mandate; Metal's
|
|
162
|
+
facilitator submits it as `pull` on the owner's account, which checks it
|
|
163
|
+
against the mandate, spends the budget and hands the token the
|
|
164
|
+
authorization. Sellers see an ordinary `exact` payment. The client sets no
|
|
165
|
+
limit of its own.
|
|
104
166
|
`readCheck` names the limit behind a refusal, `readMandateState` reads the
|
|
105
167
|
spend, and `pullCall` builds a direct payment with no seller. A credential's amounts
|
|
106
168
|
are decimal, to the cent. `verifyMandate` and `verifyMandatePayment` trust the
|
|
107
169
|
MetalAccountFactory `METAL_NETWORKS` names for the chain, or the
|
|
108
170
|
`accountFactory` given, check the account's clone code against the
|
|
109
171
|
factory's current implementation, and match the successful token transfer to the seller's requirements.
|
|
172
|
+
`verifyMandatePayment` checks a `checkoutMandate` against the payment, failing one of another
|
|
173
|
+
payment as such; its step 4 says when none was given, so no order was checked.
|
|
174
|
+
An event under the mandate that the SDK does not decode, as an account of
|
|
175
|
+
another version emits, fails the verification with its topic and the account.
|
|
110
176
|
The module runs on Node only.
|
|
111
177
|
|
|
112
178
|
**RPC.** Neither payers nor payees need one. Each network's `rpc` is its
|