@owney/sdk 0.6.9-beta.5 → 0.6.9-beta.6
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-GMNQBWUB.js +55 -0
- package/dist/index.cjs +615 -103
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +110 -88
- package/dist/surfliquid.agent-OMOYXWLP.js +385 -0
- package/package.json +3 -1
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,14 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res, err) => function __init() {
|
|
7
|
+
if (err) throw err[0];
|
|
8
|
+
try {
|
|
9
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
10
|
+
} catch (e) {
|
|
11
|
+
throw err = [e], e;
|
|
12
|
+
}
|
|
13
|
+
};
|
|
6
14
|
var __export = (target, all) => {
|
|
7
15
|
for (var name in all)
|
|
8
16
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -17,6 +25,478 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
25
|
};
|
|
18
26
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
27
|
|
|
28
|
+
// src/errors.ts
|
|
29
|
+
var OwneyError, AgentNotFoundError, NotConnectedError, AgentChainIncompatibleError;
|
|
30
|
+
var init_errors = __esm({
|
|
31
|
+
"src/errors.ts"() {
|
|
32
|
+
"use strict";
|
|
33
|
+
OwneyError = class extends Error {
|
|
34
|
+
code;
|
|
35
|
+
details;
|
|
36
|
+
agentId;
|
|
37
|
+
constructor(code, message, details, agentId) {
|
|
38
|
+
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
39
|
+
super(`${prefix} ${message}`);
|
|
40
|
+
this.name = "OwneyError";
|
|
41
|
+
this.code = code;
|
|
42
|
+
this.details = details;
|
|
43
|
+
this.agentId = agentId;
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
AgentNotFoundError = class extends OwneyError {
|
|
47
|
+
constructor(agentId, available) {
|
|
48
|
+
super(
|
|
49
|
+
"AGENT_NOT_FOUND",
|
|
50
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
51
|
+
{ agentId, available },
|
|
52
|
+
agentId
|
|
53
|
+
);
|
|
54
|
+
this.name = "AgentNotFoundError";
|
|
55
|
+
}
|
|
56
|
+
};
|
|
57
|
+
NotConnectedError = class extends OwneyError {
|
|
58
|
+
constructor() {
|
|
59
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
60
|
+
this.name = "NotConnectedError";
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
AgentChainIncompatibleError = class extends OwneyError {
|
|
64
|
+
incompatibleAgents;
|
|
65
|
+
connectedChainId;
|
|
66
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
67
|
+
const details = incompatibleAgents.map(
|
|
68
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
69
|
+
).join("; ");
|
|
70
|
+
super(
|
|
71
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
72
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
73
|
+
{ incompatibleAgents, connectedChainId }
|
|
74
|
+
);
|
|
75
|
+
this.name = "AgentChainIncompatibleError";
|
|
76
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
77
|
+
this.connectedChainId = connectedChainId;
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
// src/agents/surfliquid/surfliquid.constants.ts
|
|
84
|
+
var SURFLIQUID_CHAIN_ID, SURFLIQUID_CHAIN_NAME, SURFLIQUID_USDC_ADDRESS, SURFLIQUID_USDC_DECIMALS, SURFLIQUID_MIN_DEPOSIT, SURFLIQUID_SUPPORTED_ASSETS, SURFLIQUID_ACTION_MAP;
|
|
85
|
+
var init_surfliquid_constants = __esm({
|
|
86
|
+
"src/agents/surfliquid/surfliquid.constants.ts"() {
|
|
87
|
+
"use strict";
|
|
88
|
+
SURFLIQUID_CHAIN_ID = 8453;
|
|
89
|
+
SURFLIQUID_CHAIN_NAME = "BASE";
|
|
90
|
+
SURFLIQUID_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
91
|
+
SURFLIQUID_USDC_DECIMALS = 6;
|
|
92
|
+
SURFLIQUID_MIN_DEPOSIT = "0";
|
|
93
|
+
SURFLIQUID_SUPPORTED_ASSETS = [
|
|
94
|
+
{
|
|
95
|
+
chainId: SURFLIQUID_CHAIN_ID,
|
|
96
|
+
chain: SURFLIQUID_CHAIN_NAME,
|
|
97
|
+
assets: [{ symbol: "USDC", minDepositAmount: SURFLIQUID_MIN_DEPOSIT }]
|
|
98
|
+
}
|
|
99
|
+
];
|
|
100
|
+
SURFLIQUID_ACTION_MAP = {
|
|
101
|
+
// INITIAL_DEPOSIT is the user's real first deposit, so surface it like any
|
|
102
|
+
// other funding ("Top up"). The mini-app intentionally hides the "Deposit"
|
|
103
|
+
// action (it marks Zyfai's smart-account-creation event), which would
|
|
104
|
+
// otherwise drop a SurfLiquid user's only history row.
|
|
105
|
+
INITIAL_DEPOSIT: "Top up",
|
|
106
|
+
DEPOSIT: "Top up",
|
|
107
|
+
USER_DEPOSIT: "Top up",
|
|
108
|
+
WITHDRAWAL: "Withdraw",
|
|
109
|
+
USER_WITHDRAWAL: "Withdraw",
|
|
110
|
+
REBALANCE: "Rebalance",
|
|
111
|
+
REBALANCE_COMPLETED: "Rebalance",
|
|
112
|
+
CROSS_CHAIN_REBALANCE: "Rebalance",
|
|
113
|
+
MERKL_CLAIM: "Earned"
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// src/agents/surfliquid/surfliquid.mapper.ts
|
|
119
|
+
function mapMessage(message) {
|
|
120
|
+
const action = SURFLIQUID_ACTION_MAP[message.transactionType];
|
|
121
|
+
if (!action) return null;
|
|
122
|
+
return {
|
|
123
|
+
agent: "surfliquid",
|
|
124
|
+
action,
|
|
125
|
+
date: message.timestamp,
|
|
126
|
+
oldApy: message.apyBefore != null ? String(message.apyBefore) : null,
|
|
127
|
+
newApy: message.apyAfter != null ? String(message.apyAfter) : null,
|
|
128
|
+
transactions: [
|
|
129
|
+
{
|
|
130
|
+
txHashes: [message.txHash],
|
|
131
|
+
chainId: message.chainId,
|
|
132
|
+
tokenSymbol: message.token ?? void 0,
|
|
133
|
+
amount: message.amount != null ? String(message.amount) : void 0
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
rebalanceLog: []
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function mapHistory(result, _chainId) {
|
|
140
|
+
const data = result.messages.map(mapMessage).filter((entry) => entry !== null);
|
|
141
|
+
const hasMore = result.page < result.pages;
|
|
142
|
+
return {
|
|
143
|
+
data,
|
|
144
|
+
hasMore,
|
|
145
|
+
nextCursor: hasMore ? String(result.page + 1) : void 0
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
function mapBalances2(vault, chainId, morphoStats) {
|
|
149
|
+
const assets = (vault.assets ?? []).filter(
|
|
150
|
+
(asset) => asset.assetSymbol === "USDC" && asset.chainId === chainId
|
|
151
|
+
);
|
|
152
|
+
const tokens = assets.map((asset) => ({
|
|
153
|
+
chain: SURFLIQUID_CHAIN_NAME,
|
|
154
|
+
chainId: SURFLIQUID_CHAIN_ID,
|
|
155
|
+
asset: "USDC",
|
|
156
|
+
amount: String(asset.currentValueUSD)
|
|
157
|
+
}));
|
|
158
|
+
const positions = assets.map((asset) => {
|
|
159
|
+
const stats = morphoStats?.get(asset.morphoVaultAddress?.toLowerCase() ?? "");
|
|
160
|
+
return {
|
|
161
|
+
chain: SURFLIQUID_CHAIN_NAME,
|
|
162
|
+
protocol: "Morpho",
|
|
163
|
+
// The specific MetaMorpho vault (e.g. "Gauntlet USDC Frontier"), read from
|
|
164
|
+
// Morpho — renders as "Morpho <vault>" alongside zyfai's vault detail.
|
|
165
|
+
pool: stats?.name ?? void 0,
|
|
166
|
+
asset: "USDC",
|
|
167
|
+
amount: String(asset.currentValueUSD),
|
|
168
|
+
apy: asset.currentAPY,
|
|
169
|
+
// TVL + liquidity come straight from Morpho (SurfLiquid's API omits them).
|
|
170
|
+
tvl: stats?.tvlUsd,
|
|
171
|
+
liquidity: stats?.liquidityUsd
|
|
172
|
+
};
|
|
173
|
+
});
|
|
174
|
+
const total = assets.reduce(
|
|
175
|
+
(sum, asset) => sum + asset.currentValueUSD,
|
|
176
|
+
0
|
|
177
|
+
);
|
|
178
|
+
return {
|
|
179
|
+
smartWallet: vault.userVaultAddress ?? void 0,
|
|
180
|
+
totalBalance: String(total),
|
|
181
|
+
totalBalanceAsset: "usdc",
|
|
182
|
+
tokens,
|
|
183
|
+
positions
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function mapAccountApy(vault, days) {
|
|
187
|
+
const breakdown = vault.apyBreakdown;
|
|
188
|
+
const windowed = breakdown ? breakdown[APY_WINDOW_KEY[days]] : void 0;
|
|
189
|
+
const apy = windowed != null ? windowed : breakdown?.currentAPY ?? 0;
|
|
190
|
+
return {
|
|
191
|
+
walletAddress: vault.walletAddress ?? "",
|
|
192
|
+
weightedApyAfterFee: apy,
|
|
193
|
+
apyByChainAndAsset: { [SURFLIQUID_CHAIN_ID]: { USDC: apy } },
|
|
194
|
+
// Parity with Sail: SurfLiquid's core-sdk exposes no daily net-APY series.
|
|
195
|
+
history: []
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
function mapEarnings2(vault, vaultAddress) {
|
|
199
|
+
return {
|
|
200
|
+
smartWallet: vaultAddress,
|
|
201
|
+
lifetimeEarnings: vault.earned?.totalEarningsUSD ?? 0,
|
|
202
|
+
tokens: []
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
function mapUserProfile2(vault, address) {
|
|
206
|
+
return {
|
|
207
|
+
address,
|
|
208
|
+
smartWallet: vault.userVaultAddress ?? "",
|
|
209
|
+
chains: [SURFLIQUID_CHAIN_ID],
|
|
210
|
+
// SurfLiquid uses cookie-based session auth — no session-key concept.
|
|
211
|
+
hasActiveSessionKey: false,
|
|
212
|
+
protocols: ["SurfLiquid"]
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
var APY_WINDOW_KEY;
|
|
216
|
+
var init_surfliquid_mapper = __esm({
|
|
217
|
+
"src/agents/surfliquid/surfliquid.mapper.ts"() {
|
|
218
|
+
"use strict";
|
|
219
|
+
init_surfliquid_constants();
|
|
220
|
+
APY_WINDOW_KEY = {
|
|
221
|
+
"7D": "apy7d",
|
|
222
|
+
"14D": "apy14d",
|
|
223
|
+
"30D": "apy30d"
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
// src/agents/surfliquid/surfliquid.wallet-adapter.ts
|
|
229
|
+
var import_core_sdk, OwneyWalletAdapter;
|
|
230
|
+
var init_surfliquid_wallet_adapter = __esm({
|
|
231
|
+
"src/agents/surfliquid/surfliquid.wallet-adapter.ts"() {
|
|
232
|
+
"use strict";
|
|
233
|
+
import_core_sdk = require("@surf_liquid/core-sdk");
|
|
234
|
+
OwneyWalletAdapter = class extends import_core_sdk.BaseWalletAdapter {
|
|
235
|
+
constructor(eip1193Provider) {
|
|
236
|
+
super();
|
|
237
|
+
this.eip1193Provider = eip1193Provider;
|
|
238
|
+
}
|
|
239
|
+
eip1193Provider;
|
|
240
|
+
name = "owney";
|
|
241
|
+
get installed() {
|
|
242
|
+
return true;
|
|
243
|
+
}
|
|
244
|
+
resolveProvider() {
|
|
245
|
+
return this.eip1193Provider;
|
|
246
|
+
}
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
// src/agents/surfliquid/surfliquid.morpho.ts
|
|
252
|
+
async function fetchMorphoVaultStats(vaultAddress, chainId) {
|
|
253
|
+
try {
|
|
254
|
+
const res = await fetch(MORPHO_API_URL, {
|
|
255
|
+
method: "POST",
|
|
256
|
+
headers: { "Content-Type": "application/json" },
|
|
257
|
+
body: JSON.stringify({
|
|
258
|
+
query: VAULT_STATS_QUERY,
|
|
259
|
+
variables: { address: vaultAddress, chainId }
|
|
260
|
+
})
|
|
261
|
+
});
|
|
262
|
+
if (!res.ok) return null;
|
|
263
|
+
const json = await res.json();
|
|
264
|
+
if (json.errors) return null;
|
|
265
|
+
const vault = json.data?.vaultByAddress;
|
|
266
|
+
const tvlUsd = vault?.state?.totalAssetsUsd;
|
|
267
|
+
const liquidityUsd = vault?.liquidity?.usd;
|
|
268
|
+
if (typeof tvlUsd !== "number" || typeof liquidityUsd !== "number") {
|
|
269
|
+
return null;
|
|
270
|
+
}
|
|
271
|
+
const name = typeof vault?.name === "string" ? vault.name : null;
|
|
272
|
+
return { name, tvlUsd, liquidityUsd };
|
|
273
|
+
} catch (error) {
|
|
274
|
+
console.warn("surfliquid: Morpho vault stats fetch failed", {
|
|
275
|
+
vaultAddress,
|
|
276
|
+
chainId,
|
|
277
|
+
error
|
|
278
|
+
});
|
|
279
|
+
return null;
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
async function fetchMorphoStatsByVault(vaultAddresses, chainId) {
|
|
283
|
+
const unique = [...new Set(vaultAddresses.map((a) => a.toLowerCase()))];
|
|
284
|
+
const entries = await Promise.all(
|
|
285
|
+
unique.map(
|
|
286
|
+
async (address) => [address, await fetchMorphoVaultStats(address, chainId)]
|
|
287
|
+
)
|
|
288
|
+
);
|
|
289
|
+
const byVault = /* @__PURE__ */ new Map();
|
|
290
|
+
for (const [address, stats] of entries) {
|
|
291
|
+
if (stats) byVault.set(address, stats);
|
|
292
|
+
}
|
|
293
|
+
return byVault;
|
|
294
|
+
}
|
|
295
|
+
var MORPHO_API_URL, VAULT_STATS_QUERY;
|
|
296
|
+
var init_surfliquid_morpho = __esm({
|
|
297
|
+
"src/agents/surfliquid/surfliquid.morpho.ts"() {
|
|
298
|
+
"use strict";
|
|
299
|
+
MORPHO_API_URL = "https://api.morpho.org/graphql";
|
|
300
|
+
VAULT_STATS_QUERY = `
|
|
301
|
+
query VaultStats($address: String!, $chainId: Int!) {
|
|
302
|
+
vaultByAddress(address: $address, chainId: $chainId) {
|
|
303
|
+
name
|
|
304
|
+
state { totalAssetsUsd }
|
|
305
|
+
liquidity { usd }
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
`;
|
|
309
|
+
}
|
|
310
|
+
});
|
|
311
|
+
|
|
312
|
+
// src/agents/surfliquid/surfliquid.agent.ts
|
|
313
|
+
var surfliquid_agent_exports = {};
|
|
314
|
+
__export(surfliquid_agent_exports, {
|
|
315
|
+
SurfLiquidAgent: () => SurfLiquidAgent
|
|
316
|
+
});
|
|
317
|
+
var import_core_sdk2, import_viem5, APY_WINDOW_KEY2, SurfLiquidAgent;
|
|
318
|
+
var init_surfliquid_agent = __esm({
|
|
319
|
+
"src/agents/surfliquid/surfliquid.agent.ts"() {
|
|
320
|
+
"use strict";
|
|
321
|
+
import_core_sdk2 = require("@surf_liquid/core-sdk");
|
|
322
|
+
import_viem5 = require("viem");
|
|
323
|
+
init_errors();
|
|
324
|
+
init_surfliquid_constants();
|
|
325
|
+
init_surfliquid_mapper();
|
|
326
|
+
init_surfliquid_wallet_adapter();
|
|
327
|
+
init_surfliquid_morpho();
|
|
328
|
+
APY_WINDOW_KEY2 = {
|
|
329
|
+
"7D": "apy7d",
|
|
330
|
+
"14D": "apy14d",
|
|
331
|
+
"30D": "apy30d"
|
|
332
|
+
};
|
|
333
|
+
SurfLiquidAgent = class {
|
|
334
|
+
constructor(config) {
|
|
335
|
+
this.config = config;
|
|
336
|
+
}
|
|
337
|
+
config;
|
|
338
|
+
id = "surfliquid";
|
|
339
|
+
supportedChainIds = [SURFLIQUID_CHAIN_ID];
|
|
340
|
+
supportedAssets = SURFLIQUID_SUPPORTED_ASSETS;
|
|
341
|
+
surf = null;
|
|
342
|
+
connectedAddress = null;
|
|
343
|
+
// In-flight connect+auth, shared by concurrent callers to dedupe SIWE.
|
|
344
|
+
connectPromise = null;
|
|
345
|
+
ensureSurf() {
|
|
346
|
+
if (this.surf) return this.surf;
|
|
347
|
+
this.surf = import_core_sdk2.SurfClient.create({
|
|
348
|
+
projectName: this.config.projectName,
|
|
349
|
+
appId: this.config.appId,
|
|
350
|
+
environment: "mainnet",
|
|
351
|
+
chainId: SURFLIQUID_CHAIN_ID,
|
|
352
|
+
apiBaseUrl: this.config.apiBaseUrl,
|
|
353
|
+
rpcUrl: this.config.rpcUrl,
|
|
354
|
+
// Let the SDK auto-approve USDC to the vault before depositing.
|
|
355
|
+
autoApprove: true
|
|
356
|
+
});
|
|
357
|
+
return this.surf;
|
|
358
|
+
}
|
|
359
|
+
/**
|
|
360
|
+
* Connects + authenticates the SurfClient against owney's provider. Skips the
|
|
361
|
+
* SIWE prompt when already authenticated for this wallet (cookie session).
|
|
362
|
+
*/
|
|
363
|
+
async connect(state) {
|
|
364
|
+
const surf = this.ensureSurf();
|
|
365
|
+
const sameWallet = this.connectedAddress?.toLowerCase() === state.walletAddress.toLowerCase();
|
|
366
|
+
if (sameWallet && surf.getAuthState().authenticated) {
|
|
367
|
+
return surf;
|
|
368
|
+
}
|
|
369
|
+
if (this.connectPromise) return this.connectPromise;
|
|
370
|
+
this.connectPromise = (async () => {
|
|
371
|
+
surf.registerWalletAdapter(
|
|
372
|
+
"owney",
|
|
373
|
+
new OwneyWalletAdapter(state.provider)
|
|
374
|
+
);
|
|
375
|
+
await surf.connectWallet("owney");
|
|
376
|
+
await surf.authenticate();
|
|
377
|
+
this.connectedAddress = state.walletAddress;
|
|
378
|
+
return surf;
|
|
379
|
+
})();
|
|
380
|
+
try {
|
|
381
|
+
return await this.connectPromise;
|
|
382
|
+
} finally {
|
|
383
|
+
this.connectPromise = null;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
/**
|
|
387
|
+
* Returns the user's vault address, deploying one on first use. SurfLiquid's
|
|
388
|
+
* deposit requires the vault to exist, so this must run before depositing.
|
|
389
|
+
* Existing vault → returned as-is; otherwise `deployVault()` is sent
|
|
390
|
+
* (user-pays) and the freshly deployed address is returned.
|
|
391
|
+
*/
|
|
392
|
+
async resolveVaultAddress(surf, owner) {
|
|
393
|
+
const vault = await surf.getVault(owner).catch(() => null);
|
|
394
|
+
if (vault?.exists && vault.userVaultAddress) {
|
|
395
|
+
return vault.userVaultAddress;
|
|
396
|
+
}
|
|
397
|
+
const { vaultAddress } = await surf.deployVault();
|
|
398
|
+
return vaultAddress;
|
|
399
|
+
}
|
|
400
|
+
// --- IAgent: lifecycle ---
|
|
401
|
+
async disconnect() {
|
|
402
|
+
if (this.surf) {
|
|
403
|
+
await this.surf.disconnectWallet();
|
|
404
|
+
}
|
|
405
|
+
this.connectedAddress = null;
|
|
406
|
+
}
|
|
407
|
+
async activateAgent(state) {
|
|
408
|
+
await this.connect(state);
|
|
409
|
+
}
|
|
410
|
+
// --- IAgent: funds (user-pays; asset is always USDC, callback ignored) ---
|
|
411
|
+
async deposit(state, _chainId, amount, _asset, _depositCallback) {
|
|
412
|
+
const surf = await this.connect(state);
|
|
413
|
+
const human = (0, import_viem5.formatUnits)(BigInt(amount), SURFLIQUID_USDC_DECIMALS);
|
|
414
|
+
const smartWallet = await this.resolveVaultAddress(
|
|
415
|
+
surf,
|
|
416
|
+
state.walletAddress
|
|
417
|
+
);
|
|
418
|
+
const tx = await surf.deposit({
|
|
419
|
+
asset: SURFLIQUID_USDC_ADDRESS,
|
|
420
|
+
amount: human
|
|
421
|
+
});
|
|
422
|
+
await tx.wait();
|
|
423
|
+
return { txHash: tx.hash, smartWallet, amount };
|
|
424
|
+
}
|
|
425
|
+
async withdraw(state, _chainId, _token, amount) {
|
|
426
|
+
const surf = await this.connect(state);
|
|
427
|
+
const human = amount != null ? (0, import_viem5.formatUnits)(BigInt(amount), SURFLIQUID_USDC_DECIMALS) : void 0;
|
|
428
|
+
try {
|
|
429
|
+
const tx = await surf.withdraw({
|
|
430
|
+
asset: SURFLIQUID_USDC_ADDRESS,
|
|
431
|
+
amount: human
|
|
432
|
+
});
|
|
433
|
+
await tx.wait();
|
|
434
|
+
return {
|
|
435
|
+
txHash: tx.hash,
|
|
436
|
+
type: amount != null ? "partial" : "full",
|
|
437
|
+
amount: amount ?? "0"
|
|
438
|
+
};
|
|
439
|
+
} catch (error) {
|
|
440
|
+
throw new OwneyError(
|
|
441
|
+
"WITHDRAW_FAILED",
|
|
442
|
+
error instanceof Error ? error.message : "SurfLiquid withdraw failed.",
|
|
443
|
+
{ chainId: SURFLIQUID_CHAIN_ID, amount },
|
|
444
|
+
this.id
|
|
445
|
+
);
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
// --- IAgent: portfolio reads ---
|
|
449
|
+
async getBalances(state, chainId) {
|
|
450
|
+
const surf = await this.connect(state);
|
|
451
|
+
const vault = await surf.getVault(state.walletAddress);
|
|
452
|
+
const morphoVaultAddresses = (vault.assets ?? []).filter((asset) => asset.assetSymbol === "USDC" && asset.chainId === chainId).map((asset) => asset.morphoVaultAddress).filter((address) => Boolean(address));
|
|
453
|
+
const morphoStats = await fetchMorphoStatsByVault(
|
|
454
|
+
morphoVaultAddresses,
|
|
455
|
+
chainId
|
|
456
|
+
);
|
|
457
|
+
return mapBalances2(vault, chainId, morphoStats);
|
|
458
|
+
}
|
|
459
|
+
async getEarnings(state) {
|
|
460
|
+
const surf = await this.connect(state);
|
|
461
|
+
const vault = await surf.getVault(state.walletAddress);
|
|
462
|
+
return mapEarnings2(vault, vault.userVaultAddress ?? state.walletAddress);
|
|
463
|
+
}
|
|
464
|
+
async getAccountApy(state, _chainId, days, _tokenSymbol) {
|
|
465
|
+
const surf = await this.connect(state);
|
|
466
|
+
const vault = await surf.getVault(state.walletAddress);
|
|
467
|
+
return mapAccountApy(vault, days);
|
|
468
|
+
}
|
|
469
|
+
async getHistory(state, chainId, options) {
|
|
470
|
+
const surf = await this.connect(state);
|
|
471
|
+
const page = options?.cursor ? Number(options.cursor) : 1;
|
|
472
|
+
const limit = options?.limit ?? 10;
|
|
473
|
+
const result = await surf.getAgentMessages(
|
|
474
|
+
state.walletAddress,
|
|
475
|
+
page,
|
|
476
|
+
limit,
|
|
477
|
+
options?.fromDate,
|
|
478
|
+
options?.toDate
|
|
479
|
+
);
|
|
480
|
+
return mapHistory(result, chainId);
|
|
481
|
+
}
|
|
482
|
+
async getUserProfile(state) {
|
|
483
|
+
const surf = await this.connect(state);
|
|
484
|
+
const vault = await surf.getVault(state.walletAddress);
|
|
485
|
+
return mapUserProfile2(vault, state.walletAddress);
|
|
486
|
+
}
|
|
487
|
+
// --- IAgent: discovery (no wallet) ---
|
|
488
|
+
async getAgentApy(days, _options) {
|
|
489
|
+
const surf = this.ensureSurf();
|
|
490
|
+
const assets = await surf.getSupportedAssets(SURFLIQUID_CHAIN_ID);
|
|
491
|
+
const usdc = assets.find((asset) => asset.assetSymbol === "USDC");
|
|
492
|
+
if (!usdc) return { averageApy: 0 };
|
|
493
|
+
const windowed = usdc[APY_WINDOW_KEY2[days]];
|
|
494
|
+
return { averageApy: windowed != null ? windowed : usdc.currentAPY };
|
|
495
|
+
}
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
});
|
|
499
|
+
|
|
20
500
|
// src/index.ts
|
|
21
501
|
var index_exports = {};
|
|
22
502
|
__export(index_exports, {
|
|
@@ -89,56 +569,8 @@ var SupportedAssets = [
|
|
|
89
569
|
}
|
|
90
570
|
];
|
|
91
571
|
|
|
92
|
-
// src/errors.ts
|
|
93
|
-
var OwneyError = class extends Error {
|
|
94
|
-
code;
|
|
95
|
-
details;
|
|
96
|
-
agentId;
|
|
97
|
-
constructor(code, message, details, agentId) {
|
|
98
|
-
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
99
|
-
super(`${prefix} ${message}`);
|
|
100
|
-
this.name = "OwneyError";
|
|
101
|
-
this.code = code;
|
|
102
|
-
this.details = details;
|
|
103
|
-
this.agentId = agentId;
|
|
104
|
-
}
|
|
105
|
-
};
|
|
106
|
-
var AgentNotFoundError = class extends OwneyError {
|
|
107
|
-
constructor(agentId, available) {
|
|
108
|
-
super(
|
|
109
|
-
"AGENT_NOT_FOUND",
|
|
110
|
-
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
111
|
-
{ agentId, available },
|
|
112
|
-
agentId
|
|
113
|
-
);
|
|
114
|
-
this.name = "AgentNotFoundError";
|
|
115
|
-
}
|
|
116
|
-
};
|
|
117
|
-
var NotConnectedError = class extends OwneyError {
|
|
118
|
-
constructor() {
|
|
119
|
-
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
120
|
-
this.name = "NotConnectedError";
|
|
121
|
-
}
|
|
122
|
-
};
|
|
123
|
-
var AgentChainIncompatibleError = class extends OwneyError {
|
|
124
|
-
incompatibleAgents;
|
|
125
|
-
connectedChainId;
|
|
126
|
-
constructor(incompatibleAgents, connectedChainId) {
|
|
127
|
-
const details = incompatibleAgents.map(
|
|
128
|
-
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
129
|
-
).join("; ");
|
|
130
|
-
super(
|
|
131
|
-
"AGENT_CHAIN_INCOMPATIBLE",
|
|
132
|
-
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
133
|
-
{ incompatibleAgents, connectedChainId }
|
|
134
|
-
);
|
|
135
|
-
this.name = "AgentChainIncompatibleError";
|
|
136
|
-
this.incompatibleAgents = incompatibleAgents;
|
|
137
|
-
this.connectedChainId = connectedChainId;
|
|
138
|
-
}
|
|
139
|
-
};
|
|
140
|
-
|
|
141
572
|
// src/lib/utils.ts
|
|
573
|
+
init_errors();
|
|
142
574
|
var isValidChainId = (chainId) => {
|
|
143
575
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
144
576
|
throw new OwneyError(
|
|
@@ -212,46 +644,46 @@ function resolveChainId(chain) {
|
|
|
212
644
|
function mapBalances(raw, _chainId, smartWallet) {
|
|
213
645
|
const portfolio = raw.portfolio;
|
|
214
646
|
const portfolioByChain = portfolio.portfolioByChain ?? {};
|
|
647
|
+
const rawPositions = portfolio.positions ?? [];
|
|
648
|
+
const detailByKey = /* @__PURE__ */ new Map();
|
|
649
|
+
for (const p of rawPositions) {
|
|
650
|
+
const cid = resolveChainId(p.chain ?? "");
|
|
651
|
+
const symbol = (p.token_symbol ?? "").toUpperCase();
|
|
652
|
+
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
653
|
+
}
|
|
215
654
|
let totalBalance = 0;
|
|
216
655
|
const tokens = [];
|
|
656
|
+
const positions = [];
|
|
217
657
|
for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
|
|
218
658
|
const positionChainId = Number(chainIdKey);
|
|
659
|
+
const chainName = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
|
|
219
660
|
for (const [symbol, { balance, decimals }] of Object.entries(
|
|
220
661
|
tokensBySymbol ?? {}
|
|
221
662
|
)) {
|
|
222
|
-
const amount = hexToDecimal(balance || "0", decimals);
|
|
663
|
+
const amount = hexToDecimal(balance || "0", tokenDecimals(symbol, decimals));
|
|
223
664
|
totalBalance += amount;
|
|
224
665
|
tokens.push({
|
|
225
|
-
chain:
|
|
666
|
+
chain: chainName,
|
|
226
667
|
chainId: positionChainId,
|
|
227
668
|
asset: symbol,
|
|
228
669
|
amount: String(amount)
|
|
229
670
|
});
|
|
671
|
+
const detail = detailByKey.get(`${positionChainId}:${symbol.toUpperCase()}`);
|
|
672
|
+
positions.push({
|
|
673
|
+
chain: chainName,
|
|
674
|
+
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
675
|
+
protocolId: detail?.protocol_id,
|
|
676
|
+
pool: detail?.pool,
|
|
677
|
+
asset: symbol,
|
|
678
|
+
amount: String(amount),
|
|
679
|
+
apy: detail?.pool_apy,
|
|
680
|
+
tvl: detail?.pool_tvl,
|
|
681
|
+
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
682
|
+
// structural read keeps it undefined today and auto-populates later.
|
|
683
|
+
liquidity: detail?.liquidity
|
|
684
|
+
});
|
|
230
685
|
}
|
|
231
686
|
}
|
|
232
|
-
const positions = (portfolio.positions ?? []).map((p) => ({
|
|
233
|
-
chain: p.chain ?? "",
|
|
234
|
-
protocol: p.protocol_name ?? p.protocol_id ?? "",
|
|
235
|
-
protocolId: p.protocol_id,
|
|
236
|
-
pool: p.pool,
|
|
237
|
-
asset: p.token_symbol ?? "",
|
|
238
|
-
// Position amount is hex-encoded base units (like the token balances
|
|
239
|
-
// above). `PositionSlot` doesn't type a `decimals` field, but runtime
|
|
240
|
-
// getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
|
|
241
|
-
// when present, otherwise fall back to the per-symbol lookup so
|
|
242
|
-
// non-6-decimal assets like WETH don't render 1e12 too large.
|
|
243
|
-
amount: String(
|
|
244
|
-
hexToDecimal(
|
|
245
|
-
p.amount || "0",
|
|
246
|
-
tokenDecimals(p.token_symbol, p.decimals)
|
|
247
|
-
)
|
|
248
|
-
),
|
|
249
|
-
apy: p.pool_apy,
|
|
250
|
-
tvl: p.pool_tvl,
|
|
251
|
-
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
252
|
-
// structural read keeps it undefined today and auto-populates later.
|
|
253
|
-
liquidity: p.liquidity
|
|
254
|
-
}));
|
|
255
687
|
return {
|
|
256
688
|
smartWallet,
|
|
257
689
|
totalBalance: String(totalBalance),
|
|
@@ -528,6 +960,9 @@ function decodeHistoryCursor(token) {
|
|
|
528
960
|
return parsed;
|
|
529
961
|
}
|
|
530
962
|
|
|
963
|
+
// src/agents/zyfai/zyfai.agent.ts
|
|
964
|
+
init_errors();
|
|
965
|
+
|
|
531
966
|
// src/agents/zyfai/zyfai.auth-cache.ts
|
|
532
967
|
var KEY_PREFIX = "owney.zyfai.session";
|
|
533
968
|
var storage = () => {
|
|
@@ -1515,7 +1950,11 @@ var ZyfaiAgent = class {
|
|
|
1515
1950
|
}
|
|
1516
1951
|
};
|
|
1517
1952
|
|
|
1953
|
+
// src/client.ts
|
|
1954
|
+
init_errors();
|
|
1955
|
+
|
|
1518
1956
|
// src/lib/routing-api.ts
|
|
1957
|
+
init_errors();
|
|
1519
1958
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1520
1959
|
async function fetchOrgAgentConfig(apiKey) {
|
|
1521
1960
|
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/org-config`;
|
|
@@ -1580,6 +2019,7 @@ async function fetchAgentKeys(apiKey) {
|
|
|
1580
2019
|
}
|
|
1581
2020
|
|
|
1582
2021
|
// src/lib/health-report.ts
|
|
2022
|
+
init_errors();
|
|
1583
2023
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1584
2024
|
async function reportAgentFailure(apiKey, agentType, errorCode) {
|
|
1585
2025
|
try {
|
|
@@ -1729,9 +2169,12 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
1729
2169
|
}
|
|
1730
2170
|
|
|
1731
2171
|
// src/client.ts
|
|
1732
|
-
var
|
|
2172
|
+
var import_viem6 = require("viem");
|
|
1733
2173
|
var import_chains2 = require("viem/chains");
|
|
1734
2174
|
|
|
2175
|
+
// src/lib/sponsored-deposit.ts
|
|
2176
|
+
init_errors();
|
|
2177
|
+
|
|
1735
2178
|
// src/lib/transfer-auth.ts
|
|
1736
2179
|
var import_viem3 = require("viem");
|
|
1737
2180
|
var ERC20_META_ABI = [
|
|
@@ -1769,6 +2212,7 @@ function randomAuthNonce() {
|
|
|
1769
2212
|
}
|
|
1770
2213
|
|
|
1771
2214
|
// src/lib/sponsor-client.ts
|
|
2215
|
+
init_errors();
|
|
1772
2216
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1773
2217
|
async function postSponsorTransferAuth(input) {
|
|
1774
2218
|
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
@@ -2037,6 +2481,7 @@ function makeSponsoredDepositCallback(deps) {
|
|
|
2037
2481
|
}
|
|
2038
2482
|
|
|
2039
2483
|
// src/lib/sponsored-weth-deposit.ts
|
|
2484
|
+
init_errors();
|
|
2040
2485
|
var PERMIT_WINDOW_SECONDS = 15 * 60;
|
|
2041
2486
|
function makeSponsoredWethCallback(deps) {
|
|
2042
2487
|
const get = deps.httpGet ?? getSponsorRelayerAddress;
|
|
@@ -2145,6 +2590,7 @@ var VIEM_CHAIN2 = {
|
|
|
2145
2590
|
42161: import_chains2.arbitrum,
|
|
2146
2591
|
1: import_chains2.mainnet
|
|
2147
2592
|
};
|
|
2593
|
+
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
2148
2594
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
2149
2595
|
8453: "0x4200000000000000000000000000000000000006",
|
|
2150
2596
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -2173,6 +2619,7 @@ var OwneySDK = class {
|
|
|
2173
2619
|
zyfaiRpcUrls;
|
|
2174
2620
|
routingApiBaseUrl;
|
|
2175
2621
|
referralSource;
|
|
2622
|
+
surfliquidApiBaseUrl;
|
|
2176
2623
|
cachedSponsoredCallback = null;
|
|
2177
2624
|
cachedWethSponsoredCallback = null;
|
|
2178
2625
|
initializingAgentsPromise = null;
|
|
@@ -2182,6 +2629,7 @@ var OwneySDK = class {
|
|
|
2182
2629
|
this.zyfaiRpcUrls = config.zyfaiRpcUrls;
|
|
2183
2630
|
this.routingApiBaseUrl = config.routingApiBaseUrl;
|
|
2184
2631
|
this.referralSource = config.referralSource;
|
|
2632
|
+
this.surfliquidApiBaseUrl = config.surfliquidApiBaseUrl;
|
|
2185
2633
|
}
|
|
2186
2634
|
/**
|
|
2187
2635
|
* Establish connection state for all subsequent SDK calls.
|
|
@@ -2279,14 +2727,14 @@ var OwneySDK = class {
|
|
|
2279
2727
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2280
2728
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2281
2729
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2282
|
-
getPublicClient: (cid) => (0,
|
|
2730
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
2283
2731
|
chain: VIEM_CHAIN2[cid],
|
|
2284
|
-
transport: (0,
|
|
2732
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2285
2733
|
}),
|
|
2286
|
-
getWalletClient: (cid) => (0,
|
|
2734
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
2287
2735
|
account: owner,
|
|
2288
2736
|
chain: VIEM_CHAIN2[cid],
|
|
2289
|
-
transport: (0,
|
|
2737
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2290
2738
|
})
|
|
2291
2739
|
});
|
|
2292
2740
|
if (!onApproved) this.cachedSponsoredCallback = callback;
|
|
@@ -2312,14 +2760,14 @@ var OwneySDK = class {
|
|
|
2312
2760
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2313
2761
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2314
2762
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2315
|
-
getPublicClient: (cid) => (0,
|
|
2763
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
2316
2764
|
chain: VIEM_CHAIN2[cid],
|
|
2317
|
-
transport: (0,
|
|
2765
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2318
2766
|
}),
|
|
2319
|
-
getWalletClient: (cid) => (0,
|
|
2767
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
2320
2768
|
account: owner,
|
|
2321
2769
|
chain: VIEM_CHAIN2[cid],
|
|
2322
|
-
transport: (0,
|
|
2770
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2323
2771
|
})
|
|
2324
2772
|
});
|
|
2325
2773
|
if (!onApproved) this.cachedWethSponsoredCallback = callback;
|
|
@@ -2389,8 +2837,8 @@ var OwneySDK = class {
|
|
|
2389
2837
|
this.initializingAgentsPromise = (async () => {
|
|
2390
2838
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
2391
2839
|
this.disabledAgents.clear();
|
|
2392
|
-
for (const { key: key2, agent_type, is_enabled } of agentKeys) {
|
|
2393
|
-
const agent = this.createAgent(agent_type, key2);
|
|
2840
|
+
for (const { key: key2, agent_type, project_name, is_enabled } of agentKeys) {
|
|
2841
|
+
const agent = await this.createAgent(agent_type, key2, project_name);
|
|
2394
2842
|
if (!agent) continue;
|
|
2395
2843
|
this.agents.set(agent_type, agent);
|
|
2396
2844
|
if (is_enabled === false) {
|
|
@@ -2411,10 +2859,22 @@ var OwneySDK = class {
|
|
|
2411
2859
|
this.initializingAgentsPromise = null;
|
|
2412
2860
|
}
|
|
2413
2861
|
}
|
|
2414
|
-
createAgent(agentId, key2) {
|
|
2862
|
+
async createAgent(agentId, key2, projectName) {
|
|
2415
2863
|
if (agentId === "zyfai") {
|
|
2416
2864
|
return new ZyfaiAgent(key2, this.zyfaiRpcUrls, this.referralSource);
|
|
2417
2865
|
}
|
|
2866
|
+
if (agentId === "surfliquid") {
|
|
2867
|
+
if (!projectName) return null;
|
|
2868
|
+
const { SurfLiquidAgent: SurfLiquidAgent2 } = await Promise.resolve().then(() => (init_surfliquid_agent(), surfliquid_agent_exports));
|
|
2869
|
+
return new SurfLiquidAgent2({
|
|
2870
|
+
projectName,
|
|
2871
|
+
appId: key2,
|
|
2872
|
+
// Same-origin proxy override — SurfLiquid auth is an httpOnly cookie,
|
|
2873
|
+
// which WebKit (iOS) discards when it is third-party. See
|
|
2874
|
+
// OwneySDKConfig.surfliquidApiBaseUrl.
|
|
2875
|
+
apiBaseUrl: this.surfliquidApiBaseUrl
|
|
2876
|
+
});
|
|
2877
|
+
}
|
|
2418
2878
|
return null;
|
|
2419
2879
|
}
|
|
2420
2880
|
// --- Account lifecycle ---
|
|
@@ -2569,18 +3029,30 @@ var OwneySDK = class {
|
|
|
2569
3029
|
);
|
|
2570
3030
|
}
|
|
2571
3031
|
const agentResults = {};
|
|
3032
|
+
const agentErrors = {};
|
|
2572
3033
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
2573
|
-
|
|
2574
|
-
agent
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
3034
|
+
try {
|
|
3035
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
3036
|
+
agent,
|
|
3037
|
+
state,
|
|
3038
|
+
chainId,
|
|
3039
|
+
agentAmount,
|
|
3040
|
+
asset,
|
|
3041
|
+
effectiveCallback,
|
|
3042
|
+
depositCallback
|
|
3043
|
+
);
|
|
3044
|
+
} catch (error) {
|
|
3045
|
+
agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
|
|
3046
|
+
}
|
|
3047
|
+
}
|
|
3048
|
+
if (Object.keys(agentResults).length === 0) {
|
|
3049
|
+
throw new OwneyError(
|
|
3050
|
+
"DEPOSIT_ALL_FAILED",
|
|
3051
|
+
`All ${agentAmounts.length} agent deposit(s) failed.`,
|
|
3052
|
+
{ agentErrors }
|
|
2581
3053
|
);
|
|
2582
3054
|
}
|
|
2583
|
-
return { agentResults };
|
|
3055
|
+
return Object.keys(agentErrors).length > 0 ? { agentResults, agentErrors } : { agentResults };
|
|
2584
3056
|
}
|
|
2585
3057
|
/**
|
|
2586
3058
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -2737,6 +3209,34 @@ var OwneySDK = class {
|
|
|
2737
3209
|
}
|
|
2738
3210
|
return eligible;
|
|
2739
3211
|
}
|
|
3212
|
+
/**
|
|
3213
|
+
* Agent ids the routing API provisioned for this org that support the given
|
|
3214
|
+
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
3215
|
+
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
3216
|
+
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
3217
|
+
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
3218
|
+
*
|
|
3219
|
+
* This is the source of truth for agent availability: an agent appears here
|
|
3220
|
+
* iff the routing API returned its key. No per-app feature flags.
|
|
3221
|
+
*/
|
|
3222
|
+
async getEligibleAgentIds(chainId, asset) {
|
|
3223
|
+
try {
|
|
3224
|
+
await this.ensureAgentsInitialized();
|
|
3225
|
+
} catch (error) {
|
|
3226
|
+
if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
|
|
3227
|
+
return [];
|
|
3228
|
+
}
|
|
3229
|
+
throw error;
|
|
3230
|
+
}
|
|
3231
|
+
return [...this.agents.values()].filter((agent) => {
|
|
3232
|
+
const chainAssets = agent.supportedAssets.find(
|
|
3233
|
+
(sa) => sa.chainId === chainId
|
|
3234
|
+
);
|
|
3235
|
+
return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
|
|
3236
|
+
}).map((agent) => agent.id).sort(
|
|
3237
|
+
(a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
|
|
3238
|
+
);
|
|
3239
|
+
}
|
|
2740
3240
|
// --- Fund operations ---
|
|
2741
3241
|
/**
|
|
2742
3242
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -2772,9 +3272,17 @@ var OwneySDK = class {
|
|
|
2772
3272
|
}
|
|
2773
3273
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
2774
3274
|
if (!amount) {
|
|
3275
|
+
const aggregated2 = await this.getBalances();
|
|
3276
|
+
const funded = projectAgentBalancesForAsset(
|
|
3277
|
+
eligibleAgents,
|
|
3278
|
+
aggregated2.agentBalances,
|
|
3279
|
+
chainId,
|
|
3280
|
+
asset,
|
|
3281
|
+
assetInfo.decimals
|
|
3282
|
+
).filter((b) => b.balance > 0n);
|
|
2775
3283
|
const results2 = {};
|
|
2776
3284
|
const agentErrors2 = {};
|
|
2777
|
-
for (const agent of
|
|
3285
|
+
for (const { agent } of funded) {
|
|
2778
3286
|
try {
|
|
2779
3287
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
2780
3288
|
} catch (err) {
|
|
@@ -2791,9 +3299,10 @@ var OwneySDK = class {
|
|
|
2791
3299
|
{ asset, agentErrors: agentErrors2 }
|
|
2792
3300
|
);
|
|
2793
3301
|
}
|
|
3302
|
+
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
2794
3303
|
return {
|
|
2795
3304
|
agentResult: results2,
|
|
2796
|
-
totalWithdrawn:
|
|
3305
|
+
totalWithdrawn: totalWithdrawn.toString()
|
|
2797
3306
|
};
|
|
2798
3307
|
}
|
|
2799
3308
|
const requested = BigInt(amount);
|
|
@@ -3163,10 +3672,10 @@ var OwneySDK = class {
|
|
|
3163
3672
|
);
|
|
3164
3673
|
}
|
|
3165
3674
|
const provider = this.requireConnectedProvider();
|
|
3166
|
-
const wallet = (0,
|
|
3675
|
+
const wallet = (0, import_viem6.createWalletClient)({
|
|
3167
3676
|
account: state.walletAddress,
|
|
3168
3677
|
chain: VIEM_CHAIN2[chainId],
|
|
3169
|
-
transport: (0,
|
|
3678
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3170
3679
|
});
|
|
3171
3680
|
const hash = await wallet.writeContract({
|
|
3172
3681
|
address: token,
|
|
@@ -3176,9 +3685,9 @@ var OwneySDK = class {
|
|
|
3176
3685
|
account: state.walletAddress,
|
|
3177
3686
|
chain: VIEM_CHAIN2[chainId]
|
|
3178
3687
|
});
|
|
3179
|
-
const publicClient = (0,
|
|
3688
|
+
const publicClient = (0, import_viem6.createPublicClient)({
|
|
3180
3689
|
chain: VIEM_CHAIN2[chainId],
|
|
3181
|
-
transport: (0,
|
|
3690
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3182
3691
|
});
|
|
3183
3692
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
3184
3693
|
hash,
|
|
@@ -3286,8 +3795,11 @@ var OwneySDK = class {
|
|
|
3286
3795
|
}
|
|
3287
3796
|
};
|
|
3288
3797
|
|
|
3798
|
+
// src/index.ts
|
|
3799
|
+
init_errors();
|
|
3800
|
+
|
|
3289
3801
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
3290
|
-
var
|
|
3802
|
+
var import_viem7 = require("viem");
|
|
3291
3803
|
var import_siwe = require("siwe");
|
|
3292
3804
|
var import_sdk2 = require("@zyfai/sdk");
|
|
3293
3805
|
|
|
@@ -3414,7 +3926,7 @@ function buildSIWXConfig(deps) {
|
|
|
3414
3926
|
issuedAt,
|
|
3415
3927
|
toString() {
|
|
3416
3928
|
return new import_siwe.SiweMessage({
|
|
3417
|
-
address: (0,
|
|
3929
|
+
address: (0, import_viem7.getAddress)(accountAddress),
|
|
3418
3930
|
chainId: numericChainId(chainId),
|
|
3419
3931
|
domain,
|
|
3420
3932
|
uri,
|