@agensai/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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 JustaLab
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,51 @@
1
+ # `@agensai/sdk`
2
+
3
+ TypeScript SDK for creating ENS-named AI agent wallets.
4
+
5
+ ```bash
6
+ npm install @agensai/sdk
7
+ ```
8
+
9
+ ## Quickstart
10
+
11
+ ```ts
12
+ import { createAgent } from "@agensai/sdk";
13
+
14
+ const agent = await createAgent({
15
+ name: "dca-bot",
16
+ chainId: 84532, // Base Sepolia (default). Use 8453 for Base mainnet at v1.0.
17
+ apiKey: process.env.AGENSAI_API_KEY!,
18
+ ownerPrivateKey: process.env.AGENSAI_OWNER_PRIVATE_KEY! as `0x${string}`,
19
+ policies: [
20
+ { type: "spend", token: "USDC", amount: 50, period: "weekly" },
21
+ { type: "contract", whitelist: ["uniswap.eth"] },
22
+ { type: "expires", at: "2026-08-01" },
23
+ ],
24
+ });
25
+
26
+ console.log(agent.name); // "dca-bot.agensai.eth"
27
+ console.log(agent.address); // "0x..."
28
+
29
+ await agent.execute({
30
+ to: "treasury.acme.eth",
31
+ amount: "10 USDC",
32
+ });
33
+ ```
34
+
35
+ ## What it does
36
+
37
+ `@agensai/sdk` wraps three production primitives:
38
+
39
+ - **Smart account** → ERC-4337 (EntryPoint v0.8) via [`@jaw.id/core`](https://www.npmjs.com/package/@jaw.id/core)
40
+ - **ENS subname** → gasless issuance via the JAW SDK
41
+ - **Policies** → ERC-7715 permissions
42
+
43
+ You write `createAgent({ name, policies })`. The SDK handles the rest.
44
+
45
+ ## Full reference
46
+
47
+ [docs.agensai.xyz/sdk](https://docs.agensai.xyz/sdk)
48
+
49
+ ## License
50
+
51
+ MIT
@@ -0,0 +1,273 @@
1
+ import { Address, Hex } from 'viem';
2
+
3
+ type EnsName = `${string}.${string}`;
4
+ type EnsOrAddress = EnsName | Address;
5
+ type ChainName = "ethereum" | "base" | "optimism" | "arbitrum";
6
+ type TokenSymbol = "ETH" | "USDC" | "USDT" | "DAI" | (string & {});
7
+ type Policy = SpendPolicy | ContractPolicy | ExpiresPolicy | RatePolicy;
8
+ interface SpendPolicy {
9
+ type: "spend";
10
+ token: TokenSymbol | Address;
11
+ amount: number | string;
12
+ period: "minute" | "hour" | "day" | "daily" | "week" | "weekly" | "month" | "monthly" | "year" | "yearly" | "forever";
13
+ multiplier?: number;
14
+ }
15
+ interface ContractPolicy {
16
+ type: "contract";
17
+ whitelist: EnsOrAddress[];
18
+ functionSignature?: string;
19
+ }
20
+ interface ExpiresPolicy {
21
+ type: "expires";
22
+ at: string;
23
+ }
24
+ interface RatePolicy {
25
+ type: "rate";
26
+ max: number;
27
+ period: "minute" | "hour" | "day";
28
+ }
29
+ interface CreateAgentOptions {
30
+ name: string;
31
+ namespace?: EnsName;
32
+ chainId: number;
33
+ ownerPrivateKey?: Hex;
34
+ policies: Policy[];
35
+ description?: string;
36
+ paymasterUrl?: string;
37
+ agentPrivateKey?: Hex;
38
+ }
39
+ interface GetAgentOptions {
40
+ chainId?: number;
41
+ agentPrivateKey: Hex;
42
+ }
43
+ interface ListAgentsOptions {
44
+ chainId?: number;
45
+ ownerAddress: Address;
46
+ includeInactive?: boolean;
47
+ }
48
+ interface AgentSnapshot {
49
+ name: EnsName;
50
+ address: Address;
51
+ chainId: number;
52
+ ownerAddress: Address;
53
+ permissionId: Hex;
54
+ expiry: number;
55
+ status: "active" | "expired" | "revoked";
56
+ policies: Policy[];
57
+ }
58
+ interface PolicySnapshot {
59
+ ens: string;
60
+ address: Address;
61
+ chainId: number;
62
+ status: "active" | "expired" | "revoked";
63
+ grantedBy: string;
64
+ grantedAt: string;
65
+ permissionId: Hex;
66
+ expiresAt: string;
67
+ policies: Policy[];
68
+ revokedAt?: string;
69
+ description?: string;
70
+ }
71
+ interface ExecuteOptions {
72
+ to: EnsOrAddress;
73
+ value?: bigint | string;
74
+ data?: Hex;
75
+ amount?: string;
76
+ wait?: boolean;
77
+ }
78
+ interface BatchCall {
79
+ to: EnsOrAddress;
80
+ value?: bigint | string;
81
+ data?: Hex;
82
+ amount?: string;
83
+ }
84
+ interface BatchResult {
85
+ id: Hex;
86
+ chainId: number;
87
+ }
88
+
89
+ interface AgentConstructor {
90
+ ens: EnsName;
91
+ address: Address;
92
+ chainId: number;
93
+ ownerAddress: Address;
94
+ permissionId: Hex;
95
+ expiry: number;
96
+ policies: Policy[];
97
+ agentPrivateKey: Hex;
98
+ paymasterUrl?: string;
99
+ }
100
+ declare class Agent {
101
+ #private;
102
+ readonly name: EnsName;
103
+ readonly address: Address;
104
+ readonly chainId: number;
105
+ readonly ownerAddress: Address;
106
+ readonly permissionId: Hex;
107
+ readonly expiry: number;
108
+ constructor(args: AgentConstructor);
109
+ snapshot(): AgentSnapshot;
110
+ get policies(): Policy[];
111
+ refresh(): Promise<AgentSnapshot>;
112
+ execute(opts: ExecuteOptions): Promise<Hex>;
113
+ batch(calls: BatchCall[]): Promise<BatchResult>;
114
+ waitForReceipt(callId: Hex, opts?: {
115
+ timeoutMs?: number;
116
+ pollIntervalMs?: number;
117
+ }): Promise<{
118
+ txHash: Hex;
119
+ status: "success";
120
+ }>;
121
+ revoke(opts?: {
122
+ ownerPrivateKey?: Hex;
123
+ }): Promise<{
124
+ txHash: Hex;
125
+ }>;
126
+ toJSON(): {
127
+ ens: EnsName;
128
+ address: Address;
129
+ chainId: number;
130
+ ownerAddress: Address;
131
+ permissionId: Hex;
132
+ expiry: number;
133
+ status: "active" | "expired" | "revoked";
134
+ policies: Policy[];
135
+ };
136
+ /**
137
+ * WARNING: Output contains the agent's private key. Never log this value.
138
+ * Encrypt at rest. Treat as funds-control material.
139
+ */
140
+ toBackupJSON(): ReturnType<Agent["toJSON"]> & {
141
+ agentPrivateKey: Hex;
142
+ };
143
+ static fromJSON(blob: ReturnType<Agent["toJSON"]> | ReturnType<Agent["toBackupJSON"]>, env?: {
144
+ paymasterUrl?: string;
145
+ policies?: Policy[];
146
+ }): Agent;
147
+ }
148
+
149
+ declare function createAgent(opts: CreateAgentOptions): Promise<Agent>;
150
+
151
+ declare function getAgent(ensName: EnsName, opts: GetAgentOptions): Promise<Agent>;
152
+
153
+ declare function listAgents(opts: ListAgentsOptions): Promise<AgentSnapshot[]>;
154
+
155
+ declare function getPolicySnapshot(ens: string, chainId?: number): Promise<PolicySnapshot>;
156
+
157
+ declare function resolve(input: EnsOrAddress, chainId: number): Promise<Address>;
158
+
159
+ declare function reverseResolve(address: Address, chainId: number): Promise<string | null>;
160
+
161
+ /**
162
+ * Issues an ENS subname under the given L1 namespace pointing at the agent
163
+ * smart account on its L2 chain. Uses `overrideSignatureCheck: true` because
164
+ * we are calling server-side from a JAW-authenticated context.
165
+ */
166
+ declare function issueSubname(args: {
167
+ apiKey: string;
168
+ username: string;
169
+ namespace: string;
170
+ chainId: number;
171
+ agentAddress: Address;
172
+ textRecords?: Array<{
173
+ key: string;
174
+ value: string;
175
+ }>;
176
+ }): Promise<{
177
+ ens: string;
178
+ }>;
179
+
180
+ type CompiledPolicy = {
181
+ expiry: number;
182
+ spender: `0x${string}`;
183
+ permissions: {
184
+ calls: Array<{
185
+ target: `0x${string}`;
186
+ functionSignature?: string;
187
+ selector?: `0x${string}`;
188
+ }>;
189
+ spends: Array<{
190
+ token: `0x${string}`;
191
+ allowance: string;
192
+ unit: "minute" | "hour" | "day" | "week" | "month" | "year" | "forever";
193
+ multiplier: number;
194
+ }>;
195
+ };
196
+ rate?: {
197
+ max: number;
198
+ period: "minute" | "hour" | "day";
199
+ };
200
+ };
201
+
202
+ declare function compilePolicies(args: {
203
+ policies: Policy[];
204
+ spender: `0x${string}`;
205
+ chainId: number;
206
+ }): Promise<CompiledPolicy>;
207
+
208
+ declare const NATIVE_TOKEN: Address;
209
+ interface TokenEntry {
210
+ address: Address;
211
+ decimals: number;
212
+ }
213
+ declare function resolveToken(token: TokenSymbol | Address, chainId: number): Promise<TokenEntry>;
214
+
215
+ declare function parseAmount(input: string, chainId: number): Promise<{
216
+ token: TokenSymbol;
217
+ amountUnits: bigint;
218
+ }>;
219
+
220
+ declare const DEFAULT_CHAIN_ID = 84532;
221
+ declare const CHAINS: {
222
+ readonly 1: {
223
+ readonly name: "ethereum";
224
+ readonly rpcUrl: "https://eth.drpc.org";
225
+ };
226
+ readonly 8453: {
227
+ readonly name: "base";
228
+ readonly rpcUrl: "https://base.drpc.org";
229
+ };
230
+ readonly 84532: {
231
+ readonly name: "base";
232
+ readonly rpcUrl: "https://sepolia.base.org";
233
+ };
234
+ readonly 10: {
235
+ readonly name: "optimism";
236
+ readonly rpcUrl: "https://optimism.drpc.org";
237
+ };
238
+ readonly 42161: {
239
+ readonly name: "arbitrum";
240
+ readonly rpcUrl: "https://arbitrum.drpc.org";
241
+ };
242
+ };
243
+ declare function chainNameFor(chainId: number): ChainName;
244
+ declare function rpcUrlFor(chainId: number): string;
245
+ declare function isSupportedChain(chainId: number): boolean;
246
+
247
+ declare class AgensaiError extends Error {
248
+ name: string;
249
+ readonly cause?: unknown;
250
+ constructor(message: string, cause?: unknown);
251
+ }
252
+ declare class PolicyError extends AgensaiError {
253
+ name: string;
254
+ }
255
+ declare class ResolutionError extends AgensaiError {
256
+ name: string;
257
+ }
258
+ declare class PermissionViolationError extends AgensaiError {
259
+ name: string;
260
+ }
261
+ declare class ExecutionRevertedError extends AgensaiError {
262
+ name: string;
263
+ readonly callId: string;
264
+ readonly txHash: string;
265
+ constructor(message: string, args: {
266
+ callId: string;
267
+ txHash: string;
268
+ });
269
+ }
270
+
271
+ declare const version = "0.1.0";
272
+
273
+ export { AgensaiError, Agent, type AgentSnapshot, type BatchCall, type BatchResult, CHAINS, type ChainName, type CompiledPolicy, type ContractPolicy, type CreateAgentOptions, DEFAULT_CHAIN_ID, type EnsName, type EnsOrAddress, type ExecuteOptions, ExecutionRevertedError, type ExpiresPolicy, type GetAgentOptions, type ListAgentsOptions, NATIVE_TOKEN, PermissionViolationError, type Policy, PolicyError, type PolicySnapshot, type RatePolicy, ResolutionError, type SpendPolicy, type TokenSymbol, chainNameFor, compilePolicies, createAgent, getAgent, getPolicySnapshot, isSupportedChain, issueSubname, listAgents, parseAmount, resolve, resolveToken, reverseResolve, rpcUrlFor, version };
package/dist/index.js ADDED
@@ -0,0 +1,770 @@
1
+ import { generatePrivateKey, privateKeyToAccount } from 'viem/accounts';
2
+ import { parseUnits, encodeFunctionData, erc20Abi, createPublicClient, http } from 'viem';
3
+ import { JustaName } from '@justaname.id/sdk';
4
+
5
+ // src/createAgent.ts
6
+
7
+ // src/env.ts
8
+ var AGENSAI_API_BASE_URL = process.env["AGENSAI_API_BASE_URL"] ?? "https://api.agensai.xyz";
9
+ function getOwnerPrivateKey(opt) {
10
+ if (opt) return opt;
11
+ const env = process.env["AGENSAI_OWNER_PRIVATE_KEY"];
12
+ return env ? env : void 0;
13
+ }
14
+
15
+ // src/errors.ts
16
+ var AgensaiError = class extends Error {
17
+ name = "AgensaiError";
18
+ cause;
19
+ constructor(message, cause) {
20
+ super(message);
21
+ if (cause !== void 0) this.cause = cause;
22
+ }
23
+ };
24
+ var PolicyError = class extends AgensaiError {
25
+ name = "PolicyError";
26
+ };
27
+ var ResolutionError = class extends AgensaiError {
28
+ name = "ResolutionError";
29
+ };
30
+ var PermissionViolationError = class extends AgensaiError {
31
+ name = "PermissionViolationError";
32
+ };
33
+ var ExecutionRevertedError = class extends AgensaiError {
34
+ name = "ExecutionRevertedError";
35
+ callId;
36
+ txHash;
37
+ constructor(message, args) {
38
+ super(message);
39
+ this.callId = args.callId;
40
+ this.txHash = args.txHash;
41
+ }
42
+ };
43
+
44
+ // src/core/api.ts
45
+ var JSON_HEADERS = { "content-type": "application/json" };
46
+ async function request(method, path, body) {
47
+ const init = { method };
48
+ if (body !== void 0) {
49
+ init.headers = JSON_HEADERS;
50
+ init.body = JSON.stringify(body);
51
+ }
52
+ let res;
53
+ try {
54
+ res = await fetch(`${AGENSAI_API_BASE_URL}${path}`, init);
55
+ } catch (err) {
56
+ throw new AgensaiError(
57
+ `AGENSAI service unreachable at ${AGENSAI_API_BASE_URL}`,
58
+ err
59
+ );
60
+ }
61
+ if (!res.ok) {
62
+ let envelope = {};
63
+ try {
64
+ envelope = await res.json();
65
+ } catch {
66
+ }
67
+ const code = envelope.error?.code ?? `HTTP_${res.status}`;
68
+ const message = envelope.error?.message ?? res.statusText;
69
+ switch (code) {
70
+ case "POLICY_VIOLATION":
71
+ throw new PermissionViolationError(message);
72
+ case "RESOLUTION_FAILED":
73
+ case "AGENT_NOT_FOUND":
74
+ case "NAME_TAKEN":
75
+ throw new ResolutionError(message);
76
+ case "INVALID_INPUT":
77
+ case "INVALID_SIGNATURE":
78
+ throw new PolicyError(message);
79
+ default:
80
+ throw new AgensaiError(`AGENSAI service error (${code}): ${message}`);
81
+ }
82
+ }
83
+ return await res.json();
84
+ }
85
+ var api = {
86
+ createAgent: (req) => request("POST", "/agents", req),
87
+ getAgent: (ens, chainId) => request(
88
+ "GET",
89
+ `/agents/${encodeURIComponent(ens)}?chainId=${chainId}`
90
+ ),
91
+ listAgents: (req) => request("POST", "/agents/list", req),
92
+ executeCalls: (ens, body) => request(
93
+ "POST",
94
+ `/agents/${encodeURIComponent(ens)}/calls`,
95
+ body
96
+ ),
97
+ getCallReceipt: (callId, chainId) => request(
98
+ "GET",
99
+ `/calls/${encodeURIComponent(callId)}/receipt?chainId=${chainId}`
100
+ ),
101
+ revoke: (ens, body) => request(
102
+ "POST",
103
+ `/agents/${encodeURIComponent(ens)}/revoke`,
104
+ body
105
+ ),
106
+ refresh: (ens, chainId) => request(
107
+ "GET",
108
+ `/agents/${encodeURIComponent(ens)}?chainId=${chainId}`
109
+ )
110
+ };
111
+
112
+ // src/core/chains.ts
113
+ var DEFAULT_CHAIN_ID = 84532;
114
+ var CHAINS = {
115
+ 1: { name: "ethereum", rpcUrl: "https://eth.drpc.org" },
116
+ 8453: { name: "base", rpcUrl: "https://base.drpc.org" },
117
+ 84532: { name: "base", rpcUrl: "https://sepolia.base.org" },
118
+ 10: { name: "optimism", rpcUrl: "https://optimism.drpc.org" },
119
+ 42161: { name: "arbitrum", rpcUrl: "https://arbitrum.drpc.org" }
120
+ };
121
+ function chainNameFor(chainId) {
122
+ const c = CHAINS[chainId];
123
+ if (!c) throw new Error(`Unsupported chain: ${chainId}`);
124
+ return c.name;
125
+ }
126
+ function rpcUrlFor(chainId) {
127
+ const c = CHAINS[chainId];
128
+ if (!c) throw new Error(`Unsupported chain: ${chainId}`);
129
+ return c.rpcUrl;
130
+ }
131
+ function isSupportedChain(chainId) {
132
+ return chainId in CHAINS;
133
+ }
134
+
135
+ // src/core/client.ts
136
+ var ENS_GATEWAY = "https://api.justaname.id";
137
+ function ensGatewayUrl(path, params) {
138
+ const url = new URL(`${ENS_GATEWAY}${path}`);
139
+ for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);
140
+ return url;
141
+ }
142
+ function defaultProviderUrl(chainId) {
143
+ return rpcUrlFor(chainId);
144
+ }
145
+ function justaNameWrite(opts) {
146
+ return JustaName.init({
147
+ networks: [{ chainId: opts.chainId, providerUrl: rpcUrlFor(opts.chainId) }],
148
+ ensDomains: [
149
+ {
150
+ chainId: opts.chainId,
151
+ ensDomain: opts.namespace,
152
+ apiKey: opts.apiKey
153
+ }
154
+ ],
155
+ config: { domain: opts.domain, origin: opts.origin }
156
+ });
157
+ }
158
+
159
+ // src/ens/resolve.ts
160
+ async function resolve(input, chainId) {
161
+ if (input.startsWith("0x") && input.length === 42) {
162
+ return input;
163
+ }
164
+ const url = ensGatewayUrl("/ens/v1/subname/records", {
165
+ ens: `${input}@eip155:${chainId}`,
166
+ providerUrl: defaultProviderUrl(chainId)
167
+ });
168
+ let res;
169
+ try {
170
+ res = await fetch(url);
171
+ } catch (err) {
172
+ throw new ResolutionError(
173
+ `Could not resolve ${input}: gateway unreachable`,
174
+ err
175
+ );
176
+ }
177
+ if (!res.ok) {
178
+ throw new ResolutionError(
179
+ `Could not resolve ${input} on chain ${chainId} (${res.status})`
180
+ );
181
+ }
182
+ const json = await res.json();
183
+ const addr = json.result?.data?.records?.addresses?.[0]?.value;
184
+ if (!addr) {
185
+ throw new ResolutionError(
186
+ `Could not resolve ${input}: no address record on chain ${chainId}`
187
+ );
188
+ }
189
+ return addr;
190
+ }
191
+ var NATIVE_TOKEN = "0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE";
192
+ var REGISTRY = {
193
+ 8453: {
194
+ ETH: { address: NATIVE_TOKEN, decimals: 18 },
195
+ USDC: { address: "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", decimals: 6 },
196
+ USDT: { address: "0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2", decimals: 6 },
197
+ DAI: { address: "0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb", decimals: 18 }
198
+ },
199
+ 84532: {
200
+ ETH: { address: NATIVE_TOKEN, decimals: 18 },
201
+ USDC: { address: "0x036CbD53842c5426634e7929541eC2318f3dCF7e", decimals: 6 }
202
+ },
203
+ 1: {
204
+ ETH: { address: NATIVE_TOKEN, decimals: 18 },
205
+ USDC: { address: "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48", decimals: 6 },
206
+ USDT: { address: "0xdAC17F958D2ee523a2206206994597C13D831ec7", decimals: 6 },
207
+ DAI: { address: "0x6B175474E89094C44Da98b954EedeAC495271d0F", decimals: 18 }
208
+ },
209
+ 10: {
210
+ ETH: { address: NATIVE_TOKEN, decimals: 18 },
211
+ USDC: { address: "0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85", decimals: 6 }
212
+ }
213
+ };
214
+ var RAW_DECIMALS_CACHE = /* @__PURE__ */ new Map();
215
+ function cacheKey(chainId, address) {
216
+ return `${chainId}:${address.toLowerCase()}`;
217
+ }
218
+ async function fetchDecimalsOnchain(address, chainId) {
219
+ if (!isSupportedChain(chainId)) {
220
+ throw new Error(`Unsupported chain ${chainId} \u2014 cannot fetch decimals.`);
221
+ }
222
+ const client = createPublicClient({ transport: http(rpcUrlFor(chainId)) });
223
+ try {
224
+ const decimals = await client.readContract({
225
+ address,
226
+ abi: erc20Abi,
227
+ functionName: "decimals"
228
+ });
229
+ return Number(decimals);
230
+ } catch (err) {
231
+ throw new Error(
232
+ `Could not fetch decimals for token ${address} on chain ${chainId}. Add it to the registry or pass a known symbol (USDC, ETH, \u2026). Cause: ${err instanceof Error ? err.message : String(err)}`
233
+ );
234
+ }
235
+ }
236
+ async function resolveToken(token, chainId) {
237
+ if (token.startsWith("0x") && token.length === 42) {
238
+ const address = token;
239
+ if (address.toLowerCase() === NATIVE_TOKEN.toLowerCase()) {
240
+ return { address, decimals: 18 };
241
+ }
242
+ const key = cacheKey(chainId, address);
243
+ const cached = RAW_DECIMALS_CACHE.get(key);
244
+ if (cached !== void 0) return { address, decimals: cached };
245
+ const decimals = await fetchDecimalsOnchain(address, chainId);
246
+ RAW_DECIMALS_CACHE.set(key, decimals);
247
+ return { address, decimals };
248
+ }
249
+ const chain = REGISTRY[chainId];
250
+ const entry = chain?.[token];
251
+ if (!entry) throw new Error(`Unknown token "${token}" on chain ${chainId}`);
252
+ return entry;
253
+ }
254
+ async function parseAmount(input, chainId) {
255
+ const m = /^([\d.]+)\s+([A-Z]+)$/.exec(input.trim());
256
+ if (!m || !m[1] || !m[2]) {
257
+ throw new Error(`Could not parse amount: "${input}". Expected "10 USDC".`);
258
+ }
259
+ const tok = await resolveToken(m[2], chainId);
260
+ return {
261
+ token: m[2],
262
+ amountUnits: parseUnits(m[1], tok.decimals)
263
+ };
264
+ }
265
+
266
+ // src/Agent.ts
267
+ var READ_ONLY_KEY = "0x";
268
+ var Agent = class _Agent {
269
+ name;
270
+ address;
271
+ chainId;
272
+ ownerAddress;
273
+ permissionId;
274
+ expiry;
275
+ #agentPrivateKey;
276
+ #paymasterUrl;
277
+ #policies;
278
+ #revoked = false;
279
+ #readOnly = false;
280
+ constructor(args) {
281
+ this.name = args.ens;
282
+ this.address = args.address;
283
+ this.chainId = args.chainId;
284
+ this.ownerAddress = args.ownerAddress;
285
+ this.permissionId = args.permissionId;
286
+ this.expiry = args.expiry;
287
+ this.#agentPrivateKey = args.agentPrivateKey;
288
+ this.#paymasterUrl = args.paymasterUrl;
289
+ this.#policies = args.policies;
290
+ }
291
+ snapshot() {
292
+ const now = Math.floor(Date.now() / 1e3);
293
+ const status = this.#revoked ? "revoked" : now > this.expiry ? "expired" : "active";
294
+ return {
295
+ name: this.name,
296
+ address: this.address,
297
+ chainId: this.chainId,
298
+ ownerAddress: this.ownerAddress,
299
+ permissionId: this.permissionId,
300
+ expiry: this.expiry,
301
+ status,
302
+ policies: this.#policies
303
+ };
304
+ }
305
+ get policies() {
306
+ return this.#policies;
307
+ }
308
+ async refresh() {
309
+ const fresh = await api.refresh(this.name, this.chainId);
310
+ this.#policies = fresh.policies;
311
+ if (fresh.status === "revoked") this.#revoked = true;
312
+ return fresh;
313
+ }
314
+ async execute(opts) {
315
+ this.#assertWritable();
316
+ const call = await this.#buildCall(opts);
317
+ const { callId } = await api.executeCalls(this.name, {
318
+ agentPrivateKey: this.#agentPrivateKey,
319
+ permissionId: this.permissionId,
320
+ chainId: this.chainId,
321
+ calls: [this.#serializeCall(call)],
322
+ ...this.#paymasterUrl ? { paymasterUrl: this.#paymasterUrl } : {}
323
+ });
324
+ if (opts.wait !== false) await this.waitForReceipt(callId);
325
+ return callId;
326
+ }
327
+ async batch(calls) {
328
+ this.#assertWritable();
329
+ const built = await Promise.all(calls.map((c) => this.#buildCall(c)));
330
+ const { callId } = await api.executeCalls(this.name, {
331
+ agentPrivateKey: this.#agentPrivateKey,
332
+ permissionId: this.permissionId,
333
+ chainId: this.chainId,
334
+ calls: built.map((c) => this.#serializeCall(c)),
335
+ ...this.#paymasterUrl ? { paymasterUrl: this.#paymasterUrl } : {}
336
+ });
337
+ return { id: callId, chainId: this.chainId };
338
+ }
339
+ async waitForReceipt(callId, opts = {}) {
340
+ this.#assertWritable();
341
+ const deadline = Date.now() + (opts.timeoutMs ?? 6e4);
342
+ const interval = opts.pollIntervalMs ?? 1e3;
343
+ while (Date.now() < deadline) {
344
+ const r = await api.getCallReceipt(callId, this.chainId);
345
+ if (r.status !== "pending" && r.txHash) {
346
+ if (r.status === "reverted") {
347
+ throw new ExecutionRevertedError(
348
+ `Agent execution reverted on-chain (callId ${callId}, tx ${r.txHash}).`,
349
+ { callId, txHash: r.txHash }
350
+ );
351
+ }
352
+ return { txHash: r.txHash, status: "success" };
353
+ }
354
+ await new Promise((res) => setTimeout(res, interval));
355
+ }
356
+ throw new AgensaiError(
357
+ `waitForReceipt: callId ${callId} did not include within ${opts.timeoutMs ?? 6e4}ms`
358
+ );
359
+ }
360
+ async revoke(opts = {}) {
361
+ this.#assertWritable();
362
+ const ownerPrivateKey = getOwnerPrivateKey(opts.ownerPrivateKey);
363
+ if (!ownerPrivateKey) {
364
+ throw new AgensaiError(
365
+ "ownerPrivateKey is required (or set AGENSAI_OWNER_PRIVATE_KEY)."
366
+ );
367
+ }
368
+ const result = await api.revoke(this.name, {
369
+ ownerPrivateKey,
370
+ permissionId: this.permissionId,
371
+ chainId: this.chainId,
372
+ ...this.#paymasterUrl ? { paymasterUrl: this.#paymasterUrl } : {}
373
+ });
374
+ this.#revoked = true;
375
+ return { txHash: result.txHash };
376
+ }
377
+ async #buildCall(c) {
378
+ const to = await resolve(c.to, this.chainId);
379
+ if (c.amount) {
380
+ const { token, amountUnits } = await parseAmount(c.amount, this.chainId);
381
+ const tok = await resolveToken(token, this.chainId);
382
+ if (tok.address.toLowerCase() === NATIVE_TOKEN.toLowerCase()) {
383
+ return { to, value: amountUnits };
384
+ }
385
+ return {
386
+ to: tok.address,
387
+ data: encodeFunctionData({
388
+ abi: erc20Abi,
389
+ functionName: "transfer",
390
+ args: [to, amountUnits]
391
+ })
392
+ };
393
+ }
394
+ const out = { to };
395
+ if (c.value !== void 0) {
396
+ out.value = typeof c.value === "string" ? parseUnits(c.value, 18) : c.value;
397
+ }
398
+ if (c.data) out.data = c.data;
399
+ return out;
400
+ }
401
+ #serializeCall(c) {
402
+ const out = { to: c.to };
403
+ if (c.value !== void 0) out.value = c.value.toString();
404
+ if (c.data) out.data = c.data;
405
+ return out;
406
+ }
407
+ toJSON() {
408
+ const now = Math.floor(Date.now() / 1e3);
409
+ const status = this.#revoked ? "revoked" : now > this.expiry ? "expired" : "active";
410
+ return {
411
+ ens: this.name,
412
+ address: this.address,
413
+ chainId: this.chainId,
414
+ ownerAddress: this.ownerAddress,
415
+ permissionId: this.permissionId,
416
+ expiry: this.expiry,
417
+ status,
418
+ policies: this.#policies
419
+ };
420
+ }
421
+ /**
422
+ * WARNING: Output contains the agent's private key. Never log this value.
423
+ * Encrypt at rest. Treat as funds-control material.
424
+ */
425
+ toBackupJSON() {
426
+ return { ...this.toJSON(), agentPrivateKey: this.#agentPrivateKey };
427
+ }
428
+ static fromJSON(blob, env = {}) {
429
+ const agentPrivateKey = "agentPrivateKey" in blob ? blob.agentPrivateKey : void 0;
430
+ const ctor = {
431
+ ens: blob.ens,
432
+ address: blob.address,
433
+ chainId: blob.chainId,
434
+ ownerAddress: blob.ownerAddress,
435
+ permissionId: blob.permissionId,
436
+ expiry: blob.expiry,
437
+ policies: env.policies ?? blob.policies ?? [],
438
+ agentPrivateKey: agentPrivateKey ?? READ_ONLY_KEY
439
+ };
440
+ if (env.paymasterUrl) ctor.paymasterUrl = env.paymasterUrl;
441
+ const agent = new _Agent(ctor);
442
+ if (!agentPrivateKey) agent.#readOnly = true;
443
+ return agent;
444
+ }
445
+ #assertWritable() {
446
+ if (this.#readOnly) {
447
+ throw new AgensaiError(
448
+ "Agent restored from public snapshot; private key required for write operations"
449
+ );
450
+ }
451
+ }
452
+ };
453
+ var DEFAULT_EXPIRY_SECONDS = 60 * 60 * 24 * 30;
454
+ var ANY_TARGET = "0x3232323232323232323232323232323232323232";
455
+ var ANY_FN_SEL = "0x32323232";
456
+ async function compilePolicies(args) {
457
+ const { policies, spender, chainId } = args;
458
+ const hasSpend = policies.some((p) => p.type === "spend");
459
+ if (!hasSpend) {
460
+ throw new PolicyError(
461
+ `Every agent must have at least one spend policy. Add e.g.:
462
+ { type: "spend", token: "ETH", amount: "0.01", period: "day" }
463
+ This caps how much the agent can move. AGENSAI does not ship wildcard defaults.`
464
+ );
465
+ }
466
+ const compiled = {
467
+ expiry: Math.floor(Date.now() / 1e3) + DEFAULT_EXPIRY_SECONDS,
468
+ spender,
469
+ permissions: { calls: [], spends: [] }
470
+ };
471
+ for (const p of policies) {
472
+ switch (p.type) {
473
+ case "spend": {
474
+ const tok = await resolveToken(p.token, chainId);
475
+ const allowance = parseUnits(String(p.amount), tok.decimals).toString();
476
+ compiled.permissions.spends.push({
477
+ token: tok.address,
478
+ allowance,
479
+ unit: normalizePeriod(p.period),
480
+ multiplier: p.multiplier ?? 1
481
+ });
482
+ break;
483
+ }
484
+ case "contract": {
485
+ for (const target of p.whitelist) {
486
+ const targetAddress = await resolve(target, chainId);
487
+ compiled.permissions.calls.push({
488
+ target: targetAddress,
489
+ ...p.functionSignature ? { functionSignature: p.functionSignature } : {}
490
+ });
491
+ }
492
+ break;
493
+ }
494
+ case "expires": {
495
+ compiled.expiry = parseExpiry(p.at);
496
+ break;
497
+ }
498
+ case "rate": {
499
+ compiled.rate = { max: p.max, period: p.period };
500
+ break;
501
+ }
502
+ default: {
503
+ const _exhaustive = p;
504
+ throw new PolicyError(`Unknown policy: ${JSON.stringify(_exhaustive)}`);
505
+ }
506
+ }
507
+ }
508
+ if (compiled.permissions.calls.length === 0) {
509
+ compiled.permissions.calls.push({
510
+ target: ANY_TARGET,
511
+ selector: ANY_FN_SEL
512
+ });
513
+ }
514
+ return compiled;
515
+ }
516
+ function normalizePeriod(p) {
517
+ switch (p) {
518
+ case "daily":
519
+ return "day";
520
+ case "weekly":
521
+ return "week";
522
+ case "monthly":
523
+ return "month";
524
+ case "yearly":
525
+ return "year";
526
+ default:
527
+ return p;
528
+ }
529
+ }
530
+ function parseExpiry(input) {
531
+ const dt = Date.parse(input);
532
+ if (!Number.isNaN(dt)) return Math.floor(dt / 1e3);
533
+ const m = /^(\d+)([smhdwy])$/i.exec(input.trim());
534
+ if (!m || !m[1] || !m[2]) {
535
+ throw new PolicyError(`Invalid expiry: ${input}`);
536
+ }
537
+ const n = Number(m[1]);
538
+ const unit = m[2].toLowerCase();
539
+ const seconds = {
540
+ s: 1,
541
+ m: 60,
542
+ h: 3600,
543
+ d: 86400,
544
+ w: 604800,
545
+ y: 31536e3
546
+ };
547
+ const factor = seconds[unit];
548
+ if (!factor) throw new PolicyError(`Invalid expiry unit: ${unit}`);
549
+ return Math.floor(Date.now() / 1e3) + n * factor;
550
+ }
551
+
552
+ // src/createAgent.ts
553
+ async function createAgent(opts) {
554
+ const ownerPrivateKey = getOwnerPrivateKey(opts.ownerPrivateKey);
555
+ if (!ownerPrivateKey) {
556
+ throw new AgensaiError(
557
+ "ownerPrivateKey is required (or set AGENSAI_OWNER_PRIVATE_KEY)."
558
+ );
559
+ }
560
+ if (!/^[a-z0-9-]+$/.test(opts.name)) {
561
+ throw new AgensaiError(
562
+ `Invalid agent name "${opts.name}". Must match ^[a-z0-9-]+$.`
563
+ );
564
+ }
565
+ if (opts.namespace && opts.namespace !== "agensai.eth") {
566
+ throw new AgensaiError("Custom namespaces are reserved for v0.2.");
567
+ }
568
+ const agentPrivateKey = opts.agentPrivateKey ?? generatePrivateKey();
569
+ const PLACEHOLDER_SPENDER = "0x0000000000000000000000000000000000000001";
570
+ const compiledPolicy = await compilePolicies({
571
+ policies: opts.policies,
572
+ spender: PLACEHOLDER_SPENDER,
573
+ chainId: opts.chainId
574
+ });
575
+ const created = await api.createAgent({
576
+ name: opts.name,
577
+ chainId: opts.chainId,
578
+ ownerPrivateKey,
579
+ agentPrivateKey,
580
+ policies: opts.policies,
581
+ compiledPolicy,
582
+ ...opts.description ? { description: opts.description } : {},
583
+ ...opts.paymasterUrl ? { paymasterUrl: opts.paymasterUrl } : {}
584
+ });
585
+ const expectedSessionAddress = privateKeyToAccount(agentPrivateKey).address;
586
+ if (!created.address || !created.address.startsWith("0x")) {
587
+ throw new AgensaiError(
588
+ `service returned malformed agent address: ${created.address}`
589
+ );
590
+ }
591
+ if (created.address.toLowerCase() === expectedSessionAddress.toLowerCase()) {
592
+ throw new AgensaiError(
593
+ "service returned EOA as agent address (expected smart-account address)"
594
+ );
595
+ }
596
+ return new Agent({
597
+ ens: created.ens,
598
+ address: created.address,
599
+ chainId: created.chainId,
600
+ ownerAddress: created.ownerAddress,
601
+ permissionId: created.permissionId,
602
+ expiry: created.expiry,
603
+ policies: created.policies,
604
+ agentPrivateKey,
605
+ ...opts.paymasterUrl ? { paymasterUrl: opts.paymasterUrl } : {}
606
+ });
607
+ }
608
+ async function getAgent(ensName, opts) {
609
+ const chainId = opts.chainId ?? DEFAULT_CHAIN_ID;
610
+ const [expectedAddress, snapshot] = await Promise.all([
611
+ resolve(ensName, chainId),
612
+ api.getAgent(ensName, chainId)
613
+ ]);
614
+ const eoa = privateKeyToAccount(opts.agentPrivateKey).address;
615
+ if (eoa.toLowerCase() === expectedAddress.toLowerCase()) {
616
+ throw new AgensaiError(
617
+ `Agent key mismatch for ${ensName}: ENS resolves to ${expectedAddress}, which equals the supplied key's EOA. The agent address should be the smart-account, not the EOA.`
618
+ );
619
+ }
620
+ return new Agent({
621
+ ens: ensName,
622
+ address: snapshot.address,
623
+ chainId,
624
+ ownerAddress: snapshot.ownerAddress,
625
+ permissionId: snapshot.permissionId,
626
+ expiry: snapshot.expiry,
627
+ policies: snapshot.policies,
628
+ agentPrivateKey: opts.agentPrivateKey
629
+ });
630
+ }
631
+
632
+ // src/listAgents.ts
633
+ async function listAgents(opts) {
634
+ const chainId = opts.chainId ?? DEFAULT_CHAIN_ID;
635
+ return api.listAgents({
636
+ ownerAddress: opts.ownerAddress,
637
+ chainId,
638
+ ...opts.includeInactive !== void 0 ? { includeInactive: opts.includeInactive } : {}
639
+ });
640
+ }
641
+
642
+ // src/ens/textRecords.ts
643
+ async function readPolicyRecords(ens, chainId) {
644
+ const url = ensGatewayUrl("/ens/v1/subname/records", {
645
+ ens: `${ens}@eip155:${chainId}`,
646
+ providerUrl: defaultProviderUrl(chainId)
647
+ });
648
+ let res;
649
+ try {
650
+ res = await fetch(url);
651
+ } catch (err) {
652
+ throw new ResolutionError(`Records read failed for ${ens}`, err);
653
+ }
654
+ if (!res.ok) {
655
+ throw new ResolutionError(
656
+ `Records read failed for ${ens} (${res.status})`
657
+ );
658
+ }
659
+ const json = await res.json();
660
+ const texts = json.result?.data?.records?.texts ?? [];
661
+ const addresses = json.result?.data?.records?.addresses ?? [];
662
+ const text = (key) => texts.find((t) => t.key === key)?.value;
663
+ const address = addresses[0]?.value ?? void 0;
664
+ if (!address) {
665
+ throw new ResolutionError(`No address record on ${ens}`);
666
+ }
667
+ const blob = text("agensai.policies");
668
+ if (!blob) {
669
+ throw new ResolutionError(
670
+ `No agensai.policies record on ${ens}; ENS exists but is not an AGENSAI agent`
671
+ );
672
+ }
673
+ let parsed;
674
+ try {
675
+ parsed = JSON.parse(blob);
676
+ } catch (err) {
677
+ throw new ResolutionError(
678
+ `Could not parse agensai.policies on ${ens}`,
679
+ err
680
+ );
681
+ }
682
+ if (parsed.version !== 1) {
683
+ throw new ResolutionError(
684
+ `Unsupported agensai.policies version ${parsed.version} on ${ens}`
685
+ );
686
+ }
687
+ const status = text("agensai.status") ?? "active";
688
+ const snapshot = {
689
+ ens,
690
+ address,
691
+ chainId,
692
+ status,
693
+ grantedBy: text("agensai.granted-by") ?? "",
694
+ grantedAt: text("agensai.granted-at") ?? "",
695
+ permissionId: parsed.permissionId,
696
+ expiresAt: parsed.expiresAt,
697
+ policies: parsed.policies
698
+ };
699
+ const revokedAt = text("agensai.revoked-at");
700
+ if (revokedAt) snapshot.revokedAt = revokedAt;
701
+ const desc = text("description");
702
+ if (desc) snapshot.description = desc;
703
+ return snapshot;
704
+ }
705
+
706
+ // src/getPolicySnapshot.ts
707
+ async function getPolicySnapshot(ens, chainId = DEFAULT_CHAIN_ID) {
708
+ return readPolicyRecords(ens, chainId);
709
+ }
710
+
711
+ // src/ens/reverseResolve.ts
712
+ async function reverseResolve(address, chainId) {
713
+ const url = ensGatewayUrl("/ens/v1/primary-name", {
714
+ address,
715
+ chainId: String(chainId),
716
+ providerUrl: defaultProviderUrl(chainId)
717
+ });
718
+ let res;
719
+ try {
720
+ res = await fetch(url);
721
+ } catch {
722
+ return null;
723
+ }
724
+ if (!res.ok) return null;
725
+ const json = await res.json();
726
+ return json.result?.data?.name ?? null;
727
+ }
728
+
729
+ // src/ens/issueSubname.ts
730
+ function ensChainFor(l2ChainId) {
731
+ return l2ChainId === 1 || l2ChainId === 8453 || l2ChainId === 10 || l2ChainId === 42161 ? 1 : 11155111;
732
+ }
733
+ function coinTypeFor(chainId) {
734
+ if (chainId === 1) return 60;
735
+ return 2147483648 + chainId;
736
+ }
737
+ async function issueSubname(args) {
738
+ const ensChainId = ensChainFor(args.chainId);
739
+ const justa = justaNameWrite({
740
+ apiKey: args.apiKey,
741
+ chainId: ensChainId,
742
+ namespace: args.namespace,
743
+ // SIWE domain/origin must match what the JAW API key was bound to in the
744
+ // JustaName dashboard. Adrian's key is bound to `agensai.eth`. This is
745
+ // intentionally NOT the web product domain (`agensai.xyz`) — these are
746
+ // different layers (web vs ENS auth).
747
+ domain: "agensai.eth",
748
+ origin: "https://agensai.eth"
749
+ });
750
+ await justa.subnames.addSubname({
751
+ username: args.username,
752
+ ensDomain: args.namespace,
753
+ chainId: ensChainId,
754
+ overrideSignatureCheck: true,
755
+ addresses: [
756
+ { address: args.agentAddress, coinType: coinTypeFor(args.chainId) },
757
+ // Always also publish the SLIP-44 ETH record so generic resolvers work.
758
+ { address: args.agentAddress, coinType: 60 }
759
+ ],
760
+ text: args.textRecords ?? []
761
+ });
762
+ return { ens: `${args.username}.${args.namespace}` };
763
+ }
764
+
765
+ // src/index.ts
766
+ var version = "0.1.0";
767
+
768
+ export { AgensaiError, Agent, CHAINS, DEFAULT_CHAIN_ID, ExecutionRevertedError, NATIVE_TOKEN, PermissionViolationError, PolicyError, ResolutionError, chainNameFor, compilePolicies, createAgent, getAgent, getPolicySnapshot, isSupportedChain, issueSubname, listAgents, parseAmount, resolve, resolveToken, reverseResolve, rpcUrlFor, version };
769
+ //# sourceMappingURL=index.js.map
770
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/env.ts","../src/errors.ts","../src/core/api.ts","../src/core/chains.ts","../src/core/client.ts","../src/ens/resolve.ts","../src/tokens/registry.ts","../src/tokens/helpers.ts","../src/Agent.ts","../src/policies/compile.ts","../src/createAgent.ts","../src/getAgent.ts","../src/listAgents.ts","../src/ens/textRecords.ts","../src/getPolicySnapshot.ts","../src/ens/reverseResolve.ts","../src/ens/issueSubname.ts","../src/index.ts"],"names":["erc20Abi","parseUnits","privateKeyToAccount"],"mappings":"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","file":"index.js","sourcesContent":["import type { Hex } from \"viem\";\n\nexport const AGENSAI_API_BASE_URL: string =\n process.env[\"AGENSAI_API_BASE_URL\"] ?? \"https://api.agensai.xyz\";\n\nexport function getOwnerPrivateKey(opt?: Hex): Hex | undefined {\n if (opt) return opt;\n const env = process.env[\"AGENSAI_OWNER_PRIVATE_KEY\"];\n return env ? (env as Hex) : undefined;\n}\n","export class AgensaiError extends Error {\n override name = \"AgensaiError\";\n public override readonly cause?: unknown;\n constructor(message: string, cause?: unknown) {\n super(message);\n if (cause !== undefined) this.cause = cause;\n }\n}\n\nexport class PolicyError extends AgensaiError {\n override name = \"PolicyError\";\n}\n\nexport class ResolutionError extends AgensaiError {\n override name = \"ResolutionError\";\n}\n\nexport class PermissionViolationError extends AgensaiError {\n override name = \"PermissionViolationError\";\n}\n\nexport class ExecutionRevertedError extends AgensaiError {\n override name = \"ExecutionRevertedError\";\n public readonly callId: string;\n public readonly txHash: string;\n constructor(message: string, args: { callId: string; txHash: string }) {\n super(message);\n this.callId = args.callId;\n this.txHash = args.txHash;\n }\n}\n","import type { Address, Hex } from \"viem\";\nimport { AGENSAI_API_BASE_URL } from \"../env.js\";\nimport {\n AgensaiError,\n ResolutionError,\n PolicyError,\n PermissionViolationError,\n} from \"../errors.js\";\nimport type { Policy, AgentSnapshot } from \"../types.js\";\nimport type { CompiledPolicy } from \"../policies/types.js\";\n\nconst JSON_HEADERS = { \"content-type\": \"application/json\" } as const;\n\ninterface ErrorEnvelope {\n error?: { code?: string; message?: string; details?: unknown };\n}\n\nasync function request<T>(\n method: \"GET\" | \"POST\",\n path: string,\n body?: unknown,\n): Promise<T> {\n const init: RequestInit = { method };\n if (body !== undefined) {\n init.headers = JSON_HEADERS;\n init.body = JSON.stringify(body);\n }\n\n let res: Response;\n try {\n res = await fetch(`${AGENSAI_API_BASE_URL}${path}`, init);\n } catch (err) {\n throw new AgensaiError(\n `AGENSAI service unreachable at ${AGENSAI_API_BASE_URL}`,\n err,\n );\n }\n\n if (!res.ok) {\n let envelope: ErrorEnvelope = {};\n try {\n envelope = (await res.json()) as ErrorEnvelope;\n } catch {\n /* fall through */\n }\n const code = envelope.error?.code ?? `HTTP_${res.status}`;\n const message = envelope.error?.message ?? res.statusText;\n switch (code) {\n case \"POLICY_VIOLATION\":\n throw new PermissionViolationError(message);\n case \"RESOLUTION_FAILED\":\n case \"AGENT_NOT_FOUND\":\n case \"NAME_TAKEN\":\n throw new ResolutionError(message);\n case \"INVALID_INPUT\":\n case \"INVALID_SIGNATURE\":\n throw new PolicyError(message);\n default:\n throw new AgensaiError(`AGENSAI service error (${code}): ${message}`);\n }\n }\n\n return (await res.json()) as T;\n}\n\n// All write paths ship the relevant private keys to the AGENSAI service\n// over TLS. The service holds them in memory only for the duration of\n// the request, signs through JAW core, and never persists or logs them.\n// See SECURITY.md and docs/concepts/security-model for the full\n// trade-off.\n\nexport interface CreateAgentRequest {\n name: string;\n chainId: number;\n ownerPrivateKey: Hex;\n agentPrivateKey: Hex;\n policies: Policy[];\n compiledPolicy: CompiledPolicy;\n description?: string;\n paymasterUrl?: string;\n}\n\nexport interface CreateAgentResponse {\n ens: string;\n address: Address;\n chainId: number;\n ownerAddress: Address;\n permissionId: Hex;\n expiry: number;\n policies: Policy[];\n}\n\nexport interface ExecuteCallsRequest {\n agentPrivateKey: Hex;\n permissionId: Hex;\n chainId: number;\n calls: Array<{ to: Address; value?: string; data?: Hex }>;\n paymasterUrl?: string;\n}\n\nexport interface RevokeRequest {\n ownerPrivateKey: Hex;\n permissionId: Hex;\n chainId: number;\n paymasterUrl?: string;\n}\n\nexport const api = {\n createAgent: (req: CreateAgentRequest): Promise<CreateAgentResponse> =>\n request<CreateAgentResponse>(\"POST\", \"/agents\", req),\n\n getAgent: (ens: string, chainId: number): Promise<AgentSnapshot> =>\n request<AgentSnapshot>(\n \"GET\",\n `/agents/${encodeURIComponent(ens)}?chainId=${chainId}`,\n ),\n\n listAgents: (req: {\n ownerAddress: Address;\n chainId: number;\n includeInactive?: boolean;\n }): Promise<AgentSnapshot[]> =>\n request<AgentSnapshot[]>(\"POST\", \"/agents/list\", req),\n\n executeCalls: (\n ens: string,\n body: ExecuteCallsRequest,\n ): Promise<{ callId: Hex }> =>\n request<{ callId: Hex }>(\n \"POST\",\n `/agents/${encodeURIComponent(ens)}/calls`,\n body,\n ),\n\n getCallReceipt: (\n callId: Hex,\n chainId: number,\n ): Promise<{ status: \"pending\" | \"success\" | \"reverted\"; txHash?: Hex }> =>\n request<{ status: \"pending\" | \"success\" | \"reverted\"; txHash?: Hex }>(\n \"GET\",\n `/calls/${encodeURIComponent(callId)}/receipt?chainId=${chainId}`,\n ),\n\n revoke: (\n ens: string,\n body: RevokeRequest,\n ): Promise<{ txHash: Hex }> =>\n request<{ txHash: Hex }>(\n \"POST\",\n `/agents/${encodeURIComponent(ens)}/revoke`,\n body,\n ),\n\n refresh: (ens: string, chainId: number): Promise<AgentSnapshot> =>\n request<AgentSnapshot>(\n \"GET\",\n `/agents/${encodeURIComponent(ens)}?chainId=${chainId}`,\n ),\n};\n","import type { ChainName } from \"../types.js\";\n\nexport const DEFAULT_CHAIN_ID = 84532;\n\nexport const CHAINS = {\n 1: { name: \"ethereum\" as const, rpcUrl: \"https://eth.drpc.org\" },\n 8453: { name: \"base\" as const, rpcUrl: \"https://base.drpc.org\" },\n 84532: { name: \"base\" as const, rpcUrl: \"https://sepolia.base.org\" },\n 10: { name: \"optimism\" as const, rpcUrl: \"https://optimism.drpc.org\" },\n 42161: { name: \"arbitrum\" as const, rpcUrl: \"https://arbitrum.drpc.org\" },\n} as const;\n\nexport function chainNameFor(chainId: number): ChainName {\n const c = CHAINS[chainId as keyof typeof CHAINS];\n if (!c) throw new Error(`Unsupported chain: ${chainId}`);\n return c.name;\n}\n\nexport function rpcUrlFor(chainId: number): string {\n const c = CHAINS[chainId as keyof typeof CHAINS];\n if (!c) throw new Error(`Unsupported chain: ${chainId}`);\n return c.rpcUrl;\n}\n\nexport function isSupportedChain(chainId: number): boolean {\n return chainId in CHAINS;\n}\n","import { JustaName } from \"@justaname.id/sdk\";\nimport { rpcUrlFor } from \"./chains.js\";\n\nconst ENS_GATEWAY = \"https://api.justaname.id\";\n\n// JustaName's ChainId is the L1 ENS chain (mainnet or sepolia).\ntype EnsChainId = 1 | 11155111;\n\nexport function ensGatewayUrl(path: string, params: Record<string, string>): URL {\n const url = new URL(`${ENS_GATEWAY}${path}`);\n for (const [k, v] of Object.entries(params)) url.searchParams.set(k, v);\n return url;\n}\n\nexport function defaultProviderUrl(chainId: number): string {\n return rpcUrlFor(chainId);\n}\n\nexport function justaNameRead(chainId: EnsChainId): JustaName {\n return JustaName.init({\n networks: [{ chainId, providerUrl: rpcUrlFor(chainId) }],\n });\n}\n\nexport function justaNameWrite(opts: {\n apiKey: string;\n chainId: EnsChainId;\n namespace: string;\n domain: string;\n origin: string;\n}): JustaName {\n return JustaName.init({\n networks: [{ chainId: opts.chainId, providerUrl: rpcUrlFor(opts.chainId) }],\n ensDomains: [\n {\n chainId: opts.chainId,\n ensDomain: opts.namespace,\n apiKey: opts.apiKey,\n },\n ],\n config: { domain: opts.domain, origin: opts.origin },\n });\n}\n","import type { Address } from \"viem\";\nimport { ResolutionError } from \"../errors.js\";\nimport { ensGatewayUrl, defaultProviderUrl } from \"../core/client.js\";\nimport type { EnsOrAddress } from \"../types.js\";\n\nexport async function resolve(\n input: EnsOrAddress,\n chainId: number,\n): Promise<Address> {\n if (input.startsWith(\"0x\") && input.length === 42) {\n return input as Address;\n }\n\n const url = ensGatewayUrl(\"/ens/v1/subname/records\", {\n ens: `${input}@eip155:${chainId}`,\n providerUrl: defaultProviderUrl(chainId),\n });\n\n let res: Response;\n try {\n res = await fetch(url);\n } catch (err) {\n throw new ResolutionError(\n `Could not resolve ${input}: gateway unreachable`,\n err,\n );\n }\n if (!res.ok) {\n throw new ResolutionError(\n `Could not resolve ${input} on chain ${chainId} (${res.status})`,\n );\n }\n const json = (await res.json()) as {\n result?: {\n data?: { records?: { addresses?: Array<{ value?: string }> } };\n };\n };\n const addr = json.result?.data?.records?.addresses?.[0]?.value;\n if (!addr) {\n throw new ResolutionError(\n `Could not resolve ${input}: no address record on chain ${chainId}`,\n );\n }\n return addr as Address;\n}\n","import { createPublicClient, erc20Abi, http } from \"viem\";\nimport type { Address } from \"viem\";\nimport type { TokenSymbol } from \"../types.js\";\nimport { rpcUrlFor, isSupportedChain } from \"../core/chains.js\";\n\nexport const NATIVE_TOKEN: Address =\n \"0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE\";\n\nexport interface TokenEntry {\n address: Address;\n decimals: number;\n}\n\nconst REGISTRY: Record<number, Partial<Record<string, TokenEntry>>> = {\n 8453: {\n ETH: { address: NATIVE_TOKEN, decimals: 18 },\n USDC: { address: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\", decimals: 6 },\n USDT: { address: \"0xfde4C96c8593536E31F229EA8f37b2ADa2699bb2\", decimals: 6 },\n DAI: { address: \"0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb\", decimals: 18 },\n },\n 84532: {\n ETH: { address: NATIVE_TOKEN, decimals: 18 },\n USDC: { address: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\", decimals: 6 },\n },\n 1: {\n ETH: { address: NATIVE_TOKEN, decimals: 18 },\n USDC: { address: \"0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48\", decimals: 6 },\n USDT: { address: \"0xdAC17F958D2ee523a2206206994597C13D831ec7\", decimals: 6 },\n DAI: { address: \"0x6B175474E89094C44Da98b954EedeAC495271d0F\", decimals: 18 },\n },\n 10: {\n ETH: { address: NATIVE_TOKEN, decimals: 18 },\n USDC: { address: \"0x0b2C639c533813f4Aa9D7837CAf62653d097Ff85\", decimals: 6 },\n },\n};\n\nconst RAW_DECIMALS_CACHE = new Map<string, number>();\n\nfunction cacheKey(chainId: number, address: Address): string {\n return `${chainId}:${address.toLowerCase()}`;\n}\n\nasync function fetchDecimalsOnchain(\n address: Address,\n chainId: number,\n): Promise<number> {\n if (!isSupportedChain(chainId)) {\n throw new Error(`Unsupported chain ${chainId} — cannot fetch decimals.`);\n }\n const client = createPublicClient({ transport: http(rpcUrlFor(chainId)) });\n try {\n const decimals = await client.readContract({\n address,\n abi: erc20Abi,\n functionName: \"decimals\",\n });\n return Number(decimals);\n } catch (err) {\n throw new Error(\n `Could not fetch decimals for token ${address} on chain ${chainId}. ` +\n `Add it to the registry or pass a known symbol (USDC, ETH, …). ` +\n `Cause: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n}\n\nexport async function resolveToken(\n token: TokenSymbol | Address,\n chainId: number,\n): Promise<TokenEntry> {\n if (token.startsWith(\"0x\") && token.length === 42) {\n const address = token as Address;\n if (address.toLowerCase() === NATIVE_TOKEN.toLowerCase()) {\n return { address, decimals: 18 };\n }\n const key = cacheKey(chainId, address);\n const cached = RAW_DECIMALS_CACHE.get(key);\n if (cached !== undefined) return { address, decimals: cached };\n const decimals = await fetchDecimalsOnchain(address, chainId);\n RAW_DECIMALS_CACHE.set(key, decimals);\n return { address, decimals };\n }\n const chain = REGISTRY[chainId];\n const entry = chain?.[token];\n if (!entry) throw new Error(`Unknown token \"${token}\" on chain ${chainId}`);\n return entry;\n}\n\n// Test-only helper to seed the cache deterministically.\nexport function _setDecimalsCacheForTesting(\n chainId: number,\n address: Address,\n decimals: number,\n): void {\n RAW_DECIMALS_CACHE.set(cacheKey(chainId, address), decimals);\n}\n\nexport function _clearDecimalsCacheForTesting(): void {\n RAW_DECIMALS_CACHE.clear();\n}\n","import { parseUnits } from \"viem\";\nimport { resolveToken } from \"./registry.js\";\nimport type { TokenSymbol } from \"../types.js\";\n\nexport async function parseAmount(\n input: string,\n chainId: number,\n): Promise<{ token: TokenSymbol; amountUnits: bigint }> {\n const m = /^([\\d.]+)\\s+([A-Z]+)$/.exec(input.trim());\n if (!m || !m[1] || !m[2]) {\n throw new Error(`Could not parse amount: \"${input}\". Expected \"10 USDC\".`);\n }\n const tok = await resolveToken(m[2] as TokenSymbol, chainId);\n return {\n token: m[2] as TokenSymbol,\n amountUnits: parseUnits(m[1], tok.decimals),\n };\n}\n","import { encodeFunctionData, erc20Abi, parseUnits } from \"viem\";\nimport type { Address, Hex } from \"viem\";\nimport { api } from \"./core/api.js\";\nimport { resolve } from \"./ens/resolve.js\";\nimport { resolveToken, NATIVE_TOKEN } from \"./tokens/registry.js\";\nimport { parseAmount } from \"./tokens/helpers.js\";\nimport { getOwnerPrivateKey } from \"./env.js\";\nimport { AgensaiError, ExecutionRevertedError } from \"./errors.js\";\nimport type {\n AgentSnapshot,\n BatchCall,\n BatchResult,\n EnsName,\n ExecuteOptions,\n Policy,\n} from \"./types.js\";\n\ninterface AgentConstructor {\n ens: EnsName;\n address: Address;\n chainId: number;\n ownerAddress: Address;\n permissionId: Hex;\n expiry: number;\n policies: Policy[];\n agentPrivateKey: Hex;\n paymasterUrl?: string;\n}\n\nconst READ_ONLY_KEY: Hex = \"0x\";\n\nexport class Agent {\n readonly name: EnsName;\n readonly address: Address;\n readonly chainId: number;\n readonly ownerAddress: Address;\n readonly permissionId: Hex;\n readonly expiry: number;\n\n #agentPrivateKey: Hex;\n #paymasterUrl: string | undefined;\n #policies: Policy[];\n #revoked = false;\n #readOnly = false;\n\n constructor(args: AgentConstructor) {\n this.name = args.ens;\n this.address = args.address;\n this.chainId = args.chainId;\n this.ownerAddress = args.ownerAddress;\n this.permissionId = args.permissionId;\n this.expiry = args.expiry;\n this.#agentPrivateKey = args.agentPrivateKey;\n this.#paymasterUrl = args.paymasterUrl;\n this.#policies = args.policies;\n }\n\n snapshot(): AgentSnapshot {\n const now = Math.floor(Date.now() / 1000);\n const status: AgentSnapshot[\"status\"] = this.#revoked\n ? \"revoked\"\n : now > this.expiry\n ? \"expired\"\n : \"active\";\n return {\n name: this.name,\n address: this.address,\n chainId: this.chainId,\n ownerAddress: this.ownerAddress,\n permissionId: this.permissionId,\n expiry: this.expiry,\n status,\n policies: this.#policies,\n };\n }\n\n get policies(): Policy[] {\n return this.#policies;\n }\n\n async refresh(): Promise<AgentSnapshot> {\n const fresh = await api.refresh(this.name, this.chainId);\n this.#policies = fresh.policies;\n if (fresh.status === \"revoked\") this.#revoked = true;\n return fresh;\n }\n\n async execute(opts: ExecuteOptions): Promise<Hex> {\n this.#assertWritable();\n const call = await this.#buildCall(opts);\n const { callId } = await api.executeCalls(this.name, {\n agentPrivateKey: this.#agentPrivateKey,\n permissionId: this.permissionId,\n chainId: this.chainId,\n calls: [this.#serializeCall(call)],\n ...(this.#paymasterUrl ? { paymasterUrl: this.#paymasterUrl } : {}),\n });\n if (opts.wait !== false) await this.waitForReceipt(callId);\n return callId;\n }\n\n async batch(calls: BatchCall[]): Promise<BatchResult> {\n this.#assertWritable();\n const built = await Promise.all(calls.map((c) => this.#buildCall(c)));\n const { callId } = await api.executeCalls(this.name, {\n agentPrivateKey: this.#agentPrivateKey,\n permissionId: this.permissionId,\n chainId: this.chainId,\n calls: built.map((c) => this.#serializeCall(c)),\n ...(this.#paymasterUrl ? { paymasterUrl: this.#paymasterUrl } : {}),\n });\n return { id: callId, chainId: this.chainId };\n }\n\n async waitForReceipt(\n callId: Hex,\n opts: { timeoutMs?: number; pollIntervalMs?: number } = {},\n ): Promise<{ txHash: Hex; status: \"success\" }> {\n this.#assertWritable();\n const deadline = Date.now() + (opts.timeoutMs ?? 60_000);\n const interval = opts.pollIntervalMs ?? 1000;\n while (Date.now() < deadline) {\n const r = await api.getCallReceipt(callId, this.chainId);\n if (r.status !== \"pending\" && r.txHash) {\n if (r.status === \"reverted\") {\n // The on-chain `UserOperationEvent.success` field said false.\n // The bundle was included but the inner call reverted —\n // surface the revert rather than letting the caller treat\n // this as a successful execution. Service-side cross-checks\n // the receipt to override JAW's reported status when needed.\n throw new ExecutionRevertedError(\n `Agent execution reverted on-chain (callId ${callId}, tx ${r.txHash}).`,\n { callId, txHash: r.txHash },\n );\n }\n return { txHash: r.txHash, status: \"success\" };\n }\n await new Promise((res) => setTimeout(res, interval));\n }\n throw new AgensaiError(\n `waitForReceipt: callId ${callId} did not include within ${opts.timeoutMs ?? 60_000}ms`,\n );\n }\n\n async revoke(opts: { ownerPrivateKey?: Hex } = {}): Promise<{ txHash: Hex }> {\n this.#assertWritable();\n const ownerPrivateKey = getOwnerPrivateKey(opts.ownerPrivateKey);\n if (!ownerPrivateKey) {\n throw new AgensaiError(\n \"ownerPrivateKey is required (or set AGENSAI_OWNER_PRIVATE_KEY).\",\n );\n }\n const result = await api.revoke(this.name, {\n ownerPrivateKey,\n permissionId: this.permissionId,\n chainId: this.chainId,\n ...(this.#paymasterUrl ? { paymasterUrl: this.#paymasterUrl } : {}),\n });\n this.#revoked = true;\n return { txHash: result.txHash };\n }\n\n async #buildCall(\n c: BatchCall,\n ): Promise<{ to: Address; value?: bigint; data?: Hex }> {\n const to = await resolve(c.to, this.chainId);\n\n if (c.amount) {\n const { token, amountUnits } = await parseAmount(c.amount, this.chainId);\n const tok = await resolveToken(token, this.chainId);\n\n if (tok.address.toLowerCase() === NATIVE_TOKEN.toLowerCase()) {\n return { to, value: amountUnits };\n }\n return {\n to: tok.address,\n data: encodeFunctionData({\n abi: erc20Abi,\n functionName: \"transfer\",\n args: [to, amountUnits],\n }),\n };\n }\n\n const out: { to: Address; value?: bigint; data?: Hex } = { to };\n if (c.value !== undefined) {\n out.value = typeof c.value === \"string\" ? parseUnits(c.value, 18) : c.value;\n }\n if (c.data) out.data = c.data;\n return out;\n }\n\n #serializeCall(c: { to: Address; value?: bigint; data?: Hex }): {\n to: Address;\n value?: string;\n data?: Hex;\n } {\n const out: { to: Address; value?: string; data?: Hex } = { to: c.to };\n if (c.value !== undefined) out.value = c.value.toString();\n if (c.data) out.data = c.data;\n return out;\n }\n\n toJSON(): {\n ens: EnsName;\n address: Address;\n chainId: number;\n ownerAddress: Address;\n permissionId: Hex;\n expiry: number;\n status: \"active\" | \"expired\" | \"revoked\";\n policies: Policy[];\n } {\n const now = Math.floor(Date.now() / 1000);\n const status: \"active\" | \"expired\" | \"revoked\" = this.#revoked\n ? \"revoked\"\n : now > this.expiry\n ? \"expired\"\n : \"active\";\n return {\n ens: this.name,\n address: this.address,\n chainId: this.chainId,\n ownerAddress: this.ownerAddress,\n permissionId: this.permissionId,\n expiry: this.expiry,\n status,\n policies: this.#policies,\n };\n }\n\n /**\n * WARNING: Output contains the agent's private key. Never log this value.\n * Encrypt at rest. Treat as funds-control material.\n */\n toBackupJSON(): ReturnType<Agent[\"toJSON\"]> & { agentPrivateKey: Hex } {\n return { ...this.toJSON(), agentPrivateKey: this.#agentPrivateKey };\n }\n\n static fromJSON(\n blob:\n | ReturnType<Agent[\"toJSON\"]>\n | ReturnType<Agent[\"toBackupJSON\"]>,\n env: { paymasterUrl?: string; policies?: Policy[] } = {},\n ): Agent {\n const agentPrivateKey =\n \"agentPrivateKey\" in blob ? blob.agentPrivateKey : undefined;\n const ctor: AgentConstructor = {\n ens: blob.ens,\n address: blob.address,\n chainId: blob.chainId,\n ownerAddress: blob.ownerAddress,\n permissionId: blob.permissionId,\n expiry: blob.expiry,\n policies: env.policies ?? blob.policies ?? [],\n agentPrivateKey: agentPrivateKey ?? READ_ONLY_KEY,\n };\n if (env.paymasterUrl) ctor.paymasterUrl = env.paymasterUrl;\n const agent = new Agent(ctor);\n if (!agentPrivateKey) agent.#readOnly = true;\n return agent;\n }\n\n #assertWritable(): void {\n if (this.#readOnly) {\n throw new AgensaiError(\n \"Agent restored from public snapshot; private key required for write operations\",\n );\n }\n }\n}\n","import { parseUnits } from \"viem\";\nimport { resolve } from \"../ens/resolve.js\";\nimport { resolveToken } from \"../tokens/registry.js\";\nimport { PolicyError } from \"../errors.js\";\nimport type { Policy, SpendPolicy } from \"../types.js\";\nimport type { CompiledPolicy } from \"./types.js\";\n\nconst DEFAULT_EXPIRY_SECONDS = 60 * 60 * 24 * 30;\n\n/**\n * JustaPermissionManager wildcard sentinels (re-exported from `@jaw.id/core`).\n *\n * When a permission's `calls` whitelist is omitted (no `contract` policy\n * supplied), the agent should be able to call any contract. JAW's contract\n * uses these explicit sentinel values to express \"any target\" / \"any\n * selector\", encoded into a single `CallPermission` entry. This is the\n * documented wildcard shape — see `@jaw.id/core`'s `permissions.ts` and\n * the `JustaPermissionManager.sol` contract.\n *\n * Do NOT use an empty `calls: []` array. The on-chain validator treats an\n * empty list as \"no calls allowed\" (fail-closed), which would brick the\n * agent.\n *\n * NOTE: there is intentionally no equivalent default for spends. AGENSAI\n * requires every agent to declare at least one explicit `spend` policy at\n * creation time. Industry-standard fail-closed posture; aligns with the\n * safety promise on the landing page.\n */\nexport const ANY_TARGET: `0x${string}` =\n \"0x3232323232323232323232323232323232323232\";\nexport const ANY_FN_SEL: `0x${string}` = \"0x32323232\";\n\nexport async function compilePolicies(args: {\n policies: Policy[];\n spender: `0x${string}`;\n chainId: number;\n}): Promise<CompiledPolicy> {\n const { policies, spender, chainId } = args;\n\n // Fail-closed: every agent must explicitly declare at least one spend\n // policy. AGENSAI does not ship wildcard spend defaults — that would\n // turn \"expires-only\" into \"drain the wallet until expiry\", a footgun\n // we intentionally close. Aligns with ZeroDev / Namera / Biconomy /\n // Stripe / AWS IAM industry-standard explicit-grant posture.\n const hasSpend = policies.some((p) => p.type === \"spend\");\n if (!hasSpend) {\n throw new PolicyError(\n `Every agent must have at least one spend policy. Add e.g.:\n { type: \"spend\", token: \"ETH\", amount: \"0.01\", period: \"day\" }\nThis caps how much the agent can move. AGENSAI does not ship wildcard defaults.`,\n );\n }\n\n const compiled: CompiledPolicy = {\n expiry: Math.floor(Date.now() / 1000) + DEFAULT_EXPIRY_SECONDS,\n spender,\n permissions: { calls: [], spends: [] },\n };\n\n for (const p of policies) {\n switch (p.type) {\n case \"spend\": {\n const tok = await resolveToken(p.token, chainId);\n const allowance = parseUnits(String(p.amount), tok.decimals).toString();\n compiled.permissions.spends.push({\n token: tok.address,\n allowance,\n unit: normalizePeriod(p.period),\n multiplier: p.multiplier ?? 1,\n });\n break;\n }\n case \"contract\": {\n for (const target of p.whitelist) {\n const targetAddress = await resolve(target, chainId);\n compiled.permissions.calls.push({\n target: targetAddress,\n ...(p.functionSignature\n ? { functionSignature: p.functionSignature }\n : {}),\n });\n }\n break;\n }\n case \"expires\": {\n compiled.expiry = parseExpiry(p.at);\n break;\n }\n case \"rate\": {\n compiled.rate = { max: p.max, period: p.period };\n break;\n }\n default: {\n const _exhaustive: never = p;\n throw new PolicyError(`Unknown policy: ${JSON.stringify(_exhaustive)}`);\n }\n }\n }\n\n // No `contract` policy supplied means the user expressed intent \"agent can\n // call any contract\" within the spend + expires + rate constraints. Emit\n // JAW's documented wildcard sentinels (ANY_TARGET / ANY_FN_SEL) so the\n // permission validates on-chain. Without this, an empty `calls` array\n // would be treated as \"no calls allowed\" by JustaPermissionManager.\n if (compiled.permissions.calls.length === 0) {\n compiled.permissions.calls.push({\n target: ANY_TARGET,\n selector: ANY_FN_SEL,\n });\n }\n\n // No wildcard-spend default. The fail-closed check at the top of this\n // function guarantees `compiled.permissions.spends.length >= 1` here.\n\n return compiled;\n}\n\nexport function normalizePeriod(\n p: SpendPolicy[\"period\"],\n): \"minute\" | \"hour\" | \"day\" | \"week\" | \"month\" | \"year\" | \"forever\" {\n switch (p) {\n case \"daily\":\n return \"day\";\n case \"weekly\":\n return \"week\";\n case \"monthly\":\n return \"month\";\n case \"yearly\":\n return \"year\";\n default:\n return p;\n }\n}\n\nexport function parseExpiry(input: string): number {\n const dt = Date.parse(input);\n if (!Number.isNaN(dt)) return Math.floor(dt / 1000);\n\n const m = /^(\\d+)([smhdwy])$/i.exec(input.trim());\n if (!m || !m[1] || !m[2]) {\n throw new PolicyError(`Invalid expiry: ${input}`);\n }\n const n = Number(m[1]);\n const unit = m[2].toLowerCase();\n const seconds: Record<string, number> = {\n s: 1,\n m: 60,\n h: 3600,\n d: 86400,\n w: 604800,\n y: 31_536_000,\n };\n const factor = seconds[unit];\n if (!factor) throw new PolicyError(`Invalid expiry unit: ${unit}`);\n return Math.floor(Date.now() / 1000) + n * factor;\n}\n","import { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\";\nimport type { Hex } from \"viem\";\nimport { Agent } from \"./Agent.js\";\nimport { api } from \"./core/api.js\";\nimport { compilePolicies } from \"./policies/compile.js\";\nimport { getOwnerPrivateKey } from \"./env.js\";\nimport { AgensaiError } from \"./errors.js\";\nimport type { CreateAgentOptions, EnsName } from \"./types.js\";\n\n// `createAgent` ships the owner key + agent session key to the\n// AGENSAI service over TLS. The service holds them only for the\n// duration of the request, signs through JAW core, and drops them.\n// JAW's bundler does not accept raw signed UserOps; `Account.sendCalls`\n// is the only relay primitive. The trade-off is documented in\n// SECURITY.md.\n\nexport async function createAgent(opts: CreateAgentOptions): Promise<Agent> {\n const ownerPrivateKey = getOwnerPrivateKey(opts.ownerPrivateKey);\n if (!ownerPrivateKey) {\n throw new AgensaiError(\n \"ownerPrivateKey is required (or set AGENSAI_OWNER_PRIVATE_KEY).\",\n );\n }\n\n if (!/^[a-z0-9-]+$/.test(opts.name)) {\n throw new AgensaiError(\n `Invalid agent name \"${opts.name}\". Must match ^[a-z0-9-]+$.`,\n );\n }\n\n if (opts.namespace && opts.namespace !== \"agensai.eth\") {\n throw new AgensaiError(\"Custom namespaces are reserved for v0.2.\");\n }\n\n const agentPrivateKey: Hex = opts.agentPrivateKey ?? generatePrivateKey();\n\n // Compile policies locally. The SDK has the chain-aware token registry\n // and ENS resolver; the service receives the compiled blob and forwards\n // it verbatim to JAW. Spender is filled in service-side once the agent\n // address is derived; we use a placeholder here.\n const PLACEHOLDER_SPENDER =\n \"0x0000000000000000000000000000000000000001\" as const;\n const compiledPolicy = await compilePolicies({\n policies: opts.policies,\n spender: PLACEHOLDER_SPENDER,\n chainId: opts.chainId,\n });\n\n const created = await api.createAgent({\n name: opts.name,\n chainId: opts.chainId,\n ownerPrivateKey,\n agentPrivateKey,\n policies: opts.policies,\n compiledPolicy,\n ...(opts.description ? { description: opts.description } : {}),\n ...(opts.paymasterUrl ? { paymasterUrl: opts.paymasterUrl } : {}),\n });\n\n // Belt-and-suspenders: confirm the service returned an address that\n // matches the agent key we generated. JAW core's\n // `Account.fromLocalAccount(...).getAddress()` is deterministic over\n // (sessionPublicKey, chainId), so the SDK can verify locally.\n const expectedSessionAddress = privateKeyToAccount(agentPrivateKey).address;\n if (!created.address || !created.address.startsWith(\"0x\")) {\n throw new AgensaiError(\n `service returned malformed agent address: ${created.address}`,\n );\n }\n // The agent address is the smart-account, not the EOA — they should\n // differ. We do not assert equality here; service-side derivation is\n // authoritative. We do log a debug-friendly invariant to catch\n // truly broken responses where the service echoed the EOA back.\n if (\n created.address.toLowerCase() === expectedSessionAddress.toLowerCase()\n ) {\n throw new AgensaiError(\n \"service returned EOA as agent address (expected smart-account address)\",\n );\n }\n\n return new Agent({\n ens: created.ens as EnsName,\n address: created.address,\n chainId: created.chainId,\n ownerAddress: created.ownerAddress,\n permissionId: created.permissionId,\n expiry: created.expiry,\n policies: created.policies,\n agentPrivateKey,\n ...(opts.paymasterUrl ? { paymasterUrl: opts.paymasterUrl } : {}),\n });\n}\n","import { privateKeyToAccount } from \"viem/accounts\";\nimport { Agent } from \"./Agent.js\";\nimport { resolve } from \"./ens/resolve.js\";\nimport { api } from \"./core/api.js\";\nimport { DEFAULT_CHAIN_ID } from \"./core/chains.js\";\nimport { AgensaiError } from \"./errors.js\";\nimport type { GetAgentOptions, EnsName } from \"./types.js\";\n\nexport async function getAgent(\n ensName: EnsName,\n opts: GetAgentOptions,\n): Promise<Agent> {\n const chainId = opts.chainId ?? DEFAULT_CHAIN_ID;\n\n const [expectedAddress, snapshot] = await Promise.all([\n resolve(ensName, chainId),\n api.getAgent(ensName, chainId),\n ]);\n\n // Sanity check: the SDK can't derive the smart-account address\n // locally without JAW core, but it can confirm the supplied agent\n // key's EOA does not equal the smart-account address (that would\n // imply a misconfigured restore where the EOA was used as the agent\n // address). The authoritative check is done service-side; this is\n // a fast local guard against obvious misuse.\n const eoa = privateKeyToAccount(opts.agentPrivateKey).address;\n if (eoa.toLowerCase() === expectedAddress.toLowerCase()) {\n throw new AgensaiError(\n `Agent key mismatch for ${ensName}: ENS resolves to ${expectedAddress}, which equals the supplied key's EOA. The agent address should be the smart-account, not the EOA.`,\n );\n }\n\n return new Agent({\n ens: ensName,\n address: snapshot.address,\n chainId,\n ownerAddress: snapshot.ownerAddress,\n permissionId: snapshot.permissionId,\n expiry: snapshot.expiry,\n policies: snapshot.policies,\n agentPrivateKey: opts.agentPrivateKey,\n });\n}\n","import { api } from \"./core/api.js\";\nimport { DEFAULT_CHAIN_ID } from \"./core/chains.js\";\nimport type { AgentSnapshot, ListAgentsOptions } from \"./types.js\";\n\nexport async function listAgents(\n opts: ListAgentsOptions,\n): Promise<AgentSnapshot[]> {\n const chainId = opts.chainId ?? DEFAULT_CHAIN_ID;\n return api.listAgents({\n ownerAddress: opts.ownerAddress,\n chainId,\n ...(opts.includeInactive !== undefined\n ? { includeInactive: opts.includeInactive }\n : {}),\n });\n}\n","import type { Address, Hex } from \"viem\";\nimport { ensGatewayUrl, defaultProviderUrl } from \"../core/client.js\";\nimport { ResolutionError } from \"../errors.js\";\nimport type { Policy, PolicySnapshot } from \"../types.js\";\n\ninterface GatewayShape {\n result?: {\n data?: {\n records?: {\n texts?: Array<{ key: string; value: string }>;\n addresses?: Array<{ coinType?: number; value?: string }>;\n };\n };\n };\n}\n\ninterface PoliciesBlob {\n version: number;\n policies: Policy[];\n permissionId: Hex;\n expiresAt: string;\n}\n\nexport async function readPolicyRecords(\n ens: string,\n chainId: number,\n): Promise<PolicySnapshot> {\n const url = ensGatewayUrl(\"/ens/v1/subname/records\", {\n ens: `${ens}@eip155:${chainId}`,\n providerUrl: defaultProviderUrl(chainId),\n });\n\n let res: Response;\n try {\n res = await fetch(url);\n } catch (err) {\n throw new ResolutionError(`Records read failed for ${ens}`, err);\n }\n if (!res.ok) {\n throw new ResolutionError(\n `Records read failed for ${ens} (${res.status})`,\n );\n }\n\n const json = (await res.json()) as GatewayShape;\n const texts = json.result?.data?.records?.texts ?? [];\n const addresses = json.result?.data?.records?.addresses ?? [];\n\n const text = (key: string): string | undefined =>\n texts.find((t) => t.key === key)?.value;\n const address = (addresses[0]?.value ?? undefined) as Address | undefined;\n if (!address) {\n throw new ResolutionError(`No address record on ${ens}`);\n }\n\n const blob = text(\"agensai.policies\");\n if (!blob) {\n throw new ResolutionError(\n `No agensai.policies record on ${ens}; ENS exists but is not an AGENSAI agent`,\n );\n }\n\n let parsed: PoliciesBlob;\n try {\n parsed = JSON.parse(blob) as PoliciesBlob;\n } catch (err) {\n throw new ResolutionError(\n `Could not parse agensai.policies on ${ens}`,\n err,\n );\n }\n if (parsed.version !== 1) {\n throw new ResolutionError(\n `Unsupported agensai.policies version ${parsed.version} on ${ens}`,\n );\n }\n\n const status = (text(\"agensai.status\") ??\n \"active\") as PolicySnapshot[\"status\"];\n\n const snapshot: PolicySnapshot = {\n ens,\n address,\n chainId,\n status,\n grantedBy: text(\"agensai.granted-by\") ?? \"\",\n grantedAt: text(\"agensai.granted-at\") ?? \"\",\n permissionId: parsed.permissionId,\n expiresAt: parsed.expiresAt,\n policies: parsed.policies,\n };\n const revokedAt = text(\"agensai.revoked-at\");\n if (revokedAt) snapshot.revokedAt = revokedAt;\n const desc = text(\"description\");\n if (desc) snapshot.description = desc;\n return snapshot;\n}\n","import { readPolicyRecords } from \"./ens/textRecords.js\";\nimport { DEFAULT_CHAIN_ID } from \"./core/chains.js\";\nimport type { PolicySnapshot } from \"./types.js\";\n\nexport async function getPolicySnapshot(\n ens: string,\n chainId: number = DEFAULT_CHAIN_ID,\n): Promise<PolicySnapshot> {\n return readPolicyRecords(ens, chainId);\n}\n","import type { Address } from \"viem\";\nimport { ensGatewayUrl, defaultProviderUrl } from \"../core/client.js\";\n\nexport async function reverseResolve(\n address: Address,\n chainId: number,\n): Promise<string | null> {\n const url = ensGatewayUrl(\"/ens/v1/primary-name\", {\n address,\n chainId: String(chainId),\n providerUrl: defaultProviderUrl(chainId),\n });\n let res: Response;\n try {\n res = await fetch(url);\n } catch {\n return null;\n }\n if (!res.ok) return null;\n const json = (await res.json()) as { result?: { data?: { name?: string } } };\n return json.result?.data?.name ?? null;\n}\n","import type { Address } from \"viem\";\nimport { justaNameWrite } from \"../core/client.js\";\n\n// JustaName runs on L1 ENS — mainnet (1) or sepolia (11155111). The L2 chain\n// where the agent lives is recorded as a typed-coin address record under\n// ENSIP-11 (coinType = 0x80000000 + chainId).\ntype EnsChainId = 1 | 11155111;\n\nfunction ensChainFor(l2ChainId: number): EnsChainId {\n // Production L1 anchors mainnet; everything else (including Sepolia testnet\n // and L2 testnets) anchors Sepolia.\n return l2ChainId === 1 || l2ChainId === 8453 || l2ChainId === 10 || l2ChainId === 42161\n ? 1\n : 11155111;\n}\n\nfunction coinTypeFor(chainId: number): number {\n if (chainId === 1) return 60; // SLIP-44 ETH\n return 0x80000000 + chainId; // ENSIP-11\n}\n\n/**\n * Issues an ENS subname under the given L1 namespace pointing at the agent\n * smart account on its L2 chain. Uses `overrideSignatureCheck: true` because\n * we are calling server-side from a JAW-authenticated context.\n */\nexport async function issueSubname(args: {\n apiKey: string;\n username: string;\n namespace: string;\n chainId: number;\n agentAddress: Address;\n textRecords?: Array<{ key: string; value: string }>;\n}): Promise<{ ens: string }> {\n const ensChainId = ensChainFor(args.chainId);\n const justa = justaNameWrite({\n apiKey: args.apiKey,\n chainId: ensChainId,\n namespace: args.namespace,\n // SIWE domain/origin must match what the JAW API key was bound to in the\n // JustaName dashboard. Adrian's key is bound to `agensai.eth`. This is\n // intentionally NOT the web product domain (`agensai.xyz`) — these are\n // different layers (web vs ENS auth).\n domain: \"agensai.eth\",\n origin: \"https://agensai.eth\",\n });\n\n await justa.subnames.addSubname({\n username: args.username,\n ensDomain: args.namespace,\n chainId: ensChainId,\n overrideSignatureCheck: true,\n addresses: [\n { address: args.agentAddress, coinType: coinTypeFor(args.chainId) as never },\n // Always also publish the SLIP-44 ETH record so generic resolvers work.\n { address: args.agentAddress, coinType: 60 as never },\n ],\n text: args.textRecords ?? [],\n });\n\n return { ens: `${args.username}.${args.namespace}` };\n}\n","// @agensai/sdk — public entry point.\n\nexport { createAgent } from \"./createAgent.js\";\nexport { getAgent } from \"./getAgent.js\";\nexport { listAgents } from \"./listAgents.js\";\nexport { Agent } from \"./Agent.js\";\nexport { getPolicySnapshot } from \"./getPolicySnapshot.js\";\n\nexport { resolve, reverseResolve, issueSubname } from \"./ens/index.js\";\nexport { compilePolicies } from \"./policies/index.js\";\nexport { resolveToken, parseAmount, NATIVE_TOKEN } from \"./tokens/index.js\";\n\nexport {\n CHAINS,\n DEFAULT_CHAIN_ID,\n chainNameFor,\n rpcUrlFor,\n isSupportedChain,\n} from \"./core/chains.js\";\n\nexport type {\n CreateAgentOptions,\n GetAgentOptions,\n ListAgentsOptions,\n AgentSnapshot,\n PolicySnapshot,\n ExecuteOptions,\n BatchCall,\n BatchResult,\n Policy,\n SpendPolicy,\n ContractPolicy,\n ExpiresPolicy,\n RatePolicy,\n ChainName,\n TokenSymbol,\n EnsName,\n EnsOrAddress,\n} from \"./types.js\";\n\nexport type { CompiledPolicy } from \"./policies/types.js\";\n\nexport {\n AgensaiError,\n PolicyError,\n ResolutionError,\n PermissionViolationError,\n ExecutionRevertedError,\n} from \"./errors.js\";\n\nexport const version = \"0.1.0\";\n"]}
package/package.json ADDED
@@ -0,0 +1,68 @@
1
+ {
2
+ "name": "@agensai/sdk",
3
+ "version": "0.1.0",
4
+ "description": "ENS-native wallets for AI agents. Built on JAW.",
5
+ "license": "MIT",
6
+ "author": "JustaLab",
7
+ "homepage": "https://agensai.xyz",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/agensai/agensai.git",
11
+ "directory": "packages/sdk"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/agensai/agensai/issues"
15
+ },
16
+ "keywords": [
17
+ "agensai",
18
+ "ens",
19
+ "erc-4337",
20
+ "erc-7715",
21
+ "erc-7528",
22
+ "ai-agents",
23
+ "smart-account",
24
+ "wallet",
25
+ "jaw"
26
+ ],
27
+ "type": "module",
28
+ "main": "./dist/index.js",
29
+ "module": "./dist/index.js",
30
+ "types": "./dist/index.d.ts",
31
+ "exports": {
32
+ ".": {
33
+ "types": "./dist/index.d.ts",
34
+ "import": "./dist/index.js"
35
+ }
36
+ },
37
+ "files": [
38
+ "dist",
39
+ "README.md",
40
+ "LICENSE"
41
+ ],
42
+ "dependencies": {
43
+ "@jaw.id/core": "^0.3.0",
44
+ "@justaname.id/sdk": "^0.2.212",
45
+ "viem": "^2.38.2"
46
+ },
47
+ "devDependencies": {
48
+ "tsup": "^8.3.0",
49
+ "typescript": "^5.6.3",
50
+ "vitest": "^2.1.4"
51
+ },
52
+ "publishConfig": {
53
+ "access": "public"
54
+ },
55
+ "engines": {
56
+ "node": ">=20"
57
+ },
58
+ "scripts": {
59
+ "build": "tsup",
60
+ "dev": "tsup --watch",
61
+ "clean": "rm -rf dist .turbo",
62
+ "lint": "eslint src",
63
+ "test": "vitest run",
64
+ "test:watch": "vitest",
65
+ "test:e2e": "AGENSAI_E2E=1 vitest run tests/e2e.test.ts",
66
+ "typecheck": "tsc --noEmit"
67
+ }
68
+ }