celo-agent-sdk 0.1.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/dist/client.d.ts +264 -0
- package/dist/client.js +225 -0
- package/dist/exec.d.ts +14 -0
- package/dist/exec.js +48 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +7 -0
- package/dist/x402.d.ts +33 -0
- package/dist/x402.js +76 -0
- package/package.json +19 -0
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { X402FetchOptions } from './x402';
|
|
2
|
+
export interface WalletClientConfig {
|
|
3
|
+
/** Override path to celo-agent binary (default: "celo-agent" from PATH) */
|
|
4
|
+
cliPath?: string;
|
|
5
|
+
/** Extra environment variables passed to every CLI call */
|
|
6
|
+
env?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
export interface SendParams {
|
|
9
|
+
to: string;
|
|
10
|
+
amount: string;
|
|
11
|
+
token: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SendResult {
|
|
14
|
+
txHash: string;
|
|
15
|
+
status: string;
|
|
16
|
+
}
|
|
17
|
+
export interface SendPreview {
|
|
18
|
+
preview: true;
|
|
19
|
+
to: string;
|
|
20
|
+
amount: string;
|
|
21
|
+
symbol: string;
|
|
22
|
+
note: string;
|
|
23
|
+
}
|
|
24
|
+
export interface SwapParams {
|
|
25
|
+
from: string;
|
|
26
|
+
to: string;
|
|
27
|
+
amount: string;
|
|
28
|
+
}
|
|
29
|
+
export interface SwapResult {
|
|
30
|
+
txHash: string;
|
|
31
|
+
status: string;
|
|
32
|
+
}
|
|
33
|
+
export interface SwapPreview {
|
|
34
|
+
preview: true;
|
|
35
|
+
from: string;
|
|
36
|
+
to: string;
|
|
37
|
+
amount: string;
|
|
38
|
+
note: string;
|
|
39
|
+
}
|
|
40
|
+
export interface CallParams {
|
|
41
|
+
to: string;
|
|
42
|
+
data: string;
|
|
43
|
+
value?: string;
|
|
44
|
+
permission?: string | boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface CallResult {
|
|
47
|
+
txHash: string;
|
|
48
|
+
status: string;
|
|
49
|
+
}
|
|
50
|
+
export interface CallPreview {
|
|
51
|
+
preview: true;
|
|
52
|
+
to: string;
|
|
53
|
+
data: string;
|
|
54
|
+
value: string;
|
|
55
|
+
permissionId: string | null;
|
|
56
|
+
note: string;
|
|
57
|
+
}
|
|
58
|
+
export interface BalanceResult {
|
|
59
|
+
walletAddress: string;
|
|
60
|
+
chainId: number;
|
|
61
|
+
balances: Array<{
|
|
62
|
+
symbol: string;
|
|
63
|
+
balance: string;
|
|
64
|
+
address?: string;
|
|
65
|
+
}>;
|
|
66
|
+
}
|
|
67
|
+
export interface StatusResult {
|
|
68
|
+
ready: boolean;
|
|
69
|
+
reason?: string;
|
|
70
|
+
agentName?: string;
|
|
71
|
+
walletAddress?: string;
|
|
72
|
+
permissionId?: string;
|
|
73
|
+
chainId?: number;
|
|
74
|
+
expiry?: string;
|
|
75
|
+
expiresIn?: string;
|
|
76
|
+
permission?: unknown;
|
|
77
|
+
}
|
|
78
|
+
export interface SignResult {
|
|
79
|
+
signature: string;
|
|
80
|
+
}
|
|
81
|
+
export interface SelfStatusResult {
|
|
82
|
+
registered: boolean;
|
|
83
|
+
reason?: string;
|
|
84
|
+
selfAgentId?: number;
|
|
85
|
+
agentAddress?: string;
|
|
86
|
+
isVerified?: boolean;
|
|
87
|
+
verificationStrength?: number;
|
|
88
|
+
strengthLabel?: string;
|
|
89
|
+
network?: string;
|
|
90
|
+
}
|
|
91
|
+
export interface SelfRegisterParams {
|
|
92
|
+
network?: string;
|
|
93
|
+
minAge?: string;
|
|
94
|
+
ofac?: boolean;
|
|
95
|
+
}
|
|
96
|
+
export interface SelfRegisterResult {
|
|
97
|
+
status: string;
|
|
98
|
+
selfAgentId?: number;
|
|
99
|
+
selfAgentAddress: string;
|
|
100
|
+
network: string;
|
|
101
|
+
}
|
|
102
|
+
export interface EnsClaimResult {
|
|
103
|
+
status: string;
|
|
104
|
+
subname: string;
|
|
105
|
+
address: string;
|
|
106
|
+
chainId: number;
|
|
107
|
+
coinTypes: {
|
|
108
|
+
eth: number;
|
|
109
|
+
celoMainnet: number;
|
|
110
|
+
celoSepolia: number;
|
|
111
|
+
};
|
|
112
|
+
note: string;
|
|
113
|
+
}
|
|
114
|
+
export interface ERC8004StatusResult {
|
|
115
|
+
registered: boolean;
|
|
116
|
+
agentId?: number;
|
|
117
|
+
owner?: string;
|
|
118
|
+
walletAddress?: string;
|
|
119
|
+
agentURI?: string;
|
|
120
|
+
registrationFile?: unknown;
|
|
121
|
+
network: string;
|
|
122
|
+
scan?: string;
|
|
123
|
+
}
|
|
124
|
+
export interface ERC8004UpdateParams {
|
|
125
|
+
network?: string;
|
|
126
|
+
agentId?: string;
|
|
127
|
+
name?: string;
|
|
128
|
+
description?: string;
|
|
129
|
+
url?: string;
|
|
130
|
+
a2a?: string;
|
|
131
|
+
mcp?: string;
|
|
132
|
+
ens?: string;
|
|
133
|
+
did?: string;
|
|
134
|
+
email?: string;
|
|
135
|
+
image?: string;
|
|
136
|
+
x402?: boolean;
|
|
137
|
+
tags?: string[];
|
|
138
|
+
categories?: string[];
|
|
139
|
+
protocols?: string[];
|
|
140
|
+
}
|
|
141
|
+
export interface ERC8004UpdateResult {
|
|
142
|
+
status: string;
|
|
143
|
+
agentId: string;
|
|
144
|
+
txHash: string;
|
|
145
|
+
network: string;
|
|
146
|
+
scan: string;
|
|
147
|
+
registrationFile: unknown;
|
|
148
|
+
}
|
|
149
|
+
export interface ERC8004VerifyResult {
|
|
150
|
+
path: string;
|
|
151
|
+
url: string;
|
|
152
|
+
domain: string | null;
|
|
153
|
+
agentId: number | undefined;
|
|
154
|
+
network: string;
|
|
155
|
+
content: unknown;
|
|
156
|
+
}
|
|
157
|
+
export interface ERC8004ReputationScoreResult {
|
|
158
|
+
agentId: string;
|
|
159
|
+
network: string;
|
|
160
|
+
reputationRegistry: string;
|
|
161
|
+
totalFeedback: string;
|
|
162
|
+
averageScore: string;
|
|
163
|
+
reputationScore: string;
|
|
164
|
+
scan: string;
|
|
165
|
+
}
|
|
166
|
+
export interface ERC8004FeedbackParams {
|
|
167
|
+
network?: string;
|
|
168
|
+
agentId?: string;
|
|
169
|
+
score?: number;
|
|
170
|
+
tag?: string;
|
|
171
|
+
content?: string;
|
|
172
|
+
}
|
|
173
|
+
export interface ERC8004FeedbackResult {
|
|
174
|
+
status: string;
|
|
175
|
+
feedbackId: string | null;
|
|
176
|
+
txHash: string;
|
|
177
|
+
agentId: string;
|
|
178
|
+
score: number;
|
|
179
|
+
tag: string;
|
|
180
|
+
network: string;
|
|
181
|
+
}
|
|
182
|
+
export declare function createWalletClient(config?: WalletClientConfig): {
|
|
183
|
+
/** Send tokens. Executes immediately (broadcasts). */
|
|
184
|
+
send(params: SendParams): Promise<SendResult>;
|
|
185
|
+
/** Dry-run a send — returns what would be sent without executing. */
|
|
186
|
+
previewSend(params: SendParams): Promise<SendPreview>;
|
|
187
|
+
/** Swap tokens. Executes immediately (broadcasts). */
|
|
188
|
+
swap(params: SwapParams): Promise<SwapResult>;
|
|
189
|
+
/** Dry-run a swap — returns what would be swapped without executing. */
|
|
190
|
+
previewSwap(params: SwapParams): Promise<SwapPreview>;
|
|
191
|
+
/** Execute an arbitrary contract call. Broadcasts immediately. */
|
|
192
|
+
call(params: CallParams): Promise<CallResult>;
|
|
193
|
+
/** Dry-run a contract call. */
|
|
194
|
+
previewCall(params: CallParams): Promise<CallPreview>;
|
|
195
|
+
/** Check wallet balances (native + ERC-20). */
|
|
196
|
+
balance(): Promise<BalanceResult>;
|
|
197
|
+
/** Show agent config, permission expiry, and live permission data. */
|
|
198
|
+
status(): Promise<StatusResult>;
|
|
199
|
+
/** Raw secp256k1 sign of a 32-byte hash (session key EOA). */
|
|
200
|
+
sign(params: {
|
|
201
|
+
hash: string;
|
|
202
|
+
}): Promise<SignResult>;
|
|
203
|
+
/** EIP-191 personal sign (smart account). */
|
|
204
|
+
signMessage(params: {
|
|
205
|
+
message: string;
|
|
206
|
+
}): Promise<SignResult>;
|
|
207
|
+
/** EIP-712 typed data sign (smart account). */
|
|
208
|
+
signTyped(params: {
|
|
209
|
+
data: object | string;
|
|
210
|
+
}): Promise<SignResult>;
|
|
211
|
+
/**
|
|
212
|
+
* Create a fetch function that auto-handles x402 payments.
|
|
213
|
+
* Signs EIP-3009 TransferWithAuthorization with the session key EOA.
|
|
214
|
+
* The EOA must hold USDC for this to work.
|
|
215
|
+
*
|
|
216
|
+
* Usage:
|
|
217
|
+
* const wallet = createWalletClient()
|
|
218
|
+
* const fetchWithPay = wallet.x402Fetch()
|
|
219
|
+
* const res = await fetchWithPay('https://paid-api.com/data')
|
|
220
|
+
*/
|
|
221
|
+
x402Fetch(x402Options?: Omit<X402FetchOptions, "cliPath" | "env">): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
222
|
+
/** Check Self.xyz on-chain registration status. */
|
|
223
|
+
selfStatus(): Promise<SelfStatusResult>;
|
|
224
|
+
/** Register agent with Self.xyz (opens browser for human proof). */
|
|
225
|
+
selfRegister(params?: SelfRegisterParams): Promise<SelfRegisterResult>;
|
|
226
|
+
/**
|
|
227
|
+
* Claim a free ENS subname via JustaName (e.g. my-agent.jaw.eth).
|
|
228
|
+
* Sets address records for ETH, Celo mainnet, and Celo Sepolia.
|
|
229
|
+
* Requires JUSTANAME_API_KEY and JUSTANAME_ENS_DOMAIN in env (or pass directly).
|
|
230
|
+
*/
|
|
231
|
+
ensClaim(params?: {
|
|
232
|
+
username?: string;
|
|
233
|
+
ensDomain?: string;
|
|
234
|
+
apiKey?: string;
|
|
235
|
+
chainId?: number;
|
|
236
|
+
address?: string;
|
|
237
|
+
description?: string;
|
|
238
|
+
url?: string;
|
|
239
|
+
avatar?: string;
|
|
240
|
+
}): Promise<EnsClaimResult>;
|
|
241
|
+
/** Read ERC-8004 on-chain registration status and Agent Card. */
|
|
242
|
+
erc8004Status(params?: {
|
|
243
|
+
network?: string;
|
|
244
|
+
agentId?: string;
|
|
245
|
+
}): Promise<ERC8004StatusResult>;
|
|
246
|
+
/** Patch-and-publish: deep-merge overrides into current Agent Card and broadcast. */
|
|
247
|
+
erc8004Update(params: ERC8004UpdateParams): Promise<ERC8004UpdateResult>;
|
|
248
|
+
/**
|
|
249
|
+
* Generate `.well-known/agent-registration.json` content for endpoint verification.
|
|
250
|
+
* Returns the JSON to host; hosting instructions go to CLI stderr.
|
|
251
|
+
*/
|
|
252
|
+
erc8004Verify(params?: {
|
|
253
|
+
network?: string;
|
|
254
|
+
agentId?: string;
|
|
255
|
+
domain?: string;
|
|
256
|
+
}): Promise<ERC8004VerifyResult>;
|
|
257
|
+
/** Read on-chain reputation score from the ERC-8004 Reputation Registry. */
|
|
258
|
+
erc8004ReputationScore(params?: {
|
|
259
|
+
network?: string;
|
|
260
|
+
agentId?: string;
|
|
261
|
+
}): Promise<ERC8004ReputationScoreResult>;
|
|
262
|
+
/** Submit on-chain feedback to the ERC-8004 Reputation Registry. */
|
|
263
|
+
erc8004Feedback(params?: ERC8004FeedbackParams): Promise<ERC8004FeedbackResult>;
|
|
264
|
+
};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createWalletClient = createWalletClient;
|
|
4
|
+
/**
|
|
5
|
+
* SDK client for AI agents to interact with a JAW smart wallet.
|
|
6
|
+
*
|
|
7
|
+
* Every method shells out to the celo-agent CLI as a subprocess.
|
|
8
|
+
* Zero crypto dependencies — all signing happens inside the CLI process.
|
|
9
|
+
*/
|
|
10
|
+
const exec_1 = require("./exec");
|
|
11
|
+
const x402_1 = require("./x402");
|
|
12
|
+
// ── Client ───────────────────────────────────────────────────────────────────
|
|
13
|
+
function createWalletClient(config) {
|
|
14
|
+
const opts = {
|
|
15
|
+
cliPath: config?.cliPath,
|
|
16
|
+
env: config?.env,
|
|
17
|
+
};
|
|
18
|
+
return {
|
|
19
|
+
// ── Transactions ───────────────────────────────────────────────────────
|
|
20
|
+
/** Send tokens. Executes immediately (broadcasts). */
|
|
21
|
+
send(params) {
|
|
22
|
+
return (0, exec_1.execCli)(['send', '--to', params.to, '--amount', params.amount, '--symbol', params.token, '--broadcast'], opts);
|
|
23
|
+
},
|
|
24
|
+
/** Dry-run a send — returns what would be sent without executing. */
|
|
25
|
+
previewSend(params) {
|
|
26
|
+
return (0, exec_1.execCli)(['send', '--to', params.to, '--amount', params.amount, '--symbol', params.token], opts);
|
|
27
|
+
},
|
|
28
|
+
/** Swap tokens. Executes immediately (broadcasts). */
|
|
29
|
+
swap(params) {
|
|
30
|
+
return (0, exec_1.execCli)(['swap', '--from', params.from, '--to', params.to, '--amount', params.amount, '--broadcast'], opts);
|
|
31
|
+
},
|
|
32
|
+
/** Dry-run a swap — returns what would be swapped without executing. */
|
|
33
|
+
previewSwap(params) {
|
|
34
|
+
return (0, exec_1.execCli)(['swap', '--from', params.from, '--to', params.to, '--amount', params.amount], opts);
|
|
35
|
+
},
|
|
36
|
+
/** Execute an arbitrary contract call. Broadcasts immediately. */
|
|
37
|
+
call(params) {
|
|
38
|
+
const args = ['call', '--to', params.to, '--data', params.data, '--broadcast'];
|
|
39
|
+
if (params.value)
|
|
40
|
+
args.push('--value', params.value);
|
|
41
|
+
if (params.permission === true) {
|
|
42
|
+
args.push('--permission');
|
|
43
|
+
}
|
|
44
|
+
else if (typeof params.permission === 'string') {
|
|
45
|
+
args.push('--permission', params.permission);
|
|
46
|
+
}
|
|
47
|
+
return (0, exec_1.execCli)(args, opts);
|
|
48
|
+
},
|
|
49
|
+
/** Dry-run a contract call. */
|
|
50
|
+
previewCall(params) {
|
|
51
|
+
const args = ['call', '--to', params.to, '--data', params.data];
|
|
52
|
+
if (params.value)
|
|
53
|
+
args.push('--value', params.value);
|
|
54
|
+
if (params.permission === true) {
|
|
55
|
+
args.push('--permission');
|
|
56
|
+
}
|
|
57
|
+
else if (typeof params.permission === 'string') {
|
|
58
|
+
args.push('--permission', params.permission);
|
|
59
|
+
}
|
|
60
|
+
return (0, exec_1.execCli)(args, opts);
|
|
61
|
+
},
|
|
62
|
+
// ── Read-only ──────────────────────────────────────────────────────────
|
|
63
|
+
/** Check wallet balances (native + ERC-20). */
|
|
64
|
+
balance() {
|
|
65
|
+
return (0, exec_1.execCli)(['balance'], opts);
|
|
66
|
+
},
|
|
67
|
+
/** Show agent config, permission expiry, and live permission data. */
|
|
68
|
+
status() {
|
|
69
|
+
return (0, exec_1.execCli)(['status'], opts);
|
|
70
|
+
},
|
|
71
|
+
// ── Signing ────────────────────────────────────────────────────────────
|
|
72
|
+
/** Raw secp256k1 sign of a 32-byte hash (session key EOA). */
|
|
73
|
+
sign(params) {
|
|
74
|
+
return (0, exec_1.execCli)(['sign', '--hash', params.hash], opts);
|
|
75
|
+
},
|
|
76
|
+
/** EIP-191 personal sign (smart account). */
|
|
77
|
+
signMessage(params) {
|
|
78
|
+
return (0, exec_1.execCli)(['sign-message', '--message', params.message], opts);
|
|
79
|
+
},
|
|
80
|
+
/** EIP-712 typed data sign (smart account). */
|
|
81
|
+
signTyped(params) {
|
|
82
|
+
const json = typeof params.data === 'string' ? params.data : JSON.stringify(params.data);
|
|
83
|
+
return (0, exec_1.execCli)(['sign-typed', '--data', json], opts);
|
|
84
|
+
},
|
|
85
|
+
// ── x402 ──────────────────────────────────────────────────────────────────
|
|
86
|
+
/**
|
|
87
|
+
* Create a fetch function that auto-handles x402 payments.
|
|
88
|
+
* Signs EIP-3009 TransferWithAuthorization with the session key EOA.
|
|
89
|
+
* The EOA must hold USDC for this to work.
|
|
90
|
+
*
|
|
91
|
+
* Usage:
|
|
92
|
+
* const wallet = createWalletClient()
|
|
93
|
+
* const fetchWithPay = wallet.x402Fetch()
|
|
94
|
+
* const res = await fetchWithPay('https://paid-api.com/data')
|
|
95
|
+
*/
|
|
96
|
+
x402Fetch(x402Options) {
|
|
97
|
+
return (0, x402_1.createX402Fetch)({ ...opts, ...x402Options });
|
|
98
|
+
},
|
|
99
|
+
// ── Self.xyz ────────────────────────────────────────────────────────────
|
|
100
|
+
/** Check Self.xyz on-chain registration status. */
|
|
101
|
+
selfStatus() {
|
|
102
|
+
return (0, exec_1.execCli)(['self-status'], opts);
|
|
103
|
+
},
|
|
104
|
+
/** Register agent with Self.xyz (opens browser for human proof). */
|
|
105
|
+
selfRegister(params) {
|
|
106
|
+
const args = ['self-register'];
|
|
107
|
+
if (params?.network)
|
|
108
|
+
args.push('--network', params.network);
|
|
109
|
+
if (params?.minAge)
|
|
110
|
+
args.push('--min-age', params.minAge);
|
|
111
|
+
if (params?.ofac)
|
|
112
|
+
args.push('--ofac');
|
|
113
|
+
return (0, exec_1.execCli)(args, opts);
|
|
114
|
+
},
|
|
115
|
+
// ── ENS / JustaName ─────────────────────────────────────────────────────
|
|
116
|
+
/**
|
|
117
|
+
* Claim a free ENS subname via JustaName (e.g. my-agent.jaw.eth).
|
|
118
|
+
* Sets address records for ETH, Celo mainnet, and Celo Sepolia.
|
|
119
|
+
* Requires JUSTANAME_API_KEY and JUSTANAME_ENS_DOMAIN in env (or pass directly).
|
|
120
|
+
*/
|
|
121
|
+
ensClaim(params) {
|
|
122
|
+
const args = ['ens-claim'];
|
|
123
|
+
if (params?.username)
|
|
124
|
+
args.push('--username', params.username);
|
|
125
|
+
if (params?.ensDomain)
|
|
126
|
+
args.push('--ens-domain', params.ensDomain);
|
|
127
|
+
if (params?.apiKey)
|
|
128
|
+
args.push('--api-key', params.apiKey);
|
|
129
|
+
if (params?.chainId)
|
|
130
|
+
args.push('--chain-id', String(params.chainId));
|
|
131
|
+
if (params?.address)
|
|
132
|
+
args.push('--address', params.address);
|
|
133
|
+
if (params?.description)
|
|
134
|
+
args.push('--description', params.description);
|
|
135
|
+
if (params?.url)
|
|
136
|
+
args.push('--url', params.url);
|
|
137
|
+
if (params?.avatar)
|
|
138
|
+
args.push('--avatar', params.avatar);
|
|
139
|
+
return (0, exec_1.execCli)(args, opts);
|
|
140
|
+
},
|
|
141
|
+
// ── ERC-8004 ────────────────────────────────────────────────────────────
|
|
142
|
+
/** Read ERC-8004 on-chain registration status and Agent Card. */
|
|
143
|
+
erc8004Status(params) {
|
|
144
|
+
const args = ['8004-status'];
|
|
145
|
+
if (params?.network)
|
|
146
|
+
args.push('--network', params.network);
|
|
147
|
+
if (params?.agentId)
|
|
148
|
+
args.push('--agent-id', params.agentId);
|
|
149
|
+
return (0, exec_1.execCli)(args, opts);
|
|
150
|
+
},
|
|
151
|
+
/** Patch-and-publish: deep-merge overrides into current Agent Card and broadcast. */
|
|
152
|
+
erc8004Update(params) {
|
|
153
|
+
const args = ['8004-update'];
|
|
154
|
+
if (params.network)
|
|
155
|
+
args.push('--network', params.network);
|
|
156
|
+
if (params.agentId)
|
|
157
|
+
args.push('--agent-id', params.agentId);
|
|
158
|
+
if (params.name)
|
|
159
|
+
args.push('--name', params.name);
|
|
160
|
+
if (params.description)
|
|
161
|
+
args.push('--description', params.description);
|
|
162
|
+
if (params.url)
|
|
163
|
+
args.push('--url', params.url);
|
|
164
|
+
if (params.a2a)
|
|
165
|
+
args.push('--a2a', params.a2a);
|
|
166
|
+
if (params.mcp)
|
|
167
|
+
args.push('--mcp', params.mcp);
|
|
168
|
+
if (params.ens)
|
|
169
|
+
args.push('--ens', params.ens);
|
|
170
|
+
if (params.did)
|
|
171
|
+
args.push('--did', params.did);
|
|
172
|
+
if (params.email)
|
|
173
|
+
args.push('--email', params.email);
|
|
174
|
+
if (params.image)
|
|
175
|
+
args.push('--image', params.image);
|
|
176
|
+
if (params.x402)
|
|
177
|
+
args.push('--x402');
|
|
178
|
+
if (params.tags?.length)
|
|
179
|
+
args.push('--tags', params.tags.join(','));
|
|
180
|
+
if (params.categories?.length)
|
|
181
|
+
args.push('--categories', params.categories.join(','));
|
|
182
|
+
if (params.protocols?.length)
|
|
183
|
+
args.push('--protocols', params.protocols.join(','));
|
|
184
|
+
return (0, exec_1.execCli)(args, opts);
|
|
185
|
+
},
|
|
186
|
+
/**
|
|
187
|
+
* Generate `.well-known/agent-registration.json` content for endpoint verification.
|
|
188
|
+
* Returns the JSON to host; hosting instructions go to CLI stderr.
|
|
189
|
+
*/
|
|
190
|
+
erc8004Verify(params) {
|
|
191
|
+
const args = ['8004-verify'];
|
|
192
|
+
if (params?.network)
|
|
193
|
+
args.push('--network', params.network);
|
|
194
|
+
if (params?.agentId)
|
|
195
|
+
args.push('--agent-id', params.agentId);
|
|
196
|
+
if (params?.domain)
|
|
197
|
+
args.push('--domain', params.domain);
|
|
198
|
+
return (0, exec_1.execCli)(args, opts);
|
|
199
|
+
},
|
|
200
|
+
/** Read on-chain reputation score from the ERC-8004 Reputation Registry. */
|
|
201
|
+
erc8004ReputationScore(params) {
|
|
202
|
+
const args = ['8004-reputation', '--action', 'score'];
|
|
203
|
+
if (params?.network)
|
|
204
|
+
args.push('--network', params.network);
|
|
205
|
+
if (params?.agentId)
|
|
206
|
+
args.push('--agent-id', params.agentId);
|
|
207
|
+
return (0, exec_1.execCli)(args, opts);
|
|
208
|
+
},
|
|
209
|
+
/** Submit on-chain feedback to the ERC-8004 Reputation Registry. */
|
|
210
|
+
erc8004Feedback(params) {
|
|
211
|
+
const args = ['8004-reputation', '--action', 'feedback'];
|
|
212
|
+
if (params?.network)
|
|
213
|
+
args.push('--network', params.network);
|
|
214
|
+
if (params?.agentId)
|
|
215
|
+
args.push('--agent-id', params.agentId);
|
|
216
|
+
if (params?.score !== undefined)
|
|
217
|
+
args.push('--score', String(params.score));
|
|
218
|
+
if (params?.tag)
|
|
219
|
+
args.push('--tag', params.tag);
|
|
220
|
+
if (params?.content)
|
|
221
|
+
args.push('--content', params.content);
|
|
222
|
+
return (0, exec_1.execCli)(args, opts);
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
}
|
package/dist/exec.d.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface ExecOptions {
|
|
2
|
+
/** Override path to celo-agent binary */
|
|
3
|
+
cliPath?: string;
|
|
4
|
+
/** Extra environment variables to pass to the subprocess */
|
|
5
|
+
env?: Record<string, string>;
|
|
6
|
+
}
|
|
7
|
+
export interface CliError {
|
|
8
|
+
error: string;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Execute a celo-agent CLI command and return the parsed JSON result.
|
|
12
|
+
* Throws if the command fails or returns { error }.
|
|
13
|
+
*/
|
|
14
|
+
export declare function execCli<T>(args: string[], options?: ExecOptions): Promise<T>;
|
package/dist/exec.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.execCli = execCli;
|
|
4
|
+
/**
|
|
5
|
+
* Subprocess executor for celo-agent CLI.
|
|
6
|
+
* Spawns celo-agent commands, captures stdout, parses JSON.
|
|
7
|
+
* Zero dependencies — only Node.js built-ins.
|
|
8
|
+
*/
|
|
9
|
+
const child_process_1 = require("child_process");
|
|
10
|
+
/**
|
|
11
|
+
* Execute a celo-agent CLI command and return the parsed JSON result.
|
|
12
|
+
* Throws if the command fails or returns { error }.
|
|
13
|
+
*/
|
|
14
|
+
function execCli(args, options) {
|
|
15
|
+
const bin = options?.cliPath ?? 'celo-agent';
|
|
16
|
+
return new Promise((resolve, reject) => {
|
|
17
|
+
(0, child_process_1.execFile)(bin, args, {
|
|
18
|
+
encoding: 'utf8',
|
|
19
|
+
env: { ...process.env, ...options?.env },
|
|
20
|
+
maxBuffer: 10 * 1024 * 1024, // 10 MB
|
|
21
|
+
}, (error, stdout, stderr) => {
|
|
22
|
+
if (error && !stdout.trim()) {
|
|
23
|
+
reject(new Error(stderr.trim() || error.message));
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
// Parse JSON from stdout — celo-agent always outputs a single JSON line
|
|
27
|
+
const trimmed = stdout.trim();
|
|
28
|
+
if (!trimmed) {
|
|
29
|
+
reject(new Error(`celo-agent ${args[0]}: no output`));
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
let result;
|
|
33
|
+
try {
|
|
34
|
+
result = JSON.parse(trimmed);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
reject(new Error(`celo-agent ${args[0]}: invalid JSON output: ${trimmed}`));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
// Check for CLI-level errors
|
|
41
|
+
if (result && typeof result === 'object' && 'error' in result) {
|
|
42
|
+
reject(new Error(result.error));
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
resolve(result);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { createWalletClient } from './client';
|
|
2
|
+
export { createX402Fetch } from './x402';
|
|
3
|
+
export type { WalletClientConfig, SendParams, SendResult, SendPreview, SwapParams, SwapResult, SwapPreview, CallParams, CallResult, CallPreview, BalanceResult, StatusResult, SignResult, } from './client';
|
|
4
|
+
export type { X402FetchOptions } from './x402';
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createX402Fetch = exports.createWalletClient = void 0;
|
|
4
|
+
var client_1 = require("./client");
|
|
5
|
+
Object.defineProperty(exports, "createWalletClient", { enumerable: true, get: function () { return client_1.createWalletClient; } });
|
|
6
|
+
var x402_1 = require("./x402");
|
|
7
|
+
Object.defineProperty(exports, "createX402Fetch", { enumerable: true, get: function () { return x402_1.createX402Fetch; } });
|
package/dist/x402.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402 payment integration for JAW AgentKit SDK.
|
|
3
|
+
*
|
|
4
|
+
* Wraps fetch to automatically handle HTTP 402 Payment Required responses.
|
|
5
|
+
* All signing happens in the CLI subprocess — zero crypto deps here.
|
|
6
|
+
*
|
|
7
|
+
* Protocol flow:
|
|
8
|
+
* 1. fetch(url) → 402 + payment requirements
|
|
9
|
+
* 2. celo-agent x402-sign → base64 payment payload
|
|
10
|
+
* 3. retry with PAYMENT-SIGNATURE / X-PAYMENT header
|
|
11
|
+
* 4. return response
|
|
12
|
+
*
|
|
13
|
+
* Supports x402 V1 (body + X-PAYMENT) and V2 (PAYMENT-REQUIRED + PAYMENT-SIGNATURE).
|
|
14
|
+
*/
|
|
15
|
+
import { ExecOptions } from './exec';
|
|
16
|
+
export interface X402FetchOptions extends ExecOptions {
|
|
17
|
+
/** Maximum payment amount in smallest unit (e.g. "1000000" = 1 USDC). Rejects if price exceeds this. */
|
|
18
|
+
maxAmount?: string;
|
|
19
|
+
/** Called before signing — return false to reject the payment. */
|
|
20
|
+
onPaymentRequired?: (info: {
|
|
21
|
+
amount: string;
|
|
22
|
+
payTo: string;
|
|
23
|
+
asset: string;
|
|
24
|
+
}) => boolean | Promise<boolean>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Create a fetch function that auto-handles x402 payments.
|
|
28
|
+
*
|
|
29
|
+
* Usage:
|
|
30
|
+
* const fetchWithPay = createX402Fetch({ cliPath: '/path/to/celo-agent' })
|
|
31
|
+
* const res = await fetchWithPay('https://paid-api.com/data')
|
|
32
|
+
*/
|
|
33
|
+
export declare function createX402Fetch(options?: X402FetchOptions): (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
package/dist/x402.js
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createX402Fetch = createX402Fetch;
|
|
4
|
+
/**
|
|
5
|
+
* x402 payment integration for JAW AgentKit SDK.
|
|
6
|
+
*
|
|
7
|
+
* Wraps fetch to automatically handle HTTP 402 Payment Required responses.
|
|
8
|
+
* All signing happens in the CLI subprocess — zero crypto deps here.
|
|
9
|
+
*
|
|
10
|
+
* Protocol flow:
|
|
11
|
+
* 1. fetch(url) → 402 + payment requirements
|
|
12
|
+
* 2. celo-agent x402-sign → base64 payment payload
|
|
13
|
+
* 3. retry with PAYMENT-SIGNATURE / X-PAYMENT header
|
|
14
|
+
* 4. return response
|
|
15
|
+
*
|
|
16
|
+
* Supports x402 V1 (body + X-PAYMENT) and V2 (PAYMENT-REQUIRED + PAYMENT-SIGNATURE).
|
|
17
|
+
*/
|
|
18
|
+
const exec_1 = require("./exec");
|
|
19
|
+
/**
|
|
20
|
+
* Create a fetch function that auto-handles x402 payments.
|
|
21
|
+
*
|
|
22
|
+
* Usage:
|
|
23
|
+
* const fetchWithPay = createX402Fetch({ cliPath: '/path/to/celo-agent' })
|
|
24
|
+
* const res = await fetchWithPay('https://paid-api.com/data')
|
|
25
|
+
*/
|
|
26
|
+
function createX402Fetch(options) {
|
|
27
|
+
const execOpts = {
|
|
28
|
+
cliPath: options?.cliPath,
|
|
29
|
+
env: options?.env,
|
|
30
|
+
};
|
|
31
|
+
return async (input, init) => {
|
|
32
|
+
// 1. Initial request
|
|
33
|
+
const response = await fetch(new Request(input, init));
|
|
34
|
+
if (response.status !== 402)
|
|
35
|
+
return response;
|
|
36
|
+
// 2. Parse payment requirements — V2 header or V1 body
|
|
37
|
+
let requirements;
|
|
38
|
+
const paymentRequiredHeader = response.headers.get('PAYMENT-REQUIRED');
|
|
39
|
+
if (paymentRequiredHeader) {
|
|
40
|
+
// V2: base64-encoded header
|
|
41
|
+
requirements = JSON.parse(Buffer.from(paymentRequiredHeader, 'base64').toString('utf8'));
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
// V1: JSON body
|
|
45
|
+
const text = await response.text();
|
|
46
|
+
requirements = JSON.parse(text);
|
|
47
|
+
}
|
|
48
|
+
// 3. Optional guard: check amount / ask caller
|
|
49
|
+
if (options?.onPaymentRequired || options?.maxAmount) {
|
|
50
|
+
const accepts = requirements.accepts || [];
|
|
51
|
+
const selected = accepts.find(a => a.scheme === 'exact');
|
|
52
|
+
if (selected) {
|
|
53
|
+
const amount = selected.amount || selected.maxAmountRequired || '0';
|
|
54
|
+
if (options.maxAmount && BigInt(amount) > BigInt(options.maxAmount)) {
|
|
55
|
+
throw new Error(`x402 payment rejected: price ${amount} exceeds max ${options.maxAmount}`);
|
|
56
|
+
}
|
|
57
|
+
if (options.onPaymentRequired) {
|
|
58
|
+
const approved = await options.onPaymentRequired({
|
|
59
|
+
amount,
|
|
60
|
+
payTo: selected.payTo,
|
|
61
|
+
asset: selected.asset,
|
|
62
|
+
});
|
|
63
|
+
if (!approved)
|
|
64
|
+
throw new Error('x402 payment rejected by onPaymentRequired callback.');
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// 4. Sign via CLI
|
|
69
|
+
const result = await (0, exec_1.execCli)(['x402-sign', '--requirements', JSON.stringify(requirements)], execOpts);
|
|
70
|
+
// 5. Retry with payment header
|
|
71
|
+
const retryInit = { ...init, headers: new Headers(init?.headers) };
|
|
72
|
+
retryInit.headers.set(result.headerName, result.headerValue);
|
|
73
|
+
retryInit.headers.set('Access-Control-Expose-Headers', 'PAYMENT-RESPONSE,X-PAYMENT-RESPONSE');
|
|
74
|
+
return fetch(new Request(input, retryInit));
|
|
75
|
+
};
|
|
76
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "celo-agent-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "SDK for AI agents to interact with JAW smart wallets via the celo-agent CLI",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": ["dist"],
|
|
8
|
+
"scripts": {
|
|
9
|
+
"build": "tsc",
|
|
10
|
+
"dev": "tsc --watch"
|
|
11
|
+
},
|
|
12
|
+
"devDependencies": {
|
|
13
|
+
"@types/node": "^20.0.0",
|
|
14
|
+
"typescript": "^5.0.0"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"thirdweb": "^5.119.1"
|
|
18
|
+
}
|
|
19
|
+
}
|