@agether/sdk 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +480 -0
- package/dist/cli.d.mts +2 -0
- package/dist/cli.d.ts +19 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +2149 -0
- package/dist/cli.mjs +0 -0
- package/dist/clients/AgentIdentityClient.d.ts +163 -0
- package/dist/clients/AgentIdentityClient.d.ts.map +1 -0
- package/dist/clients/AgentIdentityClient.js +293 -0
- package/dist/clients/AgetherClient.d.ts +101 -0
- package/dist/clients/AgetherClient.d.ts.map +1 -0
- package/dist/clients/AgetherClient.js +272 -0
- package/dist/clients/ScoringClient.d.ts +138 -0
- package/dist/clients/ScoringClient.d.ts.map +1 -0
- package/dist/clients/ScoringClient.js +135 -0
- package/dist/clients/VaultClient.d.ts +62 -0
- package/dist/clients/VaultClient.d.ts.map +1 -0
- package/dist/clients/VaultClient.js +157 -0
- package/dist/clients/WalletClient.d.ts +73 -0
- package/dist/clients/WalletClient.d.ts.map +1 -0
- package/dist/clients/WalletClient.js +174 -0
- package/dist/clients/X402Client.d.ts +61 -0
- package/dist/clients/X402Client.d.ts.map +1 -0
- package/dist/clients/X402Client.js +303 -0
- package/dist/index.d.mts +932 -0
- package/dist/index.d.ts +932 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1680 -0
- package/dist/index.mjs +1610 -0
- package/dist/types/index.d.ts +220 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +52 -0
- package/dist/utils/abis.d.ts +21 -0
- package/dist/utils/abis.d.ts.map +1 -0
- package/dist/utils/abis.js +134 -0
- package/dist/utils/config.d.ts +31 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +117 -0
- package/dist/utils/format.d.ts +44 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +75 -0
- package/package.json +57 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VaultClient - Client for liquidity providers
|
|
3
|
+
*/
|
|
4
|
+
import { Contract } from 'ethers';
|
|
5
|
+
import { LP_VAULT_ABI, ERC20_ABI } from '../utils/abis';
|
|
6
|
+
export class VaultClient {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
this.config = options.config;
|
|
9
|
+
this.signer = options.signer;
|
|
10
|
+
this.vault = new Contract(options.config.contracts.lpVault, LP_VAULT_ABI, options.signer);
|
|
11
|
+
}
|
|
12
|
+
// ============ LP Operations ============
|
|
13
|
+
/**
|
|
14
|
+
* Deposit assets to vault
|
|
15
|
+
*/
|
|
16
|
+
async deposit(amount) {
|
|
17
|
+
// Approve first
|
|
18
|
+
const asset = await this.getAsset();
|
|
19
|
+
const allowance = await asset.allowance(await this.signer.getAddress(), this.config.contracts.lpVault);
|
|
20
|
+
if (allowance < amount) {
|
|
21
|
+
const approveTx = await asset.approve(this.config.contracts.lpVault, amount);
|
|
22
|
+
await approveTx.wait();
|
|
23
|
+
}
|
|
24
|
+
const receiver = await this.signer.getAddress();
|
|
25
|
+
const tx = await this.vault.deposit(amount, receiver);
|
|
26
|
+
const receipt = await tx.wait();
|
|
27
|
+
return {
|
|
28
|
+
txHash: receipt.hash,
|
|
29
|
+
blockNumber: receipt.blockNumber,
|
|
30
|
+
status: receipt.status === 1 ? 'success' : 'failed',
|
|
31
|
+
gasUsed: receipt.gasUsed,
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Withdraw assets from vault
|
|
36
|
+
*/
|
|
37
|
+
async withdraw(amount) {
|
|
38
|
+
const receiver = await this.signer.getAddress();
|
|
39
|
+
const owner = receiver;
|
|
40
|
+
const tx = await this.vault.withdraw(amount, receiver, owner);
|
|
41
|
+
const receipt = await tx.wait();
|
|
42
|
+
return {
|
|
43
|
+
txHash: receipt.hash,
|
|
44
|
+
blockNumber: receipt.blockNumber,
|
|
45
|
+
status: receipt.status === 1 ? 'success' : 'failed',
|
|
46
|
+
gasUsed: receipt.gasUsed,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Redeem shares for assets
|
|
51
|
+
*/
|
|
52
|
+
async redeem(shares) {
|
|
53
|
+
const receiver = await this.signer.getAddress();
|
|
54
|
+
const owner = receiver;
|
|
55
|
+
const tx = await this.vault.redeem(shares, receiver, owner);
|
|
56
|
+
const receipt = await tx.wait();
|
|
57
|
+
return {
|
|
58
|
+
txHash: receipt.hash,
|
|
59
|
+
blockNumber: receipt.blockNumber,
|
|
60
|
+
status: receipt.status === 1 ? 'success' : 'failed',
|
|
61
|
+
gasUsed: receipt.gasUsed,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
// ============ View Functions ============
|
|
65
|
+
/**
|
|
66
|
+
* Get vault statistics
|
|
67
|
+
*/
|
|
68
|
+
async getStats() {
|
|
69
|
+
const [totalAssets, totalBorrowed, availableLiquidity] = await Promise.all([
|
|
70
|
+
this.vault.totalAssets(),
|
|
71
|
+
this.vault.totalBorrowed(),
|
|
72
|
+
this.vault.availableLiquidity(),
|
|
73
|
+
]);
|
|
74
|
+
const utilizationRate = totalAssets > 0n
|
|
75
|
+
? Number((totalBorrowed * 10000n) / totalAssets) / 100
|
|
76
|
+
: 0;
|
|
77
|
+
const totalSupply = await this.vault.totalSupply();
|
|
78
|
+
const sharePrice = totalSupply > 0n
|
|
79
|
+
? (totalAssets * BigInt(1e18)) / totalSupply
|
|
80
|
+
: BigInt(1e18);
|
|
81
|
+
return {
|
|
82
|
+
totalAssets,
|
|
83
|
+
totalBorrowed,
|
|
84
|
+
availableLiquidity,
|
|
85
|
+
utilizationRate,
|
|
86
|
+
sharePrice,
|
|
87
|
+
};
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Get LP position
|
|
91
|
+
*/
|
|
92
|
+
async getPosition(address) {
|
|
93
|
+
const owner = address || await this.signer.getAddress();
|
|
94
|
+
const shares = await this.vault.balanceOf(owner);
|
|
95
|
+
const assets = await this.vault.convertToAssets(shares);
|
|
96
|
+
// Pending yield = current value - deposited value
|
|
97
|
+
// For simplicity, we return 0 here (would need to track deposits)
|
|
98
|
+
const pendingYield = 0n;
|
|
99
|
+
return {
|
|
100
|
+
shares,
|
|
101
|
+
assets,
|
|
102
|
+
pendingYield,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Preview deposit (how many shares for assets)
|
|
107
|
+
*/
|
|
108
|
+
async previewDeposit(assets) {
|
|
109
|
+
return await this.vault.previewDeposit(assets);
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* Preview withdraw (how many assets for shares)
|
|
113
|
+
*/
|
|
114
|
+
async previewRedeem(shares) {
|
|
115
|
+
return await this.vault.previewRedeem(shares);
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Check if withdrawal is allowed (sufficient liquidity)
|
|
119
|
+
*/
|
|
120
|
+
async canWithdraw(assets) {
|
|
121
|
+
const liquidity = await this.vault.availableLiquidity();
|
|
122
|
+
return liquidity >= assets;
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* Get current APY estimate
|
|
126
|
+
*/
|
|
127
|
+
async estimateAPY() {
|
|
128
|
+
const stats = await this.getStats();
|
|
129
|
+
// Simplified APY calculation
|
|
130
|
+
// Real implementation would use historical data
|
|
131
|
+
const avgAPR = 1200; // 12% average lending rate
|
|
132
|
+
const protocolFee = 1000; // 10% protocol fee
|
|
133
|
+
const lpYield = (avgAPR * (10000 - protocolFee)) / 10000;
|
|
134
|
+
const effectiveYield = (lpYield * stats.utilizationRate) / 100;
|
|
135
|
+
return effectiveYield / 100; // Convert bps to percentage
|
|
136
|
+
}
|
|
137
|
+
// ============ Utility ============
|
|
138
|
+
async getAsset() {
|
|
139
|
+
if (!this.asset) {
|
|
140
|
+
const assetAddress = await this.vault.asset();
|
|
141
|
+
this.asset = new Contract(assetAddress, ERC20_ABI, this.signer);
|
|
142
|
+
}
|
|
143
|
+
return this.asset;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Get underlying asset address
|
|
147
|
+
*/
|
|
148
|
+
async getAssetAddress() {
|
|
149
|
+
return await this.vault.asset();
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Get vault share token address
|
|
153
|
+
*/
|
|
154
|
+
getVaultAddress() {
|
|
155
|
+
return this.config.contracts.lpVault;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WalletClient - SDK for AgentAccount (smart wallet) operations (v2)
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Account creation and lookup via AccountFactory
|
|
6
|
+
* - Funding and withdrawing tokens
|
|
7
|
+
* - Drawing/repaying credit via AgentAccount
|
|
8
|
+
* - Token balance queries
|
|
9
|
+
*/
|
|
10
|
+
export interface WalletInfo {
|
|
11
|
+
address: string;
|
|
12
|
+
agentId: bigint;
|
|
13
|
+
owner: string;
|
|
14
|
+
ethBalance: bigint;
|
|
15
|
+
usdcBalance: bigint;
|
|
16
|
+
}
|
|
17
|
+
export interface ProviderStatus {
|
|
18
|
+
provider: string;
|
|
19
|
+
isEligible: boolean;
|
|
20
|
+
totalDebt: bigint;
|
|
21
|
+
maxDrawable: bigint;
|
|
22
|
+
}
|
|
23
|
+
export interface MorphoMarketParams {
|
|
24
|
+
loanToken: string;
|
|
25
|
+
collateralToken: string;
|
|
26
|
+
oracle: string;
|
|
27
|
+
irm: string;
|
|
28
|
+
lltv: bigint;
|
|
29
|
+
}
|
|
30
|
+
export interface PaymentProof {
|
|
31
|
+
recipient: string;
|
|
32
|
+
amount: bigint;
|
|
33
|
+
nonce: bigint;
|
|
34
|
+
deadline: bigint;
|
|
35
|
+
signature: string;
|
|
36
|
+
}
|
|
37
|
+
export interface WalletClientConfig {
|
|
38
|
+
rpcUrl: string;
|
|
39
|
+
chainId: number;
|
|
40
|
+
factoryAddress: string;
|
|
41
|
+
usdcAddress?: string;
|
|
42
|
+
privateKey?: string;
|
|
43
|
+
}
|
|
44
|
+
export declare class WalletClient {
|
|
45
|
+
private provider;
|
|
46
|
+
private privateKey;
|
|
47
|
+
private factoryAddress;
|
|
48
|
+
private usdcAddress;
|
|
49
|
+
private chainId;
|
|
50
|
+
private rpcUrl;
|
|
51
|
+
constructor(config: WalletClientConfig);
|
|
52
|
+
/**
|
|
53
|
+
* Create a fresh signer to avoid nonce caching issues
|
|
54
|
+
*/
|
|
55
|
+
private getFreshSigner;
|
|
56
|
+
private getFactoryContract;
|
|
57
|
+
private getAccountContract;
|
|
58
|
+
getChainId(): number;
|
|
59
|
+
accountExists(agentId: bigint): Promise<boolean>;
|
|
60
|
+
getAccount(agentId: bigint): Promise<string | null>;
|
|
61
|
+
predictAddress(agentId: bigint): Promise<string>;
|
|
62
|
+
createAccount(agentId: bigint): Promise<string>;
|
|
63
|
+
totalAccounts(): Promise<bigint>;
|
|
64
|
+
getWalletInfo(accountAddress: string): Promise<WalletInfo>;
|
|
65
|
+
getProviderStatus(accountAddress: string, creditProvider: string): Promise<ProviderStatus>;
|
|
66
|
+
fundAccount(accountAddress: string, tokenAddress: string, amount: bigint): Promise<string>;
|
|
67
|
+
withdraw(accountAddress: string, tokenAddress: string, amount: bigint, to?: string): Promise<string>;
|
|
68
|
+
drawCredit(accountAddress: string, creditProvider: string, amount: bigint): Promise<string>;
|
|
69
|
+
repayCredit(accountAddress: string, creditProvider: string, amount: bigint): Promise<string>;
|
|
70
|
+
execute(accountAddress: string, target: string, value: bigint, data: string): Promise<string>;
|
|
71
|
+
generatePaymentMessageHash(accountAddress: string, recipient: string, amount: bigint, nonce: bigint, deadline: bigint, chainId: number): string;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=WalletClient.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WalletClient.d.ts","sourceRoot":"","sources":["../../src/clients/WalletClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WalletClient - SDK for AgentAccount (smart wallet) operations (v2)
|
|
3
|
+
*
|
|
4
|
+
* Handles:
|
|
5
|
+
* - Account creation and lookup via AccountFactory
|
|
6
|
+
* - Funding and withdrawing tokens
|
|
7
|
+
* - Drawing/repaying credit via AgentAccount
|
|
8
|
+
* - Token balance queries
|
|
9
|
+
*/
|
|
10
|
+
import { ethers, Contract, Wallet } from 'ethers';
|
|
11
|
+
import { ACCOUNT_FACTORY_ABI, AGENT_ACCOUNT_ABI, CREDIT_PROVIDER_ABI, ERC20_ABI, } from '../utils/abis';
|
|
12
|
+
// ============ Client ============
|
|
13
|
+
export class WalletClient {
|
|
14
|
+
constructor(config) {
|
|
15
|
+
this.privateKey = null;
|
|
16
|
+
this.factoryAddress = config.factoryAddress;
|
|
17
|
+
this.usdcAddress = config.usdcAddress || ethers.ZeroAddress;
|
|
18
|
+
this.chainId = config.chainId;
|
|
19
|
+
this.rpcUrl = config.rpcUrl;
|
|
20
|
+
this.provider = new ethers.JsonRpcProvider(config.rpcUrl);
|
|
21
|
+
this.privateKey = config.privateKey || null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a fresh signer to avoid nonce caching issues
|
|
25
|
+
*/
|
|
26
|
+
getFreshSigner() {
|
|
27
|
+
if (!this.privateKey) {
|
|
28
|
+
throw new Error('Signer not configured - provide privateKey');
|
|
29
|
+
}
|
|
30
|
+
const freshProvider = new ethers.JsonRpcProvider(this.rpcUrl);
|
|
31
|
+
return new Wallet(this.privateKey, freshProvider);
|
|
32
|
+
}
|
|
33
|
+
getFactoryContract() {
|
|
34
|
+
if (this.privateKey) {
|
|
35
|
+
return new Contract(this.factoryAddress, ACCOUNT_FACTORY_ABI, this.getFreshSigner());
|
|
36
|
+
}
|
|
37
|
+
return new Contract(this.factoryAddress, ACCOUNT_FACTORY_ABI, this.provider);
|
|
38
|
+
}
|
|
39
|
+
getAccountContract(accountAddress) {
|
|
40
|
+
if (this.privateKey) {
|
|
41
|
+
return new Contract(accountAddress, AGENT_ACCOUNT_ABI, this.getFreshSigner());
|
|
42
|
+
}
|
|
43
|
+
return new Contract(accountAddress, AGENT_ACCOUNT_ABI, this.provider);
|
|
44
|
+
}
|
|
45
|
+
getChainId() {
|
|
46
|
+
return this.chainId;
|
|
47
|
+
}
|
|
48
|
+
// ============ Account Factory ============
|
|
49
|
+
async accountExists(agentId) {
|
|
50
|
+
const factory = this.getFactoryContract();
|
|
51
|
+
return factory.accountExists(agentId);
|
|
52
|
+
}
|
|
53
|
+
async getAccount(agentId) {
|
|
54
|
+
const factory = this.getFactoryContract();
|
|
55
|
+
const address = await factory.getAccount(agentId);
|
|
56
|
+
if (address === ethers.ZeroAddress) {
|
|
57
|
+
return null;
|
|
58
|
+
}
|
|
59
|
+
return address;
|
|
60
|
+
}
|
|
61
|
+
async predictAddress(agentId) {
|
|
62
|
+
const factory = this.getFactoryContract();
|
|
63
|
+
return factory.predictAddress(agentId);
|
|
64
|
+
}
|
|
65
|
+
async createAccount(agentId) {
|
|
66
|
+
if (!this.privateKey) {
|
|
67
|
+
throw new Error('Signer not configured - provide privateKey');
|
|
68
|
+
}
|
|
69
|
+
const factory = this.getFactoryContract();
|
|
70
|
+
const tx = await factory.createAccount(agentId);
|
|
71
|
+
await tx.wait();
|
|
72
|
+
const account = await this.getAccount(agentId);
|
|
73
|
+
if (!account) {
|
|
74
|
+
throw new Error('Account creation failed');
|
|
75
|
+
}
|
|
76
|
+
return account;
|
|
77
|
+
}
|
|
78
|
+
async totalAccounts() {
|
|
79
|
+
const factory = this.getFactoryContract();
|
|
80
|
+
return factory.totalAccounts();
|
|
81
|
+
}
|
|
82
|
+
// ============ Account Info ============
|
|
83
|
+
async getWalletInfo(accountAddress) {
|
|
84
|
+
const account = this.getAccountContract(accountAddress);
|
|
85
|
+
const [agentId, owner, ethBalance] = await Promise.all([
|
|
86
|
+
account.agentId(),
|
|
87
|
+
account.owner(),
|
|
88
|
+
account.ethBalance(),
|
|
89
|
+
]);
|
|
90
|
+
let usdcBalance = 0n;
|
|
91
|
+
if (this.usdcAddress !== ethers.ZeroAddress) {
|
|
92
|
+
usdcBalance = await account.balanceOf(this.usdcAddress);
|
|
93
|
+
}
|
|
94
|
+
return {
|
|
95
|
+
address: accountAddress,
|
|
96
|
+
agentId: BigInt(agentId),
|
|
97
|
+
owner,
|
|
98
|
+
ethBalance: BigInt(ethBalance),
|
|
99
|
+
usdcBalance: BigInt(usdcBalance),
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async getProviderStatus(accountAddress, creditProvider) {
|
|
103
|
+
const provider = new Contract(creditProvider, CREDIT_PROVIDER_ABI, this.provider);
|
|
104
|
+
const [isEligible, totalDebt, maxDrawable] = await Promise.all([
|
|
105
|
+
provider.isEligible(accountAddress),
|
|
106
|
+
provider.getTotalDebt(accountAddress),
|
|
107
|
+
provider.maxDrawable(accountAddress),
|
|
108
|
+
]);
|
|
109
|
+
return {
|
|
110
|
+
provider: creditProvider,
|
|
111
|
+
isEligible,
|
|
112
|
+
totalDebt: BigInt(totalDebt),
|
|
113
|
+
maxDrawable: BigInt(maxDrawable),
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
// ============ Fund / Withdraw ============
|
|
117
|
+
async fundAccount(accountAddress, tokenAddress, amount) {
|
|
118
|
+
if (!this.privateKey) {
|
|
119
|
+
throw new Error('Signer not configured');
|
|
120
|
+
}
|
|
121
|
+
const signer = this.getFreshSigner();
|
|
122
|
+
const token = new Contract(tokenAddress, ERC20_ABI, signer);
|
|
123
|
+
const approveTx = await token.approve(accountAddress, amount);
|
|
124
|
+
await approveTx.wait();
|
|
125
|
+
const signer2 = this.getFreshSigner();
|
|
126
|
+
const account = new Contract(accountAddress, AGENT_ACCOUNT_ABI, signer2);
|
|
127
|
+
const tx = await account.fund(tokenAddress, amount);
|
|
128
|
+
const receipt = await tx.wait();
|
|
129
|
+
return receipt.hash;
|
|
130
|
+
}
|
|
131
|
+
async withdraw(accountAddress, tokenAddress, amount, to) {
|
|
132
|
+
if (!this.privateKey) {
|
|
133
|
+
throw new Error('Signer not configured');
|
|
134
|
+
}
|
|
135
|
+
const account = this.getAccountContract(accountAddress);
|
|
136
|
+
const recipient = to || (await this.getFreshSigner().getAddress());
|
|
137
|
+
const tx = await account.withdraw(tokenAddress, amount, recipient);
|
|
138
|
+
const receipt = await tx.wait();
|
|
139
|
+
return receipt.hash;
|
|
140
|
+
}
|
|
141
|
+
// ============ Credit Operations ============
|
|
142
|
+
async drawCredit(accountAddress, creditProvider, amount) {
|
|
143
|
+
if (!this.privateKey) {
|
|
144
|
+
throw new Error('Signer not configured');
|
|
145
|
+
}
|
|
146
|
+
const account = this.getAccountContract(accountAddress);
|
|
147
|
+
const tx = await account.drawCredit(creditProvider, amount);
|
|
148
|
+
const receipt = await tx.wait();
|
|
149
|
+
return receipt.hash;
|
|
150
|
+
}
|
|
151
|
+
async repayCredit(accountAddress, creditProvider, amount) {
|
|
152
|
+
if (!this.privateKey) {
|
|
153
|
+
throw new Error('Signer not configured');
|
|
154
|
+
}
|
|
155
|
+
const account = this.getAccountContract(accountAddress);
|
|
156
|
+
const tx = await account.repayCredit(creditProvider, amount);
|
|
157
|
+
const receipt = await tx.wait();
|
|
158
|
+
return receipt.hash;
|
|
159
|
+
}
|
|
160
|
+
// ============ Generic Execute ============
|
|
161
|
+
async execute(accountAddress, target, value, data) {
|
|
162
|
+
if (!this.privateKey) {
|
|
163
|
+
throw new Error('Signer not configured');
|
|
164
|
+
}
|
|
165
|
+
const account = this.getAccountContract(accountAddress);
|
|
166
|
+
const tx = await account.execute(target, value, data);
|
|
167
|
+
const receipt = await tx.wait();
|
|
168
|
+
return receipt.hash;
|
|
169
|
+
}
|
|
170
|
+
// ============ Utility ============
|
|
171
|
+
generatePaymentMessageHash(accountAddress, recipient, amount, nonce, deadline, chainId) {
|
|
172
|
+
return ethers.keccak256(ethers.AbiCoder.defaultAbiCoder().encode(['address', 'uint256', 'uint256', 'uint256', 'uint256', 'address'], [recipient, amount, nonce, deadline, chainId, accountAddress]));
|
|
173
|
+
}
|
|
174
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402 HTTP Client — Make paid API calls via the x402 protocol (v2)
|
|
3
|
+
*
|
|
4
|
+
* Implements the Coinbase x402 spec:
|
|
5
|
+
* https://github.com/coinbase/x402
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Client → Resource Server (normal request)
|
|
9
|
+
* 2. Resource Server → 402 with PaymentRequired JSON body
|
|
10
|
+
* Body: { x402Version, error, resource, accepts: [PaymentRequirements…] }
|
|
11
|
+
* 3. Client picks a PaymentRequirements from `accepts`,
|
|
12
|
+
* signs an EIP-3009 transferWithAuthorization (EIP-712 typed data),
|
|
13
|
+
* builds a PaymentPayload, base64-encodes it as PAYMENT-SIGNATURE header
|
|
14
|
+
* 4. Client → Resource Server (retries with PAYMENT-SIGNATURE)
|
|
15
|
+
* 5. Resource Server forwards to Facilitator /verify → /settle
|
|
16
|
+
* 6. Resource Server → 200 + data (or error)
|
|
17
|
+
*
|
|
18
|
+
* Chain support: Base (8453), Ethereum (1), and Hardhat fork (31337).
|
|
19
|
+
* USDC domain is resolved per-chain from USDC_DOMAINS map.
|
|
20
|
+
*/
|
|
21
|
+
export interface X402Config {
|
|
22
|
+
privateKey: string;
|
|
23
|
+
rpcUrl: string;
|
|
24
|
+
backendUrl: string;
|
|
25
|
+
agentId?: string;
|
|
26
|
+
accountAddress?: string;
|
|
27
|
+
}
|
|
28
|
+
export interface X402Response<T = unknown> {
|
|
29
|
+
success: boolean;
|
|
30
|
+
data?: T;
|
|
31
|
+
error?: string;
|
|
32
|
+
paymentInfo?: {
|
|
33
|
+
amount: string;
|
|
34
|
+
asset: string;
|
|
35
|
+
network: string;
|
|
36
|
+
txHash?: string;
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** One item inside the `accepts` array returned by the resource server */
|
|
40
|
+
export interface PaymentRequirements {
|
|
41
|
+
scheme: string;
|
|
42
|
+
network: string;
|
|
43
|
+
amount: string;
|
|
44
|
+
asset: string;
|
|
45
|
+
payTo: string;
|
|
46
|
+
maxTimeoutSeconds: number;
|
|
47
|
+
extra?: Record<string, unknown>;
|
|
48
|
+
}
|
|
49
|
+
export declare class X402Client {
|
|
50
|
+
private wallet;
|
|
51
|
+
private config;
|
|
52
|
+
constructor(config: X402Config);
|
|
53
|
+
get<T = unknown>(url: string, opts?: RequestInit): Promise<X402Response<T>>;
|
|
54
|
+
post<T = unknown>(url: string, body?: unknown, opts?: RequestInit): Promise<X402Response<T>>;
|
|
55
|
+
getAddress(): string;
|
|
56
|
+
private request;
|
|
57
|
+
private parsePaymentRequired;
|
|
58
|
+
private buildPaymentPayload;
|
|
59
|
+
private riskCheck;
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=X402Client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"X402Client.d.ts","sourceRoot":"","sources":["../../src/clients/X402Client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAMH,MAAM,WAAW,UAAU;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,GAAG,OAAO;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE;QACZ,MAAM,EAAE,MAAM,CAAC;QACf,KAAK,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;QAChB,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,0EAA0E;AAC1E,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,iBAAiB,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC;AA+BD,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAa;gBAEf,MAAM,EAAE,UAAU;IAMxB,GAAG,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IAI3E,IAAI,CAAC,CAAC,GAAG,OAAO,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IASlG,UAAU,IAAI,MAAM;YAMN,OAAO;YAyFP,oBAAoB;YA2DpB,mBAAmB;YAgGnB,SAAS;CA6BxB"}
|