@owney/sdk 0.6.8-beta.3 → 0.6.9-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-GMNQBWUB.js +55 -0
- package/dist/index.cjs +606 -103
- package/dist/index.d.cts +19 -2
- package/dist/index.d.ts +19 -2
- package/dist/index.js +101 -88
- package/dist/surfliquid.agent-OMOYXWLP.js +385 -0
- package/package.json +3 -1
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,14 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res, err) => function __init() {
|
|
7
|
+
if (err) throw err[0];
|
|
8
|
+
try {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
} catch (e) {
|
|
11
|
+
throw err = [e], e;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
6
14
|
var __export = (target, all) => {
|
|
7
15
|
for (var name in all)
|
|
8
16
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -17,6 +25,478 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
25
|
};
|
|
18
26
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
27
|
|
|
28
|
+
// src/errors.ts
|
|
29
|
+
var OwneyError, AgentNotFoundError, NotConnectedError, AgentChainIncompatibleError;
|
|
30
|
+
var init_errors = __esm({
|
|
31
|
+
"src/errors.ts"() {
|
|
32
|
+
"use strict";
|
|
33
|
+
OwneyError = class extends Error {
|
|
34
|
+
code;
|
|
35
|
+
details;
|
|
36
|
+
agentId;
|
|
37
|
+
constructor(code, message, details, agentId) {
|
|
38
|
+
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
39
|
+
super(`${prefix} ${message}`);
|
|
40
|
+
this.name = "OwneyError";
|
|
41
|
+
this.code = code;
|
|
42
|
+
this.details = details;
|
|
43
|
+
this.agentId = agentId;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
AgentNotFoundError = class extends OwneyError {
|
|
47
|
+
constructor(agentId, available) {
|
|
48
|
+
super(
|
|
49
|
+
"AGENT_NOT_FOUND",
|
|
50
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
51
|
+
{ agentId, available },
|
|
52
|
+
agentId
|
|
53
|
+
);
|
|
54
|
+
this.name = "AgentNotFoundError";
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
NotConnectedError = class extends OwneyError {
|
|
58
|
+
constructor() {
|
|
59
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
60
|
+
this.name = "NotConnectedError";
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
AgentChainIncompatibleError = class extends OwneyError {
|
|
64
|
+
incompatibleAgents;
|
|
65
|
+
connectedChainId;
|
|
66
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
67
|
+
const details = incompatibleAgents.map(
|
|
68
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
69
|
+
).join("; ");
|
|
70
|
+
super(
|
|
71
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
72
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
73
|
+
{ incompatibleAgents, connectedChainId }
|
|
74
|
+
);
|
|
75
|
+
this.name = "AgentChainIncompatibleError";
|
|
76
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
77
|
+
this.connectedChainId = connectedChainId;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// src/agents/surfliquid/surfliquid.constants.ts
|
|
84
|
+
var SURFLIQUID_CHAIN_ID, SURFLIQUID_CHAIN_NAME, SURFLIQUID_USDC_ADDRESS, SURFLIQUID_USDC_DECIMALS, SURFLIQUID_MIN_DEPOSIT, SURFLIQUID_SUPPORTED_ASSETS, SURFLIQUID_ACTION_MAP;
|
|
85
|
+
var init_surfliquid_constants = __esm({
|
|
86
|
+
"src/agents/surfliquid/surfliquid.constants.ts"() {
|
|
87
|
+
"use strict";
|
|
88
|
+
SURFLIQUID_CHAIN_ID = 8453;
|
|
89
|
+
SURFLIQUID_CHAIN_NAME = "BASE";
|
|
90
|
+
SURFLIQUID_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
91
|
+
SURFLIQUID_USDC_DECIMALS = 6;
|
|
92
|
+
SURFLIQUID_MIN_DEPOSIT = "0";
|
|
93
|
+
SURFLIQUID_SUPPORTED_ASSETS = [
|
|
94
|
+
{
|
|
95
|
+
chainId: SURFLIQUID_CHAIN_ID,
|
|
96
|
+
chain: SURFLIQUID_CHAIN_NAME,
|
|
97
|
+
assets: [{ symbol: "USDC", minDepositAmount: SURFLIQUID_MIN_DEPOSIT }]
|
|
98
|
+
}
|
|
99
|
+
];
|
|
100
|
+
SURFLIQUID_ACTION_MAP = {
|
|
101
|
+
// INITIAL_DEPOSIT is the user's real first deposit, so surface it like any
|
|
102
|
+
// other funding ("Top up"). The mini-app intentionally hides the "Deposit"
|
|
103
|
+
// action (it marks Zyfai's smart-account-creation event), which would
|
|
104
|
+
// otherwise drop a SurfLiquid user's only history row.
|
|
105
|
+
INITIAL_DEPOSIT: "Top up",
|
|
106
|
+
DEPOSIT: "Top up",
|
|
107
|
+
USER_DEPOSIT: "Top up",
|
|
108
|
+
WITHDRAWAL: "Withdraw",
|
|
109
|
+
USER_WITHDRAWAL: "Withdraw",
|
|
110
|
+
REBALANCE: "Rebalance",
|
|
111
|
+
REBALANCE_COMPLETED: "Rebalance",
|
|
112
|
+
CROSS_CHAIN_REBALANCE: "Rebalance",
|
|
113
|
+
MERKL_CLAIM: "Earned"
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// src/agents/surfliquid/surfliquid.mapper.ts
|
|
119
|
+
function mapMessage(message) {
|
|
120
|
+
const action = SURFLIQUID_ACTION_MAP[message.transactionType];
|
|
121
|
+
if (!action) return null;
|
|
122
|
+
return {
|
|
123
|
+
agent: "surfliquid",
|
|
124
|
+
action,
|
|
125
|
+
date: message.timestamp,
|
|
126
|
+
oldApy: message.apyBefore != null ? String(message.apyBefore) : null,
|
|
127
|
+
newApy: message.apyAfter != null ? String(message.apyAfter) : null,
|
|
128
|
+
transactions: [
|
|
129
|
+
{
|
|
130
|
+
txHashes: [message.txHash],
|
|
131
|
+
chainId: message.chainId,
|
|
132
|
+
tokenSymbol: message.token ?? void 0,
|
|
133
|
+
amount: message.amount != null ? String(message.amount) : void 0
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
rebalanceLog: []
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function mapHistory(result, _chainId) {
|
|
140
|
+
const data = result.messages.map(mapMessage).filter((entry) => entry !== null);
|
|
141
|
+
const hasMore = result.page < result.pages;
|
|
142
|
+
return {
|
|
143
|
+
data,
|
|
144
|
+
hasMore,
|
|
145
|
+
nextCursor: hasMore ? String(result.page + 1) : void 0
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function mapBalances2(vault, chainId, morphoStats) {
|
|
149
|
+
const assets = (vault.assets ?? []).filter(
|
|
150
|
+
(asset) => asset.assetSymbol === "USDC" && asset.chainId === chainId
|
|
151
|
+
);
|
|
152
|
+
const tokens = assets.map((asset) => ({
|
|
153
|
+
chain: SURFLIQUID_CHAIN_NAME,
|
|
154
|
+
chainId: SURFLIQUID_CHAIN_ID,
|
|
155
|
+
asset: "USDC",
|
|
156
|
+
amount: String(asset.currentValueUSD)
|
|
157
|
+
}));
|
|
158
|
+
const positions = assets.map((asset) => {
|
|
159
|
+
const stats = morphoStats?.get(asset.morphoVaultAddress?.toLowerCase() ?? "");
|
|
160
|
+
return {
|
|
161
|
+
chain: SURFLIQUID_CHAIN_NAME,
|
|
162
|
+
protocol: "Morpho",
|
|
163
|
+
// The specific MetaMorpho vault (e.g. "Gauntlet USDC Frontier"), read from
|
|
164
|
+
// Morpho — renders as "Morpho <vault>" alongside zyfai's vault detail.
|
|
165
|
+
pool: stats?.name ?? void 0,
|
|
166
|
+
asset: "USDC",
|
|
167
|
+
amount: String(asset.currentValueUSD),
|
|
168
|
+
apy: asset.currentAPY,
|
|
169
|
+
// TVL + liquidity come straight from Morpho (SurfLiquid's API omits them).
|
|
170
|
+
tvl: stats?.tvlUsd,
|
|
171
|
+
liquidity: stats?.liquidityUsd
|
|
172
|
+
};
|
|
173
|
+
});
|
|
174
|
+
const total = assets.reduce(
|
|
175
|
+
(sum, asset) => sum + asset.currentValueUSD,
|
|
176
|
+
0
|
|
177
|
+
);
|
|
178
|
+
return {
|
|
179
|
+
smartWallet: vault.userVaultAddress ?? void 0,
|
|
180
|
+
totalBalance: String(total),
|
|
181
|
+
totalBalanceAsset: "usdc",
|
|
182
|
+
tokens,
|
|
183
|
+
positions
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function mapAccountApy(vault, days) {
|
|
187
|
+
const breakdown = vault.apyBreakdown;
|
|
188
|
+
const windowed = breakdown ? breakdown[APY_WINDOW_KEY[days]] : void 0;
|
|
189
|
+
const apy = windowed != null ? windowed : breakdown?.currentAPY ?? 0;
|
|
190
|
+
return {
|
|
191
|
+
walletAddress: vault.walletAddress ?? "",
|
|
192
|
+
weightedApyAfterFee: apy,
|
|
193
|
+
apyByChainAndAsset: { [SURFLIQUID_CHAIN_ID]: { USDC: apy } },
|
|
194
|
+
// Parity with Sail: SurfLiquid's core-sdk exposes no daily net-APY series.
|
|
195
|
+
history: []
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function mapEarnings2(vault, vaultAddress) {
|
|
199
|
+
return {
|
|
200
|
+
smartWallet: vaultAddress,
|
|
201
|
+
lifetimeEarnings: vault.earned?.totalEarningsUSD ?? 0,
|
|
202
|
+
tokens: []
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function mapUserProfile2(vault, address) {
|
|
206
|
+
return {
|
|
207
|
+
address,
|
|
208
|
+
smartWallet: vault.userVaultAddress ?? "",
|
|
209
|
+
chains: [SURFLIQUID_CHAIN_ID],
|
|
210
|
+
// SurfLiquid uses cookie-based session auth — no session-key concept.
|
|
211
|
+
hasActiveSessionKey: false,
|
|
212
|
+
protocols: ["SurfLiquid"]
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
var APY_WINDOW_KEY;
|
|
216
|
+
var init_surfliquid_mapper = __esm({
|
|
217
|
+
"src/agents/surfliquid/surfliquid.mapper.ts"() {
|
|
218
|
+
"use strict";
|
|
219
|
+
init_surfliquid_constants();
|
|
220
|
+
APY_WINDOW_KEY = {
|
|
221
|
+
"7D": "apy7d",
|
|
222
|
+
"14D": "apy14d",
|
|
223
|
+
"30D": "apy30d"
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// src/agents/surfliquid/surfliquid.wallet-adapter.ts
|
|
229
|
+
var import_core_sdk, OwneyWalletAdapter;
|
|
230
|
+
var init_surfliquid_wallet_adapter = __esm({
|
|
231
|
+
"src/agents/surfliquid/surfliquid.wallet-adapter.ts"() {
|
|
232
|
+
"use strict";
|
|
233
|
+
import_core_sdk = require("@surf_liquid/core-sdk");
|
|
234
|
+
OwneyWalletAdapter = class extends import_core_sdk.BaseWalletAdapter {
|
|
235
|
+
constructor(eip1193Provider) {
|
|
236
|
+
super();
|
|
237
|
+
this.eip1193Provider = eip1193Provider;
|
|
238
|
+
}
|
|
239
|
+
eip1193Provider;
|
|
240
|
+
name = "owney";
|
|
241
|
+
get installed() {
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
resolveProvider() {
|
|
245
|
+
return this.eip1193Provider;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// src/agents/surfliquid/surfliquid.morpho.ts
|
|
252
|
+
async function fetchMorphoVaultStats(vaultAddress, chainId) {
|
|
253
|
+
try {
|
|
254
|
+
const res = await fetch(MORPHO_API_URL, {
|
|
255
|
+
method: "POST",
|
|
256
|
+
headers: { "Content-Type": "application/json" },
|
|
257
|
+
body: JSON.stringify({
|
|
258
|
+
query: VAULT_STATS_QUERY,
|
|
259
|
+
variables: { address: vaultAddress, chainId }
|
|
260
|
+
})
|
|
261
|
+
});
|
|
262
|
+
if (!res.ok) return null;
|
|
263
|
+
const json = await res.json();
|
|
264
|
+
if (json.errors) return null;
|
|
265
|
+
const vault = json.data?.vaultByAddress;
|
|
266
|
+
const tvlUsd = vault?.state?.totalAssetsUsd;
|
|
267
|
+
const liquidityUsd = vault?.liquidity?.usd;
|
|
268
|
+
if (typeof tvlUsd !== "number" || typeof liquidityUsd !== "number") {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
const name = typeof vault?.name === "string" ? vault.name : null;
|
|
272
|
+
return { name, tvlUsd, liquidityUsd };
|
|
273
|
+
} catch (error) {
|
|
274
|
+
console.warn("surfliquid: Morpho vault stats fetch failed", {
|
|
275
|
+
vaultAddress,
|
|
276
|
+
chainId,
|
|
277
|
+
error
|
|
278
|
+
});
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async function fetchMorphoStatsByVault(vaultAddresses, chainId) {
|
|
283
|
+
const unique = [...new Set(vaultAddresses.map((a) => a.toLowerCase()))];
|
|
284
|
+
const entries = await Promise.all(
|
|
285
|
+
unique.map(
|
|
286
|
+
async (address) => [address, await fetchMorphoVaultStats(address, chainId)]
|
|
287
|
+
)
|
|
288
|
+
);
|
|
289
|
+
const byVault = /* @__PURE__ */ new Map();
|
|
290
|
+
for (const [address, stats] of entries) {
|
|
291
|
+
if (stats) byVault.set(address, stats);
|
|
292
|
+
}
|
|
293
|
+
return byVault;
|
|
294
|
+
}
|
|
295
|
+
var MORPHO_API_URL, VAULT_STATS_QUERY;
|
|
296
|
+
var init_surfliquid_morpho = __esm({
|
|
297
|
+
"src/agents/surfliquid/surfliquid.morpho.ts"() {
|
|
298
|
+
"use strict";
|
|
299
|
+
MORPHO_API_URL = "https://api.morpho.org/graphql";
|
|
300
|
+
VAULT_STATS_QUERY = `
|
|
301
|
+
query VaultStats($address: String!, $chainId: Int!) {
|
|
302
|
+
vaultByAddress(address: $address, chainId: $chainId) {
|
|
303
|
+
name
|
|
304
|
+
state { totalAssetsUsd }
|
|
305
|
+
liquidity { usd }
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
`;
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// src/agents/surfliquid/surfliquid.agent.ts
|
|
313
|
+
var surfliquid_agent_exports = {};
|
|
314
|
+
__export(surfliquid_agent_exports, {
|
|
315
|
+
SurfLiquidAgent: () => SurfLiquidAgent
|
|
316
|
+
});
|
|
317
|
+
var import_core_sdk2, import_viem5, APY_WINDOW_KEY2, SurfLiquidAgent;
|
|
318
|
+
var init_surfliquid_agent = __esm({
|
|
319
|
+
"src/agents/surfliquid/surfliquid.agent.ts"() {
|
|
320
|
+
"use strict";
|
|
321
|
+
import_core_sdk2 = require("@surf_liquid/core-sdk");
|
|
322
|
+
import_viem5 = require("viem");
|
|
323
|
+
init_errors();
|
|
324
|
+
init_surfliquid_constants();
|
|
325
|
+
init_surfliquid_mapper();
|
|
326
|
+
init_surfliquid_wallet_adapter();
|
|
327
|
+
init_surfliquid_morpho();
|
|
328
|
+
APY_WINDOW_KEY2 = {
|
|
329
|
+
"7D": "apy7d",
|
|
330
|
+
"14D": "apy14d",
|
|
331
|
+
"30D": "apy30d"
|
|
332
|
+
};
|
|
333
|
+
SurfLiquidAgent = class {
|
|
334
|
+
constructor(config) {
|
|
335
|
+
this.config = config;
|
|
336
|
+
}
|
|
337
|
+
config;
|
|
338
|
+
id = "surfliquid";
|
|
339
|
+
supportedChainIds = [SURFLIQUID_CHAIN_ID];
|
|
340
|
+
supportedAssets = SURFLIQUID_SUPPORTED_ASSETS;
|
|
341
|
+
surf = null;
|
|
342
|
+
connectedAddress = null;
|
|
343
|
+
// In-flight connect+auth, shared by concurrent callers to dedupe SIWE.
|
|
344
|
+
connectPromise = null;
|
|
345
|
+
ensureSurf() {
|
|
346
|
+
if (this.surf) return this.surf;
|
|
347
|
+
this.surf = import_core_sdk2.SurfClient.create({
|
|
348
|
+
projectName: this.config.projectName,
|
|
349
|
+
appId: this.config.appId,
|
|
350
|
+
environment: "mainnet",
|
|
351
|
+
chainId: SURFLIQUID_CHAIN_ID,
|
|
352
|
+
apiBaseUrl: this.config.apiBaseUrl,
|
|
353
|
+
rpcUrl: this.config.rpcUrl,
|
|
354
|
+
// Let the SDK auto-approve USDC to the vault before depositing.
|
|
355
|
+
autoApprove: true
|
|
356
|
+
});
|
|
357
|
+
return this.surf;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Connects + authenticates the SurfClient against owney's provider. Skips the
|
|
361
|
+
* SIWE prompt when already authenticated for this wallet (cookie session).
|
|
362
|
+
*/
|
|
363
|
+
async connect(state) {
|
|
364
|
+
const surf = this.ensureSurf();
|
|
365
|
+
const sameWallet = this.connectedAddress?.toLowerCase() === state.walletAddress.toLowerCase();
|
|
366
|
+
if (sameWallet && surf.getAuthState().authenticated) {
|
|
367
|
+
return surf;
|
|
368
|
+
}
|
|
369
|
+
if (this.connectPromise) return this.connectPromise;
|
|
370
|
+
this.connectPromise = (async () => {
|
|
371
|
+
surf.registerWalletAdapter(
|
|
372
|
+
"owney",
|
|
373
|
+
new OwneyWalletAdapter(state.provider)
|
|
374
|
+
);
|
|
375
|
+
await surf.connectWallet("owney");
|
|
376
|
+
await surf.authenticate();
|
|
377
|
+
this.connectedAddress = state.walletAddress;
|
|
378
|
+
return surf;
|
|
379
|
+
})();
|
|
380
|
+
try {
|
|
381
|
+
return await this.connectPromise;
|
|
382
|
+
} finally {
|
|
383
|
+
this.connectPromise = null;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Returns the user's vault address, deploying one on first use. SurfLiquid's
|
|
388
|
+
* deposit requires the vault to exist, so this must run before depositing.
|
|
389
|
+
* Existing vault → returned as-is; otherwise `deployVault()` is sent
|
|
390
|
+
* (user-pays) and the freshly deployed address is returned.
|
|
391
|
+
*/
|
|
392
|
+
async resolveVaultAddress(surf, owner) {
|
|
393
|
+
const vault = await surf.getVault(owner).catch(() => null);
|
|
394
|
+
if (vault?.exists && vault.userVaultAddress) {
|
|
395
|
+
return vault.userVaultAddress;
|
|
396
|
+
}
|
|
397
|
+
const { vaultAddress } = await surf.deployVault();
|
|
398
|
+
return vaultAddress;
|
|
399
|
+
}
|
|
400
|
+
// --- IAgent: lifecycle ---
|
|
401
|
+
async disconnect() {
|
|
402
|
+
if (this.surf) {
|
|
403
|
+
await this.surf.disconnectWallet();
|
|
404
|
+
}
|
|
405
|
+
this.connectedAddress = null;
|
|
406
|
+
}
|
|
407
|
+
async activateAgent(state) {
|
|
408
|
+
await this.connect(state);
|
|
409
|
+
}
|
|
410
|
+
// --- IAgent: funds (user-pays; asset is always USDC, callback ignored) ---
|
|
411
|
+
async deposit(state, _chainId, amount, _asset, _depositCallback) {
|
|
412
|
+
const surf = await this.connect(state);
|
|
413
|
+
const human = (0, import_viem5.formatUnits)(BigInt(amount), SURFLIQUID_USDC_DECIMALS);
|
|
414
|
+
const smartWallet = await this.resolveVaultAddress(
|
|
415
|
+
surf,
|
|
416
|
+
state.walletAddress
|
|
417
|
+
);
|
|
418
|
+
const tx = await surf.deposit({
|
|
419
|
+
asset: SURFLIQUID_USDC_ADDRESS,
|
|
420
|
+
amount: human
|
|
421
|
+
});
|
|
422
|
+
await tx.wait();
|
|
423
|
+
return { txHash: tx.hash, smartWallet, amount };
|
|
424
|
+
}
|
|
425
|
+
async withdraw(state, _chainId, _token, amount) {
|
|
426
|
+
const surf = await this.connect(state);
|
|
427
|
+
const human = amount != null ? (0, import_viem5.formatUnits)(BigInt(amount), SURFLIQUID_USDC_DECIMALS) : void 0;
|
|
428
|
+
try {
|
|
429
|
+
const tx = await surf.withdraw({
|
|
430
|
+
asset: SURFLIQUID_USDC_ADDRESS,
|
|
431
|
+
amount: human
|
|
432
|
+
});
|
|
433
|
+
await tx.wait();
|
|
434
|
+
return {
|
|
435
|
+
txHash: tx.hash,
|
|
436
|
+
type: amount != null ? "partial" : "full",
|
|
437
|
+
amount: amount ?? "0"
|
|
438
|
+
};
|
|
439
|
+
} catch (error) {
|
|
440
|
+
throw new OwneyError(
|
|
441
|
+
"WITHDRAW_FAILED",
|
|
442
|
+
error instanceof Error ? error.message : "SurfLiquid withdraw failed.",
|
|
443
|
+
{ chainId: SURFLIQUID_CHAIN_ID, amount },
|
|
444
|
+
this.id
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// --- IAgent: portfolio reads ---
|
|
449
|
+
async getBalances(state, chainId) {
|
|
450
|
+
const surf = await this.connect(state);
|
|
451
|
+
const vault = await surf.getVault(state.walletAddress);
|
|
452
|
+
const morphoVaultAddresses = (vault.assets ?? []).filter((asset) => asset.assetSymbol === "USDC" && asset.chainId === chainId).map((asset) => asset.morphoVaultAddress).filter((address) => Boolean(address));
|
|
453
|
+
const morphoStats = await fetchMorphoStatsByVault(
|
|
454
|
+
morphoVaultAddresses,
|
|
455
|
+
chainId
|
|
456
|
+
);
|
|
457
|
+
return mapBalances2(vault, chainId, morphoStats);
|
|
458
|
+
}
|
|
459
|
+
async getEarnings(state) {
|
|
460
|
+
const surf = await this.connect(state);
|
|
461
|
+
const vault = await surf.getVault(state.walletAddress);
|
|
462
|
+
return mapEarnings2(vault, vault.userVaultAddress ?? state.walletAddress);
|
|
463
|
+
}
|
|
464
|
+
async getAccountApy(state, _chainId, days, _tokenSymbol) {
|
|
465
|
+
const surf = await this.connect(state);
|
|
466
|
+
const vault = await surf.getVault(state.walletAddress);
|
|
467
|
+
return mapAccountApy(vault, days);
|
|
468
|
+
}
|
|
469
|
+
async getHistory(state, chainId, options) {
|
|
470
|
+
const surf = await this.connect(state);
|
|
471
|
+
const page = options?.cursor ? Number(options.cursor) : 1;
|
|
472
|
+
const limit = options?.limit ?? 10;
|
|
473
|
+
const result = await surf.getAgentMessages(
|
|
474
|
+
state.walletAddress,
|
|
475
|
+
page,
|
|
476
|
+
limit,
|
|
477
|
+
options?.fromDate,
|
|
478
|
+
options?.toDate
|
|
479
|
+
);
|
|
480
|
+
return mapHistory(result, chainId);
|
|
481
|
+
}
|
|
482
|
+
async getUserProfile(state) {
|
|
483
|
+
const surf = await this.connect(state);
|
|
484
|
+
const vault = await surf.getVault(state.walletAddress);
|
|
485
|
+
return mapUserProfile2(vault, state.walletAddress);
|
|
486
|
+
}
|
|
487
|
+
// --- IAgent: discovery (no wallet) ---
|
|
488
|
+
async getAgentApy(days, _options) {
|
|
489
|
+
const surf = this.ensureSurf();
|
|
490
|
+
const assets = await surf.getSupportedAssets(SURFLIQUID_CHAIN_ID);
|
|
491
|
+
const usdc = assets.find((asset) => asset.assetSymbol === "USDC");
|
|
492
|
+
if (!usdc) return { averageApy: 0 };
|
|
493
|
+
const windowed = usdc[APY_WINDOW_KEY2[days]];
|
|
494
|
+
return { averageApy: windowed != null ? windowed : usdc.currentAPY };
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
|
|
20
500
|
// src/index.ts
|
|
21
501
|
var index_exports = {};
|
|
22
502
|
__export(index_exports, {
|
|
@@ -88,56 +568,8 @@ var SupportedAssets = [
|
|
|
88
568
|
}
|
|
89
569
|
];
|
|
90
570
|
|
|
91
|
-
// src/errors.ts
|
|
92
|
-
var OwneyError = class extends Error {
|
|
93
|
-
code;
|
|
94
|
-
details;
|
|
95
|
-
agentId;
|
|
96
|
-
constructor(code, message, details, agentId) {
|
|
97
|
-
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
98
|
-
super(`${prefix} ${message}`);
|
|
99
|
-
this.name = "OwneyError";
|
|
100
|
-
this.code = code;
|
|
101
|
-
this.details = details;
|
|
102
|
-
this.agentId = agentId;
|
|
103
|
-
}
|
|
104
|
-
};
|
|
105
|
-
var AgentNotFoundError = class extends OwneyError {
|
|
106
|
-
constructor(agentId, available) {
|
|
107
|
-
super(
|
|
108
|
-
"AGENT_NOT_FOUND",
|
|
109
|
-
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
110
|
-
{ agentId, available },
|
|
111
|
-
agentId
|
|
112
|
-
);
|
|
113
|
-
this.name = "AgentNotFoundError";
|
|
114
|
-
}
|
|
115
|
-
};
|
|
116
|
-
var NotConnectedError = class extends OwneyError {
|
|
117
|
-
constructor() {
|
|
118
|
-
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
119
|
-
this.name = "NotConnectedError";
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
var AgentChainIncompatibleError = class extends OwneyError {
|
|
123
|
-
incompatibleAgents;
|
|
124
|
-
connectedChainId;
|
|
125
|
-
constructor(incompatibleAgents, connectedChainId) {
|
|
126
|
-
const details = incompatibleAgents.map(
|
|
127
|
-
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
128
|
-
).join("; ");
|
|
129
|
-
super(
|
|
130
|
-
"AGENT_CHAIN_INCOMPATIBLE",
|
|
131
|
-
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
132
|
-
{ incompatibleAgents, connectedChainId }
|
|
133
|
-
);
|
|
134
|
-
this.name = "AgentChainIncompatibleError";
|
|
135
|
-
this.incompatibleAgents = incompatibleAgents;
|
|
136
|
-
this.connectedChainId = connectedChainId;
|
|
137
|
-
}
|
|
138
|
-
};
|
|
139
|
-
|
|
140
571
|
// src/lib/utils.ts
|
|
572
|
+
init_errors();
|
|
141
573
|
var isValidChainId = (chainId) => {
|
|
142
574
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
143
575
|
throw new OwneyError(
|
|
@@ -211,46 +643,46 @@ function resolveChainId(chain) {
|
|
|
211
643
|
function mapBalances(raw, _chainId, smartWallet) {
|
|
212
644
|
const portfolio = raw.portfolio;
|
|
213
645
|
const portfolioByChain = portfolio.portfolioByChain ?? {};
|
|
646
|
+
const rawPositions = portfolio.positions ?? [];
|
|
647
|
+
const detailByKey = /* @__PURE__ */ new Map();
|
|
648
|
+
for (const p of rawPositions) {
|
|
649
|
+
const cid = resolveChainId(p.chain ?? "");
|
|
650
|
+
const symbol = (p.token_symbol ?? "").toUpperCase();
|
|
651
|
+
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
652
|
+
}
|
|
214
653
|
let totalBalance = 0;
|
|
215
654
|
const tokens = [];
|
|
655
|
+
const positions = [];
|
|
216
656
|
for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
|
|
217
657
|
const positionChainId = Number(chainIdKey);
|
|
658
|
+
const chainName = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
|
|
218
659
|
for (const [symbol, { balance, decimals }] of Object.entries(
|
|
219
660
|
tokensBySymbol ?? {}
|
|
220
661
|
)) {
|
|
221
|
-
const amount = hexToDecimal(balance || "0", decimals);
|
|
662
|
+
const amount = hexToDecimal(balance || "0", tokenDecimals(symbol, decimals));
|
|
222
663
|
totalBalance += amount;
|
|
223
664
|
tokens.push({
|
|
224
|
-
chain:
|
|
665
|
+
chain: chainName,
|
|
225
666
|
chainId: positionChainId,
|
|
226
667
|
asset: symbol,
|
|
227
668
|
amount: String(amount)
|
|
228
669
|
});
|
|
670
|
+
const detail = detailByKey.get(`${positionChainId}:${symbol.toUpperCase()}`);
|
|
671
|
+
positions.push({
|
|
672
|
+
chain: chainName,
|
|
673
|
+
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
674
|
+
protocolId: detail?.protocol_id,
|
|
675
|
+
pool: detail?.pool,
|
|
676
|
+
asset: symbol,
|
|
677
|
+
amount: String(amount),
|
|
678
|
+
apy: detail?.pool_apy,
|
|
679
|
+
tvl: detail?.pool_tvl,
|
|
680
|
+
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
681
|
+
// structural read keeps it undefined today and auto-populates later.
|
|
682
|
+
liquidity: detail?.liquidity
|
|
683
|
+
});
|
|
229
684
|
}
|
|
230
685
|
}
|
|
231
|
-
const positions = (portfolio.positions ?? []).map((p) => ({
|
|
232
|
-
chain: p.chain ?? "",
|
|
233
|
-
protocol: p.protocol_name ?? p.protocol_id ?? "",
|
|
234
|
-
protocolId: p.protocol_id,
|
|
235
|
-
pool: p.pool,
|
|
236
|
-
asset: p.token_symbol ?? "",
|
|
237
|
-
// Position amount is hex-encoded base units (like the token balances
|
|
238
|
-
// above). `PositionSlot` doesn't type a `decimals` field, but runtime
|
|
239
|
-
// getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
|
|
240
|
-
// when present, otherwise fall back to the per-symbol lookup so
|
|
241
|
-
// non-6-decimal assets like WETH don't render 1e12 too large.
|
|
242
|
-
amount: String(
|
|
243
|
-
hexToDecimal(
|
|
244
|
-
p.amount || "0",
|
|
245
|
-
tokenDecimals(p.token_symbol, p.decimals)
|
|
246
|
-
)
|
|
247
|
-
),
|
|
248
|
-
apy: p.pool_apy,
|
|
249
|
-
tvl: p.pool_tvl,
|
|
250
|
-
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
251
|
-
// structural read keeps it undefined today and auto-populates later.
|
|
252
|
-
liquidity: p.liquidity
|
|
253
|
-
}));
|
|
254
686
|
return {
|
|
255
687
|
smartWallet,
|
|
256
688
|
totalBalance: String(totalBalance),
|
|
@@ -525,6 +957,9 @@ function decodeHistoryCursor(token) {
|
|
|
525
957
|
return parsed;
|
|
526
958
|
}
|
|
527
959
|
|
|
960
|
+
// src/agents/zyfai/zyfai.agent.ts
|
|
961
|
+
init_errors();
|
|
962
|
+
|
|
528
963
|
// src/agents/zyfai/zyfai.auth-cache.ts
|
|
529
964
|
var KEY_PREFIX = "owney.zyfai.session";
|
|
530
965
|
var storage = () => {
|
|
@@ -1187,7 +1622,11 @@ var ZyfaiAgent = class {
|
|
|
1187
1622
|
}
|
|
1188
1623
|
};
|
|
1189
1624
|
|
|
1625
|
+
// src/client.ts
|
|
1626
|
+
init_errors();
|
|
1627
|
+
|
|
1190
1628
|
// src/lib/routing-api.ts
|
|
1629
|
+
init_errors();
|
|
1191
1630
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1192
1631
|
async function fetchAgentKeys(apiKey) {
|
|
1193
1632
|
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/keys`;
|
|
@@ -1218,6 +1657,7 @@ async function fetchAgentKeys(apiKey) {
|
|
|
1218
1657
|
}
|
|
1219
1658
|
|
|
1220
1659
|
// src/lib/health-report.ts
|
|
1660
|
+
init_errors();
|
|
1221
1661
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1222
1662
|
async function reportAgentFailure(apiKey, agentType, errorCode) {
|
|
1223
1663
|
try {
|
|
@@ -1367,9 +1807,12 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
1367
1807
|
}
|
|
1368
1808
|
|
|
1369
1809
|
// src/client.ts
|
|
1370
|
-
var
|
|
1810
|
+
var import_viem6 = require("viem");
|
|
1371
1811
|
var import_chains2 = require("viem/chains");
|
|
1372
1812
|
|
|
1813
|
+
// src/lib/sponsored-deposit.ts
|
|
1814
|
+
init_errors();
|
|
1815
|
+
|
|
1373
1816
|
// src/lib/transfer-auth.ts
|
|
1374
1817
|
var import_viem3 = require("viem");
|
|
1375
1818
|
var ERC20_META_ABI = [
|
|
@@ -1407,6 +1850,7 @@ function randomAuthNonce() {
|
|
|
1407
1850
|
}
|
|
1408
1851
|
|
|
1409
1852
|
// src/lib/sponsor-client.ts
|
|
1853
|
+
init_errors();
|
|
1410
1854
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1411
1855
|
async function postSponsorTransferAuth(input) {
|
|
1412
1856
|
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
@@ -1675,6 +2119,7 @@ function makeSponsoredDepositCallback(deps) {
|
|
|
1675
2119
|
}
|
|
1676
2120
|
|
|
1677
2121
|
// src/lib/sponsored-weth-deposit.ts
|
|
2122
|
+
init_errors();
|
|
1678
2123
|
var PERMIT_WINDOW_SECONDS = 15 * 60;
|
|
1679
2124
|
function makeSponsoredWethCallback(deps) {
|
|
1680
2125
|
const get = deps.httpGet ?? getSponsorRelayerAddress;
|
|
@@ -1783,6 +2228,7 @@ var VIEM_CHAIN2 = {
|
|
|
1783
2228
|
42161: import_chains2.arbitrum,
|
|
1784
2229
|
1: import_chains2.mainnet
|
|
1785
2230
|
};
|
|
2231
|
+
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
1786
2232
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
1787
2233
|
8453: "0x4200000000000000000000000000000000000006",
|
|
1788
2234
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -1910,14 +2356,14 @@ var OwneySDK = class {
|
|
|
1910
2356
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
1911
2357
|
// PublicClient/WalletClient param types — structurally identical at
|
|
1912
2358
|
// runtime, but the two share a name TS treats as unrelated.
|
|
1913
|
-
getPublicClient: (cid) => (0,
|
|
2359
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
1914
2360
|
chain: VIEM_CHAIN2[cid],
|
|
1915
|
-
transport: (0,
|
|
2361
|
+
transport: (0, import_viem6.custom)(provider)
|
|
1916
2362
|
}),
|
|
1917
|
-
getWalletClient: (cid) => (0,
|
|
2363
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
1918
2364
|
account: owner,
|
|
1919
2365
|
chain: VIEM_CHAIN2[cid],
|
|
1920
|
-
transport: (0,
|
|
2366
|
+
transport: (0, import_viem6.custom)(provider)
|
|
1921
2367
|
})
|
|
1922
2368
|
});
|
|
1923
2369
|
if (!onApproved) this.cachedSponsoredCallback = callback;
|
|
@@ -1943,14 +2389,14 @@ var OwneySDK = class {
|
|
|
1943
2389
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
1944
2390
|
// PublicClient/WalletClient param types — structurally identical at
|
|
1945
2391
|
// runtime, but the two share a name TS treats as unrelated.
|
|
1946
|
-
getPublicClient: (cid) => (0,
|
|
2392
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
1947
2393
|
chain: VIEM_CHAIN2[cid],
|
|
1948
|
-
transport: (0,
|
|
2394
|
+
transport: (0, import_viem6.custom)(provider)
|
|
1949
2395
|
}),
|
|
1950
|
-
getWalletClient: (cid) => (0,
|
|
2396
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
1951
2397
|
account: owner,
|
|
1952
2398
|
chain: VIEM_CHAIN2[cid],
|
|
1953
|
-
transport: (0,
|
|
2399
|
+
transport: (0, import_viem6.custom)(provider)
|
|
1954
2400
|
})
|
|
1955
2401
|
});
|
|
1956
2402
|
if (!onApproved) this.cachedWethSponsoredCallback = callback;
|
|
@@ -1977,8 +2423,8 @@ var OwneySDK = class {
|
|
|
1977
2423
|
this.initializingAgentsPromise = (async () => {
|
|
1978
2424
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
1979
2425
|
this.disabledAgents.clear();
|
|
1980
|
-
for (const { key, agent_type, is_enabled } of agentKeys) {
|
|
1981
|
-
const agent = this.createAgent(agent_type, key);
|
|
2426
|
+
for (const { key, agent_type, project_name, is_enabled } of agentKeys) {
|
|
2427
|
+
const agent = await this.createAgent(agent_type, key, project_name);
|
|
1982
2428
|
if (!agent) continue;
|
|
1983
2429
|
this.agents.set(agent_type, agent);
|
|
1984
2430
|
if (is_enabled === false) {
|
|
@@ -1999,10 +2445,15 @@ var OwneySDK = class {
|
|
|
1999
2445
|
this.initializingAgentsPromise = null;
|
|
2000
2446
|
}
|
|
2001
2447
|
}
|
|
2002
|
-
createAgent(agentId, key) {
|
|
2448
|
+
async createAgent(agentId, key, projectName) {
|
|
2003
2449
|
if (agentId === "zyfai") {
|
|
2004
2450
|
return new ZyfaiAgent(key, this.zyfaiRpcUrls, this.referralSource);
|
|
2005
2451
|
}
|
|
2452
|
+
if (agentId === "surfliquid") {
|
|
2453
|
+
if (!projectName) return null;
|
|
2454
|
+
const { SurfLiquidAgent: SurfLiquidAgent2 } = await Promise.resolve().then(() => (init_surfliquid_agent(), surfliquid_agent_exports));
|
|
2455
|
+
return new SurfLiquidAgent2({ projectName, appId: key });
|
|
2456
|
+
}
|
|
2006
2457
|
return null;
|
|
2007
2458
|
}
|
|
2008
2459
|
// --- Account lifecycle ---
|
|
@@ -2155,18 +2606,30 @@ var OwneySDK = class {
|
|
|
2155
2606
|
);
|
|
2156
2607
|
}
|
|
2157
2608
|
const agentResults = {};
|
|
2609
|
+
const agentErrors = {};
|
|
2158
2610
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
2159
|
-
|
|
2160
|
-
agent
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2611
|
+
try {
|
|
2612
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
2613
|
+
agent,
|
|
2614
|
+
state,
|
|
2615
|
+
chainId,
|
|
2616
|
+
agentAmount,
|
|
2617
|
+
asset,
|
|
2618
|
+
effectiveCallback,
|
|
2619
|
+
depositCallback
|
|
2620
|
+
);
|
|
2621
|
+
} catch (error) {
|
|
2622
|
+
agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
if (Object.keys(agentResults).length === 0) {
|
|
2626
|
+
throw new OwneyError(
|
|
2627
|
+
"DEPOSIT_ALL_FAILED",
|
|
2628
|
+
`All ${agentAmounts.length} agent deposit(s) failed.`,
|
|
2629
|
+
{ agentErrors }
|
|
2167
2630
|
);
|
|
2168
2631
|
}
|
|
2169
|
-
return { agentResults };
|
|
2632
|
+
return Object.keys(agentErrors).length > 0 ? { agentResults, agentErrors } : { agentResults };
|
|
2170
2633
|
}
|
|
2171
2634
|
/**
|
|
2172
2635
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -2323,6 +2786,34 @@ var OwneySDK = class {
|
|
|
2323
2786
|
}
|
|
2324
2787
|
return eligible;
|
|
2325
2788
|
}
|
|
2789
|
+
/**
|
|
2790
|
+
* Agent ids the routing API provisioned for this org that support the given
|
|
2791
|
+
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
2792
|
+
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
2793
|
+
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
2794
|
+
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
2795
|
+
*
|
|
2796
|
+
* This is the source of truth for agent availability: an agent appears here
|
|
2797
|
+
* iff the routing API returned its key. No per-app feature flags.
|
|
2798
|
+
*/
|
|
2799
|
+
async getEligibleAgentIds(chainId, asset) {
|
|
2800
|
+
try {
|
|
2801
|
+
await this.ensureAgentsInitialized();
|
|
2802
|
+
} catch (error) {
|
|
2803
|
+
if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
|
|
2804
|
+
return [];
|
|
2805
|
+
}
|
|
2806
|
+
throw error;
|
|
2807
|
+
}
|
|
2808
|
+
return [...this.agents.values()].filter((agent) => {
|
|
2809
|
+
const chainAssets = agent.supportedAssets.find(
|
|
2810
|
+
(sa) => sa.chainId === chainId
|
|
2811
|
+
);
|
|
2812
|
+
return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
|
|
2813
|
+
}).map((agent) => agent.id).sort(
|
|
2814
|
+
(a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
|
|
2815
|
+
);
|
|
2816
|
+
}
|
|
2326
2817
|
// --- Fund operations ---
|
|
2327
2818
|
/**
|
|
2328
2819
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -2358,9 +2849,17 @@ var OwneySDK = class {
|
|
|
2358
2849
|
}
|
|
2359
2850
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
2360
2851
|
if (!amount) {
|
|
2852
|
+
const aggregated2 = await this.getBalances();
|
|
2853
|
+
const funded = projectAgentBalancesForAsset(
|
|
2854
|
+
eligibleAgents,
|
|
2855
|
+
aggregated2.agentBalances,
|
|
2856
|
+
chainId,
|
|
2857
|
+
asset,
|
|
2858
|
+
assetInfo.decimals
|
|
2859
|
+
).filter((b) => b.balance > 0n);
|
|
2361
2860
|
const results2 = {};
|
|
2362
2861
|
const agentErrors2 = {};
|
|
2363
|
-
for (const agent of
|
|
2862
|
+
for (const { agent } of funded) {
|
|
2364
2863
|
try {
|
|
2365
2864
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
2366
2865
|
} catch (err) {
|
|
@@ -2377,9 +2876,10 @@ var OwneySDK = class {
|
|
|
2377
2876
|
{ asset, agentErrors: agentErrors2 }
|
|
2378
2877
|
);
|
|
2379
2878
|
}
|
|
2879
|
+
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
2380
2880
|
return {
|
|
2381
2881
|
agentResult: results2,
|
|
2382
|
-
totalWithdrawn:
|
|
2882
|
+
totalWithdrawn: totalWithdrawn.toString()
|
|
2383
2883
|
};
|
|
2384
2884
|
}
|
|
2385
2885
|
const requested = BigInt(amount);
|
|
@@ -2749,10 +3249,10 @@ var OwneySDK = class {
|
|
|
2749
3249
|
);
|
|
2750
3250
|
}
|
|
2751
3251
|
const provider = this.requireConnectedProvider();
|
|
2752
|
-
const wallet = (0,
|
|
3252
|
+
const wallet = (0, import_viem6.createWalletClient)({
|
|
2753
3253
|
account: state.walletAddress,
|
|
2754
3254
|
chain: VIEM_CHAIN2[chainId],
|
|
2755
|
-
transport: (0,
|
|
3255
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2756
3256
|
});
|
|
2757
3257
|
const hash = await wallet.writeContract({
|
|
2758
3258
|
address: token,
|
|
@@ -2762,9 +3262,9 @@ var OwneySDK = class {
|
|
|
2762
3262
|
account: state.walletAddress,
|
|
2763
3263
|
chain: VIEM_CHAIN2[chainId]
|
|
2764
3264
|
});
|
|
2765
|
-
const publicClient = (0,
|
|
3265
|
+
const publicClient = (0, import_viem6.createPublicClient)({
|
|
2766
3266
|
chain: VIEM_CHAIN2[chainId],
|
|
2767
|
-
transport: (0,
|
|
3267
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2768
3268
|
});
|
|
2769
3269
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
2770
3270
|
hash,
|
|
@@ -2872,8 +3372,11 @@ var OwneySDK = class {
|
|
|
2872
3372
|
}
|
|
2873
3373
|
};
|
|
2874
3374
|
|
|
3375
|
+
// src/index.ts
|
|
3376
|
+
init_errors();
|
|
3377
|
+
|
|
2875
3378
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
2876
|
-
var
|
|
3379
|
+
var import_viem7 = require("viem");
|
|
2877
3380
|
var import_siwe = require("siwe");
|
|
2878
3381
|
var import_sdk2 = require("@zyfai/sdk");
|
|
2879
3382
|
|
|
@@ -3000,7 +3503,7 @@ function buildSIWXConfig(deps) {
|
|
|
3000
3503
|
issuedAt,
|
|
3001
3504
|
toString() {
|
|
3002
3505
|
return new import_siwe.SiweMessage({
|
|
3003
|
-
address: (0,
|
|
3506
|
+
address: (0, import_viem7.getAddress)(accountAddress),
|
|
3004
3507
|
chainId: numericChainId(chainId),
|
|
3005
3508
|
domain,
|
|
3006
3509
|
uri,
|