@owney/sdk 0.6.9-beta.4 → 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 +860 -140
- package/dist/index.d.cts +30 -2
- package/dist/index.d.ts +30 -2
- package/dist/index.js +352 -122
- package/dist/surfliquid.agent-OMOYXWLP.js +385 -0
- package/package.json +3 -1
package/dist/index.cjs
CHANGED
|
@@ -3,20 +3,500 @@ 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 });
|
|
9
17
|
};
|
|
10
18
|
var __copyProps = (to, from, except, desc) => {
|
|
11
19
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let
|
|
13
|
-
if (!__hasOwnProp.call(to,
|
|
14
|
-
__defProp(to,
|
|
20
|
+
for (let key2 of __getOwnPropNames(from))
|
|
21
|
+
if (!__hasOwnProp.call(to, key2) && key2 !== except)
|
|
22
|
+
__defProp(to, key2, { get: () => from[key2], enumerable: !(desc = __getOwnPropDesc(from, key2)) || desc.enumerable });
|
|
15
23
|
}
|
|
16
24
|
return to;
|
|
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 = () => {
|
|
@@ -562,23 +997,23 @@ var readLegacySession = (store, address) => {
|
|
|
562
997
|
const legacyKeys = [];
|
|
563
998
|
try {
|
|
564
999
|
for (let i = 0; i < store.length; i++) {
|
|
565
|
-
const
|
|
566
|
-
if (
|
|
1000
|
+
const key2 = store.key(i);
|
|
1001
|
+
if (key2?.startsWith(prefix)) legacyKeys.push(key2);
|
|
567
1002
|
}
|
|
568
1003
|
} catch {
|
|
569
1004
|
return null;
|
|
570
1005
|
}
|
|
571
1006
|
let adopted = null;
|
|
572
|
-
for (const
|
|
1007
|
+
for (const key2 of legacyKeys) {
|
|
573
1008
|
if (!adopted) {
|
|
574
1009
|
try {
|
|
575
|
-
const parsed = JSON.parse(store.getItem(
|
|
1010
|
+
const parsed = JSON.parse(store.getItem(key2) ?? "");
|
|
576
1011
|
if (isFreshSession(parsed)) adopted = parsed;
|
|
577
1012
|
} catch {
|
|
578
1013
|
}
|
|
579
1014
|
}
|
|
580
1015
|
try {
|
|
581
|
-
store.removeItem(
|
|
1016
|
+
store.removeItem(key2);
|
|
582
1017
|
} catch {
|
|
583
1018
|
}
|
|
584
1019
|
}
|
|
@@ -586,11 +1021,11 @@ var readLegacySession = (store, address) => {
|
|
|
586
1021
|
};
|
|
587
1022
|
var readSession = (address, _chainId) => {
|
|
588
1023
|
if (typeof window === "undefined") return null;
|
|
589
|
-
const
|
|
1024
|
+
const key2 = buildKey(address);
|
|
590
1025
|
const store = storage();
|
|
591
1026
|
let raw = null;
|
|
592
1027
|
try {
|
|
593
|
-
raw = store?.getItem(
|
|
1028
|
+
raw = store?.getItem(key2) ?? null;
|
|
594
1029
|
} catch {
|
|
595
1030
|
raw = null;
|
|
596
1031
|
}
|
|
@@ -600,9 +1035,9 @@ var readSession = (address, _chainId) => {
|
|
|
600
1035
|
if (isFreshSession(parsed)) return parsed;
|
|
601
1036
|
} catch {
|
|
602
1037
|
}
|
|
603
|
-
memorySessions.delete(
|
|
1038
|
+
memorySessions.delete(key2);
|
|
604
1039
|
try {
|
|
605
|
-
store?.removeItem(
|
|
1040
|
+
store?.removeItem(key2);
|
|
606
1041
|
} catch {
|
|
607
1042
|
}
|
|
608
1043
|
return null;
|
|
@@ -612,27 +1047,27 @@ var readSession = (address, _chainId) => {
|
|
|
612
1047
|
writeSession(address, _chainId, legacy);
|
|
613
1048
|
return legacy;
|
|
614
1049
|
}
|
|
615
|
-
const cached = memorySessions.get(
|
|
1050
|
+
const cached = memorySessions.get(key2);
|
|
616
1051
|
if (isFreshSession(cached)) return cached;
|
|
617
|
-
if (cached) memorySessions.delete(
|
|
1052
|
+
if (cached) memorySessions.delete(key2);
|
|
618
1053
|
return null;
|
|
619
1054
|
};
|
|
620
1055
|
var writeSession = (address, _chainId, session) => {
|
|
621
1056
|
if (typeof window === "undefined") return;
|
|
622
|
-
const
|
|
623
|
-
memorySessions.set(
|
|
1057
|
+
const key2 = buildKey(address);
|
|
1058
|
+
memorySessions.set(key2, session);
|
|
624
1059
|
const store = storage();
|
|
625
1060
|
try {
|
|
626
|
-
store?.setItem(
|
|
1061
|
+
store?.setItem(key2, JSON.stringify(session));
|
|
627
1062
|
} catch {
|
|
628
1063
|
}
|
|
629
1064
|
};
|
|
630
1065
|
var clearSession = (address, _chainId) => {
|
|
631
|
-
const
|
|
632
|
-
memorySessions.delete(
|
|
1066
|
+
const key2 = buildKey(address);
|
|
1067
|
+
memorySessions.delete(key2);
|
|
633
1068
|
const store = storage();
|
|
634
1069
|
try {
|
|
635
|
-
store?.removeItem(
|
|
1070
|
+
store?.removeItem(key2);
|
|
636
1071
|
} catch {
|
|
637
1072
|
}
|
|
638
1073
|
readLegacySession(store, address);
|
|
@@ -696,6 +1131,99 @@ function splittingNeedsUpdate(current, desired) {
|
|
|
696
1131
|
return current.minSplits !== desired.minSplits;
|
|
697
1132
|
}
|
|
698
1133
|
|
|
1134
|
+
// src/agents/zyfai/pool-policy.ts
|
|
1135
|
+
function toZyfaiCustomizations(policy, availableByProtocol, chainsByProtocol) {
|
|
1136
|
+
const selectionByKey = /* @__PURE__ */ new Map();
|
|
1137
|
+
for (const selection of policy.selections) {
|
|
1138
|
+
selectionByKey.set(key(selection.protocolId, selection.chainId), selection);
|
|
1139
|
+
}
|
|
1140
|
+
const customizations = [];
|
|
1141
|
+
for (const [protocolId, chainIds] of Object.entries(chainsByProtocol)) {
|
|
1142
|
+
const available = availableByProtocol.get(protocolId);
|
|
1143
|
+
if (available === void 0) {
|
|
1144
|
+
continue;
|
|
1145
|
+
}
|
|
1146
|
+
const availableSet = new Set(available);
|
|
1147
|
+
for (const chainId of chainIds) {
|
|
1148
|
+
const stored = selectionByKey.get(key(protocolId, chainId));
|
|
1149
|
+
if (stored === void 0) {
|
|
1150
|
+
customizations.push({
|
|
1151
|
+
protocolId,
|
|
1152
|
+
chainId,
|
|
1153
|
+
pools: [],
|
|
1154
|
+
autoselect: true
|
|
1155
|
+
});
|
|
1156
|
+
continue;
|
|
1157
|
+
}
|
|
1158
|
+
const pools = stored.pools.filter((pool) => availableSet.has(pool));
|
|
1159
|
+
customizations.push({
|
|
1160
|
+
protocolId,
|
|
1161
|
+
chainId,
|
|
1162
|
+
pools,
|
|
1163
|
+
autoselect: false
|
|
1164
|
+
});
|
|
1165
|
+
}
|
|
1166
|
+
}
|
|
1167
|
+
return customizations;
|
|
1168
|
+
}
|
|
1169
|
+
function deriveProtocols(policy, universe, chainsByProtocol) {
|
|
1170
|
+
if (policy.selections.length === 0) {
|
|
1171
|
+
return null;
|
|
1172
|
+
}
|
|
1173
|
+
const selectionByKey = /* @__PURE__ */ new Map();
|
|
1174
|
+
for (const selection of policy.selections) {
|
|
1175
|
+
selectionByKey.set(key(selection.protocolId, selection.chainId), selection);
|
|
1176
|
+
}
|
|
1177
|
+
return universe.filter((protocolId) => {
|
|
1178
|
+
const chainIds = chainsByProtocol[protocolId];
|
|
1179
|
+
if (chainIds === void 0 || chainIds.length === 0) {
|
|
1180
|
+
return true;
|
|
1181
|
+
}
|
|
1182
|
+
const fullyDisabled = chainIds.every((chainId) => {
|
|
1183
|
+
const stored = selectionByKey.get(key(protocolId, chainId));
|
|
1184
|
+
return stored !== void 0 && stored.pools.length === 0;
|
|
1185
|
+
});
|
|
1186
|
+
return !fullyDisabled;
|
|
1187
|
+
});
|
|
1188
|
+
}
|
|
1189
|
+
function key(protocolId, chainId) {
|
|
1190
|
+
return `${protocolId}:${chainId}`;
|
|
1191
|
+
}
|
|
1192
|
+
function buildChainsByProtocol(protocols, dashboardChainIds) {
|
|
1193
|
+
const allowed = new Set(dashboardChainIds);
|
|
1194
|
+
const result = {};
|
|
1195
|
+
for (const protocol of protocols) {
|
|
1196
|
+
result[protocol.id] = (protocol.chains ?? []).filter(
|
|
1197
|
+
(chainId) => allowed.has(chainId)
|
|
1198
|
+
);
|
|
1199
|
+
}
|
|
1200
|
+
return result;
|
|
1201
|
+
}
|
|
1202
|
+
function flattenAvailablePools(raw) {
|
|
1203
|
+
const byChain = raw ?? {};
|
|
1204
|
+
const names = [];
|
|
1205
|
+
for (const byToken of Object.values(byChain ?? {})) {
|
|
1206
|
+
for (const entry of Object.values(byToken ?? {})) {
|
|
1207
|
+
for (const pool of entry?.pools ?? []) {
|
|
1208
|
+
if (pool?.name) names.push(pool.name);
|
|
1209
|
+
}
|
|
1210
|
+
}
|
|
1211
|
+
}
|
|
1212
|
+
return names;
|
|
1213
|
+
}
|
|
1214
|
+
function protocolListsEqual(a, b) {
|
|
1215
|
+
const left = [...a ?? []].sort();
|
|
1216
|
+
const right = [...b ?? []].sort();
|
|
1217
|
+
if (left.length !== right.length) return false;
|
|
1218
|
+
return left.every((value, index) => value === right[index]);
|
|
1219
|
+
}
|
|
1220
|
+
function protocolsPolicyNeedsUpdate(current, desiredProtocols, desiredAutoSelect) {
|
|
1221
|
+
if (!current) return true;
|
|
1222
|
+
if (current.autoSelectProtocols !== desiredAutoSelect) return true;
|
|
1223
|
+
if (desiredProtocols === null) return false;
|
|
1224
|
+
return !protocolListsEqual(current.protocols, desiredProtocols);
|
|
1225
|
+
}
|
|
1226
|
+
|
|
699
1227
|
// src/lib/debug.ts
|
|
700
1228
|
var configuredDebug = false;
|
|
701
1229
|
function setOwneyDebug(enabled) {
|
|
@@ -726,6 +1254,7 @@ var WETH_ADDRESS_BY_CHAIN = {
|
|
|
726
1254
|
};
|
|
727
1255
|
var VIEM_CHAIN = { 8453: import_chains.base, 42161: import_chains.arbitrum, 1: import_chains.mainnet };
|
|
728
1256
|
var SPLITTING_ASSETS = ["USDC", "WETH"];
|
|
1257
|
+
var POOL_POLICY_CHAIN_IDS = [8453, 42161, 1];
|
|
729
1258
|
function isAlreadyActiveSessionKeyError(error) {
|
|
730
1259
|
const message = error instanceof Error ? error.message : String(error);
|
|
731
1260
|
return /already has an active session key/i.test(message);
|
|
@@ -1110,6 +1639,9 @@ var ZyfaiAgent = class {
|
|
|
1110
1639
|
await Promise.all(
|
|
1111
1640
|
SPLITTING_ASSETS.map((asset) => this.applySplitting(asset, policy))
|
|
1112
1641
|
);
|
|
1642
|
+
if (policy.poolPolicy) {
|
|
1643
|
+
await this.applyPoolPolicy(policy.poolPolicy);
|
|
1644
|
+
}
|
|
1113
1645
|
}
|
|
1114
1646
|
async applySplitting(asset, policy) {
|
|
1115
1647
|
try {
|
|
@@ -1146,6 +1678,117 @@ var ZyfaiAgent = class {
|
|
|
1146
1678
|
);
|
|
1147
1679
|
}
|
|
1148
1680
|
}
|
|
1681
|
+
/**
|
|
1682
|
+
* Apply the org's protocol/pool policy to this user's Zyfai profile.
|
|
1683
|
+
*
|
|
1684
|
+
* Two Zyfai writes, in a strict order:
|
|
1685
|
+
* 1. `updateUserProfile({ protocols, autoSelectProtocols })` per asset —
|
|
1686
|
+
* the explicit allow-list. Chain-agnostic, mirrors `applySplitting`.
|
|
1687
|
+
* 2. `customizeBatch(...)` once — per (protocol, chain), asset-agnostic
|
|
1688
|
+
* pool narrowing.
|
|
1689
|
+
*
|
|
1690
|
+
* Order matters: constraining a protocol's pools (step 2) while that
|
|
1691
|
+
* protocol is not yet in the allow-list (step 1 not yet applied) lands the
|
|
1692
|
+
* constraint on something the rebalance engine isn't considering.
|
|
1693
|
+
*
|
|
1694
|
+
* Wrapped so a failure anywhere is non-fatal — this runs as a side effect of
|
|
1695
|
+
* connecting, so a Zyfai hiccup must leave the user connected with their
|
|
1696
|
+
* profile unchanged, never fail activation.
|
|
1697
|
+
*/
|
|
1698
|
+
async applyPoolPolicy(policy) {
|
|
1699
|
+
try {
|
|
1700
|
+
const { protocols: universe } = await this.sdk.getAvailableProtocols(
|
|
1701
|
+
this.supportedChainIds[0]
|
|
1702
|
+
);
|
|
1703
|
+
const universeIds = universe.map((p) => p.id);
|
|
1704
|
+
const chainsByProtocol = buildChainsByProtocol(
|
|
1705
|
+
universe,
|
|
1706
|
+
POOL_POLICY_CHAIN_IDS
|
|
1707
|
+
);
|
|
1708
|
+
debugLog("zyfai:pools", "protocol universe", {
|
|
1709
|
+
universeIds,
|
|
1710
|
+
chainsByProtocol
|
|
1711
|
+
});
|
|
1712
|
+
let strategy;
|
|
1713
|
+
const desiredProtocols = deriveProtocols(
|
|
1714
|
+
policy,
|
|
1715
|
+
universeIds,
|
|
1716
|
+
chainsByProtocol
|
|
1717
|
+
);
|
|
1718
|
+
const desiredAutoSelect = policy.autoApproveProtocols;
|
|
1719
|
+
for (const asset of SPLITTING_ASSETS) {
|
|
1720
|
+
const current = await this.sdk.getUserDetails(asset);
|
|
1721
|
+
if (strategy === void 0 && (current.strategy === "conservative" || current.strategy === "aggressive")) {
|
|
1722
|
+
strategy = current.strategy;
|
|
1723
|
+
}
|
|
1724
|
+
const needsUpdate = protocolsPolicyNeedsUpdate(
|
|
1725
|
+
current,
|
|
1726
|
+
desiredProtocols,
|
|
1727
|
+
desiredAutoSelect
|
|
1728
|
+
);
|
|
1729
|
+
debugLog("zyfai:pools", `${asset}: comparing protocols`, {
|
|
1730
|
+
current: {
|
|
1731
|
+
protocols: current.protocols,
|
|
1732
|
+
autoSelectProtocols: current.autoSelectProtocols
|
|
1733
|
+
},
|
|
1734
|
+
desired: {
|
|
1735
|
+
protocols: desiredProtocols,
|
|
1736
|
+
autoSelectProtocols: desiredAutoSelect
|
|
1737
|
+
},
|
|
1738
|
+
decision: needsUpdate ? "will write \u2014 profile differs from the org policy" : "skipping \u2014 profile already matches"
|
|
1739
|
+
});
|
|
1740
|
+
if (!needsUpdate) continue;
|
|
1741
|
+
const update = {
|
|
1742
|
+
asset,
|
|
1743
|
+
autoSelectProtocols: desiredAutoSelect
|
|
1744
|
+
};
|
|
1745
|
+
if (desiredProtocols !== null) update.protocols = desiredProtocols;
|
|
1746
|
+
await this.sdk.updateUserProfile(update);
|
|
1747
|
+
debugLog("zyfai:pools", `${asset}: wrote protocols update`, update);
|
|
1748
|
+
}
|
|
1749
|
+
const poolResults = await Promise.all(
|
|
1750
|
+
universe.map(async (protocol) => {
|
|
1751
|
+
try {
|
|
1752
|
+
const raw = await this.sdk.getAvailablePools(protocol.id, strategy);
|
|
1753
|
+
return [protocol.id, flattenAvailablePools(raw)];
|
|
1754
|
+
} catch (error) {
|
|
1755
|
+
console.warn(
|
|
1756
|
+
`[zyfai] applyPoolPolicy: getAvailablePools(${protocol.id}) failed, skipping this protocol (non-fatal):`,
|
|
1757
|
+
error instanceof Error ? error.message : String(error)
|
|
1758
|
+
);
|
|
1759
|
+
return null;
|
|
1760
|
+
}
|
|
1761
|
+
})
|
|
1762
|
+
);
|
|
1763
|
+
const availableByProtocol = /* @__PURE__ */ new Map();
|
|
1764
|
+
for (const result of poolResults) {
|
|
1765
|
+
if (result) availableByProtocol.set(result[0], result[1]);
|
|
1766
|
+
}
|
|
1767
|
+
const customizations = toZyfaiCustomizations(
|
|
1768
|
+
policy,
|
|
1769
|
+
availableByProtocol,
|
|
1770
|
+
chainsByProtocol
|
|
1771
|
+
);
|
|
1772
|
+
debugLog("zyfai:pools", "derived customizeBatch payload", {
|
|
1773
|
+
strategy,
|
|
1774
|
+
availableProtocolCount: availableByProtocol.size,
|
|
1775
|
+
customizations
|
|
1776
|
+
});
|
|
1777
|
+
if (customizations.length === 0) {
|
|
1778
|
+
debugLog("zyfai:pools", "skipping customizeBatch \u2014 nothing to send");
|
|
1779
|
+
return;
|
|
1780
|
+
}
|
|
1781
|
+
await this.sdk.customizeBatch(customizations);
|
|
1782
|
+
debugLog("zyfai:pools", "wrote customizeBatch", {
|
|
1783
|
+
count: customizations.length
|
|
1784
|
+
});
|
|
1785
|
+
} catch (error) {
|
|
1786
|
+
console.warn(
|
|
1787
|
+
"[zyfai] applyPoolPolicy failed (non-fatal):",
|
|
1788
|
+
error instanceof Error ? error.message : String(error)
|
|
1789
|
+
);
|
|
1790
|
+
}
|
|
1791
|
+
}
|
|
1149
1792
|
async deposit(state, chainId, amount, asset, depositCallback) {
|
|
1150
1793
|
try {
|
|
1151
1794
|
await this.connectFull(state, chainId);
|
|
@@ -1307,7 +1950,11 @@ var ZyfaiAgent = class {
|
|
|
1307
1950
|
}
|
|
1308
1951
|
};
|
|
1309
1952
|
|
|
1953
|
+
// src/client.ts
|
|
1954
|
+
init_errors();
|
|
1955
|
+
|
|
1310
1956
|
// src/lib/routing-api.ts
|
|
1957
|
+
init_errors();
|
|
1311
1958
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1312
1959
|
async function fetchOrgAgentConfig(apiKey) {
|
|
1313
1960
|
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/org-config`;
|
|
@@ -1372,6 +2019,7 @@ async function fetchAgentKeys(apiKey) {
|
|
|
1372
2019
|
}
|
|
1373
2020
|
|
|
1374
2021
|
// src/lib/health-report.ts
|
|
2022
|
+
init_errors();
|
|
1375
2023
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1376
2024
|
async function reportAgentFailure(apiKey, agentType, errorCode) {
|
|
1377
2025
|
try {
|
|
@@ -1521,9 +2169,12 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
1521
2169
|
}
|
|
1522
2170
|
|
|
1523
2171
|
// src/client.ts
|
|
1524
|
-
var
|
|
2172
|
+
var import_viem6 = require("viem");
|
|
1525
2173
|
var import_chains2 = require("viem/chains");
|
|
1526
2174
|
|
|
2175
|
+
// src/lib/sponsored-deposit.ts
|
|
2176
|
+
init_errors();
|
|
2177
|
+
|
|
1527
2178
|
// src/lib/transfer-auth.ts
|
|
1528
2179
|
var import_viem3 = require("viem");
|
|
1529
2180
|
var ERC20_META_ABI = [
|
|
@@ -1561,6 +2212,7 @@ function randomAuthNonce() {
|
|
|
1561
2212
|
}
|
|
1562
2213
|
|
|
1563
2214
|
// src/lib/sponsor-client.ts
|
|
2215
|
+
init_errors();
|
|
1564
2216
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1565
2217
|
async function postSponsorTransferAuth(input) {
|
|
1566
2218
|
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
@@ -1829,6 +2481,7 @@ function makeSponsoredDepositCallback(deps) {
|
|
|
1829
2481
|
}
|
|
1830
2482
|
|
|
1831
2483
|
// src/lib/sponsored-weth-deposit.ts
|
|
2484
|
+
init_errors();
|
|
1832
2485
|
var PERMIT_WINDOW_SECONDS = 15 * 60;
|
|
1833
2486
|
function makeSponsoredWethCallback(deps) {
|
|
1834
2487
|
const get = deps.httpGet ?? getSponsorRelayerAddress;
|
|
@@ -1937,6 +2590,7 @@ var VIEM_CHAIN2 = {
|
|
|
1937
2590
|
42161: import_chains2.arbitrum,
|
|
1938
2591
|
1: import_chains2.mainnet
|
|
1939
2592
|
};
|
|
2593
|
+
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
1940
2594
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
1941
2595
|
8453: "0x4200000000000000000000000000000000000006",
|
|
1942
2596
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -1965,6 +2619,7 @@ var OwneySDK = class {
|
|
|
1965
2619
|
zyfaiRpcUrls;
|
|
1966
2620
|
routingApiBaseUrl;
|
|
1967
2621
|
referralSource;
|
|
2622
|
+
surfliquidApiBaseUrl;
|
|
1968
2623
|
cachedSponsoredCallback = null;
|
|
1969
2624
|
cachedWethSponsoredCallback = null;
|
|
1970
2625
|
initializingAgentsPromise = null;
|
|
@@ -1974,6 +2629,7 @@ var OwneySDK = class {
|
|
|
1974
2629
|
this.zyfaiRpcUrls = config.zyfaiRpcUrls;
|
|
1975
2630
|
this.routingApiBaseUrl = config.routingApiBaseUrl;
|
|
1976
2631
|
this.referralSource = config.referralSource;
|
|
2632
|
+
this.surfliquidApiBaseUrl = config.surfliquidApiBaseUrl;
|
|
1977
2633
|
}
|
|
1978
2634
|
/**
|
|
1979
2635
|
* Establish connection state for all subsequent SDK calls.
|
|
@@ -2071,14 +2727,14 @@ var OwneySDK = class {
|
|
|
2071
2727
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2072
2728
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2073
2729
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2074
|
-
getPublicClient: (cid) => (0,
|
|
2730
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
2075
2731
|
chain: VIEM_CHAIN2[cid],
|
|
2076
|
-
transport: (0,
|
|
2732
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2077
2733
|
}),
|
|
2078
|
-
getWalletClient: (cid) => (0,
|
|
2734
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
2079
2735
|
account: owner,
|
|
2080
2736
|
chain: VIEM_CHAIN2[cid],
|
|
2081
|
-
transport: (0,
|
|
2737
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2082
2738
|
})
|
|
2083
2739
|
});
|
|
2084
2740
|
if (!onApproved) this.cachedSponsoredCallback = callback;
|
|
@@ -2104,14 +2760,14 @@ var OwneySDK = class {
|
|
|
2104
2760
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2105
2761
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2106
2762
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2107
|
-
getPublicClient: (cid) => (0,
|
|
2763
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
2108
2764
|
chain: VIEM_CHAIN2[cid],
|
|
2109
|
-
transport: (0,
|
|
2765
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2110
2766
|
}),
|
|
2111
|
-
getWalletClient: (cid) => (0,
|
|
2767
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
2112
2768
|
account: owner,
|
|
2113
2769
|
chain: VIEM_CHAIN2[cid],
|
|
2114
|
-
transport: (0,
|
|
2770
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2115
2771
|
})
|
|
2116
2772
|
});
|
|
2117
2773
|
if (!onApproved) this.cachedWethSponsoredCallback = callback;
|
|
@@ -2181,8 +2837,8 @@ var OwneySDK = class {
|
|
|
2181
2837
|
this.initializingAgentsPromise = (async () => {
|
|
2182
2838
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
2183
2839
|
this.disabledAgents.clear();
|
|
2184
|
-
for (const { key, agent_type, is_enabled } of agentKeys) {
|
|
2185
|
-
const agent = this.createAgent(agent_type,
|
|
2840
|
+
for (const { key: key2, agent_type, project_name, is_enabled } of agentKeys) {
|
|
2841
|
+
const agent = await this.createAgent(agent_type, key2, project_name);
|
|
2186
2842
|
if (!agent) continue;
|
|
2187
2843
|
this.agents.set(agent_type, agent);
|
|
2188
2844
|
if (is_enabled === false) {
|
|
@@ -2203,9 +2859,21 @@ var OwneySDK = class {
|
|
|
2203
2859
|
this.initializingAgentsPromise = null;
|
|
2204
2860
|
}
|
|
2205
2861
|
}
|
|
2206
|
-
createAgent(agentId,
|
|
2862
|
+
async createAgent(agentId, key2, projectName) {
|
|
2207
2863
|
if (agentId === "zyfai") {
|
|
2208
|
-
return new ZyfaiAgent(
|
|
2864
|
+
return new ZyfaiAgent(key2, this.zyfaiRpcUrls, this.referralSource);
|
|
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
|
+
});
|
|
2209
2877
|
}
|
|
2210
2878
|
return null;
|
|
2211
2879
|
}
|
|
@@ -2361,18 +3029,30 @@ var OwneySDK = class {
|
|
|
2361
3029
|
);
|
|
2362
3030
|
}
|
|
2363
3031
|
const agentResults = {};
|
|
3032
|
+
const agentErrors = {};
|
|
2364
3033
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
2365
|
-
|
|
2366
|
-
agent
|
|
2367
|
-
|
|
2368
|
-
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
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 }
|
|
2373
3053
|
);
|
|
2374
3054
|
}
|
|
2375
|
-
return { agentResults };
|
|
3055
|
+
return Object.keys(agentErrors).length > 0 ? { agentResults, agentErrors } : { agentResults };
|
|
2376
3056
|
}
|
|
2377
3057
|
/**
|
|
2378
3058
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -2529,6 +3209,34 @@ var OwneySDK = class {
|
|
|
2529
3209
|
}
|
|
2530
3210
|
return eligible;
|
|
2531
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
|
+
}
|
|
2532
3240
|
// --- Fund operations ---
|
|
2533
3241
|
/**
|
|
2534
3242
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -2564,9 +3272,17 @@ var OwneySDK = class {
|
|
|
2564
3272
|
}
|
|
2565
3273
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
2566
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);
|
|
2567
3283
|
const results2 = {};
|
|
2568
3284
|
const agentErrors2 = {};
|
|
2569
|
-
for (const agent of
|
|
3285
|
+
for (const { agent } of funded) {
|
|
2570
3286
|
try {
|
|
2571
3287
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
2572
3288
|
} catch (err) {
|
|
@@ -2583,9 +3299,10 @@ var OwneySDK = class {
|
|
|
2583
3299
|
{ asset, agentErrors: agentErrors2 }
|
|
2584
3300
|
);
|
|
2585
3301
|
}
|
|
3302
|
+
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
2586
3303
|
return {
|
|
2587
3304
|
agentResult: results2,
|
|
2588
|
-
totalWithdrawn:
|
|
3305
|
+
totalWithdrawn: totalWithdrawn.toString()
|
|
2589
3306
|
};
|
|
2590
3307
|
}
|
|
2591
3308
|
const requested = BigInt(amount);
|
|
@@ -2955,10 +3672,10 @@ var OwneySDK = class {
|
|
|
2955
3672
|
);
|
|
2956
3673
|
}
|
|
2957
3674
|
const provider = this.requireConnectedProvider();
|
|
2958
|
-
const wallet = (0,
|
|
3675
|
+
const wallet = (0, import_viem6.createWalletClient)({
|
|
2959
3676
|
account: state.walletAddress,
|
|
2960
3677
|
chain: VIEM_CHAIN2[chainId],
|
|
2961
|
-
transport: (0,
|
|
3678
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2962
3679
|
});
|
|
2963
3680
|
const hash = await wallet.writeContract({
|
|
2964
3681
|
address: token,
|
|
@@ -2968,9 +3685,9 @@ var OwneySDK = class {
|
|
|
2968
3685
|
account: state.walletAddress,
|
|
2969
3686
|
chain: VIEM_CHAIN2[chainId]
|
|
2970
3687
|
});
|
|
2971
|
-
const publicClient = (0,
|
|
3688
|
+
const publicClient = (0, import_viem6.createPublicClient)({
|
|
2972
3689
|
chain: VIEM_CHAIN2[chainId],
|
|
2973
|
-
transport: (0,
|
|
3690
|
+
transport: (0, import_viem6.custom)(provider)
|
|
2974
3691
|
});
|
|
2975
3692
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
2976
3693
|
hash,
|
|
@@ -3078,8 +3795,11 @@ var OwneySDK = class {
|
|
|
3078
3795
|
}
|
|
3079
3796
|
};
|
|
3080
3797
|
|
|
3798
|
+
// src/index.ts
|
|
3799
|
+
init_errors();
|
|
3800
|
+
|
|
3081
3801
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
3082
|
-
var
|
|
3802
|
+
var import_viem7 = require("viem");
|
|
3083
3803
|
var import_siwe = require("siwe");
|
|
3084
3804
|
var import_sdk2 = require("@zyfai/sdk");
|
|
3085
3805
|
|
|
@@ -3102,22 +3822,22 @@ var readLegacySiwxSession = (store, address) => {
|
|
|
3102
3822
|
const legacyKeys = [];
|
|
3103
3823
|
try {
|
|
3104
3824
|
for (let i = 0; i < store.length; i++) {
|
|
3105
|
-
const
|
|
3106
|
-
if (
|
|
3825
|
+
const key2 = store.key(i);
|
|
3826
|
+
if (key2?.startsWith(prefix)) legacyKeys.push(key2);
|
|
3107
3827
|
}
|
|
3108
3828
|
} catch {
|
|
3109
3829
|
return null;
|
|
3110
3830
|
}
|
|
3111
3831
|
let adopted = null;
|
|
3112
|
-
for (const
|
|
3832
|
+
for (const key2 of legacyKeys) {
|
|
3113
3833
|
if (!adopted) {
|
|
3114
3834
|
try {
|
|
3115
|
-
adopted = JSON.parse(store.getItem(
|
|
3835
|
+
adopted = JSON.parse(store.getItem(key2) ?? "");
|
|
3116
3836
|
} catch {
|
|
3117
3837
|
}
|
|
3118
3838
|
}
|
|
3119
3839
|
try {
|
|
3120
|
-
store.removeItem(
|
|
3840
|
+
store.removeItem(key2);
|
|
3121
3841
|
} catch {
|
|
3122
3842
|
}
|
|
3123
3843
|
}
|
|
@@ -3125,11 +3845,11 @@ var readLegacySiwxSession = (store, address) => {
|
|
|
3125
3845
|
};
|
|
3126
3846
|
var readSiwxSession = (address, chainId) => {
|
|
3127
3847
|
if (typeof window === "undefined") return null;
|
|
3128
|
-
const
|
|
3848
|
+
const key2 = buildKey2(address);
|
|
3129
3849
|
const store = storage2();
|
|
3130
3850
|
let raw = null;
|
|
3131
3851
|
try {
|
|
3132
|
-
raw = store?.getItem(
|
|
3852
|
+
raw = store?.getItem(key2) ?? null;
|
|
3133
3853
|
} catch {
|
|
3134
3854
|
raw = null;
|
|
3135
3855
|
}
|
|
@@ -3137,9 +3857,9 @@ var readSiwxSession = (address, chainId) => {
|
|
|
3137
3857
|
try {
|
|
3138
3858
|
return JSON.parse(raw);
|
|
3139
3859
|
} catch {
|
|
3140
|
-
memorySiwxSessions.delete(
|
|
3860
|
+
memorySiwxSessions.delete(key2);
|
|
3141
3861
|
try {
|
|
3142
|
-
store?.removeItem(
|
|
3862
|
+
store?.removeItem(key2);
|
|
3143
3863
|
} catch {
|
|
3144
3864
|
}
|
|
3145
3865
|
return null;
|
|
@@ -3150,24 +3870,24 @@ var readSiwxSession = (address, chainId) => {
|
|
|
3150
3870
|
writeSiwxSession(address, chainId, legacy);
|
|
3151
3871
|
return legacy;
|
|
3152
3872
|
}
|
|
3153
|
-
return memorySiwxSessions.get(
|
|
3873
|
+
return memorySiwxSessions.get(key2) ?? null;
|
|
3154
3874
|
};
|
|
3155
3875
|
var writeSiwxSession = (address, _chainId, session) => {
|
|
3156
3876
|
if (typeof window === "undefined") return;
|
|
3157
|
-
const
|
|
3158
|
-
memorySiwxSessions.set(
|
|
3877
|
+
const key2 = buildKey2(address);
|
|
3878
|
+
memorySiwxSessions.set(key2, session);
|
|
3159
3879
|
const store = storage2();
|
|
3160
3880
|
try {
|
|
3161
|
-
store?.setItem(
|
|
3881
|
+
store?.setItem(key2, JSON.stringify(session));
|
|
3162
3882
|
} catch {
|
|
3163
3883
|
}
|
|
3164
3884
|
};
|
|
3165
3885
|
var clearSiwxSession = (address, _chainId) => {
|
|
3166
|
-
const
|
|
3167
|
-
memorySiwxSessions.delete(
|
|
3886
|
+
const key2 = buildKey2(address);
|
|
3887
|
+
memorySiwxSessions.delete(key2);
|
|
3168
3888
|
const store = storage2();
|
|
3169
3889
|
try {
|
|
3170
|
-
store?.removeItem(
|
|
3890
|
+
store?.removeItem(key2);
|
|
3171
3891
|
} catch {
|
|
3172
3892
|
}
|
|
3173
3893
|
readLegacySiwxSession(store, address);
|
|
@@ -3206,7 +3926,7 @@ function buildSIWXConfig(deps) {
|
|
|
3206
3926
|
issuedAt,
|
|
3207
3927
|
toString() {
|
|
3208
3928
|
return new import_siwe.SiweMessage({
|
|
3209
|
-
address: (0,
|
|
3929
|
+
address: (0, import_viem7.getAddress)(accountAddress),
|
|
3210
3930
|
chainId: numericChainId(chainId),
|
|
3211
3931
|
domain,
|
|
3212
3932
|
uri,
|