@owney/sdk 0.7.28-beta.2 → 0.7.28-beta.4

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
@@ -1116,6 +1116,13 @@ function protocolsPolicyNeedsUpdate(current, desiredProtocols, desiredAutoSelect
1116
1116
  if (desiredProtocols === null) return false;
1117
1117
  return !protocolListsEqual(current.protocols, desiredProtocols);
1118
1118
  }
1119
+ function mergeScopedPoolNames(current, scoped, allAvailableNames) {
1120
+ const managed = new Set(scoped.flatMap((entry) => entry.availablePools));
1121
+ const existing = current.autoselect ? allAvailableNames : current.pools;
1122
+ const preserved = existing.filter((name) => !managed.has(name));
1123
+ const selected = scoped.flatMap((entry) => entry.pools);
1124
+ return [.../* @__PURE__ */ new Set([...preserved, ...selected])];
1125
+ }
1119
1126
  function mapAvailablePools(raw) {
1120
1127
  const byChain = raw ?? {};
1121
1128
  if (typeof byChain !== "object" || byChain === null) return [];
@@ -1712,14 +1719,73 @@ var ZyfaiAgent = class _ZyfaiAgent {
1712
1719
  return assemblePoolCatalog(universe, poolsByProtocol, params.asset);
1713
1720
  }
1714
1721
  /**
1715
- * Apply a user's own pool selection (the deposit-time Pools step) to their
1716
- * Zyfai profile. Same two writes as the org path — this is `applyPoolPolicy`
1717
- * driven by the user's `policy` instead of the organization's, with the
1718
- * deposit's chosen `strategy` passed through so pool names validate against
1719
- * the strategy the user just picked rather than their stored one.
1722
+ * Persist an explicitly saved deposit-time draft at Zyfai profile level.
1723
+ * Pool choices are merged into protocol/chain records and each active asset
1724
+ * is kept at aggressive unless the draft includes a yieldmaxxing-only pool.
1720
1725
  */
1721
- async setPoolSelection(policy, opts = {}) {
1722
- await this.applyPoolPolicy(policy, opts);
1726
+ async setPoolSelection(selection) {
1727
+ try {
1728
+ const byPair = /* @__PURE__ */ new Map();
1729
+ for (const entry of selection.selections) {
1730
+ const pair = `${entry.protocolId}:${entry.chainId}`;
1731
+ const group = byPair.get(pair) ?? [];
1732
+ group.push(entry);
1733
+ byPair.set(pair, group);
1734
+ }
1735
+ const customizations = (await Promise.all(
1736
+ [...byPair.values()].map(async (scoped) => {
1737
+ const { protocolId, chainId } = scoped[0];
1738
+ try {
1739
+ const [current, rawAvailable] = await Promise.all([
1740
+ this.sdk.getSelectedPools(protocolId, chainId),
1741
+ this.sdk.getAvailablePools(protocolId, "yieldmaxxing")
1742
+ ]);
1743
+ const allAvailableNames = mapAvailablePools(rawAvailable).filter((pool) => pool.chainId === chainId).map((pool) => pool.name);
1744
+ return {
1745
+ protocolId,
1746
+ chainId,
1747
+ pools: mergeScopedPoolNames(
1748
+ {
1749
+ pools: current.pools ?? [],
1750
+ autoselect: current.autoselect
1751
+ },
1752
+ scoped,
1753
+ allAvailableNames
1754
+ ),
1755
+ // An explicit Save freezes exactly the choices the user saw.
1756
+ // This also lets an empty list disable the pair deliberately.
1757
+ autoselect: false
1758
+ };
1759
+ } catch (error) {
1760
+ console.warn(
1761
+ `[zyfai] setPoolSelection: preserving ${protocolId}/${chainId} failed; skipping the pair:`,
1762
+ error instanceof Error ? error.message : String(error)
1763
+ );
1764
+ return null;
1765
+ }
1766
+ })
1767
+ )).filter((value) => value !== null);
1768
+ if (customizations.length > 0) {
1769
+ await this.sdk.customizeBatch(customizations);
1770
+ }
1771
+ await Promise.all(
1772
+ selection.strategies.map(async ({ asset, strategy }) => {
1773
+ const current = await this.sdk.getUserDetails(asset);
1774
+ const selectedProtocols = selection.selections.filter(
1775
+ (entry) => entry.asset === asset && entry.pools.length > 0
1776
+ ).map((entry) => entry.protocolId);
1777
+ const protocols = [
1778
+ .../* @__PURE__ */ new Set([...current.protocols ?? [], ...selectedProtocols])
1779
+ ];
1780
+ await this.sdk.updateUserProfile({ asset, strategy, protocols });
1781
+ })
1782
+ );
1783
+ } catch (error) {
1784
+ console.warn(
1785
+ "[zyfai] setPoolSelection failed (non-fatal):",
1786
+ error instanceof Error ? error.message : String(error)
1787
+ );
1788
+ }
1723
1789
  }
1724
1790
  /**
1725
1791
  * True when `smartWallet` is the backend-managed pool wallet Zyfai assigned
@@ -3008,6 +3074,10 @@ var DEFAULT_POLL_MS2 = 5e3;
3008
3074
  var MAX_BACKOFF_MS = 3e4;
3009
3075
  var backoffFor = (failures, base4) => Math.min(base4 * 2 ** Math.min(failures, 5), MAX_BACKOFF_MS);
3010
3076
  var DEFAULT_TIMEOUT_MS2 = 15 * 60 * 1e3;
3077
+ var NOT_FOUND_GRACE_MS = 2 * 60 * 1e3;
3078
+ function isNotFound(error) {
3079
+ return error instanceof OwneyError && error.details?.statusCode === 404;
3080
+ }
3011
3081
  async function runFusionOrder(deps, options) {
3012
3082
  const {
3013
3083
  orderHash,
@@ -3018,6 +3088,7 @@ async function runFusionOrder(deps, options) {
3018
3088
  } = options;
3019
3089
  const deadline = deps.now() + timeoutMs;
3020
3090
  let failures = 0;
3091
+ let notFoundSince;
3021
3092
  const published = /* @__PURE__ */ new Set();
3022
3093
  onStage?.("swapping");
3023
3094
  for (; ; ) {
@@ -3059,7 +3130,20 @@ async function runFusionOrder(deps, options) {
3059
3130
  try {
3060
3131
  ({ status } = await deps.orderStatus(orderHash));
3061
3132
  failures = 0;
3062
- } catch {
3133
+ notFoundSince = void 0;
3134
+ } catch (error) {
3135
+ if (isNotFound(error)) {
3136
+ notFoundSince ??= deps.now();
3137
+ if (deps.now() - notFoundSince >= NOT_FOUND_GRACE_MS) {
3138
+ throw new OwneyError(
3139
+ "SWAP_ORDER_NOT_FOUND",
3140
+ "The swap provider has no record of this order, so nothing was exchanged.",
3141
+ { orderHash }
3142
+ );
3143
+ }
3144
+ } else {
3145
+ notFoundSince = void 0;
3146
+ }
3063
3147
  failures += 1;
3064
3148
  await deps.sleep(backoffFor(failures, pollIntervalMs));
3065
3149
  continue;
@@ -3117,9 +3201,9 @@ async function runSameChainOrder(deps, options) {
3117
3201
  for (; ; ) {
3118
3202
  if (deps.now() >= deadline) {
3119
3203
  throw new OwneyError(
3120
- "SWAP_ORDER_EXPIRED",
3121
- "No one filled the swap in time. Nothing was exchanged and your funds are still in your wallet.",
3122
- { orderHash }
3204
+ "SWAP_REQUEST_FAILED",
3205
+ "Timed out waiting for the swap to fill. It may still complete \u2014 if it does, the swapped funds will be in your wallet. Check before retrying.",
3206
+ { orderHash, settlementUnconfirmed: true }
3123
3207
  );
3124
3208
  }
3125
3209
  let status;
@@ -3467,10 +3551,16 @@ async function runFusion(deps, options, walletAddress) {
3467
3551
  debugLog("owney-sdk", "swap: awaiting signature in wallet", {
3468
3552
  signingOnChain: quote.src.chainId
3469
3553
  });
3470
- const signature = await awaitWalletPrompt(
3471
- () => deps.signTypedData(built.typedData),
3472
- "sign the swap"
3473
- );
3554
+ let signature;
3555
+ try {
3556
+ signature = await awaitWalletPrompt(
3557
+ () => deps.signTypedData(built.typedData),
3558
+ "sign the swap"
3559
+ );
3560
+ } catch (error) {
3561
+ clearOrder(built.orderHash);
3562
+ throw error;
3563
+ }
3474
3564
  debugLog("owney-sdk", "swap: signed, submitting to relayer");
3475
3565
  await deps.api.submitOrder({
3476
3566
  srcChainId: quote.src.chainId,
@@ -3498,7 +3588,7 @@ async function runFusion(deps, options, walletAddress) {
3498
3588
  ...onStage ? { onStage } : {}
3499
3589
  });
3500
3590
  } catch (error) {
3501
- if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED")) {
3591
+ if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED" || error.code === "SWAP_ORDER_NOT_FOUND")) {
3502
3592
  clearOrder(built.orderHash);
3503
3593
  }
3504
3594
  throw error;
@@ -5733,7 +5823,7 @@ var OwneySDK = class {
5733
5823
  status: "completed"
5734
5824
  });
5735
5825
  } catch (error) {
5736
- if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED")) {
5826
+ if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED" || error.code === "SWAP_ORDER_NOT_FOUND")) {
5737
5827
  clearOrder(order.orderHash);
5738
5828
  updateWithdrawSwap(order.orderHash, { status: "refunded" });
5739
5829
  } else {
@@ -6461,7 +6551,10 @@ var OwneySDK = class {
6461
6551
  agent,
6462
6552
  "dailyEarnings",
6463
6553
  () => agent.getDailyEarnings(state, legChainId, days, tokenSymbol),
6464
- { days, tokenSymbol }
6554
+ // The leg's chain must be in the key: the read key otherwise names
6555
+ // only the CONNECTION chain, so every leg shared the first leg's
6556
+ // request and the sum counted that chain once per leg. (ROUT-561)
6557
+ { days, tokenSymbol, chainId: legChainId }
6465
6558
  )
6466
6559
  )
6467
6560
  );
@@ -6525,8 +6618,8 @@ var OwneySDK = class {
6525
6618
  }
6526
6619
  /**
6527
6620
  * Apply a user's deposit-time pool selection to their account (ROUT-569).
6528
- * `strategy` is the one chosen in the deposit flow, passed through so pool
6529
- * names validate against it rather than the user's stored strategy.
6621
+ * The request carries explicit pool choices plus the resulting strategy for
6622
+ * each asset reviewed in the deposit flow.
6530
6623
  */
6531
6624
  async setPoolSelection(params) {
6532
6625
  await this.ensureAgentsInitialized();
@@ -6537,7 +6630,7 @@ var OwneySDK = class {
6537
6630
  `Agent ${agent.id} does not support pool customization`
6538
6631
  );
6539
6632
  }
6540
- await agent.setPoolSelection(params.policy, { strategy: params.strategy });
6633
+ await agent.setPoolSelection(params.selection);
6541
6634
  }
6542
6635
  async getAccountApy({
6543
6636
  agentId,
@@ -6661,7 +6754,8 @@ var OwneySDK = class {
6661
6754
  agent,
6662
6755
  "history",
6663
6756
  () => agent.getHistory(state, leg.chainId, legFilters),
6664
- legFilters
6757
+ // Keyed per leg for the same reason as getDailyEarnings' fan-out.
6758
+ { ...legFilters, chainId: leg.chainId }
6665
6759
  );
6666
6760
  return { leg, page };
6667
6761
  })
package/dist/index.d.cts CHANGED
@@ -543,6 +543,26 @@ type AvailablePool = {
543
543
  /** Per-pool deep link (e.g. the Morpho vault page). null when absent. */
544
544
  link: string | null;
545
545
  };
546
+ /** Public Zyfai strategies used by deposit-time pool customization. */
547
+ type PoolSelectionStrategy = "aggressive" | "yieldmaxxing";
548
+ /** One asset's explicit choice for a protocol on one chain. */
549
+ type UserPoolSelection = {
550
+ asset: "USDC" | "WETH";
551
+ protocolId: string;
552
+ chainId: number;
553
+ /** Names enabled by the user for this asset/protocol/chain. */
554
+ pools: string[];
555
+ /** Every name shown for this asset/protocol/chain in the superset catalog. */
556
+ availablePools: string[];
557
+ };
558
+ /** The complete saved draft for the asset/chain legs selected in the deposit. */
559
+ type UserPoolSelectionRequest = {
560
+ strategies: Array<{
561
+ asset: "USDC" | "WETH";
562
+ strategy: PoolSelectionStrategy;
563
+ }>;
564
+ selections: UserPoolSelection[];
565
+ };
546
566
  /** One protocol with its pools for the deposit asset — what the Pools step
547
567
  * renders: a protocol row that opens to a list of selectable pools. */
548
568
  type PoolCatalogProtocol = {
@@ -886,16 +906,14 @@ interface IAgent {
886
906
  */
887
907
  getPoolCatalog?(params: {
888
908
  asset: string;
889
- strategy: "conservative" | "aggressive";
909
+ strategy: "conservative" | "aggressive" | "yieldmaxxing";
890
910
  }): Promise<PoolCatalogProtocol[]>;
891
911
  /**
892
912
  * Apply a user's own pool selection to their account, driven by the
893
913
  * deposit-time Pools step. Optional, and non-fatal like `applyOrgPolicy`.
894
914
  * (ROUT-569)
895
915
  */
896
- setPoolSelection?(policy: OrgPoolPolicy, opts?: {
897
- strategy?: "conservative" | "aggressive";
898
- }): Promise<void>;
916
+ setPoolSelection?(selection: UserPoolSelectionRequest): Promise<void>;
899
917
  deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
900
918
  withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string): Promise<AgentWithdrawResult>;
901
919
  getBalances(state: ConnectionState, chainId: number): Promise<AgentBalance>;
@@ -946,7 +964,7 @@ type AgentApyOptions = {
946
964
  chainId?: number;
947
965
  };
948
966
 
949
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "WALLET_NOT_DEPLOYED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "CHAIN_MISMATCH" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_BALANCE_UNAVAILABLE" | "DEPOSIT_PARTIAL_FAILURE" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_INSUFFICIENT_BALANCE" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_NOTHING_TO_WITHDRAW" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "AGENT_RATE_LIMITED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "SPONSORED_CALLS_UNSUPPORTED" | "SPONSORED_CALLS_NO_ID" | "SPONSORED_CALLS_NO_RECEIPT" | "SWAP_DISABLED" | "SWAP_RATE_LIMITED" | "SWAP_REQUEST_FAILED" | "SWAP_QUOTE_FAILED" | "SWAP_UNSUPPORTED_PAIR" | "SWAP_APPROVAL_REQUIRED" | "SWAP_BELOW_DEPOSIT_MINIMUM" | "SWAP_DEPOSIT_PENDING" | "SWAP_WALLET_PROMPT_TIMEOUT" | "SWAP_INSUFFICIENT_GAS" | "SWAP_NATIVE_UNSUPPORTED" | "SWAP_ORDER_EXPIRED" | "SWAP_ORDER_REFUNDED" | "SWAP_ORDER_CANCELLED" | "WITHDRAW_ARRIVAL_TIMEOUT" | "WITHDRAW_SWAP_FAILED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "POOL_CATALOG_UNSUPPORTED" | "POOL_SELECTION_UNSUPPORTED" | "VALIDATION_INVALID_DAYS";
967
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "WALLET_NOT_DEPLOYED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "CHAIN_MISMATCH" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_BALANCE_UNAVAILABLE" | "DEPOSIT_PARTIAL_FAILURE" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_INSUFFICIENT_BALANCE" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_NOTHING_TO_WITHDRAW" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "AGENT_RATE_LIMITED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "SPONSORED_CALLS_UNSUPPORTED" | "SPONSORED_CALLS_NO_ID" | "SPONSORED_CALLS_NO_RECEIPT" | "SWAP_DISABLED" | "SWAP_RATE_LIMITED" | "SWAP_REQUEST_FAILED" | "SWAP_QUOTE_FAILED" | "SWAP_UNSUPPORTED_PAIR" | "SWAP_APPROVAL_REQUIRED" | "SWAP_BELOW_DEPOSIT_MINIMUM" | "SWAP_DEPOSIT_PENDING" | "SWAP_WALLET_PROMPT_TIMEOUT" | "SWAP_INSUFFICIENT_GAS" | "SWAP_NATIVE_UNSUPPORTED" | "SWAP_ORDER_EXPIRED" | "SWAP_ORDER_REFUNDED" | "SWAP_ORDER_CANCELLED" | "SWAP_ORDER_NOT_FOUND" | "WITHDRAW_ARRIVAL_TIMEOUT" | "WITHDRAW_SWAP_FAILED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "POOL_CATALOG_UNSUPPORTED" | "POOL_SELECTION_UNSUPPORTED" | "VALIDATION_INVALID_DAYS";
950
968
  declare class OwneyError extends Error {
951
969
  readonly code: OwneyErrorCode;
952
970
  readonly details?: Record<string, unknown>;
@@ -1728,17 +1746,16 @@ declare class OwneySDK {
1728
1746
  */
1729
1747
  getPoolCatalog(params: {
1730
1748
  asset: OwneySupportedTokens;
1731
- strategy: "conservative" | "aggressive";
1749
+ strategy: "conservative" | "aggressive" | "yieldmaxxing";
1732
1750
  agentId?: AgentId;
1733
1751
  }): Promise<PoolCatalogProtocol[]>;
1734
1752
  /**
1735
1753
  * Apply a user's deposit-time pool selection to their account (ROUT-569).
1736
- * `strategy` is the one chosen in the deposit flow, passed through so pool
1737
- * names validate against it rather than the user's stored strategy.
1754
+ * The request carries explicit pool choices plus the resulting strategy for
1755
+ * each asset reviewed in the deposit flow.
1738
1756
  */
1739
1757
  setPoolSelection(params: {
1740
- policy: OrgPoolPolicy;
1741
- strategy?: "conservative" | "aggressive";
1758
+ selection: UserPoolSelectionRequest;
1742
1759
  agentId?: AgentId;
1743
1760
  }): Promise<void>;
1744
1761
  getAccountApy({ agentId, days, tokenSymbol, chainId: scope, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
@@ -1883,4 +1900,4 @@ type StoredOrder = {
1883
1900
  */
1884
1901
  declare function listOrders(now?: number): StoredOrder[];
1885
1902
 
1886
- export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyCoverage, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, type AvailablePool, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LookbackDays, NotConnectedError, type OrgPoolPolicy, type OrgPoolSelection, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawAllLeg, type OwneyWithdrawAllResult, type OwneyWithdrawResult, type PendingDeposit, type PoolCatalogProtocol, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, type WithdrawSwapRecord, type WithdrawSwapStatus, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };
1903
+ export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyCoverage, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, type AvailablePool, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LookbackDays, NotConnectedError, type OrgPoolPolicy, type OrgPoolSelection, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawAllLeg, type OwneyWithdrawAllResult, type OwneyWithdrawResult, type PendingDeposit, type PoolCatalogProtocol, type PoolSelectionStrategy, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type UserPoolSelection, type UserPoolSelectionRequest, type WithdrawOptions, type WithdrawSwapRecord, type WithdrawSwapStatus, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };
package/dist/index.d.ts CHANGED
@@ -543,6 +543,26 @@ type AvailablePool = {
543
543
  /** Per-pool deep link (e.g. the Morpho vault page). null when absent. */
544
544
  link: string | null;
545
545
  };
546
+ /** Public Zyfai strategies used by deposit-time pool customization. */
547
+ type PoolSelectionStrategy = "aggressive" | "yieldmaxxing";
548
+ /** One asset's explicit choice for a protocol on one chain. */
549
+ type UserPoolSelection = {
550
+ asset: "USDC" | "WETH";
551
+ protocolId: string;
552
+ chainId: number;
553
+ /** Names enabled by the user for this asset/protocol/chain. */
554
+ pools: string[];
555
+ /** Every name shown for this asset/protocol/chain in the superset catalog. */
556
+ availablePools: string[];
557
+ };
558
+ /** The complete saved draft for the asset/chain legs selected in the deposit. */
559
+ type UserPoolSelectionRequest = {
560
+ strategies: Array<{
561
+ asset: "USDC" | "WETH";
562
+ strategy: PoolSelectionStrategy;
563
+ }>;
564
+ selections: UserPoolSelection[];
565
+ };
546
566
  /** One protocol with its pools for the deposit asset — what the Pools step
547
567
  * renders: a protocol row that opens to a list of selectable pools. */
548
568
  type PoolCatalogProtocol = {
@@ -886,16 +906,14 @@ interface IAgent {
886
906
  */
887
907
  getPoolCatalog?(params: {
888
908
  asset: string;
889
- strategy: "conservative" | "aggressive";
909
+ strategy: "conservative" | "aggressive" | "yieldmaxxing";
890
910
  }): Promise<PoolCatalogProtocol[]>;
891
911
  /**
892
912
  * Apply a user's own pool selection to their account, driven by the
893
913
  * deposit-time Pools step. Optional, and non-fatal like `applyOrgPolicy`.
894
914
  * (ROUT-569)
895
915
  */
896
- setPoolSelection?(policy: OrgPoolPolicy, opts?: {
897
- strategy?: "conservative" | "aggressive";
898
- }): Promise<void>;
916
+ setPoolSelection?(selection: UserPoolSelectionRequest): Promise<void>;
899
917
  deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback): Promise<OwneyDepositResult>;
900
918
  withdraw(state: ConnectionState, chainId: number, token: OwneySupportedTokens, amount?: string): Promise<AgentWithdrawResult>;
901
919
  getBalances(state: ConnectionState, chainId: number): Promise<AgentBalance>;
@@ -946,7 +964,7 @@ type AgentApyOptions = {
946
964
  chainId?: number;
947
965
  };
948
966
 
949
- type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "WALLET_NOT_DEPLOYED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "CHAIN_MISMATCH" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_BALANCE_UNAVAILABLE" | "DEPOSIT_PARTIAL_FAILURE" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_INSUFFICIENT_BALANCE" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_NOTHING_TO_WITHDRAW" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "AGENT_RATE_LIMITED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "SPONSORED_CALLS_UNSUPPORTED" | "SPONSORED_CALLS_NO_ID" | "SPONSORED_CALLS_NO_RECEIPT" | "SWAP_DISABLED" | "SWAP_RATE_LIMITED" | "SWAP_REQUEST_FAILED" | "SWAP_QUOTE_FAILED" | "SWAP_UNSUPPORTED_PAIR" | "SWAP_APPROVAL_REQUIRED" | "SWAP_BELOW_DEPOSIT_MINIMUM" | "SWAP_DEPOSIT_PENDING" | "SWAP_WALLET_PROMPT_TIMEOUT" | "SWAP_INSUFFICIENT_GAS" | "SWAP_NATIVE_UNSUPPORTED" | "SWAP_ORDER_EXPIRED" | "SWAP_ORDER_REFUNDED" | "SWAP_ORDER_CANCELLED" | "WITHDRAW_ARRIVAL_TIMEOUT" | "WITHDRAW_SWAP_FAILED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "POOL_CATALOG_UNSUPPORTED" | "POOL_SELECTION_UNSUPPORTED" | "VALIDATION_INVALID_DAYS";
967
+ type OwneyErrorCode = "NOT_CONNECTED" | "NO_ACTIVE_CHAIN" | "WALLET_NO_ACCOUNTS" | "WALLET_ADDRESS_REQUIRED" | "WALLET_NOT_DEPLOYED" | "AGENT_NOT_FOUND" | "AGENT_CHAIN_INCOMPATIBLE" | "AGENT_EMPTY_LIST" | "AGENT_DISABLED" | "CHAIN_UNSUPPORTED" | "CHAIN_NO_COMPATIBLE_AGENTS" | "CHAIN_MISMATCH" | "ASSET_UNSUPPORTED" | "ASSET_NO_COMPATIBLE_AGENTS" | "DEPOSIT_BALANCE_UNAVAILABLE" | "DEPOSIT_PARTIAL_FAILURE" | "DEPOSIT_AMOUNT_BELOW_MINIMUM" | "DEPOSIT_CALLBACK_REQUIRED" | "DEPOSIT_CALLBACK_INVALID" | "DEPOSIT_NO_PERMITTED_TOKENS" | "DEPOSIT_INSUFFICIENT_BALANCE" | "WITHDRAW_NO_PERMITTED_TOKENS" | "WITHDRAW_INSUFFICIENT_BALANCE" | "WITHDRAW_ALL_FAILED" | "WITHDRAW_NOTHING_TO_WITHDRAW" | "WITHDRAW_PARTIAL_FAILURE" | "WITHDRAW_FAILED" | "AGENT_RATE_LIMITED" | "API_ROUTING_ERROR" | "API_ROUTING_FAILED" | "API_NO_AGENTS" | "SPONSOR_REQUEST_FAILED" | "PERMIT2_APPROVAL_REQUIRED" | "SPONSORED_CALLS_UNSUPPORTED" | "SPONSORED_CALLS_NO_ID" | "SPONSORED_CALLS_NO_RECEIPT" | "SWAP_DISABLED" | "SWAP_RATE_LIMITED" | "SWAP_REQUEST_FAILED" | "SWAP_QUOTE_FAILED" | "SWAP_UNSUPPORTED_PAIR" | "SWAP_APPROVAL_REQUIRED" | "SWAP_BELOW_DEPOSIT_MINIMUM" | "SWAP_DEPOSIT_PENDING" | "SWAP_WALLET_PROMPT_TIMEOUT" | "SWAP_INSUFFICIENT_GAS" | "SWAP_NATIVE_UNSUPPORTED" | "SWAP_ORDER_EXPIRED" | "SWAP_ORDER_REFUNDED" | "SWAP_ORDER_CANCELLED" | "SWAP_ORDER_NOT_FOUND" | "WITHDRAW_ARRIVAL_TIMEOUT" | "WITHDRAW_SWAP_FAILED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "POOL_CATALOG_UNSUPPORTED" | "POOL_SELECTION_UNSUPPORTED" | "VALIDATION_INVALID_DAYS";
950
968
  declare class OwneyError extends Error {
951
969
  readonly code: OwneyErrorCode;
952
970
  readonly details?: Record<string, unknown>;
@@ -1728,17 +1746,16 @@ declare class OwneySDK {
1728
1746
  */
1729
1747
  getPoolCatalog(params: {
1730
1748
  asset: OwneySupportedTokens;
1731
- strategy: "conservative" | "aggressive";
1749
+ strategy: "conservative" | "aggressive" | "yieldmaxxing";
1732
1750
  agentId?: AgentId;
1733
1751
  }): Promise<PoolCatalogProtocol[]>;
1734
1752
  /**
1735
1753
  * Apply a user's deposit-time pool selection to their account (ROUT-569).
1736
- * `strategy` is the one chosen in the deposit flow, passed through so pool
1737
- * names validate against it rather than the user's stored strategy.
1754
+ * The request carries explicit pool choices plus the resulting strategy for
1755
+ * each asset reviewed in the deposit flow.
1738
1756
  */
1739
1757
  setPoolSelection(params: {
1740
- policy: OrgPoolPolicy;
1741
- strategy?: "conservative" | "aggressive";
1758
+ selection: UserPoolSelectionRequest;
1742
1759
  agentId?: AgentId;
1743
1760
  }): Promise<void>;
1744
1761
  getAccountApy({ agentId, days, tokenSymbol, chainId: scope, }: AccountApyOptions): Promise<OwneyAccountApy | AccountAgentApy>;
@@ -1883,4 +1900,4 @@ type StoredOrder = {
1883
1900
  */
1884
1901
  declare function listOrders(now?: number): StoredOrder[];
1885
1902
 
1886
- export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyCoverage, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, type AvailablePool, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LookbackDays, NotConnectedError, type OrgPoolPolicy, type OrgPoolSelection, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawAllLeg, type OwneyWithdrawAllResult, type OwneyWithdrawResult, type PendingDeposit, type PoolCatalogProtocol, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, type WithdrawSwapRecord, type WithdrawSwapStatus, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };
1903
+ export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyCoverage, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, type AvailablePool, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LookbackDays, NotConnectedError, type OrgPoolPolicy, type OrgPoolSelection, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawAllLeg, type OwneyWithdrawAllResult, type OwneyWithdrawResult, type PendingDeposit, type PoolCatalogProtocol, type PoolSelectionStrategy, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type UserPoolSelection, type UserPoolSelectionRequest, type WithdrawOptions, type WithdrawSwapRecord, type WithdrawSwapStatus, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };
package/dist/index.js CHANGED
@@ -1076,6 +1076,13 @@ function protocolsPolicyNeedsUpdate(current, desiredProtocols, desiredAutoSelect
1076
1076
  if (desiredProtocols === null) return false;
1077
1077
  return !protocolListsEqual(current.protocols, desiredProtocols);
1078
1078
  }
1079
+ function mergeScopedPoolNames(current, scoped, allAvailableNames) {
1080
+ const managed = new Set(scoped.flatMap((entry) => entry.availablePools));
1081
+ const existing = current.autoselect ? allAvailableNames : current.pools;
1082
+ const preserved = existing.filter((name) => !managed.has(name));
1083
+ const selected = scoped.flatMap((entry) => entry.pools);
1084
+ return [.../* @__PURE__ */ new Set([...preserved, ...selected])];
1085
+ }
1079
1086
  function mapAvailablePools(raw) {
1080
1087
  const byChain = raw ?? {};
1081
1088
  if (typeof byChain !== "object" || byChain === null) return [];
@@ -1672,14 +1679,73 @@ var ZyfaiAgent = class _ZyfaiAgent {
1672
1679
  return assemblePoolCatalog(universe, poolsByProtocol, params.asset);
1673
1680
  }
1674
1681
  /**
1675
- * Apply a user's own pool selection (the deposit-time Pools step) to their
1676
- * Zyfai profile. Same two writes as the org path — this is `applyPoolPolicy`
1677
- * driven by the user's `policy` instead of the organization's, with the
1678
- * deposit's chosen `strategy` passed through so pool names validate against
1679
- * the strategy the user just picked rather than their stored one.
1682
+ * Persist an explicitly saved deposit-time draft at Zyfai profile level.
1683
+ * Pool choices are merged into protocol/chain records and each active asset
1684
+ * is kept at aggressive unless the draft includes a yieldmaxxing-only pool.
1680
1685
  */
1681
- async setPoolSelection(policy, opts = {}) {
1682
- await this.applyPoolPolicy(policy, opts);
1686
+ async setPoolSelection(selection) {
1687
+ try {
1688
+ const byPair = /* @__PURE__ */ new Map();
1689
+ for (const entry of selection.selections) {
1690
+ const pair = `${entry.protocolId}:${entry.chainId}`;
1691
+ const group = byPair.get(pair) ?? [];
1692
+ group.push(entry);
1693
+ byPair.set(pair, group);
1694
+ }
1695
+ const customizations = (await Promise.all(
1696
+ [...byPair.values()].map(async (scoped) => {
1697
+ const { protocolId, chainId } = scoped[0];
1698
+ try {
1699
+ const [current, rawAvailable] = await Promise.all([
1700
+ this.sdk.getSelectedPools(protocolId, chainId),
1701
+ this.sdk.getAvailablePools(protocolId, "yieldmaxxing")
1702
+ ]);
1703
+ const allAvailableNames = mapAvailablePools(rawAvailable).filter((pool) => pool.chainId === chainId).map((pool) => pool.name);
1704
+ return {
1705
+ protocolId,
1706
+ chainId,
1707
+ pools: mergeScopedPoolNames(
1708
+ {
1709
+ pools: current.pools ?? [],
1710
+ autoselect: current.autoselect
1711
+ },
1712
+ scoped,
1713
+ allAvailableNames
1714
+ ),
1715
+ // An explicit Save freezes exactly the choices the user saw.
1716
+ // This also lets an empty list disable the pair deliberately.
1717
+ autoselect: false
1718
+ };
1719
+ } catch (error) {
1720
+ console.warn(
1721
+ `[zyfai] setPoolSelection: preserving ${protocolId}/${chainId} failed; skipping the pair:`,
1722
+ error instanceof Error ? error.message : String(error)
1723
+ );
1724
+ return null;
1725
+ }
1726
+ })
1727
+ )).filter((value) => value !== null);
1728
+ if (customizations.length > 0) {
1729
+ await this.sdk.customizeBatch(customizations);
1730
+ }
1731
+ await Promise.all(
1732
+ selection.strategies.map(async ({ asset, strategy }) => {
1733
+ const current = await this.sdk.getUserDetails(asset);
1734
+ const selectedProtocols = selection.selections.filter(
1735
+ (entry) => entry.asset === asset && entry.pools.length > 0
1736
+ ).map((entry) => entry.protocolId);
1737
+ const protocols = [
1738
+ .../* @__PURE__ */ new Set([...current.protocols ?? [], ...selectedProtocols])
1739
+ ];
1740
+ await this.sdk.updateUserProfile({ asset, strategy, protocols });
1741
+ })
1742
+ );
1743
+ } catch (error) {
1744
+ console.warn(
1745
+ "[zyfai] setPoolSelection failed (non-fatal):",
1746
+ error instanceof Error ? error.message : String(error)
1747
+ );
1748
+ }
1683
1749
  }
1684
1750
  /**
1685
1751
  * True when `smartWallet` is the backend-managed pool wallet Zyfai assigned
@@ -2978,6 +3044,10 @@ var DEFAULT_POLL_MS2 = 5e3;
2978
3044
  var MAX_BACKOFF_MS = 3e4;
2979
3045
  var backoffFor = (failures, base4) => Math.min(base4 * 2 ** Math.min(failures, 5), MAX_BACKOFF_MS);
2980
3046
  var DEFAULT_TIMEOUT_MS2 = 15 * 60 * 1e3;
3047
+ var NOT_FOUND_GRACE_MS = 2 * 60 * 1e3;
3048
+ function isNotFound(error) {
3049
+ return error instanceof OwneyError && error.details?.statusCode === 404;
3050
+ }
2981
3051
  async function runFusionOrder(deps, options) {
2982
3052
  const {
2983
3053
  orderHash,
@@ -2988,6 +3058,7 @@ async function runFusionOrder(deps, options) {
2988
3058
  } = options;
2989
3059
  const deadline = deps.now() + timeoutMs;
2990
3060
  let failures = 0;
3061
+ let notFoundSince;
2991
3062
  const published = /* @__PURE__ */ new Set();
2992
3063
  onStage?.("swapping");
2993
3064
  for (; ; ) {
@@ -3029,7 +3100,20 @@ async function runFusionOrder(deps, options) {
3029
3100
  try {
3030
3101
  ({ status } = await deps.orderStatus(orderHash));
3031
3102
  failures = 0;
3032
- } catch {
3103
+ notFoundSince = void 0;
3104
+ } catch (error) {
3105
+ if (isNotFound(error)) {
3106
+ notFoundSince ??= deps.now();
3107
+ if (deps.now() - notFoundSince >= NOT_FOUND_GRACE_MS) {
3108
+ throw new OwneyError(
3109
+ "SWAP_ORDER_NOT_FOUND",
3110
+ "The swap provider has no record of this order, so nothing was exchanged.",
3111
+ { orderHash }
3112
+ );
3113
+ }
3114
+ } else {
3115
+ notFoundSince = void 0;
3116
+ }
3033
3117
  failures += 1;
3034
3118
  await deps.sleep(backoffFor(failures, pollIntervalMs));
3035
3119
  continue;
@@ -3087,9 +3171,9 @@ async function runSameChainOrder(deps, options) {
3087
3171
  for (; ; ) {
3088
3172
  if (deps.now() >= deadline) {
3089
3173
  throw new OwneyError(
3090
- "SWAP_ORDER_EXPIRED",
3091
- "No one filled the swap in time. Nothing was exchanged and your funds are still in your wallet.",
3092
- { orderHash }
3174
+ "SWAP_REQUEST_FAILED",
3175
+ "Timed out waiting for the swap to fill. It may still complete \u2014 if it does, the swapped funds will be in your wallet. Check before retrying.",
3176
+ { orderHash, settlementUnconfirmed: true }
3093
3177
  );
3094
3178
  }
3095
3179
  let status;
@@ -3437,10 +3521,16 @@ async function runFusion(deps, options, walletAddress) {
3437
3521
  debugLog("owney-sdk", "swap: awaiting signature in wallet", {
3438
3522
  signingOnChain: quote.src.chainId
3439
3523
  });
3440
- const signature = await awaitWalletPrompt(
3441
- () => deps.signTypedData(built.typedData),
3442
- "sign the swap"
3443
- );
3524
+ let signature;
3525
+ try {
3526
+ signature = await awaitWalletPrompt(
3527
+ () => deps.signTypedData(built.typedData),
3528
+ "sign the swap"
3529
+ );
3530
+ } catch (error) {
3531
+ clearOrder(built.orderHash);
3532
+ throw error;
3533
+ }
3444
3534
  debugLog("owney-sdk", "swap: signed, submitting to relayer");
3445
3535
  await deps.api.submitOrder({
3446
3536
  srcChainId: quote.src.chainId,
@@ -3468,7 +3558,7 @@ async function runFusion(deps, options, walletAddress) {
3468
3558
  ...onStage ? { onStage } : {}
3469
3559
  });
3470
3560
  } catch (error) {
3471
- if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED")) {
3561
+ if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED" || error.code === "SWAP_ORDER_NOT_FOUND")) {
3472
3562
  clearOrder(built.orderHash);
3473
3563
  }
3474
3564
  throw error;
@@ -5714,7 +5804,7 @@ var OwneySDK = class {
5714
5804
  status: "completed"
5715
5805
  });
5716
5806
  } catch (error) {
5717
- if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED")) {
5807
+ if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED" || error.code === "SWAP_ORDER_NOT_FOUND")) {
5718
5808
  clearOrder(order.orderHash);
5719
5809
  updateWithdrawSwap(order.orderHash, { status: "refunded" });
5720
5810
  } else {
@@ -6442,7 +6532,10 @@ var OwneySDK = class {
6442
6532
  agent,
6443
6533
  "dailyEarnings",
6444
6534
  () => agent.getDailyEarnings(state, legChainId, days, tokenSymbol),
6445
- { days, tokenSymbol }
6535
+ // The leg's chain must be in the key: the read key otherwise names
6536
+ // only the CONNECTION chain, so every leg shared the first leg's
6537
+ // request and the sum counted that chain once per leg. (ROUT-561)
6538
+ { days, tokenSymbol, chainId: legChainId }
6446
6539
  )
6447
6540
  )
6448
6541
  );
@@ -6506,8 +6599,8 @@ var OwneySDK = class {
6506
6599
  }
6507
6600
  /**
6508
6601
  * Apply a user's deposit-time pool selection to their account (ROUT-569).
6509
- * `strategy` is the one chosen in the deposit flow, passed through so pool
6510
- * names validate against it rather than the user's stored strategy.
6602
+ * The request carries explicit pool choices plus the resulting strategy for
6603
+ * each asset reviewed in the deposit flow.
6511
6604
  */
6512
6605
  async setPoolSelection(params) {
6513
6606
  await this.ensureAgentsInitialized();
@@ -6518,7 +6611,7 @@ var OwneySDK = class {
6518
6611
  `Agent ${agent.id} does not support pool customization`
6519
6612
  );
6520
6613
  }
6521
- await agent.setPoolSelection(params.policy, { strategy: params.strategy });
6614
+ await agent.setPoolSelection(params.selection);
6522
6615
  }
6523
6616
  async getAccountApy({
6524
6617
  agentId,
@@ -6642,7 +6735,8 @@ var OwneySDK = class {
6642
6735
  agent,
6643
6736
  "history",
6644
6737
  () => agent.getHistory(state, leg.chainId, legFilters),
6645
- legFilters
6738
+ // Keyed per leg for the same reason as getDailyEarnings' fan-out.
6739
+ { ...legFilters, chainId: leg.chainId }
6646
6740
  );
6647
6741
  return { leg, page };
6648
6742
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owney/sdk",
3
- "version": "0.7.28-beta.2",
3
+ "version": "0.7.28-beta.4",
4
4
  "type": "module",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.js",
@@ -23,7 +23,7 @@
23
23
  "test:watch": "vitest"
24
24
  },
25
25
  "dependencies": {
26
- "@zyfai/sdk": "0.2.55",
26
+ "@zyfai/sdk": "0.2.57",
27
27
  "siwe": "^3.0.0",
28
28
  "viem": "^2.48.1"
29
29
  },