warrant-client 0.1.0 → 0.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.
Files changed (2) hide show
  1. package/README.md +215 -25
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -1,13 +1,82 @@
1
+ <div align="center">
2
+
1
3
  # warrant-client
2
4
 
3
- Buy resources for an AI agent over x402 on Hedera: a permanent name, an email
4
- inbox it owns, a phone number, SMS, inference, and memory written to a file
5
- nobody can edit. One call at a time, in USDC, with no API key and no signup.
5
+ **Buy what an agent needs, one call at a time, in USDC on Hedera.**
6
+
7
+ A permanent name. An email inbox it owns and receives replies at. Sealed
8
+ agent-to-agent mail. A real phone number and SMS. Language model inference.
9
+ Memory written to a file nobody can edit. No API key, no signup, no human in
10
+ the loop: the account that pays is the identity.
11
+
12
+ [![npm](https://img.shields.io/npm/v/warrant-client?color=C98A2E)](https://www.npmjs.com/package/warrant-client)
13
+ [![Hedera](https://img.shields.io/badge/Hedera-testnet%20296-6FE3A5)](https://hashscan.io/testnet/contract/0xF33E2E0ecc982416f788759083129de6A147a1FE)
14
+ [![x402](https://img.shields.io/badge/x402-v2-E8B55C)](https://github.com/coinbase/x402)
15
+ [![node](https://img.shields.io/badge/node-%3E%3D20-brightgreen)](https://nodejs.org)
16
+ [![license](https://img.shields.io/badge/license-MIT-blue)](https://github.com/martinvibes/warrant/blob/master/LICENSE)
17
+
18
+ [Console](https://warrant-aufgabe.vercel.app) ·
19
+ [Docs](https://warrant-aufgabe.vercel.app/docs) ·
20
+ [Ledger](https://warrant-aufgabe.vercel.app/ledger) ·
21
+ [Catalogue](https://warrant-api-production-e111.up.railway.app/v1/catalogue) ·
22
+ [Spec](https://warrant-api-production-e111.up.railway.app/openapi.json) ·
23
+ [Skill file](https://warrant-api-production-e111.up.railway.app/skill.md) ·
24
+ [MCP](https://qmt6sdhe5ffmva3zl2iagc6hkm.bazgateway.com/mcp) ·
25
+ [Source](https://github.com/martinvibes/warrant)
26
+
27
+ </div>
28
+
29
+ ---
30
+
31
+ > An agent that has to ask a human before it can send an email is not autonomous.
32
+ > This is the other half: it pays for what it uses, and a contract on Hedera
33
+ > decides whether it may.
6
34
 
7
35
  ```bash
8
36
  npm i warrant-client
9
37
  ```
10
38
 
39
+ ## Quick start
40
+
41
+ The fastest path from zero to an agent with an on-chain name, a real inbox, and
42
+ a memory that outlives the process. Every paid step is a real settlement on
43
+ Hedera, and every resource is owned by the account that paid for it.
44
+
45
+ ```bash
46
+ # 0. The account that pays. It needs testnet USDC and nothing else —
47
+ # the facilitator sponsors the network fee, so no HBAR is required.
48
+ export WARRANT_ACCOUNT_ID=0.0.10514332
49
+ export WARRANT_PRIVATE_KEY=302e… # DER or hex
50
+ export WARRANT_AGENT_ADDRESS=0x7d14…33cC # only identity.mint needs this
51
+
52
+ # 1. See what is for sale, and what it costs. Free, and needs no key.
53
+ npx warrant catalogue
54
+
55
+ # 2. Mint the agent's identity — soulbound ERC-721 on Hedera ($0.10)
56
+ npx warrant buy identity.mint
57
+
58
+ # 3. Claim an inbox it owns and receives replies at ($1.00)
59
+ npx warrant buy email.inbox --name scout
60
+
61
+ # 4. Send a real email from it ($0.20)
62
+ npx warrant buy email.send --from scout@0gent.xyz --to you@example.com \
63
+ --subject "Hello" --body "from the agent, paid for by the agent"
64
+
65
+ # 5. Ask a model, paid per call ($0.02)
66
+ npx warrant buy inference --prompt "What is Hedera in one sentence?"
67
+
68
+ # 6. Write something it will still know tomorrow ($0.05)
69
+ npx warrant buy memory.write --content "the peer at 0x7510 answers on scout@0gent.xyz"
70
+
71
+ # 7. Search real phone inventory (free — an agent that cannot see the price
72
+ # before it commits is not choosing)
73
+ npx warrant read '/v1/phone/search?country=US&area=415'
74
+ ```
75
+
76
+ Install it globally for a shorter line: `npm i -g warrant-client && warrant catalogue`.
77
+
78
+ ## In code
79
+
11
80
  ```ts
12
81
  import { Warrant } from "warrant-client";
13
82
 
@@ -16,46 +85,167 @@ const warrant = new Warrant({
16
85
  privateKey: process.env.WARRANT_PRIVATE_KEY!,
17
86
  });
18
87
 
19
- const { result, settlement } = await warrant.buy("inference", { prompt: "hello" });
88
+ const { result, settlement } = await warrant.buy("inference", {
89
+ prompt: "summarise x402 in one line",
90
+ });
91
+
92
+ console.log(result); // the resource
93
+ console.log(settlement); // the Hedera transaction it was paid for in
20
94
  ```
21
95
 
22
- The endpoint and the price come from the service's own catalogue, so a service
23
- that adds a resource does not need this package republished to stay usable.
96
+ One call replaces three: the request that comes back `402`, the signed payment,
97
+ and the retry. Endpoints and prices are read from the service's own catalogue,
98
+ so a service that adds a resource does not need this package republished.
99
+
100
+ ## Command reference
101
+
102
+ Prices are quoted in USDC and settled at request time over
103
+ [x402](https://github.com/coinbase/x402) — one payment per call, no
104
+ subscriptions, no minimum. Flags become the JSON body: `--prompt hello` is
105
+ `{"prompt":"hello"}`.
106
+
107
+ ### Free — no key, no account, no payment
108
+
109
+ | Command | Cost | Notes |
110
+ |---|---|---|
111
+ | `warrant catalogue` | free | What is for sale and the live price. The same table the server charges against. |
112
+ | `warrant read /v1/receipts` | free | Every settled purchase, signed. Add `?limit=3`. |
113
+ | `warrant read /v1/purchases` | free | The public ledger, including what was refused. |
114
+ | `warrant read /v1/contracts` | free | Addresses of the three contracts, and the receipt issuer. |
115
+ | `warrant read /v1/stats` | free | Totals: purchases, agents, spend. |
116
+ | `warrant read /v1/agents/0.0.10514332` | free | What one agent owns and what it has left. |
117
+ | `warrant read '/v1/phone/search?country=US&area=415'` | free | Real inventory, before you commit to buying one. |
118
+ | `warrant read /v1/memory/<fileId>` | free | Read back a memory file from Hedera. |
119
+ | `warrant read /v1/email/inbox/<address>` | free | Read what arrived in an inbox the account owns. |
120
+
121
+ ### Paid — settled in USDC, one payment per call
122
+
123
+ | Command | Cost | Status | Notes |
124
+ |---|---|---|---|
125
+ | `warrant buy identity.mint` | $0.10 | ✅ Live | Soulbound ERC-721 on Hedera's EVM, one per address, plus the public key other agents seal mail to. Optional `--metadataURI`, `--encryptionKey`. Needs `WARRANT_AGENT_ADDRESS`. |
126
+ | `warrant buy inference --prompt "…"` | $0.02 | ✅ Live | One language model call, returned in OpenAI shape. Optional `--model`, `--maxTokens`. |
127
+ | `warrant buy email.inbox --name scout` | $1.00 | ✅ Live | Provisions `scout@0gent.xyz`, owned by the paying account, and **receives replies** — not just outbound. |
128
+ | `warrant buy email.send --from … --to … --subject … --body …` | $0.20 | ✅ Live | A real email from an address the agent owns, via Resend. |
129
+ | `warrant buy email.sealed --from … --to … --toAgent 0x… --subject … --body …` | $0.25 | ✅ Live | Encrypted to the recipient's on-chain key. This service relays it and cannot read it. |
130
+ | `warrant buy memory.write --content "…"` | $0.05 | ✅ Live | A permanent Hedera file, up to 4096 bytes, that nobody — this service included — can edit. |
131
+ | `warrant buy phone.provision --country US` | $0.50 | ✅ Live | A real number in 170+ countries, SMS capable, via Telnyx. Or `--phoneNumber +1…` from a search. |
132
+ | `warrant buy sms.send --from +1… --to +1… --text "…"` | $0.01 | ✅ Live | One text from a number the agent owns. |
133
+
134
+ Nothing is listed as coming soon. An offer whose provider is not configured is
135
+ not shown and not sold, so the catalogue never advertises a price that will not
136
+ be honoured.
137
+
138
+ ## How payment works
139
+
140
+ 1. Call a paid endpoint with no payment. It answers **`402 Payment Required`**
141
+ with the amount, the asset and where to pay.
142
+ 2. Sign an x402 payment for exactly that amount and retry the same request with
143
+ a `payment-signature` header.
144
+ 3. The resource runs, and its owner is the account that paid. The settlement id
145
+ comes back in the `payment-response` header.
146
+
147
+ This package does all three. Settlement is USDC `0.0.429274` on
148
+ `hedera:testnet`, through the [Blocky402](https://api.testnet.blocky402.com)
149
+ facilitator, which sponsors the network fee — so a paying agent carries
150
+ stablecoin and no HBAR.
151
+
152
+ ## The limit that makes this safe
153
+
154
+ The interesting part of Warrant is not that an agent can pay. It is that it can
155
+ be stopped.
156
+
157
+ An owner funds an `AgentTreasury` contract on Hedera with a lifetime cap, a
158
+ rolling window (`$5 a day`), and an allowlist of resource kinds. The agent draws
159
+ from it without asking anyone, and the contract refuses an out-of-scope or
160
+ over-budget draw before any money moves. The refusal comes from the chain, not
161
+ from a vendor's database, and it holds even if this service disappears.
24
162
 
25
- ## Command line
163
+ ```ts
164
+ const { result } = await warrant.buy("inference", { prompt: "…" });
165
+ // → WarrantError: WindowCapExceeded — wanted 20000 atomic, remaining 0,
166
+ // reopens at 2026-09-13T13:51:27Z
167
+ ```
168
+
169
+ | Contract | Address |
170
+ |---|---|
171
+ | `AgentIdentity` | [`0xb791348d9896Bce2FA5cA724d8F548413AcbaDf6`](https://hashscan.io/testnet/contract/0xb791348d9896Bce2FA5cA724d8F548413AcbaDf6) |
172
+ | `ResourceMarket` | [`0x7442BdF9240e42Df0B25CedefeAF13799Fd377C0`](https://hashscan.io/testnet/contract/0x7442BdF9240e42Df0B25CedefeAF13799Fd377C0) |
173
+ | `AgentTreasury` | [`0xF33E2E0ecc982416f788759083129de6A147a1FE`](https://hashscan.io/testnet/contract/0xF33E2E0ecc982416f788759083129de6A147a1FE) |
174
+
175
+ Registration and listing are permissionless. Anyone may register an identity and
176
+ anyone may list a resource, because a registry behind an admin key is a customer
177
+ list, not a registry.
178
+
179
+ ## Receipts
180
+
181
+ Every settled purchase is signed over a canonical digest, so it can be checked
182
+ without trusting this service:
26
183
 
27
184
  ```bash
28
- export WARRANT_ACCOUNT_ID=0.0.10514332
29
- export WARRANT_PRIVATE_KEY=302e…
185
+ warrant read '/v1/receipts?limit=1'
186
+ ```
30
187
 
31
- npx warrant catalogue
32
- npx warrant buy inference --prompt "one line on Hedera"
33
- npx warrant read /v1/receipts?limit=3
188
+ ```
189
+ digest = sha256(version|id|agent|kind|resource|amount|asset|network|settlement|issuedAt)
34
190
  ```
35
191
 
192
+ Rebuild the digest from the fields, recover the signer, compare it with the
193
+ issuer published at `/v1/contracts`, and read the settlement back from Hedera's
194
+ mirror node rather than from us.
195
+
36
196
  ## The one error that matters
37
197
 
38
- A payment settles before the resource runs, so an upstream failure can happen
39
- after the money moved. That comes back as a `WarrantError` with `settled: true`,
40
- and retrying it buys the failure twice.
198
+ A payment settles **before** the resource runs, so an upstream failure can happen
199
+ after the money has moved. That comes back as a `WarrantError` with
200
+ `settled: true`, and retrying it buys the failure twice.
41
201
 
42
202
  ```ts
203
+ import { WarrantError } from "warrant-client";
204
+
43
205
  try {
44
206
  await warrant.buy("email.send", { from, to, subject, body });
45
207
  } catch (err) {
46
- if (err instanceof WarrantError && err.settled) { /* paid, not delivered */ }
47
- if (err instanceof WarrantError && err.free) { /* safe to fix and repeat */ }
208
+ if (err instanceof WarrantError && err.settled) {
209
+ // charged, and the resource failed. Collect the receipt, do not retry.
210
+ }
48
211
  }
49
212
  ```
50
213
 
51
- ## What it needs
214
+ `err.free` is the inverse, and is true whenever nothing was charged — a bad
215
+ request, a refusal by the limit, an unknown kind. Those are safe to correct and
216
+ repeat.
217
+
218
+ ## API
219
+
220
+ | | |
221
+ |---|---|
222
+ | `new Warrant({ accountId, privateKey, baseUrl?, network? })` | A paying client. `baseUrl` defaults to the hosted service. |
223
+ | `warrant.offers(refresh?)` | The whole catalogue, cached after the first read. |
224
+ | `warrant.offer(kind)` | One offer, or `undefined`. |
225
+ | `warrant.buy<T>(kind, body?, agentAddress?)` | Pay for one call. Returns `{ kind, result, settlement }`. |
226
+ | `warrant.read<T>(path)` | Any free endpoint. |
227
+
228
+ ### Environment
229
+
230
+ | Variable | What it is |
231
+ |---|---|
232
+ | `WARRANT_ACCOUNT_ID` | The Hedera account paying, e.g. `0.0.10514332`. |
233
+ | `WARRANT_PRIVATE_KEY` | Its private key, DER or hex. Read it from the environment; never commit it. |
234
+ | `WARRANT_AGENT_ADDRESS` | The agent's EVM address. Only `identity.mint` needs it. |
235
+ | `WARRANT_BASE_URL` | Point at a different service. Defaults to the hosted one. |
236
+
237
+ ## Other ways in
52
238
 
53
- A Hedera account holding testnet USDC, token `0.0.429274`. It does **not** need
54
- HBAR: the facilitator sponsors the network fee.
239
+ - **Plain HTTP** everything above is one `curl` and a signature away. The spec
240
+ is at [`/openapi.json`](https://warrant-api-production-e111.up.railway.app/openapi.json).
241
+ - **MCP** — the same catalogue as tools, through the gateway listed on Bazantic:
242
+ `https://qmt6sdhe5ffmva3zl2iagc6hkm.bazgateway.com/mcp`
243
+ - **Recipes** — [agent-starter-kit](https://bazantic.com/recipes/agent-starter-kit)
244
+ stands up a new agent end to end; [spend-audit](https://bazantic.com/recipes/spend-audit)
245
+ reads back what one spent and what it was refused.
246
+ - **Coding agents** — drop in
247
+ [`/skill.md`](https://warrant-api-production-e111.up.railway.app/skill.md).
55
248
 
56
- Full documentation, including every request shape and the on-chain spending
57
- limit, is at
58
- [`/skill.md`](https://warrant-api-production-e111.up.railway.app/skill.md).
59
- Source: https://github.com/martinvibes/warrant
249
+ ## Licence
60
250
 
61
- MIT.
251
+ MIT. Source at [github.com/martinvibes/warrant](https://github.com/martinvibes/warrant).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "warrant-client",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Buy resources for an AI agent over x402 on Hedera: a name, an inbox, a phone number, inference and permanent memory, one call at a time.",
5
5
  "keywords": ["x402", "agent", "hedera", "usdc", "pay-per-call", "ai-agent", "402"],
6
6
  "license": "MIT",