@agether/sdk 2.3.4 → 2.4.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/cli.d.ts +27 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +341 -1
- package/dist/clients/AgentIdentityClient.d.ts +188 -0
- package/dist/clients/AgentIdentityClient.d.ts.map +1 -0
- package/dist/clients/AgentIdentityClient.js +337 -0
- package/dist/clients/AgetherClient.d.ts +74 -0
- package/dist/clients/AgetherClient.d.ts.map +1 -0
- package/dist/clients/AgetherClient.js +172 -0
- package/dist/clients/MorphoClient.d.ts +482 -0
- package/dist/clients/MorphoClient.d.ts.map +1 -0
- package/dist/clients/MorphoClient.js +1717 -0
- package/dist/clients/ScoringClient.d.ts +89 -0
- package/dist/clients/ScoringClient.d.ts.map +1 -0
- package/dist/clients/ScoringClient.js +93 -0
- package/dist/clients/X402Client.d.ts +168 -0
- package/dist/clients/X402Client.d.ts.map +1 -0
- package/dist/clients/X402Client.js +378 -0
- package/dist/index.d.mts +87 -1
- package/dist/index.d.ts +87 -1
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +341 -1
- package/dist/index.mjs +341 -1
- package/dist/types/index.d.ts +132 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +46 -0
- package/dist/utils/abis.d.ts +29 -0
- package/dist/utils/abis.d.ts.map +1 -0
- package/dist/utils/abis.js +139 -0
- package/dist/utils/config.d.ts +36 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +168 -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 +1 -1
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* x402 HTTP Client — Make paid API calls via the x402 protocol (v2)
|
|
3
|
+
*
|
|
4
|
+
* Built on top of the official @x402/fetch + @x402/evm SDK.
|
|
5
|
+
* https://docs.x402.org/getting-started/quickstart-for-buyers
|
|
6
|
+
*
|
|
7
|
+
* Flow:
|
|
8
|
+
* 1. Client → Resource Server (normal request)
|
|
9
|
+
* 2. Resource Server → 402 with PAYMENT-REQUIRED header (base64 JSON)
|
|
10
|
+
* 3. @x402/fetch auto-picks PaymentRequirements, signs EIP-3009 via EVM scheme
|
|
11
|
+
* 4. Client → Resource Server (retries with PAYMENT-SIGNATURE header)
|
|
12
|
+
* 5. Resource Server → verifies via facilitator → settles → 200 + data
|
|
13
|
+
*
|
|
14
|
+
* Auto-Draw: When autoDraw is enabled and USDC balance is insufficient,
|
|
15
|
+
* the client automatically borrows from Morpho Blue before paying.
|
|
16
|
+
*
|
|
17
|
+
* Spending Limits: Optional daily spending cap (dailySpendLimitUsdc) and
|
|
18
|
+
* yield-limited spending (yieldLimitedSpending) to keep borrows within
|
|
19
|
+
* theoretical collateral yield.
|
|
20
|
+
*
|
|
21
|
+
* Chain support: Base (8453), Base Sepolia (84532), Ethereum (1).
|
|
22
|
+
*/
|
|
23
|
+
import { wrapFetchWithPayment } from '@x402/fetch';
|
|
24
|
+
import { x402Client } from '@x402/core/client';
|
|
25
|
+
import { registerExactEvmScheme } from '@x402/evm/exact/client';
|
|
26
|
+
import { privateKeyToAccount, toAccount } from 'viem/accounts';
|
|
27
|
+
// ──────────────────── Client ────────────────────
|
|
28
|
+
export class X402Client {
|
|
29
|
+
constructor(config) {
|
|
30
|
+
this.config = config;
|
|
31
|
+
// ── Step 1: Resolve base signer from privateKey or walletClient ──
|
|
32
|
+
let baseSigner;
|
|
33
|
+
if ('walletClient' in config && config.walletClient) {
|
|
34
|
+
// External WalletClient mode (Privy, Turnkey, MetaMask, etc.)
|
|
35
|
+
const wc = config.walletClient;
|
|
36
|
+
const account = wc.account;
|
|
37
|
+
if (!account) {
|
|
38
|
+
throw new Error('X402Client: walletClient must have an attached account. ' +
|
|
39
|
+
'Pass an account when creating the WalletClient or use privateKey mode instead.');
|
|
40
|
+
}
|
|
41
|
+
this.address = account.address;
|
|
42
|
+
// Adapt WalletClient to the signer interface expected by @x402/evm
|
|
43
|
+
baseSigner = {
|
|
44
|
+
address: account.address,
|
|
45
|
+
signTypedData: (msg) => wc.signTypedData({
|
|
46
|
+
account,
|
|
47
|
+
domain: msg.domain,
|
|
48
|
+
types: msg.types,
|
|
49
|
+
primaryType: msg.primaryType,
|
|
50
|
+
message: msg.message,
|
|
51
|
+
}),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
else if ('privateKey' in config && config.privateKey) {
|
|
55
|
+
// Private key mode (existing behavior — SDK manages wallet)
|
|
56
|
+
const privateKey = config.privateKey.startsWith('0x')
|
|
57
|
+
? config.privateKey
|
|
58
|
+
: `0x${config.privateKey}`;
|
|
59
|
+
const account = privateKeyToAccount(privateKey);
|
|
60
|
+
this.address = account.address;
|
|
61
|
+
baseSigner = account;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
throw new Error('X402Client: provide either privateKey or walletClient in config.');
|
|
65
|
+
}
|
|
66
|
+
// ── Step 2: Wrap signer for smart-wallet (AgentAccount) if accountAddress is set ──
|
|
67
|
+
// When accountAddress is provided, EIP-3009 `from` must be the contract, and
|
|
68
|
+
// the signature must be >65 bytes so the x402 facilitator routes through USDC's
|
|
69
|
+
// `bytes signature` overload of transferWithAuthorization — triggering EIP-1271
|
|
70
|
+
// `isValidSignature` on the AgentAccount contract.
|
|
71
|
+
let signer;
|
|
72
|
+
if (config.accountAddress) {
|
|
73
|
+
const accountAddr = config.accountAddress;
|
|
74
|
+
const inner = baseSigner;
|
|
75
|
+
signer = toAccount({
|
|
76
|
+
address: accountAddr,
|
|
77
|
+
async signMessage({ message }) {
|
|
78
|
+
if ('signMessage' in inner && typeof inner.signMessage === 'function') {
|
|
79
|
+
return inner.signMessage({ message });
|
|
80
|
+
}
|
|
81
|
+
throw new Error('signMessage not supported by underlying signer');
|
|
82
|
+
},
|
|
83
|
+
async signTransaction(tx) {
|
|
84
|
+
if ('signTransaction' in inner && typeof inner.signTransaction === 'function') {
|
|
85
|
+
return inner.signTransaction(tx);
|
|
86
|
+
}
|
|
87
|
+
throw new Error('signTransaction not supported by underlying signer');
|
|
88
|
+
},
|
|
89
|
+
async signTypedData(typedData) {
|
|
90
|
+
const sig = await inner.signTypedData(typedData);
|
|
91
|
+
// For Safe7579: prepend validator module address so isValidSignature
|
|
92
|
+
// routes through Safe7579 → validator.isValidSignatureWithSender()
|
|
93
|
+
if (config.validatorModule) {
|
|
94
|
+
const validatorHex = config.validatorModule.replace('0x', '').toLowerCase();
|
|
95
|
+
const sigHex = sig.replace('0x', '');
|
|
96
|
+
return `0x${validatorHex}${sigHex}`;
|
|
97
|
+
}
|
|
98
|
+
// Fallback: append 00 to trigger EIP-1271 via >65 byte sig
|
|
99
|
+
return `${sig}00`;
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
this.address = accountAddr;
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
signer = baseSigner;
|
|
106
|
+
}
|
|
107
|
+
// Create x402 client and register EVM scheme (handles EIP-3009 signing)
|
|
108
|
+
const client = new x402Client();
|
|
109
|
+
registerExactEvmScheme(client, { signer });
|
|
110
|
+
// Wrap native fetch with automatic 402 payment handling
|
|
111
|
+
this.paidFetch = wrapFetchWithPayment(fetch, client);
|
|
112
|
+
// Initialize spending tracker
|
|
113
|
+
const today = new Date().toISOString().split('T')[0];
|
|
114
|
+
const dailyLimit = config.dailySpendLimitUsdc
|
|
115
|
+
? BigInt(Math.round(parseFloat(config.dailySpendLimitUsdc) * 1e6))
|
|
116
|
+
: 0n;
|
|
117
|
+
this._spendingTracker = { date: today, totalBorrowed: 0n, dailyLimit };
|
|
118
|
+
}
|
|
119
|
+
async get(url, opts) {
|
|
120
|
+
return this.request(url, { ...opts, method: 'GET' });
|
|
121
|
+
}
|
|
122
|
+
async post(url, body, opts) {
|
|
123
|
+
return this.request(url, {
|
|
124
|
+
...opts,
|
|
125
|
+
method: 'POST',
|
|
126
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
127
|
+
headers: { 'Content-Type': 'application/json', ...opts?.headers },
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
getAddress() {
|
|
131
|
+
return this.address;
|
|
132
|
+
}
|
|
133
|
+
/** Get the current spending tracker state */
|
|
134
|
+
getSpendingTracker() {
|
|
135
|
+
this._resetTrackerIfNewDay();
|
|
136
|
+
return { ...this._spendingTracker };
|
|
137
|
+
}
|
|
138
|
+
/** Get remaining daily spending allowance in USDC (human-readable) */
|
|
139
|
+
getRemainingDailyAllowance() {
|
|
140
|
+
this._resetTrackerIfNewDay();
|
|
141
|
+
if (this._spendingTracker.dailyLimit === 0n)
|
|
142
|
+
return 'unlimited';
|
|
143
|
+
const remaining = this._spendingTracker.dailyLimit - this._spendingTracker.totalBorrowed;
|
|
144
|
+
return (Number(remaining > 0n ? remaining : 0n) / 1e6).toFixed(2);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Pay with auto-draw: Make an x402 request with automatic Morpho borrowing.
|
|
148
|
+
*
|
|
149
|
+
* Flow:
|
|
150
|
+
* 1. Check USDC balance on AgentAccount
|
|
151
|
+
* 2. Probe the URL to discover payment amount (if 402)
|
|
152
|
+
* 3. If insufficient USDC, calculate deficit
|
|
153
|
+
* 4. Check spending limit
|
|
154
|
+
* 5. Borrow from Morpho via MorphoClient
|
|
155
|
+
* 6. Proceed with x402 payment
|
|
156
|
+
*/
|
|
157
|
+
async payWithAutoDraw(url, opts) {
|
|
158
|
+
const { morphoClient, ...fetchOpts } = opts || {};
|
|
159
|
+
// If auto-draw is not enabled or no morphoClient, fall back to normal request
|
|
160
|
+
if (!this.config.autoDraw || !morphoClient) {
|
|
161
|
+
return this.request(url, fetchOpts);
|
|
162
|
+
}
|
|
163
|
+
try {
|
|
164
|
+
// Step 1: Check current USDC balance on AgentAccount
|
|
165
|
+
const usdcBalance = await morphoClient.getUsdcBalance();
|
|
166
|
+
console.log(` [auto-draw] AgentAccount USDC balance: ${(Number(usdcBalance) / 1e6).toFixed(2)}`);
|
|
167
|
+
// Step 2: Probe the URL to discover payment amount
|
|
168
|
+
const paymentAmount = await this._probePaymentAmount(url, fetchOpts);
|
|
169
|
+
if (paymentAmount !== null) {
|
|
170
|
+
console.log(` [auto-draw] Payment required: ${(Number(paymentAmount) / 1e6).toFixed(6)} USDC`);
|
|
171
|
+
// Step 3: Check if we need to borrow
|
|
172
|
+
const bufferStr = this.config.autoDrawBuffer || '0.5';
|
|
173
|
+
const buffer = BigInt(Math.round(parseFloat(bufferStr) * 1e6));
|
|
174
|
+
const needed = paymentAmount + buffer;
|
|
175
|
+
if (usdcBalance < needed) {
|
|
176
|
+
const deficit = needed - usdcBalance;
|
|
177
|
+
console.log(` [auto-draw] Insufficient balance. Need to borrow ${(Number(deficit) / 1e6).toFixed(2)} USDC`);
|
|
178
|
+
// Step 4: Check spending limits
|
|
179
|
+
const limitCheck = await this._checkSpendingLimit(deficit, morphoClient);
|
|
180
|
+
if (!limitCheck.allowed) {
|
|
181
|
+
return {
|
|
182
|
+
success: false,
|
|
183
|
+
error: `Auto-draw blocked: ${limitCheck.reason}`,
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
// Step 5: Check if borrowing is possible (collateral check)
|
|
187
|
+
const maxBorrowable = await morphoClient.getMaxBorrowable();
|
|
188
|
+
if (maxBorrowable.total < deficit) {
|
|
189
|
+
return {
|
|
190
|
+
success: false,
|
|
191
|
+
error: `Auto-draw failed: insufficient collateral. Need ${(Number(deficit) / 1e6).toFixed(2)} USDC but can only borrow ${(Number(maxBorrowable.total) / 1e6).toFixed(2)} USDC more.`,
|
|
192
|
+
};
|
|
193
|
+
}
|
|
194
|
+
// Step 6: Borrow the deficit
|
|
195
|
+
const borrowAmount = (Number(deficit) / 1e6).toFixed(6);
|
|
196
|
+
console.log(` [auto-draw] Borrowing ${borrowAmount} USDC from Morpho...`);
|
|
197
|
+
const borrowResult = await morphoClient.borrow(borrowAmount);
|
|
198
|
+
console.log(` [auto-draw] Borrow tx: ${borrowResult.tx}`);
|
|
199
|
+
// Track spending
|
|
200
|
+
this._trackSpending(deficit);
|
|
201
|
+
// Step 7: Now proceed with the x402 payment
|
|
202
|
+
const result = await this.request(url, fetchOpts);
|
|
203
|
+
return {
|
|
204
|
+
...result,
|
|
205
|
+
autoDrawInfo: {
|
|
206
|
+
borrowed: borrowAmount,
|
|
207
|
+
borrowTx: borrowResult.tx,
|
|
208
|
+
reason: `USDC balance insufficient (had ${(Number(usdcBalance) / 1e6).toFixed(2)}, needed ${(Number(needed) / 1e6).toFixed(2)})`,
|
|
209
|
+
},
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// Balance sufficient or couldn't determine amount — proceed normally
|
|
214
|
+
return this.request(url, fetchOpts);
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
// If auto-draw fails, still try the normal request
|
|
218
|
+
console.log(` [auto-draw] Auto-draw check failed: ${error instanceof Error ? error.message : String(error)}. Proceeding with normal request.`);
|
|
219
|
+
return this.request(url, fetchOpts);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
// ──────────── Core request — @x402/fetch handles 402 automatically ────────────
|
|
223
|
+
async request(url, options) {
|
|
224
|
+
try {
|
|
225
|
+
console.log(` [x402] ${options?.method || 'GET'} ${url}`);
|
|
226
|
+
const response = await this.paidFetch(url, {
|
|
227
|
+
...options,
|
|
228
|
+
headers: {
|
|
229
|
+
...options?.headers,
|
|
230
|
+
'X-Agent-Id': this.config.agentId || '',
|
|
231
|
+
},
|
|
232
|
+
});
|
|
233
|
+
if (response.ok) {
|
|
234
|
+
const data = await response.json();
|
|
235
|
+
// Check for settlement response header
|
|
236
|
+
const paymentResponse = response.headers.get('PAYMENT-RESPONSE');
|
|
237
|
+
let txHash;
|
|
238
|
+
if (paymentResponse) {
|
|
239
|
+
try {
|
|
240
|
+
const settlement = JSON.parse(Buffer.from(paymentResponse, 'base64').toString('utf-8'));
|
|
241
|
+
txHash = settlement.transaction;
|
|
242
|
+
}
|
|
243
|
+
catch (e) {
|
|
244
|
+
console.warn('[agether] x402 payment response parse failed:', e instanceof Error ? e.message : e);
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
return {
|
|
248
|
+
success: true,
|
|
249
|
+
data,
|
|
250
|
+
...(txHash ? {
|
|
251
|
+
paymentInfo: {
|
|
252
|
+
amount: '',
|
|
253
|
+
asset: 'USDC',
|
|
254
|
+
network: 'eip155:8453',
|
|
255
|
+
txHash,
|
|
256
|
+
},
|
|
257
|
+
} : {}),
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
// If we get here, @x402/fetch already tried to pay but the server rejected
|
|
261
|
+
const errBody = await response.text();
|
|
262
|
+
return {
|
|
263
|
+
success: false,
|
|
264
|
+
error: `HTTP ${response.status}: ${errBody}`,
|
|
265
|
+
};
|
|
266
|
+
}
|
|
267
|
+
catch (error) {
|
|
268
|
+
return {
|
|
269
|
+
success: false,
|
|
270
|
+
error: `Request failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
// ──────────── Auto-Draw Helpers ────────────
|
|
275
|
+
/**
|
|
276
|
+
* Probe a URL to discover payment requirements without paying.
|
|
277
|
+
* Makes a request and parses the 402 PAYMENT-REQUIRED header.
|
|
278
|
+
* @returns Payment amount in raw USDC units (6 decimals), or null if not a 402.
|
|
279
|
+
*/
|
|
280
|
+
async _probePaymentAmount(url, options) {
|
|
281
|
+
try {
|
|
282
|
+
const response = await fetch(url, {
|
|
283
|
+
...options,
|
|
284
|
+
headers: {
|
|
285
|
+
...options?.headers,
|
|
286
|
+
'X-Agent-Id': this.config.agentId || '',
|
|
287
|
+
},
|
|
288
|
+
});
|
|
289
|
+
if (response.status !== 402)
|
|
290
|
+
return null;
|
|
291
|
+
// Parse PAYMENT-REQUIRED header (base64 JSON)
|
|
292
|
+
const paymentHeader = response.headers.get('X-PAYMENT') || response.headers.get('PAYMENT-REQUIRED');
|
|
293
|
+
if (!paymentHeader)
|
|
294
|
+
return null;
|
|
295
|
+
try {
|
|
296
|
+
const decoded = JSON.parse(Buffer.from(paymentHeader, 'base64').toString('utf-8'));
|
|
297
|
+
const requirements = Array.isArray(decoded) ? decoded : decoded.accepts || [decoded];
|
|
298
|
+
if (requirements.length > 0) {
|
|
299
|
+
const amount = requirements[0].maxAmountRequired || requirements[0].amount;
|
|
300
|
+
if (amount) {
|
|
301
|
+
return BigInt(amount);
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
catch (e) {
|
|
306
|
+
console.warn('[agether] x402 payment header parse failed:', e instanceof Error ? e.message : e);
|
|
307
|
+
}
|
|
308
|
+
return null;
|
|
309
|
+
}
|
|
310
|
+
catch (e) {
|
|
311
|
+
console.warn('[agether] x402 getPaymentRequired failed:', e instanceof Error ? e.message : e);
|
|
312
|
+
return null;
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/** Reset spending tracker if it's a new day */
|
|
316
|
+
_resetTrackerIfNewDay() {
|
|
317
|
+
const today = new Date().toISOString().split('T')[0];
|
|
318
|
+
if (this._spendingTracker.date !== today) {
|
|
319
|
+
this._spendingTracker = {
|
|
320
|
+
date: today,
|
|
321
|
+
totalBorrowed: 0n,
|
|
322
|
+
dailyLimit: this._spendingTracker.dailyLimit,
|
|
323
|
+
};
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
/** Track a new spending amount */
|
|
327
|
+
_trackSpending(amount) {
|
|
328
|
+
this._resetTrackerIfNewDay();
|
|
329
|
+
this._spendingTracker.totalBorrowed += amount;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Check if a borrow amount is within spending limits.
|
|
333
|
+
* Considers both fixed daily limits and yield-limited spending.
|
|
334
|
+
*/
|
|
335
|
+
async _checkSpendingLimit(amount, morphoClient) {
|
|
336
|
+
this._resetTrackerIfNewDay();
|
|
337
|
+
// If yield-limited spending is enabled, calculate dynamic limit
|
|
338
|
+
if (this.config.yieldLimitedSpending) {
|
|
339
|
+
try {
|
|
340
|
+
const status = await morphoClient.getStatus();
|
|
341
|
+
let totalDailyYieldUsdc = 0;
|
|
342
|
+
for (const pos of status.positions) {
|
|
343
|
+
if (parseFloat(pos.collateral) > 0) {
|
|
344
|
+
try {
|
|
345
|
+
const estimate = await morphoClient.getYieldEstimate(pos.collateralToken, pos.collateral, 1);
|
|
346
|
+
totalDailyYieldUsdc += estimate.estimatedYieldUsd;
|
|
347
|
+
}
|
|
348
|
+
catch (e) {
|
|
349
|
+
console.warn(`[agether] yield calc failed for ${pos.collateralToken}:`, e instanceof Error ? e.message : e);
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
const yieldLimit = BigInt(Math.round(totalDailyYieldUsdc * 1e6));
|
|
354
|
+
const newTotal = this._spendingTracker.totalBorrowed + amount;
|
|
355
|
+
if (yieldLimit > 0n && newTotal > yieldLimit) {
|
|
356
|
+
return {
|
|
357
|
+
allowed: false,
|
|
358
|
+
reason: `Yield-limited spending exceeded. Daily yield cap: $${(Number(yieldLimit) / 1e6).toFixed(2)}, already spent: $${(Number(this._spendingTracker.totalBorrowed) / 1e6).toFixed(2)}, requested: $${(Number(amount) / 1e6).toFixed(2)}`,
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
catch (e) {
|
|
363
|
+
console.warn('[agether] yield-limited spending check failed, falling through to fixed limit:', e instanceof Error ? e.message : e);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
// Check fixed daily limit
|
|
367
|
+
if (this._spendingTracker.dailyLimit > 0n) {
|
|
368
|
+
const newTotal = this._spendingTracker.totalBorrowed + amount;
|
|
369
|
+
if (newTotal > this._spendingTracker.dailyLimit) {
|
|
370
|
+
return {
|
|
371
|
+
allowed: false,
|
|
372
|
+
reason: `Daily spending limit exceeded. Limit: $${(Number(this._spendingTracker.dailyLimit) / 1e6).toFixed(2)}, already spent: $${(Number(this._spendingTracker.totalBorrowed) / 1e6).toFixed(2)}, requested: $${(Number(amount) / 1e6).toFixed(2)}`,
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
}
|
|
376
|
+
return { allowed: true };
|
|
377
|
+
}
|
|
378
|
+
}
|
package/dist/index.d.mts
CHANGED
|
@@ -347,6 +347,36 @@ interface FundResult {
|
|
|
347
347
|
amount: string;
|
|
348
348
|
agentAccount: string;
|
|
349
349
|
}
|
|
350
|
+
interface SupplyAssetResult {
|
|
351
|
+
tx: string;
|
|
352
|
+
amount: string;
|
|
353
|
+
marketId: string;
|
|
354
|
+
collateralToken: string;
|
|
355
|
+
agentAccount: string;
|
|
356
|
+
}
|
|
357
|
+
interface SupplyPositionResult {
|
|
358
|
+
marketId: string;
|
|
359
|
+
loanToken: string;
|
|
360
|
+
collateralToken: string;
|
|
361
|
+
supplyShares: string;
|
|
362
|
+
suppliedAssets: string;
|
|
363
|
+
netDeposited: string;
|
|
364
|
+
earnedYield: string;
|
|
365
|
+
supplyApy: number;
|
|
366
|
+
}
|
|
367
|
+
interface WithdrawSupplyResult {
|
|
368
|
+
tx: string;
|
|
369
|
+
amount: string;
|
|
370
|
+
remainingSupply: string;
|
|
371
|
+
destination: string;
|
|
372
|
+
}
|
|
373
|
+
interface PayFromYieldResult {
|
|
374
|
+
tx: string;
|
|
375
|
+
yieldWithdrawn: string;
|
|
376
|
+
recipient: string;
|
|
377
|
+
remainingYield: string;
|
|
378
|
+
remainingSupply: string;
|
|
379
|
+
}
|
|
350
380
|
declare class MorphoClient {
|
|
351
381
|
private _signer;
|
|
352
382
|
private provider;
|
|
@@ -483,6 +513,48 @@ declare class MorphoClient {
|
|
|
483
513
|
collateralValueUsd: number;
|
|
484
514
|
disclaimer: string;
|
|
485
515
|
}>;
|
|
516
|
+
/**
|
|
517
|
+
* Supply USDC to a Morpho Blue market as a lender (earn yield).
|
|
518
|
+
*
|
|
519
|
+
* Unlike `supplyCollateral` (borrower-side), this is the **lender-side**:
|
|
520
|
+
* you deposit the loanToken (USDC) into the market's supply pool and earn
|
|
521
|
+
* interest paid by borrowers.
|
|
522
|
+
*
|
|
523
|
+
* @param usdcAmount - Amount of USDC to supply (e.g. '500')
|
|
524
|
+
* @param collateralSymbol - Market collateral token to identify which market (e.g. 'WETH')
|
|
525
|
+
* Optional — defaults to highest-APY market
|
|
526
|
+
*/
|
|
527
|
+
supplyAsset(usdcAmount: string, collateralSymbol?: string): Promise<SupplyAssetResult>;
|
|
528
|
+
/**
|
|
529
|
+
* Withdraw supplied USDC (+ earned interest) from a Morpho Blue market.
|
|
530
|
+
*
|
|
531
|
+
* @param usdcAmount - Amount to withdraw (e.g. '100' or 'all' for full position)
|
|
532
|
+
* @param collateralSymbol - Market collateral to identify which market
|
|
533
|
+
* @param receiver - Destination address (defaults to EOA)
|
|
534
|
+
*/
|
|
535
|
+
withdrawSupply(usdcAmount: string, collateralSymbol?: string, receiver?: string): Promise<WithdrawSupplyResult>;
|
|
536
|
+
/**
|
|
537
|
+
* Get supply (lending) positions with yield tracking.
|
|
538
|
+
*
|
|
539
|
+
* Uses Morpho GraphQL API (no eth_getLogs / no DB / no indexer):
|
|
540
|
+
* 1. `userByAddress` → all market positions with current supplyAssets, supplyApy
|
|
541
|
+
* 2. `transactions` → all MarketSupply/MarketWithdraw history for net deposited
|
|
542
|
+
* 3. earnedYield = currentSupplyAssets − netDeposited
|
|
543
|
+
*
|
|
544
|
+
* @param collateralSymbol - Market collateral token (optional, returns all if omitted)
|
|
545
|
+
*/
|
|
546
|
+
getSupplyPositions(collateralSymbol?: string): Promise<SupplyPositionResult[]>;
|
|
547
|
+
/**
|
|
548
|
+
* Pay a recipient using ONLY earned yield from a supply position.
|
|
549
|
+
*
|
|
550
|
+
* Computes available yield, verifies the requested amount doesn't exceed it,
|
|
551
|
+
* then withdraws from the supply position and sends directly to the recipient.
|
|
552
|
+
*
|
|
553
|
+
* @param recipient - Address to receive the USDC
|
|
554
|
+
* @param usdcAmount - Amount to pay from yield (e.g. '5.50')
|
|
555
|
+
* @param collateralSymbol - Market collateral to identify which supply position
|
|
556
|
+
*/
|
|
557
|
+
payFromYield(recipient: string, usdcAmount: string, collateralSymbol?: string): Promise<PayFromYieldResult>;
|
|
486
558
|
/**
|
|
487
559
|
* Deposit collateral into Morpho Blue.
|
|
488
560
|
*
|
|
@@ -588,6 +660,20 @@ declare class MorphoClient {
|
|
|
588
660
|
private _toTuple;
|
|
589
661
|
/** Find the first market where the agent has collateral deposited. */
|
|
590
662
|
private _findActiveMarket;
|
|
663
|
+
/** Find the first market where the agent has a supply (lending) position. */
|
|
664
|
+
private _findActiveSupplyMarket;
|
|
665
|
+
/**
|
|
666
|
+
* Compute net deposited amounts per market using Morpho GraphQL API.
|
|
667
|
+
*
|
|
668
|
+
* Fetches all MarketSupply and MarketWithdraw transactions for the account,
|
|
669
|
+
* then computes: netDeposited[marketId] = Σ Supply.assets − Σ Withdraw.assets
|
|
670
|
+
*
|
|
671
|
+
* Returns a Map<marketId (lowercase), bigint>.
|
|
672
|
+
*
|
|
673
|
+
* Uses pagination (100 per page) for completeness, though agent accounts
|
|
674
|
+
* typically have single-digit transaction counts.
|
|
675
|
+
*/
|
|
676
|
+
private _computeNetDepositedAll;
|
|
591
677
|
}
|
|
592
678
|
|
|
593
679
|
/**
|
|
@@ -1125,4 +1211,4 @@ declare function getDefaultConfig(chainId: ChainId): AgetherConfig;
|
|
|
1125
1211
|
*/
|
|
1126
1212
|
declare function createConfig(chainId: ChainId, options?: Partial<AgetherConfig>): AgetherConfig;
|
|
1127
1213
|
|
|
1128
|
-
export { ACCOUNT_FACTORY_ABI, AGENT_REPUTATION_ABI, AGETHER_4337_FACTORY_ABI, AGETHER_8004_SCORER_ABI, AGETHER_8004_VALIDATION_MODULE_ABI, AGETHER_HOOK_MULTIPLEXER_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ENTRYPOINT_V07_ABI, ERC20_ABI, ERC8004_VALIDATION_MODULE_ABI, type FundResult, HOOK_MULTIPLEXER_ABI, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, MORPHO_BLUE_ABI, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, SAFE7579_ACCOUNT_ABI, SAFE_AGENT_FACTORY_ABI, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getDefaultConfig, parseUnits, rateToBps };
|
|
1214
|
+
export { ACCOUNT_FACTORY_ABI, AGENT_REPUTATION_ABI, AGETHER_4337_FACTORY_ABI, AGETHER_8004_SCORER_ABI, AGETHER_8004_VALIDATION_MODULE_ABI, AGETHER_HOOK_MULTIPLEXER_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ENTRYPOINT_V07_ABI, ERC20_ABI, ERC8004_VALIDATION_MODULE_ABI, type FundResult, HOOK_MULTIPLEXER_ABI, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, MORPHO_BLUE_ABI, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PayFromYieldResult, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, SAFE7579_ACCOUNT_ABI, SAFE_AGENT_FACTORY_ABI, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type SupplyAssetResult, type SupplyPositionResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawResult, type WithdrawSupplyResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getDefaultConfig, parseUnits, rateToBps };
|
package/dist/index.d.ts
CHANGED
|
@@ -347,6 +347,36 @@ interface FundResult {
|
|
|
347
347
|
amount: string;
|
|
348
348
|
agentAccount: string;
|
|
349
349
|
}
|
|
350
|
+
interface SupplyAssetResult {
|
|
351
|
+
tx: string;
|
|
352
|
+
amount: string;
|
|
353
|
+
marketId: string;
|
|
354
|
+
collateralToken: string;
|
|
355
|
+
agentAccount: string;
|
|
356
|
+
}
|
|
357
|
+
interface SupplyPositionResult {
|
|
358
|
+
marketId: string;
|
|
359
|
+
loanToken: string;
|
|
360
|
+
collateralToken: string;
|
|
361
|
+
supplyShares: string;
|
|
362
|
+
suppliedAssets: string;
|
|
363
|
+
netDeposited: string;
|
|
364
|
+
earnedYield: string;
|
|
365
|
+
supplyApy: number;
|
|
366
|
+
}
|
|
367
|
+
interface WithdrawSupplyResult {
|
|
368
|
+
tx: string;
|
|
369
|
+
amount: string;
|
|
370
|
+
remainingSupply: string;
|
|
371
|
+
destination: string;
|
|
372
|
+
}
|
|
373
|
+
interface PayFromYieldResult {
|
|
374
|
+
tx: string;
|
|
375
|
+
yieldWithdrawn: string;
|
|
376
|
+
recipient: string;
|
|
377
|
+
remainingYield: string;
|
|
378
|
+
remainingSupply: string;
|
|
379
|
+
}
|
|
350
380
|
declare class MorphoClient {
|
|
351
381
|
private _signer;
|
|
352
382
|
private provider;
|
|
@@ -483,6 +513,48 @@ declare class MorphoClient {
|
|
|
483
513
|
collateralValueUsd: number;
|
|
484
514
|
disclaimer: string;
|
|
485
515
|
}>;
|
|
516
|
+
/**
|
|
517
|
+
* Supply USDC to a Morpho Blue market as a lender (earn yield).
|
|
518
|
+
*
|
|
519
|
+
* Unlike `supplyCollateral` (borrower-side), this is the **lender-side**:
|
|
520
|
+
* you deposit the loanToken (USDC) into the market's supply pool and earn
|
|
521
|
+
* interest paid by borrowers.
|
|
522
|
+
*
|
|
523
|
+
* @param usdcAmount - Amount of USDC to supply (e.g. '500')
|
|
524
|
+
* @param collateralSymbol - Market collateral token to identify which market (e.g. 'WETH')
|
|
525
|
+
* Optional — defaults to highest-APY market
|
|
526
|
+
*/
|
|
527
|
+
supplyAsset(usdcAmount: string, collateralSymbol?: string): Promise<SupplyAssetResult>;
|
|
528
|
+
/**
|
|
529
|
+
* Withdraw supplied USDC (+ earned interest) from a Morpho Blue market.
|
|
530
|
+
*
|
|
531
|
+
* @param usdcAmount - Amount to withdraw (e.g. '100' or 'all' for full position)
|
|
532
|
+
* @param collateralSymbol - Market collateral to identify which market
|
|
533
|
+
* @param receiver - Destination address (defaults to EOA)
|
|
534
|
+
*/
|
|
535
|
+
withdrawSupply(usdcAmount: string, collateralSymbol?: string, receiver?: string): Promise<WithdrawSupplyResult>;
|
|
536
|
+
/**
|
|
537
|
+
* Get supply (lending) positions with yield tracking.
|
|
538
|
+
*
|
|
539
|
+
* Uses Morpho GraphQL API (no eth_getLogs / no DB / no indexer):
|
|
540
|
+
* 1. `userByAddress` → all market positions with current supplyAssets, supplyApy
|
|
541
|
+
* 2. `transactions` → all MarketSupply/MarketWithdraw history for net deposited
|
|
542
|
+
* 3. earnedYield = currentSupplyAssets − netDeposited
|
|
543
|
+
*
|
|
544
|
+
* @param collateralSymbol - Market collateral token (optional, returns all if omitted)
|
|
545
|
+
*/
|
|
546
|
+
getSupplyPositions(collateralSymbol?: string): Promise<SupplyPositionResult[]>;
|
|
547
|
+
/**
|
|
548
|
+
* Pay a recipient using ONLY earned yield from a supply position.
|
|
549
|
+
*
|
|
550
|
+
* Computes available yield, verifies the requested amount doesn't exceed it,
|
|
551
|
+
* then withdraws from the supply position and sends directly to the recipient.
|
|
552
|
+
*
|
|
553
|
+
* @param recipient - Address to receive the USDC
|
|
554
|
+
* @param usdcAmount - Amount to pay from yield (e.g. '5.50')
|
|
555
|
+
* @param collateralSymbol - Market collateral to identify which supply position
|
|
556
|
+
*/
|
|
557
|
+
payFromYield(recipient: string, usdcAmount: string, collateralSymbol?: string): Promise<PayFromYieldResult>;
|
|
486
558
|
/**
|
|
487
559
|
* Deposit collateral into Morpho Blue.
|
|
488
560
|
*
|
|
@@ -588,6 +660,20 @@ declare class MorphoClient {
|
|
|
588
660
|
private _toTuple;
|
|
589
661
|
/** Find the first market where the agent has collateral deposited. */
|
|
590
662
|
private _findActiveMarket;
|
|
663
|
+
/** Find the first market where the agent has a supply (lending) position. */
|
|
664
|
+
private _findActiveSupplyMarket;
|
|
665
|
+
/**
|
|
666
|
+
* Compute net deposited amounts per market using Morpho GraphQL API.
|
|
667
|
+
*
|
|
668
|
+
* Fetches all MarketSupply and MarketWithdraw transactions for the account,
|
|
669
|
+
* then computes: netDeposited[marketId] = Σ Supply.assets − Σ Withdraw.assets
|
|
670
|
+
*
|
|
671
|
+
* Returns a Map<marketId (lowercase), bigint>.
|
|
672
|
+
*
|
|
673
|
+
* Uses pagination (100 per page) for completeness, though agent accounts
|
|
674
|
+
* typically have single-digit transaction counts.
|
|
675
|
+
*/
|
|
676
|
+
private _computeNetDepositedAll;
|
|
591
677
|
}
|
|
592
678
|
|
|
593
679
|
/**
|
|
@@ -1125,4 +1211,4 @@ declare function getDefaultConfig(chainId: ChainId): AgetherConfig;
|
|
|
1125
1211
|
*/
|
|
1126
1212
|
declare function createConfig(chainId: ChainId, options?: Partial<AgetherConfig>): AgetherConfig;
|
|
1127
1213
|
|
|
1128
|
-
export { ACCOUNT_FACTORY_ABI, AGENT_REPUTATION_ABI, AGETHER_4337_FACTORY_ABI, AGETHER_8004_SCORER_ABI, AGETHER_8004_VALIDATION_MODULE_ABI, AGETHER_HOOK_MULTIPLEXER_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ENTRYPOINT_V07_ABI, ERC20_ABI, ERC8004_VALIDATION_MODULE_ABI, type FundResult, HOOK_MULTIPLEXER_ABI, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, MORPHO_BLUE_ABI, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, SAFE7579_ACCOUNT_ABI, SAFE_AGENT_FACTORY_ABI, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getDefaultConfig, parseUnits, rateToBps };
|
|
1214
|
+
export { ACCOUNT_FACTORY_ABI, AGENT_REPUTATION_ABI, AGETHER_4337_FACTORY_ABI, AGETHER_8004_SCORER_ABI, AGETHER_8004_VALIDATION_MODULE_ABI, AGETHER_HOOK_MULTIPLEXER_ABI, AgentIdentityClient, type AgentIdentityClientOptions, AgentNotApprovedError, AgetherClient, type AgetherClientOptions, type AgetherConfig, AgetherError, type AgetherSigner, type AgetherViemWallet, type BalancesResult, type BorrowResult, ChainId, type ContractAddresses, type DepositAndBorrowResult, type DepositResult, ENTRYPOINT_V07_ABI, ERC20_ABI, ERC8004_VALIDATION_MODULE_ABI, type FundResult, HOOK_MULTIPLEXER_ABI, IDENTITY_REGISTRY_ABI, InsufficientBalanceError, MORPHO_BLUE_ABI, MorphoClient, type MorphoClientConfig, type MorphoMarketInfo, type MorphoMarketParams, type MorphoPosition, type PayFromYieldResult, type PaymentRequirements, type PositionResult, type RegisterResult, type RepayResult, SAFE7579_ACCOUNT_ABI, SAFE_AGENT_FACTORY_ABI, type ScoreAttestation, type ScoreResult, ScoringClient, type ScoringClientConfig, ScoringRejectedError, type SpendingTracker, type StatusResult, type SupplyAssetResult, type SupplyPositionResult, type TransactionResult, VALIDATION_REGISTRY_ABI, type WithdrawResult, type WithdrawSupplyResult, X402Client, type X402Config, type X402PaymentRequest, type X402PaymentResult, type X402Response, bpsToRate, createConfig, formatAPR, formatAddress, formatHealthFactor, formatPercent, formatTimestamp, formatUSD, formatUnits, getDefaultConfig, parseUnits, rateToBps };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAIH,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,YAAY,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAEpE,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,YAAY,EACV,aAAa,EACb,kBAAkB,EAClB,cAAc,EACd,cAAc,EACd,cAAc,EACd,YAAY,EACZ,aAAa,EACb,YAAY,EACZ,sBAAsB,EACtB,WAAW,EACX,cAAc,EACd,UAAU,EACV,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,kBAAkB,GACnB,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,YAAY,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAEnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AACpE,YAAY,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAEhF,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,YAAY,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAI9H,cAAc,SAAS,CAAC;AAIxB,OAAO,EACL,UAAU,EACV,WAAW,EACX,SAAS,EACT,aAAa,EACb,SAAS,EACT,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,SAAS,EACT,SAAS,GACV,MAAM,gBAAgB,CAAC;AAIxB,OAAO,EACL,qBAAqB,EAErB,wBAAwB,EACxB,kCAAkC,EAClC,4BAA4B,EAC5B,uBAAuB,EAEvB,sBAAsB,EACtB,mBAAmB,EACnB,6BAA6B,EAC7B,oBAAoB,EACpB,oBAAoB,EAEpB,uBAAuB,EACvB,eAAe,EACf,SAAS,EACT,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,cAAc,CAAC;AAItB,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC"}
|