@owney/sdk 0.7.12-beta.1 → 0.7.12-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +213 -892
- package/dist/index.d.cts +5 -33
- package/dist/index.d.ts +5 -33
- package/dist/index.js +189 -211
- package/package.json +1 -3
- package/dist/chunk-PWIKIQOX.js +0 -140
- package/dist/surfliquid.agent-VNGQUSXN.js +0 -473
package/dist/index.js
CHANGED
|
@@ -1,17 +1,3 @@
|
|
|
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
|
-
|
|
15
1
|
// src/agents/zyfai/zyfai.agent.ts
|
|
16
2
|
import { SMART_SESSIONS_VALIDATOR, ZyfaiSDK } from "@zyfai/sdk";
|
|
17
3
|
import { createPublicClient, http, parseAbi } from "viem";
|
|
@@ -70,6 +56,55 @@ var SupportedAssets = [
|
|
|
70
56
|
}
|
|
71
57
|
];
|
|
72
58
|
|
|
59
|
+
// src/errors.ts
|
|
60
|
+
var OwneyError = class extends Error {
|
|
61
|
+
code;
|
|
62
|
+
details;
|
|
63
|
+
agentId;
|
|
64
|
+
constructor(code, message, details, agentId) {
|
|
65
|
+
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
66
|
+
super(`${prefix} ${message}`);
|
|
67
|
+
this.name = "OwneyError";
|
|
68
|
+
this.code = code;
|
|
69
|
+
this.details = details;
|
|
70
|
+
this.agentId = agentId;
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
var AgentNotFoundError = class extends OwneyError {
|
|
74
|
+
constructor(agentId, available) {
|
|
75
|
+
super(
|
|
76
|
+
"AGENT_NOT_FOUND",
|
|
77
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
78
|
+
{ agentId, available },
|
|
79
|
+
agentId
|
|
80
|
+
);
|
|
81
|
+
this.name = "AgentNotFoundError";
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
var NotConnectedError = class extends OwneyError {
|
|
85
|
+
constructor() {
|
|
86
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
87
|
+
this.name = "NotConnectedError";
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var AgentChainIncompatibleError = class extends OwneyError {
|
|
91
|
+
incompatibleAgents;
|
|
92
|
+
connectedChainId;
|
|
93
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
94
|
+
const details = incompatibleAgents.map(
|
|
95
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
96
|
+
).join("; ");
|
|
97
|
+
super(
|
|
98
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
99
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
100
|
+
{ incompatibleAgents, connectedChainId }
|
|
101
|
+
);
|
|
102
|
+
this.name = "AgentChainIncompatibleError";
|
|
103
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
104
|
+
this.connectedChainId = connectedChainId;
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
|
|
73
108
|
// src/lib/utils.ts
|
|
74
109
|
var isValidChainId = (chainId) => {
|
|
75
110
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
@@ -81,12 +116,6 @@ var isValidChainId = (chainId) => {
|
|
|
81
116
|
}
|
|
82
117
|
return chainId;
|
|
83
118
|
};
|
|
84
|
-
function isSameAsset(tokenSymbol, asset) {
|
|
85
|
-
const token = tokenSymbol.toLowerCase();
|
|
86
|
-
const target = asset.toLowerCase();
|
|
87
|
-
if (token === target) return true;
|
|
88
|
-
return target === "weth" && token === "eth" || target === "eth" && token === "weth";
|
|
89
|
-
}
|
|
90
119
|
function hexToDecimal(hex, decimals = 6) {
|
|
91
120
|
const normalized = hex.startsWith("0x") || hex.startsWith("0X") ? hex : `0x${hex}`;
|
|
92
121
|
const parsed = BigInt(normalized);
|
|
@@ -120,10 +149,6 @@ var DECIMALS_BY_SYMBOL = {
|
|
|
120
149
|
wbtc: 8,
|
|
121
150
|
cbbtc: 8
|
|
122
151
|
};
|
|
123
|
-
function canonicalSymbol(symbol) {
|
|
124
|
-
const upper = symbol.toUpperCase();
|
|
125
|
-
return upper === "ETH" ? "WETH" : upper;
|
|
126
|
-
}
|
|
127
152
|
function tokenDecimals(symbol, explicit) {
|
|
128
153
|
if (typeof explicit === "number" && Number.isFinite(explicit))
|
|
129
154
|
return explicit;
|
|
@@ -188,89 +213,55 @@ function mapPendingAllocations(raw) {
|
|
|
188
213
|
function mapBalances(raw, _chainId, smartWallet) {
|
|
189
214
|
const portfolio = raw.portfolio;
|
|
190
215
|
const portfolioByChain = portfolio.portfolioByChain ?? {};
|
|
191
|
-
const rawPositions = portfolio.positions ?? [];
|
|
192
|
-
const detailByKey = /* @__PURE__ */ new Map();
|
|
193
|
-
for (const p of rawPositions) {
|
|
194
|
-
const cid = resolveChainId(p.chain ?? "");
|
|
195
|
-
const symbol = canonicalSymbol(p.token_symbol ?? "");
|
|
196
|
-
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
197
|
-
}
|
|
198
216
|
let totalBalance = 0;
|
|
199
217
|
const tokens = [];
|
|
200
|
-
const positions = [];
|
|
201
218
|
for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
|
|
202
219
|
const positionChainId = Number(chainIdKey);
|
|
203
|
-
const chainName2 = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
|
|
204
220
|
for (const [
|
|
205
221
|
symbol,
|
|
206
222
|
{ balance, balanceWithFee, decimals }
|
|
207
223
|
] of Object.entries(tokensBySymbol ?? {})) {
|
|
208
|
-
const amount = hexToDecimal(
|
|
209
|
-
balanceWithFee ?? balance ?? "0",
|
|
210
|
-
tokenDecimals(symbol, decimals)
|
|
211
|
-
);
|
|
224
|
+
const amount = hexToDecimal(balanceWithFee ?? balance ?? "0", decimals);
|
|
212
225
|
totalBalance += amount;
|
|
213
226
|
tokens.push({
|
|
214
|
-
chain:
|
|
227
|
+
chain: CHAIN_ID_TO_NAME[positionChainId] ?? "BASE",
|
|
215
228
|
chainId: positionChainId,
|
|
216
229
|
asset: symbol,
|
|
217
230
|
amount: String(amount)
|
|
218
231
|
});
|
|
219
|
-
const detail = detailByKey.get(
|
|
220
|
-
`${positionChainId}:${canonicalSymbol(symbol)}`
|
|
221
|
-
);
|
|
222
|
-
positions.push({
|
|
223
|
-
chain: chainName2,
|
|
224
|
-
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
225
|
-
protocolId: detail?.protocol_id,
|
|
226
|
-
pool: detail?.pool,
|
|
227
|
-
// Report the token the way the rest of owney spells it ("WETH", as the
|
|
228
|
-
// pre-portfolioByChain mapper did), not Zyfai's internal "eth".
|
|
229
|
-
asset: canonicalSymbol(symbol),
|
|
230
|
-
amount: String(amount),
|
|
231
|
-
apy: detail?.pool_apy,
|
|
232
|
-
tvl: detail?.pool_tvl,
|
|
233
|
-
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
234
|
-
// structural read keeps it undefined today and auto-populates later.
|
|
235
|
-
liquidity: detail?.liquidity
|
|
236
|
-
});
|
|
237
232
|
}
|
|
238
233
|
}
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
liquidity: p.liquidity
|
|
271
|
-
}))
|
|
272
|
-
);
|
|
273
|
-
}
|
|
234
|
+
const positions = (portfolio.positions ?? []).map((p) => ({
|
|
235
|
+
chain: p.chain ?? "",
|
|
236
|
+
protocol: p.protocol_name ?? p.protocol_id ?? "",
|
|
237
|
+
protocolId: p.protocol_id,
|
|
238
|
+
pool: p.pool,
|
|
239
|
+
asset: p.token_symbol ?? "",
|
|
240
|
+
// Fee-adjusted underlying amounts are decimal base-unit strings. The
|
|
241
|
+
// legacy `amount` fallback is hex. Runtime
|
|
242
|
+
// getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
|
|
243
|
+
// when present, otherwise fall back to the per-symbol lookup.
|
|
244
|
+
amount: String(
|
|
245
|
+
p.underlyingAmountWithFee ?? p.underlyingAmount ? normalizeDecimalPlace(
|
|
246
|
+
p.underlyingAmountWithFee ?? p.underlyingAmount ?? "0",
|
|
247
|
+
tokenDecimals(
|
|
248
|
+
p.token_symbol,
|
|
249
|
+
p.decimals
|
|
250
|
+
)
|
|
251
|
+
) : hexToDecimal(
|
|
252
|
+
p.amount || "0",
|
|
253
|
+
tokenDecimals(
|
|
254
|
+
p.token_symbol,
|
|
255
|
+
p.decimals
|
|
256
|
+
)
|
|
257
|
+
)
|
|
258
|
+
),
|
|
259
|
+
apy: p.pool_apy,
|
|
260
|
+
tvl: p.pool_tvl,
|
|
261
|
+
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
262
|
+
// structural read keeps it undefined today and auto-populates later.
|
|
263
|
+
liquidity: p.liquidity
|
|
264
|
+
}));
|
|
274
265
|
const pendingAllocations = mapPendingAllocations(
|
|
275
266
|
portfolio.staleBalances
|
|
276
267
|
);
|
|
@@ -1353,37 +1344,6 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1353
1344
|
);
|
|
1354
1345
|
}
|
|
1355
1346
|
}
|
|
1356
|
-
/**
|
|
1357
|
-
* Records the deposit with Zyfai, retrying transient failures.
|
|
1358
|
-
*
|
|
1359
|
-
* This runs AFTER the transfer has already landed on-chain, so it must never
|
|
1360
|
-
* fail the deposit — the funds moved. But it is also the ONLY source of the
|
|
1361
|
-
* "Top up wallet" entry the history is built from: Zyfai auto-deploys the
|
|
1362
|
-
* balance it detects either way, so when this call is lost the user's deposit
|
|
1363
|
-
* never appears in Activity (an earlier withdrawal stays the newest row) and
|
|
1364
|
-
* nothing ever backfills it. Retry, then log loudly enough to be recoverable.
|
|
1365
|
-
*/
|
|
1366
|
-
async logDepositWithRetry(chainId, txHash, amount, tokenAddress) {
|
|
1367
|
-
const ATTEMPTS = 3;
|
|
1368
|
-
const RETRY_DELAY_MS = 1e3;
|
|
1369
|
-
for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
|
|
1370
|
-
try {
|
|
1371
|
-
await (tokenAddress ? this.sdk.logDeposit(chainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(chainId, txHash, amount));
|
|
1372
|
-
return;
|
|
1373
|
-
} catch (logError) {
|
|
1374
|
-
if (attempt === ATTEMPTS) {
|
|
1375
|
-
console.error(
|
|
1376
|
-
"[owney-sdk] Deposit landed on-chain but logDeposit failed \u2014 it will be missing from Zyfai history:",
|
|
1377
|
-
{ txHash, chainId, amount, tokenAddress, error: logError }
|
|
1378
|
-
);
|
|
1379
|
-
return;
|
|
1380
|
-
}
|
|
1381
|
-
await new Promise(
|
|
1382
|
-
(resolve) => setTimeout(resolve, RETRY_DELAY_MS * attempt)
|
|
1383
|
-
);
|
|
1384
|
-
}
|
|
1385
|
-
}
|
|
1386
|
-
}
|
|
1387
1347
|
/**
|
|
1388
1348
|
* True when `smartWallet` is the backend-managed pool wallet Zyfai assigned
|
|
1389
1349
|
* to this EOA — the "new wallet" kind that is predeployed on the chains it
|
|
@@ -1687,12 +1647,14 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1687
1647
|
);
|
|
1688
1648
|
const txHash = await depositCallback(smartWallet, validChainId, amount);
|
|
1689
1649
|
const tokenAddress = asset === "WETH" ? WETH_ADDRESS_BY_CHAIN[validChainId] : void 0;
|
|
1690
|
-
|
|
1691
|
-
validChainId,
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1650
|
+
try {
|
|
1651
|
+
await (tokenAddress ? this.sdk.logDeposit(validChainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(validChainId, txHash, amount));
|
|
1652
|
+
} catch (logError) {
|
|
1653
|
+
console.warn(
|
|
1654
|
+
"[owney-sdk] Deposit landed on-chain but logDeposit failed (non-fatal):",
|
|
1655
|
+
logError
|
|
1656
|
+
);
|
|
1657
|
+
}
|
|
1696
1658
|
return { txHash, smartWallet, amount };
|
|
1697
1659
|
}
|
|
1698
1660
|
await this.ensureWalletDeployed(this.getAddress(), validChainId);
|
|
@@ -1973,10 +1935,11 @@ async function withFailureReporting(apiKey, agentType, fn) {
|
|
|
1973
1935
|
// src/lib/helpers/withdraw-helper.ts
|
|
1974
1936
|
import { parseUnits } from "viem";
|
|
1975
1937
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
1938
|
+
const target = asset.toUpperCase();
|
|
1976
1939
|
return agents.map((agent) => {
|
|
1977
1940
|
const agentBalance = aggregated[agent.id];
|
|
1978
1941
|
const tokenBalance = agentBalance?.tokens.find(
|
|
1979
|
-
(t) => t.chainId === chainId &&
|
|
1942
|
+
(t) => t.chainId === chainId && t.asset.toUpperCase() === target
|
|
1980
1943
|
);
|
|
1981
1944
|
if (!tokenBalance) return { agent, balance: 0n };
|
|
1982
1945
|
return { agent, balance: parseUnits(tokenBalance.amount, decimals) };
|
|
@@ -2246,6 +2209,84 @@ async function getSponsorRelayerAddress(input) {
|
|
|
2246
2209
|
return parsed.data.relayer;
|
|
2247
2210
|
}
|
|
2248
2211
|
|
|
2212
|
+
// src/lib/permit2.ts
|
|
2213
|
+
import { bytesToHex as bytesToHex2 } from "viem";
|
|
2214
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
2215
|
+
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
2216
|
+
var ERC20_ALLOWANCE_ABI = [
|
|
2217
|
+
{
|
|
2218
|
+
type: "function",
|
|
2219
|
+
name: "allowance",
|
|
2220
|
+
stateMutability: "view",
|
|
2221
|
+
inputs: [
|
|
2222
|
+
{ name: "owner", type: "address" },
|
|
2223
|
+
{ name: "spender", type: "address" }
|
|
2224
|
+
],
|
|
2225
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
2226
|
+
},
|
|
2227
|
+
{
|
|
2228
|
+
type: "function",
|
|
2229
|
+
name: "approve",
|
|
2230
|
+
stateMutability: "nonpayable",
|
|
2231
|
+
inputs: [
|
|
2232
|
+
{ name: "spender", type: "address" },
|
|
2233
|
+
{ name: "amount", type: "uint256" }
|
|
2234
|
+
],
|
|
2235
|
+
outputs: [{ name: "", type: "bool" }]
|
|
2236
|
+
},
|
|
2237
|
+
{
|
|
2238
|
+
type: "function",
|
|
2239
|
+
name: "balanceOf",
|
|
2240
|
+
stateMutability: "view",
|
|
2241
|
+
inputs: [{ name: "account", type: "address" }],
|
|
2242
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
2243
|
+
}
|
|
2244
|
+
];
|
|
2245
|
+
function buildPermitTransferFromTypedData(input) {
|
|
2246
|
+
return {
|
|
2247
|
+
domain: {
|
|
2248
|
+
name: "Permit2",
|
|
2249
|
+
chainId: input.chainId,
|
|
2250
|
+
verifyingContract: PERMIT2_ADDRESS
|
|
2251
|
+
},
|
|
2252
|
+
types: {
|
|
2253
|
+
PermitTransferFrom: [
|
|
2254
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
2255
|
+
{ name: "spender", type: "address" },
|
|
2256
|
+
{ name: "nonce", type: "uint256" },
|
|
2257
|
+
{ name: "deadline", type: "uint256" }
|
|
2258
|
+
],
|
|
2259
|
+
TokenPermissions: [
|
|
2260
|
+
{ name: "token", type: "address" },
|
|
2261
|
+
{ name: "amount", type: "uint256" }
|
|
2262
|
+
]
|
|
2263
|
+
},
|
|
2264
|
+
primaryType: "PermitTransferFrom",
|
|
2265
|
+
message: input.message
|
|
2266
|
+
};
|
|
2267
|
+
}
|
|
2268
|
+
function randomPermit2Nonce() {
|
|
2269
|
+
const bytes = new Uint8Array(32);
|
|
2270
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
2271
|
+
return BigInt(bytesToHex2(bytes));
|
|
2272
|
+
}
|
|
2273
|
+
async function readPermit2Allowance(publicClient, token, owner) {
|
|
2274
|
+
return publicClient.readContract({
|
|
2275
|
+
address: token,
|
|
2276
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
2277
|
+
functionName: "allowance",
|
|
2278
|
+
args: [owner, PERMIT2_ADDRESS]
|
|
2279
|
+
});
|
|
2280
|
+
}
|
|
2281
|
+
async function readErc20Balance(publicClient, token, owner) {
|
|
2282
|
+
return publicClient.readContract({
|
|
2283
|
+
address: token,
|
|
2284
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
2285
|
+
functionName: "balanceOf",
|
|
2286
|
+
args: [owner]
|
|
2287
|
+
});
|
|
2288
|
+
}
|
|
2289
|
+
|
|
2249
2290
|
// src/lib/chain-guard.ts
|
|
2250
2291
|
var CHAIN_NAMES = {
|
|
2251
2292
|
1: "Ethereum",
|
|
@@ -2564,7 +2605,6 @@ var VIEM_CHAIN2 = {
|
|
|
2564
2605
|
42161: arbitrum2,
|
|
2565
2606
|
1: mainnet2
|
|
2566
2607
|
};
|
|
2567
|
-
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
2568
2608
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
2569
2609
|
8453: "0x4200000000000000000000000000000000000006",
|
|
2570
2610
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -2593,7 +2633,6 @@ var OwneySDK = class {
|
|
|
2593
2633
|
zyfaiRpcUrls;
|
|
2594
2634
|
routingApiBaseUrl;
|
|
2595
2635
|
referralSource;
|
|
2596
|
-
surfliquidApiBaseUrl;
|
|
2597
2636
|
cachedSponsoredCallback = null;
|
|
2598
2637
|
cachedWethSponsoredCallback = null;
|
|
2599
2638
|
paymasterServiceUrl;
|
|
@@ -2606,7 +2645,6 @@ var OwneySDK = class {
|
|
|
2606
2645
|
this.routingApiBaseUrl = config.routingApiBaseUrl;
|
|
2607
2646
|
this.paymasterServiceUrl = config.paymasterServiceUrl;
|
|
2608
2647
|
this.referralSource = config.referralSource;
|
|
2609
|
-
this.surfliquidApiBaseUrl = config.surfliquidApiBaseUrl;
|
|
2610
2648
|
}
|
|
2611
2649
|
/**
|
|
2612
2650
|
* Establish connection state for all subsequent SDK calls.
|
|
@@ -2836,8 +2874,8 @@ var OwneySDK = class {
|
|
|
2836
2874
|
this.initializingAgentsPromise = (async () => {
|
|
2837
2875
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
2838
2876
|
this.disabledAgents.clear();
|
|
2839
|
-
for (const { key: key2, agent_type,
|
|
2840
|
-
const agent =
|
|
2877
|
+
for (const { key: key2, agent_type, is_enabled } of agentKeys) {
|
|
2878
|
+
const agent = this.createAgent(agent_type, key2);
|
|
2841
2879
|
if (!agent) continue;
|
|
2842
2880
|
this.agents.set(agent_type, agent);
|
|
2843
2881
|
if (is_enabled === false) {
|
|
@@ -2858,22 +2896,10 @@ var OwneySDK = class {
|
|
|
2858
2896
|
this.initializingAgentsPromise = null;
|
|
2859
2897
|
}
|
|
2860
2898
|
}
|
|
2861
|
-
|
|
2899
|
+
createAgent(agentId, key2) {
|
|
2862
2900
|
if (agentId === "zyfai") {
|
|
2863
2901
|
return new ZyfaiAgent(key2, this.zyfaiRpcUrls, this.referralSource);
|
|
2864
2902
|
}
|
|
2865
|
-
if (agentId === "surfliquid") {
|
|
2866
|
-
if (!projectName) return null;
|
|
2867
|
-
const { SurfLiquidAgent } = await import("./surfliquid.agent-VNGQUSXN.js");
|
|
2868
|
-
return new SurfLiquidAgent({
|
|
2869
|
-
projectName,
|
|
2870
|
-
appId: key2,
|
|
2871
|
-
// Same-origin proxy override — SurfLiquid auth is an httpOnly cookie,
|
|
2872
|
-
// which WebKit (iOS) discards when it is third-party. See
|
|
2873
|
-
// OwneySDKConfig.surfliquidApiBaseUrl.
|
|
2874
|
-
apiBaseUrl: this.surfliquidApiBaseUrl
|
|
2875
|
-
});
|
|
2876
|
-
}
|
|
2877
2903
|
return null;
|
|
2878
2904
|
}
|
|
2879
2905
|
// --- Account lifecycle ---
|
|
@@ -2955,9 +2981,9 @@ var OwneySDK = class {
|
|
|
2955
2981
|
/**
|
|
2956
2982
|
* Activate agents ONE AT A TIME, each followed by its org policy.
|
|
2957
2983
|
*
|
|
2958
|
-
* Every agent opens its activation with its own wallet signature
|
|
2959
|
-
*
|
|
2960
|
-
*
|
|
2984
|
+
* Every agent opens its activation with its own wallet signature, each
|
|
2985
|
+
* exchanged for that agent's own backend session — Zyfai's SIWX for a JWT,
|
|
2986
|
+
* Sail's SIWE. Run in parallel, that puts two `personal_sign` requests on one
|
|
2961
2987
|
* wallet connection in the same instant. Over WalletConnect both are
|
|
2962
2988
|
* delivered to the wallet, which renders one signing request at a time and
|
|
2963
2989
|
* queues or silently drops the other: neither promise settles, so activation
|
|
@@ -3057,30 +3083,18 @@ var OwneySDK = class {
|
|
|
3057
3083
|
);
|
|
3058
3084
|
}
|
|
3059
3085
|
const agentResults = {};
|
|
3060
|
-
const agentErrors = {};
|
|
3061
3086
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
3062
|
-
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
|
|
3067
|
-
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
depositCallback
|
|
3071
|
-
);
|
|
3072
|
-
} catch (error) {
|
|
3073
|
-
agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
|
|
3074
|
-
}
|
|
3075
|
-
}
|
|
3076
|
-
if (Object.keys(agentResults).length === 0) {
|
|
3077
|
-
throw new OwneyError(
|
|
3078
|
-
"DEPOSIT_ALL_FAILED",
|
|
3079
|
-
`All ${agentAmounts.length} agent deposit(s) failed.`,
|
|
3080
|
-
{ agentErrors }
|
|
3087
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
3088
|
+
agent,
|
|
3089
|
+
state,
|
|
3090
|
+
chainId,
|
|
3091
|
+
agentAmount,
|
|
3092
|
+
asset,
|
|
3093
|
+
effectiveCallback,
|
|
3094
|
+
depositCallback
|
|
3081
3095
|
);
|
|
3082
3096
|
}
|
|
3083
|
-
return
|
|
3097
|
+
return { agentResults };
|
|
3084
3098
|
}
|
|
3085
3099
|
/**
|
|
3086
3100
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -3196,8 +3210,9 @@ var OwneySDK = class {
|
|
|
3196
3210
|
async hasExistingBalance(agent, state, chainId, asset) {
|
|
3197
3211
|
try {
|
|
3198
3212
|
const balance = await agent.getBalances(state, chainId);
|
|
3213
|
+
const target = asset.toLowerCase();
|
|
3199
3214
|
const token = balance.tokens.find(
|
|
3200
|
-
(t) => t.chainId === chainId &&
|
|
3215
|
+
(t) => t.chainId === chainId && t.asset.toLowerCase() === target
|
|
3201
3216
|
);
|
|
3202
3217
|
return !!token && Number(token.amount) > 0;
|
|
3203
3218
|
} catch {
|
|
@@ -3236,34 +3251,6 @@ var OwneySDK = class {
|
|
|
3236
3251
|
}
|
|
3237
3252
|
return eligible;
|
|
3238
3253
|
}
|
|
3239
|
-
/**
|
|
3240
|
-
* Agent ids the routing API provisioned for this org that support the given
|
|
3241
|
-
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
3242
|
-
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
3243
|
-
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
3244
|
-
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
3245
|
-
*
|
|
3246
|
-
* This is the source of truth for agent availability: an agent appears here
|
|
3247
|
-
* iff the routing API returned its key. No per-app feature flags.
|
|
3248
|
-
*/
|
|
3249
|
-
async getEligibleAgentIds(chainId, asset) {
|
|
3250
|
-
try {
|
|
3251
|
-
await this.ensureAgentsInitialized();
|
|
3252
|
-
} catch (error) {
|
|
3253
|
-
if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
|
|
3254
|
-
return [];
|
|
3255
|
-
}
|
|
3256
|
-
throw error;
|
|
3257
|
-
}
|
|
3258
|
-
return [...this.agents.values()].filter((agent) => {
|
|
3259
|
-
const chainAssets = agent.supportedAssets.find(
|
|
3260
|
-
(sa) => sa.chainId === chainId
|
|
3261
|
-
);
|
|
3262
|
-
return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
|
|
3263
|
-
}).map((agent) => agent.id).sort(
|
|
3264
|
-
(a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
|
|
3265
|
-
);
|
|
3266
|
-
}
|
|
3267
3254
|
// --- Fund operations ---
|
|
3268
3255
|
/**
|
|
3269
3256
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -3299,17 +3286,9 @@ var OwneySDK = class {
|
|
|
3299
3286
|
}
|
|
3300
3287
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
3301
3288
|
if (!amount) {
|
|
3302
|
-
const aggregated2 = await this.getBalances();
|
|
3303
|
-
const funded = projectAgentBalancesForAsset(
|
|
3304
|
-
eligibleAgents,
|
|
3305
|
-
aggregated2.agentBalances,
|
|
3306
|
-
chainId,
|
|
3307
|
-
asset,
|
|
3308
|
-
assetInfo.decimals
|
|
3309
|
-
).filter((b) => b.balance > 0n);
|
|
3310
3289
|
const results2 = {};
|
|
3311
3290
|
const agentErrors2 = {};
|
|
3312
|
-
for (const
|
|
3291
|
+
for (const agent of eligibleAgents) {
|
|
3313
3292
|
try {
|
|
3314
3293
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
3315
3294
|
} catch (err) {
|
|
@@ -3326,10 +3305,9 @@ var OwneySDK = class {
|
|
|
3326
3305
|
{ asset, agentErrors: agentErrors2 }
|
|
3327
3306
|
);
|
|
3328
3307
|
}
|
|
3329
|
-
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
3330
3308
|
return {
|
|
3331
3309
|
agentResult: results2,
|
|
3332
|
-
totalWithdrawn:
|
|
3310
|
+
totalWithdrawn: sumWithdrawnAmount(results2).toString()
|
|
3333
3311
|
};
|
|
3334
3312
|
}
|
|
3335
3313
|
const requested = BigInt(amount);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@owney/sdk",
|
|
3
|
-
"version": "0.7.12-beta.
|
|
3
|
+
"version": "0.7.12-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "dist/index.cjs",
|
|
6
6
|
"module": "dist/index.js",
|
|
@@ -23,9 +23,7 @@
|
|
|
23
23
|
"test:watch": "vitest"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@surf_liquid/core-sdk": "^0.4.0",
|
|
27
26
|
"@zyfai/sdk": "0.2.50",
|
|
28
|
-
"ethers": "^6.17.0",
|
|
29
27
|
"siwe": "^3.0.0",
|
|
30
28
|
"viem": "^2.48.1"
|
|
31
29
|
},
|