@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.cjs
CHANGED
|
@@ -31,6 +31,168 @@ __export(index_exports, {
|
|
|
31
31
|
});
|
|
32
32
|
module.exports = __toCommonJS(index_exports);
|
|
33
33
|
|
|
34
|
+
// src/errors.ts
|
|
35
|
+
var OwneyError = class extends Error {
|
|
36
|
+
code;
|
|
37
|
+
details;
|
|
38
|
+
agentId;
|
|
39
|
+
constructor(code, message, details, agentId) {
|
|
40
|
+
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
41
|
+
super(`${prefix} ${message}`);
|
|
42
|
+
this.name = "OwneyError";
|
|
43
|
+
this.code = code;
|
|
44
|
+
this.details = details;
|
|
45
|
+
this.agentId = agentId;
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
var AgentNotFoundError = class extends OwneyError {
|
|
49
|
+
constructor(agentId, available) {
|
|
50
|
+
super(
|
|
51
|
+
"AGENT_NOT_FOUND",
|
|
52
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
53
|
+
{ agentId, available },
|
|
54
|
+
agentId
|
|
55
|
+
);
|
|
56
|
+
this.name = "AgentNotFoundError";
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
var NotConnectedError = class extends OwneyError {
|
|
60
|
+
constructor() {
|
|
61
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
62
|
+
this.name = "NotConnectedError";
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
var AgentChainIncompatibleError = class extends OwneyError {
|
|
66
|
+
incompatibleAgents;
|
|
67
|
+
connectedChainId;
|
|
68
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
69
|
+
const details = incompatibleAgents.map(
|
|
70
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
71
|
+
).join("; ");
|
|
72
|
+
super(
|
|
73
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
74
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
75
|
+
{ incompatibleAgents, connectedChainId }
|
|
76
|
+
);
|
|
77
|
+
this.name = "AgentChainIncompatibleError";
|
|
78
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
79
|
+
this.connectedChainId = connectedChainId;
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
// src/lib/rate-limit.ts
|
|
84
|
+
function rateLimitDelay(error, now = Date.now()) {
|
|
85
|
+
const seen = /* @__PURE__ */ new Set();
|
|
86
|
+
let limited = false;
|
|
87
|
+
let delay = 0;
|
|
88
|
+
function visit(value, depth = 0) {
|
|
89
|
+
if (depth > 6 || value == null) return;
|
|
90
|
+
if (typeof value === "string") {
|
|
91
|
+
if (/rate[ _-]?limit|too many requests|HTTP_429|\b429\b/i.test(value))
|
|
92
|
+
limited = true;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
if (typeof value !== "object" || seen.has(value)) return;
|
|
96
|
+
seen.add(value);
|
|
97
|
+
const record = value;
|
|
98
|
+
if ([record.status, record.statusCode, record.code].some(
|
|
99
|
+
(code) => String(code) === "429"
|
|
100
|
+
)) {
|
|
101
|
+
limited = true;
|
|
102
|
+
}
|
|
103
|
+
for (const key2 of ["retryAfterSeconds", "retryAfter"]) {
|
|
104
|
+
const seconds = Number(record[key2]);
|
|
105
|
+
if (Number.isFinite(seconds) && seconds > 0)
|
|
106
|
+
delay = Math.max(delay, seconds * 1e3);
|
|
107
|
+
}
|
|
108
|
+
const retryAt = Number(record.retryAt);
|
|
109
|
+
if (Number.isFinite(retryAt) && retryAt > now)
|
|
110
|
+
delay = Math.max(delay, retryAt - now);
|
|
111
|
+
const headers = record.headers;
|
|
112
|
+
const header = typeof headers?.get === "function" ? headers.get("Retry-After") : headers?.["retry-after"] ?? headers?.["Retry-After"];
|
|
113
|
+
if (typeof header === "string" || typeof header === "number") {
|
|
114
|
+
const seconds = Number(header);
|
|
115
|
+
const ms = Number.isFinite(seconds) ? seconds * 1e3 : Date.parse(String(header)) - now;
|
|
116
|
+
if (Number.isFinite(ms) && ms > 0) delay = Math.max(delay, ms);
|
|
117
|
+
}
|
|
118
|
+
for (const key2 of [
|
|
119
|
+
"message",
|
|
120
|
+
"code",
|
|
121
|
+
"cause",
|
|
122
|
+
"details",
|
|
123
|
+
"response",
|
|
124
|
+
"data",
|
|
125
|
+
"fields"
|
|
126
|
+
]) {
|
|
127
|
+
visit(record[key2], depth + 1);
|
|
128
|
+
}
|
|
129
|
+
for (const key2 of ["agentErrors", "failures"]) {
|
|
130
|
+
const entries = record[key2];
|
|
131
|
+
if (entries && typeof entries === "object") {
|
|
132
|
+
for (const entry of Object.values(entries)) visit(entry, depth + 1);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
visit(error);
|
|
137
|
+
return limited ? delay : void 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// src/lib/agent-reads.ts
|
|
141
|
+
var AgentReads = class {
|
|
142
|
+
inFlight = /* @__PURE__ */ new Map();
|
|
143
|
+
cooldowns = /* @__PURE__ */ new Map();
|
|
144
|
+
// A reconnect must not reuse work started by the previous connection.
|
|
145
|
+
clearInFlight() {
|
|
146
|
+
this.inFlight.clear();
|
|
147
|
+
}
|
|
148
|
+
limited(agentId, until) {
|
|
149
|
+
return new OwneyError(
|
|
150
|
+
"AGENT_RATE_LIMITED",
|
|
151
|
+
"Too many requests. Please wait before trying again.",
|
|
152
|
+
{
|
|
153
|
+
statusCode: 429,
|
|
154
|
+
retryAt: until,
|
|
155
|
+
retryAfterSeconds: Math.max(0, Math.ceil((until - Date.now()) / 1e3))
|
|
156
|
+
},
|
|
157
|
+
agentId
|
|
158
|
+
);
|
|
159
|
+
}
|
|
160
|
+
run(agentId, key2, fetch2) {
|
|
161
|
+
const cooldown = this.cooldowns.get(agentId);
|
|
162
|
+
if (cooldown && cooldown.until > Date.now()) {
|
|
163
|
+
return Promise.reject(this.limited(agentId, cooldown.until));
|
|
164
|
+
}
|
|
165
|
+
const requestKey = JSON.stringify([agentId, key2]);
|
|
166
|
+
const existing = this.inFlight.get(requestKey);
|
|
167
|
+
if (existing) return existing;
|
|
168
|
+
const promise = Promise.resolve().then(fetch2).then(
|
|
169
|
+
(value) => {
|
|
170
|
+
if (this.cooldowns.get(agentId) === cooldown)
|
|
171
|
+
this.cooldowns.delete(agentId);
|
|
172
|
+
return value;
|
|
173
|
+
},
|
|
174
|
+
(error) => {
|
|
175
|
+
const requestedDelay = rateLimitDelay(error);
|
|
176
|
+
if (requestedDelay === void 0) throw error;
|
|
177
|
+
const previous = this.cooldowns.get(agentId);
|
|
178
|
+
const failures = previous && previous.until > Date.now() ? previous.failures : Math.min((previous?.failures ?? 0) + 1, 5);
|
|
179
|
+
const delay = Math.max(
|
|
180
|
+
requestedDelay,
|
|
181
|
+
Math.min(3e4 * 2 ** (failures - 1), 3e5)
|
|
182
|
+
);
|
|
183
|
+
const until = Math.max(previous?.until ?? 0, Date.now() + delay);
|
|
184
|
+
this.cooldowns.set(agentId, { until, failures });
|
|
185
|
+
throw this.limited(agentId, until);
|
|
186
|
+
}
|
|
187
|
+
).finally(() => {
|
|
188
|
+
if (this.inFlight.get(requestKey) === promise)
|
|
189
|
+
this.inFlight.delete(requestKey);
|
|
190
|
+
});
|
|
191
|
+
this.inFlight.set(requestKey, promise);
|
|
192
|
+
return promise;
|
|
193
|
+
}
|
|
194
|
+
};
|
|
195
|
+
|
|
34
196
|
// src/agents/zyfai/zyfai.agent.ts
|
|
35
197
|
var import_sdk = require("@zyfai/sdk");
|
|
36
198
|
var import_viem = require("viem");
|
|
@@ -100,55 +262,6 @@ function debugLog(scope, message, data) {
|
|
|
100
262
|
}
|
|
101
263
|
}
|
|
102
264
|
|
|
103
|
-
// src/errors.ts
|
|
104
|
-
var OwneyError = class extends Error {
|
|
105
|
-
code;
|
|
106
|
-
details;
|
|
107
|
-
agentId;
|
|
108
|
-
constructor(code, message, details, agentId) {
|
|
109
|
-
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
110
|
-
super(`${prefix} ${message}`);
|
|
111
|
-
this.name = "OwneyError";
|
|
112
|
-
this.code = code;
|
|
113
|
-
this.details = details;
|
|
114
|
-
this.agentId = agentId;
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
var AgentNotFoundError = class extends OwneyError {
|
|
118
|
-
constructor(agentId, available) {
|
|
119
|
-
super(
|
|
120
|
-
"AGENT_NOT_FOUND",
|
|
121
|
-
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
122
|
-
{ agentId, available },
|
|
123
|
-
agentId
|
|
124
|
-
);
|
|
125
|
-
this.name = "AgentNotFoundError";
|
|
126
|
-
}
|
|
127
|
-
};
|
|
128
|
-
var NotConnectedError = class extends OwneyError {
|
|
129
|
-
constructor() {
|
|
130
|
-
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
131
|
-
this.name = "NotConnectedError";
|
|
132
|
-
}
|
|
133
|
-
};
|
|
134
|
-
var AgentChainIncompatibleError = class extends OwneyError {
|
|
135
|
-
incompatibleAgents;
|
|
136
|
-
connectedChainId;
|
|
137
|
-
constructor(incompatibleAgents, connectedChainId) {
|
|
138
|
-
const details = incompatibleAgents.map(
|
|
139
|
-
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
140
|
-
).join("; ");
|
|
141
|
-
super(
|
|
142
|
-
"AGENT_CHAIN_INCOMPATIBLE",
|
|
143
|
-
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
144
|
-
{ incompatibleAgents, connectedChainId }
|
|
145
|
-
);
|
|
146
|
-
this.name = "AgentChainIncompatibleError";
|
|
147
|
-
this.incompatibleAgents = incompatibleAgents;
|
|
148
|
-
this.connectedChainId = connectedChainId;
|
|
149
|
-
}
|
|
150
|
-
};
|
|
151
|
-
|
|
152
265
|
// src/lib/utils.ts
|
|
153
266
|
var isValidChainId = (chainId) => {
|
|
154
267
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
@@ -952,7 +1065,10 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
952
1065
|
// successful decode is cached forever; failures are NOT cached so a transient
|
|
953
1066
|
// RPC error retries on the next fetch.
|
|
954
1067
|
withdrawAmountCache = /* @__PURE__ */ new Map();
|
|
955
|
-
|
|
1068
|
+
earningsReads = /* @__PURE__ */ new Map();
|
|
1069
|
+
earningsRefreshes = /* @__PURE__ */ new Map();
|
|
1070
|
+
earningsSnapshot = null;
|
|
1071
|
+
earningsGeneration = 0;
|
|
956
1072
|
constructor(apiKey, rpcUrls, referralSource) {
|
|
957
1073
|
this.rpcUrls = rpcUrls ?? DEFAULT_ZYFAI_RPC_URLS;
|
|
958
1074
|
this.sdk = new import_sdk.ZyfaiSDK({
|
|
@@ -1197,6 +1313,10 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1197
1313
|
}
|
|
1198
1314
|
// --- IAgent: Connection lifecycle ---
|
|
1199
1315
|
async disconnect() {
|
|
1316
|
+
this.earningsGeneration++;
|
|
1317
|
+
this.earningsReads.clear();
|
|
1318
|
+
this.earningsRefreshes.clear();
|
|
1319
|
+
this.earningsSnapshot = null;
|
|
1200
1320
|
if (this.connectedAddress && this.connectedChainId !== null) {
|
|
1201
1321
|
clearSession(this.connectedAddress, this.connectedChainId);
|
|
1202
1322
|
}
|
|
@@ -1745,26 +1865,59 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1745
1865
|
const raw = await this.sdk.getPortfolio(this.getAddress());
|
|
1746
1866
|
return mapBalances(raw, validChainId, smartWallet);
|
|
1747
1867
|
}
|
|
1868
|
+
earningsKey(state, chainId, smartWallet) {
|
|
1869
|
+
return JSON.stringify([
|
|
1870
|
+
state.walletAddress?.toLowerCase(),
|
|
1871
|
+
chainId,
|
|
1872
|
+
smartWallet.toLowerCase()
|
|
1873
|
+
]);
|
|
1874
|
+
}
|
|
1875
|
+
readEarnings(key2, smartWallet) {
|
|
1876
|
+
const existing = this.earningsReads.get(key2);
|
|
1877
|
+
if (existing) return existing;
|
|
1878
|
+
const generation = this.earningsGeneration;
|
|
1879
|
+
const pending = Promise.resolve().then(() => this.sdk.getOnchainEarnings(smartWallet)).then((raw) => {
|
|
1880
|
+
if (generation === this.earningsGeneration) {
|
|
1881
|
+
this.earningsSnapshot = { key: key2, raw, at: Date.now() };
|
|
1882
|
+
}
|
|
1883
|
+
return raw;
|
|
1884
|
+
}).finally(() => {
|
|
1885
|
+
if (this.earningsReads.get(key2) === pending)
|
|
1886
|
+
this.earningsReads.delete(key2);
|
|
1887
|
+
});
|
|
1888
|
+
this.earningsReads.set(key2, pending);
|
|
1889
|
+
return pending;
|
|
1890
|
+
}
|
|
1748
1891
|
async getEarnings(state, chainId) {
|
|
1749
1892
|
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
1750
|
-
const raw = await this.
|
|
1893
|
+
const raw = await this.readEarnings(
|
|
1894
|
+
this.earningsKey(state, chainId, smartWallet),
|
|
1895
|
+
smartWallet
|
|
1896
|
+
);
|
|
1751
1897
|
return mapEarnings(raw, smartWallet);
|
|
1752
1898
|
}
|
|
1753
1899
|
async refreshEarnings(state, chainId) {
|
|
1754
|
-
|
|
1755
|
-
|
|
1756
|
-
|
|
1757
|
-
|
|
1900
|
+
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
1901
|
+
const key2 = this.earningsKey(state, chainId, smartWallet);
|
|
1902
|
+
const existing = this.earningsRefreshes.get(key2);
|
|
1903
|
+
if (existing) return existing;
|
|
1904
|
+
const generation = this.earningsGeneration;
|
|
1905
|
+
const pending = (async () => {
|
|
1906
|
+
const recent = this.earningsSnapshot;
|
|
1907
|
+
const current = recent?.key === key2 && Date.now() - recent.at < 5e3 ? recent.raw : await this.readEarnings(key2, smartWallet);
|
|
1758
1908
|
const lastCheck = current.data.lastCheckTimestamp ? Date.parse(current.data.lastCheckTimestamp) : Number.NaN;
|
|
1759
1909
|
const isFresh = Number.isFinite(lastCheck) && Date.now() - lastCheck < EARNINGS_REFRESH_COOLDOWN_MS;
|
|
1760
1910
|
const earnings = isFresh ? current : await this.sdk.calculateOnchainEarnings(smartWallet);
|
|
1911
|
+
if (!isFresh && generation === this.earningsGeneration) {
|
|
1912
|
+
this.earningsSnapshot = { key: key2, raw: earnings, at: Date.now() };
|
|
1913
|
+
}
|
|
1761
1914
|
return mapEarnings(earnings, smartWallet);
|
|
1762
|
-
})()
|
|
1763
|
-
|
|
1764
|
-
|
|
1765
|
-
}
|
|
1766
|
-
|
|
1767
|
-
|
|
1915
|
+
})().finally(() => {
|
|
1916
|
+
if (this.earningsRefreshes.get(key2) === pending)
|
|
1917
|
+
this.earningsRefreshes.delete(key2);
|
|
1918
|
+
});
|
|
1919
|
+
this.earningsRefreshes.set(key2, pending);
|
|
1920
|
+
return pending;
|
|
1768
1921
|
}
|
|
1769
1922
|
async getAccountApy(state, chainId, days, tokenSymbol) {
|
|
1770
1923
|
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
@@ -2682,6 +2835,17 @@ var OwneySDK = class {
|
|
|
2682
2835
|
cachedWethSponsoredCallback = null;
|
|
2683
2836
|
paymasterServiceUrl;
|
|
2684
2837
|
cachedSponsoredCallsCallbacks = /* @__PURE__ */ new Map();
|
|
2838
|
+
agentReads = new AgentReads();
|
|
2839
|
+
activationChecks = /* @__PURE__ */ new Map();
|
|
2840
|
+
readAgent(agent, method, fetch2, params = null) {
|
|
2841
|
+
const key2 = JSON.stringify([
|
|
2842
|
+
this.state?.walletAddress.toLowerCase() ?? null,
|
|
2843
|
+
this.state?.chainId ?? null,
|
|
2844
|
+
method,
|
|
2845
|
+
params
|
|
2846
|
+
]);
|
|
2847
|
+
return this.agentReads.run(agent.id, key2, fetch2);
|
|
2848
|
+
}
|
|
2685
2849
|
initializingAgentsPromise = null;
|
|
2686
2850
|
constructor(config) {
|
|
2687
2851
|
this.apiKey = config.apiKey;
|
|
@@ -2708,6 +2872,8 @@ var OwneySDK = class {
|
|
|
2708
2872
|
"No accounts found. Ensure the wallet is unlocked and connected."
|
|
2709
2873
|
);
|
|
2710
2874
|
}
|
|
2875
|
+
this.agentReads.clearInFlight();
|
|
2876
|
+
this.activationChecks.clear();
|
|
2711
2877
|
this.state = { provider, walletAddress, chainId: null };
|
|
2712
2878
|
this.cachedSponsoredCallback = null;
|
|
2713
2879
|
this.cachedWethSponsoredCallback = null;
|
|
@@ -2723,6 +2889,8 @@ var OwneySDK = class {
|
|
|
2723
2889
|
}
|
|
2724
2890
|
this.activeAgents.clear();
|
|
2725
2891
|
this.disabledAgents.clear();
|
|
2892
|
+
this.agentReads.clearInFlight();
|
|
2893
|
+
this.activationChecks.clear();
|
|
2726
2894
|
this.state = null;
|
|
2727
2895
|
this.cachedSponsoredCallback = null;
|
|
2728
2896
|
this.cachedWethSponsoredCallback = null;
|
|
@@ -2953,6 +3121,37 @@ var OwneySDK = class {
|
|
|
2953
3121
|
}
|
|
2954
3122
|
return null;
|
|
2955
3123
|
}
|
|
3124
|
+
/**
|
|
3125
|
+
* Discover the agents actually returned by routing for this organization.
|
|
3126
|
+
* Consumers should use this instead of hardcoding a global agent roster.
|
|
3127
|
+
*/
|
|
3128
|
+
async getAvailableAgents(options = {}) {
|
|
3129
|
+
await this.ensureAgentsInitialized();
|
|
3130
|
+
const { chainId, asset, includeDisabled = false } = options;
|
|
3131
|
+
const available = [];
|
|
3132
|
+
for (const [id, agent] of this.agents) {
|
|
3133
|
+
const isEnabled = !this.isAgentDisabled(id);
|
|
3134
|
+
if (!includeDisabled && !isEnabled) continue;
|
|
3135
|
+
if (chainId !== void 0 && !agent.supportedChainIds.includes(chainId)) {
|
|
3136
|
+
continue;
|
|
3137
|
+
}
|
|
3138
|
+
if (asset !== void 0) {
|
|
3139
|
+
const supportsAsset = agent.supportedAssets.some(
|
|
3140
|
+
(entry) => (chainId === void 0 || entry.chainId === chainId) && entry.assets.some((candidate) => candidate.symbol === asset)
|
|
3141
|
+
);
|
|
3142
|
+
if (!supportsAsset) {
|
|
3143
|
+
continue;
|
|
3144
|
+
}
|
|
3145
|
+
}
|
|
3146
|
+
available.push({
|
|
3147
|
+
id,
|
|
3148
|
+
isEnabled,
|
|
3149
|
+
supportedChainIds: agent.supportedChainIds,
|
|
3150
|
+
supportedAssets: agent.supportedAssets
|
|
3151
|
+
});
|
|
3152
|
+
}
|
|
3153
|
+
return available;
|
|
3154
|
+
}
|
|
2956
3155
|
// --- Account lifecycle ---
|
|
2957
3156
|
/**
|
|
2958
3157
|
* Activate the user's smart wallet for the specified agents, or all chain-compatible agents if omitted.
|
|
@@ -3000,9 +3199,7 @@ var OwneySDK = class {
|
|
|
3000
3199
|
this.activeAgents.add(id);
|
|
3001
3200
|
}
|
|
3002
3201
|
state.chainId = chainId;
|
|
3003
|
-
this.activateAgentsInTurn(agents, state, chainId)
|
|
3004
|
-
console.error("activateAgent background init failed:", error);
|
|
3005
|
-
});
|
|
3202
|
+
await this.activateAgentsInTurn(agents, state, chainId);
|
|
3006
3203
|
return;
|
|
3007
3204
|
}
|
|
3008
3205
|
const compatible = [...this.agents.values()].filter(
|
|
@@ -3023,11 +3220,7 @@ var OwneySDK = class {
|
|
|
3023
3220
|
const enabledCompatible = compatible.filter(
|
|
3024
3221
|
(agent) => !this.isAgentDisabled(agent.id)
|
|
3025
3222
|
);
|
|
3026
|
-
this.activateAgentsInTurn(enabledCompatible, state, chainId)
|
|
3027
|
-
(error) => {
|
|
3028
|
-
console.error("activateAgent background init failed:", error);
|
|
3029
|
-
}
|
|
3030
|
-
);
|
|
3223
|
+
await this.activateAgentsInTurn(enabledCompatible, state, chainId);
|
|
3031
3224
|
}
|
|
3032
3225
|
/**
|
|
3033
3226
|
* Activate agents ONE AT A TIME, each followed by its org policy.
|
|
@@ -3064,7 +3257,7 @@ var OwneySDK = class {
|
|
|
3064
3257
|
if (firstError !== null) throw firstError;
|
|
3065
3258
|
}
|
|
3066
3259
|
/**
|
|
3067
|
-
* Deposit
|
|
3260
|
+
* Deposit into a specific agent, or distribute across all eligible agents.
|
|
3068
3261
|
* Validates that the asset is supported and amount meets minimums for the target agent(s).
|
|
3069
3262
|
* @param options - Deposit parameters
|
|
3070
3263
|
* @param options.amount - Amount to deposit in smallest unit (e.g. "100000000" for 100 USDC)
|
|
@@ -3072,7 +3265,8 @@ var OwneySDK = class {
|
|
|
3072
3265
|
* @param options.depositCallback - Callback that performs the token transfer and returns a tx hash.
|
|
3073
3266
|
* When agentId is omitted, this callback is invoked once per eligible agent with that agent's
|
|
3074
3267
|
* split amount and smart wallet address — expect multiple wallet prompts.
|
|
3075
|
-
* @param options.agentId - Optional
|
|
3268
|
+
* @param options.agentId - Optional explicit target. Otherwise split equally,
|
|
3269
|
+
* or fund remaining agents when a recovery deposit cannot meet every minimum.
|
|
3076
3270
|
* @returns {OwneyDepositResult} for a single agent, or {OwneyMultiDepositResult} with per-agent results
|
|
3077
3271
|
*/
|
|
3078
3272
|
async deposit(options) {
|
|
@@ -3110,7 +3304,7 @@ var OwneySDK = class {
|
|
|
3110
3304
|
});
|
|
3111
3305
|
const exemptFlags = await Promise.all(
|
|
3112
3306
|
eligibleAgents.map(
|
|
3113
|
-
(a) => this.hasExistingBalance(a, state, chainId, asset)
|
|
3307
|
+
(a) => this.hasExistingBalance(a, state, chainId, asset, true)
|
|
3114
3308
|
)
|
|
3115
3309
|
);
|
|
3116
3310
|
const exempt = new Set(
|
|
@@ -3124,23 +3318,67 @@ var OwneySDK = class {
|
|
|
3124
3318
|
exempt
|
|
3125
3319
|
);
|
|
3126
3320
|
if (agentAmounts.length === 0) {
|
|
3321
|
+
const agentsRequiringActivation = eligibleAgents.filter(
|
|
3322
|
+
(agent) => !exempt.has(agent.id)
|
|
3323
|
+
);
|
|
3324
|
+
const perAgentMinimum = agentsRequiringActivation.reduce(
|
|
3325
|
+
(highest, agent) => {
|
|
3326
|
+
const minimum = this.getMinDepositAmount(agent, chainId, asset);
|
|
3327
|
+
return minimum > highest ? minimum : highest;
|
|
3328
|
+
},
|
|
3329
|
+
0n
|
|
3330
|
+
);
|
|
3331
|
+
const minimumRequired = agentsRequiringActivation.length > 0 ? (perAgentMinimum > 0n ? perAgentMinimum : 1n) * BigInt(agentsRequiringActivation.length) : BigInt(eligibleAgents.length);
|
|
3127
3332
|
throw new OwneyError(
|
|
3128
3333
|
"DEPOSIT_AMOUNT_BELOW_MINIMUM",
|
|
3129
|
-
`Amount "${amount}" cannot
|
|
3130
|
-
{
|
|
3334
|
+
`Amount "${amount}" cannot activate every eligible agent. The combined minimum is "${minimumRequired.toString()}" for ${asset}.`,
|
|
3335
|
+
{
|
|
3336
|
+
amount,
|
|
3337
|
+
asset,
|
|
3338
|
+
chainId,
|
|
3339
|
+
minDepositAmount: minimumRequired.toString(),
|
|
3340
|
+
perAgentDepositAmount: perAgentMinimum.toString(),
|
|
3341
|
+
agentMinimums: agentsRequiringActivation.map((agent) => ({
|
|
3342
|
+
agentId: agent.id,
|
|
3343
|
+
minDepositAmount: this.getMinDepositAmount(
|
|
3344
|
+
agent,
|
|
3345
|
+
chainId,
|
|
3346
|
+
asset
|
|
3347
|
+
).toString()
|
|
3348
|
+
}))
|
|
3349
|
+
}
|
|
3131
3350
|
);
|
|
3132
3351
|
}
|
|
3133
3352
|
const agentResults = {};
|
|
3134
|
-
for (const
|
|
3135
|
-
|
|
3136
|
-
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
|
|
3141
|
-
|
|
3142
|
-
|
|
3143
|
-
|
|
3353
|
+
for (const [
|
|
3354
|
+
index,
|
|
3355
|
+
{ agent, amount: agentAmount }
|
|
3356
|
+
] of agentAmounts.entries()) {
|
|
3357
|
+
try {
|
|
3358
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
3359
|
+
agent,
|
|
3360
|
+
state,
|
|
3361
|
+
chainId,
|
|
3362
|
+
agentAmount,
|
|
3363
|
+
asset,
|
|
3364
|
+
effectiveCallback,
|
|
3365
|
+
depositCallback
|
|
3366
|
+
);
|
|
3367
|
+
} catch (error) {
|
|
3368
|
+
if (Object.keys(agentResults).length === 0) throw error;
|
|
3369
|
+
throw new OwneyError(
|
|
3370
|
+
"DEPOSIT_PARTIAL_FAILURE",
|
|
3371
|
+
"Some deposits completed before another agent failed. Check activity and balances before depositing again; the failed transfer may still settle.",
|
|
3372
|
+
{
|
|
3373
|
+
agentResults,
|
|
3374
|
+
failedAgentId: agent.id,
|
|
3375
|
+
failedAmount: agentAmount,
|
|
3376
|
+
unattemptedAgentIds: agentAmounts.slice(index + 1).map(({ agent: agent2 }) => agent2.id),
|
|
3377
|
+
cause: error
|
|
3378
|
+
},
|
|
3379
|
+
agent.id
|
|
3380
|
+
);
|
|
3381
|
+
}
|
|
3144
3382
|
}
|
|
3145
3383
|
return { agentResults };
|
|
3146
3384
|
}
|
|
@@ -3213,6 +3451,17 @@ var OwneySDK = class {
|
|
|
3213
3451
|
}
|
|
3214
3452
|
splitDepositAmount(totalAmount, agents, chainId, asset, exempt = /* @__PURE__ */ new Set()) {
|
|
3215
3453
|
if (agents.length === 0) return [];
|
|
3454
|
+
const agentsRequiringActivation = agents.filter(
|
|
3455
|
+
(agent) => !exempt.has(agent.id)
|
|
3456
|
+
);
|
|
3457
|
+
if (agentsRequiringActivation.length === agents.length) {
|
|
3458
|
+
const highestMinimum2 = agents.reduce((highest, agent) => {
|
|
3459
|
+
const minimum = this.getMinDepositAmount(agent, chainId, asset);
|
|
3460
|
+
return minimum > highest ? minimum : highest;
|
|
3461
|
+
}, 0n);
|
|
3462
|
+
const minimumRequired2 = (highestMinimum2 > 0n ? highestMinimum2 : 1n) * BigInt(agents.length);
|
|
3463
|
+
if (totalAmount < minimumRequired2) return [];
|
|
3464
|
+
}
|
|
3216
3465
|
const perAgent = totalAmount / BigInt(agents.length);
|
|
3217
3466
|
const remainder = totalAmount % BigInt(agents.length);
|
|
3218
3467
|
const splits = agents.map((agent, i) => ({
|
|
@@ -3220,18 +3469,26 @@ var OwneySDK = class {
|
|
|
3220
3469
|
amount: i === agents.length - 1 ? perAgent + remainder : perAgent
|
|
3221
3470
|
}));
|
|
3222
3471
|
const valid = splits.filter(
|
|
3223
|
-
(s) => exempt.has(s.agent.id) || s.amount >= this.getMinDepositAmount(s.agent, chainId, asset)
|
|
3472
|
+
(s) => s.amount > 0n && (exempt.has(s.agent.id) || s.amount >= this.getMinDepositAmount(s.agent, chainId, asset))
|
|
3224
3473
|
);
|
|
3225
3474
|
if (valid.length === agents.length) {
|
|
3226
3475
|
return splits.map((s) => ({ agent: s.agent, amount: String(s.amount) }));
|
|
3227
3476
|
}
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
);
|
|
3477
|
+
const targets = agentsRequiringActivation.length > 0 ? agentsRequiringActivation : agents;
|
|
3478
|
+
const highestMinimum = targets.reduce((highest, agent) => {
|
|
3479
|
+
const minimum = this.getMinDepositAmount(agent, chainId, asset);
|
|
3480
|
+
return minimum > highest ? minimum : highest;
|
|
3481
|
+
}, 0n);
|
|
3482
|
+
const minimumRequired = (highestMinimum > 0n ? highestMinimum : 1n) * BigInt(targets.length);
|
|
3483
|
+
if (totalAmount < minimumRequired) return [];
|
|
3484
|
+
const targetShare = totalAmount / BigInt(targets.length);
|
|
3485
|
+
const targetRemainder = totalAmount % BigInt(targets.length);
|
|
3486
|
+
return targets.map((agent, index) => ({
|
|
3487
|
+
agent,
|
|
3488
|
+
amount: String(
|
|
3489
|
+
targetShare + (index === targets.length - 1 ? targetRemainder : 0n)
|
|
3490
|
+
)
|
|
3491
|
+
}));
|
|
3235
3492
|
}
|
|
3236
3493
|
async validateMinDepositAmount(agent, state, chainId, asset, amount) {
|
|
3237
3494
|
const minDepositAmount = this.getMinDepositAmount(agent, chainId, asset);
|
|
@@ -3256,15 +3513,29 @@ var OwneySDK = class {
|
|
|
3256
3513
|
* per-agent minimum. Fails closed: any error reading balances returns
|
|
3257
3514
|
* false, so the minimum is enforced as today.
|
|
3258
3515
|
*/
|
|
3259
|
-
async hasExistingBalance(agent, state, chainId, asset) {
|
|
3516
|
+
async hasExistingBalance(agent, state, chainId, asset, requireReliableRead = false) {
|
|
3260
3517
|
try {
|
|
3261
3518
|
const balance = await agent.getBalances(state, chainId);
|
|
3262
3519
|
const target = asset.toLowerCase();
|
|
3263
3520
|
const token = balance.tokens.find(
|
|
3264
3521
|
(t) => t.chainId === chainId && t.asset.toLowerCase() === target
|
|
3265
3522
|
);
|
|
3266
|
-
|
|
3267
|
-
|
|
3523
|
+
const targetChainName = agent.supportedAssets.find((entry) => entry.chainId === chainId)?.chain?.trim().toUpperCase();
|
|
3524
|
+
const position = (balance.positions ?? []).find((p) => {
|
|
3525
|
+
const positionChain = p.chain.trim().toUpperCase();
|
|
3526
|
+
const matchesChain = positionChain === String(chainId) || targetChainName !== void 0 && positionChain === targetChainName;
|
|
3527
|
+
return matchesChain && p.asset.toLowerCase() === target && Number(p.amount) > 0;
|
|
3528
|
+
});
|
|
3529
|
+
return !!token && Number(token.amount) > 0 || !!position;
|
|
3530
|
+
} catch (error) {
|
|
3531
|
+
if (requireReliableRead) {
|
|
3532
|
+
throw new OwneyError(
|
|
3533
|
+
"DEPOSIT_BALANCE_UNAVAILABLE",
|
|
3534
|
+
"Could not verify every agent balance. No deposit was submitted. Try again once balances are available.",
|
|
3535
|
+
{ agentId: agent.id, chainId, asset, cause: error },
|
|
3536
|
+
agent.id
|
|
3537
|
+
);
|
|
3538
|
+
}
|
|
3268
3539
|
return false;
|
|
3269
3540
|
}
|
|
3270
3541
|
}
|
|
@@ -3360,9 +3631,12 @@ var OwneySDK = class {
|
|
|
3360
3631
|
{ asset, agentErrors: agentErrors2 }
|
|
3361
3632
|
);
|
|
3362
3633
|
}
|
|
3634
|
+
const amountsKnown = Object.values(results2).every(
|
|
3635
|
+
(result) => typeof result.amount === "string" && /^\d+$/.test(result.amount)
|
|
3636
|
+
);
|
|
3363
3637
|
return {
|
|
3364
3638
|
agentResult: results2,
|
|
3365
|
-
totalWithdrawn: sumWithdrawnAmount(results2).toString()
|
|
3639
|
+
totalWithdrawn: amountsKnown ? sumWithdrawnAmount(results2).toString() : null
|
|
3366
3640
|
};
|
|
3367
3641
|
}
|
|
3368
3642
|
const requested = BigInt(amount);
|
|
@@ -3467,7 +3741,8 @@ var OwneySDK = class {
|
|
|
3467
3741
|
const state = this.requireState();
|
|
3468
3742
|
const chainId = this.requireChainId();
|
|
3469
3743
|
if (agentId) {
|
|
3470
|
-
const
|
|
3744
|
+
const agent = this.getAgent(agentId);
|
|
3745
|
+
const result = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
|
|
3471
3746
|
return result;
|
|
3472
3747
|
}
|
|
3473
3748
|
let totalBalance = 0;
|
|
@@ -3475,12 +3750,14 @@ var OwneySDK = class {
|
|
|
3475
3750
|
const entries = [...this.getActiveAgents().entries()];
|
|
3476
3751
|
const balanceResults = await Promise.allSettled(
|
|
3477
3752
|
entries.map(async ([id, agent]) => {
|
|
3478
|
-
const b = await agent.getBalances(state, chainId);
|
|
3753
|
+
const b = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
|
|
3479
3754
|
return [id, b];
|
|
3480
3755
|
})
|
|
3481
3756
|
);
|
|
3482
3757
|
let successCount = 0;
|
|
3483
3758
|
const agentErrors = {};
|
|
3759
|
+
const agentRetryAt = {};
|
|
3760
|
+
const agentFailures = [];
|
|
3484
3761
|
for (let i = 0; i < balanceResults.length; i++) {
|
|
3485
3762
|
const settledResult = balanceResults[i];
|
|
3486
3763
|
const [agentId2] = entries[i];
|
|
@@ -3492,19 +3769,23 @@ var OwneySDK = class {
|
|
|
3492
3769
|
continue;
|
|
3493
3770
|
}
|
|
3494
3771
|
const reason = settledResult.reason;
|
|
3772
|
+
agentFailures.push(reason);
|
|
3773
|
+
const retryDelay = rateLimitDelay(reason);
|
|
3774
|
+
if (retryDelay !== void 0) agentRetryAt[agentId2] = Date.now() + retryDelay;
|
|
3495
3775
|
agentErrors[agentId2] = reason instanceof Error ? reason.message : String(reason);
|
|
3496
3776
|
}
|
|
3497
3777
|
if (successCount === 0) {
|
|
3498
3778
|
throw new OwneyError(
|
|
3499
3779
|
"BALANCE_ALL_FAILED",
|
|
3500
3780
|
"Failed to fetch balances for all active agents.",
|
|
3501
|
-
{ agentErrors }
|
|
3781
|
+
{ agentErrors, failures: agentFailures }
|
|
3502
3782
|
);
|
|
3503
3783
|
}
|
|
3504
3784
|
return {
|
|
3505
3785
|
totalBalance: String(totalBalance),
|
|
3506
3786
|
totalBalanceAsset: "usdc",
|
|
3507
|
-
agentBalances: results
|
|
3787
|
+
agentBalances: results,
|
|
3788
|
+
...Object.keys(agentErrors).length > 0 ? { agentErrors, agentRetryAt } : {}
|
|
3508
3789
|
};
|
|
3509
3790
|
}
|
|
3510
3791
|
/**
|
|
@@ -3516,14 +3797,15 @@ var OwneySDK = class {
|
|
|
3516
3797
|
const state = this.requireState();
|
|
3517
3798
|
const chainId = this.requireChainId();
|
|
3518
3799
|
if (agentId) {
|
|
3519
|
-
|
|
3800
|
+
const agent = this.getAgent(agentId);
|
|
3801
|
+
return this.readAgent(agent, "earnings", () => agent.getEarnings(state, chainId));
|
|
3520
3802
|
}
|
|
3521
3803
|
let totalEarnings = 0;
|
|
3522
3804
|
const results = {};
|
|
3523
3805
|
const entries = [...this.getActiveAgents().entries()];
|
|
3524
3806
|
const earningsResults = await Promise.all(
|
|
3525
3807
|
entries.map(async ([id, agent]) => {
|
|
3526
|
-
const e = await agent.getEarnings(state, chainId);
|
|
3808
|
+
const e = await this.readAgent(agent, "earnings", () => agent.getEarnings(state, chainId));
|
|
3527
3809
|
return [id, e];
|
|
3528
3810
|
})
|
|
3529
3811
|
);
|
|
@@ -3543,7 +3825,11 @@ var OwneySDK = class {
|
|
|
3543
3825
|
async refreshEarnings(agentId) {
|
|
3544
3826
|
const state = this.requireState();
|
|
3545
3827
|
const chainId = this.requireChainId();
|
|
3546
|
-
const refreshAgent = (agent) =>
|
|
3828
|
+
const refreshAgent = (agent) => this.readAgent(
|
|
3829
|
+
agent,
|
|
3830
|
+
agent.refreshEarnings ? "refreshEarnings" : "earnings",
|
|
3831
|
+
() => agent.refreshEarnings?.(state, chainId) ?? agent.getEarnings(state, chainId)
|
|
3832
|
+
);
|
|
3547
3833
|
if (agentId) return refreshAgent(this.getAgent(agentId));
|
|
3548
3834
|
let totalEarnings = 0;
|
|
3549
3835
|
const agentEarnings = {};
|
|
@@ -3574,11 +3860,12 @@ var OwneySDK = class {
|
|
|
3574
3860
|
const state = this.requireState();
|
|
3575
3861
|
const chainId = this.requireChainId();
|
|
3576
3862
|
if (agentId) {
|
|
3577
|
-
|
|
3578
|
-
|
|
3579
|
-
|
|
3580
|
-
|
|
3581
|
-
tokenSymbol
|
|
3863
|
+
const agent = this.getAgent(agentId);
|
|
3864
|
+
return this.readAgent(
|
|
3865
|
+
agent,
|
|
3866
|
+
"accountApy",
|
|
3867
|
+
() => agent.getAccountApy(state, chainId, days, tokenSymbol),
|
|
3868
|
+
{ days, tokenSymbol }
|
|
3582
3869
|
);
|
|
3583
3870
|
}
|
|
3584
3871
|
const activeAgents = this.getActiveAgents();
|
|
@@ -3586,18 +3873,18 @@ var OwneySDK = class {
|
|
|
3586
3873
|
const [apyResults, balanceResults] = await Promise.all([
|
|
3587
3874
|
Promise.all(
|
|
3588
3875
|
entries.map(async ([id, agent]) => {
|
|
3589
|
-
const apy = await
|
|
3590
|
-
|
|
3591
|
-
|
|
3592
|
-
days,
|
|
3593
|
-
tokenSymbol
|
|
3876
|
+
const apy = await this.readAgent(
|
|
3877
|
+
agent,
|
|
3878
|
+
"accountApy",
|
|
3879
|
+
() => agent.getAccountApy(state, chainId, days, tokenSymbol),
|
|
3880
|
+
{ days, tokenSymbol }
|
|
3594
3881
|
);
|
|
3595
3882
|
return [id, apy];
|
|
3596
3883
|
})
|
|
3597
3884
|
),
|
|
3598
3885
|
Promise.all(
|
|
3599
3886
|
entries.map(async ([id, agent]) => {
|
|
3600
|
-
const b = await agent.getBalances(state, chainId);
|
|
3887
|
+
const b = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
|
|
3601
3888
|
return [id, Number(b.totalBalance)];
|
|
3602
3889
|
})
|
|
3603
3890
|
)
|
|
@@ -3654,7 +3941,8 @@ var OwneySDK = class {
|
|
|
3654
3941
|
const chainId = this.requireChainId();
|
|
3655
3942
|
const { agentId, filters } = options ?? {};
|
|
3656
3943
|
if (agentId) {
|
|
3657
|
-
|
|
3944
|
+
const agent = this.getAgent(agentId);
|
|
3945
|
+
return this.readAgent(agent, "history", () => agent.getHistory(state, chainId, filters), filters);
|
|
3658
3946
|
}
|
|
3659
3947
|
const activeAgents = [...this.getActiveAgents().values()];
|
|
3660
3948
|
const cursorMap = filters?.cursor ? decodeMultiAgentCursor(filters.cursor) : {};
|
|
@@ -3664,10 +3952,13 @@ var OwneySDK = class {
|
|
|
3664
3952
|
if (filters?.cursor && agentCursor === void 0) {
|
|
3665
3953
|
return { agentId: agent.id, page: null };
|
|
3666
3954
|
}
|
|
3667
|
-
const
|
|
3668
|
-
|
|
3669
|
-
|
|
3670
|
-
|
|
3955
|
+
const agentFilters = { ...filters, cursor: agentCursor };
|
|
3956
|
+
const page = await this.readAgent(
|
|
3957
|
+
agent,
|
|
3958
|
+
"history",
|
|
3959
|
+
() => agent.getHistory(state, chainId, agentFilters),
|
|
3960
|
+
agentFilters
|
|
3961
|
+
);
|
|
3671
3962
|
return { agentId: agent.id, page };
|
|
3672
3963
|
})
|
|
3673
3964
|
);
|
|
@@ -3707,13 +3998,14 @@ var OwneySDK = class {
|
|
|
3707
3998
|
const state = this.requireState();
|
|
3708
3999
|
const chainId = this.requireChainId();
|
|
3709
4000
|
if (agentId) {
|
|
3710
|
-
|
|
4001
|
+
const agent = this.getAgent(agentId);
|
|
4002
|
+
return this.readAgent(agent, "profile", () => agent.getUserProfile(state, chainId));
|
|
3711
4003
|
}
|
|
3712
4004
|
const results = {};
|
|
3713
4005
|
const entries = [...this.getActiveAgents().entries()];
|
|
3714
4006
|
const profileResults = await Promise.all(
|
|
3715
4007
|
entries.map(async ([id, agent]) => {
|
|
3716
|
-
const p = await agent.getUserProfile(state, chainId);
|
|
4008
|
+
const p = await this.readAgent(agent, "profile", () => agent.getUserProfile(state, chainId));
|
|
3717
4009
|
return [id, p];
|
|
3718
4010
|
})
|
|
3719
4011
|
);
|
|
@@ -3736,7 +4028,20 @@ var OwneySDK = class {
|
|
|
3736
4028
|
const chainId = this.requireChainId();
|
|
3737
4029
|
const agent = this.getAgent(agentId);
|
|
3738
4030
|
if (typeof agent.ensureAutoSelectProtocols !== "function") return false;
|
|
3739
|
-
|
|
4031
|
+
const key2 = JSON.stringify([
|
|
4032
|
+
state.walletAddress.toLowerCase(),
|
|
4033
|
+
agentId,
|
|
4034
|
+
chainId,
|
|
4035
|
+
asset
|
|
4036
|
+
]);
|
|
4037
|
+
const existing = this.activationChecks.get(key2);
|
|
4038
|
+
if (existing) return existing;
|
|
4039
|
+
const pending = Promise.resolve().then(() => agent.ensureAutoSelectProtocols(state, chainId, asset)).finally(() => {
|
|
4040
|
+
if (this.activationChecks.get(key2) === pending)
|
|
4041
|
+
this.activationChecks.delete(key2);
|
|
4042
|
+
});
|
|
4043
|
+
this.activationChecks.set(key2, pending);
|
|
4044
|
+
return pending;
|
|
3740
4045
|
}
|
|
3741
4046
|
/**
|
|
3742
4047
|
* One-time, user-paid approval of Permit2 on the sponsored WETH token for
|
|
@@ -3807,13 +4112,14 @@ var OwneySDK = class {
|
|
|
3807
4112
|
await this.ensureAgentsInitialized();
|
|
3808
4113
|
const agentOptions = { tokenSymbol, chainId };
|
|
3809
4114
|
if (agentId) {
|
|
3810
|
-
|
|
4115
|
+
const agent = this.getAgent(agentId);
|
|
4116
|
+
return this.readAgent(agent, "agentApy", () => agent.getAgentApy(days, agentOptions), { days, ...agentOptions });
|
|
3811
4117
|
}
|
|
3812
4118
|
const results = {};
|
|
3813
4119
|
const agentEntries = [...this.agents.entries()];
|
|
3814
4120
|
const apyResults = await Promise.all(
|
|
3815
4121
|
agentEntries.map(async ([id, agent]) => {
|
|
3816
|
-
const apy = await agent.getAgentApy(days, agentOptions);
|
|
4122
|
+
const apy = await this.readAgent(agent, "agentApy", () => agent.getAgentApy(days, agentOptions), { days, ...agentOptions });
|
|
3817
4123
|
return [id, apy];
|
|
3818
4124
|
})
|
|
3819
4125
|
);
|
|
@@ -3840,7 +4146,7 @@ var OwneySDK = class {
|
|
|
3840
4146
|
const entries = [...activeAgents.entries()];
|
|
3841
4147
|
const balanceResults = await Promise.allSettled(
|
|
3842
4148
|
entries.map(async ([id, agent]) => {
|
|
3843
|
-
const b = await agent.getBalances(state, chainId);
|
|
4149
|
+
const b = await this.readAgent(agent, "balances", () => agent.getBalances(state, chainId));
|
|
3844
4150
|
return [id, b.positions ?? []];
|
|
3845
4151
|
})
|
|
3846
4152
|
);
|
|
@@ -3848,6 +4154,7 @@ var OwneySDK = class {
|
|
|
3848
4154
|
const allPositions = [];
|
|
3849
4155
|
let successCount = 0;
|
|
3850
4156
|
const agentErrors = {};
|
|
4157
|
+
const agentFailures = [];
|
|
3851
4158
|
for (let i = 0; i < balanceResults.length; i++) {
|
|
3852
4159
|
const settled = balanceResults[i];
|
|
3853
4160
|
const [aid] = entries[i];
|
|
@@ -3862,6 +4169,7 @@ var OwneySDK = class {
|
|
|
3862
4169
|
successCount += 1;
|
|
3863
4170
|
} else {
|
|
3864
4171
|
const reason = settled.reason;
|
|
4172
|
+
agentFailures.push(reason);
|
|
3865
4173
|
agentErrors[aid] = reason instanceof Error ? reason.message : String(reason);
|
|
3866
4174
|
console.error(`getAllocationApy agent "${aid}" failed:`, reason);
|
|
3867
4175
|
}
|
|
@@ -3870,7 +4178,7 @@ var OwneySDK = class {
|
|
|
3870
4178
|
throw new OwneyError(
|
|
3871
4179
|
"ALLOCATION_ALL_FAILED",
|
|
3872
4180
|
"Failed to fetch allocation APY: all agents failed.",
|
|
3873
|
-
{ agentErrors }
|
|
4181
|
+
{ agentErrors, failures: agentFailures }
|
|
3874
4182
|
);
|
|
3875
4183
|
}
|
|
3876
4184
|
const overall = computeAllocationApy(allPositions);
|