@owney/sdk 0.6.5-beta.0 → 0.6.5-beta.2
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/index.cjs +217 -180
- package/dist/index.d.cts +25 -4
- package/dist/index.d.ts +25 -4
- package/dist/index.js +216 -179
- package/package.json +5 -2
package/dist/index.cjs
CHANGED
|
@@ -18,8 +18,8 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
18
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
19
|
|
|
20
20
|
// src/index.ts
|
|
21
|
-
var
|
|
22
|
-
__export(
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
23
|
AgentChainIncompatibleError: () => AgentChainIncompatibleError,
|
|
24
24
|
AgentNotFoundError: () => AgentNotFoundError,
|
|
25
25
|
InvalidHistoryCursorError: () => InvalidHistoryCursorError,
|
|
@@ -28,7 +28,7 @@ __export(src_exports, {
|
|
|
28
28
|
OwneySDK: () => OwneySDK,
|
|
29
29
|
createOwneySIWX: () => createOwneySIWX
|
|
30
30
|
});
|
|
31
|
-
module.exports = __toCommonJS(
|
|
31
|
+
module.exports = __toCommonJS(index_exports);
|
|
32
32
|
|
|
33
33
|
// src/agents/zyfai/zyfai.agent.ts
|
|
34
34
|
var import_sdk = require("@zyfai/sdk");
|
|
@@ -37,8 +37,8 @@ var import_chains = require("viem/chains");
|
|
|
37
37
|
|
|
38
38
|
// src/types/config.ts
|
|
39
39
|
var P_SUPPORTED_CHAINS = {
|
|
40
|
-
chainIds: [8453, 42161],
|
|
41
|
-
chains: ["BASE", "ARBITRUM"]
|
|
40
|
+
chainIds: [8453, 42161, 1],
|
|
41
|
+
chains: ["BASE", "ARBITRUM", "ETHEREUM"]
|
|
42
42
|
};
|
|
43
43
|
var SUPPORTED_TOKENS = ["USDC", "USDT", "WETH"];
|
|
44
44
|
var SUPPORTED_CHAIN_IDS = P_SUPPORTED_CHAINS.chainIds;
|
|
@@ -73,6 +73,12 @@ var SupportedAssets = [
|
|
|
73
73
|
symbol: "WETH",
|
|
74
74
|
chainId: 42161,
|
|
75
75
|
decimals: 18
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
address: `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`,
|
|
79
|
+
symbol: "USDC",
|
|
80
|
+
chainId: 1,
|
|
81
|
+
decimals: 6
|
|
76
82
|
}
|
|
77
83
|
];
|
|
78
84
|
|
|
@@ -139,8 +145,7 @@ var isValidChainId = (chainId) => {
|
|
|
139
145
|
function hexToDecimal(hex, decimals = 6) {
|
|
140
146
|
const normalized = hex.startsWith("0x") || hex.startsWith("0X") ? hex : `0x${hex}`;
|
|
141
147
|
const parsed = BigInt(normalized);
|
|
142
|
-
if (decimals <= 0)
|
|
143
|
-
return Number(parsed);
|
|
148
|
+
if (decimals <= 0) return Number(parsed);
|
|
144
149
|
const divisor = BigInt(10 ** decimals);
|
|
145
150
|
const whole = parsed / divisor;
|
|
146
151
|
const remainder = parsed % divisor;
|
|
@@ -153,6 +158,20 @@ var DayFilterMapping = {
|
|
|
153
158
|
};
|
|
154
159
|
|
|
155
160
|
// src/agents/zyfai/zyfai.mapper.ts
|
|
161
|
+
var DECIMALS_BY_SYMBOL = {
|
|
162
|
+
usdc: 6,
|
|
163
|
+
usdt: 6,
|
|
164
|
+
weth: 18,
|
|
165
|
+
eth: 18,
|
|
166
|
+
cbeth: 18,
|
|
167
|
+
wbtc: 8,
|
|
168
|
+
cbbtc: 8
|
|
169
|
+
};
|
|
170
|
+
function tokenDecimals(symbol, explicit) {
|
|
171
|
+
if (typeof explicit === "number" && Number.isFinite(explicit))
|
|
172
|
+
return explicit;
|
|
173
|
+
return DECIMALS_BY_SYMBOL[(symbol ?? "").toLowerCase()] ?? 6;
|
|
174
|
+
}
|
|
156
175
|
function mapDeposit(raw) {
|
|
157
176
|
return {
|
|
158
177
|
txHash: raw.txHash,
|
|
@@ -169,7 +188,8 @@ function mapWithdraw(raw) {
|
|
|
169
188
|
}
|
|
170
189
|
var CHAIN_ID_TO_NAME = {
|
|
171
190
|
8453: "BASE",
|
|
172
|
-
42161: "ARBITRUM"
|
|
191
|
+
42161: "ARBITRUM",
|
|
192
|
+
1: "ETHEREUM"
|
|
173
193
|
};
|
|
174
194
|
var NAME_TO_CHAIN_ID = Object.entries(
|
|
175
195
|
CHAIN_ID_TO_NAME
|
|
@@ -179,8 +199,7 @@ var NAME_TO_CHAIN_ID = Object.entries(
|
|
|
179
199
|
}, {});
|
|
180
200
|
function resolveChainId(chain) {
|
|
181
201
|
const asNum = Number(chain);
|
|
182
|
-
if (Number.isFinite(asNum) && asNum > 0)
|
|
183
|
-
return asNum;
|
|
202
|
+
if (Number.isFinite(asNum) && asNum > 0) return asNum;
|
|
184
203
|
return NAME_TO_CHAIN_ID[chain.trim().toLowerCase()] ?? NaN;
|
|
185
204
|
}
|
|
186
205
|
function mapBalances(raw, _chainId, smartWallet) {
|
|
@@ -210,9 +229,16 @@ function mapBalances(raw, _chainId, smartWallet) {
|
|
|
210
229
|
pool: p.pool,
|
|
211
230
|
asset: p.token_symbol ?? "",
|
|
212
231
|
// Position amount is hex-encoded base units (like the token balances
|
|
213
|
-
// above).
|
|
214
|
-
//
|
|
215
|
-
|
|
232
|
+
// above). `PositionSlot` doesn't type a `decimals` field, but runtime
|
|
233
|
+
// getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
|
|
234
|
+
// when present, otherwise fall back to the per-symbol lookup so
|
|
235
|
+
// non-6-decimal assets like WETH don't render 1e12 too large.
|
|
236
|
+
amount: String(
|
|
237
|
+
hexToDecimal(
|
|
238
|
+
p.amount || "0",
|
|
239
|
+
tokenDecimals(p.token_symbol, p.decimals)
|
|
240
|
+
)
|
|
241
|
+
),
|
|
216
242
|
apy: p.pool_apy,
|
|
217
243
|
tvl: p.pool_tvl,
|
|
218
244
|
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
@@ -257,41 +283,39 @@ function mapEarnings(raw, smartWallet) {
|
|
|
257
283
|
};
|
|
258
284
|
}
|
|
259
285
|
function mapWeightedApyByChain(raw) {
|
|
260
|
-
if (!raw)
|
|
261
|
-
return void 0;
|
|
286
|
+
if (!raw) return void 0;
|
|
262
287
|
const out = {};
|
|
263
288
|
for (const [chainKey, tokenApy] of Object.entries(raw)) {
|
|
264
289
|
const chainId = Number(chainKey);
|
|
265
|
-
if (!SUPPORTED_CHAIN_IDS.includes(chainId))
|
|
266
|
-
continue;
|
|
290
|
+
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) continue;
|
|
267
291
|
const perAsset = {};
|
|
268
292
|
for (const [symbol, apy] of Object.entries(tokenApy)) {
|
|
269
293
|
const token = symbol;
|
|
270
|
-
if (!SUPPORTED_TOKENS.includes(token))
|
|
271
|
-
continue;
|
|
294
|
+
if (!SUPPORTED_TOKENS.includes(token)) continue;
|
|
272
295
|
perAsset[token] = apy;
|
|
273
296
|
}
|
|
274
|
-
if (Object.keys(perAsset).length > 0)
|
|
275
|
-
out[chainId] = perAsset;
|
|
297
|
+
if (Object.keys(perAsset).length > 0) out[chainId] = perAsset;
|
|
276
298
|
}
|
|
277
299
|
return Object.keys(out).length > 0 ? out : void 0;
|
|
278
300
|
}
|
|
279
|
-
function rawPoolApyForChain(entry, chainId) {
|
|
301
|
+
function rawPoolApyForChain(entry, chainId, tokenSymbol) {
|
|
280
302
|
let weightedSum = 0;
|
|
281
303
|
let totalBalance = 0;
|
|
282
304
|
for (const p of entry.positions ?? []) {
|
|
283
|
-
if (p.chainId !== chainId)
|
|
284
|
-
|
|
305
|
+
if (p.chainId !== chainId) continue;
|
|
306
|
+
if (tokenSymbol && p.tokenSymbol !== tokenSymbol) continue;
|
|
285
307
|
const balance = p.balance ?? 0;
|
|
286
|
-
if (balance <= 0 || typeof p.apy !== "number")
|
|
287
|
-
continue;
|
|
308
|
+
if (balance <= 0 || typeof p.apy !== "number") continue;
|
|
288
309
|
weightedSum += p.apy * balance;
|
|
289
310
|
totalBalance += balance;
|
|
290
311
|
}
|
|
291
312
|
return totalBalance > 0 ? weightedSum / totalBalance : null;
|
|
292
313
|
}
|
|
293
|
-
function mapApyHistory(raw, chainId) {
|
|
294
|
-
const history = Object.entries(raw.history ?? {}).map(([date, entry]) => ({
|
|
314
|
+
function mapApyHistory(raw, chainId, tokenSymbol) {
|
|
315
|
+
const history = Object.entries(raw.history ?? {}).map(([date, entry]) => ({
|
|
316
|
+
date,
|
|
317
|
+
apy: rawPoolApyForChain(entry, chainId, tokenSymbol)
|
|
318
|
+
})).filter((p) => p.apy !== null).sort((a, b) => a.date.localeCompare(b.date));
|
|
295
319
|
return {
|
|
296
320
|
walletAddress: raw.walletAddress,
|
|
297
321
|
weightedApyAfterFee: raw.weightedApyAfterFee ? sumTokenValues(raw.weightedApyAfterFee) : void 0,
|
|
@@ -314,6 +338,7 @@ function mapEntries(rawEntries, chainId) {
|
|
|
314
338
|
"Withdraw from protocol": "Withdraw",
|
|
315
339
|
Rebalance: "Rebalance"
|
|
316
340
|
};
|
|
341
|
+
void chainId;
|
|
317
342
|
return rawEntries.map((entry) => {
|
|
318
343
|
const rawLog = entry.rebalanceLog;
|
|
319
344
|
const positions = entry.positions ?? [];
|
|
@@ -335,7 +360,15 @@ function mapEntries(rawEntries, chainId) {
|
|
|
335
360
|
fromPool: from.pool,
|
|
336
361
|
toPool: to.pool,
|
|
337
362
|
tokenSymbol: matched?.token_symbol ?? "",
|
|
338
|
-
amount: matched ? String(
|
|
363
|
+
amount: matched ? String(
|
|
364
|
+
hexToDecimal(
|
|
365
|
+
matched.amount || "0x",
|
|
366
|
+
tokenDecimals(
|
|
367
|
+
matched.token_symbol,
|
|
368
|
+
matched.decimals
|
|
369
|
+
)
|
|
370
|
+
)
|
|
371
|
+
) : "",
|
|
339
372
|
status: "success"
|
|
340
373
|
}
|
|
341
374
|
];
|
|
@@ -354,7 +387,12 @@ function mapEntries(rawEntries, chainId) {
|
|
|
354
387
|
txHashes: entry.transactionHash ? [entry.transactionHash] : [],
|
|
355
388
|
chainId: entry.chainId,
|
|
356
389
|
tokenSymbol: entry?.positions?.[0]?.token_symbol,
|
|
357
|
-
amount: hasAmount ? String(
|
|
390
|
+
amount: hasAmount ? String(
|
|
391
|
+
hexToDecimal(
|
|
392
|
+
rawAmount,
|
|
393
|
+
tokenDecimals(entry?.positions?.[0]?.token_symbol)
|
|
394
|
+
)
|
|
395
|
+
) : void 0
|
|
358
396
|
}
|
|
359
397
|
],
|
|
360
398
|
rebalanceLog
|
|
@@ -379,8 +417,7 @@ function mapApyByStrategy(raw) {
|
|
|
379
417
|
const supported = SupportedAssets.find(
|
|
380
418
|
(asset) => asset.chainId === entry.chain_id && asset.symbol === entry.token_symbol
|
|
381
419
|
);
|
|
382
|
-
if (!supported)
|
|
383
|
-
continue;
|
|
420
|
+
if (!supported) continue;
|
|
384
421
|
const chainKey = supported.chainId;
|
|
385
422
|
const symbolKey = supported.symbol;
|
|
386
423
|
const bucket = apyPerAsset[chainKey] ?? {};
|
|
@@ -410,10 +447,8 @@ function computeAllocationApy(positions) {
|
|
|
410
447
|
totalValue += value;
|
|
411
448
|
const chainId = resolveChainId(p.chain);
|
|
412
449
|
const token = p.asset;
|
|
413
|
-
if (!SUPPORTED_CHAIN_IDS.includes(chainId))
|
|
414
|
-
|
|
415
|
-
if (!SUPPORTED_TOKENS.includes(token))
|
|
416
|
-
continue;
|
|
450
|
+
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) continue;
|
|
451
|
+
if (!SUPPORTED_TOKENS.includes(token)) continue;
|
|
417
452
|
const perAsset = buckets[chainId] ?? {};
|
|
418
453
|
const cell = perAsset[token] ?? { weightedSum: 0, value: 0 };
|
|
419
454
|
cell.weightedSum += apy * value;
|
|
@@ -430,8 +465,7 @@ function computeAllocationApy(positions) {
|
|
|
430
465
|
out[token] = cell.weightedSum / cell.value;
|
|
431
466
|
}
|
|
432
467
|
}
|
|
433
|
-
if (Object.keys(out).length > 0)
|
|
434
|
-
apyByChainAndAsset[chainId] = out;
|
|
468
|
+
if (Object.keys(out).length > 0) apyByChainAndAsset[chainId] = out;
|
|
435
469
|
}
|
|
436
470
|
const totalApy = totalValue > 0 ? String(weightedSum / totalValue) : "0";
|
|
437
471
|
return { totalApy, apyByChainAndAsset };
|
|
@@ -448,19 +482,14 @@ function extractWithdrawnAmount(logs, recipient, token, decimals) {
|
|
|
448
482
|
let total = 0n;
|
|
449
483
|
let matched = false;
|
|
450
484
|
for (const log of logs) {
|
|
451
|
-
if (log.address.toLowerCase() !== wantToken)
|
|
452
|
-
|
|
453
|
-
if ((log.topics[
|
|
454
|
-
|
|
455
|
-
if (topicToAddress(log.topics[2]) !== wantRecipient)
|
|
456
|
-
continue;
|
|
457
|
-
if (!log.data || log.data === "0x")
|
|
458
|
-
continue;
|
|
485
|
+
if (log.address.toLowerCase() !== wantToken) continue;
|
|
486
|
+
if ((log.topics[0] ?? "").toLowerCase() !== TRANSFER_TOPIC) continue;
|
|
487
|
+
if (topicToAddress(log.topics[2]) !== wantRecipient) continue;
|
|
488
|
+
if (!log.data || log.data === "0x") continue;
|
|
459
489
|
total += BigInt(log.data);
|
|
460
490
|
matched = true;
|
|
461
491
|
}
|
|
462
|
-
if (!matched)
|
|
463
|
-
return void 0;
|
|
492
|
+
if (!matched) return void 0;
|
|
464
493
|
return String(hexToDecimal(`0x${total.toString(16)}`, decimals));
|
|
465
494
|
}
|
|
466
495
|
|
|
@@ -476,8 +505,7 @@ function encodeHistoryCursor(payload) {
|
|
|
476
505
|
return Buffer.from(JSON.stringify(payload), "utf8").toString("base64");
|
|
477
506
|
}
|
|
478
507
|
function decodeHistoryCursor(token) {
|
|
479
|
-
if (!token)
|
|
480
|
-
throw new InvalidHistoryCursorError("Cursor is empty.");
|
|
508
|
+
if (!token) throw new InvalidHistoryCursorError("Cursor is empty.");
|
|
481
509
|
let parsed;
|
|
482
510
|
try {
|
|
483
511
|
const json = Buffer.from(token, "base64").toString("utf8");
|
|
@@ -494,8 +522,7 @@ function decodeHistoryCursor(token) {
|
|
|
494
522
|
// src/agents/zyfai/zyfai.auth-cache.ts
|
|
495
523
|
var KEY_PREFIX = "owney.zyfai.session";
|
|
496
524
|
var storage = () => {
|
|
497
|
-
if (typeof window === "undefined")
|
|
498
|
-
return null;
|
|
525
|
+
if (typeof window === "undefined") return null;
|
|
499
526
|
try {
|
|
500
527
|
return window.localStorage;
|
|
501
528
|
} catch {
|
|
@@ -505,15 +532,13 @@ var storage = () => {
|
|
|
505
532
|
var buildKey = (address, chainId) => `${KEY_PREFIX}:${address.toLowerCase()}:${chainId}`;
|
|
506
533
|
var isJwtExpired = (token) => {
|
|
507
534
|
const parts = token.split(".");
|
|
508
|
-
if (parts.length !== 3)
|
|
509
|
-
return false;
|
|
535
|
+
if (parts.length !== 3) return false;
|
|
510
536
|
try {
|
|
511
537
|
const payload = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
512
538
|
const padded = payload + "=".repeat((4 - payload.length % 4) % 4);
|
|
513
539
|
const decoded = typeof atob === "function" ? atob(padded) : Buffer.from(padded, "base64").toString("utf8");
|
|
514
540
|
const claims = JSON.parse(decoded);
|
|
515
|
-
if (typeof claims.exp !== "number")
|
|
516
|
-
return false;
|
|
541
|
+
if (typeof claims.exp !== "number") return false;
|
|
517
542
|
return Date.now() / 1e3 >= claims.exp - 30;
|
|
518
543
|
} catch {
|
|
519
544
|
return false;
|
|
@@ -521,11 +546,9 @@ var isJwtExpired = (token) => {
|
|
|
521
546
|
};
|
|
522
547
|
var readSession = (address, chainId) => {
|
|
523
548
|
const store = storage();
|
|
524
|
-
if (!store)
|
|
525
|
-
return null;
|
|
549
|
+
if (!store) return null;
|
|
526
550
|
const raw = store.getItem(buildKey(address, chainId));
|
|
527
|
-
if (!raw)
|
|
528
|
-
return null;
|
|
551
|
+
if (!raw) return null;
|
|
529
552
|
try {
|
|
530
553
|
const parsed = JSON.parse(raw);
|
|
531
554
|
if (!parsed.token || isJwtExpired(parsed.token)) {
|
|
@@ -540,8 +563,7 @@ var readSession = (address, chainId) => {
|
|
|
540
563
|
};
|
|
541
564
|
var writeSession = (address, chainId, session) => {
|
|
542
565
|
const store = storage();
|
|
543
|
-
if (!store)
|
|
544
|
-
return;
|
|
566
|
+
if (!store) return;
|
|
545
567
|
try {
|
|
546
568
|
store.setItem(buildKey(address, chainId), JSON.stringify(session));
|
|
547
569
|
} catch {
|
|
@@ -549,8 +571,7 @@ var writeSession = (address, chainId, session) => {
|
|
|
549
571
|
};
|
|
550
572
|
var clearSession = (address, chainId) => {
|
|
551
573
|
const store = storage();
|
|
552
|
-
if (!store)
|
|
553
|
-
return;
|
|
574
|
+
if (!store) return;
|
|
554
575
|
try {
|
|
555
576
|
store.removeItem(buildKey(address, chainId));
|
|
556
577
|
} catch {
|
|
@@ -559,8 +580,7 @@ var clearSession = (address, chainId) => {
|
|
|
559
580
|
|
|
560
581
|
// src/agents/zyfai/autoSelect.ts
|
|
561
582
|
function buildAutoSelectUpdate(current, asset) {
|
|
562
|
-
if (current.autoSelectProtocols === true)
|
|
563
|
-
return null;
|
|
583
|
+
if (current.autoSelectProtocols === true) return null;
|
|
564
584
|
return {
|
|
565
585
|
asset,
|
|
566
586
|
autoSelectProtocols: true,
|
|
@@ -571,16 +591,18 @@ function buildAutoSelectUpdate(current, asset) {
|
|
|
571
591
|
// src/agents/zyfai/zyfai.agent.ts
|
|
572
592
|
var DEFAULT_ZYFAI_RPC_URLS = {
|
|
573
593
|
8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
|
|
574
|
-
42161: "https://arb-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V"
|
|
594
|
+
42161: "https://arb-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
|
|
595
|
+
1: "https://eth-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V"
|
|
575
596
|
};
|
|
576
597
|
var WETH_ADDRESS_BY_CHAIN = {
|
|
577
598
|
8453: "0x4200000000000000000000000000000000000006",
|
|
578
|
-
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"
|
|
599
|
+
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
600
|
+
1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
|
579
601
|
};
|
|
580
|
-
var VIEM_CHAIN = { 8453: import_chains.base, 42161: import_chains.arbitrum };
|
|
602
|
+
var VIEM_CHAIN = { 8453: import_chains.base, 42161: import_chains.arbitrum, 1: import_chains.mainnet };
|
|
581
603
|
var ZyfaiAgent = class {
|
|
582
604
|
id = "zyfai";
|
|
583
|
-
supportedChainIds = [8453, 42161];
|
|
605
|
+
supportedChainIds = [8453, 42161, 1];
|
|
584
606
|
supportedAssets = [
|
|
585
607
|
{
|
|
586
608
|
chainId: 8453,
|
|
@@ -597,6 +619,13 @@ var ZyfaiAgent = class {
|
|
|
597
619
|
{ symbol: "USDC", minDepositAmount: "1500000" },
|
|
598
620
|
{ symbol: "WETH", minDepositAmount: "500000000000000" }
|
|
599
621
|
]
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
chainId: 1,
|
|
625
|
+
chain: "ETHEREUM",
|
|
626
|
+
// Zyfai enforces a 10,000 USDC minimum portfolio on Ethereum mainnet
|
|
627
|
+
// (mainnet gas only pays off on large positions). 10_000 * 1e6 raw units.
|
|
628
|
+
assets: [{ symbol: "USDC", minDepositAmount: "10000000000" }]
|
|
600
629
|
}
|
|
601
630
|
];
|
|
602
631
|
sdk;
|
|
@@ -620,8 +649,7 @@ var ZyfaiAgent = class {
|
|
|
620
649
|
}
|
|
621
650
|
getPublicClient(chainId) {
|
|
622
651
|
const cached = this.publicClients.get(chainId);
|
|
623
|
-
if (cached)
|
|
624
|
-
return cached;
|
|
652
|
+
if (cached) return cached;
|
|
625
653
|
const client = (0, import_viem.createPublicClient)({
|
|
626
654
|
chain: VIEM_CHAIN[chainId],
|
|
627
655
|
transport: (0, import_viem.http)(this.rpcUrls[chainId])
|
|
@@ -631,33 +659,43 @@ var ZyfaiAgent = class {
|
|
|
631
659
|
}
|
|
632
660
|
/**
|
|
633
661
|
* Fills in the true withdrawn amount for `Withdraw` entries by decoding the
|
|
634
|
-
*
|
|
662
|
+
* on-chain `Transfer` that lands in the user's wallet. The Zyfai history
|
|
635
663
|
* payload only reports the *remaining* position for a partial withdraw (see
|
|
636
664
|
* the note in `mapEntries`), so without this the UI shows the leftover
|
|
637
665
|
* balance instead of the amount withdrawn.
|
|
638
666
|
*
|
|
667
|
+
* The withdrawn asset varies per entry (USDC or WETH), so it's resolved
|
|
668
|
+
* from `tx.tokenSymbol` (set by `mapEntries` from the entry's own
|
|
669
|
+
* position) rather than assumed to always be USDC. Zyfai sometimes
|
|
670
|
+
* denominates WETH as lowercase "eth" — that's normalized to WETH.
|
|
671
|
+
* Entries with no symbol (older payload shapes) fall back to USDC to
|
|
672
|
+
* preserve prior behavior.
|
|
673
|
+
*
|
|
639
674
|
* Mutates `entries` in place. Runs all lookups concurrently and is tolerant
|
|
640
675
|
* of RPC failures: an entry whose amount can't be resolved keeps
|
|
641
676
|
* `amount: undefined`, which consumers render as a hidden/retryable row
|
|
642
677
|
* rather than a wrong number.
|
|
643
678
|
*/
|
|
644
679
|
async resolveWithdrawnAmounts(entries, chainId, recipient) {
|
|
645
|
-
const asset = SupportedAssets.find(
|
|
646
|
-
(a) => a.chainId === chainId && a.symbol === "USDC"
|
|
647
|
-
);
|
|
648
|
-
if (!asset)
|
|
649
|
-
return;
|
|
650
680
|
const withdrawals = entries.filter(
|
|
651
681
|
(e) => e.action === "Withdraw" && e.transactions[0]?.txHashes[0]
|
|
652
682
|
);
|
|
653
|
-
if (withdrawals.length === 0)
|
|
654
|
-
return;
|
|
683
|
+
if (withdrawals.length === 0) return;
|
|
655
684
|
const client = this.getPublicClient(chainId);
|
|
656
685
|
await Promise.all(
|
|
657
686
|
withdrawals.map(async (entry) => {
|
|
658
687
|
const tx = entry.transactions[0];
|
|
659
688
|
const txHash = tx.txHashes[0];
|
|
660
|
-
const
|
|
689
|
+
const rawSymbol = tx.tokenSymbol;
|
|
690
|
+
const normalizedSymbol = rawSymbol ? rawSymbol.toLowerCase() === "eth" ? "WETH" : rawSymbol.toUpperCase() : "USDC";
|
|
691
|
+
const asset = SupportedAssets.find(
|
|
692
|
+
(a) => a.chainId === chainId && a.symbol === normalizedSymbol
|
|
693
|
+
) ?? SupportedAssets.find(
|
|
694
|
+
(a) => a.chainId === chainId && a.symbol === "USDC"
|
|
695
|
+
);
|
|
696
|
+
if (!asset) return;
|
|
697
|
+
const cacheKey = `${txHash}:${asset.address}`;
|
|
698
|
+
const cached = this.withdrawAmountCache.get(cacheKey);
|
|
661
699
|
if (cached !== void 0) {
|
|
662
700
|
tx.amount = cached;
|
|
663
701
|
return;
|
|
@@ -673,7 +711,7 @@ var ZyfaiAgent = class {
|
|
|
673
711
|
asset.decimals
|
|
674
712
|
);
|
|
675
713
|
if (amount !== void 0) {
|
|
676
|
-
this.withdrawAmountCache.set(
|
|
714
|
+
this.withdrawAmountCache.set(cacheKey, amount);
|
|
677
715
|
tx.amount = amount;
|
|
678
716
|
}
|
|
679
717
|
} catch {
|
|
@@ -692,13 +730,11 @@ var ZyfaiAgent = class {
|
|
|
692
730
|
* for some apps and the patch only matters in the browser anyway.
|
|
693
731
|
*/
|
|
694
732
|
installAuthCache() {
|
|
695
|
-
if (typeof window === "undefined")
|
|
696
|
-
return;
|
|
733
|
+
if (typeof window === "undefined") return;
|
|
697
734
|
const internals = this.sdk;
|
|
698
735
|
const original = internals.authenticateUser.bind(internals);
|
|
699
736
|
internals.authenticateUser = async () => {
|
|
700
|
-
if (internals.authenticatedUserId !== null)
|
|
701
|
-
return;
|
|
737
|
+
if (internals.authenticatedUserId !== null) return;
|
|
702
738
|
const address = internals.walletClient?.account?.address;
|
|
703
739
|
const chainId = internals.currentChainId;
|
|
704
740
|
if (address && chainId) {
|
|
@@ -773,12 +809,10 @@ var ZyfaiAgent = class {
|
|
|
773
809
|
return await this.sdk.connectAccount(provider, chainId);
|
|
774
810
|
} catch (error) {
|
|
775
811
|
const message = error instanceof Error ? error.message : String(error);
|
|
776
|
-
if (!message.toLowerCase().includes("unauthorized"))
|
|
777
|
-
throw error;
|
|
812
|
+
if (!message.toLowerCase().includes("unauthorized")) throw error;
|
|
778
813
|
const internals = this.sdk;
|
|
779
814
|
const address = internals.walletClient?.account?.address;
|
|
780
|
-
if (address)
|
|
781
|
-
clearSession(address, chainId);
|
|
815
|
+
if (address) clearSession(address, chainId);
|
|
782
816
|
return await this.sdk.connectAccount(provider, chainId);
|
|
783
817
|
}
|
|
784
818
|
}
|
|
@@ -908,10 +942,10 @@ var ZyfaiAgent = class {
|
|
|
908
942
|
const raw = await this.sdk.getOnchainEarnings(smartWallet);
|
|
909
943
|
return mapEarnings(raw, smartWallet);
|
|
910
944
|
}
|
|
911
|
-
async getAccountApy(state, chainId, days) {
|
|
945
|
+
async getAccountApy(state, chainId, days, tokenSymbol) {
|
|
912
946
|
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
913
947
|
const raw = await this.sdk.getDailyApyHistory(smartWallet, days);
|
|
914
|
-
return mapApyHistory(raw, chainId);
|
|
948
|
+
return mapApyHistory(raw, chainId, tokenSymbol);
|
|
915
949
|
}
|
|
916
950
|
async getHistory(state, chainId, options) {
|
|
917
951
|
const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
|
|
@@ -976,8 +1010,7 @@ var ZyfaiAgent = class {
|
|
|
976
1010
|
},
|
|
977
1011
|
asset
|
|
978
1012
|
);
|
|
979
|
-
if (!update)
|
|
980
|
-
return false;
|
|
1013
|
+
if (!update) return false;
|
|
981
1014
|
await this.sdk.updateUserProfile(update);
|
|
982
1015
|
return true;
|
|
983
1016
|
}
|
|
@@ -1066,8 +1099,7 @@ function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decima
|
|
|
1066
1099
|
const tokenBalance = agentBalance?.tokens.find(
|
|
1067
1100
|
(t) => t.chainId === chainId && t.asset.toUpperCase() === target
|
|
1068
1101
|
);
|
|
1069
|
-
if (!tokenBalance)
|
|
1070
|
-
return { agent, balance: 0n };
|
|
1102
|
+
if (!tokenBalance) return { agent, balance: 0n };
|
|
1071
1103
|
return { agent, balance: (0, import_viem2.parseUnits)(tokenBalance.amount, decimals) };
|
|
1072
1104
|
});
|
|
1073
1105
|
}
|
|
@@ -1084,11 +1116,9 @@ function planProportionalShares(balances, requested, totalAvailable) {
|
|
|
1084
1116
|
return diff > 0n ? 1 : diff < 0n ? -1 : 0;
|
|
1085
1117
|
});
|
|
1086
1118
|
for (const p of byHeadroom) {
|
|
1087
|
-
if (remainder === 0n)
|
|
1088
|
-
break;
|
|
1119
|
+
if (remainder === 0n) break;
|
|
1089
1120
|
const headroom = p.balance - p.planned;
|
|
1090
|
-
if (headroom <= 0n)
|
|
1091
|
-
continue;
|
|
1121
|
+
if (headroom <= 0n) continue;
|
|
1092
1122
|
const take = headroom < remainder ? headroom : remainder;
|
|
1093
1123
|
p.planned += take;
|
|
1094
1124
|
remainder -= take;
|
|
@@ -1117,8 +1147,7 @@ function redistributeShare(plans, fromIndex, amount, candidatePool) {
|
|
|
1117
1147
|
(s, c) => s + (c.balance - c.planned),
|
|
1118
1148
|
0n
|
|
1119
1149
|
);
|
|
1120
|
-
if (totalHeadroom === 0n)
|
|
1121
|
-
return;
|
|
1150
|
+
if (totalHeadroom === 0n) return;
|
|
1122
1151
|
let distributed = 0n;
|
|
1123
1152
|
for (const c of candidates) {
|
|
1124
1153
|
const headroom = c.balance - c.planned;
|
|
@@ -1129,11 +1158,9 @@ function redistributeShare(plans, fromIndex, amount, candidatePool) {
|
|
|
1129
1158
|
}
|
|
1130
1159
|
let leftover = amount - distributed;
|
|
1131
1160
|
for (const c of candidates) {
|
|
1132
|
-
if (leftover === 0n)
|
|
1133
|
-
break;
|
|
1161
|
+
if (leftover === 0n) break;
|
|
1134
1162
|
const headroom = c.balance - c.planned;
|
|
1135
|
-
if (headroom <= 0n)
|
|
1136
|
-
continue;
|
|
1163
|
+
if (headroom <= 0n) continue;
|
|
1137
1164
|
const take = headroom < leftover ? headroom : leftover;
|
|
1138
1165
|
c.planned += take;
|
|
1139
1166
|
leftover -= take;
|
|
@@ -1150,16 +1177,13 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
1150
1177
|
for (const id of Object.keys(agentApys)) {
|
|
1151
1178
|
const cells = agentApys[id].apyByChainAndAsset;
|
|
1152
1179
|
const balance = agentBalances[id] ?? 0;
|
|
1153
|
-
if (!cells || balance <= 0)
|
|
1154
|
-
continue;
|
|
1180
|
+
if (!cells || balance <= 0) continue;
|
|
1155
1181
|
for (const [chainKey, perAsset] of Object.entries(cells)) {
|
|
1156
|
-
if (!perAsset)
|
|
1157
|
-
continue;
|
|
1182
|
+
if (!perAsset) continue;
|
|
1158
1183
|
const chainId = Number(chainKey);
|
|
1159
1184
|
for (const [asset, apyValue] of Object.entries(perAsset)) {
|
|
1160
1185
|
const apy = Number(apyValue ?? 0);
|
|
1161
|
-
if (apy === 0)
|
|
1162
|
-
continue;
|
|
1186
|
+
if (apy === 0) continue;
|
|
1163
1187
|
sums[chainId] ??= {};
|
|
1164
1188
|
weights[chainId] ??= {};
|
|
1165
1189
|
sums[chainId][asset] = (sums[chainId][asset] ?? 0) + apy * balance;
|
|
@@ -1173,8 +1197,7 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
1173
1197
|
const perAssetOut = {};
|
|
1174
1198
|
for (const asset of Object.keys(sums[chainId])) {
|
|
1175
1199
|
const w = weights[chainId][asset];
|
|
1176
|
-
if (w > 0)
|
|
1177
|
-
perAssetOut[asset] = sums[chainId][asset] / w;
|
|
1200
|
+
if (w > 0) perAssetOut[asset] = sums[chainId][asset] / w;
|
|
1178
1201
|
}
|
|
1179
1202
|
if (Object.keys(perAssetOut).length > 0) {
|
|
1180
1203
|
out[chainId] = perAssetOut;
|
|
@@ -1231,7 +1254,10 @@ async function postSponsorTransferAuth(input) {
|
|
|
1231
1254
|
try {
|
|
1232
1255
|
res = await fetch(`${base3}/api/v1/sponsor/erc20-transfer-auth`, {
|
|
1233
1256
|
method: "POST",
|
|
1234
|
-
headers: {
|
|
1257
|
+
headers: {
|
|
1258
|
+
"content-type": "application/json",
|
|
1259
|
+
"x-owney-api-key": input.apiKey
|
|
1260
|
+
},
|
|
1235
1261
|
body: JSON.stringify(input.body)
|
|
1236
1262
|
});
|
|
1237
1263
|
} catch (networkError) {
|
|
@@ -1251,7 +1277,13 @@ async function postSponsorTransferAuth(input) {
|
|
|
1251
1277
|
throw new OwneyError(
|
|
1252
1278
|
"SPONSOR_REQUEST_FAILED",
|
|
1253
1279
|
`Sponsor API error ${res.status}: ${parsed?.message ?? text.slice(0, 500)}`,
|
|
1254
|
-
{
|
|
1280
|
+
{
|
|
1281
|
+
statusCode: res.status,
|
|
1282
|
+
responseBody: text.slice(0, 500),
|
|
1283
|
+
// 503 SPONSOR_UNAVAILABLE = relayer out of gas; the tx was rejected
|
|
1284
|
+
// before broadcast, so it is safe to fall back to a user-paid deposit.
|
|
1285
|
+
safeToFallback: res.status === 503
|
|
1286
|
+
}
|
|
1255
1287
|
);
|
|
1256
1288
|
}
|
|
1257
1289
|
return parsed.data;
|
|
@@ -1262,7 +1294,10 @@ async function postSponsorPermit2Transfer(input) {
|
|
|
1262
1294
|
try {
|
|
1263
1295
|
res = await fetch(`${base3}/api/v1/sponsor/permit2-transfer`, {
|
|
1264
1296
|
method: "POST",
|
|
1265
|
-
headers: {
|
|
1297
|
+
headers: {
|
|
1298
|
+
"content-type": "application/json",
|
|
1299
|
+
"x-owney-api-key": input.apiKey
|
|
1300
|
+
},
|
|
1266
1301
|
body: JSON.stringify(input.body)
|
|
1267
1302
|
});
|
|
1268
1303
|
} catch (networkError) {
|
|
@@ -1285,7 +1320,7 @@ async function postSponsorPermit2Transfer(input) {
|
|
|
1285
1320
|
{
|
|
1286
1321
|
statusCode: res.status,
|
|
1287
1322
|
responseBody: text.slice(0, 500),
|
|
1288
|
-
safeToFallback: res.status >= 400 && res.status < 500
|
|
1323
|
+
safeToFallback: res.status >= 400 && res.status < 500 || res.status === 503
|
|
1289
1324
|
}
|
|
1290
1325
|
);
|
|
1291
1326
|
}
|
|
@@ -1295,9 +1330,12 @@ async function getSponsorRelayerAddress(input) {
|
|
|
1295
1330
|
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
1296
1331
|
let res;
|
|
1297
1332
|
try {
|
|
1298
|
-
res = await fetch(
|
|
1299
|
-
|
|
1300
|
-
|
|
1333
|
+
res = await fetch(
|
|
1334
|
+
`${base3}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
|
|
1335
|
+
{
|
|
1336
|
+
headers: { "x-owney-api-key": input.apiKey }
|
|
1337
|
+
}
|
|
1338
|
+
);
|
|
1301
1339
|
} catch (networkError) {
|
|
1302
1340
|
throw new OwneyError(
|
|
1303
1341
|
"SPONSOR_REQUEST_FAILED",
|
|
@@ -1315,7 +1353,11 @@ async function getSponsorRelayerAddress(input) {
|
|
|
1315
1353
|
throw new OwneyError(
|
|
1316
1354
|
"SPONSOR_REQUEST_FAILED",
|
|
1317
1355
|
`Sponsor API error ${res.status}: ${parsed?.message ?? text.slice(0, 500)}`,
|
|
1318
|
-
{
|
|
1356
|
+
{
|
|
1357
|
+
statusCode: res.status,
|
|
1358
|
+
responseBody: text.slice(0, 500),
|
|
1359
|
+
safeToFallback: true
|
|
1360
|
+
}
|
|
1319
1361
|
);
|
|
1320
1362
|
}
|
|
1321
1363
|
return parsed.data.relayer;
|
|
@@ -1502,18 +1544,21 @@ function decodeMultiAgentCursor(token) {
|
|
|
1502
1544
|
}
|
|
1503
1545
|
var SPONSORED_USDC_BY_CHAIN = {
|
|
1504
1546
|
8453: "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
|
|
1505
|
-
42161: "0xaf88d065e77c8cc2239327c5edb3a432268e5831"
|
|
1547
|
+
42161: "0xaf88d065e77c8cc2239327c5edb3a432268e5831",
|
|
1548
|
+
1: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
|
|
1506
1549
|
};
|
|
1507
1550
|
var VIEM_CHAIN2 = {
|
|
1508
1551
|
8453: import_chains2.base,
|
|
1509
|
-
42161: import_chains2.arbitrum
|
|
1552
|
+
42161: import_chains2.arbitrum,
|
|
1553
|
+
1: import_chains2.mainnet
|
|
1510
1554
|
};
|
|
1511
1555
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
1512
1556
|
8453: "0x4200000000000000000000000000000000000006",
|
|
1513
|
-
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"
|
|
1557
|
+
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
1558
|
+
1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
|
1514
1559
|
};
|
|
1515
1560
|
function shouldFallbackToUserPaid(error, asset, appCallback) {
|
|
1516
|
-
return asset === "WETH" && appCallback === void 0 && error instanceof OwneyError && error.code === "SPONSOR_REQUEST_FAILED" && error.details?.safeToFallback === true;
|
|
1561
|
+
return (asset === "WETH" || asset === "USDC") && appCallback === void 0 && error instanceof OwneyError && error.code === "SPONSOR_REQUEST_FAILED" && error.details?.safeToFallback === true;
|
|
1517
1562
|
}
|
|
1518
1563
|
var OwneySDK = class {
|
|
1519
1564
|
agents = /* @__PURE__ */ new Map();
|
|
@@ -1527,12 +1572,14 @@ var OwneySDK = class {
|
|
|
1527
1572
|
state = null;
|
|
1528
1573
|
apiKey;
|
|
1529
1574
|
zyfaiRpcUrls;
|
|
1575
|
+
routingApiBaseUrl;
|
|
1530
1576
|
cachedSponsoredCallback = null;
|
|
1531
1577
|
cachedWethSponsoredCallback = null;
|
|
1532
1578
|
initializingAgentsPromise = null;
|
|
1533
1579
|
constructor(config) {
|
|
1534
1580
|
this.apiKey = config.apiKey;
|
|
1535
1581
|
this.zyfaiRpcUrls = config.zyfaiRpcUrls;
|
|
1582
|
+
this.routingApiBaseUrl = config.routingApiBaseUrl;
|
|
1536
1583
|
}
|
|
1537
1584
|
/**
|
|
1538
1585
|
* Establish connection state for all subsequent SDK calls.
|
|
@@ -1587,8 +1634,7 @@ var OwneySDK = class {
|
|
|
1587
1634
|
return this.state?.chainId ?? null;
|
|
1588
1635
|
}
|
|
1589
1636
|
requireState() {
|
|
1590
|
-
if (!this.state)
|
|
1591
|
-
throw new NotConnectedError();
|
|
1637
|
+
if (!this.state) throw new NotConnectedError();
|
|
1592
1638
|
return this.state;
|
|
1593
1639
|
}
|
|
1594
1640
|
requireChainId() {
|
|
@@ -1618,12 +1664,12 @@ var OwneySDK = class {
|
|
|
1618
1664
|
* `TransferWithAuthorization`, then POSTs to the sponsor API.
|
|
1619
1665
|
*/
|
|
1620
1666
|
getDefaultSponsoredCallback() {
|
|
1621
|
-
if (this.cachedSponsoredCallback)
|
|
1622
|
-
return this.cachedSponsoredCallback;
|
|
1667
|
+
if (this.cachedSponsoredCallback) return this.cachedSponsoredCallback;
|
|
1623
1668
|
const provider = this.requireConnectedProvider();
|
|
1624
1669
|
const owner = this.state.walletAddress;
|
|
1625
1670
|
this.cachedSponsoredCallback = makeSponsoredDepositCallback({
|
|
1626
1671
|
apiKey: this.apiKey,
|
|
1672
|
+
baseUrl: this.routingApiBaseUrl,
|
|
1627
1673
|
ownerAddress: owner,
|
|
1628
1674
|
tokenAddressByChain: SPONSORED_USDC_BY_CHAIN,
|
|
1629
1675
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
@@ -1654,6 +1700,7 @@ var OwneySDK = class {
|
|
|
1654
1700
|
const owner = this.state.walletAddress;
|
|
1655
1701
|
this.cachedWethSponsoredCallback = makeSponsoredWethCallback({
|
|
1656
1702
|
apiKey: this.apiKey,
|
|
1703
|
+
baseUrl: this.routingApiBaseUrl,
|
|
1657
1704
|
ownerAddress: owner,
|
|
1658
1705
|
tokenAddressByChain: SPONSORED_WETH_BY_CHAIN,
|
|
1659
1706
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
@@ -1682,22 +1729,19 @@ var OwneySDK = class {
|
|
|
1682
1729
|
const active = /* @__PURE__ */ new Map();
|
|
1683
1730
|
for (const id of this.activeAgents) {
|
|
1684
1731
|
const agent = this.agents.get(id);
|
|
1685
|
-
if (agent)
|
|
1686
|
-
active.set(id, agent);
|
|
1732
|
+
if (agent) active.set(id, agent);
|
|
1687
1733
|
}
|
|
1688
1734
|
return active;
|
|
1689
1735
|
}
|
|
1690
1736
|
async ensureAgentsInitialized() {
|
|
1691
|
-
if (this.agents.size > 0)
|
|
1692
|
-
return;
|
|
1737
|
+
if (this.agents.size > 0) return;
|
|
1693
1738
|
if (!this.initializingAgentsPromise) {
|
|
1694
1739
|
this.initializingAgentsPromise = (async () => {
|
|
1695
1740
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
1696
1741
|
this.disabledAgents.clear();
|
|
1697
1742
|
for (const { key, agent_type, is_enabled } of agentKeys) {
|
|
1698
1743
|
const agent = this.createAgent(agent_type, key);
|
|
1699
|
-
if (!agent)
|
|
1700
|
-
continue;
|
|
1744
|
+
if (!agent) continue;
|
|
1701
1745
|
this.agents.set(agent_type, agent);
|
|
1702
1746
|
if (is_enabled === false) {
|
|
1703
1747
|
this.disabledAgents.add(agent_type);
|
|
@@ -1936,10 +1980,9 @@ var OwneySDK = class {
|
|
|
1936
1980
|
await this.approvePermit2();
|
|
1937
1981
|
continue;
|
|
1938
1982
|
}
|
|
1939
|
-
if (!shouldFallbackToUserPaid(error, asset, appCallback))
|
|
1940
|
-
throw error;
|
|
1983
|
+
if (!shouldFallbackToUserPaid(error, asset, appCallback)) throw error;
|
|
1941
1984
|
console.warn(
|
|
1942
|
-
|
|
1985
|
+
`[owney-sdk] ${asset} sponsorship unavailable, falling back to user-paid deposit:`,
|
|
1943
1986
|
error
|
|
1944
1987
|
);
|
|
1945
1988
|
return attempt(void 0);
|
|
@@ -1954,8 +1997,7 @@ var OwneySDK = class {
|
|
|
1954
1997
|
return BigInt(assetEntry?.minDepositAmount ?? "0");
|
|
1955
1998
|
}
|
|
1956
1999
|
splitDepositAmount(totalAmount, agents, chainId, asset, exempt = /* @__PURE__ */ new Set()) {
|
|
1957
|
-
if (agents.length === 0)
|
|
1958
|
-
return [];
|
|
2000
|
+
if (agents.length === 0) return [];
|
|
1959
2001
|
const perAgent = totalAmount / BigInt(agents.length);
|
|
1960
2002
|
const remainder = totalAmount % BigInt(agents.length);
|
|
1961
2003
|
const splits = agents.map((agent, i) => ({
|
|
@@ -1979,10 +2021,8 @@ var OwneySDK = class {
|
|
|
1979
2021
|
async validateMinDepositAmount(agent, state, chainId, asset, amount) {
|
|
1980
2022
|
const minDepositAmount = this.getMinDepositAmount(agent, chainId, asset);
|
|
1981
2023
|
const parsedAmount = BigInt(amount);
|
|
1982
|
-
if (parsedAmount >= minDepositAmount)
|
|
1983
|
-
|
|
1984
|
-
if (await this.hasExistingBalance(agent, state, chainId, asset))
|
|
1985
|
-
return;
|
|
2024
|
+
if (parsedAmount >= minDepositAmount) return;
|
|
2025
|
+
if (await this.hasExistingBalance(agent, state, chainId, asset)) return;
|
|
1986
2026
|
throw new OwneyError(
|
|
1987
2027
|
"DEPOSIT_AMOUNT_BELOW_MINIMUM",
|
|
1988
2028
|
`Amount "${amount}" is below the required minimum deposit "${minDepositAmount.toString()}" for agent "${agent.id}" on chain ${chainId} for asset "${asset}".`,
|
|
@@ -2146,8 +2186,7 @@ var OwneySDK = class {
|
|
|
2146
2186
|
const agentErrors = {};
|
|
2147
2187
|
for (let i = 0; i < plans.length; i++) {
|
|
2148
2188
|
const p = plans[i];
|
|
2149
|
-
if (p.planned === 0n)
|
|
2150
|
-
continue;
|
|
2189
|
+
if (p.planned === 0n) continue;
|
|
2151
2190
|
try {
|
|
2152
2191
|
results[p.agent.id] = await p.agent.withdraw(
|
|
2153
2192
|
state,
|
|
@@ -2281,19 +2320,30 @@ var OwneySDK = class {
|
|
|
2281
2320
|
*/
|
|
2282
2321
|
async getAccountApy({
|
|
2283
2322
|
agentId,
|
|
2284
|
-
days
|
|
2323
|
+
days,
|
|
2324
|
+
tokenSymbol
|
|
2285
2325
|
}) {
|
|
2286
2326
|
const state = this.requireState();
|
|
2287
2327
|
const chainId = this.requireChainId();
|
|
2288
2328
|
if (agentId) {
|
|
2289
|
-
return this.getAgent(agentId).getAccountApy(
|
|
2329
|
+
return this.getAgent(agentId).getAccountApy(
|
|
2330
|
+
state,
|
|
2331
|
+
chainId,
|
|
2332
|
+
days,
|
|
2333
|
+
tokenSymbol
|
|
2334
|
+
);
|
|
2290
2335
|
}
|
|
2291
2336
|
const activeAgents = this.getActiveAgents();
|
|
2292
2337
|
const entries = [...activeAgents.entries()];
|
|
2293
2338
|
const [apyResults, balanceResults] = await Promise.all([
|
|
2294
2339
|
Promise.all(
|
|
2295
2340
|
entries.map(async ([id, agent]) => {
|
|
2296
|
-
const apy = await agent.getAccountApy(
|
|
2341
|
+
const apy = await agent.getAccountApy(
|
|
2342
|
+
state,
|
|
2343
|
+
chainId,
|
|
2344
|
+
days,
|
|
2345
|
+
tokenSymbol
|
|
2346
|
+
);
|
|
2297
2347
|
return [id, apy];
|
|
2298
2348
|
})
|
|
2299
2349
|
),
|
|
@@ -2316,15 +2366,13 @@ var OwneySDK = class {
|
|
|
2316
2366
|
let relevantBalance = 0;
|
|
2317
2367
|
for (const id of Object.keys(results)) {
|
|
2318
2368
|
const agentApy = Number(results[id].weightedApyAfterFee ?? 0);
|
|
2319
|
-
if (agentApy === 0)
|
|
2320
|
-
continue;
|
|
2369
|
+
if (agentApy === 0) continue;
|
|
2321
2370
|
relevantBalance += balances[id];
|
|
2322
2371
|
}
|
|
2323
2372
|
if (relevantBalance > 0) {
|
|
2324
2373
|
for (const id of Object.keys(results)) {
|
|
2325
2374
|
const agentApy = Number(results[id].weightedApyAfterFee ?? 0);
|
|
2326
|
-
if (agentApy === 0)
|
|
2327
|
-
continue;
|
|
2375
|
+
if (agentApy === 0) continue;
|
|
2328
2376
|
const weight = balances[id] / relevantBalance;
|
|
2329
2377
|
totalApy += agentApy * weight;
|
|
2330
2378
|
}
|
|
@@ -2379,8 +2427,7 @@ var OwneySDK = class {
|
|
|
2379
2427
|
const nextCursorMap = {};
|
|
2380
2428
|
let hasMore = false;
|
|
2381
2429
|
for (const { agentId: id, page } of perAgent) {
|
|
2382
|
-
if (!page)
|
|
2383
|
-
continue;
|
|
2430
|
+
if (!page) continue;
|
|
2384
2431
|
merged.push(...page.data);
|
|
2385
2432
|
if (page.hasMore && page.nextCursor) {
|
|
2386
2433
|
nextCursorMap[id] = page.nextCursor;
|
|
@@ -2389,16 +2436,12 @@ var OwneySDK = class {
|
|
|
2389
2436
|
}
|
|
2390
2437
|
merged.sort((a, b) => {
|
|
2391
2438
|
const dateDiff = new Date(b.date).getTime() - new Date(a.date).getTime();
|
|
2392
|
-
if (dateDiff !== 0)
|
|
2393
|
-
|
|
2394
|
-
if (a.agent !== b.agent)
|
|
2395
|
-
return a.agent < b.agent ? -1 : 1;
|
|
2439
|
+
if (dateDiff !== 0) return dateDiff;
|
|
2440
|
+
if (a.agent !== b.agent) return a.agent < b.agent ? -1 : 1;
|
|
2396
2441
|
const aTx = a.transactions?.[0]?.txHashes?.[0] ?? "";
|
|
2397
2442
|
const bTx = b.transactions?.[0]?.txHashes?.[0] ?? "";
|
|
2398
|
-
if (aTx !== bTx)
|
|
2399
|
-
|
|
2400
|
-
if (a.action !== b.action)
|
|
2401
|
-
return a.action < b.action ? -1 : 1;
|
|
2443
|
+
if (aTx !== bTx) return aTx < bTx ? -1 : 1;
|
|
2444
|
+
if (a.action !== b.action) return a.action < b.action ? -1 : 1;
|
|
2402
2445
|
return 0;
|
|
2403
2446
|
});
|
|
2404
2447
|
return {
|
|
@@ -2444,8 +2487,7 @@ var OwneySDK = class {
|
|
|
2444
2487
|
const state = this.requireState();
|
|
2445
2488
|
const chainId = this.requireChainId();
|
|
2446
2489
|
const agent = this.getAgent(agentId);
|
|
2447
|
-
if (typeof agent.ensureAutoSelectProtocols !== "function")
|
|
2448
|
-
return false;
|
|
2490
|
+
if (typeof agent.ensureAutoSelectProtocols !== "function") return false;
|
|
2449
2491
|
return agent.ensureAutoSelectProtocols(state, chainId, asset);
|
|
2450
2492
|
}
|
|
2451
2493
|
/**
|
|
@@ -2457,8 +2499,10 @@ var OwneySDK = class {
|
|
|
2457
2499
|
* @returns the approval transaction hash.
|
|
2458
2500
|
*/
|
|
2459
2501
|
async approvePermit2(asset = "WETH") {
|
|
2502
|
+
void asset;
|
|
2460
2503
|
const state = this.requireState();
|
|
2461
2504
|
const chainId = this.requireChainId();
|
|
2505
|
+
this.validateAssetSupport(this.getAgent("zyfai"), chainId, "WETH");
|
|
2462
2506
|
const token = SPONSORED_WETH_BY_CHAIN[chainId];
|
|
2463
2507
|
if (!token) {
|
|
2464
2508
|
throw new OwneyError(
|
|
@@ -2598,8 +2642,7 @@ var import_sdk2 = require("@zyfai/sdk");
|
|
|
2598
2642
|
// src/agents/zyfai/zyfai.siwx-cache.ts
|
|
2599
2643
|
var KEY_PREFIX2 = "owney.siwx.session";
|
|
2600
2644
|
var storage2 = () => {
|
|
2601
|
-
if (typeof window === "undefined")
|
|
2602
|
-
return null;
|
|
2645
|
+
if (typeof window === "undefined") return null;
|
|
2603
2646
|
try {
|
|
2604
2647
|
return window.localStorage;
|
|
2605
2648
|
} catch {
|
|
@@ -2609,11 +2652,9 @@ var storage2 = () => {
|
|
|
2609
2652
|
var buildKey2 = (address, chainId) => `${KEY_PREFIX2}:${address.toLowerCase()}:${chainId}`;
|
|
2610
2653
|
var readSiwxSession = (address, chainId) => {
|
|
2611
2654
|
const store = storage2();
|
|
2612
|
-
if (!store)
|
|
2613
|
-
return null;
|
|
2655
|
+
if (!store) return null;
|
|
2614
2656
|
const raw = store.getItem(buildKey2(address, chainId));
|
|
2615
|
-
if (!raw)
|
|
2616
|
-
return null;
|
|
2657
|
+
if (!raw) return null;
|
|
2617
2658
|
try {
|
|
2618
2659
|
return JSON.parse(raw);
|
|
2619
2660
|
} catch {
|
|
@@ -2623,8 +2664,7 @@ var readSiwxSession = (address, chainId) => {
|
|
|
2623
2664
|
};
|
|
2624
2665
|
var writeSiwxSession = (address, chainId, session) => {
|
|
2625
2666
|
const store = storage2();
|
|
2626
|
-
if (!store)
|
|
2627
|
-
return;
|
|
2667
|
+
if (!store) return;
|
|
2628
2668
|
try {
|
|
2629
2669
|
store.setItem(buildKey2(address, chainId), JSON.stringify(session));
|
|
2630
2670
|
} catch {
|
|
@@ -2632,8 +2672,7 @@ var writeSiwxSession = (address, chainId, session) => {
|
|
|
2632
2672
|
};
|
|
2633
2673
|
var clearSiwxSession = (address, chainId) => {
|
|
2634
2674
|
const store = storage2();
|
|
2635
|
-
if (!store)
|
|
2636
|
-
return;
|
|
2675
|
+
if (!store) return;
|
|
2637
2676
|
try {
|
|
2638
2677
|
store.removeItem(buildKey2(address, chainId));
|
|
2639
2678
|
} catch {
|
|
@@ -2696,12 +2735,10 @@ function buildSIWXConfig(deps) {
|
|
|
2696
2735
|
const jwt = readSession(address, id);
|
|
2697
2736
|
const stored = readSiwxSession(address, id);
|
|
2698
2737
|
if (!jwt) {
|
|
2699
|
-
if (stored)
|
|
2700
|
-
clearSiwxSession(address, id);
|
|
2738
|
+
if (stored) clearSiwxSession(address, id);
|
|
2701
2739
|
return [];
|
|
2702
2740
|
}
|
|
2703
|
-
if (!stored)
|
|
2704
|
-
return [];
|
|
2741
|
+
if (!stored) return [];
|
|
2705
2742
|
const session = {
|
|
2706
2743
|
// `stored.data.chainId` is a plain string in the cache (kept AppKit-free);
|
|
2707
2744
|
// it always holds a valid CaipNetworkId here, so narrow at the boundary.
|