@owney/sdk 0.6.9-beta.0 → 0.6.9-beta.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -3,14 +3,6 @@ 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
- };
14
6
  var __export = (target, all) => {
15
7
  for (var name in all)
16
8
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -25,478 +17,6 @@ var __copyProps = (to, from, except, desc) => {
25
17
  };
26
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
27
19
 
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
-
500
20
  // src/index.ts
501
21
  var index_exports = {};
502
22
  __export(index_exports, {
@@ -506,7 +26,8 @@ __export(index_exports, {
506
26
  NotConnectedError: () => NotConnectedError,
507
27
  OwneyError: () => OwneyError,
508
28
  OwneySDK: () => OwneySDK,
509
- createOwneySIWX: () => createOwneySIWX
29
+ createOwneySIWX: () => createOwneySIWX,
30
+ setOwneyDebug: () => setOwneyDebug
510
31
  });
511
32
  module.exports = __toCommonJS(index_exports);
512
33
 
@@ -568,8 +89,56 @@ var SupportedAssets = [
568
89
  }
569
90
  ];
570
91
 
92
+ // src/errors.ts
93
+ var OwneyError = class extends Error {
94
+ code;
95
+ details;
96
+ agentId;
97
+ constructor(code, message, details, agentId) {
98
+ const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
99
+ super(`${prefix} ${message}`);
100
+ this.name = "OwneyError";
101
+ this.code = code;
102
+ this.details = details;
103
+ this.agentId = agentId;
104
+ }
105
+ };
106
+ var AgentNotFoundError = class extends OwneyError {
107
+ constructor(agentId, available) {
108
+ super(
109
+ "AGENT_NOT_FOUND",
110
+ `Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
111
+ { agentId, available },
112
+ agentId
113
+ );
114
+ this.name = "AgentNotFoundError";
115
+ }
116
+ };
117
+ var NotConnectedError = class extends OwneyError {
118
+ constructor() {
119
+ super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
120
+ this.name = "NotConnectedError";
121
+ }
122
+ };
123
+ var AgentChainIncompatibleError = class extends OwneyError {
124
+ incompatibleAgents;
125
+ connectedChainId;
126
+ constructor(incompatibleAgents, connectedChainId) {
127
+ const details = incompatibleAgents.map(
128
+ ({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
129
+ ).join("; ");
130
+ super(
131
+ "AGENT_CHAIN_INCOMPATIBLE",
132
+ `Chain ${connectedChainId} is not supported by the following agents: ${details}`,
133
+ { incompatibleAgents, connectedChainId }
134
+ );
135
+ this.name = "AgentChainIncompatibleError";
136
+ this.incompatibleAgents = incompatibleAgents;
137
+ this.connectedChainId = connectedChainId;
138
+ }
139
+ };
140
+
571
141
  // src/lib/utils.ts
572
- init_errors();
573
142
  var isValidChainId = (chainId) => {
574
143
  if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
575
144
  throw new OwneyError(
@@ -643,46 +212,46 @@ function resolveChainId(chain) {
643
212
  function mapBalances(raw, _chainId, smartWallet) {
644
213
  const portfolio = raw.portfolio;
645
214
  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
- }
653
215
  let totalBalance = 0;
654
216
  const tokens = [];
655
- const positions = [];
656
217
  for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
657
218
  const positionChainId = Number(chainIdKey);
658
- const chainName = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
659
219
  for (const [symbol, { balance, decimals }] of Object.entries(
660
220
  tokensBySymbol ?? {}
661
221
  )) {
662
- const amount = hexToDecimal(balance || "0", tokenDecimals(symbol, decimals));
222
+ const amount = hexToDecimal(balance || "0", decimals);
663
223
  totalBalance += amount;
664
224
  tokens.push({
665
- chain: chainName,
225
+ chain: CHAIN_ID_TO_NAME[positionChainId] ?? "BASE",
666
226
  chainId: positionChainId,
667
227
  asset: symbol,
668
228
  amount: String(amount)
669
229
  });
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
- });
684
230
  }
685
231
  }
232
+ const positions = (portfolio.positions ?? []).map((p) => ({
233
+ chain: p.chain ?? "",
234
+ protocol: p.protocol_name ?? p.protocol_id ?? "",
235
+ protocolId: p.protocol_id,
236
+ pool: p.pool,
237
+ asset: p.token_symbol ?? "",
238
+ // Position amount is hex-encoded base units (like the token balances
239
+ // above). `PositionSlot` doesn't type a `decimals` field, but runtime
240
+ // getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
241
+ // when present, otherwise fall back to the per-symbol lookup so
242
+ // non-6-decimal assets like WETH don't render 1e12 too large.
243
+ amount: String(
244
+ hexToDecimal(
245
+ p.amount || "0",
246
+ tokenDecimals(p.token_symbol, p.decimals)
247
+ )
248
+ ),
249
+ apy: p.pool_apy,
250
+ tvl: p.pool_tvl,
251
+ // PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
252
+ // structural read keeps it undefined today and auto-populates later.
253
+ liquidity: p.liquidity
254
+ }));
686
255
  return {
687
256
  smartWallet,
688
257
  totalBalance: String(totalBalance),
@@ -957,9 +526,6 @@ function decodeHistoryCursor(token) {
957
526
  return parsed;
958
527
  }
959
528
 
960
- // src/agents/zyfai/zyfai.agent.ts
961
- init_errors();
962
-
963
529
  // src/agents/zyfai/zyfai.auth-cache.ts
964
530
  var KEY_PREFIX = "owney.zyfai.session";
965
531
  var storage = () => {
@@ -1095,6 +661,56 @@ function buildProtocolMergeUpdate(available, current, asset) {
1095
661
  };
1096
662
  }
1097
663
 
664
+ // src/agents/zyfai/splitting.ts
665
+ var MAX_MIN_SPLITS = 4;
666
+ var MIN_FORCE_SPLITS = 2;
667
+ var AUTOMATIC_MIN_SPLITS = 1;
668
+ function toZyfaiSplitting(policy) {
669
+ switch (policy.splittingMode) {
670
+ case "none":
671
+ return { splitting: false };
672
+ case "automatic":
673
+ return { splitting: true, minSplits: AUTOMATIC_MIN_SPLITS };
674
+ case "force":
675
+ return {
676
+ splitting: true,
677
+ minSplits: clampForceSplits(policy.minSplits)
678
+ };
679
+ }
680
+ }
681
+ function clampForceSplits(minSplits) {
682
+ if (typeof minSplits !== "number" || !Number.isFinite(minSplits)) {
683
+ return MIN_FORCE_SPLITS;
684
+ }
685
+ const rounded = Math.round(minSplits);
686
+ if (rounded < MIN_FORCE_SPLITS) return MIN_FORCE_SPLITS;
687
+ if (rounded > MAX_MIN_SPLITS) return MAX_MIN_SPLITS;
688
+ return rounded;
689
+ }
690
+ function splittingNeedsUpdate(current, desired) {
691
+ if (!current) return true;
692
+ if (current.splitting !== desired.splitting) return true;
693
+ if (desired.minSplits === void 0) return false;
694
+ return current.minSplits !== desired.minSplits;
695
+ }
696
+
697
+ // src/lib/debug.ts
698
+ var configuredDebug = false;
699
+ function setOwneyDebug(enabled) {
700
+ configuredDebug = enabled;
701
+ }
702
+ function isOwneyDebug() {
703
+ return globalThis.__OWNEY_DEBUG__ === true || configuredDebug;
704
+ }
705
+ function debugLog(scope, message, data) {
706
+ if (!isOwneyDebug()) return;
707
+ if (data === void 0) {
708
+ console.log(`[${scope}] ${message}`);
709
+ } else {
710
+ console.log(`[${scope}] ${message}`, data);
711
+ }
712
+ }
713
+
1098
714
  // src/agents/zyfai/zyfai.agent.ts
1099
715
  var DEFAULT_ZYFAI_RPC_URLS = {
1100
716
  8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
@@ -1107,6 +723,7 @@ var WETH_ADDRESS_BY_CHAIN = {
1107
723
  1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
1108
724
  };
1109
725
  var VIEM_CHAIN = { 8453: import_chains.base, 42161: import_chains.arbitrum, 1: import_chains.mainnet };
726
+ var SPLITTING_ASSETS = ["USDC", "WETH"];
1110
727
  function isAlreadyActiveSessionKeyError(error) {
1111
728
  const message = error instanceof Error ? error.message : String(error);
1112
729
  return /already has an active session key/i.test(message);
@@ -1471,6 +1088,62 @@ var ZyfaiAgent = class {
1471
1088
  throw error;
1472
1089
  }
1473
1090
  }
1091
+ /**
1092
+ * Apply the org's capital splitting policy to this user's Zyfai profile.
1093
+ *
1094
+ * Per ASSET, not per chain: Zyfai stores splitting under
1095
+ * `assetTypeSettings[asset]`, so one call would only configure USDC and leave a
1096
+ * WETH holder's real setting untouched.
1097
+ *
1098
+ * Non-fatal throughout. This is a side effect of connecting, so a Zyfai hiccup
1099
+ * must leave the user connected with their profile unchanged, never fail
1100
+ * activation.
1101
+ */
1102
+ async applyOrgPolicy(_state, _chainId, policy) {
1103
+ debugLog("zyfai:splitting", "applying org policy", {
1104
+ policy,
1105
+ // Per asset because Zyfai stores splitting under assetTypeSettings[asset].
1106
+ assets: SPLITTING_ASSETS
1107
+ });
1108
+ await Promise.all(
1109
+ SPLITTING_ASSETS.map((asset) => this.applySplitting(asset, policy))
1110
+ );
1111
+ }
1112
+ async applySplitting(asset, policy) {
1113
+ try {
1114
+ const desired = toZyfaiSplitting(policy);
1115
+ const current = await this.sdk.getUserDetails(asset);
1116
+ const currentSplitting = {
1117
+ splitting: current?.splitting,
1118
+ minSplits: current?.minSplits
1119
+ };
1120
+ const needsUpdate = splittingNeedsUpdate(current, desired);
1121
+ debugLog("zyfai:splitting", `${asset}: comparing`, {
1122
+ mode: policy.splittingMode,
1123
+ current: currentSplitting,
1124
+ desired,
1125
+ // Spelled out because the "why" is the non-obvious part: minSplits is
1126
+ // what separates automatic (1) from force (2-4), not `splitting`.
1127
+ decision: needsUpdate ? "will write \u2014 profile differs from the org policy" : "skipping \u2014 profile already matches"
1128
+ });
1129
+ if (!needsUpdate) return;
1130
+ const result = await this.sdk.updateUserProfile({ asset, ...desired });
1131
+ debugLog("zyfai:splitting", `${asset}: wrote updateUserProfile`, {
1132
+ sent: { asset, ...desired },
1133
+ // updateUserProfile re-reads the profile after PATCHing, so this is
1134
+ // Zyfai's own view of the result rather than an echo of what we sent.
1135
+ zyfaiNowReports: {
1136
+ splitting: result?.splitting,
1137
+ minSplits: result?.minSplits
1138
+ }
1139
+ });
1140
+ } catch (error) {
1141
+ console.warn(
1142
+ `[zyfai] applyOrgPolicy(${asset}) failed (non-fatal):`,
1143
+ error instanceof Error ? error.message : String(error)
1144
+ );
1145
+ }
1146
+ }
1474
1147
  async deposit(state, chainId, amount, asset, depositCallback) {
1475
1148
  try {
1476
1149
  await this.connectFull(state, chainId);
@@ -1622,12 +1295,42 @@ var ZyfaiAgent = class {
1622
1295
  }
1623
1296
  };
1624
1297
 
1625
- // src/client.ts
1626
- init_errors();
1627
-
1628
1298
  // src/lib/routing-api.ts
1629
- init_errors();
1630
1299
  var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
1300
+ async function fetchOrgAgentConfig(apiKey) {
1301
+ const url = `${ROUTING_API_BASE_URL}/api/v1/agent/org-config`;
1302
+ try {
1303
+ const res = await fetch(url, {
1304
+ method: "GET",
1305
+ headers: {
1306
+ "Content-Type": "application/json",
1307
+ "x-owney-api-key": `${apiKey}`
1308
+ }
1309
+ });
1310
+ if (!res.ok) {
1311
+ if (res.status !== 404) {
1312
+ console.warn(
1313
+ `[owney-sdk] Could not read org agent config (${res.status}); leaving user profiles unchanged.`
1314
+ );
1315
+ }
1316
+ return null;
1317
+ }
1318
+ const json = await res.json();
1319
+ const policy = json.success ? json.data ?? null : null;
1320
+ debugLog(
1321
+ "owney-sdk",
1322
+ policy ? "org agent config: loaded" : "org agent config: none set by this partner \u2014 user profiles will be left as they are",
1323
+ policy ?? void 0
1324
+ );
1325
+ return policy;
1326
+ } catch (error) {
1327
+ console.warn(
1328
+ "[owney-sdk] Could not read org agent config (non-fatal):",
1329
+ error instanceof Error ? error.message : String(error)
1330
+ );
1331
+ return null;
1332
+ }
1333
+ }
1631
1334
  async function fetchAgentKeys(apiKey) {
1632
1335
  const url = `${ROUTING_API_BASE_URL}/api/v1/agent/keys`;
1633
1336
  const res = await fetch(url, {
@@ -1657,7 +1360,6 @@ async function fetchAgentKeys(apiKey) {
1657
1360
  }
1658
1361
 
1659
1362
  // src/lib/health-report.ts
1660
- init_errors();
1661
1363
  var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
1662
1364
  async function reportAgentFailure(apiKey, agentType, errorCode) {
1663
1365
  try {
@@ -1807,12 +1509,9 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
1807
1509
  }
1808
1510
 
1809
1511
  // src/client.ts
1810
- var import_viem6 = require("viem");
1512
+ var import_viem5 = require("viem");
1811
1513
  var import_chains2 = require("viem/chains");
1812
1514
 
1813
- // src/lib/sponsored-deposit.ts
1814
- init_errors();
1815
-
1816
1515
  // src/lib/transfer-auth.ts
1817
1516
  var import_viem3 = require("viem");
1818
1517
  var ERC20_META_ABI = [
@@ -1850,7 +1549,6 @@ function randomAuthNonce() {
1850
1549
  }
1851
1550
 
1852
1551
  // src/lib/sponsor-client.ts
1853
- init_errors();
1854
1552
  var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
1855
1553
  async function postSponsorTransferAuth(input) {
1856
1554
  const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
@@ -2119,7 +1817,6 @@ function makeSponsoredDepositCallback(deps) {
2119
1817
  }
2120
1818
 
2121
1819
  // src/lib/sponsored-weth-deposit.ts
2122
- init_errors();
2123
1820
  var PERMIT_WINDOW_SECONDS = 15 * 60;
2124
1821
  function makeSponsoredWethCallback(deps) {
2125
1822
  const get = deps.httpGet ?? getSponsorRelayerAddress;
@@ -2228,7 +1925,6 @@ var VIEM_CHAIN2 = {
2228
1925
  42161: import_chains2.arbitrum,
2229
1926
  1: import_chains2.mainnet
2230
1927
  };
2231
- var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
2232
1928
  var SPONSORED_WETH_BY_CHAIN = {
2233
1929
  8453: "0x4200000000000000000000000000000000000006",
2234
1930
  42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
@@ -2248,6 +1944,12 @@ var OwneySDK = class {
2248
1944
  disabledAgents = /* @__PURE__ */ new Set();
2249
1945
  state = null;
2250
1946
  apiKey;
1947
+ // The org's agent policy, fetched once per client. Applied to each agent on
1948
+ // activation (ROUT-229). `undefined` means "not fetched yet", `null` means
1949
+ // "fetched, and the partner has no policy" — which is a real answer meaning
1950
+ // leave every user's agent profile alone.
1951
+ orgAgentConfig;
1952
+ orgAgentConfigPromise = null;
2251
1953
  zyfaiRpcUrls;
2252
1954
  routingApiBaseUrl;
2253
1955
  referralSource;
@@ -2256,6 +1958,7 @@ var OwneySDK = class {
2256
1958
  initializingAgentsPromise = null;
2257
1959
  constructor(config) {
2258
1960
  this.apiKey = config.apiKey;
1961
+ if (config.debug) setOwneyDebug(true);
2259
1962
  this.zyfaiRpcUrls = config.zyfaiRpcUrls;
2260
1963
  this.routingApiBaseUrl = config.routingApiBaseUrl;
2261
1964
  this.referralSource = config.referralSource;
@@ -2356,14 +2059,14 @@ var OwneySDK = class {
2356
2059
  // Casts work around viem's chain-narrowed Client vs the generic
2357
2060
  // PublicClient/WalletClient param types — structurally identical at
2358
2061
  // runtime, but the two share a name TS treats as unrelated.
2359
- getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
2062
+ getPublicClient: (cid) => (0, import_viem5.createPublicClient)({
2360
2063
  chain: VIEM_CHAIN2[cid],
2361
- transport: (0, import_viem6.custom)(provider)
2064
+ transport: (0, import_viem5.custom)(provider)
2362
2065
  }),
2363
- getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
2066
+ getWalletClient: (cid) => (0, import_viem5.createWalletClient)({
2364
2067
  account: owner,
2365
2068
  chain: VIEM_CHAIN2[cid],
2366
- transport: (0, import_viem6.custom)(provider)
2069
+ transport: (0, import_viem5.custom)(provider)
2367
2070
  })
2368
2071
  });
2369
2072
  if (!onApproved) this.cachedSponsoredCallback = callback;
@@ -2389,14 +2092,14 @@ var OwneySDK = class {
2389
2092
  // Casts work around viem's chain-narrowed Client vs the generic
2390
2093
  // PublicClient/WalletClient param types — structurally identical at
2391
2094
  // runtime, but the two share a name TS treats as unrelated.
2392
- getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
2095
+ getPublicClient: (cid) => (0, import_viem5.createPublicClient)({
2393
2096
  chain: VIEM_CHAIN2[cid],
2394
- transport: (0, import_viem6.custom)(provider)
2097
+ transport: (0, import_viem5.custom)(provider)
2395
2098
  }),
2396
- getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
2099
+ getWalletClient: (cid) => (0, import_viem5.createWalletClient)({
2397
2100
  account: owner,
2398
2101
  chain: VIEM_CHAIN2[cid],
2399
- transport: (0, import_viem6.custom)(provider)
2102
+ transport: (0, import_viem5.custom)(provider)
2400
2103
  })
2401
2104
  });
2402
2105
  if (!onApproved) this.cachedWethSponsoredCallback = callback;
@@ -2417,14 +2120,57 @@ var OwneySDK = class {
2417
2120
  }
2418
2121
  return active;
2419
2122
  }
2123
+ /**
2124
+ * Read the org's agent policy once and reuse it. fetchOrgAgentConfig never
2125
+ * throws — it degrades to null — so this cannot break activation.
2126
+ */
2127
+ async getOrgAgentConfig() {
2128
+ if (this.orgAgentConfig !== void 0) return this.orgAgentConfig;
2129
+ if (!this.orgAgentConfigPromise) {
2130
+ this.orgAgentConfigPromise = fetchOrgAgentConfig(this.apiKey).then(
2131
+ (config) => {
2132
+ this.orgAgentConfig = config;
2133
+ return config;
2134
+ }
2135
+ );
2136
+ }
2137
+ return this.orgAgentConfigPromise;
2138
+ }
2139
+ /**
2140
+ * Apply the org policy to one agent, after it has activated.
2141
+ *
2142
+ * Sequenced after activation rather than alongside it because applying the
2143
+ * policy needs the authenticated session activation establishes. Every failure
2144
+ * mode is swallowed: a partner's splitting preference is not worth failing a
2145
+ * user's connect over.
2146
+ */
2147
+ async applyOrgPolicyTo(agent, state, chainId) {
2148
+ if (!agent.applyOrgPolicy) {
2149
+ debugLog(
2150
+ "owney-sdk",
2151
+ `${agent.id}: no applyOrgPolicy \u2014 agent has no org-level knobs, skipping`
2152
+ );
2153
+ return;
2154
+ }
2155
+ try {
2156
+ const policy = await this.getOrgAgentConfig();
2157
+ if (!policy) return;
2158
+ await agent.applyOrgPolicy(state, chainId, policy);
2159
+ } catch (error) {
2160
+ console.warn(
2161
+ `[owney-sdk] applyOrgPolicy(${agent.id}) failed (non-fatal):`,
2162
+ error instanceof Error ? error.message : String(error)
2163
+ );
2164
+ }
2165
+ }
2420
2166
  async ensureAgentsInitialized() {
2421
2167
  if (this.agents.size > 0) return;
2422
2168
  if (!this.initializingAgentsPromise) {
2423
2169
  this.initializingAgentsPromise = (async () => {
2424
2170
  const agentKeys = await fetchAgentKeys(this.apiKey);
2425
2171
  this.disabledAgents.clear();
2426
- for (const { key, agent_type, project_name, is_enabled } of agentKeys) {
2427
- const agent = await this.createAgent(agent_type, key, project_name);
2172
+ for (const { key, agent_type, is_enabled } of agentKeys) {
2173
+ const agent = this.createAgent(agent_type, key);
2428
2174
  if (!agent) continue;
2429
2175
  this.agents.set(agent_type, agent);
2430
2176
  if (is_enabled === false) {
@@ -2445,15 +2191,10 @@ var OwneySDK = class {
2445
2191
  this.initializingAgentsPromise = null;
2446
2192
  }
2447
2193
  }
2448
- async createAgent(agentId, key, projectName) {
2194
+ createAgent(agentId, key) {
2449
2195
  if (agentId === "zyfai") {
2450
2196
  return new ZyfaiAgent(key, this.zyfaiRpcUrls, this.referralSource);
2451
2197
  }
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
- }
2457
2198
  return null;
2458
2199
  }
2459
2200
  // --- Account lifecycle ---
@@ -2506,6 +2247,7 @@ var OwneySDK = class {
2506
2247
  Promise.all(
2507
2248
  agents.map(async (agent) => {
2508
2249
  await agent.activateAgent(state, chainId);
2250
+ await this.applyOrgPolicyTo(agent, state, chainId);
2509
2251
  })
2510
2252
  ).catch((error) => {
2511
2253
  console.error("activateAgent background init failed:", error);
@@ -2533,6 +2275,7 @@ var OwneySDK = class {
2533
2275
  Promise.all(
2534
2276
  enabledCompatible.map(async (agent) => {
2535
2277
  await agent.activateAgent(state, chainId);
2278
+ await this.applyOrgPolicyTo(agent, state, chainId);
2536
2279
  })
2537
2280
  ).catch((error) => {
2538
2281
  console.error("activateAgent background init failed:", error);
@@ -2606,30 +2349,18 @@ var OwneySDK = class {
2606
2349
  );
2607
2350
  }
2608
2351
  const agentResults = {};
2609
- const agentErrors = {};
2610
2352
  for (const { agent, amount: agentAmount } of agentAmounts) {
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 }
2353
+ agentResults[agent.id] = await this.depositWithFallback(
2354
+ agent,
2355
+ state,
2356
+ chainId,
2357
+ agentAmount,
2358
+ asset,
2359
+ effectiveCallback,
2360
+ depositCallback
2630
2361
  );
2631
2362
  }
2632
- return Object.keys(agentErrors).length > 0 ? { agentResults, agentErrors } : { agentResults };
2363
+ return { agentResults };
2633
2364
  }
2634
2365
  /**
2635
2366
  * Invokes `agent.deposit` with the resolved sponsored callback, composing
@@ -2786,34 +2517,6 @@ var OwneySDK = class {
2786
2517
  }
2787
2518
  return eligible;
2788
2519
  }
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
- }
2817
2520
  // --- Fund operations ---
2818
2521
  /**
2819
2522
  * Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
@@ -2849,17 +2552,9 @@ var OwneySDK = class {
2849
2552
  }
2850
2553
  const eligibleAgents = this.getEligibleAgents(chainId, asset);
2851
2554
  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);
2860
2555
  const results2 = {};
2861
2556
  const agentErrors2 = {};
2862
- for (const { agent } of funded) {
2557
+ for (const agent of eligibleAgents) {
2863
2558
  try {
2864
2559
  results2[agent.id] = await agent.withdraw(state, chainId, token);
2865
2560
  } catch (err) {
@@ -2876,10 +2571,9 @@ var OwneySDK = class {
2876
2571
  { asset, agentErrors: agentErrors2 }
2877
2572
  );
2878
2573
  }
2879
- const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
2880
2574
  return {
2881
2575
  agentResult: results2,
2882
- totalWithdrawn: totalWithdrawn.toString()
2576
+ totalWithdrawn: sumWithdrawnAmount(results2).toString()
2883
2577
  };
2884
2578
  }
2885
2579
  const requested = BigInt(amount);
@@ -3249,10 +2943,10 @@ var OwneySDK = class {
3249
2943
  );
3250
2944
  }
3251
2945
  const provider = this.requireConnectedProvider();
3252
- const wallet = (0, import_viem6.createWalletClient)({
2946
+ const wallet = (0, import_viem5.createWalletClient)({
3253
2947
  account: state.walletAddress,
3254
2948
  chain: VIEM_CHAIN2[chainId],
3255
- transport: (0, import_viem6.custom)(provider)
2949
+ transport: (0, import_viem5.custom)(provider)
3256
2950
  });
3257
2951
  const hash = await wallet.writeContract({
3258
2952
  address: token,
@@ -3262,9 +2956,9 @@ var OwneySDK = class {
3262
2956
  account: state.walletAddress,
3263
2957
  chain: VIEM_CHAIN2[chainId]
3264
2958
  });
3265
- const publicClient = (0, import_viem6.createPublicClient)({
2959
+ const publicClient = (0, import_viem5.createPublicClient)({
3266
2960
  chain: VIEM_CHAIN2[chainId],
3267
- transport: (0, import_viem6.custom)(provider)
2961
+ transport: (0, import_viem5.custom)(provider)
3268
2962
  });
3269
2963
  const receipt = await publicClient.waitForTransactionReceipt({
3270
2964
  hash,
@@ -3372,11 +3066,8 @@ var OwneySDK = class {
3372
3066
  }
3373
3067
  };
3374
3068
 
3375
- // src/index.ts
3376
- init_errors();
3377
-
3378
3069
  // src/agents/zyfai/zyfai.siwx.ts
3379
- var import_viem7 = require("viem");
3070
+ var import_viem6 = require("viem");
3380
3071
  var import_siwe = require("siwe");
3381
3072
  var import_sdk2 = require("@zyfai/sdk");
3382
3073
 
@@ -3503,7 +3194,7 @@ function buildSIWXConfig(deps) {
3503
3194
  issuedAt,
3504
3195
  toString() {
3505
3196
  return new import_siwe.SiweMessage({
3506
- address: (0, import_viem7.getAddress)(accountAddress),
3197
+ address: (0, import_viem6.getAddress)(accountAddress),
3507
3198
  chainId: numericChainId(chainId),
3508
3199
  domain,
3509
3200
  uri,
@@ -3594,5 +3285,6 @@ function createOwneySIWX(config) {
3594
3285
  NotConnectedError,
3595
3286
  OwneyError,
3596
3287
  OwneySDK,
3597
- createOwneySIWX
3288
+ createOwneySIWX,
3289
+ setOwneyDebug
3598
3290
  });