@owney/sdk 0.7.26-beta.4 → 0.7.26-beta.5

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
@@ -147,12 +147,30 @@ type SwapQuote = {
147
147
  */
148
148
  permitSupported?: boolean;
149
149
  /**
150
- * True only for a cross-chain swap FROM native ETH, which needs an on-chain
151
- * order creation carrying the full amount as msg.value. The user's funds
152
- * leave the wallet before any fill, so the UI must say so. ERC-20 sources are
153
- * signature-only after their one-time approval.
150
+ * True only for a cross-chain swap FROM native ETH, which Fusion+ cannot
151
+ * take as a source: the escrow pulls the maker's funds with `transferFrom`,
152
+ * and no signature can move native value. Left unread, the order signs
153
+ * perfectly well and the relayer refuses it with a bare 502 — after the user
154
+ * has already signed (ROUT-242).
155
+ *
156
+ * So the client wraps first and swaps `wrappedNative` instead. ERC-20
157
+ * sources are signature-only after their one-time approval.
154
158
  */
155
159
  requiresOnchainOrder: boolean;
160
+ /**
161
+ * The ERC-20 the source chain's native asset wraps into. Present only
162
+ * alongside `requiresOnchainOrder`.
163
+ *
164
+ * Comes from the routing API rather than a client-side lookup because the
165
+ * wrapper cannot be derived from the symbol: "WETH" on Polygon is bridged
166
+ * Ether, an entirely different asset from wrapped POL. This address receives
167
+ * the user's whole swap amount as msg.value, so guessing it is not an option.
168
+ */
169
+ wrappedNative?: {
170
+ symbol: string;
171
+ address: string;
172
+ decimals: number;
173
+ };
156
174
  /**
157
175
  * What the swap costs, as the provider reports it on this quote.
158
176
  *
@@ -202,7 +220,7 @@ type SwapOrderStatus = "pending" | "executed" | "expired" | "cancelled" | "refun
202
220
  * of the flow and the one place a user would otherwise think nothing is
203
221
  * happening.
204
222
  */
205
- type SwapStage = "withdrawing" | "withdrawn" | "quoting" | "approving" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
223
+ type SwapStage = "withdrawing" | "withdrawn" | "quoting" | "wrapping" | "wrapped" | "approving" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
206
224
  /**
207
225
  * Which way the funds travel, which decides what each side may be.
208
226
  *
@@ -742,6 +760,68 @@ type AgentApyOptions = {
742
760
  chainId?: number;
743
761
  };
744
762
 
763
+ 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_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" | "VALIDATION_INVALID_DAYS";
764
+ declare class OwneyError extends Error {
765
+ readonly code: OwneyErrorCode;
766
+ readonly details?: Record<string, unknown>;
767
+ readonly agentId?: string;
768
+ constructor(code: OwneyErrorCode, message: string, details?: Record<string, unknown>, agentId?: string);
769
+ }
770
+ declare class AgentNotFoundError extends OwneyError {
771
+ constructor(agentId: string, available: string[]);
772
+ }
773
+ declare class NotConnectedError extends OwneyError {
774
+ constructor();
775
+ }
776
+ declare class AgentChainIncompatibleError extends OwneyError {
777
+ readonly incompatibleAgents: Array<{
778
+ agentId: string;
779
+ supportedChainIds: readonly number[];
780
+ }>;
781
+ readonly connectedChainId: number;
782
+ constructor(incompatibleAgents: Array<{
783
+ agentId: string;
784
+ supportedChainIds: readonly number[];
785
+ }>, connectedChainId: number);
786
+ }
787
+
788
+ /**
789
+ * Swaps that landed but were never deposited.
790
+ *
791
+ * `swapAndDeposit` does two things, and the deposit is the line after the
792
+ * swap. When the swap works and the deposit does not, the user is left holding
793
+ * the swapped asset with the form back on screen and nothing to say why
794
+ * (ROUT-242, comment 15980) — and the error they got said "your funds have not
795
+ * been moved", which is exactly wrong and makes a retry spend them twice.
796
+ *
797
+ * So the outcome is written down. Recovering it needs no order, no secret and
798
+ * no signature: the money is already in the wallet in the right asset, and
799
+ * what is missing is an ordinary deposit. Recording it is what lets the reload
800
+ * the user actually performs pick the job back up.
801
+ *
802
+ * Storage failures are swallowed everywhere here. Losing the note is bad;
803
+ * failing the swap because we could not write the note is worse.
804
+ */
805
+ type PendingDeposit = {
806
+ /** Stable id so a retry can clear exactly the one it handled. */
807
+ id: string;
808
+ /** What arrived, in the asset's smallest unit. */
809
+ received: string;
810
+ /** The deposit asset. */
811
+ symbol: string;
812
+ /**
813
+ * The chain the funds are ON, which for a cross-chain swap is the
814
+ * DESTINATION — depositing against the source would read an empty wallet.
815
+ */
816
+ chainId: number;
817
+ /** Narrows the deposit to one agent when the caller asked for one. */
818
+ agentId?: string;
819
+ /** Epoch ms, for the sweep. */
820
+ createdAt: number;
821
+ };
822
+ /** Every record, dismissed ones included, newest first. Sweeps as it goes. */
823
+ declare function listPendingDeposits(now?: number): PendingDeposit[];
824
+
745
825
  declare class OwneySDK {
746
826
  private agents;
747
827
  private activeAgents;
@@ -929,6 +1009,22 @@ declare class OwneySDK {
929
1009
  * network has actually changed.
930
1010
  */
931
1011
  private ensureSwapChain;
1012
+ /**
1013
+ * Turn a native-source cross-chain quote into an ERC-20 one.
1014
+ *
1015
+ * Fusion+ cannot escrow native value, so the quote arrives with
1016
+ * `requiresOnchainOrder` set and the relayer would refuse the order after
1017
+ * the user signed it (ROUT-242). Wrapping first costs one transaction and
1018
+ * puts the swap back on the ERC-20 rail that already works, rather than
1019
+ * adding a second order type that would need its own escrow handling.
1020
+ *
1021
+ * Re-quoted afterwards rather than patched: the amount wrapped may be less
1022
+ * than the amount quoted (gas has to come out of the same balance), and
1023
+ * every executor dep — allowance, permit, balances — is derived from the
1024
+ * quote's source token. A quote naming ETH would have all of them reading
1025
+ * the wrong asset.
1026
+ */
1027
+ private wrapNativeSource;
932
1028
  /**
933
1029
  * Binds the executor's abstract deps to this client's wallet.
934
1030
  *
@@ -936,6 +1032,28 @@ declare class OwneySDK {
936
1032
  * flow stays testable without a provider — the executor never imports viem.
937
1033
  */
938
1034
  private buildSwapDeps;
1035
+ /**
1036
+ * Waits until the WALLET'S OWN node reports at least `amount` of `token`.
1037
+ *
1038
+ * Separate from the swap's arrival measurement on purpose: that one runs on
1039
+ * a pinned HTTP RPC, and what matters here is the view the deposit will
1040
+ * actually use. Returns whether it got there — a courtesy, not a gate, since
1041
+ * the deposit's own check is the authority and refusing to even attempt
1042
+ * would strand funds we might have been able to move.
1043
+ */
1044
+ private walletSeesBalance;
1045
+ /**
1046
+ * Runs a quoted swap. A named seam rather than an inline `executeSwap` call
1047
+ * so the deposit half of `swapAndDeposit` can be exercised on its own.
1048
+ */
1049
+ private runSwap;
1050
+ /**
1051
+ * The half of the swap deps that only ever talks to the routing API.
1052
+ *
1053
+ * Split out because resuming an order needs exactly this and nothing else —
1054
+ * no provider, no wallet client, no chain. See `resumePendingSwaps`.
1055
+ */
1056
+ private swapRunnerDeps;
939
1057
  /**
940
1058
  * Assets the user may pay with, and what each chain deposits into.
941
1059
  *
@@ -945,6 +1063,49 @@ declare class OwneySDK {
945
1063
  getSwapTokens(): Promise<{
946
1064
  chains: SwapChainTokens[];
947
1065
  }>;
1066
+ /**
1067
+ * Swaps that landed but were never deposited, newest first.
1068
+ *
1069
+ * The money is already in the wallet in the right asset — what is missing is
1070
+ * an ordinary deposit, which is why this needs no order and no signature to
1071
+ * describe. See `completePendingDeposit`.
1072
+ */
1073
+ listPendingDeposits(): ReturnType<typeof listPendingDeposits>;
1074
+ /**
1075
+ * Deposit a swap that already landed.
1076
+ *
1077
+ * Nothing is swapped again: the funds are in the wallet, so this is the
1078
+ * second half of `swapAndDeposit` on its own. Cleared only once the deposit
1079
+ * has actually gone through — a failure here leaves the record in place so it
1080
+ * can be offered again rather than silently dropped.
1081
+ */
1082
+ completePendingDeposit(id: string): Promise<OwneyDepositResult | OwneyMultiDepositResult>;
1083
+ /**
1084
+ * Pick up cross-chain swaps a previous session left in flight.
1085
+ *
1086
+ * A Fusion+ order is only finished when the client publishes a secret for
1087
+ * each fill, once the escrows exist — so a user who closed the tab mid-swap
1088
+ * leaves an order nobody will ever complete, and it expires and refunds
1089
+ * instead of arriving. The preimages are stored for exactly this (24h sweep,
1090
+ * see the secret store); this is the other half.
1091
+ *
1092
+ * Needs NO wallet, deliberately. The signature already happened and the funds
1093
+ * are already escrowed, so finishing is pure API work — demanding a reconnect
1094
+ * first would strand the people it exists for.
1095
+ *
1096
+ * Every order is attempted even if an earlier one throws: they are unrelated
1097
+ * escrows, and one ending badly must not abandon the next one's secrets.
1098
+ * `unfinished` is not a verdict — the order may still settle, so unless the
1099
+ * chain has said refunded or cancelled its preimages are kept.
1100
+ */
1101
+ resumePendingSwaps(options?: {
1102
+ onStage?: (orderHash: string, stage: SwapStage) => void;
1103
+ timeoutMs?: number;
1104
+ }): Promise<{
1105
+ orderHash: string;
1106
+ status: "completed" | "unfinished";
1107
+ error?: OwneyError;
1108
+ }[]>;
948
1109
  /**
949
1110
  * What the wallet actually holds, across every supported chain, restricted
950
1111
  * to tokens a swap could use.
@@ -983,6 +1144,13 @@ declare class OwneySDK {
983
1144
  chainId?: number;
984
1145
  query: string;
985
1146
  limit?: number;
1147
+ /**
1148
+ * Which picker is asking. A withdrawal ends in the user's own wallet, so
1149
+ * the "is this something anyone deliberately holds" gate is theirs to
1150
+ * waive; a deposit ends in an agent and stays curated. Omit it for the
1151
+ * curated list.
1152
+ */
1153
+ direction?: SwapDirection;
986
1154
  }): Promise<{
987
1155
  tokens: SwapTokenSearchResult[];
988
1156
  }>;
@@ -1202,31 +1370,6 @@ declare class OwneySDK {
1202
1370
  getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
1203
1371
  }
1204
1372
 
1205
- 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_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_ORDER_EXPIRED" | "SWAP_ORDER_REFUNDED" | "SWAP_ORDER_CANCELLED" | "WITHDRAW_ARRIVAL_TIMEOUT" | "WITHDRAW_SWAP_FAILED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
1206
- declare class OwneyError extends Error {
1207
- readonly code: OwneyErrorCode;
1208
- readonly details?: Record<string, unknown>;
1209
- readonly agentId?: string;
1210
- constructor(code: OwneyErrorCode, message: string, details?: Record<string, unknown>, agentId?: string);
1211
- }
1212
- declare class AgentNotFoundError extends OwneyError {
1213
- constructor(agentId: string, available: string[]);
1214
- }
1215
- declare class NotConnectedError extends OwneyError {
1216
- constructor();
1217
- }
1218
- declare class AgentChainIncompatibleError extends OwneyError {
1219
- readonly incompatibleAgents: Array<{
1220
- agentId: string;
1221
- supportedChainIds: readonly number[];
1222
- }>;
1223
- readonly connectedChainId: number;
1224
- constructor(incompatibleAgents: Array<{
1225
- agentId: string;
1226
- supportedChainIds: readonly number[];
1227
- }>, connectedChainId: number);
1228
- }
1229
-
1230
1373
  declare class InvalidHistoryCursorError extends Error {
1231
1374
  readonly code: "invalid_cursor";
1232
1375
  constructor(message: string);
@@ -1304,4 +1447,4 @@ type StoredOrder = {
1304
1447
  */
1305
1448
  declare function listOrders(now?: number): StoredOrder[];
1306
1449
 
1307
- 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 ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, 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 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 OwneyWithdrawResult, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, createOwneySIWX, listOrders as listPendingSwaps, setOwneyDebug };
1450
+ 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 ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, 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 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 OwneyWithdrawResult, type PendingDeposit, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, setOwneyDebug };
package/dist/index.d.ts CHANGED
@@ -147,12 +147,30 @@ type SwapQuote = {
147
147
  */
148
148
  permitSupported?: boolean;
149
149
  /**
150
- * True only for a cross-chain swap FROM native ETH, which needs an on-chain
151
- * order creation carrying the full amount as msg.value. The user's funds
152
- * leave the wallet before any fill, so the UI must say so. ERC-20 sources are
153
- * signature-only after their one-time approval.
150
+ * True only for a cross-chain swap FROM native ETH, which Fusion+ cannot
151
+ * take as a source: the escrow pulls the maker's funds with `transferFrom`,
152
+ * and no signature can move native value. Left unread, the order signs
153
+ * perfectly well and the relayer refuses it with a bare 502 — after the user
154
+ * has already signed (ROUT-242).
155
+ *
156
+ * So the client wraps first and swaps `wrappedNative` instead. ERC-20
157
+ * sources are signature-only after their one-time approval.
154
158
  */
155
159
  requiresOnchainOrder: boolean;
160
+ /**
161
+ * The ERC-20 the source chain's native asset wraps into. Present only
162
+ * alongside `requiresOnchainOrder`.
163
+ *
164
+ * Comes from the routing API rather than a client-side lookup because the
165
+ * wrapper cannot be derived from the symbol: "WETH" on Polygon is bridged
166
+ * Ether, an entirely different asset from wrapped POL. This address receives
167
+ * the user's whole swap amount as msg.value, so guessing it is not an option.
168
+ */
169
+ wrappedNative?: {
170
+ symbol: string;
171
+ address: string;
172
+ decimals: number;
173
+ };
156
174
  /**
157
175
  * What the swap costs, as the provider reports it on this quote.
158
176
  *
@@ -202,7 +220,7 @@ type SwapOrderStatus = "pending" | "executed" | "expired" | "cancelled" | "refun
202
220
  * of the flow and the one place a user would otherwise think nothing is
203
221
  * happening.
204
222
  */
205
- type SwapStage = "withdrawing" | "withdrawn" | "quoting" | "approving" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
223
+ type SwapStage = "withdrawing" | "withdrawn" | "quoting" | "wrapping" | "wrapped" | "approving" | "signing" | "swapping" | "swapped" | "depositing" | "refunding" | "refunded";
206
224
  /**
207
225
  * Which way the funds travel, which decides what each side may be.
208
226
  *
@@ -742,6 +760,68 @@ type AgentApyOptions = {
742
760
  chainId?: number;
743
761
  };
744
762
 
763
+ 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_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" | "VALIDATION_INVALID_DAYS";
764
+ declare class OwneyError extends Error {
765
+ readonly code: OwneyErrorCode;
766
+ readonly details?: Record<string, unknown>;
767
+ readonly agentId?: string;
768
+ constructor(code: OwneyErrorCode, message: string, details?: Record<string, unknown>, agentId?: string);
769
+ }
770
+ declare class AgentNotFoundError extends OwneyError {
771
+ constructor(agentId: string, available: string[]);
772
+ }
773
+ declare class NotConnectedError extends OwneyError {
774
+ constructor();
775
+ }
776
+ declare class AgentChainIncompatibleError extends OwneyError {
777
+ readonly incompatibleAgents: Array<{
778
+ agentId: string;
779
+ supportedChainIds: readonly number[];
780
+ }>;
781
+ readonly connectedChainId: number;
782
+ constructor(incompatibleAgents: Array<{
783
+ agentId: string;
784
+ supportedChainIds: readonly number[];
785
+ }>, connectedChainId: number);
786
+ }
787
+
788
+ /**
789
+ * Swaps that landed but were never deposited.
790
+ *
791
+ * `swapAndDeposit` does two things, and the deposit is the line after the
792
+ * swap. When the swap works and the deposit does not, the user is left holding
793
+ * the swapped asset with the form back on screen and nothing to say why
794
+ * (ROUT-242, comment 15980) — and the error they got said "your funds have not
795
+ * been moved", which is exactly wrong and makes a retry spend them twice.
796
+ *
797
+ * So the outcome is written down. Recovering it needs no order, no secret and
798
+ * no signature: the money is already in the wallet in the right asset, and
799
+ * what is missing is an ordinary deposit. Recording it is what lets the reload
800
+ * the user actually performs pick the job back up.
801
+ *
802
+ * Storage failures are swallowed everywhere here. Losing the note is bad;
803
+ * failing the swap because we could not write the note is worse.
804
+ */
805
+ type PendingDeposit = {
806
+ /** Stable id so a retry can clear exactly the one it handled. */
807
+ id: string;
808
+ /** What arrived, in the asset's smallest unit. */
809
+ received: string;
810
+ /** The deposit asset. */
811
+ symbol: string;
812
+ /**
813
+ * The chain the funds are ON, which for a cross-chain swap is the
814
+ * DESTINATION — depositing against the source would read an empty wallet.
815
+ */
816
+ chainId: number;
817
+ /** Narrows the deposit to one agent when the caller asked for one. */
818
+ agentId?: string;
819
+ /** Epoch ms, for the sweep. */
820
+ createdAt: number;
821
+ };
822
+ /** Every record, dismissed ones included, newest first. Sweeps as it goes. */
823
+ declare function listPendingDeposits(now?: number): PendingDeposit[];
824
+
745
825
  declare class OwneySDK {
746
826
  private agents;
747
827
  private activeAgents;
@@ -929,6 +1009,22 @@ declare class OwneySDK {
929
1009
  * network has actually changed.
930
1010
  */
931
1011
  private ensureSwapChain;
1012
+ /**
1013
+ * Turn a native-source cross-chain quote into an ERC-20 one.
1014
+ *
1015
+ * Fusion+ cannot escrow native value, so the quote arrives with
1016
+ * `requiresOnchainOrder` set and the relayer would refuse the order after
1017
+ * the user signed it (ROUT-242). Wrapping first costs one transaction and
1018
+ * puts the swap back on the ERC-20 rail that already works, rather than
1019
+ * adding a second order type that would need its own escrow handling.
1020
+ *
1021
+ * Re-quoted afterwards rather than patched: the amount wrapped may be less
1022
+ * than the amount quoted (gas has to come out of the same balance), and
1023
+ * every executor dep — allowance, permit, balances — is derived from the
1024
+ * quote's source token. A quote naming ETH would have all of them reading
1025
+ * the wrong asset.
1026
+ */
1027
+ private wrapNativeSource;
932
1028
  /**
933
1029
  * Binds the executor's abstract deps to this client's wallet.
934
1030
  *
@@ -936,6 +1032,28 @@ declare class OwneySDK {
936
1032
  * flow stays testable without a provider — the executor never imports viem.
937
1033
  */
938
1034
  private buildSwapDeps;
1035
+ /**
1036
+ * Waits until the WALLET'S OWN node reports at least `amount` of `token`.
1037
+ *
1038
+ * Separate from the swap's arrival measurement on purpose: that one runs on
1039
+ * a pinned HTTP RPC, and what matters here is the view the deposit will
1040
+ * actually use. Returns whether it got there — a courtesy, not a gate, since
1041
+ * the deposit's own check is the authority and refusing to even attempt
1042
+ * would strand funds we might have been able to move.
1043
+ */
1044
+ private walletSeesBalance;
1045
+ /**
1046
+ * Runs a quoted swap. A named seam rather than an inline `executeSwap` call
1047
+ * so the deposit half of `swapAndDeposit` can be exercised on its own.
1048
+ */
1049
+ private runSwap;
1050
+ /**
1051
+ * The half of the swap deps that only ever talks to the routing API.
1052
+ *
1053
+ * Split out because resuming an order needs exactly this and nothing else —
1054
+ * no provider, no wallet client, no chain. See `resumePendingSwaps`.
1055
+ */
1056
+ private swapRunnerDeps;
939
1057
  /**
940
1058
  * Assets the user may pay with, and what each chain deposits into.
941
1059
  *
@@ -945,6 +1063,49 @@ declare class OwneySDK {
945
1063
  getSwapTokens(): Promise<{
946
1064
  chains: SwapChainTokens[];
947
1065
  }>;
1066
+ /**
1067
+ * Swaps that landed but were never deposited, newest first.
1068
+ *
1069
+ * The money is already in the wallet in the right asset — what is missing is
1070
+ * an ordinary deposit, which is why this needs no order and no signature to
1071
+ * describe. See `completePendingDeposit`.
1072
+ */
1073
+ listPendingDeposits(): ReturnType<typeof listPendingDeposits>;
1074
+ /**
1075
+ * Deposit a swap that already landed.
1076
+ *
1077
+ * Nothing is swapped again: the funds are in the wallet, so this is the
1078
+ * second half of `swapAndDeposit` on its own. Cleared only once the deposit
1079
+ * has actually gone through — a failure here leaves the record in place so it
1080
+ * can be offered again rather than silently dropped.
1081
+ */
1082
+ completePendingDeposit(id: string): Promise<OwneyDepositResult | OwneyMultiDepositResult>;
1083
+ /**
1084
+ * Pick up cross-chain swaps a previous session left in flight.
1085
+ *
1086
+ * A Fusion+ order is only finished when the client publishes a secret for
1087
+ * each fill, once the escrows exist — so a user who closed the tab mid-swap
1088
+ * leaves an order nobody will ever complete, and it expires and refunds
1089
+ * instead of arriving. The preimages are stored for exactly this (24h sweep,
1090
+ * see the secret store); this is the other half.
1091
+ *
1092
+ * Needs NO wallet, deliberately. The signature already happened and the funds
1093
+ * are already escrowed, so finishing is pure API work — demanding a reconnect
1094
+ * first would strand the people it exists for.
1095
+ *
1096
+ * Every order is attempted even if an earlier one throws: they are unrelated
1097
+ * escrows, and one ending badly must not abandon the next one's secrets.
1098
+ * `unfinished` is not a verdict — the order may still settle, so unless the
1099
+ * chain has said refunded or cancelled its preimages are kept.
1100
+ */
1101
+ resumePendingSwaps(options?: {
1102
+ onStage?: (orderHash: string, stage: SwapStage) => void;
1103
+ timeoutMs?: number;
1104
+ }): Promise<{
1105
+ orderHash: string;
1106
+ status: "completed" | "unfinished";
1107
+ error?: OwneyError;
1108
+ }[]>;
948
1109
  /**
949
1110
  * What the wallet actually holds, across every supported chain, restricted
950
1111
  * to tokens a swap could use.
@@ -983,6 +1144,13 @@ declare class OwneySDK {
983
1144
  chainId?: number;
984
1145
  query: string;
985
1146
  limit?: number;
1147
+ /**
1148
+ * Which picker is asking. A withdrawal ends in the user's own wallet, so
1149
+ * the "is this something anyone deliberately holds" gate is theirs to
1150
+ * waive; a deposit ends in an agent and stays curated. Omit it for the
1151
+ * curated list.
1152
+ */
1153
+ direction?: SwapDirection;
986
1154
  }): Promise<{
987
1155
  tokens: SwapTokenSearchResult[];
988
1156
  }>;
@@ -1202,31 +1370,6 @@ declare class OwneySDK {
1202
1370
  getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
1203
1371
  }
1204
1372
 
1205
- 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_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_ORDER_EXPIRED" | "SWAP_ORDER_REFUNDED" | "SWAP_ORDER_CANCELLED" | "WITHDRAW_ARRIVAL_TIMEOUT" | "WITHDRAW_SWAP_FAILED" | "BALANCE_ALL_FAILED" | "ALLOCATION_ALL_FAILED" | "VALIDATION_INVALID_DAYS";
1206
- declare class OwneyError extends Error {
1207
- readonly code: OwneyErrorCode;
1208
- readonly details?: Record<string, unknown>;
1209
- readonly agentId?: string;
1210
- constructor(code: OwneyErrorCode, message: string, details?: Record<string, unknown>, agentId?: string);
1211
- }
1212
- declare class AgentNotFoundError extends OwneyError {
1213
- constructor(agentId: string, available: string[]);
1214
- }
1215
- declare class NotConnectedError extends OwneyError {
1216
- constructor();
1217
- }
1218
- declare class AgentChainIncompatibleError extends OwneyError {
1219
- readonly incompatibleAgents: Array<{
1220
- agentId: string;
1221
- supportedChainIds: readonly number[];
1222
- }>;
1223
- readonly connectedChainId: number;
1224
- constructor(incompatibleAgents: Array<{
1225
- agentId: string;
1226
- supportedChainIds: readonly number[];
1227
- }>, connectedChainId: number);
1228
- }
1229
-
1230
1373
  declare class InvalidHistoryCursorError extends Error {
1231
1374
  readonly code: "invalid_cursor";
1232
1375
  constructor(message: string);
@@ -1304,4 +1447,4 @@ type StoredOrder = {
1304
1447
  */
1305
1448
  declare function listOrders(now?: number): StoredOrder[];
1306
1449
 
1307
- 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 ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, 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 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 OwneyWithdrawResult, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, createOwneySIWX, listOrders as listPendingSwaps, setOwneyDebug };
1450
+ 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 ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, 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 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 OwneyWithdrawResult, type PendingDeposit, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, setOwneyDebug };