@haven_ai/sdk 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.
package/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # @haven_ai/sdk
2
2
 
3
- TypeScript SDK for [Haven](https://github.com/d-hinders/Haven) — agent wallet infrastructure for the autonomous economy.
3
+ TypeScript SDK for [Haven](https://github.com/d-hinders/Haven-AI) — agent wallet infrastructure for the autonomous economy.
4
4
 
5
- Haven gives AI agents the ability to hold, send, and receive money within strict, user-defined guardrails. This SDK makes it trivial to integrate Haven payments into any agent.
5
+ Haven lets AI agents request and sign payments within strict, user-approved on-chain guardrails. This SDK makes it straightforward to integrate Haven payment requests into any agent without giving Haven custody of user or agent keys.
6
6
 
7
7
  ## Install
8
8
 
@@ -32,6 +32,35 @@ console.log(result.txHash) // 0x...
32
32
  console.log(result.explorerUrl) // https://gnosisscan.io/tx/0x... (or basescan.org for Base)
33
33
  ```
34
34
 
35
+ ## Try it live — zero setup
36
+
37
+ Haven hosts a demo endpoint you can hit immediately after creating an agent:
38
+
39
+ ```typescript
40
+ import { HavenClient } from '@haven_ai/sdk'
41
+
42
+ const haven = new HavenClient({
43
+ apiKey: process.env.HAVEN_API_KEY!, // from Haven dashboard
44
+ delegateKey: process.env.DELEGATE_KEY!, // agent's delegate private key
45
+ baseUrl: 'https://havenbackend-production-8a00.up.railway.app', // hosted Haven, or your self-hosted URL
46
+ })
47
+
48
+ // haven.fetch handles 402 → pay → retry automatically
49
+ const response = await haven.fetch(
50
+ 'https://havenbackend-production-8a00.up.railway.app/demo/x402/data',
51
+ )
52
+ const data = await response.json()
53
+
54
+ console.log(data.message) // "You paid! Here's your demo data."
55
+ console.log(data.fact) // a fun fact about the agent economy
56
+ console.log(data.explorerUrl) // link to the on-chain payment tx
57
+ ```
58
+
59
+ Tell your agent:
60
+ > "Use Haven to fetch `https://havenbackend-production-8a00.up.railway.app/demo/x402/data` and show me what came back."
61
+
62
+ The agent will pay a tiny amount (~0.01 EURe on Gnosis Chain), receive the demo payload, and you'll see the payment in your Haven dashboard activity feed — no local server or extra config required.
63
+
35
64
  ## Supported Networks & Tokens
36
65
 
37
66
  | Network | CAIP-2 | Tokens |
@@ -63,7 +92,9 @@ const result = await haven.waitForConfirmation(intent.paymentId)
63
92
 
64
93
  ## x402 Protocol Support
65
94
 
66
- Haven natively supports the [x402](https://x402.org) payment protocol. When an API returns HTTP 402, Haven evaluates the payment against policy, executes from the Safe, and retries automatically:
95
+ Production merchant acceptance, facilitator, settlement, fiat, or acquiring functionality needs separate product and legal review under the repo's [CASP / MiCA guardrails](../../docs/regulatory/casp-risk-guardrails.md). The hosted x402 endpoint is an internal technical demo, not a merchant settlement product.
96
+
97
+ Haven natively supports the [x402](https://x402.org) payment protocol. When an API returns HTTP 402, the SDK evaluates the challenge against the agent's approved limits, uses the configured delegate key for the required signature, and retries automatically:
67
98
 
68
99
  ```typescript
69
100
  // Automatic — fetch() intercepts 402, pays, and retries
@@ -71,17 +102,20 @@ const response = await haven.fetch('https://paid-api.example.com/data')
71
102
  const data = await response.json()
72
103
 
73
104
  // Manual — parse and authorize the 402 yourself
74
- import { parsePaymentRequired } from '@haven_ai/sdk'
105
+ import { parsePaymentRequiredResponse } from '@haven_ai/sdk'
75
106
 
76
107
  const apiResponse = await fetch('https://paid-api.example.com/data')
77
108
  if (apiResponse.status === 402) {
78
- const paymentRequired = parsePaymentRequired(apiResponse)
109
+ const paymentRequired = await parsePaymentRequiredResponse(apiResponse)
79
110
  const receipt = await haven.authorizeX402(paymentRequired)
111
+ // Retry with { 'X-PAYMENT': receipt.paymentHeader }
80
112
  console.log(receipt.explorerUrl)
81
113
  }
82
114
  ```
83
115
 
84
- Supported x402 networks: `eip155:100` (Gnosis Chain) and `eip155:8453` (Base).
116
+ Merchant-verified x402 retries use the official EIP-3009 `exact` scheme on Base USDC (`base` / `eip155:8453`) and send the payment as `X-PAYMENT`. Haven's older tx-hash proof helper remains exported for Haven-native integrations, but `haven.fetch()` does not send `PAYMENT-SIGNATURE`.
117
+
118
+ For standard x402, the `x402-wallet` identity is the agent delegate wallet, because that is the wallet that signs and settles the merchant payment. Integrations that scope access by Haven wallet/Safe address should use a Haven-native flow instead of standard merchant x402.
85
119
 
86
120
  ## AI Agent Integration
87
121
 
@@ -97,7 +131,7 @@ const haven = new HavenClient({ apiKey, delegateKey })
97
131
  const anthropic = new Anthropic()
98
132
 
99
133
  const response = await anthropic.messages.create({
100
- model: 'claude-opus-4-6',
134
+ model: 'claude-opus-4-7',
101
135
  tools: havenTools.claude(), // or havenTools.openai() for OpenAI
102
136
  messages: [{ role: 'user', content: 'Pay 5 EURe to 0xabc for API access' }],
103
137
  })
@@ -115,9 +149,9 @@ for (const block of response.content) {
115
149
 
116
150
  | Tool | Description |
117
151
  |------|-------------|
118
- | `make_payment` | Send a payment from the Haven-managed Safe wallet |
119
- | `get_payment_status` | Check the status of a previously initiated payment |
120
- | `authorize_x402_payment` | Pay for an HTTP 402 resource via the x402 protocol |
152
+ | `make_payment` | Request and sign a payment from the user-controlled Safe within approved limits |
153
+ | `get_payment_status` | Check the status of a payment intent or approval request |
154
+ | `authorize_x402_payment` | Authorize a policy-limited x402 payment and return a payment header for an HTTP 402 resource |
121
155
 
122
156
  ## Configuration
123
157
 
@@ -126,20 +160,58 @@ const haven = new HavenClient({
126
160
  apiKey: 'sk_agent_xxx', // required — Haven agent API key
127
161
  delegateKey: '0x...', // optional — enables .pay() and .sign()
128
162
  baseUrl: 'http://localhost:3001', // default
163
+ x402Wallet: '0x...', // optional fallback when no delegate key is configured
129
164
  requestTimeout: 30000, // per-request timeout (ms)
130
165
  confirmationTimeout: 90000, // polling timeout (ms)
131
166
  pollingInterval: 3000, // polling interval (ms)
132
167
  })
133
168
  ```
134
169
 
170
+ ## Payments above the on-chain allowance
171
+
172
+ Haven's policy lives on the Safe AllowanceModule (token, amount, reset period).
173
+ If an agent requests a payment above the remaining allowance, Haven does **not**
174
+ reject it — it returns HTTP 202 with `status: 'pending_approval'`, a
175
+ `payment_id`, `phase`, and `next_action`, then queues it for the wallet owner
176
+ to approve in the dashboard.
177
+
178
+ Surface that to the user: the payment isn't dead, it's waiting for a human to
179
+ sign off. Check `getPaymentStatus(payment_id)` or the `get_payment_status`
180
+ tool later instead of retrying in a tight loop.
181
+
182
+ For x402, the manual approval path has two steps. First, the user approves the
183
+ funding movement from the Haven wallet to the agent's delegate wallet. Once
184
+ Haven reports `next_action: 'retry_original_x402_request'`, retry the original
185
+ paid API request so the SDK can attach the merchant x402 payment header. Do not
186
+ rewrite the SDK while waiting for approval.
187
+
188
+ ```typescript
189
+ try {
190
+ await haven.pay({ token: 'USDC', amount: '500', to: '0xabc...' })
191
+ } catch (err) {
192
+ if (err instanceof HavenPaymentStateError && err.nextAction === 'wait_for_user_approval') {
193
+ console.log(err.paymentId, err.phase, err.nextAction)
194
+ console.log('Queued for owner approval — visible in the Haven dashboard.')
195
+ }
196
+ }
197
+
198
+ const status = await haven.getPaymentStatus('approval-or-payment-id')
199
+ if (status.nextAction === 'retry_original_x402_request') {
200
+ // Retry the original paid API request.
201
+ }
202
+ ```
203
+
135
204
  ## Error Handling
136
205
 
137
206
  ```typescript
138
- import { HavenApiError, HavenSigningError, HavenTimeoutError } from '@haven_ai/sdk'
207
+ import { HavenApiError, HavenPaymentStateError, HavenSigningError, HavenTimeoutError } from '@haven_ai/sdk'
139
208
 
140
209
  try {
141
210
  await haven.pay({ token: 'EURe', amount: '5.00', to: '0xabc...' })
142
211
  } catch (err) {
212
+ if (err instanceof HavenPaymentStateError) {
213
+ console.log(err.paymentId, err.phase, err.nextAction)
214
+ }
143
215
  if (err instanceof HavenApiError) {
144
216
  console.log(err.statusCode, err.message) // API returned an error
145
217
  }