warrant-client 0.1.0 → 0.1.2

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