@owney/sdk 0.6.7-beta.1 → 0.6.7-beta.3

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.d.cts CHANGED
@@ -15,6 +15,12 @@ interface OwneySDKConfig {
15
15
  * e.g. "http://localhost:3000", when testing sponsor changes.
16
16
  */
17
17
  routingApiBaseUrl?: string;
18
+ /**
19
+ * Optional attribution tag forwarded to Zyfai's /auth/login when the SDK
20
+ * authenticates (e.g. "delos"). Replaces the equivalent option on
21
+ * `createOwneySIWX` for apps that don't use the AppKit SIWX modal.
22
+ */
23
+ referralSource?: string;
18
24
  }
19
25
  interface ConnectionState {
20
26
  provider: any;
@@ -28,7 +34,7 @@ type OwneySupportedChainId = (typeof SUPPORTED_CHAIN_IDS)[number];
28
34
  type OwneySupportedChains = (typeof SUPPORTED_CHAINS)[number];
29
35
  type OwneySupportedTokens = (typeof SUPPORTED_TOKENS)[number];
30
36
 
31
- type AgentId = "zyfai" | "sail" | "surfliquid";
37
+ type AgentId = "zyfai" | "sail";
32
38
  type Asset = string;
33
39
  type AgentSupportedAsset = {
34
40
  readonly symbol: string;
@@ -101,12 +107,6 @@ interface OwneyDepositResult {
101
107
  }
102
108
  interface OwneyMultiDepositResult {
103
109
  agentResults: Record<string, OwneyDepositResult>;
104
- /**
105
- * Per-agent failure messages for agents that errored during a diversified
106
- * deposit. Present only when at least one (but not all) agents failed —
107
- * the deposit is partial, not total. Omitted when every agent succeeded.
108
- */
109
- agentErrors?: Record<string, string>;
110
110
  }
111
111
  interface AgentWithdrawResult {
112
112
  txHash?: string;
@@ -319,6 +319,7 @@ declare class OwneySDK {
319
319
  private apiKey;
320
320
  private zyfaiRpcUrls?;
321
321
  private routingApiBaseUrl?;
322
+ private referralSource?;
322
323
  private cachedSponsoredCallback;
323
324
  private cachedWethSponsoredCallback;
324
325
  private initializingAgentsPromise;
@@ -428,17 +429,6 @@ declare class OwneySDK {
428
429
  private hasExistingBalance;
429
430
  private validateAssetSupport;
430
431
  private getEligibleAgents;
431
- /**
432
- * Agent ids the routing API provisioned for this org that support the given
433
- * chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
434
- * surfliquid first). Returns `[]` when the org has no compatible agent — never
435
- * throws on an empty org. Loads agent keys on first call (apiKey only, no
436
- * wallet), so the UI can resolve which agent to use before the user connects.
437
- *
438
- * This is the source of truth for agent availability: an agent appears here
439
- * iff the routing API returned its key. No per-app feature flags.
440
- */
441
- getEligibleAgentIds(chainId: number, asset: string): Promise<AgentId[]>;
442
432
  /**
443
433
  * Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
444
434
  * Validates that the asset is supported by the target agent(s) on the active chain.
@@ -534,7 +524,7 @@ declare class OwneySDK {
534
524
  getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
535
525
  }
536
526
 
537
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_ALL_FAILED" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
527
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
538
528
  declare class OwneyError extends Error {
539
529
  readonly code: OwneyErrorCode;
540
530
  readonly details?: Record<string, unknown>;
package/dist/index.d.ts CHANGED
@@ -15,6 +15,12 @@ interface OwneySDKConfig {
15
15
  * e.g. "http://localhost:3000", when testing sponsor changes.
16
16
  */
17
17
  routingApiBaseUrl?: string;
18
+ /**
19
+ * Optional attribution tag forwarded to Zyfai's /auth/login when the SDK
20
+ * authenticates (e.g. "delos"). Replaces the equivalent option on
21
+ * `createOwneySIWX` for apps that don't use the AppKit SIWX modal.
22
+ */
23
+ referralSource?: string;
18
24
  }
19
25
  interface ConnectionState {
20
26
  provider: any;
@@ -28,7 +34,7 @@ type OwneySupportedChainId = (typeof SUPPORTED_CHAIN_IDS)[number];
28
34
  type OwneySupportedChains = (typeof SUPPORTED_CHAINS)[number];
29
35
  type OwneySupportedTokens = (typeof SUPPORTED_TOKENS)[number];
30
36
 
31
- type AgentId = "zyfai" | "sail" | "surfliquid";
37
+ type AgentId = "zyfai" | "sail";
32
38
  type Asset = string;
33
39
  type AgentSupportedAsset = {
34
40
  readonly symbol: string;
@@ -101,12 +107,6 @@ interface OwneyDepositResult {
101
107
  }
102
108
  interface OwneyMultiDepositResult {
103
109
  agentResults: Record<string, OwneyDepositResult>;
104
- /**
105
- * Per-agent failure messages for agents that errored during a diversified
106
- * deposit. Present only when at least one (but not all) agents failed —
107
- * the deposit is partial, not total. Omitted when every agent succeeded.
108
- */
109
- agentErrors?: Record<string, string>;
110
110
  }
111
111
  interface AgentWithdrawResult {
112
112
  txHash?: string;
@@ -319,6 +319,7 @@ declare class OwneySDK {
319
319
  private apiKey;
320
320
  private zyfaiRpcUrls?;
321
321
  private routingApiBaseUrl?;
322
+ private referralSource?;
322
323
  private cachedSponsoredCallback;
323
324
  private cachedWethSponsoredCallback;
324
325
  private initializingAgentsPromise;
@@ -428,17 +429,6 @@ declare class OwneySDK {
428
429
  private hasExistingBalance;
429
430
  private validateAssetSupport;
430
431
  private getEligibleAgents;
431
- /**
432
- * Agent ids the routing API provisioned for this org that support the given
433
- * chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
434
- * surfliquid first). Returns `[]` when the org has no compatible agent — never
435
- * throws on an empty org. Loads agent keys on first call (apiKey only, no
436
- * wallet), so the UI can resolve which agent to use before the user connects.
437
- *
438
- * This is the source of truth for agent availability: an agent appears here
439
- * iff the routing API returned its key. No per-app feature flags.
440
- */
441
- getEligibleAgentIds(chainId: number, asset: string): Promise<AgentId[]>;
442
432
  /**
443
433
  * Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
444
434
  * Validates that the asset is supported by the target agent(s) on the active chain.
@@ -534,7 +524,7 @@ declare class OwneySDK {
534
524
  getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
535
525
  }
536
526
 
537
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_ALL_FAILED" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
527
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_SAIL_ERROR" | "API_SAIL_TIMEOUT" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
538
528
  declare class OwneyError extends Error {
539
529
  readonly code: OwneyErrorCode;
540
530
  readonly details?: Record<string, unknown>;
package/dist/index.js CHANGED
@@ -1,10 +1,3 @@
1
- import {
2
- AgentChainIncompatibleError,
3
- AgentNotFoundError,
4
- NotConnectedError,
5
- OwneyError
6
- } from "./chunk-GMNQBWUB.js";
7
-
8
1
  // src/agents/zyfai/zyfai.agent.ts
9
2
  import { ZyfaiSDK } from "@zyfai/sdk";
10
3
  import { createPublicClient, http } from "viem";
@@ -63,6 +56,55 @@ var SupportedAssets = [
63
56
  }
64
57
  ];
65
58
 
59
+ // src/errors.ts
60
+ var OwneyError = class extends Error {
61
+ code;
62
+ details;
63
+ agentId;
64
+ constructor(code, message, details, agentId) {
65
+ const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
66
+ super(`${prefix} ${message}`);
67
+ this.name = "OwneyError";
68
+ this.code = code;
69
+ this.details = details;
70
+ this.agentId = agentId;
71
+ }
72
+ };
73
+ var AgentNotFoundError = class extends OwneyError {
74
+ constructor(agentId, available) {
75
+ super(
76
+ "AGENT_NOT_FOUND",
77
+ `Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
78
+ { agentId, available },
79
+ agentId
80
+ );
81
+ this.name = "AgentNotFoundError";
82
+ }
83
+ };
84
+ var NotConnectedError = class extends OwneyError {
85
+ constructor() {
86
+ super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
87
+ this.name = "NotConnectedError";
88
+ }
89
+ };
90
+ var AgentChainIncompatibleError = class extends OwneyError {
91
+ incompatibleAgents;
92
+ connectedChainId;
93
+ constructor(incompatibleAgents, connectedChainId) {
94
+ const details = incompatibleAgents.map(
95
+ ({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
96
+ ).join("; ");
97
+ super(
98
+ "AGENT_CHAIN_INCOMPATIBLE",
99
+ `Chain ${connectedChainId} is not supported by the following agents: ${details}`,
100
+ { incompatibleAgents, connectedChainId }
101
+ );
102
+ this.name = "AgentChainIncompatibleError";
103
+ this.incompatibleAgents = incompatibleAgents;
104
+ this.connectedChainId = connectedChainId;
105
+ }
106
+ };
107
+
66
108
  // src/lib/utils.ts
67
109
  var isValidChainId = (chainId) => {
68
110
  if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
@@ -137,46 +179,46 @@ function resolveChainId(chain) {
137
179
  function mapBalances(raw, _chainId, smartWallet) {
138
180
  const portfolio = raw.portfolio;
139
181
  const portfolioByChain = portfolio.portfolioByChain ?? {};
140
- const rawPositions = portfolio.positions ?? [];
141
- const detailByKey = /* @__PURE__ */ new Map();
142
- for (const p of rawPositions) {
143
- const cid = resolveChainId(p.chain ?? "");
144
- const symbol = (p.token_symbol ?? "").toUpperCase();
145
- if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
146
- }
147
182
  let totalBalance = 0;
148
183
  const tokens = [];
149
- const positions = [];
150
184
  for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
151
185
  const positionChainId = Number(chainIdKey);
152
- const chainName = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
153
186
  for (const [symbol, { balance, decimals }] of Object.entries(
154
187
  tokensBySymbol ?? {}
155
188
  )) {
156
- const amount = hexToDecimal(balance || "0", tokenDecimals(symbol, decimals));
189
+ const amount = hexToDecimal(balance || "0", decimals);
157
190
  totalBalance += amount;
158
191
  tokens.push({
159
- chain: chainName,
192
+ chain: CHAIN_ID_TO_NAME[positionChainId] ?? "BASE",
160
193
  chainId: positionChainId,
161
194
  asset: symbol,
162
195
  amount: String(amount)
163
196
  });
164
- const detail = detailByKey.get(`${positionChainId}:${symbol.toUpperCase()}`);
165
- positions.push({
166
- chain: chainName,
167
- protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
168
- protocolId: detail?.protocol_id,
169
- pool: detail?.pool,
170
- asset: symbol,
171
- amount: String(amount),
172
- apy: detail?.pool_apy,
173
- tvl: detail?.pool_tvl,
174
- // PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
175
- // structural read keeps it undefined today and auto-populates later.
176
- liquidity: detail?.liquidity
177
- });
178
197
  }
179
198
  }
199
+ const positions = (portfolio.positions ?? []).map((p) => ({
200
+ chain: p.chain ?? "",
201
+ protocol: p.protocol_name ?? p.protocol_id ?? "",
202
+ protocolId: p.protocol_id,
203
+ pool: p.pool,
204
+ asset: p.token_symbol ?? "",
205
+ // Position amount is hex-encoded base units (like the token balances
206
+ // above). `PositionSlot` doesn't type a `decimals` field, but runtime
207
+ // getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
208
+ // when present, otherwise fall back to the per-symbol lookup so
209
+ // non-6-decimal assets like WETH don't render 1e12 too large.
210
+ amount: String(
211
+ hexToDecimal(
212
+ p.amount || "0",
213
+ tokenDecimals(p.token_symbol, p.decimals)
214
+ )
215
+ ),
216
+ apy: p.pool_apy,
217
+ tvl: p.pool_tvl,
218
+ // PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
219
+ // structural read keeps it undefined today and auto-populates later.
220
+ liquidity: p.liquidity
221
+ }));
180
222
  return {
181
223
  smartWallet,
182
224
  totalBalance: String(totalBalance),
@@ -461,7 +503,8 @@ var storage = () => {
461
503
  return null;
462
504
  }
463
505
  };
464
- var buildKey = (address, chainId) => `${KEY_PREFIX}:${address.toLowerCase()}:${chainId}`;
506
+ var buildKey = (address) => `${KEY_PREFIX}:${address.toLowerCase()}`;
507
+ var legacyKeyPrefix = (address) => `${KEY_PREFIX}:${address.toLowerCase()}:`;
465
508
  var isJwtExpired = (token) => {
466
509
  const parts = token.split(".");
467
510
  if (parts.length !== 3) return false;
@@ -478,9 +521,37 @@ var isJwtExpired = (token) => {
478
521
  };
479
522
  var memorySessions = /* @__PURE__ */ new Map();
480
523
  var isFreshSession = (session) => !!session && !!session.token && !isJwtExpired(session.token);
481
- var readSession = (address, chainId) => {
524
+ var readLegacySession = (store, address) => {
525
+ if (!store) return null;
526
+ const prefix = legacyKeyPrefix(address);
527
+ const legacyKeys = [];
528
+ try {
529
+ for (let i = 0; i < store.length; i++) {
530
+ const key = store.key(i);
531
+ if (key?.startsWith(prefix)) legacyKeys.push(key);
532
+ }
533
+ } catch {
534
+ return null;
535
+ }
536
+ let adopted = null;
537
+ for (const key of legacyKeys) {
538
+ if (!adopted) {
539
+ try {
540
+ const parsed = JSON.parse(store.getItem(key) ?? "");
541
+ if (isFreshSession(parsed)) adopted = parsed;
542
+ } catch {
543
+ }
544
+ }
545
+ try {
546
+ store.removeItem(key);
547
+ } catch {
548
+ }
549
+ }
550
+ return adopted;
551
+ };
552
+ var readSession = (address, _chainId) => {
482
553
  if (typeof window === "undefined") return null;
483
- const key = buildKey(address, chainId);
554
+ const key = buildKey(address);
484
555
  const store = storage();
485
556
  let raw = null;
486
557
  try {
@@ -501,14 +572,19 @@ var readSession = (address, chainId) => {
501
572
  }
502
573
  return null;
503
574
  }
575
+ const legacy = readLegacySession(store, address);
576
+ if (legacy) {
577
+ writeSession(address, _chainId, legacy);
578
+ return legacy;
579
+ }
504
580
  const cached = memorySessions.get(key);
505
581
  if (isFreshSession(cached)) return cached;
506
582
  if (cached) memorySessions.delete(key);
507
583
  return null;
508
584
  };
509
- var writeSession = (address, chainId, session) => {
585
+ var writeSession = (address, _chainId, session) => {
510
586
  if (typeof window === "undefined") return;
511
- const key = buildKey(address, chainId);
587
+ const key = buildKey(address);
512
588
  memorySessions.set(key, session);
513
589
  const store = storage();
514
590
  try {
@@ -516,14 +592,15 @@ var writeSession = (address, chainId, session) => {
516
592
  } catch {
517
593
  }
518
594
  };
519
- var clearSession = (address, chainId) => {
520
- const key = buildKey(address, chainId);
595
+ var clearSession = (address, _chainId) => {
596
+ const key = buildKey(address);
521
597
  memorySessions.delete(key);
522
598
  const store = storage();
523
599
  try {
524
600
  store?.removeItem(key);
525
601
  } catch {
526
602
  }
603
+ readLegacySession(store, address);
527
604
  };
528
605
 
529
606
  // src/agents/zyfai/autoSelect.ts
@@ -600,11 +677,15 @@ var ZyfaiAgent = class {
600
677
  // successful decode is cached forever; failures are NOT cached so a transient
601
678
  // RPC error retries on the next fetch.
602
679
  withdrawAmountCache = /* @__PURE__ */ new Map();
603
- constructor(apiKey, rpcUrls) {
680
+ constructor(apiKey, rpcUrls, referralSource) {
604
681
  this.rpcUrls = rpcUrls ?? DEFAULT_ZYFAI_RPC_URLS;
605
682
  this.sdk = new ZyfaiSDK({
606
683
  apiKey,
607
- rpcUrls: this.rpcUrls
684
+ rpcUrls: this.rpcUrls,
685
+ // Forwarded to /auth/login by the SDK's own SIWE handshake, so
686
+ // attribution survives without the AppKit SIWX config (which carried it
687
+ // via `createOwneySIWX({ referralSource })` when apps used the modal).
688
+ referralSource
608
689
  });
609
690
  this.installAuthCache();
610
691
  }
@@ -1551,7 +1632,6 @@ var VIEM_CHAIN2 = {
1551
1632
  42161: arbitrum2,
1552
1633
  1: mainnet2
1553
1634
  };
1554
- var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
1555
1635
  var SPONSORED_WETH_BY_CHAIN = {
1556
1636
  8453: "0x4200000000000000000000000000000000000006",
1557
1637
  42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
@@ -1573,6 +1653,7 @@ var OwneySDK = class {
1573
1653
  apiKey;
1574
1654
  zyfaiRpcUrls;
1575
1655
  routingApiBaseUrl;
1656
+ referralSource;
1576
1657
  cachedSponsoredCallback = null;
1577
1658
  cachedWethSponsoredCallback = null;
1578
1659
  initializingAgentsPromise = null;
@@ -1580,6 +1661,7 @@ var OwneySDK = class {
1580
1661
  this.apiKey = config.apiKey;
1581
1662
  this.zyfaiRpcUrls = config.zyfaiRpcUrls;
1582
1663
  this.routingApiBaseUrl = config.routingApiBaseUrl;
1664
+ this.referralSource = config.referralSource;
1583
1665
  }
1584
1666
  /**
1585
1667
  * Establish connection state for all subsequent SDK calls.
@@ -1739,8 +1821,8 @@ var OwneySDK = class {
1739
1821
  this.initializingAgentsPromise = (async () => {
1740
1822
  const agentKeys = await fetchAgentKeys(this.apiKey);
1741
1823
  this.disabledAgents.clear();
1742
- for (const { key, agent_type, project_name, is_enabled } of agentKeys) {
1743
- const agent = await this.createAgent(agent_type, key, project_name);
1824
+ for (const { key, agent_type, is_enabled } of agentKeys) {
1825
+ const agent = this.createAgent(agent_type, key);
1744
1826
  if (!agent) continue;
1745
1827
  this.agents.set(agent_type, agent);
1746
1828
  if (is_enabled === false) {
@@ -1761,14 +1843,9 @@ var OwneySDK = class {
1761
1843
  this.initializingAgentsPromise = null;
1762
1844
  }
1763
1845
  }
1764
- async createAgent(agentId, key, projectName) {
1846
+ createAgent(agentId, key) {
1765
1847
  if (agentId === "zyfai") {
1766
- return new ZyfaiAgent(key, this.zyfaiRpcUrls);
1767
- }
1768
- if (agentId === "surfliquid") {
1769
- if (!projectName) return null;
1770
- const { SurfLiquidAgent } = await import("./surfliquid.agent-OMOYXWLP.js");
1771
- return new SurfLiquidAgent({ projectName, appId: key });
1848
+ return new ZyfaiAgent(key, this.zyfaiRpcUrls, this.referralSource);
1772
1849
  }
1773
1850
  return null;
1774
1851
  }
@@ -1922,30 +1999,18 @@ var OwneySDK = class {
1922
1999
  );
1923
2000
  }
1924
2001
  const agentResults = {};
1925
- const agentErrors = {};
1926
2002
  for (const { agent, amount: agentAmount } of agentAmounts) {
1927
- try {
1928
- agentResults[agent.id] = await this.depositWithFallback(
1929
- agent,
1930
- state,
1931
- chainId,
1932
- agentAmount,
1933
- asset,
1934
- effectiveCallback,
1935
- depositCallback
1936
- );
1937
- } catch (error) {
1938
- agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
1939
- }
1940
- }
1941
- if (Object.keys(agentResults).length === 0) {
1942
- throw new OwneyError(
1943
- "DEPOSIT_ALL_FAILED",
1944
- `All ${agentAmounts.length} agent deposit(s) failed.`,
1945
- { agentErrors }
2003
+ agentResults[agent.id] = await this.depositWithFallback(
2004
+ agent,
2005
+ state,
2006
+ chainId,
2007
+ agentAmount,
2008
+ asset,
2009
+ effectiveCallback,
2010
+ depositCallback
1946
2011
  );
1947
2012
  }
1948
- return Object.keys(agentErrors).length > 0 ? { agentResults, agentErrors } : { agentResults };
2013
+ return { agentResults };
1949
2014
  }
1950
2015
  /**
1951
2016
  * Invokes `agent.deposit` with the resolved sponsored callback, composing
@@ -2102,34 +2167,6 @@ var OwneySDK = class {
2102
2167
  }
2103
2168
  return eligible;
2104
2169
  }
2105
- /**
2106
- * Agent ids the routing API provisioned for this org that support the given
2107
- * chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
2108
- * surfliquid first). Returns `[]` when the org has no compatible agent — never
2109
- * throws on an empty org. Loads agent keys on first call (apiKey only, no
2110
- * wallet), so the UI can resolve which agent to use before the user connects.
2111
- *
2112
- * This is the source of truth for agent availability: an agent appears here
2113
- * iff the routing API returned its key. No per-app feature flags.
2114
- */
2115
- async getEligibleAgentIds(chainId, asset) {
2116
- try {
2117
- await this.ensureAgentsInitialized();
2118
- } catch (error) {
2119
- if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
2120
- return [];
2121
- }
2122
- throw error;
2123
- }
2124
- return [...this.agents.values()].filter((agent) => {
2125
- const chainAssets = agent.supportedAssets.find(
2126
- (sa) => sa.chainId === chainId
2127
- );
2128
- return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
2129
- }).map((agent) => agent.id).sort(
2130
- (a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
2131
- );
2132
- }
2133
2170
  // --- Fund operations ---
2134
2171
  /**
2135
2172
  * Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
@@ -2165,17 +2202,9 @@ var OwneySDK = class {
2165
2202
  }
2166
2203
  const eligibleAgents = this.getEligibleAgents(chainId, asset);
2167
2204
  if (!amount) {
2168
- const aggregated2 = await this.getBalances();
2169
- const funded = projectAgentBalancesForAsset(
2170
- eligibleAgents,
2171
- aggregated2.agentBalances,
2172
- chainId,
2173
- asset,
2174
- assetInfo.decimals
2175
- ).filter((b) => b.balance > 0n);
2176
2205
  const results2 = {};
2177
2206
  const agentErrors2 = {};
2178
- for (const { agent } of funded) {
2207
+ for (const agent of eligibleAgents) {
2179
2208
  try {
2180
2209
  results2[agent.id] = await agent.withdraw(state, chainId, token);
2181
2210
  } catch (err) {
@@ -2192,10 +2221,9 @@ var OwneySDK = class {
2192
2221
  { asset, agentErrors: agentErrors2 }
2193
2222
  );
2194
2223
  }
2195
- const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
2196
2224
  return {
2197
2225
  agentResult: results2,
2198
- totalWithdrawn: totalWithdrawn.toString()
2226
+ totalWithdrawn: sumWithdrawnAmount(results2).toString()
2199
2227
  };
2200
2228
  }
2201
2229
  const requested = BigInt(amount);
@@ -2703,11 +2731,39 @@ var storage2 = () => {
2703
2731
  return null;
2704
2732
  }
2705
2733
  };
2706
- var buildKey2 = (address, chainId) => `${KEY_PREFIX2}:${address.toLowerCase()}:${chainId}`;
2734
+ var buildKey2 = (address) => `${KEY_PREFIX2}:${address.toLowerCase()}`;
2735
+ var legacyKeyPrefix2 = (address) => `${KEY_PREFIX2}:${address.toLowerCase()}:`;
2707
2736
  var memorySiwxSessions = /* @__PURE__ */ new Map();
2737
+ var readLegacySiwxSession = (store, address) => {
2738
+ if (!store) return null;
2739
+ const prefix = legacyKeyPrefix2(address);
2740
+ const legacyKeys = [];
2741
+ try {
2742
+ for (let i = 0; i < store.length; i++) {
2743
+ const key = store.key(i);
2744
+ if (key?.startsWith(prefix)) legacyKeys.push(key);
2745
+ }
2746
+ } catch {
2747
+ return null;
2748
+ }
2749
+ let adopted = null;
2750
+ for (const key of legacyKeys) {
2751
+ if (!adopted) {
2752
+ try {
2753
+ adopted = JSON.parse(store.getItem(key) ?? "");
2754
+ } catch {
2755
+ }
2756
+ }
2757
+ try {
2758
+ store.removeItem(key);
2759
+ } catch {
2760
+ }
2761
+ }
2762
+ return adopted;
2763
+ };
2708
2764
  var readSiwxSession = (address, chainId) => {
2709
2765
  if (typeof window === "undefined") return null;
2710
- const key = buildKey2(address, chainId);
2766
+ const key = buildKey2(address);
2711
2767
  const store = storage2();
2712
2768
  let raw = null;
2713
2769
  try {
@@ -2727,11 +2783,16 @@ var readSiwxSession = (address, chainId) => {
2727
2783
  return null;
2728
2784
  }
2729
2785
  }
2786
+ const legacy = readLegacySiwxSession(store, address);
2787
+ if (legacy) {
2788
+ writeSiwxSession(address, chainId, legacy);
2789
+ return legacy;
2790
+ }
2730
2791
  return memorySiwxSessions.get(key) ?? null;
2731
2792
  };
2732
- var writeSiwxSession = (address, chainId, session) => {
2793
+ var writeSiwxSession = (address, _chainId, session) => {
2733
2794
  if (typeof window === "undefined") return;
2734
- const key = buildKey2(address, chainId);
2795
+ const key = buildKey2(address);
2735
2796
  memorySiwxSessions.set(key, session);
2736
2797
  const store = storage2();
2737
2798
  try {
@@ -2739,14 +2800,15 @@ var writeSiwxSession = (address, chainId, session) => {
2739
2800
  } catch {
2740
2801
  }
2741
2802
  };
2742
- var clearSiwxSession = (address, chainId) => {
2743
- const key = buildKey2(address, chainId);
2803
+ var clearSiwxSession = (address, _chainId) => {
2804
+ const key = buildKey2(address);
2744
2805
  memorySiwxSessions.delete(key);
2745
2806
  const store = storage2();
2746
2807
  try {
2747
2808
  store?.removeItem(key);
2748
2809
  } catch {
2749
2810
  }
2811
+ readLegacySiwxSession(store, address);
2750
2812
  };
2751
2813
 
2752
2814
  // src/agents/zyfai/zyfai.siwx.ts
@@ -2810,9 +2872,12 @@ function buildSIWXConfig(deps) {
2810
2872
  }
2811
2873
  if (!stored) return [];
2812
2874
  const session = {
2813
- // `stored.data.chainId` is a plain string in the cache (kept AppKit-free);
2814
- // it always holds a valid CaipNetworkId here, so narrow at the boundary.
2815
- data: stored.data,
2875
+ // `stored.data` is kept AppKit-free in the cache, so narrow at the
2876
+ // boundary. Echo the REQUESTED chain rather than the one originally
2877
+ // signed: the Zyfai JWT is account-scoped (no chain claim), so one
2878
+ // signature is valid for every chain, and AppKit would otherwise treat
2879
+ // the session as not covering the active network and re-prompt.
2880
+ data: { ...stored.data, chainId },
2816
2881
  message: stored.message,
2817
2882
  signature: stored.signature
2818
2883
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.6.7-beta.1",
3
+ "version": "0.6.7-beta.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -23,9 +23,7 @@
23
23
  "test:watch": "vitest"
24
24
  },
25
25
  "dependencies": {
26
- "@surf_liquid/core-sdk": "^0.4.0",
27
26
  "@zyfai/sdk": "0.2.40",
28
- "ethers": "^6.17.0",
29
27
  "siwe": "^3.0.0",
30
28
  "viem": "^2.48.1"
31
29
  },