@owney/sdk 0.6.9-beta.5 → 0.6.9-beta.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-PWIKIQOX.js +140 -0
- package/dist/index.cjs +770 -191
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +117 -166
- package/dist/surfliquid.agent-JOJJ3C5Y.js +448 -0
- package/package.json +3 -1
package/dist/index.d.cts
CHANGED
|
@@ -21,6 +21,16 @@ interface OwneySDKConfig {
|
|
|
21
21
|
* `createOwneySIWX` for apps that don't use the AppKit SIWX modal.
|
|
22
22
|
*/
|
|
23
23
|
referralSource?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Optional override for the SurfLiquid API base URL (defaults to the
|
|
26
|
+
* SurfLiquid SDK's production URL). SurfLiquid auth is an httpOnly
|
|
27
|
+
* SameSite=None cookie set by api.surfliquid.com — a THIRD-PARTY cookie from
|
|
28
|
+
* the embedding app's origin, which WebKit (all iOS browsers) discards, so
|
|
29
|
+
* every authenticated SurfLiquid call 401s on iOS. Point this at a
|
|
30
|
+
* same-origin reverse proxy (e.g. "/api/surf") so the session cookie becomes
|
|
31
|
+
* first-party. Relative paths resolve against the page origin.
|
|
32
|
+
*/
|
|
33
|
+
surfliquidApiBaseUrl?: string;
|
|
24
34
|
/**
|
|
25
35
|
* Turn on the SDK's debug logging (default false). Traces the decisions that
|
|
26
36
|
* are otherwise invisible — notably how the organization's agent policy is
|
|
@@ -43,7 +53,7 @@ type OwneySupportedChainId = (typeof SUPPORTED_CHAIN_IDS)[number];
|
|
|
43
53
|
type OwneySupportedChains = (typeof SUPPORTED_CHAINS)[number];
|
|
44
54
|
type OwneySupportedTokens = (typeof SUPPORTED_TOKENS)[number];
|
|
45
55
|
|
|
46
|
-
type AgentId = "zyfai" | "sail";
|
|
56
|
+
type AgentId = "zyfai" | "sail" | "surfliquid";
|
|
47
57
|
type Asset = string;
|
|
48
58
|
type AgentSupportedAsset = {
|
|
49
59
|
readonly symbol: string;
|
|
@@ -150,6 +160,12 @@ interface OwneyDepositResult {
|
|
|
150
160
|
}
|
|
151
161
|
interface OwneyMultiDepositResult {
|
|
152
162
|
agentResults: Record<string, OwneyDepositResult>;
|
|
163
|
+
/**
|
|
164
|
+
* Per-agent failure messages for agents that errored during a diversified
|
|
165
|
+
* deposit. Present only when at least one (but not all) agents failed —
|
|
166
|
+
* the deposit is partial, not total. Omitted when every agent succeeded.
|
|
167
|
+
*/
|
|
168
|
+
agentErrors?: Record<string, string>;
|
|
153
169
|
}
|
|
154
170
|
interface AgentWithdrawResult {
|
|
155
171
|
txHash?: string;
|
|
@@ -391,6 +407,7 @@ declare class OwneySDK {
|
|
|
391
407
|
private zyfaiRpcUrls?;
|
|
392
408
|
private routingApiBaseUrl?;
|
|
393
409
|
private referralSource?;
|
|
410
|
+
private surfliquidApiBaseUrl?;
|
|
394
411
|
private cachedSponsoredCallback;
|
|
395
412
|
private cachedWethSponsoredCallback;
|
|
396
413
|
private initializingAgentsPromise;
|
|
@@ -514,6 +531,17 @@ declare class OwneySDK {
|
|
|
514
531
|
private hasExistingBalance;
|
|
515
532
|
private validateAssetSupport;
|
|
516
533
|
private getEligibleAgents;
|
|
534
|
+
/**
|
|
535
|
+
* Agent ids the routing API provisioned for this org that support the given
|
|
536
|
+
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
537
|
+
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
538
|
+
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
539
|
+
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
540
|
+
*
|
|
541
|
+
* This is the source of truth for agent availability: an agent appears here
|
|
542
|
+
* iff the routing API returned its key. No per-app feature flags.
|
|
543
|
+
*/
|
|
544
|
+
getEligibleAgentIds(chainId: number, asset: string): Promise<AgentId[]>;
|
|
517
545
|
/**
|
|
518
546
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
519
547
|
* Validates that the asset is supported by the target agent(s) on the active chain.
|
|
@@ -609,7 +637,7 @@ declare class OwneySDK {
|
|
|
609
637
|
getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
|
|
610
638
|
}
|
|
611
639
|
|
|
612
|
-
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_INSUFFICIENT_BALANCE" | "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";
|
|
640
|
+
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" | "DEPOSIT_INSUFFICIENT_BALANCE" | "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";
|
|
613
641
|
declare class OwneyError extends Error {
|
|
614
642
|
readonly code: OwneyErrorCode;
|
|
615
643
|
readonly details?: Record<string, unknown>;
|
package/dist/index.d.ts
CHANGED
|
@@ -21,6 +21,16 @@ interface OwneySDKConfig {
|
|
|
21
21
|
* `createOwneySIWX` for apps that don't use the AppKit SIWX modal.
|
|
22
22
|
*/
|
|
23
23
|
referralSource?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Optional override for the SurfLiquid API base URL (defaults to the
|
|
26
|
+
* SurfLiquid SDK's production URL). SurfLiquid auth is an httpOnly
|
|
27
|
+
* SameSite=None cookie set by api.surfliquid.com — a THIRD-PARTY cookie from
|
|
28
|
+
* the embedding app's origin, which WebKit (all iOS browsers) discards, so
|
|
29
|
+
* every authenticated SurfLiquid call 401s on iOS. Point this at a
|
|
30
|
+
* same-origin reverse proxy (e.g. "/api/surf") so the session cookie becomes
|
|
31
|
+
* first-party. Relative paths resolve against the page origin.
|
|
32
|
+
*/
|
|
33
|
+
surfliquidApiBaseUrl?: string;
|
|
24
34
|
/**
|
|
25
35
|
* Turn on the SDK's debug logging (default false). Traces the decisions that
|
|
26
36
|
* are otherwise invisible — notably how the organization's agent policy is
|
|
@@ -43,7 +53,7 @@ type OwneySupportedChainId = (typeof SUPPORTED_CHAIN_IDS)[number];
|
|
|
43
53
|
type OwneySupportedChains = (typeof SUPPORTED_CHAINS)[number];
|
|
44
54
|
type OwneySupportedTokens = (typeof SUPPORTED_TOKENS)[number];
|
|
45
55
|
|
|
46
|
-
type AgentId = "zyfai" | "sail";
|
|
56
|
+
type AgentId = "zyfai" | "sail" | "surfliquid";
|
|
47
57
|
type Asset = string;
|
|
48
58
|
type AgentSupportedAsset = {
|
|
49
59
|
readonly symbol: string;
|
|
@@ -150,6 +160,12 @@ interface OwneyDepositResult {
|
|
|
150
160
|
}
|
|
151
161
|
interface OwneyMultiDepositResult {
|
|
152
162
|
agentResults: Record<string, OwneyDepositResult>;
|
|
163
|
+
/**
|
|
164
|
+
* Per-agent failure messages for agents that errored during a diversified
|
|
165
|
+
* deposit. Present only when at least one (but not all) agents failed —
|
|
166
|
+
* the deposit is partial, not total. Omitted when every agent succeeded.
|
|
167
|
+
*/
|
|
168
|
+
agentErrors?: Record<string, string>;
|
|
153
169
|
}
|
|
154
170
|
interface AgentWithdrawResult {
|
|
155
171
|
txHash?: string;
|
|
@@ -391,6 +407,7 @@ declare class OwneySDK {
|
|
|
391
407
|
private zyfaiRpcUrls?;
|
|
392
408
|
private routingApiBaseUrl?;
|
|
393
409
|
private referralSource?;
|
|
410
|
+
private surfliquidApiBaseUrl?;
|
|
394
411
|
private cachedSponsoredCallback;
|
|
395
412
|
private cachedWethSponsoredCallback;
|
|
396
413
|
private initializingAgentsPromise;
|
|
@@ -514,6 +531,17 @@ declare class OwneySDK {
|
|
|
514
531
|
private hasExistingBalance;
|
|
515
532
|
private validateAssetSupport;
|
|
516
533
|
private getEligibleAgents;
|
|
534
|
+
/**
|
|
535
|
+
* Agent ids the routing API provisioned for this org that support the given
|
|
536
|
+
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
537
|
+
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
538
|
+
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
539
|
+
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
540
|
+
*
|
|
541
|
+
* This is the source of truth for agent availability: an agent appears here
|
|
542
|
+
* iff the routing API returned its key. No per-app feature flags.
|
|
543
|
+
*/
|
|
544
|
+
getEligibleAgentIds(chainId: number, asset: string): Promise<AgentId[]>;
|
|
517
545
|
/**
|
|
518
546
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
519
547
|
* Validates that the asset is supported by the target agent(s) on the active chain.
|
|
@@ -609,7 +637,7 @@ declare class OwneySDK {
|
|
|
609
637
|
getAllocationApy({ agentId, }?: AllocationApyOptions): Promise<OwneyAllocationApy>;
|
|
610
638
|
}
|
|
611
639
|
|
|
612
|
-
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_INSUFFICIENT_BALANCE" | "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";
|
|
640
|
+
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" | "DEPOSIT_INSUFFICIENT_BALANCE" | "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";
|
|
613
641
|
declare class OwneyError extends Error {
|
|
614
642
|
readonly code: OwneyErrorCode;
|
|
615
643
|
readonly details?: Record<string, unknown>;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
AgentChainIncompatibleError,
|
|
3
|
+
AgentNotFoundError,
|
|
4
|
+
ERC20_ALLOWANCE_ABI,
|
|
5
|
+
MAX_UINT256,
|
|
6
|
+
NotConnectedError,
|
|
7
|
+
OwneyError,
|
|
8
|
+
PERMIT2_ADDRESS,
|
|
9
|
+
buildPermitTransferFromTypedData,
|
|
10
|
+
randomPermit2Nonce,
|
|
11
|
+
readErc20Balance,
|
|
12
|
+
readPermit2Allowance
|
|
13
|
+
} from "./chunk-PWIKIQOX.js";
|
|
14
|
+
|
|
1
15
|
// src/agents/zyfai/zyfai.agent.ts
|
|
2
16
|
import { ZyfaiSDK } from "@zyfai/sdk";
|
|
3
17
|
import { createPublicClient, http } from "viem";
|
|
@@ -56,55 +70,6 @@ var SupportedAssets = [
|
|
|
56
70
|
}
|
|
57
71
|
];
|
|
58
72
|
|
|
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
|
-
|
|
108
73
|
// src/lib/utils.ts
|
|
109
74
|
var isValidChainId = (chainId) => {
|
|
110
75
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
@@ -179,46 +144,46 @@ function resolveChainId(chain) {
|
|
|
179
144
|
function mapBalances(raw, _chainId, smartWallet) {
|
|
180
145
|
const portfolio = raw.portfolio;
|
|
181
146
|
const portfolioByChain = portfolio.portfolioByChain ?? {};
|
|
147
|
+
const rawPositions = portfolio.positions ?? [];
|
|
148
|
+
const detailByKey = /* @__PURE__ */ new Map();
|
|
149
|
+
for (const p of rawPositions) {
|
|
150
|
+
const cid = resolveChainId(p.chain ?? "");
|
|
151
|
+
const symbol = (p.token_symbol ?? "").toUpperCase();
|
|
152
|
+
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
153
|
+
}
|
|
182
154
|
let totalBalance = 0;
|
|
183
155
|
const tokens = [];
|
|
156
|
+
const positions = [];
|
|
184
157
|
for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
|
|
185
158
|
const positionChainId = Number(chainIdKey);
|
|
159
|
+
const chainName = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
|
|
186
160
|
for (const [symbol, { balance, decimals }] of Object.entries(
|
|
187
161
|
tokensBySymbol ?? {}
|
|
188
162
|
)) {
|
|
189
|
-
const amount = hexToDecimal(balance || "0", decimals);
|
|
163
|
+
const amount = hexToDecimal(balance || "0", tokenDecimals(symbol, decimals));
|
|
190
164
|
totalBalance += amount;
|
|
191
165
|
tokens.push({
|
|
192
|
-
chain:
|
|
166
|
+
chain: chainName,
|
|
193
167
|
chainId: positionChainId,
|
|
194
168
|
asset: symbol,
|
|
195
169
|
amount: String(amount)
|
|
196
170
|
});
|
|
171
|
+
const detail = detailByKey.get(`${positionChainId}:${symbol.toUpperCase()}`);
|
|
172
|
+
positions.push({
|
|
173
|
+
chain: chainName,
|
|
174
|
+
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
175
|
+
protocolId: detail?.protocol_id,
|
|
176
|
+
pool: detail?.pool,
|
|
177
|
+
asset: symbol,
|
|
178
|
+
amount: String(amount),
|
|
179
|
+
apy: detail?.pool_apy,
|
|
180
|
+
tvl: detail?.pool_tvl,
|
|
181
|
+
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
182
|
+
// structural read keeps it undefined today and auto-populates later.
|
|
183
|
+
liquidity: detail?.liquidity
|
|
184
|
+
});
|
|
197
185
|
}
|
|
198
186
|
}
|
|
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
|
-
}));
|
|
222
187
|
return {
|
|
223
188
|
smartWallet,
|
|
224
189
|
totalBalance: String(totalBalance),
|
|
@@ -1856,84 +1821,6 @@ async function getSponsorRelayerAddress(input) {
|
|
|
1856
1821
|
return parsed.data.relayer;
|
|
1857
1822
|
}
|
|
1858
1823
|
|
|
1859
|
-
// src/lib/permit2.ts
|
|
1860
|
-
import { bytesToHex as bytesToHex2 } from "viem";
|
|
1861
|
-
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
1862
|
-
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
1863
|
-
var ERC20_ALLOWANCE_ABI = [
|
|
1864
|
-
{
|
|
1865
|
-
type: "function",
|
|
1866
|
-
name: "allowance",
|
|
1867
|
-
stateMutability: "view",
|
|
1868
|
-
inputs: [
|
|
1869
|
-
{ name: "owner", type: "address" },
|
|
1870
|
-
{ name: "spender", type: "address" }
|
|
1871
|
-
],
|
|
1872
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
1873
|
-
},
|
|
1874
|
-
{
|
|
1875
|
-
type: "function",
|
|
1876
|
-
name: "approve",
|
|
1877
|
-
stateMutability: "nonpayable",
|
|
1878
|
-
inputs: [
|
|
1879
|
-
{ name: "spender", type: "address" },
|
|
1880
|
-
{ name: "amount", type: "uint256" }
|
|
1881
|
-
],
|
|
1882
|
-
outputs: [{ name: "", type: "bool" }]
|
|
1883
|
-
},
|
|
1884
|
-
{
|
|
1885
|
-
type: "function",
|
|
1886
|
-
name: "balanceOf",
|
|
1887
|
-
stateMutability: "view",
|
|
1888
|
-
inputs: [{ name: "account", type: "address" }],
|
|
1889
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
1890
|
-
}
|
|
1891
|
-
];
|
|
1892
|
-
function buildPermitTransferFromTypedData(input) {
|
|
1893
|
-
return {
|
|
1894
|
-
domain: {
|
|
1895
|
-
name: "Permit2",
|
|
1896
|
-
chainId: input.chainId,
|
|
1897
|
-
verifyingContract: PERMIT2_ADDRESS
|
|
1898
|
-
},
|
|
1899
|
-
types: {
|
|
1900
|
-
PermitTransferFrom: [
|
|
1901
|
-
{ name: "permitted", type: "TokenPermissions" },
|
|
1902
|
-
{ name: "spender", type: "address" },
|
|
1903
|
-
{ name: "nonce", type: "uint256" },
|
|
1904
|
-
{ name: "deadline", type: "uint256" }
|
|
1905
|
-
],
|
|
1906
|
-
TokenPermissions: [
|
|
1907
|
-
{ name: "token", type: "address" },
|
|
1908
|
-
{ name: "amount", type: "uint256" }
|
|
1909
|
-
]
|
|
1910
|
-
},
|
|
1911
|
-
primaryType: "PermitTransferFrom",
|
|
1912
|
-
message: input.message
|
|
1913
|
-
};
|
|
1914
|
-
}
|
|
1915
|
-
function randomPermit2Nonce() {
|
|
1916
|
-
const bytes = new Uint8Array(32);
|
|
1917
|
-
globalThis.crypto.getRandomValues(bytes);
|
|
1918
|
-
return BigInt(bytesToHex2(bytes));
|
|
1919
|
-
}
|
|
1920
|
-
async function readPermit2Allowance(publicClient, token, owner) {
|
|
1921
|
-
return publicClient.readContract({
|
|
1922
|
-
address: token,
|
|
1923
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
1924
|
-
functionName: "allowance",
|
|
1925
|
-
args: [owner, PERMIT2_ADDRESS]
|
|
1926
|
-
});
|
|
1927
|
-
}
|
|
1928
|
-
async function readErc20Balance(publicClient, token, owner) {
|
|
1929
|
-
return publicClient.readContract({
|
|
1930
|
-
address: token,
|
|
1931
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
1932
|
-
functionName: "balanceOf",
|
|
1933
|
-
args: [owner]
|
|
1934
|
-
});
|
|
1935
|
-
}
|
|
1936
|
-
|
|
1937
1824
|
// src/lib/sponsored-deposit.ts
|
|
1938
1825
|
var AUTH_WINDOW_SECONDS = 15 * 60;
|
|
1939
1826
|
function makeSponsoredDepositCallback(deps) {
|
|
@@ -2116,6 +2003,7 @@ var VIEM_CHAIN2 = {
|
|
|
2116
2003
|
42161: arbitrum2,
|
|
2117
2004
|
1: mainnet2
|
|
2118
2005
|
};
|
|
2006
|
+
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
2119
2007
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
2120
2008
|
8453: "0x4200000000000000000000000000000000000006",
|
|
2121
2009
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -2144,6 +2032,7 @@ var OwneySDK = class {
|
|
|
2144
2032
|
zyfaiRpcUrls;
|
|
2145
2033
|
routingApiBaseUrl;
|
|
2146
2034
|
referralSource;
|
|
2035
|
+
surfliquidApiBaseUrl;
|
|
2147
2036
|
cachedSponsoredCallback = null;
|
|
2148
2037
|
cachedWethSponsoredCallback = null;
|
|
2149
2038
|
initializingAgentsPromise = null;
|
|
@@ -2153,6 +2042,7 @@ var OwneySDK = class {
|
|
|
2153
2042
|
this.zyfaiRpcUrls = config.zyfaiRpcUrls;
|
|
2154
2043
|
this.routingApiBaseUrl = config.routingApiBaseUrl;
|
|
2155
2044
|
this.referralSource = config.referralSource;
|
|
2045
|
+
this.surfliquidApiBaseUrl = config.surfliquidApiBaseUrl;
|
|
2156
2046
|
}
|
|
2157
2047
|
/**
|
|
2158
2048
|
* Establish connection state for all subsequent SDK calls.
|
|
@@ -2360,8 +2250,8 @@ var OwneySDK = class {
|
|
|
2360
2250
|
this.initializingAgentsPromise = (async () => {
|
|
2361
2251
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
2362
2252
|
this.disabledAgents.clear();
|
|
2363
|
-
for (const { key: key2, agent_type, is_enabled } of agentKeys) {
|
|
2364
|
-
const agent = this.createAgent(agent_type, key2);
|
|
2253
|
+
for (const { key: key2, agent_type, project_name, is_enabled } of agentKeys) {
|
|
2254
|
+
const agent = await this.createAgent(agent_type, key2, project_name);
|
|
2365
2255
|
if (!agent) continue;
|
|
2366
2256
|
this.agents.set(agent_type, agent);
|
|
2367
2257
|
if (is_enabled === false) {
|
|
@@ -2382,10 +2272,22 @@ var OwneySDK = class {
|
|
|
2382
2272
|
this.initializingAgentsPromise = null;
|
|
2383
2273
|
}
|
|
2384
2274
|
}
|
|
2385
|
-
createAgent(agentId, key2) {
|
|
2275
|
+
async createAgent(agentId, key2, projectName) {
|
|
2386
2276
|
if (agentId === "zyfai") {
|
|
2387
2277
|
return new ZyfaiAgent(key2, this.zyfaiRpcUrls, this.referralSource);
|
|
2388
2278
|
}
|
|
2279
|
+
if (agentId === "surfliquid") {
|
|
2280
|
+
if (!projectName) return null;
|
|
2281
|
+
const { SurfLiquidAgent } = await import("./surfliquid.agent-JOJJ3C5Y.js");
|
|
2282
|
+
return new SurfLiquidAgent({
|
|
2283
|
+
projectName,
|
|
2284
|
+
appId: key2,
|
|
2285
|
+
// Same-origin proxy override — SurfLiquid auth is an httpOnly cookie,
|
|
2286
|
+
// which WebKit (iOS) discards when it is third-party. See
|
|
2287
|
+
// OwneySDKConfig.surfliquidApiBaseUrl.
|
|
2288
|
+
apiBaseUrl: this.surfliquidApiBaseUrl
|
|
2289
|
+
});
|
|
2290
|
+
}
|
|
2389
2291
|
return null;
|
|
2390
2292
|
}
|
|
2391
2293
|
// --- Account lifecycle ---
|
|
@@ -2540,18 +2442,30 @@ var OwneySDK = class {
|
|
|
2540
2442
|
);
|
|
2541
2443
|
}
|
|
2542
2444
|
const agentResults = {};
|
|
2445
|
+
const agentErrors = {};
|
|
2543
2446
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
2544
|
-
|
|
2545
|
-
agent
|
|
2546
|
-
|
|
2547
|
-
|
|
2548
|
-
|
|
2549
|
-
|
|
2550
|
-
|
|
2551
|
-
|
|
2447
|
+
try {
|
|
2448
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
2449
|
+
agent,
|
|
2450
|
+
state,
|
|
2451
|
+
chainId,
|
|
2452
|
+
agentAmount,
|
|
2453
|
+
asset,
|
|
2454
|
+
effectiveCallback,
|
|
2455
|
+
depositCallback
|
|
2456
|
+
);
|
|
2457
|
+
} catch (error) {
|
|
2458
|
+
agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
|
|
2459
|
+
}
|
|
2460
|
+
}
|
|
2461
|
+
if (Object.keys(agentResults).length === 0) {
|
|
2462
|
+
throw new OwneyError(
|
|
2463
|
+
"DEPOSIT_ALL_FAILED",
|
|
2464
|
+
`All ${agentAmounts.length} agent deposit(s) failed.`,
|
|
2465
|
+
{ agentErrors }
|
|
2552
2466
|
);
|
|
2553
2467
|
}
|
|
2554
|
-
return { agentResults };
|
|
2468
|
+
return Object.keys(agentErrors).length > 0 ? { agentResults, agentErrors } : { agentResults };
|
|
2555
2469
|
}
|
|
2556
2470
|
/**
|
|
2557
2471
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -2708,6 +2622,34 @@ var OwneySDK = class {
|
|
|
2708
2622
|
}
|
|
2709
2623
|
return eligible;
|
|
2710
2624
|
}
|
|
2625
|
+
/**
|
|
2626
|
+
* Agent ids the routing API provisioned for this org that support the given
|
|
2627
|
+
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
2628
|
+
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
2629
|
+
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
2630
|
+
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
2631
|
+
*
|
|
2632
|
+
* This is the source of truth for agent availability: an agent appears here
|
|
2633
|
+
* iff the routing API returned its key. No per-app feature flags.
|
|
2634
|
+
*/
|
|
2635
|
+
async getEligibleAgentIds(chainId, asset) {
|
|
2636
|
+
try {
|
|
2637
|
+
await this.ensureAgentsInitialized();
|
|
2638
|
+
} catch (error) {
|
|
2639
|
+
if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
|
|
2640
|
+
return [];
|
|
2641
|
+
}
|
|
2642
|
+
throw error;
|
|
2643
|
+
}
|
|
2644
|
+
return [...this.agents.values()].filter((agent) => {
|
|
2645
|
+
const chainAssets = agent.supportedAssets.find(
|
|
2646
|
+
(sa) => sa.chainId === chainId
|
|
2647
|
+
);
|
|
2648
|
+
return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
|
|
2649
|
+
}).map((agent) => agent.id).sort(
|
|
2650
|
+
(a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
|
|
2651
|
+
);
|
|
2652
|
+
}
|
|
2711
2653
|
// --- Fund operations ---
|
|
2712
2654
|
/**
|
|
2713
2655
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -2743,9 +2685,17 @@ var OwneySDK = class {
|
|
|
2743
2685
|
}
|
|
2744
2686
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
2745
2687
|
if (!amount) {
|
|
2688
|
+
const aggregated2 = await this.getBalances();
|
|
2689
|
+
const funded = projectAgentBalancesForAsset(
|
|
2690
|
+
eligibleAgents,
|
|
2691
|
+
aggregated2.agentBalances,
|
|
2692
|
+
chainId,
|
|
2693
|
+
asset,
|
|
2694
|
+
assetInfo.decimals
|
|
2695
|
+
).filter((b) => b.balance > 0n);
|
|
2746
2696
|
const results2 = {};
|
|
2747
2697
|
const agentErrors2 = {};
|
|
2748
|
-
for (const agent of
|
|
2698
|
+
for (const { agent } of funded) {
|
|
2749
2699
|
try {
|
|
2750
2700
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
2751
2701
|
} catch (err) {
|
|
@@ -2762,9 +2712,10 @@ var OwneySDK = class {
|
|
|
2762
2712
|
{ asset, agentErrors: agentErrors2 }
|
|
2763
2713
|
);
|
|
2764
2714
|
}
|
|
2715
|
+
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
2765
2716
|
return {
|
|
2766
2717
|
agentResult: results2,
|
|
2767
|
-
totalWithdrawn:
|
|
2718
|
+
totalWithdrawn: totalWithdrawn.toString()
|
|
2768
2719
|
};
|
|
2769
2720
|
}
|
|
2770
2721
|
const requested = BigInt(amount);
|