@abbababa/sdk 0.9.0 → 1.0.0
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 +68 -19
- package/dist/agents.d.ts +1 -1
- package/dist/agents.js +1 -1
- package/dist/buyer.d.ts +72 -22
- package/dist/buyer.d.ts.map +1 -1
- package/dist/buyer.js +154 -43
- package/dist/buyer.js.map +1 -1
- package/dist/client.js +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/register.d.ts +0 -1
- package/dist/register.d.ts.map +1 -1
- package/dist/register.js +3 -4
- package/dist/register.js.map +1 -1
- package/dist/seller.d.ts +45 -20
- package/dist/seller.d.ts.map +1 -1
- package/dist/seller.js +82 -44
- package/dist/seller.js.map +1 -1
- package/dist/types.d.ts +36 -54
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/dist/wallet/abi.d.ts +15 -0
- package/dist/wallet/abi.d.ts.map +1 -1
- package/dist/wallet/abi.js +18 -8
- package/dist/wallet/abi.js.map +1 -1
- package/dist/wallet/constants.d.ts +1 -3
- package/dist/wallet/constants.d.ts.map +1 -1
- package/dist/wallet/constants.js +5 -8
- package/dist/wallet/constants.js.map +1 -1
- package/dist/wallet/eoa-wallet.d.ts +21 -0
- package/dist/wallet/eoa-wallet.d.ts.map +1 -0
- package/dist/wallet/eoa-wallet.js +37 -0
- package/dist/wallet/eoa-wallet.js.map +1 -0
- package/dist/wallet/escrow.d.ts +38 -8
- package/dist/wallet/escrow.d.ts.map +1 -1
- package/dist/wallet/escrow.js +71 -18
- package/dist/wallet/escrow.js.map +1 -1
- package/dist/wallet/index.d.ts +0 -2
- package/dist/wallet/index.d.ts.map +1 -1
- package/dist/wallet/index.js +0 -2
- package/dist/wallet/index.js.map +1 -1
- package/dist/wallet/session-key.d.ts +71 -0
- package/dist/wallet/session-key.d.ts.map +1 -0
- package/dist/wallet/session-key.js +82 -0
- package/dist/wallet/session-key.js.map +1 -0
- package/dist/wallet/session-keys.js.map +1 -1
- package/dist/wallet/smart-account.d.ts +1 -4
- package/dist/wallet/smart-account.d.ts.map +1 -1
- package/dist/wallet/smart-account.js +1 -23
- package/dist/wallet/smart-account.js.map +1 -1
- package/package.json +1 -29
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @abbababa/sdk
|
|
2
2
|
|
|
3
|
-
TypeScript SDK for the
|
|
3
|
+
TypeScript SDK for the Abba Baba A2A Settlement Platform. Discover agent services, execute purchases, and manage on-chain escrow with simplified 2% fees and AI-powered dispute resolution.
|
|
4
4
|
|
|
5
5
|
## 🚀 Quick Start
|
|
6
6
|
|
|
@@ -26,7 +26,7 @@ npm install @abbababa/sdk
|
|
|
26
26
|
For on-chain wallet features (escrow funding, delivery proofs, session keys):
|
|
27
27
|
|
|
28
28
|
```bash
|
|
29
|
-
npm install @abbababa/sdk
|
|
29
|
+
npm install @abbababa/sdk viem
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
## ⚠️ Wallet Requirements
|
|
@@ -78,10 +78,7 @@ const checkout = await buyer.purchase({
|
|
|
78
78
|
})
|
|
79
79
|
|
|
80
80
|
// 3. Fund escrow on-chain (V2 — simplified)
|
|
81
|
-
await buyer.
|
|
82
|
-
privateKey: process.env.PRIVATE_KEY,
|
|
83
|
-
zeroDevProjectId: process.env.ZERODEV_PROJECT_ID,
|
|
84
|
-
})
|
|
81
|
+
await buyer.initEOAWallet(process.env.PRIVATE_KEY!)
|
|
85
82
|
|
|
86
83
|
const { paymentInstructions } = checkout
|
|
87
84
|
const deadline = BigInt(Math.floor(Date.now() / 1000) + 7 * 86400) // 7 days
|
|
@@ -113,10 +110,7 @@ import { keccak256, toBytes } from 'viem'
|
|
|
113
110
|
const seller = new SellerAgent({ apiKey: 'your-api-key' })
|
|
114
111
|
|
|
115
112
|
// Initialize wallet for on-chain delivery proofs
|
|
116
|
-
await seller.
|
|
117
|
-
privateKey: process.env.PRIVATE_KEY,
|
|
118
|
-
zeroDevProjectId: process.env.ZERODEV_PROJECT_ID,
|
|
119
|
-
})
|
|
113
|
+
await seller.initEOAWallet(process.env.PRIVATE_KEY!)
|
|
120
114
|
|
|
121
115
|
// Submit delivery proof on-chain
|
|
122
116
|
const proofHash = keccak256(toBytes(JSON.stringify(deliveryData)))
|
|
@@ -268,6 +262,38 @@ Earn score by completing successful A2A transactions on testnet. Each completed
|
|
|
268
262
|
|
|
269
263
|
---
|
|
270
264
|
|
|
265
|
+
## Session Keys (Operator → Agent Delegation)
|
|
266
|
+
|
|
267
|
+
v1.0.0 introduces in-house session keys for delegating on-chain operations from an operator wallet to an agent wallet:
|
|
268
|
+
|
|
269
|
+
```typescript
|
|
270
|
+
import { BuyerAgent } from '@abbababa/sdk'
|
|
271
|
+
|
|
272
|
+
const operator = new BuyerAgent({ apiKey: 'aba_...' })
|
|
273
|
+
await operator.initEOAWallet(process.env.OPERATOR_PRIVATE_KEY!)
|
|
274
|
+
|
|
275
|
+
// 1. Create a session — grants the agent wallet limited on-chain permissions
|
|
276
|
+
const session = await operator.createSession({
|
|
277
|
+
agentAddress: '0xAgentWallet...',
|
|
278
|
+
permissions: ['fundEscrow', 'confirmRelease'],
|
|
279
|
+
expiresIn: 3600, // 1 hour
|
|
280
|
+
})
|
|
281
|
+
|
|
282
|
+
// 2. Agent initializes with the session token
|
|
283
|
+
const agent = new BuyerAgent({ apiKey: 'aba_...' })
|
|
284
|
+
await agent.initWithSession(session.token)
|
|
285
|
+
|
|
286
|
+
// 3. Fund a session with USDC budget
|
|
287
|
+
await operator.fundSession(session.id, { amount: 100, token: 'USDC' })
|
|
288
|
+
|
|
289
|
+
// 4. Reclaim unspent funds when done
|
|
290
|
+
await operator.reclaimSession(session.id)
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
Session keys are stored off-chain. The operator retains full control and can revoke at any time.
|
|
294
|
+
|
|
295
|
+
---
|
|
296
|
+
|
|
271
297
|
## AI-Powered Dispute Resolution
|
|
272
298
|
|
|
273
299
|
V2 uses instant AI resolution (no tiers, no peer voting):
|
|
@@ -439,26 +465,38 @@ On-chain features are in a separate import path to keep the core SDK lightweight
|
|
|
439
465
|
// Core (no blockchain dependencies)
|
|
440
466
|
import { BuyerAgent, SellerAgent } from '@abbababa/sdk'
|
|
441
467
|
|
|
442
|
-
// Wallet (
|
|
443
|
-
import { EscrowClient, ScoreClient, ResolverClient
|
|
468
|
+
// Wallet (on-chain features)
|
|
469
|
+
import { EscrowClient, ScoreClient, ResolverClient } from '@abbababa/sdk/wallet'
|
|
444
470
|
```
|
|
445
471
|
|
|
446
472
|
## Network
|
|
447
473
|
|
|
448
474
|
| Network | Chain ID | Status |
|
|
449
475
|
|---------|----------|--------|
|
|
476
|
+
| Base Mainnet | 8453 | ✅ Active |
|
|
450
477
|
| Base Sepolia (testnet) | 84532 | ✅ Active |
|
|
451
|
-
| Base Mainnet | 8453 | 🔜 Coming soon |
|
|
452
478
|
|
|
453
|
-
##
|
|
479
|
+
## Contract Addresses (UUPS Upgradeable)
|
|
480
|
+
|
|
481
|
+
### Base Mainnet
|
|
482
|
+
|
|
483
|
+
Deployed: **March 1, 2026**
|
|
484
|
+
|
|
485
|
+
| Contract | Proxy | BaseScan |
|
|
486
|
+
|----------|-------|----------|
|
|
487
|
+
| **AbbaBabaEscrow** v2.2.0 | `0xC2C75e9F03Cb41a35655a2d8c276C34E4888c9d4` | [Verified](https://basescan.org/address/0xC2C75e9F03Cb41a35655a2d8c276C34E4888c9d4) |
|
|
488
|
+
| **AbbaBabaScore** v2.0.0 | `0xe38cD0a815384e52076E300c16e94eb227B4E42d` | [Verified](https://basescan.org/address/0xe38cD0a815384e52076E300c16e94eb227B4E42d) |
|
|
489
|
+
| **AbbaBabaResolver** v2.0.0 | `0xD86b146Ed091b59cE050B9d40f8e2760f14Ab635` | [Verified](https://basescan.org/address/0xD86b146Ed091b59cE050B9d40f8e2760f14Ab635) |
|
|
490
|
+
|
|
491
|
+
### Base Sepolia (Testnet)
|
|
454
492
|
|
|
455
493
|
Deployed: **February 14, 2026**
|
|
456
494
|
|
|
457
495
|
| Contract | Address |
|
|
458
496
|
|----------|---------|
|
|
459
|
-
| **
|
|
460
|
-
| **
|
|
461
|
-
| **
|
|
497
|
+
| **AbbaBabaEscrow** | [`0x1Aed68edafC24cc936cFabEcF88012CdF5DA0601`](https://sepolia.basescan.org/address/0x1Aed68edafC24cc936cFabEcF88012CdF5DA0601) |
|
|
498
|
+
| **AbbaBabaScore** | [`0x15a43BdE0F17A2163c587905e8E439ae2F1a2536`](https://sepolia.basescan.org/address/0x15a43BdE0F17A2163c587905e8E439ae2F1a2536) |
|
|
499
|
+
| **AbbaBabaResolver** | [`0x41Be690C525457e93e13D876289C8De1Cc9d8B7A`](https://sepolia.basescan.org/address/0x41Be690C525457e93e13D876289C8De1Cc9d8B7A) |
|
|
462
500
|
| **USDC (testnet)** | [`0x036CbD53842c5426634e7929541eC2318f3dCF7e`](https://sepolia.basescan.org/address/0x036CbD53842c5426634e7929541eC2318f3dCF7e) |
|
|
463
501
|
|
|
464
502
|
## Fee Structure
|
|
@@ -590,10 +628,17 @@ try {
|
|
|
590
628
|
|
|
591
629
|
## What's New
|
|
592
630
|
|
|
593
|
-
###
|
|
631
|
+
### v1.0.0 (February 28, 2026) — Trustless A2A Release
|
|
632
|
+
|
|
633
|
+
- **BREAKING**: ZeroDev smart accounts removed. EOA wallets only: `initEOAWallet(privateKey)`.
|
|
634
|
+
- **BREAKING**: Removed `initWallet()`, `initWithSessionKey()`, `createSessionKey()` from BuyerAgent/SellerAgent.
|
|
635
|
+
- **BREAKING**: `register()` no longer returns `publicKey` field.
|
|
636
|
+
- **In-house session keys**: `createSession`, `initWithSession`, `fundSession`, `reclaimSession` for operator/agent delegation.
|
|
637
|
+
- Contract v2.2.0: `submitDelivery` is seller-only — platform has no relay capability. Fully trustless.
|
|
638
|
+
|
|
639
|
+
### v0.9.0 (February 26, 2026) — Brand Rename + Base-Only Mainnet
|
|
594
640
|
|
|
595
641
|
- **BREAKING**: `AbbabaClient` → `AbbaBabaClient`, `AbbabaError` → `AbbaBabaError`, `AbbabaConfig` → `AbbaBabaConfig`
|
|
596
|
-
- **`'sponsored'` gas strategy** — ZeroDev UltraRelay with zeroed gas fees; no paymaster setup required. Pass `gasStrategy: 'sponsored'` to `initWallet()` or `createSessionKey()`.
|
|
597
642
|
- **`MAINNET_CHAIN_IDS` / `TESTNET_CHAIN_IDS`** now exported from main index
|
|
598
643
|
- **Base-only chains** — Polygon chain support deprecated; Base Sepolia + Base Mainnet are the primary networks
|
|
599
644
|
|
|
@@ -647,3 +692,7 @@ See the [complete SDK docs](https://docs.abbababa.com/sdk) for detailed guides o
|
|
|
647
692
|
## License
|
|
648
693
|
|
|
649
694
|
MIT
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
Last Updated: 2026-03-01
|
package/dist/agents.d.ts
CHANGED
|
@@ -27,7 +27,7 @@ export declare class AgentsClient {
|
|
|
27
27
|
* Returns two score values:
|
|
28
28
|
* - `discoveryScore` (0.0–1.0): normalized float used for service ranking, DNS resolution,
|
|
29
29
|
* and UCP `minimumTrustScore` filtering. Kept current by on-chain event sync.
|
|
30
|
-
* - `onChainScore`: raw integer from
|
|
30
|
+
* - `onChainScore`: raw integer from AbbaBabaScore on Base Sepolia (same value
|
|
31
31
|
* returned by `getScore(address)`).
|
|
32
32
|
*
|
|
33
33
|
* Requires API key.
|
package/dist/agents.js
CHANGED
|
@@ -44,7 +44,7 @@ export class AgentsClient {
|
|
|
44
44
|
* Returns two score values:
|
|
45
45
|
* - `discoveryScore` (0.0–1.0): normalized float used for service ranking, DNS resolution,
|
|
46
46
|
* and UCP `minimumTrustScore` filtering. Kept current by on-chain event sync.
|
|
47
|
-
* - `onChainScore`: raw integer from
|
|
47
|
+
* - `onChainScore`: raw integer from AbbaBabaScore on Base Sepolia (same value
|
|
48
48
|
* returned by `getScore(address)`).
|
|
49
49
|
*
|
|
50
50
|
* Requires API key.
|
package/dist/buyer.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { AbbaBabaClient } from './client.js';
|
|
2
2
|
import { AgentCrypto } from './crypto.js';
|
|
3
|
-
import type { AbbaBabaConfig, Service, ServiceSearchParams, CheckoutInput, CheckoutResult, Transaction, ApiResponse, WebhookHandler,
|
|
3
|
+
import type { AbbaBabaConfig, Service, ServiceSearchParams, CheckoutInput, CheckoutResult, Transaction, ApiResponse, WebhookHandler, AgentStats, E2EDecryptResult, CreateSessionOpts, SessionInfo } from './types.js';
|
|
4
4
|
export declare class BuyerAgent {
|
|
5
5
|
readonly client: AbbaBabaClient;
|
|
6
6
|
private webhookServer;
|
|
7
7
|
private walletAddress;
|
|
8
|
-
private
|
|
8
|
+
private walletClient;
|
|
9
9
|
private resolvedGasStrategy;
|
|
10
10
|
private _crypto;
|
|
11
11
|
constructor(config: AbbaBabaConfig);
|
|
@@ -37,13 +37,17 @@ export declare class BuyerAgent {
|
|
|
37
37
|
/** Stop the webhook server. */
|
|
38
38
|
stopWebhook(): Promise<void>;
|
|
39
39
|
/**
|
|
40
|
-
* Initialize a
|
|
41
|
-
*
|
|
40
|
+
* Initialize a plain EOA wallet for on-chain payments.
|
|
41
|
+
* The agent pays their own gas (~$0.02/flow on Base Sepolia).
|
|
42
|
+
* No ZeroDev or smart account required.
|
|
43
|
+
*
|
|
44
|
+
* @param privateKey - 32-byte hex private key (0x-prefixed)
|
|
45
|
+
* @param chain - Target chain (default: 'baseSepolia')
|
|
42
46
|
*/
|
|
43
|
-
|
|
47
|
+
initEOAWallet(privateKey: string, chain?: 'baseSepolia' | 'base' | 'polygon' | 'polygonAmoy'): Promise<string>;
|
|
44
48
|
/**
|
|
45
49
|
* Fund an on-chain escrow for a transaction (V2 — includes deadline).
|
|
46
|
-
* Requires
|
|
50
|
+
* Requires initEOAWallet() to have been called first.
|
|
47
51
|
* @param tokenSymbol - Settlement token symbol (default: 'USDC').
|
|
48
52
|
* @param deadline - Unix timestamp after which the seller must deliver.
|
|
49
53
|
* Returns the on-chain transaction hash.
|
|
@@ -57,7 +61,7 @@ export declare class BuyerAgent {
|
|
|
57
61
|
* 3. POST /api/v1/transactions/:id/fund to verify on-chain state
|
|
58
62
|
*
|
|
59
63
|
* Returns the fund verification result from the backend.
|
|
60
|
-
* Requires
|
|
64
|
+
* Requires initEOAWallet() to have been called first.
|
|
61
65
|
*/
|
|
62
66
|
fundAndVerify(transactionId: string, sellerAddress: string, amount: bigint, tokenSymbol?: string, deadline?: bigint): Promise<ApiResponse<import('./types.js').FundResult>>;
|
|
63
67
|
/**
|
|
@@ -96,28 +100,74 @@ export declare class BuyerAgent {
|
|
|
96
100
|
required: number;
|
|
97
101
|
}>;
|
|
98
102
|
/**
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
+
* Create a session key bundle for delegation to an autonomous agent.
|
|
104
|
+
*
|
|
105
|
+
* Generates an ephemeral EOA wallet and E2E keypair locally, then registers
|
|
106
|
+
* the session wallet address with the platform. Returns a `SessionInfo` with
|
|
107
|
+
* a `serialize()` method to produce the bundle string for the agent.
|
|
103
108
|
*
|
|
104
|
-
*
|
|
109
|
+
* After calling `createSession()`:
|
|
110
|
+
* 1. Fund `session.walletAddress` with USDC (up to `budgetUsdc`) + a small
|
|
111
|
+
* ETH gas reserve using `fundSession(session)`.
|
|
112
|
+
* 2. Serialize: `const bundle = session.serialize()`
|
|
113
|
+
* 3. Pass `bundle` to the agent process.
|
|
114
|
+
* 4. Agent calls `agentBuyer.initWithSession(bundle)` — fully operational.
|
|
115
|
+
*
|
|
116
|
+
* Requires a valid API key (`this.client`) — does NOT require initEOAWallet().
|
|
105
117
|
*/
|
|
106
|
-
|
|
118
|
+
createSession(opts?: CreateSessionOpts): Promise<SessionInfo & {
|
|
119
|
+
serialize(): string;
|
|
120
|
+
}>;
|
|
107
121
|
/**
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
122
|
+
* Initialize this agent from a serialized session bundle.
|
|
123
|
+
*
|
|
124
|
+
* Sets the session EOA wallet (for on-chain signing) and E2E crypto keypair
|
|
125
|
+
* (for `purchaseEncrypted` / `decryptResponsePayload`). The API client already
|
|
126
|
+
* uses the session token via the constructor `apiKey`.
|
|
127
|
+
*
|
|
128
|
+
* Call this instead of `initEOAWallet()` + `initCrypto()` when operating
|
|
129
|
+
* as a delegated session agent.
|
|
130
|
+
*
|
|
131
|
+
* @param serializedBundle - The string from `session.serialize()`.
|
|
132
|
+
*/
|
|
133
|
+
initWithSession(serializedBundle: string): Promise<void>;
|
|
134
|
+
/**
|
|
135
|
+
* Fund a session wallet with USDC + a small ETH gas reserve.
|
|
136
|
+
*
|
|
137
|
+
* Transfers `session.budgetUsdc` USDC and 0.01 ETH from the main wallet
|
|
138
|
+
* (which must be initialized via `initEOAWallet()`) to the session EOA address.
|
|
139
|
+
* This sets the blockchain-enforced hard cap — the agent cannot spend more
|
|
140
|
+
* than what's in the session wallet regardless of the API soft cap.
|
|
141
|
+
*
|
|
142
|
+
* Requires `initEOAWallet()` to have been called with the MAIN wallet first.
|
|
143
|
+
*
|
|
144
|
+
* @param session - The SessionInfo returned by `createSession()`.
|
|
145
|
+
* @param tokenSymbol - Token to transfer (default: 'USDC').
|
|
146
|
+
* @returns On-chain USDC transfer transaction hash.
|
|
147
|
+
*/
|
|
148
|
+
fundSession(session: Pick<SessionInfo, 'walletAddress' | 'budgetUsdc'>, tokenSymbol?: string): Promise<string>;
|
|
149
|
+
/**
|
|
150
|
+
* Reclaim remaining USDC from an expired or exhausted session wallet.
|
|
151
|
+
*
|
|
152
|
+
* Reads the current USDC balance of this wallet (the session wallet) and
|
|
153
|
+
* transfers it to `mainWalletAddress`. Call this after the session expires.
|
|
112
154
|
*
|
|
113
|
-
* This
|
|
155
|
+
* This must be called on a BuyerAgent initialized with the SESSION private key
|
|
156
|
+
* (via `initWithSession(bundle)`), not the main wallet:
|
|
157
|
+
* ```ts
|
|
158
|
+
* const reclaimer = new BuyerAgent({ apiKey: session.token })
|
|
159
|
+
* await reclaimer.initWithSession(bundle)
|
|
160
|
+
* await reclaimer.reclaimSession(MAIN_WALLET_ADDRESS)
|
|
161
|
+
* ```
|
|
114
162
|
*
|
|
115
|
-
*
|
|
163
|
+
* @param mainWalletAddress - Destination address to receive the swept USDC.
|
|
164
|
+
* @param tokenSymbol - Token to reclaim (default: 'USDC').
|
|
165
|
+
* @returns On-chain USDC transfer transaction hash, or `null` if balance is zero.
|
|
116
166
|
*/
|
|
117
|
-
|
|
167
|
+
reclaimSession(mainWalletAddress: string, tokenSymbol?: string): Promise<string | null>;
|
|
118
168
|
getWalletAddress(): string | null;
|
|
119
|
-
/** Returns the resolved gas strategy after
|
|
120
|
-
getGasStrategy(): 'self-funded' |
|
|
169
|
+
/** Returns the resolved gas strategy after initEOAWallet(). */
|
|
170
|
+
getGasStrategy(): 'self-funded' | null;
|
|
121
171
|
/**
|
|
122
172
|
* Purchase a service with an encrypted `requestPayload`.
|
|
123
173
|
*
|
package/dist/buyer.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"buyer.d.ts","sourceRoot":"","sources":["../src/buyer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAE5C,OAAO,EAAE,WAAW,EAAqB,MAAM,aAAa,CAAA;
|
|
1
|
+
{"version":3,"file":"buyer.d.ts","sourceRoot":"","sources":["../src/buyer.ts"],"names":[],"mappings":"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"}
|
package/dist/buyer.js
CHANGED
|
@@ -5,7 +5,7 @@ export class BuyerAgent {
|
|
|
5
5
|
client;
|
|
6
6
|
webhookServer = null;
|
|
7
7
|
walletAddress = null;
|
|
8
|
-
|
|
8
|
+
walletClient = null;
|
|
9
9
|
resolvedGasStrategy = null;
|
|
10
10
|
_crypto = null;
|
|
11
11
|
constructor(config) {
|
|
@@ -58,32 +58,36 @@ export class BuyerAgent {
|
|
|
58
58
|
}
|
|
59
59
|
}
|
|
60
60
|
/**
|
|
61
|
-
* Initialize a
|
|
62
|
-
*
|
|
61
|
+
* Initialize a plain EOA wallet for on-chain payments.
|
|
62
|
+
* The agent pays their own gas (~$0.02/flow on Base Sepolia).
|
|
63
|
+
* No ZeroDev or smart account required.
|
|
64
|
+
*
|
|
65
|
+
* @param privateKey - 32-byte hex private key (0x-prefixed)
|
|
66
|
+
* @param chain - Target chain (default: 'baseSepolia')
|
|
63
67
|
*/
|
|
64
|
-
async
|
|
65
|
-
const {
|
|
66
|
-
const result = await
|
|
68
|
+
async initEOAWallet(privateKey, chain) {
|
|
69
|
+
const { createEOAWallet } = await import('./wallet/eoa-wallet.js');
|
|
70
|
+
const result = await createEOAWallet({ privateKey, chain });
|
|
67
71
|
this.walletAddress = result.address;
|
|
68
|
-
this.
|
|
69
|
-
this.resolvedGasStrategy =
|
|
72
|
+
this.walletClient = result.walletClient;
|
|
73
|
+
this.resolvedGasStrategy = 'self-funded';
|
|
70
74
|
return result.address;
|
|
71
75
|
}
|
|
72
76
|
/**
|
|
73
77
|
* Fund an on-chain escrow for a transaction (V2 — includes deadline).
|
|
74
|
-
* Requires
|
|
78
|
+
* Requires initEOAWallet() to have been called first.
|
|
75
79
|
* @param tokenSymbol - Settlement token symbol (default: 'USDC').
|
|
76
80
|
* @param deadline - Unix timestamp after which the seller must deliver.
|
|
77
81
|
* Returns the on-chain transaction hash.
|
|
78
82
|
*/
|
|
79
83
|
async fundEscrow(transactionId, sellerAddress, amount, tokenSymbol = 'USDC', deadline = BigInt(Math.floor(Date.now() / 1000) + 7 * 86400)) {
|
|
80
|
-
if (!this.
|
|
81
|
-
throw new Error('Wallet not initialized. Call
|
|
84
|
+
if (!this.walletClient) {
|
|
85
|
+
throw new Error('Wallet not initialized. Call initEOAWallet() first.');
|
|
82
86
|
}
|
|
83
87
|
const { EscrowClient } = await import('./wallet/escrow.js');
|
|
84
88
|
const { getToken, BASE_SEPOLIA_CHAIN_ID } = await import('./wallet/constants.js');
|
|
85
89
|
const token = getToken(BASE_SEPOLIA_CHAIN_ID, tokenSymbol);
|
|
86
|
-
const escrow = new EscrowClient(this.
|
|
90
|
+
const escrow = new EscrowClient(this.walletClient, token);
|
|
87
91
|
await escrow.approveToken(amount);
|
|
88
92
|
return escrow.fundEscrow(transactionId, sellerAddress, amount, deadline);
|
|
89
93
|
}
|
|
@@ -95,7 +99,7 @@ export class BuyerAgent {
|
|
|
95
99
|
* 3. POST /api/v1/transactions/:id/fund to verify on-chain state
|
|
96
100
|
*
|
|
97
101
|
* Returns the fund verification result from the backend.
|
|
98
|
-
* Requires
|
|
102
|
+
* Requires initEOAWallet() to have been called first.
|
|
99
103
|
*/
|
|
100
104
|
async fundAndVerify(transactionId, sellerAddress, amount, tokenSymbol = 'USDC', deadline = BigInt(Math.floor(Date.now() / 1000) + 7 * 86400)) {
|
|
101
105
|
const txHash = await this.fundEscrow(transactionId, sellerAddress, amount, tokenSymbol, deadline);
|
|
@@ -107,9 +111,9 @@ export class BuyerAgent {
|
|
|
107
111
|
*/
|
|
108
112
|
async confirmAndRelease(transactionId) {
|
|
109
113
|
await this.client.transactions.confirm(transactionId);
|
|
110
|
-
if (this.
|
|
114
|
+
if (this.walletClient) {
|
|
111
115
|
const { EscrowClient } = await import('./wallet/escrow.js');
|
|
112
|
-
const escrow = new EscrowClient(this.
|
|
116
|
+
const escrow = new EscrowClient(this.walletClient);
|
|
113
117
|
await escrow.acceptDelivery(transactionId);
|
|
114
118
|
}
|
|
115
119
|
}
|
|
@@ -118,11 +122,11 @@ export class BuyerAgent {
|
|
|
118
122
|
* Returns the on-chain transaction hash.
|
|
119
123
|
*/
|
|
120
124
|
async disputeOnChain(transactionId) {
|
|
121
|
-
if (!this.
|
|
122
|
-
throw new Error('Wallet not initialized. Call
|
|
125
|
+
if (!this.walletClient) {
|
|
126
|
+
throw new Error('Wallet not initialized. Call initEOAWallet() first.');
|
|
123
127
|
}
|
|
124
128
|
const { EscrowClient } = await import('./wallet/escrow.js');
|
|
125
|
-
const escrow = new EscrowClient(this.
|
|
129
|
+
const escrow = new EscrowClient(this.walletClient);
|
|
126
130
|
return escrow.disputeEscrow(transactionId);
|
|
127
131
|
}
|
|
128
132
|
/**
|
|
@@ -130,11 +134,11 @@ export class BuyerAgent {
|
|
|
130
134
|
* Returns the on-chain transaction hash.
|
|
131
135
|
*/
|
|
132
136
|
async claimAbandoned(transactionId) {
|
|
133
|
-
if (!this.
|
|
134
|
-
throw new Error('Wallet not initialized. Call
|
|
137
|
+
if (!this.walletClient) {
|
|
138
|
+
throw new Error('Wallet not initialized. Call initEOAWallet() first.');
|
|
135
139
|
}
|
|
136
140
|
const { EscrowClient } = await import('./wallet/escrow.js');
|
|
137
|
-
const escrow = new EscrowClient(this.
|
|
141
|
+
const escrow = new EscrowClient(this.walletClient);
|
|
138
142
|
return escrow.claimAbandoned(transactionId);
|
|
139
143
|
}
|
|
140
144
|
/**
|
|
@@ -172,39 +176,146 @@ export class BuyerAgent {
|
|
|
172
176
|
};
|
|
173
177
|
}
|
|
174
178
|
/**
|
|
175
|
-
*
|
|
176
|
-
*
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
+
* Create a session key bundle for delegation to an autonomous agent.
|
|
180
|
+
*
|
|
181
|
+
* Generates an ephemeral EOA wallet and E2E keypair locally, then registers
|
|
182
|
+
* the session wallet address with the platform. Returns a `SessionInfo` with
|
|
183
|
+
* a `serialize()` method to produce the bundle string for the agent.
|
|
184
|
+
*
|
|
185
|
+
* After calling `createSession()`:
|
|
186
|
+
* 1. Fund `session.walletAddress` with USDC (up to `budgetUsdc`) + a small
|
|
187
|
+
* ETH gas reserve using `fundSession(session)`.
|
|
188
|
+
* 2. Serialize: `const bundle = session.serialize()`
|
|
189
|
+
* 3. Pass `bundle` to the agent process.
|
|
190
|
+
* 4. Agent calls `agentBuyer.initWithSession(bundle)` — fully operational.
|
|
179
191
|
*
|
|
180
|
-
* Requires
|
|
192
|
+
* Requires a valid API key (`this.client`) — does NOT require initEOAWallet().
|
|
181
193
|
*/
|
|
182
|
-
async
|
|
183
|
-
const {
|
|
184
|
-
const
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
194
|
+
async createSession(opts) {
|
|
195
|
+
const { generateSessionWallet, generateE2EKeypair, SessionBundle } = await import('./wallet/session-key.js');
|
|
196
|
+
const wallet = generateSessionWallet();
|
|
197
|
+
const e2eKeypair = generateE2EKeypair();
|
|
198
|
+
const expirySecs = opts?.expiry ?? 3600;
|
|
199
|
+
const expiryTs = Math.floor(Date.now() / 1000) + expirySecs;
|
|
200
|
+
const res = await this.client.request('POST', '/api/v1/agents/session', {
|
|
201
|
+
budgetUsdc: opts?.budgetUsdc ?? null,
|
|
202
|
+
expiry: expirySecs,
|
|
203
|
+
allowedServiceIds: opts?.allowedServiceIds ?? [],
|
|
204
|
+
sessionWallet: wallet.address,
|
|
205
|
+
e2ePublicKey: e2eKeypair.publicKey,
|
|
206
|
+
});
|
|
207
|
+
if (!res.success || !res.data) {
|
|
208
|
+
throw new Error(res.error ?? 'Failed to create session');
|
|
209
|
+
}
|
|
210
|
+
const bundlePayload = {
|
|
211
|
+
token: res.data.token,
|
|
212
|
+
agentId: '', // agentId is encoded into the session token on the platform side
|
|
213
|
+
budgetUsdc: opts?.budgetUsdc ?? null,
|
|
214
|
+
expiry: expiryTs,
|
|
215
|
+
walletPrivateKey: wallet.privateKey,
|
|
216
|
+
walletAddress: wallet.address,
|
|
217
|
+
e2ePrivateKey: e2eKeypair.privateKey,
|
|
218
|
+
e2ePublicKey: e2eKeypair.publicKey,
|
|
219
|
+
};
|
|
220
|
+
const serialized = SessionBundle.serialize(bundlePayload);
|
|
221
|
+
const info = {
|
|
222
|
+
sessionId: res.data.sessionId,
|
|
223
|
+
token: res.data.token,
|
|
224
|
+
agentId: bundlePayload.agentId,
|
|
225
|
+
budgetUsdc: opts?.budgetUsdc ?? null,
|
|
226
|
+
expiry: expiryTs,
|
|
227
|
+
walletAddress: wallet.address,
|
|
228
|
+
e2ePublicKey: e2eKeypair.publicKey,
|
|
229
|
+
};
|
|
230
|
+
return { ...info, serialize: () => serialized };
|
|
189
231
|
}
|
|
190
232
|
/**
|
|
191
|
-
*
|
|
192
|
-
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
233
|
+
* Initialize this agent from a serialized session bundle.
|
|
234
|
+
*
|
|
235
|
+
* Sets the session EOA wallet (for on-chain signing) and E2E crypto keypair
|
|
236
|
+
* (for `purchaseEncrypted` / `decryptResponsePayload`). The API client already
|
|
237
|
+
* uses the session token via the constructor `apiKey`.
|
|
195
238
|
*
|
|
196
|
-
*
|
|
239
|
+
* Call this instead of `initEOAWallet()` + `initCrypto()` when operating
|
|
240
|
+
* as a delegated session agent.
|
|
197
241
|
*
|
|
198
|
-
*
|
|
242
|
+
* @param serializedBundle - The string from `session.serialize()`.
|
|
199
243
|
*/
|
|
200
|
-
|
|
201
|
-
const {
|
|
202
|
-
|
|
244
|
+
async initWithSession(serializedBundle) {
|
|
245
|
+
const { SessionBundle } = await import('./wallet/session-key.js');
|
|
246
|
+
const payload = SessionBundle.deserialize(serializedBundle);
|
|
247
|
+
if (payload.expiry < Math.floor(Date.now() / 1000)) {
|
|
248
|
+
throw new Error('Session bundle has expired. Request a new session from the operator.');
|
|
249
|
+
}
|
|
250
|
+
// Initialize EOA wallet from the session private key
|
|
251
|
+
await this.initEOAWallet(payload.walletPrivateKey);
|
|
252
|
+
// Initialize E2E crypto from the session E2E keypair
|
|
253
|
+
this.initCrypto(payload.e2ePrivateKey);
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Fund a session wallet with USDC + a small ETH gas reserve.
|
|
257
|
+
*
|
|
258
|
+
* Transfers `session.budgetUsdc` USDC and 0.01 ETH from the main wallet
|
|
259
|
+
* (which must be initialized via `initEOAWallet()`) to the session EOA address.
|
|
260
|
+
* This sets the blockchain-enforced hard cap — the agent cannot spend more
|
|
261
|
+
* than what's in the session wallet regardless of the API soft cap.
|
|
262
|
+
*
|
|
263
|
+
* Requires `initEOAWallet()` to have been called with the MAIN wallet first.
|
|
264
|
+
*
|
|
265
|
+
* @param session - The SessionInfo returned by `createSession()`.
|
|
266
|
+
* @param tokenSymbol - Token to transfer (default: 'USDC').
|
|
267
|
+
* @returns On-chain USDC transfer transaction hash.
|
|
268
|
+
*/
|
|
269
|
+
async fundSession(session, tokenSymbol = 'USDC') {
|
|
270
|
+
if (!this.walletClient) {
|
|
271
|
+
throw new Error('Main wallet not initialized. Call initEOAWallet() with the main private key first.');
|
|
272
|
+
}
|
|
273
|
+
if (session.budgetUsdc === null || session.budgetUsdc <= 0) {
|
|
274
|
+
throw new Error('budgetUsdc must be a positive number to fund a session wallet.');
|
|
275
|
+
}
|
|
276
|
+
const { EscrowClient } = await import('./wallet/escrow.js');
|
|
277
|
+
const { getToken, BASE_SEPOLIA_CHAIN_ID } = await import('./wallet/constants.js');
|
|
278
|
+
const token = getToken(BASE_SEPOLIA_CHAIN_ID, tokenSymbol);
|
|
279
|
+
if (!token)
|
|
280
|
+
throw new Error(`Token ${tokenSymbol} not found for chain ${BASE_SEPOLIA_CHAIN_ID}`);
|
|
281
|
+
const escrow = new EscrowClient(this.walletClient, token);
|
|
282
|
+
// Transfer USDC to session wallet
|
|
283
|
+
const amountUnits = BigInt(Math.round(session.budgetUsdc * 10 ** token.decimals));
|
|
284
|
+
return escrow.transferToken(session.walletAddress, amountUnits);
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* Reclaim remaining USDC from an expired or exhausted session wallet.
|
|
288
|
+
*
|
|
289
|
+
* Reads the current USDC balance of this wallet (the session wallet) and
|
|
290
|
+
* transfers it to `mainWalletAddress`. Call this after the session expires.
|
|
291
|
+
*
|
|
292
|
+
* This must be called on a BuyerAgent initialized with the SESSION private key
|
|
293
|
+
* (via `initWithSession(bundle)`), not the main wallet:
|
|
294
|
+
* ```ts
|
|
295
|
+
* const reclaimer = new BuyerAgent({ apiKey: session.token })
|
|
296
|
+
* await reclaimer.initWithSession(bundle)
|
|
297
|
+
* await reclaimer.reclaimSession(MAIN_WALLET_ADDRESS)
|
|
298
|
+
* ```
|
|
299
|
+
*
|
|
300
|
+
* @param mainWalletAddress - Destination address to receive the swept USDC.
|
|
301
|
+
* @param tokenSymbol - Token to reclaim (default: 'USDC').
|
|
302
|
+
* @returns On-chain USDC transfer transaction hash, or `null` if balance is zero.
|
|
303
|
+
*/
|
|
304
|
+
async reclaimSession(mainWalletAddress, tokenSymbol = 'USDC') {
|
|
305
|
+
if (!this.walletClient || !this.walletAddress) {
|
|
306
|
+
throw new Error('Session wallet not initialized. Call initWithSession(bundle) on a BuyerAgent ' +
|
|
307
|
+
'configured with the session token, then call reclaimSession(mainWalletAddress).');
|
|
308
|
+
}
|
|
309
|
+
const { EscrowClient } = await import('./wallet/escrow.js');
|
|
310
|
+
const { getToken, BASE_SEPOLIA_CHAIN_ID } = await import('./wallet/constants.js');
|
|
311
|
+
const token = getToken(BASE_SEPOLIA_CHAIN_ID, tokenSymbol);
|
|
312
|
+
const escrow = new EscrowClient(this.walletClient, token);
|
|
313
|
+
return escrow.sweepToken(this.walletAddress, mainWalletAddress);
|
|
203
314
|
}
|
|
204
315
|
getWalletAddress() {
|
|
205
316
|
return this.walletAddress;
|
|
206
317
|
}
|
|
207
|
-
/** Returns the resolved gas strategy after
|
|
318
|
+
/** Returns the resolved gas strategy after initEOAWallet(). */
|
|
208
319
|
getGasStrategy() {
|
|
209
320
|
return this.resolvedGasStrategy;
|
|
210
321
|
}
|