@owney/sdk 0.7.16 → 0.7.17-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +434 -126
- package/dist/index.d.cts +35 -5
- package/dist/index.d.ts +35 -5
- package/dist/index.js +434 -126
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,3 +1,165 @@
|
|
|
1
|
+
// src/errors.ts
|
|
2
|
+
var OwneyError = class extends Error {
|
|
3
|
+
code;
|
|
4
|
+
details;
|
|
5
|
+
agentId;
|
|
6
|
+
constructor(code, message, details, agentId) {
|
|
7
|
+
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
8
|
+
super(`${prefix} ${message}`);
|
|
9
|
+
this.name = "OwneyError";
|
|
10
|
+
this.code = code;
|
|
11
|
+
this.details = details;
|
|
12
|
+
this.agentId = agentId;
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
var AgentNotFoundError = class extends OwneyError {
|
|
16
|
+
constructor(agentId, available) {
|
|
17
|
+
super(
|
|
18
|
+
"AGENT_NOT_FOUND",
|
|
19
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
20
|
+
{ agentId, available },
|
|
21
|
+
agentId
|
|
22
|
+
);
|
|
23
|
+
this.name = "AgentNotFoundError";
|
|
24
|
+
}
|
|
25
|
+
};
|
|
26
|
+
var NotConnectedError = class extends OwneyError {
|
|
27
|
+
constructor() {
|
|
28
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
29
|
+
this.name = "NotConnectedError";
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
var AgentChainIncompatibleError = class extends OwneyError {
|
|
33
|
+
incompatibleAgents;
|
|
34
|
+
connectedChainId;
|
|
35
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
36
|
+
const details = incompatibleAgents.map(
|
|
37
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
38
|
+
).join("; ");
|
|
39
|
+
super(
|
|
40
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
41
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
42
|
+
{ incompatibleAgents, connectedChainId }
|
|
43
|
+
);
|
|
44
|
+
this.name = "AgentChainIncompatibleError";
|
|
45
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
46
|
+
this.connectedChainId = connectedChainId;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// src/lib/rate-limit.ts
|
|
51
|
+
function rateLimitDelay(error, now = Date.now()) {
|
|
52
|
+
const seen = /* @__PURE__ */ new Set();
|
|
53
|
+
let limited = false;
|
|
54
|
+
let delay = 0;
|
|
55
|
+
function visit(value, depth = 0) {
|
|
56
|
+
if (depth > 6 || value == null) return;
|
|
57
|
+
if (typeof value === "string") {
|
|
58
|
+
if (/rate[ _-]?limit|too many requests|HTTP_429|\b429\b/i.test(value))
|
|
59
|
+
limited = true;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (typeof value !== "object" || seen.has(value)) return;
|
|
63
|
+
seen.add(value);
|
|
64
|
+
const record = value;
|
|
65
|
+
if ([record.status, record.statusCode, record.code].some(
|
|
66
|
+
(code) => String(code) === "429"
|
|
67
|
+
)) {
|
|
68
|
+
limited = true;
|
|
69
|
+
}
|
|
70
|
+
for (const key2 of ["retryAfterSeconds", "retryAfter"]) {
|
|
71
|
+
const seconds = Number(record[key2]);
|
|
72
|
+
if (Number.isFinite(seconds) && seconds > 0)
|
|
73
|
+
delay = Math.max(delay, seconds * 1e3);
|
|
74
|
+
}
|
|
75
|
+
const retryAt = Number(record.retryAt);
|
|
76
|
+
if (Number.isFinite(retryAt) && retryAt > now)
|
|
77
|
+
delay = Math.max(delay, retryAt - now);
|
|
78
|
+
const headers = record.headers;
|
|
79
|
+
const header = typeof headers?.get === "function" ? headers.get("Retry-After") : headers?.["retry-after"] ?? headers?.["Retry-After"];
|
|
80
|
+
if (typeof header === "string" || typeof header === "number") {
|
|
81
|
+
const seconds = Number(header);
|
|
82
|
+
const ms = Number.isFinite(seconds) ? seconds * 1e3 : Date.parse(String(header)) - now;
|
|
83
|
+
if (Number.isFinite(ms) && ms > 0) delay = Math.max(delay, ms);
|
|
84
|
+
}
|
|
85
|
+
for (const key2 of [
|
|
86
|
+
"message",
|
|
87
|
+
"code",
|
|
88
|
+
"cause",
|
|
89
|
+
"details",
|
|
90
|
+
"response",
|
|
91
|
+
"data",
|
|
92
|
+
"fields"
|
|
93
|
+
]) {
|
|
94
|
+
visit(record[key2], depth + 1);
|
|
95
|
+
}
|
|
96
|
+
for (const key2 of ["agentErrors", "failures"]) {
|
|
97
|
+
const entries = record[key2];
|
|
98
|
+
if (entries && typeof entries === "object") {
|
|
99
|
+
for (const entry of Object.values(entries)) visit(entry, depth + 1);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
visit(error);
|
|
104
|
+
return limited ? delay : void 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/lib/agent-reads.ts
|
|
108
|
+
var AgentReads = class {
|
|
109
|
+
inFlight = /* @__PURE__ */ new Map();
|
|
110
|
+
cooldowns = /* @__PURE__ */ new Map();
|
|
111
|
+
// A reconnect must not reuse work started by the previous connection.
|
|
112
|
+
clearInFlight() {
|
|
113
|
+
this.inFlight.clear();
|
|
114
|
+
}
|
|
115
|
+
limited(agentId, until) {
|
|
116
|
+
return new OwneyError(
|
|
117
|
+
"AGENT_RATE_LIMITED",
|
|
118
|
+
"Too many requests. Please wait before trying again.",
|
|
119
|
+
{
|
|
120
|
+
statusCode: 429,
|
|
121
|
+
retryAt: until,
|
|
122
|
+
retryAfterSeconds: Math.max(0, Math.ceil((until - Date.now()) / 1e3))
|
|
123
|
+
},
|
|
124
|
+
agentId
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
run(agentId, key2, fetch2) {
|
|
128
|
+
const cooldown = this.cooldowns.get(agentId);
|
|
129
|
+
if (cooldown && cooldown.until > Date.now()) {
|
|
130
|
+
return Promise.reject(this.limited(agentId, cooldown.until));
|
|
131
|
+
}
|
|
132
|
+
const requestKey = JSON.stringify([agentId, key2]);
|
|
133
|
+
const existing = this.inFlight.get(requestKey);
|
|
134
|
+
if (existing) return existing;
|
|
135
|
+
const promise = Promise.resolve().then(fetch2).then(
|
|
136
|
+
(value) => {
|
|
137
|
+
if (this.cooldowns.get(agentId) === cooldown)
|
|
138
|
+
this.cooldowns.delete(agentId);
|
|
139
|
+
return value;
|
|
140
|
+
},
|
|
141
|
+
(error) => {
|
|
142
|
+
const requestedDelay = rateLimitDelay(error);
|
|
143
|
+
if (requestedDelay === void 0) throw error;
|
|
144
|
+
const previous = this.cooldowns.get(agentId);
|
|
145
|
+
const failures = previous && previous.until > Date.now() ? previous.failures : Math.min((previous?.failures ?? 0) + 1, 5);
|
|
146
|
+
const delay = Math.max(
|
|
147
|
+
requestedDelay,
|
|
148
|
+
Math.min(3e4 * 2 ** (failures - 1), 3e5)
|
|
149
|
+
);
|
|
150
|
+
const until = Math.max(previous?.until ?? 0, Date.now() + delay);
|
|
151
|
+
this.cooldowns.set(agentId, { until, failures });
|
|
152
|
+
throw this.limited(agentId, until);
|
|
153
|
+
}
|
|
154
|
+
).finally(() => {
|
|
155
|
+
if (this.inFlight.get(requestKey) === promise)
|
|
156
|
+
this.inFlight.delete(requestKey);
|
|
157
|
+
});
|
|
158
|
+
this.inFlight.set(requestKey, promise);
|
|
159
|
+
return promise;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
|
|
1
163
|
// src/agents/zyfai/zyfai.agent.ts
|
|
2
164
|
import { SMART_SESSIONS_VALIDATOR, ZyfaiSDK } from "@zyfai/sdk";
|
|
3
165
|
import { createPublicClient, http, parseAbi } from "viem";
|
|
@@ -67,55 +229,6 @@ function debugLog(scope, message, data) {
|
|
|
67
229
|
}
|
|
68
230
|
}
|
|
69
231
|
|
|
70
|
-
// src/errors.ts
|
|
71
|
-
var OwneyError = class extends Error {
|
|
72
|
-
code;
|
|
73
|
-
details;
|
|
74
|
-
agentId;
|
|
75
|
-
constructor(code, message, details, agentId) {
|
|
76
|
-
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
77
|
-
super(`${prefix} ${message}`);
|
|
78
|
-
this.name = "OwneyError";
|
|
79
|
-
this.code = code;
|
|
80
|
-
this.details = details;
|
|
81
|
-
this.agentId = agentId;
|
|
82
|
-
}
|
|
83
|
-
};
|
|
84
|
-
var AgentNotFoundError = class extends OwneyError {
|
|
85
|
-
constructor(agentId, available) {
|
|
86
|
-
super(
|
|
87
|
-
"AGENT_NOT_FOUND",
|
|
88
|
-
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
89
|
-
{ agentId, available },
|
|
90
|
-
agentId
|
|
91
|
-
);
|
|
92
|
-
this.name = "AgentNotFoundError";
|
|
93
|
-
}
|
|
94
|
-
};
|
|
95
|
-
var NotConnectedError = class extends OwneyError {
|
|
96
|
-
constructor() {
|
|
97
|
-
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
98
|
-
this.name = "NotConnectedError";
|
|
99
|
-
}
|
|
100
|
-
};
|
|
101
|
-
var AgentChainIncompatibleError = class extends OwneyError {
|
|
102
|
-
incompatibleAgents;
|
|
103
|
-
connectedChainId;
|
|
104
|
-
constructor(incompatibleAgents, connectedChainId) {
|
|
105
|
-
const details = incompatibleAgents.map(
|
|
106
|
-
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
107
|
-
).join("; ");
|
|
108
|
-
super(
|
|
109
|
-
"AGENT_CHAIN_INCOMPATIBLE",
|
|
110
|
-
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
111
|
-
{ incompatibleAgents, connectedChainId }
|
|
112
|
-
);
|
|
113
|
-
this.name = "AgentChainIncompatibleError";
|
|
114
|
-
this.incompatibleAgents = incompatibleAgents;
|
|
115
|
-
this.connectedChainId = connectedChainId;
|
|
116
|
-
}
|
|
117
|
-
};
|
|
118
|
-
|
|
119
232
|
// src/lib/utils.ts
|
|
120
233
|
var isValidChainId = (chainId) => {
|
|
121
234
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
@@ -919,7 +1032,10 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
919
1032
|
// successful decode is cached forever; failures are NOT cached so a transient
|
|
920
1033
|
// RPC error retries on the next fetch.
|
|
921
1034
|
withdrawAmountCache = /* @__PURE__ */ new Map();
|
|
922
|
-
|
|
1035
|
+
earningsReads = /* @__PURE__ */ new Map();
|
|
1036
|
+
earningsRefreshes = /* @__PURE__ */ new Map();
|
|
1037
|
+
earningsSnapshot = null;
|
|
1038
|
+
earningsGeneration = 0;
|
|
923
1039
|
constructor(apiKey, rpcUrls, referralSource) {
|
|
924
1040
|
this.rpcUrls = rpcUrls ?? DEFAULT_ZYFAI_RPC_URLS;
|
|
925
1041
|
this.sdk = new ZyfaiSDK({
|
|
@@ -1164,6 +1280,10 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1164
1280
|
}
|
|
1165
1281
|
// --- IAgent: Connection lifecycle ---
|
|
1166
1282
|
async disconnect() {
|
|
1283
|
+
this.earningsGeneration++;
|
|
1284
|
+
this.earningsReads.clear();
|
|
1285
|
+
this.earningsRefreshes.clear();
|
|
1286
|
+
this.earningsSnapshot = null;
|
|
1167
1287
|
if (this.connectedAddress && this.connectedChainId !== null) {
|
|
1168
1288
|
clearSession(this.connectedAddress, this.connectedChainId);
|
|
1169
1289
|
}
|
|
@@ -1712,26 +1832,59 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1712
1832
|
const raw = await this.sdk.getPortfolio(this.getAddress());
|
|
1713
1833
|
return mapBalances(raw, validChainId, smartWallet);
|
|
1714
1834
|
}
|
|
1835
|
+
earningsKey(state, chainId, smartWallet) {
|
|
1836
|
+
return JSON.stringify([
|
|
1837
|
+
state.walletAddress?.toLowerCase(),
|
|
1838
|
+
chainId,
|
|
1839
|
+
smartWallet.toLowerCase()
|
|
1840
|
+
]);
|
|
1841
|
+
}
|
|
1842
|
+
readEarnings(key2, smartWallet) {
|
|
1843
|
+
const existing = this.earningsReads.get(key2);
|
|
1844
|
+
if (existing) return existing;
|
|
1845
|
+
const generation = this.earningsGeneration;
|
|
1846
|
+
const pending = Promise.resolve().then(() => this.sdk.getOnchainEarnings(smartWallet)).then((raw) => {
|
|
1847
|
+
if (generation === this.earningsGeneration) {
|
|
1848
|
+
this.earningsSnapshot = { key: key2, raw, at: Date.now() };
|
|
1849
|
+
}
|
|
1850
|
+
return raw;
|
|
1851
|
+
}).finally(() => {
|
|
1852
|
+
if (this.earningsReads.get(key2) === pending)
|
|
1853
|
+
this.earningsReads.delete(key2);
|
|
1854
|
+
});
|
|
1855
|
+
this.earningsReads.set(key2, pending);
|
|
1856
|
+
return pending;
|
|
1857
|
+
}
|
|
1715
1858
|
async getEarnings(state, chainId) {
|
|
1716
1859
|
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
1717
|
-
const raw = await this.
|
|
1860
|
+
const raw = await this.readEarnings(
|
|
1861
|
+
this.earningsKey(state, chainId, smartWallet),
|
|
1862
|
+
smartWallet
|
|
1863
|
+
);
|
|
1718
1864
|
return mapEarnings(raw, smartWallet);
|
|
1719
1865
|
}
|
|
1720
1866
|
async refreshEarnings(state, chainId) {
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1867
|
+
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
1868
|
+
const key2 = this.earningsKey(state, chainId, smartWallet);
|
|
1869
|
+
const existing = this.earningsRefreshes.get(key2);
|
|
1870
|
+
if (existing) return existing;
|
|
1871
|
+
const generation = this.earningsGeneration;
|
|
1872
|
+
const pending = (async () => {
|
|
1873
|
+
const recent = this.earningsSnapshot;
|
|
1874
|
+
const current = recent?.key === key2 && Date.now() - recent.at < 5e3 ? recent.raw : await this.readEarnings(key2, smartWallet);
|
|
1725
1875
|
const lastCheck = current.data.lastCheckTimestamp ? Date.parse(current.data.lastCheckTimestamp) : Number.NaN;
|
|
1726
1876
|
const isFresh = Number.isFinite(lastCheck) && Date.now() - lastCheck < EARNINGS_REFRESH_COOLDOWN_MS;
|
|
1727
1877
|
const earnings = isFresh ? current : await this.sdk.calculateOnchainEarnings(smartWallet);
|
|
1878
|
+
if (!isFresh && generation === this.earningsGeneration) {
|
|
1879
|
+
this.earningsSnapshot = { key: key2, raw: earnings, at: Date.now() };
|
|
1880
|
+
}
|
|
1728
1881
|
return mapEarnings(earnings, smartWallet);
|
|
1729
|
-
})()
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
}
|
|
1733
|
-
|
|
1734
|
-
|
|
1882
|
+
})().finally(() => {
|
|
1883
|
+
if (this.earningsRefreshes.get(key2) === pending)
|
|
1884
|
+
this.earningsRefreshes.delete(key2);
|
|
1885
|
+
});
|
|
1886
|
+
this.earningsRefreshes.set(key2, pending);
|
|
1887
|
+
return pending;
|
|
1735
1888
|
}
|
|
1736
1889
|
async getAccountApy(state, chainId, days, tokenSymbol) {
|
|
1737
1890
|
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
@@ -2653,6 +2806,17 @@ var OwneySDK = class {
|
|
|
2653
2806
|
cachedWethSponsoredCallback = null;
|
|
2654
2807
|
paymasterServiceUrl;
|
|
2655
2808
|
cachedSponsoredCallsCallbacks = /* @__PURE__ */ new Map();
|
|
2809
|
+
agentReads = new AgentReads();
|
|
2810
|
+
activationChecks = /* @__PURE__ */ new Map();
|
|
2811
|
+
readAgent(agent, method, fetch2, params = null) {
|
|
2812
|
+
const key2 = JSON.stringify([
|
|
2813
|
+
this.state?.walletAddress.toLowerCase() ?? null,
|
|
2814
|
+
this.state?.chainId ?? null,
|
|
2815
|
+
method,
|
|
2816
|
+
params
|
|
2817
|
+
]);
|
|
2818
|
+
return this.agentReads.run(agent.id, key2, fetch2);
|
|
2819
|
+
}
|
|
2656
2820
|
initializingAgentsPromise = null;
|
|
2657
2821
|
constructor(config) {
|
|
2658
2822
|
this.apiKey = config.apiKey;
|
|
@@ -2679,6 +2843,8 @@ var OwneySDK = class {
|
|
|
2679
2843
|
"No accounts found. Ensure the wallet is unlocked and connected."
|
|
2680
2844
|
);
|
|
2681
2845
|
}
|
|
2846
|
+
this.agentReads.clearInFlight();
|
|
2847
|
+
this.activationChecks.clear();
|
|
2682
2848
|
this.state = { provider, walletAddress, chainId: null };
|
|
2683
2849
|
this.cachedSponsoredCallback = null;
|
|
2684
2850
|
this.cachedWethSponsoredCallback = null;
|
|
@@ -2694,6 +2860,8 @@ var OwneySDK = class {
|
|
|
2694
2860
|
}
|
|
2695
2861
|
this.activeAgents.clear();
|
|
2696
2862
|
this.disabledAgents.clear();
|
|
2863
|
+
this.agentReads.clearInFlight();
|
|
2864
|
+
this.activationChecks.clear();
|
|
2697
2865
|
this.state = null;
|
|
2698
2866
|
this.cachedSponsoredCallback = null;
|
|
2699
2867
|
this.cachedWethSponsoredCallback = null;
|
|
@@ -2924,6 +3092,37 @@ var OwneySDK = class {
|
|
|
2924
3092
|
}
|
|
2925
3093
|
return null;
|
|
2926
3094
|
}
|
|
3095
|
+
/**
|
|
3096
|
+
* Discover the agents actually returned by routing for this organization.
|
|
3097
|
+
* Consumers should use this instead of hardcoding a global agent roster.
|
|
3098
|
+
*/
|
|
3099
|
+
async getAvailableAgents(options = {}) {
|
|
3100
|
+
await this.ensureAgentsInitialized();
|
|
3101
|
+
const { chainId, asset, includeDisabled = false } = options;
|
|
3102
|
+
const available = [];
|
|
3103
|
+
for (const [id, agent] of this.agents) {
|
|
3104
|
+
const isEnabled = !this.isAgentDisabled(id);
|
|
3105
|
+
if (!includeDisabled && !isEnabled) continue;
|
|
3106
|
+
if (chainId !== void 0 && !agent.supportedChainIds.includes(chainId)) {
|
|
3107
|
+
continue;
|
|
3108
|
+
}
|
|
3109
|
+
if (asset !== void 0) {
|
|
3110
|
+
const supportsAsset = agent.supportedAssets.some(
|
|
3111
|
+
(entry) => (chainId === void 0 || entry.chainId === chainId) && entry.assets.some((candidate) => candidate.symbol === asset)
|
|
3112
|
+
);
|
|
3113
|
+
if (!supportsAsset) {
|
|
3114
|
+
continue;
|
|
3115
|
+
}
|
|
3116
|
+
}
|
|
3117
|
+
available.push({
|
|
3118
|
+
id,
|
|
3119
|
+
isEnabled,
|
|
3120
|
+
supportedChainIds: agent.supportedChainIds,
|
|
3121
|
+
supportedAssets: agent.supportedAssets
|
|
3122
|
+
});
|
|
3123
|
+
}
|
|
3124
|
+
return available;
|
|
3125
|
+
}
|
|
2927
3126
|
// --- Account lifecycle ---
|
|
2928
3127
|
/**
|
|
2929
3128
|
* Activate the user's smart wallet for the specified agents, or all chain-compatible agents if omitted.
|
|
@@ -2971,9 +3170,7 @@ var OwneySDK = class {
|
|
|
2971
3170
|
this.activeAgents.add(id);
|
|
2972
3171
|
}
|
|
2973
3172
|
state.chainId = chainId;
|
|
2974
|
-
this.activateAgentsInTurn(agents, state, chainId)
|
|
2975
|
-
console.error("activateAgent background init failed:", error);
|
|
2976
|
-
});
|
|
3173
|
+
await this.activateAgentsInTurn(agents, state, chainId);
|
|
2977
3174
|
return;
|
|
2978
3175
|
}
|
|
2979
3176
|
const compatible = [...this.agents.values()].filter(
|
|
@@ -2994,11 +3191,7 @@ var OwneySDK = class {
|
|
|
2994
3191
|
const enabledCompatible = compatible.filter(
|
|
2995
3192
|
(agent) => !this.isAgentDisabled(agent.id)
|
|
2996
3193
|
);
|
|
2997
|
-
this.activateAgentsInTurn(enabledCompatible, state, chainId)
|
|
2998
|
-
(error) => {
|
|
2999
|
-
console.error("activateAgent background init failed:", error);
|
|
3000
|
-
}
|
|
3001
|
-
);
|
|
3194
|
+
await this.activateAgentsInTurn(enabledCompatible, state, chainId);
|
|
3002
3195
|
}
|
|
3003
3196
|
/**
|
|
3004
3197
|
* Activate agents ONE AT A TIME, each followed by its org policy.
|
|
@@ -3035,7 +3228,7 @@ var OwneySDK = class {
|
|
|
3035
3228
|
if (firstError !== null) throw firstError;
|
|
3036
3229
|
}
|
|
3037
3230
|
/**
|
|
3038
|
-
* Deposit
|
|
3231
|
+
* Deposit into a specific agent, or distribute across all eligible agents.
|
|
3039
3232
|
* Validates that the asset is supported and amount meets minimums for the target agent(s).
|
|
3040
3233
|
* @param options - Deposit parameters
|
|
3041
3234
|
* @param options.amount - Amount to deposit in smallest unit (e.g. "100000000" for 100 USDC)
|
|
@@ -3043,7 +3236,8 @@ var OwneySDK = class {
|
|
|
3043
3236
|
* @param options.depositCallback - Callback that performs the token transfer and returns a tx hash.
|
|
3044
3237
|
* When agentId is omitted, this callback is invoked once per eligible agent with that agent's
|
|
3045
3238
|
* split amount and smart wallet address — expect multiple wallet prompts.
|
|
3046
|
-
* @param options.agentId - Optional
|
|
3239
|
+
* @param options.agentId - Optional explicit target. Otherwise split equally,
|
|
3240
|
+
* or fund remaining agents when a recovery deposit cannot meet every minimum.
|
|
3047
3241
|
* @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
|
|
3048
3242
|
*/
|
|
3049
3243
|
async deposit(options) {
|
|
@@ -3081,7 +3275,7 @@ var OwneySDK = class {
|
|
|
3081
3275
|
});
|
|
3082
3276
|
const exemptFlags = await Promise.all(
|
|
3083
3277
|
eligibleAgents.map(
|
|
3084
|
-
(a) => this.hasExistingBalance(a, state, chainId, asset)
|
|
3278
|
+
(a) => this.hasExistingBalance(a, state, chainId, asset, true)
|
|
3085
3279
|
)
|
|
3086
3280
|
);
|
|
3087
3281
|
const exempt = new Set(
|
|
@@ -3095,23 +3289,67 @@ var OwneySDK = class {
|
|
|
3095
3289
|
exempt
|
|
3096
3290
|
);
|
|
3097
3291
|
if (agentAmounts.length === 0) {
|
|
3292
|
+
const agentsRequiringActivation = eligibleAgents.filter(
|
|
3293
|
+
(agent) => !exempt.has(agent.id)
|
|
3294
|
+
);
|
|
3295
|
+
const perAgentMinimum = agentsRequiringActivation.reduce(
|
|
3296
|
+
(highest, agent) => {
|
|
3297
|
+
const minimum = this.getMinDepositAmount(agent, chainId, asset);
|
|
3298
|
+
return minimum > highest ? minimum : highest;
|
|
3299
|
+
},
|
|
3300
|
+
0n
|
|
3301
|
+
);
|
|
3302
|
+
const minimumRequired = agentsRequiringActivation.length > 0 ? (perAgentMinimum > 0n ? perAgentMinimum : 1n) * BigInt(agentsRequiringActivation.length) : BigInt(eligibleAgents.length);
|
|
3098
3303
|
throw new OwneyError(
|
|
3099
3304
|
"DEPOSIT_AMOUNT_BELOW_MINIMUM",
|
|
3100
|
-
`Amount "${amount}" cannot
|
|
3101
|
-
{
|
|
3305
|
+
`Amount "${amount}" cannot activate every eligible agent. The combined minimum is "${minimumRequired.toString()}" for ${asset}.`,
|
|
3306
|
+
{
|
|
3307
|
+
amount,
|
|
3308
|
+
asset,
|
|
3309
|
+
chainId,
|
|
3310
|
+
minDepositAmount: minimumRequired.toString(),
|
|
3311
|
+
perAgentDepositAmount: perAgentMinimum.toString(),
|
|
3312
|
+
agentMinimums: agentsRequiringActivation.map((agent) => ({
|
|
3313
|
+
agentId: agent.id,
|
|
3314
|
+
minDepositAmount: this.getMinDepositAmount(
|
|
3315
|
+
agent,
|
|
3316
|
+
chainId,
|
|
3317
|
+
asset
|
|
3318
|
+
).toString()
|
|
3319
|
+
}))
|
|
3320
|
+
}
|
|
3102
3321
|
);
|
|
3103
3322
|
}
|
|
3104
3323
|
const agentResults = {};
|
|
3105
|
-
for (const
|
|
3106
|
-
|
|
3107
|
-
|
|
3108
|
-
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
|
|
3324
|
+
for (const [
|
|
3325
|
+
index,
|
|
3326
|
+
{ agent, amount: agentAmount }
|
|
3327
|
+
] of agentAmounts.entries()) {
|
|
3328
|
+
try {
|
|
3329
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
3330
|
+
agent,
|
|
3331
|
+
state,
|
|
3332
|
+
chainId,
|
|
3333
|
+
agentAmount,
|
|
3334
|
+
asset,
|
|
3335
|
+
effectiveCallback,
|
|
3336
|
+
depositCallback
|
|
3337
|
+
);
|
|
3338
|
+
} catch (error) {
|
|
3339
|
+
if (Object.keys(agentResults).length === 0) throw error;
|
|
3340
|
+
throw new OwneyError(
|
|
3341
|
+
"DEPOSIT_PARTIAL_FAILURE",
|
|
3342
|
+
"Some deposits completed before another agent failed. Check activity and balances before depositing again; the failed transfer may still settle.",
|
|
3343
|
+
{
|
|
3344
|
+
agentResults,
|
|
3345
|
+
failedAgentId: agent.id,
|
|
3346
|
+
failedAmount: agentAmount,
|
|
3347
|
+
unattemptedAgentIds: agentAmounts.slice(index + 1).map(({ agent: agent2 }) => agent2.id),
|
|
3348
|
+
cause: error
|
|
3349
|
+
},
|
|
3350
|
+
agent.id
|
|
3351
|
+
);
|
|
3352
|
+
}
|
|
3115
3353
|
}
|
|
3116
3354
|
return { agentResults };
|
|
3117
3355
|
}
|
|
@@ -3184,6 +3422,17 @@ var OwneySDK = class {
|
|
|
3184
3422
|
}
|
|
3185
3423
|
splitDepositAmount(totalAmount, agents, chainId, asset, exempt = /* @__PURE__ */ new Set()) {
|
|
3186
3424
|
if (agents.length === 0) return [];
|
|
3425
|
+
const agentsRequiringActivation = agents.filter(
|
|
3426
|
+
(agent) => !exempt.has(agent.id)
|
|
3427
|
+
);
|
|
3428
|
+
if (agentsRequiringActivation.length === agents.length) {
|
|
3429
|
+
const highestMinimum2 = agents.reduce((highest, agent) => {
|
|
3430
|
+
const minimum = this.getMinDepositAmount(agent, chainId, asset);
|
|
3431
|
+
return minimum > highest ? minimum : highest;
|
|
3432
|
+
}, 0n);
|
|
3433
|
+
const minimumRequired2 = (highestMinimum2 > 0n ? highestMinimum2 : 1n) * BigInt(agents.length);
|
|
3434
|
+
if (totalAmount < minimumRequired2) return [];
|
|
3435
|
+
}
|
|
3187
3436
|
const perAgent = totalAmount / BigInt(agents.length);
|
|
3188
3437
|
const remainder = totalAmount % BigInt(agents.length);
|
|
3189
3438
|
const splits = agents.map((agent, i) => ({
|
|
@@ -3191,18 +3440,26 @@ var OwneySDK = class {
|
|
|
3191
3440
|
amount: i === agents.length - 1 ? perAgent + remainder : perAgent
|
|
3192
3441
|
}));
|
|
3193
3442
|
const valid = splits.filter(
|
|
3194
|
-
(s) => exempt.has(s.agent.id) || s.amount >= this.getMinDepositAmount(s.agent, chainId, asset)
|
|
3443
|
+
(s) => s.amount > 0n && (exempt.has(s.agent.id) || s.amount >= this.getMinDepositAmount(s.agent, chainId, asset))
|
|
3195
3444
|
);
|
|
3196
3445
|
if (valid.length === agents.length) {
|
|
3197
3446
|
return splits.map((s) => ({ agent: s.agent, amount: String(s.amount) }));
|
|
3198
3447
|
}
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
);
|
|
3448
|
+
const targets = agentsRequiringActivation.length > 0 ? agentsRequiringActivation : agents;
|
|
3449
|
+
const highestMinimum = targets.reduce((highest, agent) => {
|
|
3450
|
+
const minimum = this.getMinDepositAmount(agent, chainId, asset);
|
|
3451
|
+
return minimum > highest ? minimum : highest;
|
|
3452
|
+
}, 0n);
|
|
3453
|
+
const minimumRequired = (highestMinimum > 0n ? highestMinimum : 1n) * BigInt(targets.length);
|
|
3454
|
+
if (totalAmount < minimumRequired) return [];
|
|
3455
|
+
const targetShare = totalAmount / BigInt(targets.length);
|
|
3456
|
+
const targetRemainder = totalAmount % BigInt(targets.length);
|
|
3457
|
+
return targets.map((agent, index) => ({
|
|
3458
|
+
agent,
|
|
3459
|
+
amount: String(
|
|
3460
|
+
targetShare + (index === targets.length - 1 ? targetRemainder : 0n)
|
|
3461
|
+
)
|
|
3462
|
+
}));
|
|
3206
3463
|
}
|
|
3207
3464
|
async validateMinDepositAmount(agent, state, chainId, asset, amount) {
|
|
3208
3465
|
const minDepositAmount = this.getMinDepositAmount(agent, chainId, asset);
|
|
@@ -3227,15 +3484,29 @@ var OwneySDK = class {
|
|
|
3227
3484
|
* per-agent minimum. Fails closed: any error reading balances returns
|
|
3228
3485
|
* false, so the minimum is enforced as today.
|
|
3229
3486
|
*/
|
|
3230
|
-
async hasExistingBalance(agent, state, chainId, asset) {
|
|
3487
|
+
async hasExistingBalance(agent, state, chainId, asset, requireReliableRead = false) {
|
|
3231
3488
|
try {
|
|
3232
3489
|
const balance = await agent.getBalances(state, chainId);
|
|
3233
3490
|
const target = asset.toLowerCase();
|
|
3234
3491
|
const token = balance.tokens.find(
|
|
3235
3492
|
(t) => t.chainId === chainId && t.asset.toLowerCase() === target
|
|
3236
3493
|
);
|
|
3237
|
-
|
|
3238
|
-
|
|
3494
|
+
const targetChainName = agent.supportedAssets.find((entry) => entry.chainId === chainId)?.chain?.trim().toUpperCase();
|
|
3495
|
+
const position = (balance.positions ?? []).find((p) => {
|
|
3496
|
+
const positionChain = p.chain.trim().toUpperCase();
|
|
3497
|
+
const matchesChain = positionChain === String(chainId) || targetChainName !== void 0 && positionChain === targetChainName;
|
|
3498
|
+
return matchesChain && p.asset.toLowerCase() === target && Number(p.amount) > 0;
|
|
3499
|
+
});
|
|
3500
|
+
return !!token && Number(token.amount) > 0 || !!position;
|
|
3501
|
+
} catch (error) {
|
|
3502
|
+
if (requireReliableRead) {
|
|
3503
|
+
throw new OwneyError(
|
|
3504
|
+
"DEPOSIT_BALANCE_UNAVAILABLE",
|
|
3505
|
+
"Could not verify every agent balance. No deposit was submitted. Try again once balances are available.",
|
|
3506
|
+
{ agentId: agent.id, chainId, asset, cause: error },
|
|
3507
|
+
agent.id
|
|
3508
|
+
);
|
|
3509
|
+
}
|
|
3239
3510
|
return false;
|
|
3240
3511
|
}
|
|
3241
3512
|
}
|
|
@@ -3331,9 +3602,12 @@ var OwneySDK = class {
|
|
|
3331
3602
|
{ asset, agentErrors: agentErrors2 }
|
|
3332
3603
|
);
|
|
3333
3604
|
}
|
|
3605
|
+
const amountsKnown = Object.values(results2).every(
|
|
3606
|
+
(result) => typeof result.amount === "string" && /^\d+$/.test(result.amount)
|
|
3607
|
+
);
|
|
3334
3608
|
return {
|
|
3335
3609
|
agentResult: results2,
|
|
3336
|
-
totalWithdrawn: sumWithdrawnAmount(results2).toString()
|
|
3610
|
+
totalWithdrawn: amountsKnown ? sumWithdrawnAmount(results2).toString() : null
|
|
3337
3611
|
};
|
|
3338
3612
|
}
|
|
3339
3613
|
const requested = BigInt(amount);
|
|
@@ -3438,7 +3712,8 @@ var OwneySDK = class {
|
|
|
3438
3712
|
const state = this.requireState();
|
|
3439
3713
|
const chainId = this.requireChainId();
|
|
3440
3714
|
if (agentId) {
|
|
3441
|
-
const
|
|
3715
|
+
const agent = this.getAgent(agentId);
|
|
3716
|
+
const result = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
|
|
3442
3717
|
return result;
|
|
3443
3718
|
}
|
|
3444
3719
|
let totalBalance = 0;
|
|
@@ -3446,12 +3721,14 @@ var OwneySDK = class {
|
|
|
3446
3721
|
const entries = [...this.getActiveAgents().entries()];
|
|
3447
3722
|
const balanceResults = await Promise.allSettled(
|
|
3448
3723
|
entries.map(async ([id, agent]) => {
|
|
3449
|
-
const b = await agent.getBalances(state, chainId);
|
|
3724
|
+
const b = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
|
|
3450
3725
|
return [id, b];
|
|
3451
3726
|
})
|
|
3452
3727
|
);
|
|
3453
3728
|
let successCount = 0;
|
|
3454
3729
|
const agentErrors = {};
|
|
3730
|
+
const agentRetryAt = {};
|
|
3731
|
+
const agentFailures = [];
|
|
3455
3732
|
for (let i = 0; i < balanceResults.length; i++) {
|
|
3456
3733
|
const settledResult = balanceResults[i];
|
|
3457
3734
|
const [agentId2] = entries[i];
|
|
@@ -3463,19 +3740,23 @@ var OwneySDK = class {
|
|
|
3463
3740
|
continue;
|
|
3464
3741
|
}
|
|
3465
3742
|
const reason = settledResult.reason;
|
|
3743
|
+
agentFailures.push(reason);
|
|
3744
|
+
const retryDelay = rateLimitDelay(reason);
|
|
3745
|
+
if (retryDelay !== void 0) agentRetryAt[agentId2] = Date.now() + retryDelay;
|
|
3466
3746
|
agentErrors[agentId2] = reason instanceof Error ? reason.message : String(reason);
|
|
3467
3747
|
}
|
|
3468
3748
|
if (successCount === 0) {
|
|
3469
3749
|
throw new OwneyError(
|
|
3470
3750
|
"BALANCE_ALL_FAILED",
|
|
3471
3751
|
"Failed to fetch balances for all active agents.",
|
|
3472
|
-
{ agentErrors }
|
|
3752
|
+
{ agentErrors, failures: agentFailures }
|
|
3473
3753
|
);
|
|
3474
3754
|
}
|
|
3475
3755
|
return {
|
|
3476
3756
|
totalBalance: String(totalBalance),
|
|
3477
3757
|
totalBalanceAsset: "usdc",
|
|
3478
|
-
agentBalances: results
|
|
3758
|
+
agentBalances: results,
|
|
3759
|
+
...Object.keys(agentErrors).length > 0 ? { agentErrors, agentRetryAt } : {}
|
|
3479
3760
|
};
|
|
3480
3761
|
}
|
|
3481
3762
|
/**
|
|
@@ -3487,14 +3768,15 @@ var OwneySDK = class {
|
|
|
3487
3768
|
const state = this.requireState();
|
|
3488
3769
|
const chainId = this.requireChainId();
|
|
3489
3770
|
if (agentId) {
|
|
3490
|
-
|
|
3771
|
+
const agent = this.getAgent(agentId);
|
|
3772
|
+
return this.readAgent(agent, "earnings", () => agent.getEarnings(state, chainId));
|
|
3491
3773
|
}
|
|
3492
3774
|
let totalEarnings = 0;
|
|
3493
3775
|
const results = {};
|
|
3494
3776
|
const entries = [...this.getActiveAgents().entries()];
|
|
3495
3777
|
const earningsResults = await Promise.all(
|
|
3496
3778
|
entries.map(async ([id, agent]) => {
|
|
3497
|
-
const e = await agent.getEarnings(state, chainId);
|
|
3779
|
+
const e = await this.readAgent(agent, "earnings", () => agent.getEarnings(state, chainId));
|
|
3498
3780
|
return [id, e];
|
|
3499
3781
|
})
|
|
3500
3782
|
);
|
|
@@ -3514,7 +3796,11 @@ var OwneySDK = class {
|
|
|
3514
3796
|
async refreshEarnings(agentId) {
|
|
3515
3797
|
const state = this.requireState();
|
|
3516
3798
|
const chainId = this.requireChainId();
|
|
3517
|
-
const refreshAgent = (agent) =>
|
|
3799
|
+
const refreshAgent = (agent) => this.readAgent(
|
|
3800
|
+
agent,
|
|
3801
|
+
agent.refreshEarnings ? "refreshEarnings" : "earnings",
|
|
3802
|
+
() => agent.refreshEarnings?.(state, chainId) ?? agent.getEarnings(state, chainId)
|
|
3803
|
+
);
|
|
3518
3804
|
if (agentId) return refreshAgent(this.getAgent(agentId));
|
|
3519
3805
|
let totalEarnings = 0;
|
|
3520
3806
|
const agentEarnings = {};
|
|
@@ -3545,11 +3831,12 @@ var OwneySDK = class {
|
|
|
3545
3831
|
const state = this.requireState();
|
|
3546
3832
|
const chainId = this.requireChainId();
|
|
3547
3833
|
if (agentId) {
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
tokenSymbol
|
|
3834
|
+
const agent = this.getAgent(agentId);
|
|
3835
|
+
return this.readAgent(
|
|
3836
|
+
agent,
|
|
3837
|
+
"accountApy",
|
|
3838
|
+
() => agent.getAccountApy(state, chainId, days, tokenSymbol),
|
|
3839
|
+
{ days, tokenSymbol }
|
|
3553
3840
|
);
|
|
3554
3841
|
}
|
|
3555
3842
|
const activeAgents = this.getActiveAgents();
|
|
@@ -3557,18 +3844,18 @@ var OwneySDK = class {
|
|
|
3557
3844
|
const [apyResults, balanceResults] = await Promise.all([
|
|
3558
3845
|
Promise.all(
|
|
3559
3846
|
entries.map(async ([id, agent]) => {
|
|
3560
|
-
const apy = await
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
days,
|
|
3564
|
-
tokenSymbol
|
|
3847
|
+
const apy = await this.readAgent(
|
|
3848
|
+
agent,
|
|
3849
|
+
"accountApy",
|
|
3850
|
+
() => agent.getAccountApy(state, chainId, days, tokenSymbol),
|
|
3851
|
+
{ days, tokenSymbol }
|
|
3565
3852
|
);
|
|
3566
3853
|
return [id, apy];
|
|
3567
3854
|
})
|
|
3568
3855
|
),
|
|
3569
3856
|
Promise.all(
|
|
3570
3857
|
entries.map(async ([id, agent]) => {
|
|
3571
|
-
const b = await agent.getBalances(state, chainId);
|
|
3858
|
+
const b = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
|
|
3572
3859
|
return [id, Number(b.totalBalance)];
|
|
3573
3860
|
})
|
|
3574
3861
|
)
|
|
@@ -3625,7 +3912,8 @@ var OwneySDK = class {
|
|
|
3625
3912
|
const chainId = this.requireChainId();
|
|
3626
3913
|
const { agentId, filters } = options ?? {};
|
|
3627
3914
|
if (agentId) {
|
|
3628
|
-
|
|
3915
|
+
const agent = this.getAgent(agentId);
|
|
3916
|
+
return this.readAgent(agent, "history", () => agent.getHistory(state, chainId, filters), filters);
|
|
3629
3917
|
}
|
|
3630
3918
|
const activeAgents = [...this.getActiveAgents().values()];
|
|
3631
3919
|
const cursorMap = filters?.cursor ? decodeMultiAgentCursor(filters.cursor) : {};
|
|
@@ -3635,10 +3923,13 @@ var OwneySDK = class {
|
|
|
3635
3923
|
if (filters?.cursor && agentCursor === void 0) {
|
|
3636
3924
|
return { agentId: agent.id, page: null };
|
|
3637
3925
|
}
|
|
3638
|
-
const
|
|
3639
|
-
|
|
3640
|
-
|
|
3641
|
-
|
|
3926
|
+
const agentFilters = { ...filters, cursor: agentCursor };
|
|
3927
|
+
const page = await this.readAgent(
|
|
3928
|
+
agent,
|
|
3929
|
+
"history",
|
|
3930
|
+
() => agent.getHistory(state, chainId, agentFilters),
|
|
3931
|
+
agentFilters
|
|
3932
|
+
);
|
|
3642
3933
|
return { agentId: agent.id, page };
|
|
3643
3934
|
})
|
|
3644
3935
|
);
|
|
@@ -3678,13 +3969,14 @@ var OwneySDK = class {
|
|
|
3678
3969
|
const state = this.requireState();
|
|
3679
3970
|
const chainId = this.requireChainId();
|
|
3680
3971
|
if (agentId) {
|
|
3681
|
-
|
|
3972
|
+
const agent = this.getAgent(agentId);
|
|
3973
|
+
return this.readAgent(agent, "profile", () => agent.getUserProfile(state, chainId));
|
|
3682
3974
|
}
|
|
3683
3975
|
const results = {};
|
|
3684
3976
|
const entries = [...this.getActiveAgents().entries()];
|
|
3685
3977
|
const profileResults = await Promise.all(
|
|
3686
3978
|
entries.map(async ([id, agent]) => {
|
|
3687
|
-
const p = await agent.getUserProfile(state, chainId);
|
|
3979
|
+
const p = await this.readAgent(agent, "profile", () => agent.getUserProfile(state, chainId));
|
|
3688
3980
|
return [id, p];
|
|
3689
3981
|
})
|
|
3690
3982
|
);
|
|
@@ -3707,7 +3999,20 @@ var OwneySDK = class {
|
|
|
3707
3999
|
const chainId = this.requireChainId();
|
|
3708
4000
|
const agent = this.getAgent(agentId);
|
|
3709
4001
|
if (typeof agent.ensureAutoSelectProtocols !== "function") return false;
|
|
3710
|
-
|
|
4002
|
+
const key2 = JSON.stringify([
|
|
4003
|
+
state.walletAddress.toLowerCase(),
|
|
4004
|
+
agentId,
|
|
4005
|
+
chainId,
|
|
4006
|
+
asset
|
|
4007
|
+
]);
|
|
4008
|
+
const existing = this.activationChecks.get(key2);
|
|
4009
|
+
if (existing) return existing;
|
|
4010
|
+
const pending = Promise.resolve().then(() => agent.ensureAutoSelectProtocols(state, chainId, asset)).finally(() => {
|
|
4011
|
+
if (this.activationChecks.get(key2) === pending)
|
|
4012
|
+
this.activationChecks.delete(key2);
|
|
4013
|
+
});
|
|
4014
|
+
this.activationChecks.set(key2, pending);
|
|
4015
|
+
return pending;
|
|
3711
4016
|
}
|
|
3712
4017
|
/**
|
|
3713
4018
|
* One-time, user-paid approval of Permit2 on the sponsored WETH token for
|
|
@@ -3778,13 +4083,14 @@ var OwneySDK = class {
|
|
|
3778
4083
|
await this.ensureAgentsInitialized();
|
|
3779
4084
|
const agentOptions = { tokenSymbol, chainId };
|
|
3780
4085
|
if (agentId) {
|
|
3781
|
-
|
|
4086
|
+
const agent = this.getAgent(agentId);
|
|
4087
|
+
return this.readAgent(agent, "agentApy", () => agent.getAgentApy(days, agentOptions), { days, ...agentOptions });
|
|
3782
4088
|
}
|
|
3783
4089
|
const results = {};
|
|
3784
4090
|
const agentEntries = [...this.agents.entries()];
|
|
3785
4091
|
const apyResults = await Promise.all(
|
|
3786
4092
|
agentEntries.map(async ([id, agent]) => {
|
|
3787
|
-
const apy = await agent.getAgentApy(days, agentOptions);
|
|
4093
|
+
const apy = await this.readAgent(agent, "agentApy", () => agent.getAgentApy(days, agentOptions), { days, ...agentOptions });
|
|
3788
4094
|
return [id, apy];
|
|
3789
4095
|
})
|
|
3790
4096
|
);
|
|
@@ -3811,7 +4117,7 @@ var OwneySDK = class {
|
|
|
3811
4117
|
const entries = [...activeAgents.entries()];
|
|
3812
4118
|
const balanceResults = await Promise.allSettled(
|
|
3813
4119
|
entries.map(async ([id, agent]) => {
|
|
3814
|
-
const b = await agent.getBalances(state, chainId);
|
|
4120
|
+
const b = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
|
|
3815
4121
|
return [id, b.positions ?? []];
|
|
3816
4122
|
})
|
|
3817
4123
|
);
|
|
@@ -3819,6 +4125,7 @@ var OwneySDK = class {
|
|
|
3819
4125
|
const allPositions = [];
|
|
3820
4126
|
let successCount = 0;
|
|
3821
4127
|
const agentErrors = {};
|
|
4128
|
+
const agentFailures = [];
|
|
3822
4129
|
for (let i = 0; i < balanceResults.length; i++) {
|
|
3823
4130
|
const settled = balanceResults[i];
|
|
3824
4131
|
const [aid] = entries[i];
|
|
@@ -3833,6 +4140,7 @@ var OwneySDK = class {
|
|
|
3833
4140
|
successCount += 1;
|
|
3834
4141
|
} else {
|
|
3835
4142
|
const reason = settled.reason;
|
|
4143
|
+
agentFailures.push(reason);
|
|
3836
4144
|
agentErrors[aid] = reason instanceof Error ? reason.message : String(reason);
|
|
3837
4145
|
console.error(`getAllocationApy agent "${aid}" failed:`, reason);
|
|
3838
4146
|
}
|
|
@@ -3841,7 +4149,7 @@ var OwneySDK = class {
|
|
|
3841
4149
|
throw new OwneyError(
|
|
3842
4150
|
"ALLOCATION_ALL_FAILED",
|
|
3843
4151
|
"Failed to fetch allocation APY: all agents failed.",
|
|
3844
|
-
{ agentErrors }
|
|
4152
|
+
{ agentErrors, failures: agentFailures }
|
|
3845
4153
|
);
|
|
3846
4154
|
}
|
|
3847
4155
|
const overall = computeAllocationApy(allPositions);
|