@auteng/agent-utils 0.1.1 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +68 -22
- package/dist/index.d.mts +44 -11
- package/dist/index.d.ts +44 -11
- package/dist/index.js +161 -74
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +163 -77
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -6
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @auteng/agent-utils
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Give your AI agent its own crypto wallets. Create purpose-specific wallets funded with USDC on Base, then let the agent spend autonomously on x402-enabled services like sandboxed compute. No accounts, no KYC — just wallet addresses and USDC.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,32 +8,54 @@ Utility belt for autonomous AI agents — wallet, compute, and x402 payments.
|
|
|
8
8
|
npm install @auteng/agent-utils
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Quick Start
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```typescript
|
|
14
|
+
import { wallet, compute } from '@auteng/agent-utils';
|
|
15
|
+
|
|
16
|
+
// 1. Create a wallet for this task
|
|
17
|
+
const w = await wallet.create({ name: "my-task" });
|
|
18
|
+
console.log(`Fund me: send USDC on Base to ${w.address}`);
|
|
19
|
+
|
|
20
|
+
// 2. Wait for funding
|
|
21
|
+
await w.waitForFunding(5_000000n); // wait for $5 USDC
|
|
22
|
+
|
|
23
|
+
// 3. Run sandboxed code (payment handled automatically)
|
|
24
|
+
const result = await compute.run({
|
|
25
|
+
code: 'print("hello from the sandbox")',
|
|
26
|
+
stack: 'python',
|
|
27
|
+
wallet: w,
|
|
28
|
+
});
|
|
29
|
+
console.log(result.stdout);
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
## Wallets
|
|
33
|
+
|
|
34
|
+
Each wallet is an independent keypair with its own address and balance. Create as many as you need — one per task, one per month, one per budget.
|
|
14
35
|
|
|
15
36
|
```typescript
|
|
16
37
|
import { wallet } from '@auteng/agent-utils';
|
|
17
38
|
|
|
18
|
-
await wallet.create();
|
|
19
|
-
|
|
39
|
+
const monthly = await wallet.create({ name: "feb-2026" });
|
|
40
|
+
const task = await wallet.create({ name: "data-pipeline" });
|
|
41
|
+
const dev = await wallet.create({ name: "testnet", network: "base-sepolia" });
|
|
20
42
|
```
|
|
21
43
|
|
|
22
|
-
|
|
44
|
+
Wallets are persisted at `.auteng/wallets/<name>.json`. Creating a wallet that already exists loads it from disk.
|
|
23
45
|
|
|
24
46
|
### Check balance
|
|
25
47
|
|
|
26
48
|
```typescript
|
|
27
|
-
const balance = await
|
|
28
|
-
// Returns USDC
|
|
29
|
-
//
|
|
49
|
+
const balance = await monthly.checkBalance();
|
|
50
|
+
// Returns USDC in minor units (6 decimals)
|
|
51
|
+
// 10_000000n = $10.00 USDC
|
|
30
52
|
```
|
|
31
53
|
|
|
32
54
|
### Wait for funding
|
|
33
55
|
|
|
34
56
|
```typescript
|
|
35
|
-
await
|
|
36
|
-
// Polls every 10s until >= 10 USDC is available
|
|
57
|
+
await monthly.waitForFunding(10_000000n);
|
|
58
|
+
// Polls Base every 10s until >= $10 USDC is available
|
|
37
59
|
```
|
|
38
60
|
|
|
39
61
|
### x402 fetch
|
|
@@ -41,41 +63,65 @@ await wallet.waitForFunding(10_000000n);
|
|
|
41
63
|
Drop-in `fetch()` replacement that handles x402 payments automatically:
|
|
42
64
|
|
|
43
65
|
```typescript
|
|
44
|
-
const res = await
|
|
66
|
+
const res = await monthly.fetch('https://x402.auteng.ai/api/x402/compute', {
|
|
45
67
|
method: 'POST',
|
|
68
|
+
headers: { 'Content-Type': 'application/json' },
|
|
46
69
|
body: JSON.stringify({ code: 'print("hi")', stack: 'python', size: 'small' }),
|
|
47
70
|
});
|
|
48
71
|
```
|
|
49
72
|
|
|
50
|
-
If the server returns `402 Payment Required`, the library signs an EIP-3009 authorization and retries with payment headers.
|
|
73
|
+
If the server returns `402 Payment Required`, the library signs an EIP-3009 authorization and retries with payment headers. No gas needed.
|
|
74
|
+
|
|
75
|
+
### Retrieve and list wallets
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
const w = wallet.get("feb-2026"); // load by name
|
|
79
|
+
const all = wallet.list(); // list all wallets
|
|
80
|
+
|
|
81
|
+
for (const w of all) {
|
|
82
|
+
const bal = await w.checkBalance();
|
|
83
|
+
console.log(`${w.name}: ${w.address} — ${bal} USDC`);
|
|
84
|
+
}
|
|
85
|
+
```
|
|
51
86
|
|
|
52
87
|
## Compute
|
|
53
88
|
|
|
54
|
-
Run sandboxed code via AutEng's x402 compute endpoint:
|
|
89
|
+
Run sandboxed code via AutEng's x402 compute endpoint. Pass a wallet to pay for execution:
|
|
55
90
|
|
|
56
91
|
```typescript
|
|
57
|
-
import { compute } from '@auteng/agent-utils';
|
|
92
|
+
import { wallet, compute } from '@auteng/agent-utils';
|
|
93
|
+
|
|
94
|
+
const w = await wallet.create({ name: "compute-budget" });
|
|
58
95
|
|
|
59
96
|
const result = await compute.run({
|
|
60
97
|
code: 'print("hello world")',
|
|
61
98
|
stack: 'python', // 'python' | 'node'
|
|
62
99
|
size: 'small', // 'small' | 'med' | 'large'
|
|
100
|
+
wallet: w,
|
|
63
101
|
});
|
|
64
102
|
console.log(result.stdout); // "hello world\n"
|
|
65
103
|
```
|
|
66
104
|
|
|
67
105
|
### Pricing
|
|
68
106
|
|
|
107
|
+
| Size | vCPU | RAM | Base price | Per second |
|
|
108
|
+
|-------|------|-------|-----------|------------|
|
|
109
|
+
| small | 2 | 1 GB | $0.002 | $0.00005 |
|
|
110
|
+
| med | 4 | 4 GB | $0.008 | $0.00012 |
|
|
111
|
+
| large | 8 | 16 GB | $0.03 | $0.00025 |
|
|
112
|
+
|
|
69
113
|
```typescript
|
|
70
|
-
compute.pricing();
|
|
71
|
-
// { small: { base_price_usd: 0.002, ... }, med: { ... }, large: { ... } }
|
|
114
|
+
compute.pricing(); // returns full pricing table
|
|
72
115
|
```
|
|
73
116
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
117
|
+
## Development
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
npm install # install dependencies
|
|
121
|
+
npm run build # build CJS/ESM/DTS to dist/
|
|
122
|
+
npm test # run unit + integration tests
|
|
123
|
+
npm run test:watch # run tests in watch mode
|
|
124
|
+
```
|
|
79
125
|
|
|
80
126
|
## License
|
|
81
127
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
import { PrivateKeyAccount } from 'viem';
|
|
2
|
+
|
|
1
3
|
type Network = "base" | "base-sepolia";
|
|
2
|
-
interface
|
|
3
|
-
/**
|
|
4
|
-
|
|
4
|
+
interface CreateWalletOptions {
|
|
5
|
+
/** Wallet identifier. Default: "default" */
|
|
6
|
+
name?: string;
|
|
5
7
|
/** Network to use. Default: `base` */
|
|
6
8
|
network?: Network;
|
|
7
9
|
/** Custom RPC endpoint. Default: public Base RPC */
|
|
8
10
|
rpcUrl?: string;
|
|
11
|
+
/** Base directory for wallet storage. Default: ".auteng/wallets" */
|
|
12
|
+
walletsDir?: string;
|
|
9
13
|
}
|
|
14
|
+
/** @deprecated Use CreateWalletOptions instead */
|
|
15
|
+
type WalletConfig = CreateWalletOptions;
|
|
10
16
|
interface WaitForFundingOptions {
|
|
11
17
|
/** Poll interval in milliseconds. Default: 10000 (10s) */
|
|
12
18
|
pollInterval?: number;
|
|
@@ -14,14 +20,22 @@ interface WaitForFundingOptions {
|
|
|
14
20
|
timeout?: number;
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
declare
|
|
18
|
-
|
|
19
|
-
* Create a new EVM wallet or load an existing one from disk.
|
|
20
|
-
* Idempotent: if the wallet file already exists, loads it.
|
|
21
|
-
*/
|
|
22
|
-
create(opts?: WalletConfig): Promise<void>;
|
|
23
|
-
/** The wallet's public address. Throws if not created. */
|
|
23
|
+
declare class Wallet {
|
|
24
|
+
readonly name: string;
|
|
24
25
|
readonly address: `0x${string}`;
|
|
26
|
+
readonly network: Network;
|
|
27
|
+
private _account;
|
|
28
|
+
private _privateKey;
|
|
29
|
+
private _rpcUrl;
|
|
30
|
+
private _paymentFetch;
|
|
31
|
+
constructor(params: {
|
|
32
|
+
name: string;
|
|
33
|
+
account: PrivateKeyAccount;
|
|
34
|
+
privateKey: `0x${string}`;
|
|
35
|
+
network: Network;
|
|
36
|
+
rpcUrl?: string;
|
|
37
|
+
paymentFetch: typeof globalThis.fetch;
|
|
38
|
+
});
|
|
25
39
|
/** Check USDC balance on Base. Returns balance in minor units (6 decimals). */
|
|
26
40
|
checkBalance(): Promise<bigint>;
|
|
27
41
|
/**
|
|
@@ -35,6 +49,23 @@ declare const wallet: {
|
|
|
35
49
|
* and retries the request with payment headers.
|
|
36
50
|
*/
|
|
37
51
|
fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
declare const wallet: {
|
|
55
|
+
/**
|
|
56
|
+
* Create a new named wallet or load an existing one from disk.
|
|
57
|
+
* Idempotent: if a wallet with this name already exists, returns it.
|
|
58
|
+
*/
|
|
59
|
+
create(opts?: CreateWalletOptions): Promise<Wallet>;
|
|
60
|
+
/**
|
|
61
|
+
* Retrieve a previously-created wallet by name.
|
|
62
|
+
* Loads from disk if not in memory. Throws if not found.
|
|
63
|
+
*/
|
|
64
|
+
get(name: string): Wallet;
|
|
65
|
+
/** List all persisted wallets. */
|
|
66
|
+
list(): Wallet[];
|
|
67
|
+
/** @internal Clear in-memory cache and reset wallets dir. For testing only. */
|
|
68
|
+
_reset(): void;
|
|
38
69
|
};
|
|
39
70
|
|
|
40
71
|
type Stack = "python" | "node";
|
|
@@ -44,6 +75,8 @@ interface ComputeRequest {
|
|
|
44
75
|
code: string;
|
|
45
76
|
/** Runtime stack: 'python' (3.14) or 'node' (24 LTS) */
|
|
46
77
|
stack: Stack;
|
|
78
|
+
/** The wallet to pay from */
|
|
79
|
+
wallet: Wallet;
|
|
47
80
|
/** Sandbox size. Default: 'small' */
|
|
48
81
|
size?: Size;
|
|
49
82
|
/** Execution timeout in seconds. Default: per-size default */
|
|
@@ -81,4 +114,4 @@ declare const compute: {
|
|
|
81
114
|
setEndpoint(url: string): void;
|
|
82
115
|
};
|
|
83
116
|
|
|
84
|
-
export { type ComputeRequest, type ComputeResponse, type Network, type PricingTier, type Size, type Stack, type WaitForFundingOptions, type WalletConfig, compute, wallet };
|
|
117
|
+
export { type ComputeRequest, type ComputeResponse, type CreateWalletOptions, type Network, type PricingTier, type Size, type Stack, type WaitForFundingOptions, Wallet, type WalletConfig, compute, wallet };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
import { PrivateKeyAccount } from 'viem';
|
|
2
|
+
|
|
1
3
|
type Network = "base" | "base-sepolia";
|
|
2
|
-
interface
|
|
3
|
-
/**
|
|
4
|
-
|
|
4
|
+
interface CreateWalletOptions {
|
|
5
|
+
/** Wallet identifier. Default: "default" */
|
|
6
|
+
name?: string;
|
|
5
7
|
/** Network to use. Default: `base` */
|
|
6
8
|
network?: Network;
|
|
7
9
|
/** Custom RPC endpoint. Default: public Base RPC */
|
|
8
10
|
rpcUrl?: string;
|
|
11
|
+
/** Base directory for wallet storage. Default: ".auteng/wallets" */
|
|
12
|
+
walletsDir?: string;
|
|
9
13
|
}
|
|
14
|
+
/** @deprecated Use CreateWalletOptions instead */
|
|
15
|
+
type WalletConfig = CreateWalletOptions;
|
|
10
16
|
interface WaitForFundingOptions {
|
|
11
17
|
/** Poll interval in milliseconds. Default: 10000 (10s) */
|
|
12
18
|
pollInterval?: number;
|
|
@@ -14,14 +20,22 @@ interface WaitForFundingOptions {
|
|
|
14
20
|
timeout?: number;
|
|
15
21
|
}
|
|
16
22
|
|
|
17
|
-
declare
|
|
18
|
-
|
|
19
|
-
* Create a new EVM wallet or load an existing one from disk.
|
|
20
|
-
* Idempotent: if the wallet file already exists, loads it.
|
|
21
|
-
*/
|
|
22
|
-
create(opts?: WalletConfig): Promise<void>;
|
|
23
|
-
/** The wallet's public address. Throws if not created. */
|
|
23
|
+
declare class Wallet {
|
|
24
|
+
readonly name: string;
|
|
24
25
|
readonly address: `0x${string}`;
|
|
26
|
+
readonly network: Network;
|
|
27
|
+
private _account;
|
|
28
|
+
private _privateKey;
|
|
29
|
+
private _rpcUrl;
|
|
30
|
+
private _paymentFetch;
|
|
31
|
+
constructor(params: {
|
|
32
|
+
name: string;
|
|
33
|
+
account: PrivateKeyAccount;
|
|
34
|
+
privateKey: `0x${string}`;
|
|
35
|
+
network: Network;
|
|
36
|
+
rpcUrl?: string;
|
|
37
|
+
paymentFetch: typeof globalThis.fetch;
|
|
38
|
+
});
|
|
25
39
|
/** Check USDC balance on Base. Returns balance in minor units (6 decimals). */
|
|
26
40
|
checkBalance(): Promise<bigint>;
|
|
27
41
|
/**
|
|
@@ -35,6 +49,23 @@ declare const wallet: {
|
|
|
35
49
|
* and retries the request with payment headers.
|
|
36
50
|
*/
|
|
37
51
|
fetch(input: string | URL | Request, init?: RequestInit): Promise<Response>;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
declare const wallet: {
|
|
55
|
+
/**
|
|
56
|
+
* Create a new named wallet or load an existing one from disk.
|
|
57
|
+
* Idempotent: if a wallet with this name already exists, returns it.
|
|
58
|
+
*/
|
|
59
|
+
create(opts?: CreateWalletOptions): Promise<Wallet>;
|
|
60
|
+
/**
|
|
61
|
+
* Retrieve a previously-created wallet by name.
|
|
62
|
+
* Loads from disk if not in memory. Throws if not found.
|
|
63
|
+
*/
|
|
64
|
+
get(name: string): Wallet;
|
|
65
|
+
/** List all persisted wallets. */
|
|
66
|
+
list(): Wallet[];
|
|
67
|
+
/** @internal Clear in-memory cache and reset wallets dir. For testing only. */
|
|
68
|
+
_reset(): void;
|
|
38
69
|
};
|
|
39
70
|
|
|
40
71
|
type Stack = "python" | "node";
|
|
@@ -44,6 +75,8 @@ interface ComputeRequest {
|
|
|
44
75
|
code: string;
|
|
45
76
|
/** Runtime stack: 'python' (3.14) or 'node' (24 LTS) */
|
|
46
77
|
stack: Stack;
|
|
78
|
+
/** The wallet to pay from */
|
|
79
|
+
wallet: Wallet;
|
|
47
80
|
/** Sandbox size. Default: 'small' */
|
|
48
81
|
size?: Size;
|
|
49
82
|
/** Execution timeout in seconds. Default: per-size default */
|
|
@@ -81,4 +114,4 @@ declare const compute: {
|
|
|
81
114
|
setEndpoint(url: string): void;
|
|
82
115
|
};
|
|
83
116
|
|
|
84
|
-
export { type ComputeRequest, type ComputeResponse, type Network, type PricingTier, type Size, type Stack, type WaitForFundingOptions, type WalletConfig, compute, wallet };
|
|
117
|
+
export { type ComputeRequest, type ComputeResponse, type CreateWalletOptions, type Network, type PricingTier, type Size, type Stack, type WaitForFundingOptions, Wallet, type WalletConfig, compute, wallet };
|
package/dist/index.js
CHANGED
|
@@ -20,6 +20,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
20
20
|
// src/index.ts
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
|
+
Wallet: () => Wallet,
|
|
23
24
|
compute: () => compute,
|
|
24
25
|
wallet: () => wallet
|
|
25
26
|
});
|
|
@@ -43,6 +44,14 @@ function loadKeypair(privateKey) {
|
|
|
43
44
|
// src/wallet/storage.ts
|
|
44
45
|
var import_node_fs = require("fs");
|
|
45
46
|
var import_node_path = require("path");
|
|
47
|
+
var VALID_NAME = /^[a-z0-9_-]+$/;
|
|
48
|
+
function validateWalletName(name) {
|
|
49
|
+
if (!VALID_NAME.test(name)) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Invalid wallet name "${name}". Use lowercase letters, numbers, hyphens, and underscores only.`
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
46
55
|
function readWalletFile(path) {
|
|
47
56
|
if (!(0, import_node_fs.existsSync)(path)) return null;
|
|
48
57
|
const raw = (0, import_node_fs.readFileSync)(path, "utf-8");
|
|
@@ -54,6 +63,45 @@ function writeWalletFile(path, data) {
|
|
|
54
63
|
mode: 384
|
|
55
64
|
});
|
|
56
65
|
}
|
|
66
|
+
function listWalletFiles(dir) {
|
|
67
|
+
const resolved = (0, import_node_path.resolve)(dir);
|
|
68
|
+
if (!(0, import_node_fs.existsSync)(resolved)) return [];
|
|
69
|
+
return (0, import_node_fs.readdirSync)(resolved).filter((f) => f.endsWith(".json")).map((f) => f.replace(/\.json$/, ""));
|
|
70
|
+
}
|
|
71
|
+
function migrateLegacyWallet(walletsDir) {
|
|
72
|
+
const legacyPath = (0, import_node_path.resolve)(walletsDir, "..", "wallet.json");
|
|
73
|
+
const newPath = (0, import_node_path.join)((0, import_node_path.resolve)(walletsDir), "default.json");
|
|
74
|
+
if ((0, import_node_fs.existsSync)(legacyPath) && !(0, import_node_fs.existsSync)(newPath)) {
|
|
75
|
+
const data = readWalletFile(legacyPath);
|
|
76
|
+
if (data) {
|
|
77
|
+
(0, import_node_fs.mkdirSync)((0, import_node_path.resolve)(walletsDir), { recursive: true });
|
|
78
|
+
(0, import_node_fs.copyFileSync)(legacyPath, newPath);
|
|
79
|
+
return data;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return null;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// src/x402/index.ts
|
|
86
|
+
var import_client = require("@x402/core/client");
|
|
87
|
+
var import_client2 = require("@x402/evm/exact/client");
|
|
88
|
+
var import_evm = require("@x402/evm");
|
|
89
|
+
var import_fetch = require("@x402/fetch");
|
|
90
|
+
var import_accounts2 = require("viem/accounts");
|
|
91
|
+
var import_viem = require("viem");
|
|
92
|
+
var import_chains = require("viem/chains");
|
|
93
|
+
function createPaymentFetch(privateKey, network = "base", rpcUrl) {
|
|
94
|
+
const account = (0, import_accounts2.privateKeyToAccount)(privateKey);
|
|
95
|
+
const chain = network === "base" ? import_chains.base : import_chains.baseSepolia;
|
|
96
|
+
const publicClient = (0, import_viem.createPublicClient)({
|
|
97
|
+
chain,
|
|
98
|
+
transport: (0, import_viem.http)(rpcUrl)
|
|
99
|
+
});
|
|
100
|
+
const signer = (0, import_evm.toClientEvmSigner)(account, publicClient);
|
|
101
|
+
const client = new import_client.x402Client();
|
|
102
|
+
(0, import_client2.registerExactEvmScheme)(client, { signer });
|
|
103
|
+
return (0, import_fetch.wrapFetchWithPayment)(fetch, client);
|
|
104
|
+
}
|
|
57
105
|
|
|
58
106
|
// src/wallet/types.ts
|
|
59
107
|
var NETWORK_CONFIG = {
|
|
@@ -92,103 +140,138 @@ async function getUsdcBalance(address, network, rpcUrl) {
|
|
|
92
140
|
return BigInt(json.result ?? "0x0");
|
|
93
141
|
}
|
|
94
142
|
|
|
95
|
-
// src/
|
|
96
|
-
var
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
(0, import_client2.registerExactEvmScheme)(client, { signer });
|
|
113
|
-
return (0, import_fetch.wrapFetchWithPayment)(fetch, client);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
// src/wallet/index.ts
|
|
117
|
-
var _account = null;
|
|
118
|
-
var _privateKey = null;
|
|
119
|
-
var _network = "base";
|
|
120
|
-
var _rpcUrl;
|
|
121
|
-
var _paymentFetch = null;
|
|
122
|
-
function ensureCreated() {
|
|
123
|
-
if (!_account) {
|
|
124
|
-
throw new Error("Wallet not initialized. Call wallet.create() first.");
|
|
143
|
+
// src/wallet/wallet.ts
|
|
144
|
+
var Wallet = class {
|
|
145
|
+
name;
|
|
146
|
+
address;
|
|
147
|
+
network;
|
|
148
|
+
_account;
|
|
149
|
+
_privateKey;
|
|
150
|
+
_rpcUrl;
|
|
151
|
+
_paymentFetch;
|
|
152
|
+
constructor(params) {
|
|
153
|
+
this.name = params.name;
|
|
154
|
+
this._account = params.account;
|
|
155
|
+
this._privateKey = params.privateKey;
|
|
156
|
+
this.address = params.account.address;
|
|
157
|
+
this.network = params.network;
|
|
158
|
+
this._rpcUrl = params.rpcUrl;
|
|
159
|
+
this._paymentFetch = params.paymentFetch;
|
|
125
160
|
}
|
|
126
|
-
}
|
|
127
|
-
var wallet = {
|
|
128
|
-
/**
|
|
129
|
-
* Create a new EVM wallet or load an existing one from disk.
|
|
130
|
-
* Idempotent: if the wallet file already exists, loads it.
|
|
131
|
-
*/
|
|
132
|
-
async create(opts) {
|
|
133
|
-
const keyPath = (0, import_node_path2.resolve)(opts?.keyPath ?? ".auteng/wallet.json");
|
|
134
|
-
_network = opts?.network ?? "base";
|
|
135
|
-
_rpcUrl = opts?.rpcUrl;
|
|
136
|
-
const existing = readWalletFile(keyPath);
|
|
137
|
-
if (existing) {
|
|
138
|
-
_privateKey = existing.privateKey;
|
|
139
|
-
const { account } = loadKeypair(existing.privateKey);
|
|
140
|
-
_account = account;
|
|
141
|
-
_network = existing.network;
|
|
142
|
-
} else {
|
|
143
|
-
const { privateKey, account } = createKeypair();
|
|
144
|
-
_privateKey = privateKey;
|
|
145
|
-
_account = account;
|
|
146
|
-
writeWalletFile(keyPath, {
|
|
147
|
-
privateKey,
|
|
148
|
-
address: account.address,
|
|
149
|
-
network: _network
|
|
150
|
-
});
|
|
151
|
-
}
|
|
152
|
-
_paymentFetch = createPaymentFetch(_privateKey, _network, _rpcUrl);
|
|
153
|
-
},
|
|
154
|
-
/** The wallet's public address. Throws if not created. */
|
|
155
|
-
get address() {
|
|
156
|
-
ensureCreated();
|
|
157
|
-
return _account.address;
|
|
158
|
-
},
|
|
159
161
|
/** Check USDC balance on Base. Returns balance in minor units (6 decimals). */
|
|
160
162
|
async checkBalance() {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
},
|
|
163
|
+
return getUsdcBalance(this._account.address, this.network, this._rpcUrl);
|
|
164
|
+
}
|
|
164
165
|
/**
|
|
165
166
|
* Poll until USDC balance >= minAmount.
|
|
166
167
|
* @param minAmount - minimum USDC balance in minor units (6 decimals)
|
|
167
168
|
*/
|
|
168
169
|
async waitForFunding(minAmount, opts) {
|
|
169
|
-
ensureCreated();
|
|
170
170
|
const interval = opts?.pollInterval ?? 1e4;
|
|
171
171
|
const deadline = opts?.timeout ? Date.now() + opts.timeout : null;
|
|
172
172
|
while (true) {
|
|
173
|
-
const balance = await getUsdcBalance(_account.address,
|
|
173
|
+
const balance = await getUsdcBalance(this._account.address, this.network, this._rpcUrl);
|
|
174
174
|
if (balance >= minAmount) return;
|
|
175
175
|
if (deadline && Date.now() >= deadline) {
|
|
176
176
|
throw new Error(`Funding timeout: balance ${balance} < required ${minAmount}`);
|
|
177
177
|
}
|
|
178
178
|
await new Promise((r) => setTimeout(r, interval));
|
|
179
179
|
}
|
|
180
|
-
}
|
|
180
|
+
}
|
|
181
181
|
/**
|
|
182
182
|
* Drop-in `fetch()` replacement that handles x402 payments automatically.
|
|
183
183
|
* If the server returns 402, the library signs an EIP-3009 authorization
|
|
184
184
|
* and retries the request with payment headers.
|
|
185
185
|
*/
|
|
186
186
|
async fetch(input, init) {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
187
|
+
return this._paymentFetch(input, init);
|
|
188
|
+
}
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// src/wallet/index.ts
|
|
192
|
+
var DEFAULT_WALLETS_DIR = ".auteng/wallets";
|
|
193
|
+
var _wallets = /* @__PURE__ */ new Map();
|
|
194
|
+
var _walletsDir = (0, import_node_path2.resolve)(DEFAULT_WALLETS_DIR);
|
|
195
|
+
var wallet = {
|
|
196
|
+
/**
|
|
197
|
+
* Create a new named wallet or load an existing one from disk.
|
|
198
|
+
* Idempotent: if a wallet with this name already exists, returns it.
|
|
199
|
+
*/
|
|
200
|
+
async create(opts) {
|
|
201
|
+
const name = opts?.name ?? "default";
|
|
202
|
+
validateWalletName(name);
|
|
203
|
+
if (_wallets.has(name)) return _wallets.get(name);
|
|
204
|
+
const dir = (0, import_node_path2.resolve)(opts?.walletsDir ?? DEFAULT_WALLETS_DIR);
|
|
205
|
+
_walletsDir = dir;
|
|
206
|
+
const filePath = (0, import_node_path2.join)(dir, `${name}.json`);
|
|
207
|
+
const network = opts?.network ?? "base";
|
|
208
|
+
const rpcUrl = opts?.rpcUrl;
|
|
209
|
+
let existing = readWalletFile(filePath);
|
|
210
|
+
if (!existing && name === "default") {
|
|
211
|
+
existing = migrateLegacyWallet(dir);
|
|
212
|
+
}
|
|
213
|
+
let privateKey;
|
|
214
|
+
let account;
|
|
215
|
+
if (existing) {
|
|
216
|
+
privateKey = existing.privateKey;
|
|
217
|
+
account = loadKeypair(existing.privateKey).account;
|
|
218
|
+
} else {
|
|
219
|
+
const kp = createKeypair();
|
|
220
|
+
privateKey = kp.privateKey;
|
|
221
|
+
account = kp.account;
|
|
222
|
+
writeWalletFile(filePath, {
|
|
223
|
+
privateKey,
|
|
224
|
+
address: account.address,
|
|
225
|
+
network
|
|
226
|
+
});
|
|
190
227
|
}
|
|
191
|
-
|
|
228
|
+
const effectiveNetwork = existing?.network ?? network;
|
|
229
|
+
const paymentFetch = createPaymentFetch(privateKey, effectiveNetwork, rpcUrl);
|
|
230
|
+
const w = new Wallet({
|
|
231
|
+
name,
|
|
232
|
+
account,
|
|
233
|
+
privateKey,
|
|
234
|
+
network: effectiveNetwork,
|
|
235
|
+
rpcUrl,
|
|
236
|
+
paymentFetch
|
|
237
|
+
});
|
|
238
|
+
_wallets.set(name, w);
|
|
239
|
+
return w;
|
|
240
|
+
},
|
|
241
|
+
/**
|
|
242
|
+
* Retrieve a previously-created wallet by name.
|
|
243
|
+
* Loads from disk if not in memory. Throws if not found.
|
|
244
|
+
*/
|
|
245
|
+
get(name) {
|
|
246
|
+
validateWalletName(name);
|
|
247
|
+
if (_wallets.has(name)) return _wallets.get(name);
|
|
248
|
+
const filePath = (0, import_node_path2.join)(_walletsDir, `${name}.json`);
|
|
249
|
+
const data = readWalletFile(filePath);
|
|
250
|
+
if (!data) throw new Error(`Wallet "${name}" not found`);
|
|
251
|
+
const { account } = loadKeypair(data.privateKey);
|
|
252
|
+
const paymentFetch = createPaymentFetch(data.privateKey, data.network);
|
|
253
|
+
const w = new Wallet({
|
|
254
|
+
name,
|
|
255
|
+
account,
|
|
256
|
+
privateKey: data.privateKey,
|
|
257
|
+
network: data.network,
|
|
258
|
+
paymentFetch
|
|
259
|
+
});
|
|
260
|
+
_wallets.set(name, w);
|
|
261
|
+
return w;
|
|
262
|
+
},
|
|
263
|
+
/** List all persisted wallets. */
|
|
264
|
+
list() {
|
|
265
|
+
const names = listWalletFiles(_walletsDir);
|
|
266
|
+
return names.map((n) => {
|
|
267
|
+
if (_wallets.has(n)) return _wallets.get(n);
|
|
268
|
+
return wallet.get(n);
|
|
269
|
+
});
|
|
270
|
+
},
|
|
271
|
+
/** @internal Clear in-memory cache and reset wallets dir. For testing only. */
|
|
272
|
+
_reset() {
|
|
273
|
+
_wallets.clear();
|
|
274
|
+
_walletsDir = (0, import_node_path2.resolve)(DEFAULT_WALLETS_DIR);
|
|
192
275
|
}
|
|
193
276
|
};
|
|
194
277
|
|
|
@@ -242,7 +325,10 @@ var compute = {
|
|
|
242
325
|
},
|
|
243
326
|
...request.files != null && { files: request.files }
|
|
244
327
|
};
|
|
245
|
-
|
|
328
|
+
if (!request.wallet) {
|
|
329
|
+
throw new Error("compute.run: 'wallet' is required");
|
|
330
|
+
}
|
|
331
|
+
const response = await request.wallet.fetch(_endpoint, {
|
|
246
332
|
method: "POST",
|
|
247
333
|
headers: { "Content-Type": "application/json" },
|
|
248
334
|
body: JSON.stringify(body)
|
|
@@ -267,6 +353,7 @@ var compute = {
|
|
|
267
353
|
};
|
|
268
354
|
// Annotate the CommonJS export names for ESM import in node:
|
|
269
355
|
0 && (module.exports = {
|
|
356
|
+
Wallet,
|
|
270
357
|
compute,
|
|
271
358
|
wallet
|
|
272
359
|
});
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/wallet/index.ts","../src/wallet/keypair.ts","../src/wallet/storage.ts","../src/wallet/types.ts","../src/wallet/balance.ts","../src/x402/index.ts","../src/compute/index.ts"],"sourcesContent":["export { wallet } from \"./wallet/index.js\"\nexport { compute } from \"./compute/index.js\"\n\nexport type { WalletConfig, WaitForFundingOptions, Network } from \"./wallet/types.js\"\nexport type { ComputeRequest, ComputeResponse, PricingTier, Stack, Size } from \"./compute/types.js\"\n","import { resolve } from \"node:path\"\nimport type { PrivateKeyAccount } from \"viem\"\nimport { createKeypair, loadKeypair } from \"./keypair.js\"\nimport { readWalletFile, writeWalletFile } from \"./storage.js\"\nimport { getUsdcBalance } from \"./balance.js\"\nimport { createPaymentFetch } from \"../x402/index.js\"\nimport type { Network, WalletConfig, WaitForFundingOptions } from \"./types.js\"\n\n// --- Internal state ---\n\nlet _account: PrivateKeyAccount | null = null\nlet _privateKey: `0x${string}` | null = null\nlet _network: Network = \"base\"\nlet _rpcUrl: string | undefined\nlet _paymentFetch: typeof globalThis.fetch | null = null\n\nfunction ensureCreated(): void {\n if (!_account) {\n throw new Error(\"Wallet not initialized. Call wallet.create() first.\")\n }\n}\n\n// --- Public API ---\n\nexport const wallet = {\n /**\n * Create a new EVM wallet or load an existing one from disk.\n * Idempotent: if the wallet file already exists, loads it.\n */\n async create(opts?: WalletConfig): Promise<void> {\n const keyPath = resolve(opts?.keyPath ?? \".auteng/wallet.json\")\n _network = opts?.network ?? \"base\"\n _rpcUrl = opts?.rpcUrl\n\n const existing = readWalletFile(keyPath)\n if (existing) {\n _privateKey = existing.privateKey\n const { account } = loadKeypair(existing.privateKey)\n _account = account\n _network = existing.network\n } else {\n const { privateKey, account } = createKeypair()\n _privateKey = privateKey\n _account = account\n writeWalletFile(keyPath, {\n privateKey,\n address: account.address,\n network: _network,\n })\n }\n\n _paymentFetch = createPaymentFetch(_privateKey!, _network, _rpcUrl)\n },\n\n /** The wallet's public address. Throws if not created. */\n get address(): `0x${string}` {\n ensureCreated()\n return _account!.address\n },\n\n /** Check USDC balance on Base. Returns balance in minor units (6 decimals). */\n async checkBalance(): Promise<bigint> {\n ensureCreated()\n return getUsdcBalance(_account!.address, _network, _rpcUrl)\n },\n\n /**\n * Poll until USDC balance >= minAmount.\n * @param minAmount - minimum USDC balance in minor units (6 decimals)\n */\n async waitForFunding(minAmount: bigint, opts?: WaitForFundingOptions): Promise<void> {\n ensureCreated()\n const interval = opts?.pollInterval ?? 10_000\n const deadline = opts?.timeout ? Date.now() + opts.timeout : null\n\n while (true) {\n const balance = await getUsdcBalance(_account!.address, _network, _rpcUrl)\n if (balance >= minAmount) return\n\n if (deadline && Date.now() >= deadline) {\n throw new Error(`Funding timeout: balance ${balance} < required ${minAmount}`)\n }\n\n await new Promise((r) => setTimeout(r, interval))\n }\n },\n\n /**\n * Drop-in `fetch()` replacement that handles x402 payments automatically.\n * If the server returns 402, the library signs an EIP-3009 authorization\n * and retries the request with payment headers.\n */\n async fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> {\n ensureCreated()\n if (!_paymentFetch) {\n throw new Error(\"Payment layer not initialized\")\n }\n return _paymentFetch(input, init)\n },\n}\n","import { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\"\nimport type { PrivateKeyAccount } from \"viem\"\n\nexport function createKeypair(): {\n privateKey: `0x${string}`\n account: PrivateKeyAccount\n} {\n const privateKey = generatePrivateKey()\n const account = privateKeyToAccount(privateKey)\n return { privateKey, account }\n}\n\nexport function loadKeypair(privateKey: `0x${string}`): {\n account: PrivateKeyAccount\n} {\n const account = privateKeyToAccount(privateKey)\n return { account }\n}\n","import { mkdirSync, readFileSync, writeFileSync, existsSync } from \"node:fs\"\nimport { dirname } from \"node:path\"\nimport type { WalletFile } from \"./types.js\"\n\nexport function readWalletFile(path: string): WalletFile | null {\n if (!existsSync(path)) return null\n const raw = readFileSync(path, \"utf-8\")\n return JSON.parse(raw) as WalletFile\n}\n\nexport function writeWalletFile(path: string, data: WalletFile): void {\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, JSON.stringify(data, null, 2) + \"\\n\", {\n mode: 0o600,\n })\n}\n","export type Network = \"base\" | \"base-sepolia\"\n\nexport interface WalletConfig {\n /** Path to store the wallet keypair. Default: `.auteng/wallet.json` */\n keyPath?: string\n /** Network to use. Default: `base` */\n network?: Network\n /** Custom RPC endpoint. Default: public Base RPC */\n rpcUrl?: string\n}\n\nexport interface WalletFile {\n privateKey: `0x${string}`\n address: `0x${string}`\n network: Network\n}\n\nexport interface WaitForFundingOptions {\n /** Poll interval in milliseconds. Default: 10000 (10s) */\n pollInterval?: number\n /** Timeout in milliseconds. Default: none (waits forever) */\n timeout?: number\n}\n\nexport const NETWORK_CONFIG: Record<Network, { chainId: number; usdcAddress: `0x${string}`; rpcUrl: string }> = {\n base: {\n chainId: 8453,\n usdcAddress: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n rpcUrl: \"https://mainnet.base.org\",\n },\n \"base-sepolia\": {\n chainId: 84532,\n usdcAddress: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n rpcUrl: \"https://sepolia.base.org\",\n },\n}\n","import type { Network } from \"./types.js\"\nimport { NETWORK_CONFIG } from \"./types.js\"\n\n/**\n * Read USDC balance for `address` via a direct `eth_call` to the USDC\n * contract's `balanceOf(address)` function. No viem client needed — just\n * a plain JSON-RPC POST.\n */\nexport async function getUsdcBalance(address: `0x${string}`, network: Network, rpcUrl?: string): Promise<bigint> {\n const config = NETWORK_CONFIG[network]\n const url = rpcUrl ?? config.rpcUrl\n\n // balanceOf(address) selector = 0x70a08231\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, \"0\")\n const data = `0x70a08231${paddedAddress}`\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_call\",\n params: [{ to: config.usdcAddress, data }, \"latest\"],\n }),\n })\n\n const json = (await res.json()) as { result?: string; error?: unknown }\n if (json.error) {\n throw new Error(`RPC error: ${JSON.stringify(json.error)}`)\n }\n return BigInt(json.result ?? \"0x0\")\n}\n","import { x402Client } from \"@x402/core/client\"\nimport { registerExactEvmScheme } from \"@x402/evm/exact/client\"\nimport { toClientEvmSigner } from \"@x402/evm\"\nimport { wrapFetchWithPayment } from \"@x402/fetch\"\nimport { privateKeyToAccount } from \"viem/accounts\"\nimport { createPublicClient, http } from \"viem\"\nimport { base, baseSepolia } from \"viem/chains\"\nimport type { Network } from \"../wallet/types.js\"\n\n/**\n * Create a fetch function that automatically handles x402 payments.\n * When the server returns 402, the SDK signs an EIP-3009 authorization\n * using the provided private key and retries with payment headers.\n */\nexport function createPaymentFetch(\n privateKey: `0x${string}`,\n network: Network = \"base\",\n rpcUrl?: string\n): typeof globalThis.fetch {\n const account = privateKeyToAccount(privateKey)\n const chain = network === \"base\" ? base : baseSepolia\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n })\n const signer = toClientEvmSigner(account, publicClient)\n\n const client = new x402Client()\n registerExactEvmScheme(client, { signer })\n return wrapFetchWithPayment(fetch, client)\n}\n","import { wallet } from \"../wallet/index.js\"\nimport type { ComputeRequest, ComputeResponse, PricingTier, Size } from \"./types.js\"\n\nconst DEFAULT_ENDPOINT = \"https://x402.auteng.ai/api/x402/compute\"\n\nlet _endpoint = DEFAULT_ENDPOINT\n\nconst PRICING: Record<Size, PricingTier> = {\n small: {\n vcpu: 2,\n ram_gb: 1,\n default_timeout_s: 30,\n max_timeout_s: 300,\n base_price_usd: 0.002,\n per_second_usd: 0.00005,\n },\n med: {\n vcpu: 4,\n ram_gb: 4,\n default_timeout_s: 60,\n max_timeout_s: 600,\n base_price_usd: 0.008,\n per_second_usd: 0.00012,\n },\n large: {\n vcpu: 8,\n ram_gb: 16,\n default_timeout_s: 120,\n max_timeout_s: 3600,\n base_price_usd: 0.03,\n per_second_usd: 0.00025,\n },\n}\n\nexport const compute = {\n /**\n * Execute sandboxed code via AutEng's x402 compute endpoint.\n * Payment is handled automatically via the wallet's x402 layer.\n */\n async run(request: ComputeRequest): Promise<ComputeResponse> {\n if (!request.code) {\n throw new Error(\"compute.run: 'code' is required\")\n }\n if (!request.stack) {\n throw new Error(\"compute.run: 'stack' is required\")\n }\n\n const body = {\n code: request.code,\n stack: request.stack,\n size: request.size ?? \"small\",\n ...(request.timeout_seconds != null && {\n timeout_seconds: request.timeout_seconds,\n }),\n ...(request.files != null && { files: request.files }),\n }\n\n const response = await wallet.fetch(_endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\")\n throw new Error(`Compute request failed (${response.status}): ${text}`)\n }\n\n return (await response.json()) as ComputeResponse\n },\n\n /** Returns the pricing table for all compute sizes. */\n pricing(): Record<Size, PricingTier> {\n return { ...PRICING }\n },\n\n /**\n * Override the compute endpoint URL.\n * Default: https://x402.auteng.ai/api/x402/compute\n */\n setEndpoint(url: string): void {\n _endpoint = url\n },\n}\n"],"mappings":"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","names":["import_node_path","import_client","import_accounts"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/wallet/index.ts","../src/wallet/keypair.ts","../src/wallet/storage.ts","../src/x402/index.ts","../src/wallet/types.ts","../src/wallet/balance.ts","../src/wallet/wallet.ts","../src/compute/index.ts"],"sourcesContent":["export { wallet } from \"./wallet/index.js\"\nexport { Wallet } from \"./wallet/wallet.js\"\nexport { compute } from \"./compute/index.js\"\n\nexport type { CreateWalletOptions, WalletConfig, WaitForFundingOptions, Network } from \"./wallet/types.js\"\nexport type { ComputeRequest, ComputeResponse, PricingTier, Stack, Size } from \"./compute/types.js\"\n","import { join, resolve } from \"node:path\"\nimport { createKeypair, loadKeypair } from \"./keypair.js\"\nimport { readWalletFile, writeWalletFile, listWalletFiles, migrateLegacyWallet, validateWalletName } from \"./storage.js\"\nimport { createPaymentFetch } from \"../x402/index.js\"\nimport { Wallet } from \"./wallet.js\"\nimport type { CreateWalletOptions } from \"./types.js\"\n\nconst DEFAULT_WALLETS_DIR = \".auteng/wallets\"\n\nconst _wallets = new Map<string, Wallet>()\nlet _walletsDir = resolve(DEFAULT_WALLETS_DIR)\n\nexport const wallet = {\n /**\n * Create a new named wallet or load an existing one from disk.\n * Idempotent: if a wallet with this name already exists, returns it.\n */\n async create(opts?: CreateWalletOptions): Promise<Wallet> {\n const name = opts?.name ?? \"default\"\n validateWalletName(name)\n\n if (_wallets.has(name)) return _wallets.get(name)!\n\n const dir = resolve(opts?.walletsDir ?? DEFAULT_WALLETS_DIR)\n _walletsDir = dir\n const filePath = join(dir, `${name}.json`)\n const network = opts?.network ?? \"base\"\n const rpcUrl = opts?.rpcUrl\n\n let existing = readWalletFile(filePath)\n\n if (!existing && name === \"default\") {\n existing = migrateLegacyWallet(dir)\n }\n\n let privateKey: `0x${string}`\n let account: ReturnType<typeof loadKeypair>[\"account\"]\n\n if (existing) {\n privateKey = existing.privateKey\n account = loadKeypair(existing.privateKey).account\n } else {\n const kp = createKeypair()\n privateKey = kp.privateKey\n account = kp.account\n writeWalletFile(filePath, {\n privateKey,\n address: account.address,\n network,\n })\n }\n\n const effectiveNetwork = existing?.network ?? network\n const paymentFetch = createPaymentFetch(privateKey, effectiveNetwork, rpcUrl)\n const w = new Wallet({\n name,\n account,\n privateKey,\n network: effectiveNetwork,\n rpcUrl,\n paymentFetch,\n })\n _wallets.set(name, w)\n return w\n },\n\n /**\n * Retrieve a previously-created wallet by name.\n * Loads from disk if not in memory. Throws if not found.\n */\n get(name: string): Wallet {\n validateWalletName(name)\n\n if (_wallets.has(name)) return _wallets.get(name)!\n\n const filePath = join(_walletsDir, `${name}.json`)\n const data = readWalletFile(filePath)\n if (!data) throw new Error(`Wallet \"${name}\" not found`)\n\n const { account } = loadKeypair(data.privateKey)\n const paymentFetch = createPaymentFetch(data.privateKey, data.network)\n const w = new Wallet({\n name,\n account,\n privateKey: data.privateKey,\n network: data.network,\n paymentFetch,\n })\n _wallets.set(name, w)\n return w\n },\n\n /** List all persisted wallets. */\n list(): Wallet[] {\n const names = listWalletFiles(_walletsDir)\n return names.map((n) => {\n if (_wallets.has(n)) return _wallets.get(n)!\n return wallet.get(n)\n })\n },\n\n /** @internal Clear in-memory cache and reset wallets dir. For testing only. */\n _reset(): void {\n _wallets.clear()\n _walletsDir = resolve(DEFAULT_WALLETS_DIR)\n },\n}\n","import { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\"\nimport type { PrivateKeyAccount } from \"viem\"\n\nexport function createKeypair(): {\n privateKey: `0x${string}`\n account: PrivateKeyAccount\n} {\n const privateKey = generatePrivateKey()\n const account = privateKeyToAccount(privateKey)\n return { privateKey, account }\n}\n\nexport function loadKeypair(privateKey: `0x${string}`): {\n account: PrivateKeyAccount\n} {\n const account = privateKeyToAccount(privateKey)\n return { account }\n}\n","import { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync, copyFileSync } from \"node:fs\"\nimport { dirname, join, resolve } from \"node:path\"\nimport type { WalletFile } from \"./types.js\"\n\nconst VALID_NAME = /^[a-z0-9_-]+$/\n\nexport function validateWalletName(name: string): void {\n if (!VALID_NAME.test(name)) {\n throw new Error(\n `Invalid wallet name \"${name}\". Use lowercase letters, numbers, hyphens, and underscores only.`\n )\n }\n}\n\nexport function readWalletFile(path: string): WalletFile | null {\n if (!existsSync(path)) return null\n const raw = readFileSync(path, \"utf-8\")\n return JSON.parse(raw) as WalletFile\n}\n\nexport function writeWalletFile(path: string, data: WalletFile): void {\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, JSON.stringify(data, null, 2) + \"\\n\", {\n mode: 0o600,\n })\n}\n\nexport function listWalletFiles(dir: string): string[] {\n const resolved = resolve(dir)\n if (!existsSync(resolved)) return []\n return readdirSync(resolved)\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => f.replace(/\\.json$/, \"\"))\n}\n\nexport function migrateLegacyWallet(walletsDir: string): WalletFile | null {\n const legacyPath = resolve(walletsDir, \"..\", \"wallet.json\")\n const newPath = join(resolve(walletsDir), \"default.json\")\n if (existsSync(legacyPath) && !existsSync(newPath)) {\n const data = readWalletFile(legacyPath)\n if (data) {\n mkdirSync(resolve(walletsDir), { recursive: true })\n copyFileSync(legacyPath, newPath)\n return data\n }\n }\n return null\n}\n","import { x402Client } from \"@x402/core/client\"\nimport { registerExactEvmScheme } from \"@x402/evm/exact/client\"\nimport { toClientEvmSigner } from \"@x402/evm\"\nimport { wrapFetchWithPayment } from \"@x402/fetch\"\nimport { privateKeyToAccount } from \"viem/accounts\"\nimport { createPublicClient, http } from \"viem\"\nimport { base, baseSepolia } from \"viem/chains\"\nimport type { Network } from \"../wallet/types.js\"\n\n/**\n * Create a fetch function that automatically handles x402 payments.\n * When the server returns 402, the SDK signs an EIP-3009 authorization\n * using the provided private key and retries with payment headers.\n */\nexport function createPaymentFetch(\n privateKey: `0x${string}`,\n network: Network = \"base\",\n rpcUrl?: string\n): typeof globalThis.fetch {\n const account = privateKeyToAccount(privateKey)\n const chain = network === \"base\" ? base : baseSepolia\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n })\n const signer = toClientEvmSigner(account, publicClient)\n\n const client = new x402Client()\n registerExactEvmScheme(client, { signer })\n return wrapFetchWithPayment(fetch, client)\n}\n","export type Network = \"base\" | \"base-sepolia\"\n\nexport interface CreateWalletOptions {\n /** Wallet identifier. Default: \"default\" */\n name?: string\n /** Network to use. Default: `base` */\n network?: Network\n /** Custom RPC endpoint. Default: public Base RPC */\n rpcUrl?: string\n /** Base directory for wallet storage. Default: \".auteng/wallets\" */\n walletsDir?: string\n}\n\n/** @deprecated Use CreateWalletOptions instead */\nexport type WalletConfig = CreateWalletOptions\n\nexport interface WalletFile {\n privateKey: `0x${string}`\n address: `0x${string}`\n network: Network\n}\n\nexport interface WaitForFundingOptions {\n /** Poll interval in milliseconds. Default: 10000 (10s) */\n pollInterval?: number\n /** Timeout in milliseconds. Default: none (waits forever) */\n timeout?: number\n}\n\nexport const NETWORK_CONFIG: Record<Network, { chainId: number; usdcAddress: `0x${string}`; rpcUrl: string }> = {\n base: {\n chainId: 8453,\n usdcAddress: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n rpcUrl: \"https://mainnet.base.org\",\n },\n \"base-sepolia\": {\n chainId: 84532,\n usdcAddress: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n rpcUrl: \"https://sepolia.base.org\",\n },\n}\n","import type { Network } from \"./types.js\"\nimport { NETWORK_CONFIG } from \"./types.js\"\n\n/**\n * Read USDC balance for `address` via a direct `eth_call` to the USDC\n * contract's `balanceOf(address)` function. No viem client needed — just\n * a plain JSON-RPC POST.\n */\nexport async function getUsdcBalance(address: `0x${string}`, network: Network, rpcUrl?: string): Promise<bigint> {\n const config = NETWORK_CONFIG[network]\n const url = rpcUrl ?? config.rpcUrl\n\n // balanceOf(address) selector = 0x70a08231\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, \"0\")\n const data = `0x70a08231${paddedAddress}`\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_call\",\n params: [{ to: config.usdcAddress, data }, \"latest\"],\n }),\n })\n\n const json = (await res.json()) as { result?: string; error?: unknown }\n if (json.error) {\n throw new Error(`RPC error: ${JSON.stringify(json.error)}`)\n }\n return BigInt(json.result ?? \"0x0\")\n}\n","import type { PrivateKeyAccount } from \"viem\"\nimport { getUsdcBalance } from \"./balance.js\"\nimport type { Network, WaitForFundingOptions } from \"./types.js\"\n\nexport class Wallet {\n readonly name: string\n readonly address: `0x${string}`\n readonly network: Network\n\n private _account: PrivateKeyAccount\n private _privateKey: `0x${string}`\n private _rpcUrl: string | undefined\n private _paymentFetch: typeof globalThis.fetch\n\n constructor(params: {\n name: string\n account: PrivateKeyAccount\n privateKey: `0x${string}`\n network: Network\n rpcUrl?: string\n paymentFetch: typeof globalThis.fetch\n }) {\n this.name = params.name\n this._account = params.account\n this._privateKey = params.privateKey\n this.address = params.account.address\n this.network = params.network\n this._rpcUrl = params.rpcUrl\n this._paymentFetch = params.paymentFetch\n }\n\n /** Check USDC balance on Base. Returns balance in minor units (6 decimals). */\n async checkBalance(): Promise<bigint> {\n return getUsdcBalance(this._account.address, this.network, this._rpcUrl)\n }\n\n /**\n * Poll until USDC balance >= minAmount.\n * @param minAmount - minimum USDC balance in minor units (6 decimals)\n */\n async waitForFunding(minAmount: bigint, opts?: WaitForFundingOptions): Promise<void> {\n const interval = opts?.pollInterval ?? 10_000\n const deadline = opts?.timeout ? Date.now() + opts.timeout : null\n\n while (true) {\n const balance = await getUsdcBalance(this._account.address, this.network, this._rpcUrl)\n if (balance >= minAmount) return\n\n if (deadline && Date.now() >= deadline) {\n throw new Error(`Funding timeout: balance ${balance} < required ${minAmount}`)\n }\n\n await new Promise((r) => setTimeout(r, interval))\n }\n }\n\n /**\n * Drop-in `fetch()` replacement that handles x402 payments automatically.\n * If the server returns 402, the library signs an EIP-3009 authorization\n * and retries the request with payment headers.\n */\n async fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> {\n return this._paymentFetch(input, init)\n }\n}\n","import type { ComputeRequest, ComputeResponse, PricingTier, Size } from \"./types.js\"\n\nconst DEFAULT_ENDPOINT = \"https://x402.auteng.ai/api/x402/compute\"\n\nlet _endpoint = DEFAULT_ENDPOINT\n\nconst PRICING: Record<Size, PricingTier> = {\n small: {\n vcpu: 2,\n ram_gb: 1,\n default_timeout_s: 30,\n max_timeout_s: 300,\n base_price_usd: 0.002,\n per_second_usd: 0.00005,\n },\n med: {\n vcpu: 4,\n ram_gb: 4,\n default_timeout_s: 60,\n max_timeout_s: 600,\n base_price_usd: 0.008,\n per_second_usd: 0.00012,\n },\n large: {\n vcpu: 8,\n ram_gb: 16,\n default_timeout_s: 120,\n max_timeout_s: 3600,\n base_price_usd: 0.03,\n per_second_usd: 0.00025,\n },\n}\n\nexport const compute = {\n /**\n * Execute sandboxed code via AutEng's x402 compute endpoint.\n * Payment is handled automatically via the wallet's x402 layer.\n */\n async run(request: ComputeRequest): Promise<ComputeResponse> {\n if (!request.code) {\n throw new Error(\"compute.run: 'code' is required\")\n }\n if (!request.stack) {\n throw new Error(\"compute.run: 'stack' is required\")\n }\n\n const body = {\n code: request.code,\n stack: request.stack,\n size: request.size ?? \"small\",\n ...(request.timeout_seconds != null && {\n timeout_seconds: request.timeout_seconds,\n }),\n ...(request.files != null && { files: request.files }),\n }\n\n if (!request.wallet) {\n throw new Error(\"compute.run: 'wallet' is required\")\n }\n\n const response = await request.wallet.fetch(_endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\")\n throw new Error(`Compute request failed (${response.status}): ${text}`)\n }\n\n return (await response.json()) as ComputeResponse\n },\n\n /** Returns the pricing table for all compute sizes. */\n pricing(): Record<Size, PricingTier> {\n return { ...PRICING }\n },\n\n /**\n * Override the compute endpoint URL.\n * Default: https://x402.auteng.ai/api/x402/compute\n */\n setEndpoint(url: string): void {\n _endpoint = url\n },\n}\n"],"mappings":"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","names":["import_node_path","import_client","import_accounts"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/wallet/index.ts
|
|
2
|
-
import { resolve } from "path";
|
|
2
|
+
import { join as join2, resolve as resolve2 } from "path";
|
|
3
3
|
|
|
4
4
|
// src/wallet/keypair.ts
|
|
5
5
|
import { generatePrivateKey, privateKeyToAccount } from "viem/accounts";
|
|
@@ -14,8 +14,16 @@ function loadKeypair(privateKey) {
|
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
// src/wallet/storage.ts
|
|
17
|
-
import { mkdirSync, readFileSync, writeFileSync, existsSync } from "fs";
|
|
18
|
-
import { dirname } from "path";
|
|
17
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync, copyFileSync } from "fs";
|
|
18
|
+
import { dirname, join, resolve } from "path";
|
|
19
|
+
var VALID_NAME = /^[a-z0-9_-]+$/;
|
|
20
|
+
function validateWalletName(name) {
|
|
21
|
+
if (!VALID_NAME.test(name)) {
|
|
22
|
+
throw new Error(
|
|
23
|
+
`Invalid wallet name "${name}". Use lowercase letters, numbers, hyphens, and underscores only.`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
19
27
|
function readWalletFile(path) {
|
|
20
28
|
if (!existsSync(path)) return null;
|
|
21
29
|
const raw = readFileSync(path, "utf-8");
|
|
@@ -27,6 +35,45 @@ function writeWalletFile(path, data) {
|
|
|
27
35
|
mode: 384
|
|
28
36
|
});
|
|
29
37
|
}
|
|
38
|
+
function listWalletFiles(dir) {
|
|
39
|
+
const resolved = resolve(dir);
|
|
40
|
+
if (!existsSync(resolved)) return [];
|
|
41
|
+
return readdirSync(resolved).filter((f) => f.endsWith(".json")).map((f) => f.replace(/\.json$/, ""));
|
|
42
|
+
}
|
|
43
|
+
function migrateLegacyWallet(walletsDir) {
|
|
44
|
+
const legacyPath = resolve(walletsDir, "..", "wallet.json");
|
|
45
|
+
const newPath = join(resolve(walletsDir), "default.json");
|
|
46
|
+
if (existsSync(legacyPath) && !existsSync(newPath)) {
|
|
47
|
+
const data = readWalletFile(legacyPath);
|
|
48
|
+
if (data) {
|
|
49
|
+
mkdirSync(resolve(walletsDir), { recursive: true });
|
|
50
|
+
copyFileSync(legacyPath, newPath);
|
|
51
|
+
return data;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/x402/index.ts
|
|
58
|
+
import { x402Client } from "@x402/core/client";
|
|
59
|
+
import { registerExactEvmScheme } from "@x402/evm/exact/client";
|
|
60
|
+
import { toClientEvmSigner } from "@x402/evm";
|
|
61
|
+
import { wrapFetchWithPayment } from "@x402/fetch";
|
|
62
|
+
import { privateKeyToAccount as privateKeyToAccount2 } from "viem/accounts";
|
|
63
|
+
import { createPublicClient, http } from "viem";
|
|
64
|
+
import { base, baseSepolia } from "viem/chains";
|
|
65
|
+
function createPaymentFetch(privateKey, network = "base", rpcUrl) {
|
|
66
|
+
const account = privateKeyToAccount2(privateKey);
|
|
67
|
+
const chain = network === "base" ? base : baseSepolia;
|
|
68
|
+
const publicClient = createPublicClient({
|
|
69
|
+
chain,
|
|
70
|
+
transport: http(rpcUrl)
|
|
71
|
+
});
|
|
72
|
+
const signer = toClientEvmSigner(account, publicClient);
|
|
73
|
+
const client = new x402Client();
|
|
74
|
+
registerExactEvmScheme(client, { signer });
|
|
75
|
+
return wrapFetchWithPayment(fetch, client);
|
|
76
|
+
}
|
|
30
77
|
|
|
31
78
|
// src/wallet/types.ts
|
|
32
79
|
var NETWORK_CONFIG = {
|
|
@@ -65,103 +112,138 @@ async function getUsdcBalance(address, network, rpcUrl) {
|
|
|
65
112
|
return BigInt(json.result ?? "0x0");
|
|
66
113
|
}
|
|
67
114
|
|
|
68
|
-
// src/
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
registerExactEvmScheme(client, { signer });
|
|
86
|
-
return wrapFetchWithPayment(fetch, client);
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// src/wallet/index.ts
|
|
90
|
-
var _account = null;
|
|
91
|
-
var _privateKey = null;
|
|
92
|
-
var _network = "base";
|
|
93
|
-
var _rpcUrl;
|
|
94
|
-
var _paymentFetch = null;
|
|
95
|
-
function ensureCreated() {
|
|
96
|
-
if (!_account) {
|
|
97
|
-
throw new Error("Wallet not initialized. Call wallet.create() first.");
|
|
115
|
+
// src/wallet/wallet.ts
|
|
116
|
+
var Wallet = class {
|
|
117
|
+
name;
|
|
118
|
+
address;
|
|
119
|
+
network;
|
|
120
|
+
_account;
|
|
121
|
+
_privateKey;
|
|
122
|
+
_rpcUrl;
|
|
123
|
+
_paymentFetch;
|
|
124
|
+
constructor(params) {
|
|
125
|
+
this.name = params.name;
|
|
126
|
+
this._account = params.account;
|
|
127
|
+
this._privateKey = params.privateKey;
|
|
128
|
+
this.address = params.account.address;
|
|
129
|
+
this.network = params.network;
|
|
130
|
+
this._rpcUrl = params.rpcUrl;
|
|
131
|
+
this._paymentFetch = params.paymentFetch;
|
|
98
132
|
}
|
|
99
|
-
}
|
|
100
|
-
var wallet = {
|
|
101
|
-
/**
|
|
102
|
-
* Create a new EVM wallet or load an existing one from disk.
|
|
103
|
-
* Idempotent: if the wallet file already exists, loads it.
|
|
104
|
-
*/
|
|
105
|
-
async create(opts) {
|
|
106
|
-
const keyPath = resolve(opts?.keyPath ?? ".auteng/wallet.json");
|
|
107
|
-
_network = opts?.network ?? "base";
|
|
108
|
-
_rpcUrl = opts?.rpcUrl;
|
|
109
|
-
const existing = readWalletFile(keyPath);
|
|
110
|
-
if (existing) {
|
|
111
|
-
_privateKey = existing.privateKey;
|
|
112
|
-
const { account } = loadKeypair(existing.privateKey);
|
|
113
|
-
_account = account;
|
|
114
|
-
_network = existing.network;
|
|
115
|
-
} else {
|
|
116
|
-
const { privateKey, account } = createKeypair();
|
|
117
|
-
_privateKey = privateKey;
|
|
118
|
-
_account = account;
|
|
119
|
-
writeWalletFile(keyPath, {
|
|
120
|
-
privateKey,
|
|
121
|
-
address: account.address,
|
|
122
|
-
network: _network
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
_paymentFetch = createPaymentFetch(_privateKey, _network, _rpcUrl);
|
|
126
|
-
},
|
|
127
|
-
/** The wallet's public address. Throws if not created. */
|
|
128
|
-
get address() {
|
|
129
|
-
ensureCreated();
|
|
130
|
-
return _account.address;
|
|
131
|
-
},
|
|
132
133
|
/** Check USDC balance on Base. Returns balance in minor units (6 decimals). */
|
|
133
134
|
async checkBalance() {
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
},
|
|
135
|
+
return getUsdcBalance(this._account.address, this.network, this._rpcUrl);
|
|
136
|
+
}
|
|
137
137
|
/**
|
|
138
138
|
* Poll until USDC balance >= minAmount.
|
|
139
139
|
* @param minAmount - minimum USDC balance in minor units (6 decimals)
|
|
140
140
|
*/
|
|
141
141
|
async waitForFunding(minAmount, opts) {
|
|
142
|
-
ensureCreated();
|
|
143
142
|
const interval = opts?.pollInterval ?? 1e4;
|
|
144
143
|
const deadline = opts?.timeout ? Date.now() + opts.timeout : null;
|
|
145
144
|
while (true) {
|
|
146
|
-
const balance = await getUsdcBalance(_account.address,
|
|
145
|
+
const balance = await getUsdcBalance(this._account.address, this.network, this._rpcUrl);
|
|
147
146
|
if (balance >= minAmount) return;
|
|
148
147
|
if (deadline && Date.now() >= deadline) {
|
|
149
148
|
throw new Error(`Funding timeout: balance ${balance} < required ${minAmount}`);
|
|
150
149
|
}
|
|
151
150
|
await new Promise((r) => setTimeout(r, interval));
|
|
152
151
|
}
|
|
153
|
-
}
|
|
152
|
+
}
|
|
154
153
|
/**
|
|
155
154
|
* Drop-in `fetch()` replacement that handles x402 payments automatically.
|
|
156
155
|
* If the server returns 402, the library signs an EIP-3009 authorization
|
|
157
156
|
* and retries the request with payment headers.
|
|
158
157
|
*/
|
|
159
158
|
async fetch(input, init) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
159
|
+
return this._paymentFetch(input, init);
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
// src/wallet/index.ts
|
|
164
|
+
var DEFAULT_WALLETS_DIR = ".auteng/wallets";
|
|
165
|
+
var _wallets = /* @__PURE__ */ new Map();
|
|
166
|
+
var _walletsDir = resolve2(DEFAULT_WALLETS_DIR);
|
|
167
|
+
var wallet = {
|
|
168
|
+
/**
|
|
169
|
+
* Create a new named wallet or load an existing one from disk.
|
|
170
|
+
* Idempotent: if a wallet with this name already exists, returns it.
|
|
171
|
+
*/
|
|
172
|
+
async create(opts) {
|
|
173
|
+
const name = opts?.name ?? "default";
|
|
174
|
+
validateWalletName(name);
|
|
175
|
+
if (_wallets.has(name)) return _wallets.get(name);
|
|
176
|
+
const dir = resolve2(opts?.walletsDir ?? DEFAULT_WALLETS_DIR);
|
|
177
|
+
_walletsDir = dir;
|
|
178
|
+
const filePath = join2(dir, `${name}.json`);
|
|
179
|
+
const network = opts?.network ?? "base";
|
|
180
|
+
const rpcUrl = opts?.rpcUrl;
|
|
181
|
+
let existing = readWalletFile(filePath);
|
|
182
|
+
if (!existing && name === "default") {
|
|
183
|
+
existing = migrateLegacyWallet(dir);
|
|
184
|
+
}
|
|
185
|
+
let privateKey;
|
|
186
|
+
let account;
|
|
187
|
+
if (existing) {
|
|
188
|
+
privateKey = existing.privateKey;
|
|
189
|
+
account = loadKeypair(existing.privateKey).account;
|
|
190
|
+
} else {
|
|
191
|
+
const kp = createKeypair();
|
|
192
|
+
privateKey = kp.privateKey;
|
|
193
|
+
account = kp.account;
|
|
194
|
+
writeWalletFile(filePath, {
|
|
195
|
+
privateKey,
|
|
196
|
+
address: account.address,
|
|
197
|
+
network
|
|
198
|
+
});
|
|
163
199
|
}
|
|
164
|
-
|
|
200
|
+
const effectiveNetwork = existing?.network ?? network;
|
|
201
|
+
const paymentFetch = createPaymentFetch(privateKey, effectiveNetwork, rpcUrl);
|
|
202
|
+
const w = new Wallet({
|
|
203
|
+
name,
|
|
204
|
+
account,
|
|
205
|
+
privateKey,
|
|
206
|
+
network: effectiveNetwork,
|
|
207
|
+
rpcUrl,
|
|
208
|
+
paymentFetch
|
|
209
|
+
});
|
|
210
|
+
_wallets.set(name, w);
|
|
211
|
+
return w;
|
|
212
|
+
},
|
|
213
|
+
/**
|
|
214
|
+
* Retrieve a previously-created wallet by name.
|
|
215
|
+
* Loads from disk if not in memory. Throws if not found.
|
|
216
|
+
*/
|
|
217
|
+
get(name) {
|
|
218
|
+
validateWalletName(name);
|
|
219
|
+
if (_wallets.has(name)) return _wallets.get(name);
|
|
220
|
+
const filePath = join2(_walletsDir, `${name}.json`);
|
|
221
|
+
const data = readWalletFile(filePath);
|
|
222
|
+
if (!data) throw new Error(`Wallet "${name}" not found`);
|
|
223
|
+
const { account } = loadKeypair(data.privateKey);
|
|
224
|
+
const paymentFetch = createPaymentFetch(data.privateKey, data.network);
|
|
225
|
+
const w = new Wallet({
|
|
226
|
+
name,
|
|
227
|
+
account,
|
|
228
|
+
privateKey: data.privateKey,
|
|
229
|
+
network: data.network,
|
|
230
|
+
paymentFetch
|
|
231
|
+
});
|
|
232
|
+
_wallets.set(name, w);
|
|
233
|
+
return w;
|
|
234
|
+
},
|
|
235
|
+
/** List all persisted wallets. */
|
|
236
|
+
list() {
|
|
237
|
+
const names = listWalletFiles(_walletsDir);
|
|
238
|
+
return names.map((n) => {
|
|
239
|
+
if (_wallets.has(n)) return _wallets.get(n);
|
|
240
|
+
return wallet.get(n);
|
|
241
|
+
});
|
|
242
|
+
},
|
|
243
|
+
/** @internal Clear in-memory cache and reset wallets dir. For testing only. */
|
|
244
|
+
_reset() {
|
|
245
|
+
_wallets.clear();
|
|
246
|
+
_walletsDir = resolve2(DEFAULT_WALLETS_DIR);
|
|
165
247
|
}
|
|
166
248
|
};
|
|
167
249
|
|
|
@@ -215,7 +297,10 @@ var compute = {
|
|
|
215
297
|
},
|
|
216
298
|
...request.files != null && { files: request.files }
|
|
217
299
|
};
|
|
218
|
-
|
|
300
|
+
if (!request.wallet) {
|
|
301
|
+
throw new Error("compute.run: 'wallet' is required");
|
|
302
|
+
}
|
|
303
|
+
const response = await request.wallet.fetch(_endpoint, {
|
|
219
304
|
method: "POST",
|
|
220
305
|
headers: { "Content-Type": "application/json" },
|
|
221
306
|
body: JSON.stringify(body)
|
|
@@ -239,6 +324,7 @@ var compute = {
|
|
|
239
324
|
}
|
|
240
325
|
};
|
|
241
326
|
export {
|
|
327
|
+
Wallet,
|
|
242
328
|
compute,
|
|
243
329
|
wallet
|
|
244
330
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/wallet/index.ts","../src/wallet/keypair.ts","../src/wallet/storage.ts","../src/wallet/types.ts","../src/wallet/balance.ts","../src/x402/index.ts","../src/compute/index.ts"],"sourcesContent":["import { resolve } from \"node:path\"\nimport type { PrivateKeyAccount } from \"viem\"\nimport { createKeypair, loadKeypair } from \"./keypair.js\"\nimport { readWalletFile, writeWalletFile } from \"./storage.js\"\nimport { getUsdcBalance } from \"./balance.js\"\nimport { createPaymentFetch } from \"../x402/index.js\"\nimport type { Network, WalletConfig, WaitForFundingOptions } from \"./types.js\"\n\n// --- Internal state ---\n\nlet _account: PrivateKeyAccount | null = null\nlet _privateKey: `0x${string}` | null = null\nlet _network: Network = \"base\"\nlet _rpcUrl: string | undefined\nlet _paymentFetch: typeof globalThis.fetch | null = null\n\nfunction ensureCreated(): void {\n if (!_account) {\n throw new Error(\"Wallet not initialized. Call wallet.create() first.\")\n }\n}\n\n// --- Public API ---\n\nexport const wallet = {\n /**\n * Create a new EVM wallet or load an existing one from disk.\n * Idempotent: if the wallet file already exists, loads it.\n */\n async create(opts?: WalletConfig): Promise<void> {\n const keyPath = resolve(opts?.keyPath ?? \".auteng/wallet.json\")\n _network = opts?.network ?? \"base\"\n _rpcUrl = opts?.rpcUrl\n\n const existing = readWalletFile(keyPath)\n if (existing) {\n _privateKey = existing.privateKey\n const { account } = loadKeypair(existing.privateKey)\n _account = account\n _network = existing.network\n } else {\n const { privateKey, account } = createKeypair()\n _privateKey = privateKey\n _account = account\n writeWalletFile(keyPath, {\n privateKey,\n address: account.address,\n network: _network,\n })\n }\n\n _paymentFetch = createPaymentFetch(_privateKey!, _network, _rpcUrl)\n },\n\n /** The wallet's public address. Throws if not created. */\n get address(): `0x${string}` {\n ensureCreated()\n return _account!.address\n },\n\n /** Check USDC balance on Base. Returns balance in minor units (6 decimals). */\n async checkBalance(): Promise<bigint> {\n ensureCreated()\n return getUsdcBalance(_account!.address, _network, _rpcUrl)\n },\n\n /**\n * Poll until USDC balance >= minAmount.\n * @param minAmount - minimum USDC balance in minor units (6 decimals)\n */\n async waitForFunding(minAmount: bigint, opts?: WaitForFundingOptions): Promise<void> {\n ensureCreated()\n const interval = opts?.pollInterval ?? 10_000\n const deadline = opts?.timeout ? Date.now() + opts.timeout : null\n\n while (true) {\n const balance = await getUsdcBalance(_account!.address, _network, _rpcUrl)\n if (balance >= minAmount) return\n\n if (deadline && Date.now() >= deadline) {\n throw new Error(`Funding timeout: balance ${balance} < required ${minAmount}`)\n }\n\n await new Promise((r) => setTimeout(r, interval))\n }\n },\n\n /**\n * Drop-in `fetch()` replacement that handles x402 payments automatically.\n * If the server returns 402, the library signs an EIP-3009 authorization\n * and retries the request with payment headers.\n */\n async fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> {\n ensureCreated()\n if (!_paymentFetch) {\n throw new Error(\"Payment layer not initialized\")\n }\n return _paymentFetch(input, init)\n },\n}\n","import { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\"\nimport type { PrivateKeyAccount } from \"viem\"\n\nexport function createKeypair(): {\n privateKey: `0x${string}`\n account: PrivateKeyAccount\n} {\n const privateKey = generatePrivateKey()\n const account = privateKeyToAccount(privateKey)\n return { privateKey, account }\n}\n\nexport function loadKeypair(privateKey: `0x${string}`): {\n account: PrivateKeyAccount\n} {\n const account = privateKeyToAccount(privateKey)\n return { account }\n}\n","import { mkdirSync, readFileSync, writeFileSync, existsSync } from \"node:fs\"\nimport { dirname } from \"node:path\"\nimport type { WalletFile } from \"./types.js\"\n\nexport function readWalletFile(path: string): WalletFile | null {\n if (!existsSync(path)) return null\n const raw = readFileSync(path, \"utf-8\")\n return JSON.parse(raw) as WalletFile\n}\n\nexport function writeWalletFile(path: string, data: WalletFile): void {\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, JSON.stringify(data, null, 2) + \"\\n\", {\n mode: 0o600,\n })\n}\n","export type Network = \"base\" | \"base-sepolia\"\n\nexport interface WalletConfig {\n /** Path to store the wallet keypair. Default: `.auteng/wallet.json` */\n keyPath?: string\n /** Network to use. Default: `base` */\n network?: Network\n /** Custom RPC endpoint. Default: public Base RPC */\n rpcUrl?: string\n}\n\nexport interface WalletFile {\n privateKey: `0x${string}`\n address: `0x${string}`\n network: Network\n}\n\nexport interface WaitForFundingOptions {\n /** Poll interval in milliseconds. Default: 10000 (10s) */\n pollInterval?: number\n /** Timeout in milliseconds. Default: none (waits forever) */\n timeout?: number\n}\n\nexport const NETWORK_CONFIG: Record<Network, { chainId: number; usdcAddress: `0x${string}`; rpcUrl: string }> = {\n base: {\n chainId: 8453,\n usdcAddress: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n rpcUrl: \"https://mainnet.base.org\",\n },\n \"base-sepolia\": {\n chainId: 84532,\n usdcAddress: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n rpcUrl: \"https://sepolia.base.org\",\n },\n}\n","import type { Network } from \"./types.js\"\nimport { NETWORK_CONFIG } from \"./types.js\"\n\n/**\n * Read USDC balance for `address` via a direct `eth_call` to the USDC\n * contract's `balanceOf(address)` function. No viem client needed — just\n * a plain JSON-RPC POST.\n */\nexport async function getUsdcBalance(address: `0x${string}`, network: Network, rpcUrl?: string): Promise<bigint> {\n const config = NETWORK_CONFIG[network]\n const url = rpcUrl ?? config.rpcUrl\n\n // balanceOf(address) selector = 0x70a08231\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, \"0\")\n const data = `0x70a08231${paddedAddress}`\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_call\",\n params: [{ to: config.usdcAddress, data }, \"latest\"],\n }),\n })\n\n const json = (await res.json()) as { result?: string; error?: unknown }\n if (json.error) {\n throw new Error(`RPC error: ${JSON.stringify(json.error)}`)\n }\n return BigInt(json.result ?? \"0x0\")\n}\n","import { x402Client } from \"@x402/core/client\"\nimport { registerExactEvmScheme } from \"@x402/evm/exact/client\"\nimport { toClientEvmSigner } from \"@x402/evm\"\nimport { wrapFetchWithPayment } from \"@x402/fetch\"\nimport { privateKeyToAccount } from \"viem/accounts\"\nimport { createPublicClient, http } from \"viem\"\nimport { base, baseSepolia } from \"viem/chains\"\nimport type { Network } from \"../wallet/types.js\"\n\n/**\n * Create a fetch function that automatically handles x402 payments.\n * When the server returns 402, the SDK signs an EIP-3009 authorization\n * using the provided private key and retries with payment headers.\n */\nexport function createPaymentFetch(\n privateKey: `0x${string}`,\n network: Network = \"base\",\n rpcUrl?: string\n): typeof globalThis.fetch {\n const account = privateKeyToAccount(privateKey)\n const chain = network === \"base\" ? base : baseSepolia\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n })\n const signer = toClientEvmSigner(account, publicClient)\n\n const client = new x402Client()\n registerExactEvmScheme(client, { signer })\n return wrapFetchWithPayment(fetch, client)\n}\n","import { wallet } from \"../wallet/index.js\"\nimport type { ComputeRequest, ComputeResponse, PricingTier, Size } from \"./types.js\"\n\nconst DEFAULT_ENDPOINT = \"https://x402.auteng.ai/api/x402/compute\"\n\nlet _endpoint = DEFAULT_ENDPOINT\n\nconst PRICING: Record<Size, PricingTier> = {\n small: {\n vcpu: 2,\n ram_gb: 1,\n default_timeout_s: 30,\n max_timeout_s: 300,\n base_price_usd: 0.002,\n per_second_usd: 0.00005,\n },\n med: {\n vcpu: 4,\n ram_gb: 4,\n default_timeout_s: 60,\n max_timeout_s: 600,\n base_price_usd: 0.008,\n per_second_usd: 0.00012,\n },\n large: {\n vcpu: 8,\n ram_gb: 16,\n default_timeout_s: 120,\n max_timeout_s: 3600,\n base_price_usd: 0.03,\n per_second_usd: 0.00025,\n },\n}\n\nexport const compute = {\n /**\n * Execute sandboxed code via AutEng's x402 compute endpoint.\n * Payment is handled automatically via the wallet's x402 layer.\n */\n async run(request: ComputeRequest): Promise<ComputeResponse> {\n if (!request.code) {\n throw new Error(\"compute.run: 'code' is required\")\n }\n if (!request.stack) {\n throw new Error(\"compute.run: 'stack' is required\")\n }\n\n const body = {\n code: request.code,\n stack: request.stack,\n size: request.size ?? \"small\",\n ...(request.timeout_seconds != null && {\n timeout_seconds: request.timeout_seconds,\n }),\n ...(request.files != null && { files: request.files }),\n }\n\n const response = await wallet.fetch(_endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\")\n throw new Error(`Compute request failed (${response.status}): ${text}`)\n }\n\n return (await response.json()) as ComputeResponse\n },\n\n /** Returns the pricing table for all compute sizes. */\n pricing(): Record<Size, PricingTier> {\n return { ...PRICING }\n },\n\n /**\n * Override the compute endpoint URL.\n * Default: https://x402.auteng.ai/api/x402/compute\n */\n setEndpoint(url: string): void {\n _endpoint = url\n },\n}\n"],"mappings":"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","names":["privateKeyToAccount"]}
|
|
1
|
+
{"version":3,"sources":["../src/wallet/index.ts","../src/wallet/keypair.ts","../src/wallet/storage.ts","../src/x402/index.ts","../src/wallet/types.ts","../src/wallet/balance.ts","../src/wallet/wallet.ts","../src/compute/index.ts"],"sourcesContent":["import { join, resolve } from \"node:path\"\nimport { createKeypair, loadKeypair } from \"./keypair.js\"\nimport { readWalletFile, writeWalletFile, listWalletFiles, migrateLegacyWallet, validateWalletName } from \"./storage.js\"\nimport { createPaymentFetch } from \"../x402/index.js\"\nimport { Wallet } from \"./wallet.js\"\nimport type { CreateWalletOptions } from \"./types.js\"\n\nconst DEFAULT_WALLETS_DIR = \".auteng/wallets\"\n\nconst _wallets = new Map<string, Wallet>()\nlet _walletsDir = resolve(DEFAULT_WALLETS_DIR)\n\nexport const wallet = {\n /**\n * Create a new named wallet or load an existing one from disk.\n * Idempotent: if a wallet with this name already exists, returns it.\n */\n async create(opts?: CreateWalletOptions): Promise<Wallet> {\n const name = opts?.name ?? \"default\"\n validateWalletName(name)\n\n if (_wallets.has(name)) return _wallets.get(name)!\n\n const dir = resolve(opts?.walletsDir ?? DEFAULT_WALLETS_DIR)\n _walletsDir = dir\n const filePath = join(dir, `${name}.json`)\n const network = opts?.network ?? \"base\"\n const rpcUrl = opts?.rpcUrl\n\n let existing = readWalletFile(filePath)\n\n if (!existing && name === \"default\") {\n existing = migrateLegacyWallet(dir)\n }\n\n let privateKey: `0x${string}`\n let account: ReturnType<typeof loadKeypair>[\"account\"]\n\n if (existing) {\n privateKey = existing.privateKey\n account = loadKeypair(existing.privateKey).account\n } else {\n const kp = createKeypair()\n privateKey = kp.privateKey\n account = kp.account\n writeWalletFile(filePath, {\n privateKey,\n address: account.address,\n network,\n })\n }\n\n const effectiveNetwork = existing?.network ?? network\n const paymentFetch = createPaymentFetch(privateKey, effectiveNetwork, rpcUrl)\n const w = new Wallet({\n name,\n account,\n privateKey,\n network: effectiveNetwork,\n rpcUrl,\n paymentFetch,\n })\n _wallets.set(name, w)\n return w\n },\n\n /**\n * Retrieve a previously-created wallet by name.\n * Loads from disk if not in memory. Throws if not found.\n */\n get(name: string): Wallet {\n validateWalletName(name)\n\n if (_wallets.has(name)) return _wallets.get(name)!\n\n const filePath = join(_walletsDir, `${name}.json`)\n const data = readWalletFile(filePath)\n if (!data) throw new Error(`Wallet \"${name}\" not found`)\n\n const { account } = loadKeypair(data.privateKey)\n const paymentFetch = createPaymentFetch(data.privateKey, data.network)\n const w = new Wallet({\n name,\n account,\n privateKey: data.privateKey,\n network: data.network,\n paymentFetch,\n })\n _wallets.set(name, w)\n return w\n },\n\n /** List all persisted wallets. */\n list(): Wallet[] {\n const names = listWalletFiles(_walletsDir)\n return names.map((n) => {\n if (_wallets.has(n)) return _wallets.get(n)!\n return wallet.get(n)\n })\n },\n\n /** @internal Clear in-memory cache and reset wallets dir. For testing only. */\n _reset(): void {\n _wallets.clear()\n _walletsDir = resolve(DEFAULT_WALLETS_DIR)\n },\n}\n","import { generatePrivateKey, privateKeyToAccount } from \"viem/accounts\"\nimport type { PrivateKeyAccount } from \"viem\"\n\nexport function createKeypair(): {\n privateKey: `0x${string}`\n account: PrivateKeyAccount\n} {\n const privateKey = generatePrivateKey()\n const account = privateKeyToAccount(privateKey)\n return { privateKey, account }\n}\n\nexport function loadKeypair(privateKey: `0x${string}`): {\n account: PrivateKeyAccount\n} {\n const account = privateKeyToAccount(privateKey)\n return { account }\n}\n","import { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync, copyFileSync } from \"node:fs\"\nimport { dirname, join, resolve } from \"node:path\"\nimport type { WalletFile } from \"./types.js\"\n\nconst VALID_NAME = /^[a-z0-9_-]+$/\n\nexport function validateWalletName(name: string): void {\n if (!VALID_NAME.test(name)) {\n throw new Error(\n `Invalid wallet name \"${name}\". Use lowercase letters, numbers, hyphens, and underscores only.`\n )\n }\n}\n\nexport function readWalletFile(path: string): WalletFile | null {\n if (!existsSync(path)) return null\n const raw = readFileSync(path, \"utf-8\")\n return JSON.parse(raw) as WalletFile\n}\n\nexport function writeWalletFile(path: string, data: WalletFile): void {\n mkdirSync(dirname(path), { recursive: true })\n writeFileSync(path, JSON.stringify(data, null, 2) + \"\\n\", {\n mode: 0o600,\n })\n}\n\nexport function listWalletFiles(dir: string): string[] {\n const resolved = resolve(dir)\n if (!existsSync(resolved)) return []\n return readdirSync(resolved)\n .filter((f) => f.endsWith(\".json\"))\n .map((f) => f.replace(/\\.json$/, \"\"))\n}\n\nexport function migrateLegacyWallet(walletsDir: string): WalletFile | null {\n const legacyPath = resolve(walletsDir, \"..\", \"wallet.json\")\n const newPath = join(resolve(walletsDir), \"default.json\")\n if (existsSync(legacyPath) && !existsSync(newPath)) {\n const data = readWalletFile(legacyPath)\n if (data) {\n mkdirSync(resolve(walletsDir), { recursive: true })\n copyFileSync(legacyPath, newPath)\n return data\n }\n }\n return null\n}\n","import { x402Client } from \"@x402/core/client\"\nimport { registerExactEvmScheme } from \"@x402/evm/exact/client\"\nimport { toClientEvmSigner } from \"@x402/evm\"\nimport { wrapFetchWithPayment } from \"@x402/fetch\"\nimport { privateKeyToAccount } from \"viem/accounts\"\nimport { createPublicClient, http } from \"viem\"\nimport { base, baseSepolia } from \"viem/chains\"\nimport type { Network } from \"../wallet/types.js\"\n\n/**\n * Create a fetch function that automatically handles x402 payments.\n * When the server returns 402, the SDK signs an EIP-3009 authorization\n * using the provided private key and retries with payment headers.\n */\nexport function createPaymentFetch(\n privateKey: `0x${string}`,\n network: Network = \"base\",\n rpcUrl?: string\n): typeof globalThis.fetch {\n const account = privateKeyToAccount(privateKey)\n const chain = network === \"base\" ? base : baseSepolia\n const publicClient = createPublicClient({\n chain,\n transport: http(rpcUrl),\n })\n const signer = toClientEvmSigner(account, publicClient)\n\n const client = new x402Client()\n registerExactEvmScheme(client, { signer })\n return wrapFetchWithPayment(fetch, client)\n}\n","export type Network = \"base\" | \"base-sepolia\"\n\nexport interface CreateWalletOptions {\n /** Wallet identifier. Default: \"default\" */\n name?: string\n /** Network to use. Default: `base` */\n network?: Network\n /** Custom RPC endpoint. Default: public Base RPC */\n rpcUrl?: string\n /** Base directory for wallet storage. Default: \".auteng/wallets\" */\n walletsDir?: string\n}\n\n/** @deprecated Use CreateWalletOptions instead */\nexport type WalletConfig = CreateWalletOptions\n\nexport interface WalletFile {\n privateKey: `0x${string}`\n address: `0x${string}`\n network: Network\n}\n\nexport interface WaitForFundingOptions {\n /** Poll interval in milliseconds. Default: 10000 (10s) */\n pollInterval?: number\n /** Timeout in milliseconds. Default: none (waits forever) */\n timeout?: number\n}\n\nexport const NETWORK_CONFIG: Record<Network, { chainId: number; usdcAddress: `0x${string}`; rpcUrl: string }> = {\n base: {\n chainId: 8453,\n usdcAddress: \"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913\",\n rpcUrl: \"https://mainnet.base.org\",\n },\n \"base-sepolia\": {\n chainId: 84532,\n usdcAddress: \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n rpcUrl: \"https://sepolia.base.org\",\n },\n}\n","import type { Network } from \"./types.js\"\nimport { NETWORK_CONFIG } from \"./types.js\"\n\n/**\n * Read USDC balance for `address` via a direct `eth_call` to the USDC\n * contract's `balanceOf(address)` function. No viem client needed — just\n * a plain JSON-RPC POST.\n */\nexport async function getUsdcBalance(address: `0x${string}`, network: Network, rpcUrl?: string): Promise<bigint> {\n const config = NETWORK_CONFIG[network]\n const url = rpcUrl ?? config.rpcUrl\n\n // balanceOf(address) selector = 0x70a08231\n const paddedAddress = address.slice(2).toLowerCase().padStart(64, \"0\")\n const data = `0x70a08231${paddedAddress}`\n\n const res = await fetch(url, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({\n jsonrpc: \"2.0\",\n id: 1,\n method: \"eth_call\",\n params: [{ to: config.usdcAddress, data }, \"latest\"],\n }),\n })\n\n const json = (await res.json()) as { result?: string; error?: unknown }\n if (json.error) {\n throw new Error(`RPC error: ${JSON.stringify(json.error)}`)\n }\n return BigInt(json.result ?? \"0x0\")\n}\n","import type { PrivateKeyAccount } from \"viem\"\nimport { getUsdcBalance } from \"./balance.js\"\nimport type { Network, WaitForFundingOptions } from \"./types.js\"\n\nexport class Wallet {\n readonly name: string\n readonly address: `0x${string}`\n readonly network: Network\n\n private _account: PrivateKeyAccount\n private _privateKey: `0x${string}`\n private _rpcUrl: string | undefined\n private _paymentFetch: typeof globalThis.fetch\n\n constructor(params: {\n name: string\n account: PrivateKeyAccount\n privateKey: `0x${string}`\n network: Network\n rpcUrl?: string\n paymentFetch: typeof globalThis.fetch\n }) {\n this.name = params.name\n this._account = params.account\n this._privateKey = params.privateKey\n this.address = params.account.address\n this.network = params.network\n this._rpcUrl = params.rpcUrl\n this._paymentFetch = params.paymentFetch\n }\n\n /** Check USDC balance on Base. Returns balance in minor units (6 decimals). */\n async checkBalance(): Promise<bigint> {\n return getUsdcBalance(this._account.address, this.network, this._rpcUrl)\n }\n\n /**\n * Poll until USDC balance >= minAmount.\n * @param minAmount - minimum USDC balance in minor units (6 decimals)\n */\n async waitForFunding(minAmount: bigint, opts?: WaitForFundingOptions): Promise<void> {\n const interval = opts?.pollInterval ?? 10_000\n const deadline = opts?.timeout ? Date.now() + opts.timeout : null\n\n while (true) {\n const balance = await getUsdcBalance(this._account.address, this.network, this._rpcUrl)\n if (balance >= minAmount) return\n\n if (deadline && Date.now() >= deadline) {\n throw new Error(`Funding timeout: balance ${balance} < required ${minAmount}`)\n }\n\n await new Promise((r) => setTimeout(r, interval))\n }\n }\n\n /**\n * Drop-in `fetch()` replacement that handles x402 payments automatically.\n * If the server returns 402, the library signs an EIP-3009 authorization\n * and retries the request with payment headers.\n */\n async fetch(input: string | URL | Request, init?: RequestInit): Promise<Response> {\n return this._paymentFetch(input, init)\n }\n}\n","import type { ComputeRequest, ComputeResponse, PricingTier, Size } from \"./types.js\"\n\nconst DEFAULT_ENDPOINT = \"https://x402.auteng.ai/api/x402/compute\"\n\nlet _endpoint = DEFAULT_ENDPOINT\n\nconst PRICING: Record<Size, PricingTier> = {\n small: {\n vcpu: 2,\n ram_gb: 1,\n default_timeout_s: 30,\n max_timeout_s: 300,\n base_price_usd: 0.002,\n per_second_usd: 0.00005,\n },\n med: {\n vcpu: 4,\n ram_gb: 4,\n default_timeout_s: 60,\n max_timeout_s: 600,\n base_price_usd: 0.008,\n per_second_usd: 0.00012,\n },\n large: {\n vcpu: 8,\n ram_gb: 16,\n default_timeout_s: 120,\n max_timeout_s: 3600,\n base_price_usd: 0.03,\n per_second_usd: 0.00025,\n },\n}\n\nexport const compute = {\n /**\n * Execute sandboxed code via AutEng's x402 compute endpoint.\n * Payment is handled automatically via the wallet's x402 layer.\n */\n async run(request: ComputeRequest): Promise<ComputeResponse> {\n if (!request.code) {\n throw new Error(\"compute.run: 'code' is required\")\n }\n if (!request.stack) {\n throw new Error(\"compute.run: 'stack' is required\")\n }\n\n const body = {\n code: request.code,\n stack: request.stack,\n size: request.size ?? \"small\",\n ...(request.timeout_seconds != null && {\n timeout_seconds: request.timeout_seconds,\n }),\n ...(request.files != null && { files: request.files }),\n }\n\n if (!request.wallet) {\n throw new Error(\"compute.run: 'wallet' is required\")\n }\n\n const response = await request.wallet.fetch(_endpoint, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(body),\n })\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"\")\n throw new Error(`Compute request failed (${response.status}): ${text}`)\n }\n\n return (await response.json()) as ComputeResponse\n },\n\n /** Returns the pricing table for all compute sizes. */\n pricing(): Record<Size, PricingTier> {\n return { ...PRICING }\n },\n\n /**\n * Override the compute endpoint URL.\n * Default: https://x402.auteng.ai/api/x402/compute\n */\n setEndpoint(url: string): void {\n _endpoint = url\n },\n}\n"],"mappings":"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","names":["join","resolve","privateKeyToAccount","resolve","join"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auteng/agent-utils",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Utility belt for autonomous AI agents — wallet, compute, and more",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -19,19 +19,22 @@
|
|
|
19
19
|
"scripts": {
|
|
20
20
|
"build": "tsup",
|
|
21
21
|
"dev": "tsup --watch",
|
|
22
|
-
"clean": "rimraf dist"
|
|
22
|
+
"clean": "rimraf dist",
|
|
23
|
+
"test": "vitest run",
|
|
24
|
+
"test:watch": "vitest"
|
|
23
25
|
},
|
|
24
26
|
"dependencies": {
|
|
25
|
-
"viem": "^2.39.0",
|
|
26
27
|
"@x402/core": "^2.2.0",
|
|
27
28
|
"@x402/evm": "^2.2.0",
|
|
28
|
-
"@x402/fetch": "^2.2.0"
|
|
29
|
+
"@x402/fetch": "^2.2.0",
|
|
30
|
+
"viem": "^2.39.0"
|
|
29
31
|
},
|
|
30
32
|
"devDependencies": {
|
|
33
|
+
"@types/node": "^20.0.0",
|
|
34
|
+
"rimraf": "^5.0.10",
|
|
31
35
|
"tsup": "^8.0.0",
|
|
32
36
|
"typescript": "^5.4.5",
|
|
33
|
-
"
|
|
34
|
-
"@types/node": "^20.0.0"
|
|
37
|
+
"vitest": "^4.0.18"
|
|
35
38
|
},
|
|
36
39
|
"publishConfig": {
|
|
37
40
|
"access": "public"
|