@owney/sdk 0.6.6-beta.7 → 0.6.7-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/chunk-GMNQBWUB.js +55 -0
- package/dist/index.cjs +608 -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 = () => {
|
|
@@ -1096,7 +1531,11 @@ var ZyfaiAgent = class {
|
|
|
1096
1531
|
}
|
|
1097
1532
|
};
|
|
1098
1533
|
|
|
1534
|
+
// src/client.ts
|
|
1535
|
+
init_errors();
|
|
1536
|
+
|
|
1099
1537
|
// src/lib/routing-api.ts
|
|
1538
|
+
init_errors();
|
|
1100
1539
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1101
1540
|
async function fetchAgentKeys(apiKey) {
|
|
1102
1541
|
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/keys`;
|
|
@@ -1127,6 +1566,7 @@ async function fetchAgentKeys(apiKey) {
|
|
|
1127
1566
|
}
|
|
1128
1567
|
|
|
1129
1568
|
// src/lib/health-report.ts
|
|
1569
|
+
init_errors();
|
|
1130
1570
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1131
1571
|
async function reportAgentFailure(apiKey, agentType, errorCode) {
|
|
1132
1572
|
try {
|
|
@@ -1276,9 +1716,12 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
1276
1716
|
}
|
|
1277
1717
|
|
|
1278
1718
|
// src/client.ts
|
|
1279
|
-
var
|
|
1719
|
+
var import_viem6 = require("viem");
|
|
1280
1720
|
var import_chains2 = require("viem/chains");
|
|
1281
1721
|
|
|
1722
|
+
// src/lib/sponsored-deposit.ts
|
|
1723
|
+
init_errors();
|
|
1724
|
+
|
|
1282
1725
|
// src/lib/transfer-auth.ts
|
|
1283
1726
|
var import_viem3 = require("viem");
|
|
1284
1727
|
var ERC20_META_ABI = [
|
|
@@ -1316,6 +1759,7 @@ function randomAuthNonce() {
|
|
|
1316
1759
|
}
|
|
1317
1760
|
|
|
1318
1761
|
// src/lib/sponsor-client.ts
|
|
1762
|
+
init_errors();
|
|
1319
1763
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1320
1764
|
async function postSponsorTransferAuth(input) {
|
|
1321
1765
|
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
@@ -1482,6 +1926,9 @@ function makeSponsoredDepositCallback(deps) {
|
|
|
1482
1926
|
};
|
|
1483
1927
|
}
|
|
1484
1928
|
|
|
1929
|
+
// src/lib/sponsored-weth-deposit.ts
|
|
1930
|
+
init_errors();
|
|
1931
|
+
|
|
1485
1932
|
// src/lib/permit2.ts
|
|
1486
1933
|
var import_viem4 = require("viem");
|
|
1487
1934
|
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
@@ -1621,6 +2068,7 @@ var VIEM_CHAIN2 = {
|
|
|
1621
2068
|
42161: import_chains2.arbitrum,
|
|
1622
2069
|
1: import_chains2.mainnet
|
|
1623
2070
|
};
|
|
2071
|
+
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
1624
2072
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
1625
2073
|
8453: "0x4200000000000000000000000000000000000006",
|
|
1626
2074
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -1744,14 +2192,14 @@ var OwneySDK = class {
|
|
|
1744
2192
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
1745
2193
|
// PublicClient/WalletClient param types — structurally identical at
|
|
1746
2194
|
// runtime, but the two share a name TS treats as unrelated.
|
|
1747
|
-
getPublicClient: (cid) => (0,
|
|
2195
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
1748
2196
|
chain: VIEM_CHAIN2[cid],
|
|
1749
|
-
transport: (0,
|
|
2197
|
+
transport: (0, import_viem6.custom)(provider)
|
|
1750
2198
|
}),
|
|
1751
|
-
getWalletClient: (cid) => (0,
|
|
2199
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
1752
2200
|
account: owner,
|
|
1753
2201
|
chain: VIEM_CHAIN2[cid],
|
|
1754
|
-
transport: (0,
|
|
2202
|
+
transport: (0, import_viem6.custom)(provider)
|
|
1755
2203
|
})
|
|
1756
2204
|
});
|
|
1757
2205
|
return this.cachedSponsoredCallback;
|
|
@@ -1775,14 +2223,14 @@ var OwneySDK = class {
|
|
|
1775
2223
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
1776
2224
|
// PublicClient/WalletClient param types — structurally identical at
|
|
1777
2225
|
// runtime, but the two share a name TS treats as unrelated.
|
|
1778
|
-
getPublicClient: (cid) => (0,
|
|
2226
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
1779
2227
|
chain: VIEM_CHAIN2[cid],
|
|
1780
|
-
transport: (0,
|
|
2228
|
+
transport: (0, import_viem6.custom)(provider)
|
|
1781
2229
|
}),
|
|
1782
|
-
getWalletClient: (cid) => (0,
|
|
2230
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
1783
2231
|
account: owner,
|
|
1784
2232
|
chain: VIEM_CHAIN2[cid],
|
|
1785
|
-
transport: (0,
|
|
2233
|
+
transport: (0, import_viem6.custom)(provider)
|
|
1786
2234
|
})
|
|
1787
2235
|
});
|
|
1788
2236
|
return this.cachedWethSponsoredCallback;
|
|
@@ -1808,8 +2256,8 @@ var OwneySDK = class {
|
|
|
1808
2256
|
this.initializingAgentsPromise = (async () => {
|
|
1809
2257
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
1810
2258
|
this.disabledAgents.clear();
|
|
1811
|
-
for (const { key, agent_type, is_enabled } of agentKeys) {
|
|
1812
|
-
const agent = this.createAgent(agent_type, key);
|
|
2259
|
+
for (const { key, agent_type, project_name, is_enabled } of agentKeys) {
|
|
2260
|
+
const agent = await this.createAgent(agent_type, key, project_name);
|
|
1813
2261
|
if (!agent) continue;
|
|
1814
2262
|
this.agents.set(agent_type, agent);
|
|
1815
2263
|
if (is_enabled === false) {
|
|
@@ -1830,10 +2278,15 @@ var OwneySDK = class {
|
|
|
1830
2278
|
this.initializingAgentsPromise = null;
|
|
1831
2279
|
}
|
|
1832
2280
|
}
|
|
1833
|
-
createAgent(agentId, key) {
|
|
2281
|
+
async createAgent(agentId, key, projectName) {
|
|
1834
2282
|
if (agentId === "zyfai") {
|
|
1835
2283
|
return new ZyfaiAgent(key, this.zyfaiRpcUrls);
|
|
1836
2284
|
}
|
|
2285
|
+
if (agentId === "surfliquid") {
|
|
2286
|
+
if (!projectName) return null;
|
|
2287
|
+
const { SurfLiquidAgent: SurfLiquidAgent2 } = await Promise.resolve().then(() => (init_surfliquid_agent(), surfliquid_agent_exports));
|
|
2288
|
+
return new SurfLiquidAgent2({ projectName, appId: key });
|
|
2289
|
+
}
|
|
1837
2290
|
return null;
|
|
1838
2291
|
}
|
|
1839
2292
|
// --- Account lifecycle ---
|
|
@@ -1986,18 +2439,30 @@ var OwneySDK = class {
|
|
|
1986
2439
|
);
|
|
1987
2440
|
}
|
|
1988
2441
|
const agentResults = {};
|
|
2442
|
+
const agentErrors = {};
|
|
1989
2443
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
1990
|
-
|
|
1991
|
-
agent
|
|
1992
|
-
|
|
1993
|
-
|
|
1994
|
-
|
|
1995
|
-
|
|
1996
|
-
|
|
1997
|
-
|
|
2444
|
+
try {
|
|
2445
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
2446
|
+
agent,
|
|
2447
|
+
state,
|
|
2448
|
+
chainId,
|
|
2449
|
+
agentAmount,
|
|
2450
|
+
asset,
|
|
2451
|
+
effectiveCallback,
|
|
2452
|
+
depositCallback
|
|
2453
|
+
);
|
|
2454
|
+
} catch (error) {
|
|
2455
|
+
agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
|
|
2456
|
+
}
|
|
2457
|
+
}
|
|
2458
|
+
if (Object.keys(agentResults).length === 0) {
|
|
2459
|
+
throw new OwneyError(
|
|
2460
|
+
"DEPOSIT_ALL_FAILED",
|
|
2461
|
+
`All ${agentAmounts.length} agent deposit(s) failed.`,
|
|
2462
|
+
{ agentErrors }
|
|
1998
2463
|
);
|
|
1999
2464
|
}
|
|
2000
|
-
return { agentResults };
|
|
2465
|
+
return Object.keys(agentErrors).length > 0 ? { agentResults, agentErrors } : { agentResults };
|
|
2001
2466
|
}
|
|
2002
2467
|
/**
|
|
2003
2468
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -2154,6 +2619,34 @@ var OwneySDK = class {
|
|
|
2154
2619
|
}
|
|
2155
2620
|
return eligible;
|
|
2156
2621
|
}
|
|
2622
|
+
/**
|
|
2623
|
+
* Agent ids the routing API provisioned for this org that support the given
|
|
2624
|
+
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
2625
|
+
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
2626
|
+
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
2627
|
+
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
2628
|
+
*
|
|
2629
|
+
* This is the source of truth for agent availability: an agent appears here
|
|
2630
|
+
* iff the routing API returned its key. No per-app feature flags.
|
|
2631
|
+
*/
|
|
2632
|
+
async getEligibleAgentIds(chainId, asset) {
|
|
2633
|
+
try {
|
|
2634
|
+
await this.ensureAgentsInitialized();
|
|
2635
|
+
} catch (error) {
|
|
2636
|
+
if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
|
|
2637
|
+
return [];
|
|
2638
|
+
}
|
|
2639
|
+
throw error;
|
|
2640
|
+
}
|
|
2641
|
+
return [...this.agents.values()].filter((agent) => {
|
|
2642
|
+
const chainAssets = agent.supportedAssets.find(
|
|
2643
|
+
(sa) => sa.chainId === chainId
|
|
2644
|
+
);
|
|
2645
|
+
return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
|
|
2646
|
+
}).map((agent) => agent.id).sort(
|
|
2647
|
+
(a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
|
|
2648
|
+
);
|
|
2649
|
+
}
|
|
2157
2650
|
// --- Fund operations ---
|
|
2158
2651
|
/**
|
|
2159
2652
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -2189,9 +2682,17 @@ var OwneySDK = class {
|
|
|
2189
2682
|
}
|
|
2190
2683
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
2191
2684
|
if (!amount) {
|
|
2685
|
+
const aggregated2 = await this.getBalances();
|
|
2686
|
+
const funded = projectAgentBalancesForAsset(
|
|
2687
|
+
eligibleAgents,
|
|
2688
|
+
aggregated2.agentBalances,
|
|
2689
|
+
chainId,
|
|
2690
|
+
asset,
|
|
2691
|
+
assetInfo.decimals
|
|
2692
|
+
).filter((b) => b.balance > 0n);
|
|
2192
2693
|
const results2 = {};
|
|
2193
2694
|
const agentErrors2 = {};
|
|
2194
|
-
for (const agent of
|
|
2695
|
+
for (const { agent } of funded) {
|
|
2195
2696
|
try {
|
|
2196
2697
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
2197
2698
|
} catch (err) {
|
|
@@ -2208,9 +2709,10 @@ var OwneySDK = class {
|
|
|
2208
2709
|
{ asset, agentErrors: agentErrors2 }
|
|
2209
2710
|
);
|
|
2210
2711
|
}
|
|
2712
|
+
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
2211
2713
|
return {
|
|
2212
2714
|
agentResult: results2,
|
|
2213
|
-
totalWithdrawn:
|
|
2715
|
+
totalWithdrawn: totalWithdrawn.toString()
|
|
2214
2716
|
};
|
|
2215
2717
|
}
|
|
2216
2718
|
const requested = BigInt(amount);
|
|
@@ -2580,10 +3082,10 @@ var OwneySDK = class {
|
|
|
2580
3082
|
);
|
|
2581
3083
|
}
|
|
2582
3084
|
const provider = this.requireConnectedProvider();
|
|
2583
|
-
const wallet = (0,
|
|
3085
|
+
const wallet = (0, import_viem6.createWalletClient)({
|
|
2584
3086
|
account: state.walletAddress,
|
|
2585
3087
|
chain: VIEM_CHAIN2[chainId],
|
|
2586
|
-
transport: (0,
|
|
3088
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2587
3089
|
});
|
|
2588
3090
|
const hash = await wallet.writeContract({
|
|
2589
3091
|
address: token,
|
|
@@ -2593,9 +3095,9 @@ var OwneySDK = class {
|
|
|
2593
3095
|
account: state.walletAddress,
|
|
2594
3096
|
chain: VIEM_CHAIN2[chainId]
|
|
2595
3097
|
});
|
|
2596
|
-
const publicClient = (0,
|
|
3098
|
+
const publicClient = (0, import_viem6.createPublicClient)({
|
|
2597
3099
|
chain: VIEM_CHAIN2[chainId],
|
|
2598
|
-
transport: (0,
|
|
3100
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2599
3101
|
});
|
|
2600
3102
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
2601
3103
|
hash,
|
|
@@ -2703,8 +3205,11 @@ var OwneySDK = class {
|
|
|
2703
3205
|
}
|
|
2704
3206
|
};
|
|
2705
3207
|
|
|
3208
|
+
// src/index.ts
|
|
3209
|
+
init_errors();
|
|
3210
|
+
|
|
2706
3211
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
2707
|
-
var
|
|
3212
|
+
var import_viem7 = require("viem");
|
|
2708
3213
|
var import_siwe = require("siwe");
|
|
2709
3214
|
var import_sdk2 = require("@zyfai/sdk");
|
|
2710
3215
|
|
|
@@ -2797,7 +3302,7 @@ function buildSIWXConfig(deps) {
|
|
|
2797
3302
|
issuedAt,
|
|
2798
3303
|
toString() {
|
|
2799
3304
|
return new import_siwe.SiweMessage({
|
|
2800
|
-
address: (0,
|
|
3305
|
+
address: (0, import_viem7.getAddress)(accountAddress),
|
|
2801
3306
|
chainId: numericChainId(chainId),
|
|
2802
3307
|
domain,
|
|
2803
3308
|
uri,
|