@owney/sdk 0.6.7-beta.1 → 0.6.7-beta.3
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 +200 -627
- package/dist/index.d.cts +9 -19
- package/dist/index.d.ts +9 -19
- package/dist/index.js +185 -120
- 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
|
|
@@ -1109,11 +709,15 @@ var ZyfaiAgent = class {
|
|
|
1109
709
|
// successful decode is cached forever; failures are NOT cached so a transient
|
|
1110
710
|
// RPC error retries on the next fetch.
|
|
1111
711
|
withdrawAmountCache = /* @__PURE__ */ new Map();
|
|
1112
|
-
constructor(apiKey, rpcUrls) {
|
|
712
|
+
constructor(apiKey, rpcUrls, referralSource) {
|
|
1113
713
|
this.rpcUrls = rpcUrls ?? DEFAULT_ZYFAI_RPC_URLS;
|
|
1114
714
|
this.sdk = new import_sdk.ZyfaiSDK({
|
|
1115
715
|
apiKey,
|
|
1116
|
-
rpcUrls: this.rpcUrls
|
|
716
|
+
rpcUrls: this.rpcUrls,
|
|
717
|
+
// Forwarded to /auth/login by the SDK's own SIWE handshake, so
|
|
718
|
+
// attribution survives without the AppKit SIWX config (which carried it
|
|
719
|
+
// via `createOwneySIWX({ referralSource })` when apps used the modal).
|
|
720
|
+
referralSource
|
|
1117
721
|
});
|
|
1118
722
|
this.installAuthCache();
|
|
1119
723
|
}
|
|
@@ -1531,11 +1135,7 @@ var ZyfaiAgent = class {
|
|
|
1531
1135
|
}
|
|
1532
1136
|
};
|
|
1533
1137
|
|
|
1534
|
-
// src/client.ts
|
|
1535
|
-
init_errors();
|
|
1536
|
-
|
|
1537
1138
|
// src/lib/routing-api.ts
|
|
1538
|
-
init_errors();
|
|
1539
1139
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1540
1140
|
async function fetchAgentKeys(apiKey) {
|
|
1541
1141
|
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/keys`;
|
|
@@ -1566,7 +1166,6 @@ async function fetchAgentKeys(apiKey) {
|
|
|
1566
1166
|
}
|
|
1567
1167
|
|
|
1568
1168
|
// src/lib/health-report.ts
|
|
1569
|
-
init_errors();
|
|
1570
1169
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1571
1170
|
async function reportAgentFailure(apiKey, agentType, errorCode) {
|
|
1572
1171
|
try {
|
|
@@ -1716,12 +1315,9 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
1716
1315
|
}
|
|
1717
1316
|
|
|
1718
1317
|
// src/client.ts
|
|
1719
|
-
var
|
|
1318
|
+
var import_viem5 = require("viem");
|
|
1720
1319
|
var import_chains2 = require("viem/chains");
|
|
1721
1320
|
|
|
1722
|
-
// src/lib/sponsored-deposit.ts
|
|
1723
|
-
init_errors();
|
|
1724
|
-
|
|
1725
1321
|
// src/lib/transfer-auth.ts
|
|
1726
1322
|
var import_viem3 = require("viem");
|
|
1727
1323
|
var ERC20_META_ABI = [
|
|
@@ -1759,7 +1355,6 @@ function randomAuthNonce() {
|
|
|
1759
1355
|
}
|
|
1760
1356
|
|
|
1761
1357
|
// src/lib/sponsor-client.ts
|
|
1762
|
-
init_errors();
|
|
1763
1358
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
1764
1359
|
async function postSponsorTransferAuth(input) {
|
|
1765
1360
|
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
@@ -1926,9 +1521,6 @@ function makeSponsoredDepositCallback(deps) {
|
|
|
1926
1521
|
};
|
|
1927
1522
|
}
|
|
1928
1523
|
|
|
1929
|
-
// src/lib/sponsored-weth-deposit.ts
|
|
1930
|
-
init_errors();
|
|
1931
|
-
|
|
1932
1524
|
// src/lib/permit2.ts
|
|
1933
1525
|
var import_viem4 = require("viem");
|
|
1934
1526
|
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
@@ -2068,7 +1660,6 @@ var VIEM_CHAIN2 = {
|
|
|
2068
1660
|
42161: import_chains2.arbitrum,
|
|
2069
1661
|
1: import_chains2.mainnet
|
|
2070
1662
|
};
|
|
2071
|
-
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
2072
1663
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
2073
1664
|
8453: "0x4200000000000000000000000000000000000006",
|
|
2074
1665
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -2090,6 +1681,7 @@ var OwneySDK = class {
|
|
|
2090
1681
|
apiKey;
|
|
2091
1682
|
zyfaiRpcUrls;
|
|
2092
1683
|
routingApiBaseUrl;
|
|
1684
|
+
referralSource;
|
|
2093
1685
|
cachedSponsoredCallback = null;
|
|
2094
1686
|
cachedWethSponsoredCallback = null;
|
|
2095
1687
|
initializingAgentsPromise = null;
|
|
@@ -2097,6 +1689,7 @@ var OwneySDK = class {
|
|
|
2097
1689
|
this.apiKey = config.apiKey;
|
|
2098
1690
|
this.zyfaiRpcUrls = config.zyfaiRpcUrls;
|
|
2099
1691
|
this.routingApiBaseUrl = config.routingApiBaseUrl;
|
|
1692
|
+
this.referralSource = config.referralSource;
|
|
2100
1693
|
}
|
|
2101
1694
|
/**
|
|
2102
1695
|
* Establish connection state for all subsequent SDK calls.
|
|
@@ -2192,14 +1785,14 @@ var OwneySDK = class {
|
|
|
2192
1785
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2193
1786
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2194
1787
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2195
|
-
getPublicClient: (cid) => (0,
|
|
1788
|
+
getPublicClient: (cid) => (0, import_viem5.createPublicClient)({
|
|
2196
1789
|
chain: VIEM_CHAIN2[cid],
|
|
2197
|
-
transport: (0,
|
|
1790
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2198
1791
|
}),
|
|
2199
|
-
getWalletClient: (cid) => (0,
|
|
1792
|
+
getWalletClient: (cid) => (0, import_viem5.createWalletClient)({
|
|
2200
1793
|
account: owner,
|
|
2201
1794
|
chain: VIEM_CHAIN2[cid],
|
|
2202
|
-
transport: (0,
|
|
1795
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2203
1796
|
})
|
|
2204
1797
|
});
|
|
2205
1798
|
return this.cachedSponsoredCallback;
|
|
@@ -2223,14 +1816,14 @@ var OwneySDK = class {
|
|
|
2223
1816
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2224
1817
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2225
1818
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2226
|
-
getPublicClient: (cid) => (0,
|
|
1819
|
+
getPublicClient: (cid) => (0, import_viem5.createPublicClient)({
|
|
2227
1820
|
chain: VIEM_CHAIN2[cid],
|
|
2228
|
-
transport: (0,
|
|
1821
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2229
1822
|
}),
|
|
2230
|
-
getWalletClient: (cid) => (0,
|
|
1823
|
+
getWalletClient: (cid) => (0, import_viem5.createWalletClient)({
|
|
2231
1824
|
account: owner,
|
|
2232
1825
|
chain: VIEM_CHAIN2[cid],
|
|
2233
|
-
transport: (0,
|
|
1826
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2234
1827
|
})
|
|
2235
1828
|
});
|
|
2236
1829
|
return this.cachedWethSponsoredCallback;
|
|
@@ -2256,8 +1849,8 @@ var OwneySDK = class {
|
|
|
2256
1849
|
this.initializingAgentsPromise = (async () => {
|
|
2257
1850
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
2258
1851
|
this.disabledAgents.clear();
|
|
2259
|
-
for (const { key, agent_type,
|
|
2260
|
-
const agent =
|
|
1852
|
+
for (const { key, agent_type, is_enabled } of agentKeys) {
|
|
1853
|
+
const agent = this.createAgent(agent_type, key);
|
|
2261
1854
|
if (!agent) continue;
|
|
2262
1855
|
this.agents.set(agent_type, agent);
|
|
2263
1856
|
if (is_enabled === false) {
|
|
@@ -2278,14 +1871,9 @@ var OwneySDK = class {
|
|
|
2278
1871
|
this.initializingAgentsPromise = null;
|
|
2279
1872
|
}
|
|
2280
1873
|
}
|
|
2281
|
-
|
|
1874
|
+
createAgent(agentId, key) {
|
|
2282
1875
|
if (agentId === "zyfai") {
|
|
2283
|
-
return new ZyfaiAgent(key, this.zyfaiRpcUrls);
|
|
2284
|
-
}
|
|
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 });
|
|
1876
|
+
return new ZyfaiAgent(key, this.zyfaiRpcUrls, this.referralSource);
|
|
2289
1877
|
}
|
|
2290
1878
|
return null;
|
|
2291
1879
|
}
|
|
@@ -2439,30 +2027,18 @@ var OwneySDK = class {
|
|
|
2439
2027
|
);
|
|
2440
2028
|
}
|
|
2441
2029
|
const agentResults = {};
|
|
2442
|
-
const agentErrors = {};
|
|
2443
2030
|
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 }
|
|
2031
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
2032
|
+
agent,
|
|
2033
|
+
state,
|
|
2034
|
+
chainId,
|
|
2035
|
+
agentAmount,
|
|
2036
|
+
asset,
|
|
2037
|
+
effectiveCallback,
|
|
2038
|
+
depositCallback
|
|
2463
2039
|
);
|
|
2464
2040
|
}
|
|
2465
|
-
return
|
|
2041
|
+
return { agentResults };
|
|
2466
2042
|
}
|
|
2467
2043
|
/**
|
|
2468
2044
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -2619,34 +2195,6 @@ var OwneySDK = class {
|
|
|
2619
2195
|
}
|
|
2620
2196
|
return eligible;
|
|
2621
2197
|
}
|
|
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
2198
|
// --- Fund operations ---
|
|
2651
2199
|
/**
|
|
2652
2200
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -2682,17 +2230,9 @@ var OwneySDK = class {
|
|
|
2682
2230
|
}
|
|
2683
2231
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
2684
2232
|
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
2233
|
const results2 = {};
|
|
2694
2234
|
const agentErrors2 = {};
|
|
2695
|
-
for (const
|
|
2235
|
+
for (const agent of eligibleAgents) {
|
|
2696
2236
|
try {
|
|
2697
2237
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
2698
2238
|
} catch (err) {
|
|
@@ -2709,10 +2249,9 @@ var OwneySDK = class {
|
|
|
2709
2249
|
{ asset, agentErrors: agentErrors2 }
|
|
2710
2250
|
);
|
|
2711
2251
|
}
|
|
2712
|
-
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
2713
2252
|
return {
|
|
2714
2253
|
agentResult: results2,
|
|
2715
|
-
totalWithdrawn:
|
|
2254
|
+
totalWithdrawn: sumWithdrawnAmount(results2).toString()
|
|
2716
2255
|
};
|
|
2717
2256
|
}
|
|
2718
2257
|
const requested = BigInt(amount);
|
|
@@ -3082,10 +2621,10 @@ var OwneySDK = class {
|
|
|
3082
2621
|
);
|
|
3083
2622
|
}
|
|
3084
2623
|
const provider = this.requireConnectedProvider();
|
|
3085
|
-
const wallet = (0,
|
|
2624
|
+
const wallet = (0, import_viem5.createWalletClient)({
|
|
3086
2625
|
account: state.walletAddress,
|
|
3087
2626
|
chain: VIEM_CHAIN2[chainId],
|
|
3088
|
-
transport: (0,
|
|
2627
|
+
transport: (0, import_viem5.custom)(provider)
|
|
3089
2628
|
});
|
|
3090
2629
|
const hash = await wallet.writeContract({
|
|
3091
2630
|
address: token,
|
|
@@ -3095,9 +2634,9 @@ var OwneySDK = class {
|
|
|
3095
2634
|
account: state.walletAddress,
|
|
3096
2635
|
chain: VIEM_CHAIN2[chainId]
|
|
3097
2636
|
});
|
|
3098
|
-
const publicClient = (0,
|
|
2637
|
+
const publicClient = (0, import_viem5.createPublicClient)({
|
|
3099
2638
|
chain: VIEM_CHAIN2[chainId],
|
|
3100
|
-
transport: (0,
|
|
2639
|
+
transport: (0, import_viem5.custom)(provider)
|
|
3101
2640
|
});
|
|
3102
2641
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
3103
2642
|
hash,
|
|
@@ -3205,11 +2744,8 @@ var OwneySDK = class {
|
|
|
3205
2744
|
}
|
|
3206
2745
|
};
|
|
3207
2746
|
|
|
3208
|
-
// src/index.ts
|
|
3209
|
-
init_errors();
|
|
3210
|
-
|
|
3211
2747
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
3212
|
-
var
|
|
2748
|
+
var import_viem6 = require("viem");
|
|
3213
2749
|
var import_siwe = require("siwe");
|
|
3214
2750
|
var import_sdk2 = require("@zyfai/sdk");
|
|
3215
2751
|
|
|
@@ -3223,11 +2759,39 @@ var storage2 = () => {
|
|
|
3223
2759
|
return null;
|
|
3224
2760
|
}
|
|
3225
2761
|
};
|
|
3226
|
-
var buildKey2 = (address
|
|
2762
|
+
var buildKey2 = (address) => `${KEY_PREFIX2}:${address.toLowerCase()}`;
|
|
2763
|
+
var legacyKeyPrefix2 = (address) => `${KEY_PREFIX2}:${address.toLowerCase()}:`;
|
|
3227
2764
|
var memorySiwxSessions = /* @__PURE__ */ new Map();
|
|
2765
|
+
var readLegacySiwxSession = (store, address) => {
|
|
2766
|
+
if (!store) return null;
|
|
2767
|
+
const prefix = legacyKeyPrefix2(address);
|
|
2768
|
+
const legacyKeys = [];
|
|
2769
|
+
try {
|
|
2770
|
+
for (let i = 0; i < store.length; i++) {
|
|
2771
|
+
const key = store.key(i);
|
|
2772
|
+
if (key?.startsWith(prefix)) legacyKeys.push(key);
|
|
2773
|
+
}
|
|
2774
|
+
} catch {
|
|
2775
|
+
return null;
|
|
2776
|
+
}
|
|
2777
|
+
let adopted = null;
|
|
2778
|
+
for (const key of legacyKeys) {
|
|
2779
|
+
if (!adopted) {
|
|
2780
|
+
try {
|
|
2781
|
+
adopted = JSON.parse(store.getItem(key) ?? "");
|
|
2782
|
+
} catch {
|
|
2783
|
+
}
|
|
2784
|
+
}
|
|
2785
|
+
try {
|
|
2786
|
+
store.removeItem(key);
|
|
2787
|
+
} catch {
|
|
2788
|
+
}
|
|
2789
|
+
}
|
|
2790
|
+
return adopted;
|
|
2791
|
+
};
|
|
3228
2792
|
var readSiwxSession = (address, chainId) => {
|
|
3229
2793
|
if (typeof window === "undefined") return null;
|
|
3230
|
-
const key = buildKey2(address
|
|
2794
|
+
const key = buildKey2(address);
|
|
3231
2795
|
const store = storage2();
|
|
3232
2796
|
let raw = null;
|
|
3233
2797
|
try {
|
|
@@ -3247,11 +2811,16 @@ var readSiwxSession = (address, chainId) => {
|
|
|
3247
2811
|
return null;
|
|
3248
2812
|
}
|
|
3249
2813
|
}
|
|
2814
|
+
const legacy = readLegacySiwxSession(store, address);
|
|
2815
|
+
if (legacy) {
|
|
2816
|
+
writeSiwxSession(address, chainId, legacy);
|
|
2817
|
+
return legacy;
|
|
2818
|
+
}
|
|
3250
2819
|
return memorySiwxSessions.get(key) ?? null;
|
|
3251
2820
|
};
|
|
3252
|
-
var writeSiwxSession = (address,
|
|
2821
|
+
var writeSiwxSession = (address, _chainId, session) => {
|
|
3253
2822
|
if (typeof window === "undefined") return;
|
|
3254
|
-
const key = buildKey2(address
|
|
2823
|
+
const key = buildKey2(address);
|
|
3255
2824
|
memorySiwxSessions.set(key, session);
|
|
3256
2825
|
const store = storage2();
|
|
3257
2826
|
try {
|
|
@@ -3259,14 +2828,15 @@ var writeSiwxSession = (address, chainId, session) => {
|
|
|
3259
2828
|
} catch {
|
|
3260
2829
|
}
|
|
3261
2830
|
};
|
|
3262
|
-
var clearSiwxSession = (address,
|
|
3263
|
-
const key = buildKey2(address
|
|
2831
|
+
var clearSiwxSession = (address, _chainId) => {
|
|
2832
|
+
const key = buildKey2(address);
|
|
3264
2833
|
memorySiwxSessions.delete(key);
|
|
3265
2834
|
const store = storage2();
|
|
3266
2835
|
try {
|
|
3267
2836
|
store?.removeItem(key);
|
|
3268
2837
|
} catch {
|
|
3269
2838
|
}
|
|
2839
|
+
readLegacySiwxSession(store, address);
|
|
3270
2840
|
};
|
|
3271
2841
|
|
|
3272
2842
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
@@ -3302,7 +2872,7 @@ function buildSIWXConfig(deps) {
|
|
|
3302
2872
|
issuedAt,
|
|
3303
2873
|
toString() {
|
|
3304
2874
|
return new import_siwe.SiweMessage({
|
|
3305
|
-
address: (0,
|
|
2875
|
+
address: (0, import_viem6.getAddress)(accountAddress),
|
|
3306
2876
|
chainId: numericChainId(chainId),
|
|
3307
2877
|
domain,
|
|
3308
2878
|
uri,
|
|
@@ -3330,9 +2900,12 @@ function buildSIWXConfig(deps) {
|
|
|
3330
2900
|
}
|
|
3331
2901
|
if (!stored) return [];
|
|
3332
2902
|
const session = {
|
|
3333
|
-
// `stored.data
|
|
3334
|
-
//
|
|
3335
|
-
|
|
2903
|
+
// `stored.data` is kept AppKit-free in the cache, so narrow at the
|
|
2904
|
+
// boundary. Echo the REQUESTED chain rather than the one originally
|
|
2905
|
+
// signed: the Zyfai JWT is account-scoped (no chain claim), so one
|
|
2906
|
+
// signature is valid for every chain, and AppKit would otherwise treat
|
|
2907
|
+
// the session as not covering the active network and re-prompt.
|
|
2908
|
+
data: { ...stored.data, chainId },
|
|
3336
2909
|
message: stored.message,
|
|
3337
2910
|
signature: stored.signature
|
|
3338
2911
|
};
|