@owney/sdk 0.6.7-beta.1 → 0.6.7-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 +191 -624
- package/dist/index.d.cts +2 -19
- package/dist/index.d.ts +2 -19
- package/dist/index.js +176 -117
- package/package.json +1 -3
- package/dist/chunk-GMNQBWUB.js +0 -55
- package/dist/surfliquid.agent-OMOYXWLP.js +0 -385
package/dist/index.cjs
CHANGED
|
@@ -3,14 +3,6 @@ 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
|
-
};
|
|
14
6
|
var __export = (target, all) => {
|
|
15
7
|
for (var name in all)
|
|
16
8
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -25,478 +17,6 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
25
17
|
};
|
|
26
18
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
27
19
|
|
|
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
|
-
|
|
500
20
|
// src/index.ts
|
|
501
21
|
var index_exports = {};
|
|
502
22
|
__export(index_exports, {
|
|
@@ -568,8 +88,56 @@ var SupportedAssets = [
|
|
|
568
88
|
}
|
|
569
89
|
];
|
|
570
90
|
|
|
91
|
+
// src/errors.ts
|
|
92
|
+
var OwneyError = class extends Error {
|
|
93
|
+
code;
|
|
94
|
+
details;
|
|
95
|
+
agentId;
|
|
96
|
+
constructor(code, message, details, agentId) {
|
|
97
|
+
const prefix = agentId ? `[${code}][agent:${agentId}]` : `[${code}]`;
|
|
98
|
+
super(`${prefix} ${message}`);
|
|
99
|
+
this.name = "OwneyError";
|
|
100
|
+
this.code = code;
|
|
101
|
+
this.details = details;
|
|
102
|
+
this.agentId = agentId;
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
var AgentNotFoundError = class extends OwneyError {
|
|
106
|
+
constructor(agentId, available) {
|
|
107
|
+
super(
|
|
108
|
+
"AGENT_NOT_FOUND",
|
|
109
|
+
`Unknown agent "${agentId}". Available agents: ${available.join(", ")}`,
|
|
110
|
+
{ agentId, available },
|
|
111
|
+
agentId
|
|
112
|
+
);
|
|
113
|
+
this.name = "AgentNotFoundError";
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
var NotConnectedError = class extends OwneyError {
|
|
117
|
+
constructor() {
|
|
118
|
+
super("NOT_CONNECTED", "Not connected. Call sdk.connect(provider) first.");
|
|
119
|
+
this.name = "NotConnectedError";
|
|
120
|
+
}
|
|
121
|
+
};
|
|
122
|
+
var AgentChainIncompatibleError = class extends OwneyError {
|
|
123
|
+
incompatibleAgents;
|
|
124
|
+
connectedChainId;
|
|
125
|
+
constructor(incompatibleAgents, connectedChainId) {
|
|
126
|
+
const details = incompatibleAgents.map(
|
|
127
|
+
({ agentId, supportedChainIds }) => `"${agentId}" supports chains [${supportedChainIds.join(", ")}]`
|
|
128
|
+
).join("; ");
|
|
129
|
+
super(
|
|
130
|
+
"AGENT_CHAIN_INCOMPATIBLE",
|
|
131
|
+
`Chain ${connectedChainId} is not supported by the following agents: ${details}`,
|
|
132
|
+
{ incompatibleAgents, connectedChainId }
|
|
133
|
+
);
|
|
134
|
+
this.name = "AgentChainIncompatibleError";
|
|
135
|
+
this.incompatibleAgents = incompatibleAgents;
|
|
136
|
+
this.connectedChainId = connectedChainId;
|
|
137
|
+
}
|
|
138
|
+
};
|
|
139
|
+
|
|
571
140
|
// src/lib/utils.ts
|
|
572
|
-
init_errors();
|
|
573
141
|
var isValidChainId = (chainId) => {
|
|
574
142
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
575
143
|
throw new OwneyError(
|
|
@@ -643,46 +211,46 @@ function resolveChainId(chain) {
|
|
|
643
211
|
function mapBalances(raw, _chainId, smartWallet) {
|
|
644
212
|
const portfolio = raw.portfolio;
|
|
645
213
|
const portfolioByChain = portfolio.portfolioByChain ?? {};
|
|
646
|
-
const rawPositions = portfolio.positions ?? [];
|
|
647
|
-
const detailByKey = /* @__PURE__ */ new Map();
|
|
648
|
-
for (const p of rawPositions) {
|
|
649
|
-
const cid = resolveChainId(p.chain ?? "");
|
|
650
|
-
const symbol = (p.token_symbol ?? "").toUpperCase();
|
|
651
|
-
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
652
|
-
}
|
|
653
214
|
let totalBalance = 0;
|
|
654
215
|
const tokens = [];
|
|
655
|
-
const positions = [];
|
|
656
216
|
for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
|
|
657
217
|
const positionChainId = Number(chainIdKey);
|
|
658
|
-
const chainName = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
|
|
659
218
|
for (const [symbol, { balance, decimals }] of Object.entries(
|
|
660
219
|
tokensBySymbol ?? {}
|
|
661
220
|
)) {
|
|
662
|
-
const amount = hexToDecimal(balance || "0",
|
|
221
|
+
const amount = hexToDecimal(balance || "0", decimals);
|
|
663
222
|
totalBalance += amount;
|
|
664
223
|
tokens.push({
|
|
665
|
-
chain:
|
|
224
|
+
chain: CHAIN_ID_TO_NAME[positionChainId] ?? "BASE",
|
|
666
225
|
chainId: positionChainId,
|
|
667
226
|
asset: symbol,
|
|
668
227
|
amount: String(amount)
|
|
669
228
|
});
|
|
670
|
-
const detail = detailByKey.get(`${positionChainId}:${symbol.toUpperCase()}`);
|
|
671
|
-
positions.push({
|
|
672
|
-
chain: chainName,
|
|
673
|
-
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
674
|
-
protocolId: detail?.protocol_id,
|
|
675
|
-
pool: detail?.pool,
|
|
676
|
-
asset: symbol,
|
|
677
|
-
amount: String(amount),
|
|
678
|
-
apy: detail?.pool_apy,
|
|
679
|
-
tvl: detail?.pool_tvl,
|
|
680
|
-
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
681
|
-
// structural read keeps it undefined today and auto-populates later.
|
|
682
|
-
liquidity: detail?.liquidity
|
|
683
|
-
});
|
|
684
229
|
}
|
|
685
230
|
}
|
|
231
|
+
const positions = (portfolio.positions ?? []).map((p) => ({
|
|
232
|
+
chain: p.chain ?? "",
|
|
233
|
+
protocol: p.protocol_name ?? p.protocol_id ?? "",
|
|
234
|
+
protocolId: p.protocol_id,
|
|
235
|
+
pool: p.pool,
|
|
236
|
+
asset: p.token_symbol ?? "",
|
|
237
|
+
// Position amount is hex-encoded base units (like the token balances
|
|
238
|
+
// above). `PositionSlot` doesn't type a `decimals` field, but runtime
|
|
239
|
+
// getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
|
|
240
|
+
// when present, otherwise fall back to the per-symbol lookup so
|
|
241
|
+
// non-6-decimal assets like WETH don't render 1e12 too large.
|
|
242
|
+
amount: String(
|
|
243
|
+
hexToDecimal(
|
|
244
|
+
p.amount || "0",
|
|
245
|
+
tokenDecimals(p.token_symbol, p.decimals)
|
|
246
|
+
)
|
|
247
|
+
),
|
|
248
|
+
apy: p.pool_apy,
|
|
249
|
+
tvl: p.pool_tvl,
|
|
250
|
+
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
251
|
+
// structural read keeps it undefined today and auto-populates later.
|
|
252
|
+
liquidity: p.liquidity
|
|
253
|
+
}));
|
|
686
254
|
return {
|
|
687
255
|
smartWallet,
|
|
688
256
|
totalBalance: String(totalBalance),
|
|
@@ -957,9 +525,6 @@ function decodeHistoryCursor(token) {
|
|
|
957
525
|
return parsed;
|
|
958
526
|
}
|
|
959
527
|
|
|
960
|
-
// src/agents/zyfai/zyfai.agent.ts
|
|
961
|
-
init_errors();
|
|
962
|
-
|
|
963
528
|
// src/agents/zyfai/zyfai.auth-cache.ts
|
|
964
529
|
var KEY_PREFIX = "owney.zyfai.session";
|
|
965
530
|
var storage = () => {
|
|
@@ -970,7 +535,8 @@ var storage = () => {
|
|
|
970
535
|
return null;
|
|
971
536
|
}
|
|
972
537
|
};
|
|
973
|
-
var buildKey = (address
|
|
538
|
+
var buildKey = (address) => `${KEY_PREFIX}:${address.toLowerCase()}`;
|
|
539
|
+
var legacyKeyPrefix = (address) => `${KEY_PREFIX}:${address.toLowerCase()}:`;
|
|
974
540
|
var isJwtExpired = (token) => {
|
|
975
541
|
const parts = token.split(".");
|
|
976
542
|
if (parts.length !== 3) return false;
|
|
@@ -987,9 +553,37 @@ var isJwtExpired = (token) => {
|
|
|
987
553
|
};
|
|
988
554
|
var memorySessions = /* @__PURE__ */ new Map();
|
|
989
555
|
var isFreshSession = (session) => !!session && !!session.token && !isJwtExpired(session.token);
|
|
990
|
-
var
|
|
556
|
+
var readLegacySession = (store, address) => {
|
|
557
|
+
if (!store) return null;
|
|
558
|
+
const prefix = legacyKeyPrefix(address);
|
|
559
|
+
const legacyKeys = [];
|
|
560
|
+
try {
|
|
561
|
+
for (let i = 0; i < store.length; i++) {
|
|
562
|
+
const key = store.key(i);
|
|
563
|
+
if (key?.startsWith(prefix)) legacyKeys.push(key);
|
|
564
|
+
}
|
|
565
|
+
} catch {
|
|
566
|
+
return null;
|
|
567
|
+
}
|
|
568
|
+
let adopted = null;
|
|
569
|
+
for (const key of legacyKeys) {
|
|
570
|
+
if (!adopted) {
|
|
571
|
+
try {
|
|
572
|
+
const parsed = JSON.parse(store.getItem(key) ?? "");
|
|
573
|
+
if (isFreshSession(parsed)) adopted = parsed;
|
|
574
|
+
} catch {
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
try {
|
|
578
|
+
store.removeItem(key);
|
|
579
|
+
} catch {
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
return adopted;
|
|
583
|
+
};
|
|
584
|
+
var readSession = (address, _chainId) => {
|
|
991
585
|
if (typeof window === "undefined") return null;
|
|
992
|
-
const key = buildKey(address
|
|
586
|
+
const key = buildKey(address);
|
|
993
587
|
const store = storage();
|
|
994
588
|
let raw = null;
|
|
995
589
|
try {
|
|
@@ -1010,14 +604,19 @@ var readSession = (address, chainId) => {
|
|
|
1010
604
|
}
|
|
1011
605
|
return null;
|
|
1012
606
|
}
|
|
607
|
+
const legacy = readLegacySession(store, address);
|
|
608
|
+
if (legacy) {
|
|
609
|
+
writeSession(address, _chainId, legacy);
|
|
610
|
+
return legacy;
|
|
611
|
+
}
|
|
1013
612
|
const cached = memorySessions.get(key);
|
|
1014
613
|
if (isFreshSession(cached)) return cached;
|
|
1015
614
|
if (cached) memorySessions.delete(key);
|
|
1016
615
|
return null;
|
|
1017
616
|
};
|
|
1018
|
-
var writeSession = (address,
|
|
617
|
+
var writeSession = (address, _chainId, session) => {
|
|
1019
618
|
if (typeof window === "undefined") return;
|
|
1020
|
-
const key = buildKey(address
|
|
619
|
+
const key = buildKey(address);
|
|
1021
620
|
memorySessions.set(key, session);
|
|
1022
621
|
const store = storage();
|
|
1023
622
|
try {
|
|
@@ -1025,14 +624,15 @@ var writeSession = (address, chainId, session) => {
|
|
|
1025
624
|
} catch {
|
|
1026
625
|
}
|
|
1027
626
|
};
|
|
1028
|
-
var clearSession = (address,
|
|
1029
|
-
const key = buildKey(address
|
|
627
|
+
var clearSession = (address, _chainId) => {
|
|
628
|
+
const key = buildKey(address);
|
|
1030
629
|
memorySessions.delete(key);
|
|
1031
630
|
const store = storage();
|
|
1032
631
|
try {
|
|
1033
632
|
store?.removeItem(key);
|
|
1034
633
|
} catch {
|
|
1035
634
|
}
|
|
635
|
+
readLegacySession(store, address);
|
|
1036
636
|
};
|
|
1037
637
|
|
|
1038
638
|
// src/agents/zyfai/autoSelect.ts
|
|
@@ -1531,11 +1131,7 @@ var ZyfaiAgent = class {
|
|
|
1531
1131
|
}
|
|
1532
1132
|
};
|
|
1533
1133
|
|
|
1534
|
-
// src/client.ts
|
|
1535
|
-
init_errors();
|
|
1536
|
-
|
|
1537
1134
|
// src/lib/routing-api.ts
|
|
1538
|
-
init_errors();
|
|
1539
1135
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1540
1136
|
async function fetchAgentKeys(apiKey) {
|
|
1541
1137
|
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/keys`;
|
|
@@ -1566,7 +1162,6 @@ async function fetchAgentKeys(apiKey) {
|
|
|
1566
1162
|
}
|
|
1567
1163
|
|
|
1568
1164
|
// src/lib/health-report.ts
|
|
1569
|
-
init_errors();
|
|
1570
1165
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1571
1166
|
async function reportAgentFailure(apiKey, agentType, errorCode) {
|
|
1572
1167
|
try {
|
|
@@ -1716,12 +1311,9 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
1716
1311
|
}
|
|
1717
1312
|
|
|
1718
1313
|
// src/client.ts
|
|
1719
|
-
var
|
|
1314
|
+
var import_viem5 = require("viem");
|
|
1720
1315
|
var import_chains2 = require("viem/chains");
|
|
1721
1316
|
|
|
1722
|
-
// src/lib/sponsored-deposit.ts
|
|
1723
|
-
init_errors();
|
|
1724
|
-
|
|
1725
1317
|
// src/lib/transfer-auth.ts
|
|
1726
1318
|
var import_viem3 = require("viem");
|
|
1727
1319
|
var ERC20_META_ABI = [
|
|
@@ -1759,7 +1351,6 @@ function randomAuthNonce() {
|
|
|
1759
1351
|
}
|
|
1760
1352
|
|
|
1761
1353
|
// src/lib/sponsor-client.ts
|
|
1762
|
-
init_errors();
|
|
1763
1354
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1764
1355
|
async function postSponsorTransferAuth(input) {
|
|
1765
1356
|
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
@@ -1926,9 +1517,6 @@ function makeSponsoredDepositCallback(deps) {
|
|
|
1926
1517
|
};
|
|
1927
1518
|
}
|
|
1928
1519
|
|
|
1929
|
-
// src/lib/sponsored-weth-deposit.ts
|
|
1930
|
-
init_errors();
|
|
1931
|
-
|
|
1932
1520
|
// src/lib/permit2.ts
|
|
1933
1521
|
var import_viem4 = require("viem");
|
|
1934
1522
|
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
@@ -2068,7 +1656,6 @@ var VIEM_CHAIN2 = {
|
|
|
2068
1656
|
42161: import_chains2.arbitrum,
|
|
2069
1657
|
1: import_chains2.mainnet
|
|
2070
1658
|
};
|
|
2071
|
-
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
2072
1659
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
2073
1660
|
8453: "0x4200000000000000000000000000000000000006",
|
|
2074
1661
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -2192,14 +1779,14 @@ var OwneySDK = class {
|
|
|
2192
1779
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2193
1780
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2194
1781
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2195
|
-
getPublicClient: (cid) => (0,
|
|
1782
|
+
getPublicClient: (cid) => (0, import_viem5.createPublicClient)({
|
|
2196
1783
|
chain: VIEM_CHAIN2[cid],
|
|
2197
|
-
transport: (0,
|
|
1784
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2198
1785
|
}),
|
|
2199
|
-
getWalletClient: (cid) => (0,
|
|
1786
|
+
getWalletClient: (cid) => (0, import_viem5.createWalletClient)({
|
|
2200
1787
|
account: owner,
|
|
2201
1788
|
chain: VIEM_CHAIN2[cid],
|
|
2202
|
-
transport: (0,
|
|
1789
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2203
1790
|
})
|
|
2204
1791
|
});
|
|
2205
1792
|
return this.cachedSponsoredCallback;
|
|
@@ -2223,14 +1810,14 @@ var OwneySDK = class {
|
|
|
2223
1810
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2224
1811
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2225
1812
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2226
|
-
getPublicClient: (cid) => (0,
|
|
1813
|
+
getPublicClient: (cid) => (0, import_viem5.createPublicClient)({
|
|
2227
1814
|
chain: VIEM_CHAIN2[cid],
|
|
2228
|
-
transport: (0,
|
|
1815
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2229
1816
|
}),
|
|
2230
|
-
getWalletClient: (cid) => (0,
|
|
1817
|
+
getWalletClient: (cid) => (0, import_viem5.createWalletClient)({
|
|
2231
1818
|
account: owner,
|
|
2232
1819
|
chain: VIEM_CHAIN2[cid],
|
|
2233
|
-
transport: (0,
|
|
1820
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2234
1821
|
})
|
|
2235
1822
|
});
|
|
2236
1823
|
return this.cachedWethSponsoredCallback;
|
|
@@ -2256,8 +1843,8 @@ var OwneySDK = class {
|
|
|
2256
1843
|
this.initializingAgentsPromise = (async () => {
|
|
2257
1844
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
2258
1845
|
this.disabledAgents.clear();
|
|
2259
|
-
for (const { key, agent_type,
|
|
2260
|
-
const agent =
|
|
1846
|
+
for (const { key, agent_type, is_enabled } of agentKeys) {
|
|
1847
|
+
const agent = this.createAgent(agent_type, key);
|
|
2261
1848
|
if (!agent) continue;
|
|
2262
1849
|
this.agents.set(agent_type, agent);
|
|
2263
1850
|
if (is_enabled === false) {
|
|
@@ -2278,15 +1865,10 @@ var OwneySDK = class {
|
|
|
2278
1865
|
this.initializingAgentsPromise = null;
|
|
2279
1866
|
}
|
|
2280
1867
|
}
|
|
2281
|
-
|
|
1868
|
+
createAgent(agentId, key) {
|
|
2282
1869
|
if (agentId === "zyfai") {
|
|
2283
1870
|
return new ZyfaiAgent(key, this.zyfaiRpcUrls);
|
|
2284
1871
|
}
|
|
2285
|
-
if (agentId === "surfliquid") {
|
|
2286
|
-
if (!projectName) return null;
|
|
2287
|
-
const { SurfLiquidAgent: SurfLiquidAgent2 } = await Promise.resolve().then(() => (init_surfliquid_agent(), surfliquid_agent_exports));
|
|
2288
|
-
return new SurfLiquidAgent2({ projectName, appId: key });
|
|
2289
|
-
}
|
|
2290
1872
|
return null;
|
|
2291
1873
|
}
|
|
2292
1874
|
// --- Account lifecycle ---
|
|
@@ -2439,30 +2021,18 @@ var OwneySDK = class {
|
|
|
2439
2021
|
);
|
|
2440
2022
|
}
|
|
2441
2023
|
const agentResults = {};
|
|
2442
|
-
const agentErrors = {};
|
|
2443
2024
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
depositCallback
|
|
2453
|
-
);
|
|
2454
|
-
} catch (error) {
|
|
2455
|
-
agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
|
|
2456
|
-
}
|
|
2457
|
-
}
|
|
2458
|
-
if (Object.keys(agentResults).length === 0) {
|
|
2459
|
-
throw new OwneyError(
|
|
2460
|
-
"DEPOSIT_ALL_FAILED",
|
|
2461
|
-
`All ${agentAmounts.length} agent deposit(s) failed.`,
|
|
2462
|
-
{ agentErrors }
|
|
2025
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
2026
|
+
agent,
|
|
2027
|
+
state,
|
|
2028
|
+
chainId,
|
|
2029
|
+
agentAmount,
|
|
2030
|
+
asset,
|
|
2031
|
+
effectiveCallback,
|
|
2032
|
+
depositCallback
|
|
2463
2033
|
);
|
|
2464
2034
|
}
|
|
2465
|
-
return
|
|
2035
|
+
return { agentResults };
|
|
2466
2036
|
}
|
|
2467
2037
|
/**
|
|
2468
2038
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -2619,34 +2189,6 @@ var OwneySDK = class {
|
|
|
2619
2189
|
}
|
|
2620
2190
|
return eligible;
|
|
2621
2191
|
}
|
|
2622
|
-
/**
|
|
2623
|
-
* Agent ids the routing API provisioned for this org that support the given
|
|
2624
|
-
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
2625
|
-
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
2626
|
-
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
2627
|
-
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
2628
|
-
*
|
|
2629
|
-
* This is the source of truth for agent availability: an agent appears here
|
|
2630
|
-
* iff the routing API returned its key. No per-app feature flags.
|
|
2631
|
-
*/
|
|
2632
|
-
async getEligibleAgentIds(chainId, asset) {
|
|
2633
|
-
try {
|
|
2634
|
-
await this.ensureAgentsInitialized();
|
|
2635
|
-
} catch (error) {
|
|
2636
|
-
if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
|
|
2637
|
-
return [];
|
|
2638
|
-
}
|
|
2639
|
-
throw error;
|
|
2640
|
-
}
|
|
2641
|
-
return [...this.agents.values()].filter((agent) => {
|
|
2642
|
-
const chainAssets = agent.supportedAssets.find(
|
|
2643
|
-
(sa) => sa.chainId === chainId
|
|
2644
|
-
);
|
|
2645
|
-
return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
|
|
2646
|
-
}).map((agent) => agent.id).sort(
|
|
2647
|
-
(a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
|
|
2648
|
-
);
|
|
2649
|
-
}
|
|
2650
2192
|
// --- Fund operations ---
|
|
2651
2193
|
/**
|
|
2652
2194
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -2682,17 +2224,9 @@ var OwneySDK = class {
|
|
|
2682
2224
|
}
|
|
2683
2225
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
2684
2226
|
if (!amount) {
|
|
2685
|
-
const aggregated2 = await this.getBalances();
|
|
2686
|
-
const funded = projectAgentBalancesForAsset(
|
|
2687
|
-
eligibleAgents,
|
|
2688
|
-
aggregated2.agentBalances,
|
|
2689
|
-
chainId,
|
|
2690
|
-
asset,
|
|
2691
|
-
assetInfo.decimals
|
|
2692
|
-
).filter((b) => b.balance > 0n);
|
|
2693
2227
|
const results2 = {};
|
|
2694
2228
|
const agentErrors2 = {};
|
|
2695
|
-
for (const
|
|
2229
|
+
for (const agent of eligibleAgents) {
|
|
2696
2230
|
try {
|
|
2697
2231
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
2698
2232
|
} catch (err) {
|
|
@@ -2709,10 +2243,9 @@ var OwneySDK = class {
|
|
|
2709
2243
|
{ asset, agentErrors: agentErrors2 }
|
|
2710
2244
|
);
|
|
2711
2245
|
}
|
|
2712
|
-
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
2713
2246
|
return {
|
|
2714
2247
|
agentResult: results2,
|
|
2715
|
-
totalWithdrawn:
|
|
2248
|
+
totalWithdrawn: sumWithdrawnAmount(results2).toString()
|
|
2716
2249
|
};
|
|
2717
2250
|
}
|
|
2718
2251
|
const requested = BigInt(amount);
|
|
@@ -3082,10 +2615,10 @@ var OwneySDK = class {
|
|
|
3082
2615
|
);
|
|
3083
2616
|
}
|
|
3084
2617
|
const provider = this.requireConnectedProvider();
|
|
3085
|
-
const wallet = (0,
|
|
2618
|
+
const wallet = (0, import_viem5.createWalletClient)({
|
|
3086
2619
|
account: state.walletAddress,
|
|
3087
2620
|
chain: VIEM_CHAIN2[chainId],
|
|
3088
|
-
transport: (0,
|
|
2621
|
+
transport: (0, import_viem5.custom)(provider)
|
|
3089
2622
|
});
|
|
3090
2623
|
const hash = await wallet.writeContract({
|
|
3091
2624
|
address: token,
|
|
@@ -3095,9 +2628,9 @@ var OwneySDK = class {
|
|
|
3095
2628
|
account: state.walletAddress,
|
|
3096
2629
|
chain: VIEM_CHAIN2[chainId]
|
|
3097
2630
|
});
|
|
3098
|
-
const publicClient = (0,
|
|
2631
|
+
const publicClient = (0, import_viem5.createPublicClient)({
|
|
3099
2632
|
chain: VIEM_CHAIN2[chainId],
|
|
3100
|
-
transport: (0,
|
|
2633
|
+
transport: (0, import_viem5.custom)(provider)
|
|
3101
2634
|
});
|
|
3102
2635
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
3103
2636
|
hash,
|
|
@@ -3205,11 +2738,8 @@ var OwneySDK = class {
|
|
|
3205
2738
|
}
|
|
3206
2739
|
};
|
|
3207
2740
|
|
|
3208
|
-
// src/index.ts
|
|
3209
|
-
init_errors();
|
|
3210
|
-
|
|
3211
2741
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
3212
|
-
var
|
|
2742
|
+
var import_viem6 = require("viem");
|
|
3213
2743
|
var import_siwe = require("siwe");
|
|
3214
2744
|
var import_sdk2 = require("@zyfai/sdk");
|
|
3215
2745
|
|
|
@@ -3223,11 +2753,39 @@ var storage2 = () => {
|
|
|
3223
2753
|
return null;
|
|
3224
2754
|
}
|
|
3225
2755
|
};
|
|
3226
|
-
var buildKey2 = (address
|
|
2756
|
+
var buildKey2 = (address) => `${KEY_PREFIX2}:${address.toLowerCase()}`;
|
|
2757
|
+
var legacyKeyPrefix2 = (address) => `${KEY_PREFIX2}:${address.toLowerCase()}:`;
|
|
3227
2758
|
var memorySiwxSessions = /* @__PURE__ */ new Map();
|
|
2759
|
+
var readLegacySiwxSession = (store, address) => {
|
|
2760
|
+
if (!store) return null;
|
|
2761
|
+
const prefix = legacyKeyPrefix2(address);
|
|
2762
|
+
const legacyKeys = [];
|
|
2763
|
+
try {
|
|
2764
|
+
for (let i = 0; i < store.length; i++) {
|
|
2765
|
+
const key = store.key(i);
|
|
2766
|
+
if (key?.startsWith(prefix)) legacyKeys.push(key);
|
|
2767
|
+
}
|
|
2768
|
+
} catch {
|
|
2769
|
+
return null;
|
|
2770
|
+
}
|
|
2771
|
+
let adopted = null;
|
|
2772
|
+
for (const key of legacyKeys) {
|
|
2773
|
+
if (!adopted) {
|
|
2774
|
+
try {
|
|
2775
|
+
adopted = JSON.parse(store.getItem(key) ?? "");
|
|
2776
|
+
} catch {
|
|
2777
|
+
}
|
|
2778
|
+
}
|
|
2779
|
+
try {
|
|
2780
|
+
store.removeItem(key);
|
|
2781
|
+
} catch {
|
|
2782
|
+
}
|
|
2783
|
+
}
|
|
2784
|
+
return adopted;
|
|
2785
|
+
};
|
|
3228
2786
|
var readSiwxSession = (address, chainId) => {
|
|
3229
2787
|
if (typeof window === "undefined") return null;
|
|
3230
|
-
const key = buildKey2(address
|
|
2788
|
+
const key = buildKey2(address);
|
|
3231
2789
|
const store = storage2();
|
|
3232
2790
|
let raw = null;
|
|
3233
2791
|
try {
|
|
@@ -3247,11 +2805,16 @@ var readSiwxSession = (address, chainId) => {
|
|
|
3247
2805
|
return null;
|
|
3248
2806
|
}
|
|
3249
2807
|
}
|
|
2808
|
+
const legacy = readLegacySiwxSession(store, address);
|
|
2809
|
+
if (legacy) {
|
|
2810
|
+
writeSiwxSession(address, chainId, legacy);
|
|
2811
|
+
return legacy;
|
|
2812
|
+
}
|
|
3250
2813
|
return memorySiwxSessions.get(key) ?? null;
|
|
3251
2814
|
};
|
|
3252
|
-
var writeSiwxSession = (address,
|
|
2815
|
+
var writeSiwxSession = (address, _chainId, session) => {
|
|
3253
2816
|
if (typeof window === "undefined") return;
|
|
3254
|
-
const key = buildKey2(address
|
|
2817
|
+
const key = buildKey2(address);
|
|
3255
2818
|
memorySiwxSessions.set(key, session);
|
|
3256
2819
|
const store = storage2();
|
|
3257
2820
|
try {
|
|
@@ -3259,14 +2822,15 @@ var writeSiwxSession = (address, chainId, session) => {
|
|
|
3259
2822
|
} catch {
|
|
3260
2823
|
}
|
|
3261
2824
|
};
|
|
3262
|
-
var clearSiwxSession = (address,
|
|
3263
|
-
const key = buildKey2(address
|
|
2825
|
+
var clearSiwxSession = (address, _chainId) => {
|
|
2826
|
+
const key = buildKey2(address);
|
|
3264
2827
|
memorySiwxSessions.delete(key);
|
|
3265
2828
|
const store = storage2();
|
|
3266
2829
|
try {
|
|
3267
2830
|
store?.removeItem(key);
|
|
3268
2831
|
} catch {
|
|
3269
2832
|
}
|
|
2833
|
+
readLegacySiwxSession(store, address);
|
|
3270
2834
|
};
|
|
3271
2835
|
|
|
3272
2836
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
@@ -3302,7 +2866,7 @@ function buildSIWXConfig(deps) {
|
|
|
3302
2866
|
issuedAt,
|
|
3303
2867
|
toString() {
|
|
3304
2868
|
return new import_siwe.SiweMessage({
|
|
3305
|
-
address: (0,
|
|
2869
|
+
address: (0, import_viem6.getAddress)(accountAddress),
|
|
3306
2870
|
chainId: numericChainId(chainId),
|
|
3307
2871
|
domain,
|
|
3308
2872
|
uri,
|
|
@@ -3330,9 +2894,12 @@ function buildSIWXConfig(deps) {
|
|
|
3330
2894
|
}
|
|
3331
2895
|
if (!stored) return [];
|
|
3332
2896
|
const session = {
|
|
3333
|
-
// `stored.data
|
|
3334
|
-
//
|
|
3335
|
-
|
|
2897
|
+
// `stored.data` is kept AppKit-free in the cache, so narrow at the
|
|
2898
|
+
// boundary. Echo the REQUESTED chain rather than the one originally
|
|
2899
|
+
// signed: the Zyfai JWT is account-scoped (no chain claim), so one
|
|
2900
|
+
// signature is valid for every chain, and AppKit would otherwise treat
|
|
2901
|
+
// the session as not covering the active network and re-prompt.
|
|
2902
|
+
data: { ...stored.data, chainId },
|
|
3336
2903
|
message: stored.message,
|
|
3337
2904
|
signature: stored.signature
|
|
3338
2905
|
};
|