@devbond/gc 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/autonomy/behavior.d.ts +3 -2
- package/dist/autonomy/behavior.js +2 -2
- package/dist/autonomy/behavior.js.map +1 -1
- package/dist/autonomy/llm-client.d.ts +5 -9
- package/dist/autonomy/llm-client.js +13 -138
- package/dist/autonomy/llm-client.js.map +1 -1
- package/dist/finance/action/buyback.d.ts +36 -0
- package/dist/finance/action/buyback.js +27 -0
- package/dist/finance/action/buyback.js.map +1 -0
- package/dist/finance/action/gas-refill.d.ts +29 -0
- package/dist/finance/action/gas-refill.js +106 -0
- package/dist/finance/action/gas-refill.js.map +1 -0
- package/dist/finance/action/index.d.ts +8 -0
- package/dist/finance/action/index.js +9 -0
- package/dist/finance/action/index.js.map +1 -0
- package/dist/finance/action/pay-bills.d.ts +35 -0
- package/dist/finance/action/pay-bills.js +39 -0
- package/dist/finance/action/pay-bills.js.map +1 -0
- package/dist/finance/action/treasury.d.ts +26 -0
- package/dist/finance/action/treasury.js +46 -0
- package/dist/finance/action/treasury.js.map +1 -0
- package/dist/finance/action/x402.d.ts +124 -0
- package/dist/finance/action/x402.js +200 -0
- package/dist/finance/action/x402.js.map +1 -0
- package/dist/finance/earn.d.ts +49 -0
- package/dist/finance/earn.js +77 -0
- package/dist/finance/earn.js.map +1 -0
- package/dist/finance/index.d.ts +5 -0
- package/dist/finance/index.js +5 -0
- package/dist/finance/index.js.map +1 -0
- package/dist/finance/spend.d.ts +53 -0
- package/dist/finance/spend.js +89 -0
- package/dist/finance/spend.js.map +1 -0
- package/dist/finance/wallet.d.ts +23 -0
- package/dist/finance/wallet.js +82 -0
- package/dist/finance/wallet.js.map +1 -0
- package/dist/index.js +15 -9
- package/dist/index.js.map +1 -1
- package/dist/survival/survival-manager.d.ts +4 -2
- package/dist/survival/survival-manager.js +9 -3
- package/dist/survival/survival-manager.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* treasury.ts — Treasury 能力探测与提款
|
|
3
|
+
*
|
|
4
|
+
* 负责检测 token 合约是否支持 withdrawToWallet(V2 能力),
|
|
5
|
+
* 以及执行 treasury → wallet 的稳定币提款。
|
|
6
|
+
*/
|
|
7
|
+
import { ethers } from "ethers";
|
|
8
|
+
export interface TreasuryCapabilities {
|
|
9
|
+
/** Whether the contract supports withdrawToWallet */
|
|
10
|
+
hasWithdrawToWallet: boolean;
|
|
11
|
+
}
|
|
12
|
+
export interface WithdrawResult {
|
|
13
|
+
txHash: string;
|
|
14
|
+
amount: bigint;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Detect treasury capabilities by probing the token contract.
|
|
18
|
+
* Calls withdrawToWallet.staticCall(0) — if the contract has the function,
|
|
19
|
+
* it will revert with a "Goo:" validation error; if not, it reverts differently.
|
|
20
|
+
*/
|
|
21
|
+
export declare function detectTreasuryCapabilities(tokenAddress: string, provider: ethers.JsonRpcProvider): Promise<TreasuryCapabilities>;
|
|
22
|
+
/**
|
|
23
|
+
* Withdraw stablecoin from treasury to the agent's wallet.
|
|
24
|
+
* Requires the contract to support withdrawToWallet (V2).
|
|
25
|
+
*/
|
|
26
|
+
export declare function withdrawFromTreasury(signer: ethers.Wallet, tokenAddress: string, amount: bigint, stableDecimals?: number): Promise<WithdrawResult>;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* treasury.ts — Treasury 能力探测与提款
|
|
3
|
+
*
|
|
4
|
+
* 负责检测 token 合约是否支持 withdrawToWallet(V2 能力),
|
|
5
|
+
* 以及执行 treasury → wallet 的稳定币提款。
|
|
6
|
+
*/
|
|
7
|
+
import { ethers } from "ethers";
|
|
8
|
+
// ─── ABI (treasury-specific) ────────────────────────────────────────────
|
|
9
|
+
const TREASURY_ABI = [
|
|
10
|
+
"function withdrawToWallet(uint256 amount)",
|
|
11
|
+
"function treasuryBalance() view returns (uint256)",
|
|
12
|
+
"function starvingThreshold() view returns (uint256)",
|
|
13
|
+
];
|
|
14
|
+
// ─── Functions ──────────────────────────────────────────────────────────
|
|
15
|
+
/**
|
|
16
|
+
* Detect treasury capabilities by probing the token contract.
|
|
17
|
+
* Calls withdrawToWallet.staticCall(0) — if the contract has the function,
|
|
18
|
+
* it will revert with a "Goo:" validation error; if not, it reverts differently.
|
|
19
|
+
*/
|
|
20
|
+
export async function detectTreasuryCapabilities(tokenAddress, provider) {
|
|
21
|
+
const contract = new ethers.Contract(tokenAddress, TREASURY_ABI, provider);
|
|
22
|
+
let hasWithdrawToWallet = false;
|
|
23
|
+
try {
|
|
24
|
+
await contract.withdrawToWallet.staticCall(0n).catch((err) => {
|
|
25
|
+
if (err.message.includes("Goo:")) {
|
|
26
|
+
hasWithdrawToWallet = true;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
catch {
|
|
31
|
+
hasWithdrawToWallet = false;
|
|
32
|
+
}
|
|
33
|
+
return { hasWithdrawToWallet };
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Withdraw stablecoin from treasury to the agent's wallet.
|
|
37
|
+
* Requires the contract to support withdrawToWallet (V2).
|
|
38
|
+
*/
|
|
39
|
+
export async function withdrawFromTreasury(signer, tokenAddress, amount, stableDecimals = 18) {
|
|
40
|
+
const contract = new ethers.Contract(tokenAddress, TREASURY_ABI, signer);
|
|
41
|
+
const tx = await contract.withdrawToWallet(amount);
|
|
42
|
+
const receipt = await tx.wait();
|
|
43
|
+
console.log(`[treasury] Withdrew ${ethers.formatUnits(amount, stableDecimals)} stable from treasury (tx: ${receipt.hash})`);
|
|
44
|
+
return { txHash: receipt.hash, amount };
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=treasury.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"treasury.js","sourceRoot":"","sources":["../../../src/finance/action/treasury.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,2EAA2E;AAE3E,MAAM,YAAY,GAAG;IACnB,2CAA2C;IAC3C,mDAAmD;IACnD,qDAAqD;CACtD,CAAC;AAcF,2EAA2E;AAE3E;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,YAAoB,EACpB,QAAgC;IAEhC,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,EAAE,QAAQ,CAAC,CAAC;IAE3E,IAAI,mBAAmB,GAAG,KAAK,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,QAAQ,CAAC,gBAAgB,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAU,EAAE,EAAE;YAClE,IAAI,GAAG,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;gBACjC,mBAAmB,GAAG,IAAI,CAAC;YAC7B,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,mBAAmB,GAAG,KAAK,CAAC;IAC9B,CAAC;IAED,OAAO,EAAE,mBAAmB,EAAE,CAAC;AACjC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,MAAqB,EACrB,YAAoB,EACpB,MAAc,EACd,iBAAyB,EAAE;IAE3B,MAAM,QAAQ,GAAG,IAAI,MAAM,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,EAAE,MAAM,CAAC,CAAC;IACzE,MAAM,EAAE,GAAG,MAAM,QAAQ,CAAC,gBAAgB,CAAC,MAAM,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC;IAChC,OAAO,CAAC,GAAG,CACT,uBAAuB,MAAM,CAAC,WAAW,CAAC,MAAM,EAAE,cAAc,CAAC,8BAA8B,OAAO,CAAC,IAAI,GAAG,CAC/G,CAAC;IACF,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,CAAC;AAC1C,CAAC"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402.ts — x402 支付协议:Permit2 签名、payment header 组装、402 编排
|
|
3
|
+
*
|
|
4
|
+
* 当上游服务返回 402 Payment Required 时,负责完成 x402 协议全流程:
|
|
5
|
+
* 解析 402 响应 → 签名 Permit2 → 组装 payment-signature header → 重试请求 → 读取结算信息。
|
|
6
|
+
*
|
|
7
|
+
* 这是 x402 的唯一业务入口;llm-client / pay-bills 等调用方统一通过此模块。
|
|
8
|
+
*/
|
|
9
|
+
import { ethers } from "ethers";
|
|
10
|
+
import type { SpendManager, SpendCategory } from "../spend.js";
|
|
11
|
+
export declare const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
12
|
+
export declare const X402_PERMIT2_PROXY = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
|
|
13
|
+
export declare const PERMIT2_WITNESS_TYPES: {
|
|
14
|
+
PermitWitnessTransferFrom: {
|
|
15
|
+
name: string;
|
|
16
|
+
type: string;
|
|
17
|
+
}[];
|
|
18
|
+
TokenPermissions: {
|
|
19
|
+
name: string;
|
|
20
|
+
type: string;
|
|
21
|
+
}[];
|
|
22
|
+
Witness: {
|
|
23
|
+
name: string;
|
|
24
|
+
type: string;
|
|
25
|
+
}[];
|
|
26
|
+
};
|
|
27
|
+
export interface X402PaymentParams {
|
|
28
|
+
/** 支付网络,如 "eip155:56" */
|
|
29
|
+
network: string;
|
|
30
|
+
/** 支付资产地址 */
|
|
31
|
+
asset: string;
|
|
32
|
+
/** 支付金额(wei 或最小单位字符串) */
|
|
33
|
+
amount: string;
|
|
34
|
+
/** 收款方地址(x402 payTo) */
|
|
35
|
+
payTo: string;
|
|
36
|
+
/** 可选:超时秒数 */
|
|
37
|
+
maxTimeoutSeconds?: number;
|
|
38
|
+
}
|
|
39
|
+
export interface X402SignedResult {
|
|
40
|
+
from: string;
|
|
41
|
+
signature: string;
|
|
42
|
+
permit2Authorization: Record<string, unknown>;
|
|
43
|
+
}
|
|
44
|
+
export interface X402PaymentResult {
|
|
45
|
+
success: boolean;
|
|
46
|
+
response?: Response;
|
|
47
|
+
/** 支付金额(来自 402 response 的 accepts[0].amount) */
|
|
48
|
+
amount?: string;
|
|
49
|
+
settlement?: X402Settlement;
|
|
50
|
+
error?: string;
|
|
51
|
+
}
|
|
52
|
+
export interface X402Settlement {
|
|
53
|
+
txHash?: string;
|
|
54
|
+
payer?: string;
|
|
55
|
+
}
|
|
56
|
+
/** Parsed 402 response body */
|
|
57
|
+
export interface X402ResponseBody {
|
|
58
|
+
x402Version?: number;
|
|
59
|
+
resource?: {
|
|
60
|
+
url: string;
|
|
61
|
+
description?: string;
|
|
62
|
+
mimeType?: string;
|
|
63
|
+
};
|
|
64
|
+
accepts?: Array<{
|
|
65
|
+
scheme: string;
|
|
66
|
+
network: string;
|
|
67
|
+
asset: string;
|
|
68
|
+
amount: string;
|
|
69
|
+
payTo: string;
|
|
70
|
+
maxTimeoutSeconds?: number;
|
|
71
|
+
extra?: {
|
|
72
|
+
name?: string;
|
|
73
|
+
version?: string;
|
|
74
|
+
};
|
|
75
|
+
}>;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Sign a Permit2 PermitWitnessTransferFrom for x402 payment.
|
|
79
|
+
* Pure function — only needs an ethers.Wallet signer and payment params.
|
|
80
|
+
*/
|
|
81
|
+
export declare function signPermit2(signer: ethers.Wallet, params: X402PaymentParams): Promise<X402SignedResult>;
|
|
82
|
+
/**
|
|
83
|
+
* Build base64-encoded payment-signature header from signed Permit2 data.
|
|
84
|
+
*/
|
|
85
|
+
export declare function buildPaymentHeader(signed: X402SignedResult, opts: {
|
|
86
|
+
x402Version: number;
|
|
87
|
+
network: string;
|
|
88
|
+
resource?: unknown;
|
|
89
|
+
accepted?: unknown;
|
|
90
|
+
}): string;
|
|
91
|
+
/**
|
|
92
|
+
* Parse a 402 response body to extract payment requirements.
|
|
93
|
+
*/
|
|
94
|
+
export declare function parseX402Response(body: X402ResponseBody): {
|
|
95
|
+
requirements: X402PaymentParams;
|
|
96
|
+
x402Version: number;
|
|
97
|
+
resource?: unknown;
|
|
98
|
+
};
|
|
99
|
+
/**
|
|
100
|
+
* Read settlement info from response headers (x-bsc-llm-router-tx / payer).
|
|
101
|
+
*/
|
|
102
|
+
export declare function readSettlement(res: Response): X402Settlement;
|
|
103
|
+
/**
|
|
104
|
+
* Handle a complete HTTP 402 flow:
|
|
105
|
+
* 1. Parse 402 response body for payment requirements
|
|
106
|
+
* 2. Sign Permit2 authorization
|
|
107
|
+
* 3. Build payment-signature header
|
|
108
|
+
* 4. Retry the original request with the header
|
|
109
|
+
* 5. Validate retry response (reject if still 402)
|
|
110
|
+
* 6. Read settlement info from response headers
|
|
111
|
+
*
|
|
112
|
+
* This is the single entry point for x402 payment handling.
|
|
113
|
+
*/
|
|
114
|
+
export declare function handleHttpX402(signer: ethers.Wallet, res402: Response, retry: (paymentHeader: string) => Promise<Response>, spend?: {
|
|
115
|
+
manager: SpendManager;
|
|
116
|
+
category: SpendCategory;
|
|
117
|
+
}): Promise<X402PaymentResult>;
|
|
118
|
+
/** Alias for signPermit2. */
|
|
119
|
+
export declare function signX402Payment(signer: ethers.Wallet, params: X402PaymentParams): Promise<X402SignedResult>;
|
|
120
|
+
/**
|
|
121
|
+
* Simple callback-based 402 handler for non-HTTP contexts (e.g. pay-bills).
|
|
122
|
+
* Signs, builds the payment header, and passes it to the callback.
|
|
123
|
+
*/
|
|
124
|
+
export declare function handleX402Payment(signer: ethers.Wallet, params: X402PaymentParams, retryWithHeader: (paymentHeader: string) => Promise<unknown>, x402Version?: number): Promise<X402PaymentResult>;
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402.ts — x402 支付协议:Permit2 签名、payment header 组装、402 编排
|
|
3
|
+
*
|
|
4
|
+
* 当上游服务返回 402 Payment Required 时,负责完成 x402 协议全流程:
|
|
5
|
+
* 解析 402 响应 → 签名 Permit2 → 组装 payment-signature header → 重试请求 → 读取结算信息。
|
|
6
|
+
*
|
|
7
|
+
* 这是 x402 的唯一业务入口;llm-client / pay-bills 等调用方统一通过此模块。
|
|
8
|
+
*/
|
|
9
|
+
import { ethers } from "ethers";
|
|
10
|
+
// ─── Permit2 constants ──────────────────────────────────────────────────
|
|
11
|
+
export const PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
12
|
+
export const X402_PERMIT2_PROXY = "0x402085c248EeA27D92E8b30b2C58ed07f9E20001";
|
|
13
|
+
export const PERMIT2_WITNESS_TYPES = {
|
|
14
|
+
PermitWitnessTransferFrom: [
|
|
15
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
16
|
+
{ name: "spender", type: "address" },
|
|
17
|
+
{ name: "nonce", type: "uint256" },
|
|
18
|
+
{ name: "deadline", type: "uint256" },
|
|
19
|
+
{ name: "witness", type: "Witness" },
|
|
20
|
+
],
|
|
21
|
+
TokenPermissions: [
|
|
22
|
+
{ name: "token", type: "address" },
|
|
23
|
+
{ name: "amount", type: "uint256" },
|
|
24
|
+
],
|
|
25
|
+
Witness: [
|
|
26
|
+
{ name: "to", type: "address" },
|
|
27
|
+
{ name: "validAfter", type: "uint256" },
|
|
28
|
+
],
|
|
29
|
+
};
|
|
30
|
+
// ─── Low-level helpers ──────────────────────────────────────────────────
|
|
31
|
+
/**
|
|
32
|
+
* Sign a Permit2 PermitWitnessTransferFrom for x402 payment.
|
|
33
|
+
* Pure function — only needs an ethers.Wallet signer and payment params.
|
|
34
|
+
*/
|
|
35
|
+
export async function signPermit2(signer, params) {
|
|
36
|
+
const now = Math.floor(Date.now() / 1000);
|
|
37
|
+
const chainId = parseInt(params.network.split(":")[1], 10);
|
|
38
|
+
const deadline = now + (params.maxTimeoutSeconds || 300);
|
|
39
|
+
const validAfter = now - 600;
|
|
40
|
+
const nonceBytes = ethers.randomBytes(32);
|
|
41
|
+
const nonce = ethers.toBigInt(nonceBytes);
|
|
42
|
+
const domain = {
|
|
43
|
+
name: "Permit2",
|
|
44
|
+
verifyingContract: PERMIT2_ADDRESS,
|
|
45
|
+
chainId,
|
|
46
|
+
};
|
|
47
|
+
const message = {
|
|
48
|
+
permitted: {
|
|
49
|
+
token: params.asset,
|
|
50
|
+
amount: BigInt(params.amount),
|
|
51
|
+
},
|
|
52
|
+
spender: X402_PERMIT2_PROXY,
|
|
53
|
+
nonce,
|
|
54
|
+
deadline: BigInt(deadline),
|
|
55
|
+
witness: {
|
|
56
|
+
to: params.payTo,
|
|
57
|
+
validAfter: BigInt(validAfter),
|
|
58
|
+
},
|
|
59
|
+
};
|
|
60
|
+
const signature = await signer.signTypedData(domain, PERMIT2_WITNESS_TYPES, message);
|
|
61
|
+
const permit2Authorization = {
|
|
62
|
+
from: signer.address,
|
|
63
|
+
spender: X402_PERMIT2_PROXY,
|
|
64
|
+
nonce: nonce.toString(),
|
|
65
|
+
deadline: String(deadline),
|
|
66
|
+
permitted: {
|
|
67
|
+
token: params.asset,
|
|
68
|
+
amount: params.amount,
|
|
69
|
+
},
|
|
70
|
+
witness: {
|
|
71
|
+
to: params.payTo,
|
|
72
|
+
validAfter: String(validAfter),
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
return { from: signer.address, signature, permit2Authorization };
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Build base64-encoded payment-signature header from signed Permit2 data.
|
|
79
|
+
*/
|
|
80
|
+
export function buildPaymentHeader(signed, opts) {
|
|
81
|
+
const paymentPayload = {
|
|
82
|
+
x402Version: opts.x402Version,
|
|
83
|
+
scheme: "exact",
|
|
84
|
+
network: opts.network,
|
|
85
|
+
payload: {
|
|
86
|
+
permit2Authorization: signed.permit2Authorization,
|
|
87
|
+
signature: signed.signature,
|
|
88
|
+
},
|
|
89
|
+
resource: opts.resource,
|
|
90
|
+
accepted: opts.accepted,
|
|
91
|
+
};
|
|
92
|
+
return btoa(JSON.stringify(paymentPayload));
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Parse a 402 response body to extract payment requirements.
|
|
96
|
+
*/
|
|
97
|
+
export function parseX402Response(body) {
|
|
98
|
+
const requirements = body.accepts?.[0];
|
|
99
|
+
if (!requirements) {
|
|
100
|
+
throw new Error("x402: No payment requirements in 402 response");
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
requirements: {
|
|
104
|
+
network: requirements.network,
|
|
105
|
+
asset: requirements.asset,
|
|
106
|
+
amount: requirements.amount,
|
|
107
|
+
payTo: requirements.payTo,
|
|
108
|
+
maxTimeoutSeconds: requirements.maxTimeoutSeconds,
|
|
109
|
+
},
|
|
110
|
+
x402Version: body.x402Version ?? 2,
|
|
111
|
+
resource: body.resource,
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Read settlement info from response headers (x-bsc-llm-router-tx / payer).
|
|
116
|
+
*/
|
|
117
|
+
export function readSettlement(res) {
|
|
118
|
+
return {
|
|
119
|
+
txHash: res.headers.get("x-bsc-llm-router-tx") ?? undefined,
|
|
120
|
+
payer: res.headers.get("x-bsc-llm-router-payer") ?? undefined,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
// ─── Complete 402 orchestration ─────────────────────────────────────────
|
|
124
|
+
/**
|
|
125
|
+
* Handle a complete HTTP 402 flow:
|
|
126
|
+
* 1. Parse 402 response body for payment requirements
|
|
127
|
+
* 2. Sign Permit2 authorization
|
|
128
|
+
* 3. Build payment-signature header
|
|
129
|
+
* 4. Retry the original request with the header
|
|
130
|
+
* 5. Validate retry response (reject if still 402)
|
|
131
|
+
* 6. Read settlement info from response headers
|
|
132
|
+
*
|
|
133
|
+
* This is the single entry point for x402 payment handling.
|
|
134
|
+
*/
|
|
135
|
+
export async function handleHttpX402(signer, res402, retry, spend) {
|
|
136
|
+
try {
|
|
137
|
+
// 1. Parse 402 body
|
|
138
|
+
const body = await res402.json();
|
|
139
|
+
const { requirements, x402Version, resource } = parseX402Response(body);
|
|
140
|
+
console.log(` [x402] Payment required: ${requirements.amount} on ${requirements.network} → signing...`);
|
|
141
|
+
// 2. Sign
|
|
142
|
+
const signed = await signPermit2(signer, requirements);
|
|
143
|
+
// 3. Build header
|
|
144
|
+
const paymentHeader = buildPaymentHeader(signed, {
|
|
145
|
+
x402Version,
|
|
146
|
+
network: requirements.network,
|
|
147
|
+
resource,
|
|
148
|
+
accepted: body.accepts?.[0],
|
|
149
|
+
});
|
|
150
|
+
// 4. Retry with payment header
|
|
151
|
+
const retryRes = await retry(paymentHeader);
|
|
152
|
+
// 5. Validate
|
|
153
|
+
if (retryRes.status === 402) {
|
|
154
|
+
const errBody = await retryRes.text().catch(() => "");
|
|
155
|
+
throw new Error(`x402: Payment rejected after signing: ${errBody}`);
|
|
156
|
+
}
|
|
157
|
+
// 6. Read settlement
|
|
158
|
+
const settlement = readSettlement(retryRes);
|
|
159
|
+
if (settlement.txHash) {
|
|
160
|
+
console.log(` [x402] Settled: payer=${settlement.payer} tx=${settlement.txHash}`);
|
|
161
|
+
// Record spend if manager provided
|
|
162
|
+
if (spend) {
|
|
163
|
+
try {
|
|
164
|
+
spend.manager.record(spend.category, BigInt(requirements.amount), settlement.txHash);
|
|
165
|
+
}
|
|
166
|
+
catch { /* ignore recording errors */ }
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return { success: true, response: retryRes, amount: requirements.amount, settlement };
|
|
170
|
+
}
|
|
171
|
+
catch (err) {
|
|
172
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
173
|
+
return { success: false, error: msg };
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
// ─── Convenience aliases ────────────────────────────────────────────────
|
|
177
|
+
/** Alias for signPermit2. */
|
|
178
|
+
export async function signX402Payment(signer, params) {
|
|
179
|
+
return signPermit2(signer, params);
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Simple callback-based 402 handler for non-HTTP contexts (e.g. pay-bills).
|
|
183
|
+
* Signs, builds the payment header, and passes it to the callback.
|
|
184
|
+
*/
|
|
185
|
+
export async function handleX402Payment(signer, params, retryWithHeader, x402Version = 2) {
|
|
186
|
+
try {
|
|
187
|
+
const signed = await signPermit2(signer, params);
|
|
188
|
+
const paymentHeader = buildPaymentHeader(signed, {
|
|
189
|
+
x402Version,
|
|
190
|
+
network: params.network,
|
|
191
|
+
});
|
|
192
|
+
const response = await retryWithHeader(paymentHeader);
|
|
193
|
+
return { success: true, response: response };
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
197
|
+
return { success: false, error: msg };
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
//# sourceMappingURL=x402.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"x402.js","sourceRoot":"","sources":["../../../src/finance/action/x402.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* earn.ts — Agent 收入管理
|
|
3
|
+
*
|
|
4
|
+
* 自持数据与持久化,负责记录、汇总 agent 的各类收入(pulse 奖励、invest 收益等),
|
|
5
|
+
* 用于 runway 与收支分析。
|
|
6
|
+
*/
|
|
7
|
+
export type EarnCategory = "pulse" | "invest" | "reward" | "other";
|
|
8
|
+
export interface EarnEntry {
|
|
9
|
+
category: EarnCategory;
|
|
10
|
+
amount: string;
|
|
11
|
+
txHash?: string;
|
|
12
|
+
timestamp: string;
|
|
13
|
+
/** 可选说明,如 "pulse round #42" */
|
|
14
|
+
note?: string;
|
|
15
|
+
}
|
|
16
|
+
export interface EarningSummary {
|
|
17
|
+
total: bigint;
|
|
18
|
+
byCategory: Record<EarnCategory, bigint>;
|
|
19
|
+
entries: EarnEntry[];
|
|
20
|
+
}
|
|
21
|
+
export interface EarnManagerConfig {
|
|
22
|
+
dataDir: string;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* 管理当前 agent 的收入:记录入账、按类别汇总、持久化收入日志。
|
|
26
|
+
*/
|
|
27
|
+
export declare class EarnManager {
|
|
28
|
+
private config;
|
|
29
|
+
private earnLog;
|
|
30
|
+
constructor(config: EarnManagerConfig);
|
|
31
|
+
/**
|
|
32
|
+
* 记录一笔收入。
|
|
33
|
+
*/
|
|
34
|
+
record(category: EarnCategory, amount: bigint, txHash?: string, note?: string): void;
|
|
35
|
+
/**
|
|
36
|
+
* 获取收入汇总(总览与按类别)。
|
|
37
|
+
*/
|
|
38
|
+
getSummary(): EarningSummary;
|
|
39
|
+
getEntries(): EarnEntry[];
|
|
40
|
+
getEntriesByCategory(category: EarnCategory): EarnEntry[];
|
|
41
|
+
/**
|
|
42
|
+
* 加载持久化收入日志。
|
|
43
|
+
*/
|
|
44
|
+
load(): Promise<void>;
|
|
45
|
+
/**
|
|
46
|
+
* 持久化收入日志到 dataDir。
|
|
47
|
+
*/
|
|
48
|
+
save(): Promise<void>;
|
|
49
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* earn.ts — Agent 收入管理
|
|
3
|
+
*
|
|
4
|
+
* 自持数据与持久化,负责记录、汇总 agent 的各类收入(pulse 奖励、invest 收益等),
|
|
5
|
+
* 用于 runway 与收支分析。
|
|
6
|
+
*/
|
|
7
|
+
import { readFile, writeFile, mkdir } from "node:fs/promises";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
// ─── EarnManager ───────────────────────────────────────────────────────
|
|
10
|
+
const EARN_LOG_FILE = "wallet-earnings.json";
|
|
11
|
+
/**
|
|
12
|
+
* 管理当前 agent 的收入:记录入账、按类别汇总、持久化收入日志。
|
|
13
|
+
*/
|
|
14
|
+
export class EarnManager {
|
|
15
|
+
config;
|
|
16
|
+
earnLog = [];
|
|
17
|
+
constructor(config) {
|
|
18
|
+
this.config = config;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* 记录一笔收入。
|
|
22
|
+
*/
|
|
23
|
+
record(category, amount, txHash, note) {
|
|
24
|
+
this.earnLog.push({
|
|
25
|
+
category,
|
|
26
|
+
amount: amount.toString(),
|
|
27
|
+
txHash,
|
|
28
|
+
timestamp: new Date().toISOString(),
|
|
29
|
+
note,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* 获取收入汇总(总览与按类别)。
|
|
34
|
+
*/
|
|
35
|
+
getSummary() {
|
|
36
|
+
const byCategory = {
|
|
37
|
+
pulse: 0n,
|
|
38
|
+
invest: 0n,
|
|
39
|
+
reward: 0n,
|
|
40
|
+
other: 0n,
|
|
41
|
+
};
|
|
42
|
+
let total = 0n;
|
|
43
|
+
for (const entry of this.earnLog) {
|
|
44
|
+
const amt = BigInt(entry.amount);
|
|
45
|
+
byCategory[entry.category] += amt;
|
|
46
|
+
total += amt;
|
|
47
|
+
}
|
|
48
|
+
return { total, byCategory, entries: [...this.earnLog] };
|
|
49
|
+
}
|
|
50
|
+
getEntries() {
|
|
51
|
+
return [...this.earnLog];
|
|
52
|
+
}
|
|
53
|
+
getEntriesByCategory(category) {
|
|
54
|
+
return this.earnLog.filter((e) => e.category === category);
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* 加载持久化收入日志。
|
|
58
|
+
*/
|
|
59
|
+
async load() {
|
|
60
|
+
try {
|
|
61
|
+
const raw = await readFile(join(this.config.dataDir, EARN_LOG_FILE), "utf-8");
|
|
62
|
+
const parsed = JSON.parse(raw);
|
|
63
|
+
this.earnLog = Array.isArray(parsed) ? parsed : [];
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
this.earnLog = [];
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* 持久化收入日志到 dataDir。
|
|
71
|
+
*/
|
|
72
|
+
async save() {
|
|
73
|
+
await mkdir(this.config.dataDir, { recursive: true });
|
|
74
|
+
await writeFile(join(this.config.dataDir, EARN_LOG_FILE), JSON.stringify(this.earnLog, null, 2));
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=earn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"earn.js","sourceRoot":"","sources":["../../src/finance/earn.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAyBjC,0EAA0E;AAE1E,MAAM,aAAa,GAAG,sBAAsB,CAAC;AAE7C;;GAEG;AACH,MAAM,OAAO,WAAW;IAGF;IAFZ,OAAO,GAAgB,EAAE,CAAC;IAElC,YAAoB,MAAyB;QAAzB,WAAM,GAAN,MAAM,CAAmB;IAAG,CAAC;IAEjD;;OAEG;IACH,MAAM,CACJ,QAAsB,EACtB,MAAc,EACd,MAAe,EACf,IAAa;QAEb,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;YAChB,QAAQ;YACR,MAAM,EAAE,MAAM,CAAC,QAAQ,EAAE;YACzB,MAAM;YACN,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,IAAI;SACL,CAAC,CAAC;IACL,CAAC;IAED;;OAEG;IACH,UAAU;QACR,MAAM,UAAU,GAAiC;YAC/C,KAAK,EAAE,EAAE;YACT,MAAM,EAAE,EAAE;YACV,MAAM,EAAE,EAAE;YACV,KAAK,EAAE,EAAE;SACV,CAAC;QACF,IAAI,KAAK,GAAG,EAAE,CAAC;QACf,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjC,MAAM,GAAG,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;YACjC,UAAU,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,GAAG,CAAC;YAClC,KAAK,IAAI,GAAG,CAAC;QACf,CAAC;QACD,OAAO,EAAE,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC;IAC3D,CAAC;IAED,UAAU;QACR,OAAO,CAAC,GAAG,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,oBAAoB,CAAC,QAAsB;QACzC,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,QAAQ,CAAC,CAAC;IAC7D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,QAAQ,CACxB,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,EACxC,OAAO,CACR,CAAC;YACF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;QACrD,CAAC;QAAC,MAAM,CAAC;YACP,IAAI,CAAC,OAAO,GAAG,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACtD,MAAM,SAAS,CACb,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,aAAa,CAAC,EACxC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CACtC,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { AgentWallet } from "./wallet.js";
|
|
2
|
+
export type { GasRefillResult } from "./action/gas-refill.js";
|
|
3
|
+
export { SpendManager, type SpendManagerConfig, type SpendCategory, type SpendEntry, type SpendingSummary, } from "./spend.js";
|
|
4
|
+
export { EarnManager, type EarnCategory, type EarnEntry, type EarningSummary, type EarnManagerConfig, } from "./earn.js";
|
|
5
|
+
export * from "./action/index.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/finance/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAI1C,OAAO,EACL,YAAY,GAKb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,WAAW,GAKZ,MAAM,WAAW,CAAC;AAEnB,cAAc,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* spend.ts — Agent 支出管理
|
|
3
|
+
*
|
|
4
|
+
* 自持数据与持久化,负责记录、汇总 agent 的各类支出(gas、llm、invest、other)。
|
|
5
|
+
*/
|
|
6
|
+
export type SpendCategory = "gas" | "llm" | "invest" | "other";
|
|
7
|
+
export interface SpendEntry {
|
|
8
|
+
category: SpendCategory;
|
|
9
|
+
amount: string;
|
|
10
|
+
txHash?: string;
|
|
11
|
+
timestamp: string;
|
|
12
|
+
}
|
|
13
|
+
export interface SpendingSummary {
|
|
14
|
+
total: bigint;
|
|
15
|
+
byCategory: Record<SpendCategory, bigint>;
|
|
16
|
+
entries: SpendEntry[];
|
|
17
|
+
}
|
|
18
|
+
export interface SpendManagerConfig {
|
|
19
|
+
dataDir: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* 管理当前 agent 的支出:记录、分类、汇总、持久化。
|
|
23
|
+
* 自持 spendLog 数据,不依赖 AgentWallet。
|
|
24
|
+
*/
|
|
25
|
+
export declare class SpendManager {
|
|
26
|
+
private config;
|
|
27
|
+
private spendLog;
|
|
28
|
+
constructor(config: SpendManagerConfig);
|
|
29
|
+
/**
|
|
30
|
+
* 记录一笔支出。
|
|
31
|
+
*/
|
|
32
|
+
record(category: SpendCategory, amount: bigint, txHash?: string): void;
|
|
33
|
+
/**
|
|
34
|
+
* 获取当前支出汇总(按类别与总览)。
|
|
35
|
+
*/
|
|
36
|
+
getSummary(): SpendingSummary;
|
|
37
|
+
/**
|
|
38
|
+
* 获取原始支出条目列表。
|
|
39
|
+
*/
|
|
40
|
+
getEntries(): SpendEntry[];
|
|
41
|
+
/**
|
|
42
|
+
* 按类别筛选支出条目。
|
|
43
|
+
*/
|
|
44
|
+
getEntriesByCategory(category: SpendCategory): SpendEntry[];
|
|
45
|
+
/**
|
|
46
|
+
* 从 dataDir 加载持久化的支出日志。
|
|
47
|
+
*/
|
|
48
|
+
load(): Promise<void>;
|
|
49
|
+
/**
|
|
50
|
+
* 持久化支出日志到 dataDir。
|
|
51
|
+
*/
|
|
52
|
+
save(): Promise<void>;
|
|
53
|
+
}
|