@owney/sdk 0.7.10-beta.0 → 0.7.11
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 +238 -891
- package/dist/index.d.cts +11 -30
- package/dist/index.d.ts +11 -30
- package/dist/index.js +214 -210
- package/package.json +2 -4
- package/dist/chunk-PWIKIQOX.js +0 -140
- package/dist/surfliquid.agent-VNGQUSXN.js +0 -473
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,645 +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/lib/permit2.ts
|
|
84
|
-
function buildPermitTransferFromTypedData(input) {
|
|
85
|
-
return {
|
|
86
|
-
domain: {
|
|
87
|
-
name: "Permit2",
|
|
88
|
-
chainId: input.chainId,
|
|
89
|
-
verifyingContract: PERMIT2_ADDRESS
|
|
90
|
-
},
|
|
91
|
-
types: {
|
|
92
|
-
PermitTransferFrom: [
|
|
93
|
-
{ name: "permitted", type: "TokenPermissions" },
|
|
94
|
-
{ name: "spender", type: "address" },
|
|
95
|
-
{ name: "nonce", type: "uint256" },
|
|
96
|
-
{ name: "deadline", type: "uint256" }
|
|
97
|
-
],
|
|
98
|
-
TokenPermissions: [
|
|
99
|
-
{ name: "token", type: "address" },
|
|
100
|
-
{ name: "amount", type: "uint256" }
|
|
101
|
-
]
|
|
102
|
-
},
|
|
103
|
-
primaryType: "PermitTransferFrom",
|
|
104
|
-
message: input.message
|
|
105
|
-
};
|
|
106
|
-
}
|
|
107
|
-
function randomPermit2Nonce() {
|
|
108
|
-
const bytes = new Uint8Array(32);
|
|
109
|
-
globalThis.crypto.getRandomValues(bytes);
|
|
110
|
-
return BigInt((0, import_viem4.bytesToHex)(bytes));
|
|
111
|
-
}
|
|
112
|
-
async function readPermit2Allowance(publicClient, token, owner) {
|
|
113
|
-
return publicClient.readContract({
|
|
114
|
-
address: token,
|
|
115
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
116
|
-
functionName: "allowance",
|
|
117
|
-
args: [owner, PERMIT2_ADDRESS]
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
async function readErc20Balance(publicClient, token, owner) {
|
|
121
|
-
return publicClient.readContract({
|
|
122
|
-
address: token,
|
|
123
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
124
|
-
functionName: "balanceOf",
|
|
125
|
-
args: [owner]
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
var import_viem4, PERMIT2_ADDRESS, MAX_UINT256, ERC20_ALLOWANCE_ABI;
|
|
129
|
-
var init_permit2 = __esm({
|
|
130
|
-
"src/lib/permit2.ts"() {
|
|
131
|
-
"use strict";
|
|
132
|
-
import_viem4 = require("viem");
|
|
133
|
-
PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
134
|
-
MAX_UINT256 = 2n ** 256n - 1n;
|
|
135
|
-
ERC20_ALLOWANCE_ABI = [
|
|
136
|
-
{
|
|
137
|
-
type: "function",
|
|
138
|
-
name: "allowance",
|
|
139
|
-
stateMutability: "view",
|
|
140
|
-
inputs: [
|
|
141
|
-
{ name: "owner", type: "address" },
|
|
142
|
-
{ name: "spender", type: "address" }
|
|
143
|
-
],
|
|
144
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
145
|
-
},
|
|
146
|
-
{
|
|
147
|
-
type: "function",
|
|
148
|
-
name: "approve",
|
|
149
|
-
stateMutability: "nonpayable",
|
|
150
|
-
inputs: [
|
|
151
|
-
{ name: "spender", type: "address" },
|
|
152
|
-
{ name: "amount", type: "uint256" }
|
|
153
|
-
],
|
|
154
|
-
outputs: [{ name: "", type: "bool" }]
|
|
155
|
-
},
|
|
156
|
-
{
|
|
157
|
-
type: "function",
|
|
158
|
-
name: "balanceOf",
|
|
159
|
-
stateMutability: "view",
|
|
160
|
-
inputs: [{ name: "account", type: "address" }],
|
|
161
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
162
|
-
}
|
|
163
|
-
];
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// src/agents/surfliquid/surfliquid.constants.ts
|
|
168
|
-
var SURFLIQUID_CHAIN_ID, SURFLIQUID_CHAIN_NAME, SURFLIQUID_USDC_ADDRESS, SURFLIQUID_USDC_DECIMALS, SURFLIQUID_MIN_DEPOSIT, SURFLIQUID_APPROVAL_TARGET, SURFLIQUID_SUPPORTED_ASSETS, SURFLIQUID_ACTION_MAP;
|
|
169
|
-
var init_surfliquid_constants = __esm({
|
|
170
|
-
"src/agents/surfliquid/surfliquid.constants.ts"() {
|
|
171
|
-
"use strict";
|
|
172
|
-
SURFLIQUID_CHAIN_ID = 8453;
|
|
173
|
-
SURFLIQUID_CHAIN_NAME = "BASE";
|
|
174
|
-
SURFLIQUID_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
175
|
-
SURFLIQUID_USDC_DECIMALS = 6;
|
|
176
|
-
SURFLIQUID_MIN_DEPOSIT = "0";
|
|
177
|
-
SURFLIQUID_APPROVAL_TARGET = 100000000000n;
|
|
178
|
-
SURFLIQUID_SUPPORTED_ASSETS = [
|
|
179
|
-
{
|
|
180
|
-
chainId: SURFLIQUID_CHAIN_ID,
|
|
181
|
-
chain: SURFLIQUID_CHAIN_NAME,
|
|
182
|
-
assets: [{ symbol: "USDC", minDepositAmount: SURFLIQUID_MIN_DEPOSIT }]
|
|
183
|
-
}
|
|
184
|
-
];
|
|
185
|
-
SURFLIQUID_ACTION_MAP = {
|
|
186
|
-
// INITIAL_DEPOSIT is the user's real first deposit, so surface it like any
|
|
187
|
-
// other funding ("Top up"). The mini-app intentionally hides the "Deposit"
|
|
188
|
-
// action (it marks Zyfai's smart-account-creation event), which would
|
|
189
|
-
// otherwise drop a SurfLiquid user's only history row.
|
|
190
|
-
INITIAL_DEPOSIT: "Top up",
|
|
191
|
-
DEPOSIT: "Top up",
|
|
192
|
-
USER_DEPOSIT: "Top up",
|
|
193
|
-
WITHDRAWAL: "Withdraw",
|
|
194
|
-
USER_WITHDRAWAL: "Withdraw",
|
|
195
|
-
REBALANCE: "Rebalance",
|
|
196
|
-
REBALANCE_COMPLETED: "Rebalance",
|
|
197
|
-
CROSS_CHAIN_REBALANCE: "Rebalance",
|
|
198
|
-
MERKL_CLAIM: "Earned"
|
|
199
|
-
};
|
|
200
|
-
}
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
// src/agents/surfliquid/surfliquid.mapper.ts
|
|
204
|
-
function mapMessage(message) {
|
|
205
|
-
const action = SURFLIQUID_ACTION_MAP[message.transactionType];
|
|
206
|
-
if (!action) return null;
|
|
207
|
-
return {
|
|
208
|
-
agent: "surfliquid",
|
|
209
|
-
action,
|
|
210
|
-
date: message.timestamp,
|
|
211
|
-
oldApy: message.apyBefore != null ? String(message.apyBefore) : null,
|
|
212
|
-
newApy: message.apyAfter != null ? String(message.apyAfter) : null,
|
|
213
|
-
transactions: [
|
|
214
|
-
{
|
|
215
|
-
txHashes: [message.txHash],
|
|
216
|
-
chainId: message.chainId,
|
|
217
|
-
tokenSymbol: message.token ?? void 0,
|
|
218
|
-
amount: message.amount != null ? String(message.amount) : void 0
|
|
219
|
-
}
|
|
220
|
-
],
|
|
221
|
-
rebalanceLog: []
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
function mapHistory(result, _chainId) {
|
|
225
|
-
const data = result.messages.map(mapMessage).filter((entry) => entry !== null);
|
|
226
|
-
const hasMore = result.page < result.pages;
|
|
227
|
-
return {
|
|
228
|
-
data,
|
|
229
|
-
hasMore,
|
|
230
|
-
nextCursor: hasMore ? String(result.page + 1) : void 0
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
function mapBalances2(vault, chainId, morphoStats) {
|
|
234
|
-
const assets = (vault.assets ?? []).filter(
|
|
235
|
-
(asset) => asset.assetSymbol === "USDC" && asset.chainId === chainId
|
|
236
|
-
);
|
|
237
|
-
const tokens = assets.map((asset) => ({
|
|
238
|
-
chain: SURFLIQUID_CHAIN_NAME,
|
|
239
|
-
chainId: SURFLIQUID_CHAIN_ID,
|
|
240
|
-
asset: "USDC",
|
|
241
|
-
amount: String(asset.currentValueUSD)
|
|
242
|
-
}));
|
|
243
|
-
const positions = assets.map((asset) => {
|
|
244
|
-
const stats = morphoStats?.get(asset.morphoVaultAddress?.toLowerCase() ?? "");
|
|
245
|
-
return {
|
|
246
|
-
chain: SURFLIQUID_CHAIN_NAME,
|
|
247
|
-
protocol: "Morpho",
|
|
248
|
-
// The specific MetaMorpho vault (e.g. "Gauntlet USDC Frontier"), read from
|
|
249
|
-
// Morpho — renders as "Morpho <vault>" alongside zyfai's vault detail.
|
|
250
|
-
pool: stats?.name ?? void 0,
|
|
251
|
-
asset: "USDC",
|
|
252
|
-
amount: String(asset.currentValueUSD),
|
|
253
|
-
apy: asset.currentAPY,
|
|
254
|
-
// TVL + liquidity come straight from Morpho (SurfLiquid's API omits them).
|
|
255
|
-
tvl: stats?.tvlUsd,
|
|
256
|
-
liquidity: stats?.liquidityUsd
|
|
257
|
-
};
|
|
258
|
-
});
|
|
259
|
-
const total = assets.reduce(
|
|
260
|
-
(sum, asset) => sum + asset.currentValueUSD,
|
|
261
|
-
0
|
|
262
|
-
);
|
|
263
|
-
return {
|
|
264
|
-
smartWallet: vault.userVaultAddress ?? void 0,
|
|
265
|
-
totalBalance: String(total),
|
|
266
|
-
totalBalanceAsset: "usdc",
|
|
267
|
-
tokens,
|
|
268
|
-
positions
|
|
269
|
-
};
|
|
270
|
-
}
|
|
271
|
-
function mapAccountApy(vault, days) {
|
|
272
|
-
const breakdown = vault.apyBreakdown;
|
|
273
|
-
const windowed = breakdown ? breakdown[APY_WINDOW_KEY[days]] : void 0;
|
|
274
|
-
const apy = windowed != null ? windowed : breakdown?.currentAPY ?? 0;
|
|
275
|
-
return {
|
|
276
|
-
walletAddress: vault.walletAddress ?? "",
|
|
277
|
-
weightedApyAfterFee: apy,
|
|
278
|
-
apyByChainAndAsset: { [SURFLIQUID_CHAIN_ID]: { USDC: apy } },
|
|
279
|
-
// Parity with Sail: SurfLiquid's core-sdk exposes no daily net-APY series.
|
|
280
|
-
history: []
|
|
281
|
-
};
|
|
282
|
-
}
|
|
283
|
-
function mapEarnings2(vault, vaultAddress) {
|
|
284
|
-
return {
|
|
285
|
-
smartWallet: vaultAddress,
|
|
286
|
-
lifetimeEarnings: vault.earned?.totalEarningsUSD ?? 0,
|
|
287
|
-
tokens: []
|
|
288
|
-
};
|
|
289
|
-
}
|
|
290
|
-
function mapUserProfile2(vault, address) {
|
|
291
|
-
return {
|
|
292
|
-
address,
|
|
293
|
-
smartWallet: vault.userVaultAddress ?? "",
|
|
294
|
-
chains: [SURFLIQUID_CHAIN_ID],
|
|
295
|
-
// SurfLiquid uses cookie-based session auth — no session-key concept.
|
|
296
|
-
hasActiveSessionKey: false,
|
|
297
|
-
protocols: ["SurfLiquid"]
|
|
298
|
-
};
|
|
299
|
-
}
|
|
300
|
-
var APY_WINDOW_KEY;
|
|
301
|
-
var init_surfliquid_mapper = __esm({
|
|
302
|
-
"src/agents/surfliquid/surfliquid.mapper.ts"() {
|
|
303
|
-
"use strict";
|
|
304
|
-
init_surfliquid_constants();
|
|
305
|
-
APY_WINDOW_KEY = {
|
|
306
|
-
"7D": "apy7d",
|
|
307
|
-
"14D": "apy14d",
|
|
308
|
-
"30D": "apy30d"
|
|
309
|
-
};
|
|
310
|
-
}
|
|
311
|
-
});
|
|
312
|
-
|
|
313
|
-
// src/agents/surfliquid/surfliquid.wallet-adapter.ts
|
|
314
|
-
var import_core_sdk, OwneyWalletAdapter;
|
|
315
|
-
var init_surfliquid_wallet_adapter = __esm({
|
|
316
|
-
"src/agents/surfliquid/surfliquid.wallet-adapter.ts"() {
|
|
317
|
-
"use strict";
|
|
318
|
-
import_core_sdk = require("@surf_liquid/core-sdk");
|
|
319
|
-
OwneyWalletAdapter = class extends import_core_sdk.BaseWalletAdapter {
|
|
320
|
-
constructor(eip1193Provider) {
|
|
321
|
-
super();
|
|
322
|
-
this.eip1193Provider = eip1193Provider;
|
|
323
|
-
}
|
|
324
|
-
eip1193Provider;
|
|
325
|
-
name = "owney";
|
|
326
|
-
get installed() {
|
|
327
|
-
return true;
|
|
328
|
-
}
|
|
329
|
-
resolveProvider() {
|
|
330
|
-
return this.eip1193Provider;
|
|
331
|
-
}
|
|
332
|
-
};
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
|
|
336
|
-
// src/agents/surfliquid/surfliquid.morpho.ts
|
|
337
|
-
async function queryMorpho(query, vaultAddress, chainId) {
|
|
338
|
-
try {
|
|
339
|
-
const res = await fetch(MORPHO_API_URL, {
|
|
340
|
-
method: "POST",
|
|
341
|
-
headers: { "Content-Type": "application/json" },
|
|
342
|
-
body: JSON.stringify({
|
|
343
|
-
query,
|
|
344
|
-
variables: { address: vaultAddress, chainId }
|
|
345
|
-
})
|
|
346
|
-
});
|
|
347
|
-
if (!res.ok) return null;
|
|
348
|
-
const json = await res.json();
|
|
349
|
-
if (json.errors) return null;
|
|
350
|
-
return json.data ?? null;
|
|
351
|
-
} catch (error) {
|
|
352
|
-
console.warn("surfliquid: Morpho vault stats fetch failed", {
|
|
353
|
-
vaultAddress,
|
|
354
|
-
chainId,
|
|
355
|
-
error
|
|
356
|
-
});
|
|
357
|
-
return null;
|
|
358
|
-
}
|
|
359
|
-
}
|
|
360
|
-
function toStats(name, tvlUsd, liquidityUsd) {
|
|
361
|
-
if (typeof tvlUsd !== "number" || typeof liquidityUsd !== "number") {
|
|
362
|
-
return null;
|
|
363
|
-
}
|
|
364
|
-
return {
|
|
365
|
-
name: typeof name === "string" ? name : null,
|
|
366
|
-
tvlUsd,
|
|
367
|
-
liquidityUsd
|
|
368
|
-
};
|
|
369
|
-
}
|
|
370
|
-
async function fetchMorphoVaultStats(vaultAddress, chainId) {
|
|
371
|
-
const v1 = await queryMorpho(VAULT_STATS_QUERY, vaultAddress, chainId);
|
|
372
|
-
const vault = v1?.vaultByAddress;
|
|
373
|
-
const v1Stats = toStats(
|
|
374
|
-
vault?.name,
|
|
375
|
-
vault?.state?.totalAssetsUsd,
|
|
376
|
-
vault?.liquidity?.usd
|
|
377
|
-
);
|
|
378
|
-
if (v1Stats) return v1Stats;
|
|
379
|
-
const v2 = await queryMorpho(VAULT_V2_STATS_QUERY, vaultAddress, chainId);
|
|
380
|
-
const vaultV2 = v2?.vaultV2ByAddress;
|
|
381
|
-
return toStats(vaultV2?.name, vaultV2?.totalAssetsUsd, vaultV2?.liquidityUsd);
|
|
382
|
-
}
|
|
383
|
-
async function fetchMorphoStatsByVault(vaultAddresses, chainId) {
|
|
384
|
-
const unique = [...new Set(vaultAddresses.map((a) => a.toLowerCase()))];
|
|
385
|
-
const entries = await Promise.all(
|
|
386
|
-
unique.map(
|
|
387
|
-
async (address) => [address, await fetchMorphoVaultStats(address, chainId)]
|
|
388
|
-
)
|
|
389
|
-
);
|
|
390
|
-
const byVault = /* @__PURE__ */ new Map();
|
|
391
|
-
for (const [address, stats] of entries) {
|
|
392
|
-
if (stats) byVault.set(address, stats);
|
|
393
|
-
}
|
|
394
|
-
return byVault;
|
|
395
|
-
}
|
|
396
|
-
var MORPHO_API_URL, VAULT_STATS_QUERY, VAULT_V2_STATS_QUERY;
|
|
397
|
-
var init_surfliquid_morpho = __esm({
|
|
398
|
-
"src/agents/surfliquid/surfliquid.morpho.ts"() {
|
|
399
|
-
"use strict";
|
|
400
|
-
MORPHO_API_URL = "https://api.morpho.org/graphql";
|
|
401
|
-
VAULT_STATS_QUERY = `
|
|
402
|
-
query VaultStats($address: String!, $chainId: Int!) {
|
|
403
|
-
vaultByAddress(address: $address, chainId: $chainId) {
|
|
404
|
-
name
|
|
405
|
-
state { totalAssetsUsd }
|
|
406
|
-
liquidity { usd }
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
`;
|
|
410
|
-
VAULT_V2_STATS_QUERY = `
|
|
411
|
-
query VaultV2Stats($address: String!, $chainId: Int!) {
|
|
412
|
-
vaultV2ByAddress(address: $address, chainId: $chainId) {
|
|
413
|
-
name
|
|
414
|
-
totalAssetsUsd
|
|
415
|
-
liquidityUsd
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
`;
|
|
419
|
-
}
|
|
420
|
-
});
|
|
421
|
-
|
|
422
|
-
// src/agents/surfliquid/surfliquid.agent.ts
|
|
423
|
-
var surfliquid_agent_exports = {};
|
|
424
|
-
__export(surfliquid_agent_exports, {
|
|
425
|
-
SurfLiquidAgent: () => SurfLiquidAgent
|
|
426
|
-
});
|
|
427
|
-
var import_core_sdk2, import_viem6, import_chains2, APY_WINDOW_KEY2, SurfLiquidAgent;
|
|
428
|
-
var init_surfliquid_agent = __esm({
|
|
429
|
-
"src/agents/surfliquid/surfliquid.agent.ts"() {
|
|
430
|
-
"use strict";
|
|
431
|
-
import_core_sdk2 = require("@surf_liquid/core-sdk");
|
|
432
|
-
import_viem6 = require("viem");
|
|
433
|
-
import_chains2 = require("viem/chains");
|
|
434
|
-
init_errors();
|
|
435
|
-
init_surfliquid_constants();
|
|
436
|
-
init_permit2();
|
|
437
|
-
init_surfliquid_mapper();
|
|
438
|
-
init_surfliquid_wallet_adapter();
|
|
439
|
-
init_surfliquid_morpho();
|
|
440
|
-
APY_WINDOW_KEY2 = {
|
|
441
|
-
"7D": "apy7d",
|
|
442
|
-
"14D": "apy14d",
|
|
443
|
-
"30D": "apy30d"
|
|
444
|
-
};
|
|
445
|
-
SurfLiquidAgent = class {
|
|
446
|
-
constructor(config) {
|
|
447
|
-
this.config = config;
|
|
448
|
-
}
|
|
449
|
-
config;
|
|
450
|
-
id = "surfliquid";
|
|
451
|
-
supportedChainIds = [SURFLIQUID_CHAIN_ID];
|
|
452
|
-
supportedAssets = SURFLIQUID_SUPPORTED_ASSETS;
|
|
453
|
-
surf = null;
|
|
454
|
-
connectedAddress = null;
|
|
455
|
-
// In-flight connect+auth, shared by concurrent callers to dedupe SIWE.
|
|
456
|
-
connectPromise = null;
|
|
457
|
-
ensureSurf() {
|
|
458
|
-
if (this.surf) return this.surf;
|
|
459
|
-
this.surf = import_core_sdk2.SurfClient.create({
|
|
460
|
-
projectName: this.config.projectName,
|
|
461
|
-
appId: this.config.appId,
|
|
462
|
-
environment: "mainnet",
|
|
463
|
-
chainId: SURFLIQUID_CHAIN_ID,
|
|
464
|
-
apiBaseUrl: this.config.apiBaseUrl,
|
|
465
|
-
rpcUrl: this.config.rpcUrl,
|
|
466
|
-
// Let the SDK auto-approve USDC to the vault before depositing.
|
|
467
|
-
autoApprove: true
|
|
468
|
-
});
|
|
469
|
-
return this.surf;
|
|
470
|
-
}
|
|
471
|
-
/**
|
|
472
|
-
* Connects + authenticates the SurfClient against owney's provider. Skips the
|
|
473
|
-
* SIWE prompt when already authenticated for this wallet (cookie session).
|
|
474
|
-
*/
|
|
475
|
-
async connect(state) {
|
|
476
|
-
const surf = this.ensureSurf();
|
|
477
|
-
const sameWallet = this.connectedAddress?.toLowerCase() === state.walletAddress.toLowerCase();
|
|
478
|
-
if (sameWallet && surf.getAuthState().authenticated) {
|
|
479
|
-
return surf;
|
|
480
|
-
}
|
|
481
|
-
if (this.connectPromise) return this.connectPromise;
|
|
482
|
-
this.connectPromise = (async () => {
|
|
483
|
-
surf.registerWalletAdapter(
|
|
484
|
-
"owney",
|
|
485
|
-
new OwneyWalletAdapter(state.provider)
|
|
486
|
-
);
|
|
487
|
-
await surf.connectWallet("owney");
|
|
488
|
-
await surf.authenticate();
|
|
489
|
-
this.connectedAddress = state.walletAddress;
|
|
490
|
-
return surf;
|
|
491
|
-
})();
|
|
492
|
-
try {
|
|
493
|
-
return await this.connectPromise;
|
|
494
|
-
} finally {
|
|
495
|
-
this.connectPromise = null;
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
/**
|
|
499
|
-
* Returns the user's vault address, deploying one on first use. SurfLiquid's
|
|
500
|
-
* deposit requires the vault to exist, so this must run before depositing.
|
|
501
|
-
* Existing vault → returned as-is; otherwise `deployVault()` is sent
|
|
502
|
-
* (user-pays) and the freshly deployed address is returned.
|
|
503
|
-
*/
|
|
504
|
-
async resolveVaultAddress(surf, owner) {
|
|
505
|
-
const vault = await surf.getVault(owner).catch(() => null);
|
|
506
|
-
if (vault?.exists && vault.userVaultAddress) {
|
|
507
|
-
return vault.userVaultAddress;
|
|
508
|
-
}
|
|
509
|
-
const { vaultAddress } = await surf.deployVault();
|
|
510
|
-
return vaultAddress;
|
|
511
|
-
}
|
|
512
|
-
/**
|
|
513
|
-
* Grants the user's vault a standing USDC allowance so SurfLiquid's
|
|
514
|
-
* `autoApprove` has nothing to do — see {@link SURFLIQUID_APPROVAL_TARGET}
|
|
515
|
-
* for why one prompt per deposit is worth removing.
|
|
516
|
-
*
|
|
517
|
-
* Fails OPEN on a read error: if the allowance can't be checked we simply
|
|
518
|
-
* return and let SurfLiquid's own per-deposit approve run, because a flaky
|
|
519
|
-
* RPC must never block a deposit. A failed or rejected APPROVE does
|
|
520
|
-
* propagate — the user declined a transaction, and letting SurfLiquid
|
|
521
|
-
* immediately ask again for a smaller one is exactly the double prompt this
|
|
522
|
-
* removes.
|
|
523
|
-
*/
|
|
524
|
-
async ensureVaultAllowance(state, vaultAddress, amount) {
|
|
525
|
-
const spender = vaultAddress;
|
|
526
|
-
const transport = (0, import_viem6.custom)(state.provider);
|
|
527
|
-
const publicClient = (0, import_viem6.createPublicClient)({ chain: import_chains2.base, transport });
|
|
528
|
-
let allowance;
|
|
529
|
-
try {
|
|
530
|
-
allowance = await publicClient.readContract({
|
|
531
|
-
address: SURFLIQUID_USDC_ADDRESS,
|
|
532
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
533
|
-
functionName: "allowance",
|
|
534
|
-
args: [state.walletAddress, spender]
|
|
535
|
-
});
|
|
536
|
-
} catch (error) {
|
|
537
|
-
console.warn(
|
|
538
|
-
"[owney-sdk] SurfLiquid allowance pre-check failed; deferring to its per-deposit approve:",
|
|
539
|
-
error instanceof Error ? error.message : String(error)
|
|
540
|
-
);
|
|
541
|
-
return;
|
|
542
|
-
}
|
|
543
|
-
if (allowance >= amount) return;
|
|
544
|
-
const target = amount > SURFLIQUID_APPROVAL_TARGET ? amount : SURFLIQUID_APPROVAL_TARGET;
|
|
545
|
-
const wallet = (0, import_viem6.createWalletClient)({
|
|
546
|
-
account: state.walletAddress,
|
|
547
|
-
chain: import_chains2.base,
|
|
548
|
-
transport
|
|
549
|
-
});
|
|
550
|
-
const hash = await wallet.writeContract({
|
|
551
|
-
address: SURFLIQUID_USDC_ADDRESS,
|
|
552
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
553
|
-
functionName: "approve",
|
|
554
|
-
args: [spender, target],
|
|
555
|
-
account: state.walletAddress,
|
|
556
|
-
chain: import_chains2.base
|
|
557
|
-
});
|
|
558
|
-
const receipt = await publicClient.waitForTransactionReceipt({
|
|
559
|
-
hash,
|
|
560
|
-
confirmations: 1
|
|
561
|
-
});
|
|
562
|
-
if (receipt.status !== "success") {
|
|
563
|
-
throw new Error(`SurfLiquid USDC approval reverted (tx ${hash})`);
|
|
564
|
-
}
|
|
565
|
-
}
|
|
566
|
-
// --- IAgent: lifecycle ---
|
|
567
|
-
async disconnect() {
|
|
568
|
-
if (this.surf) {
|
|
569
|
-
await this.surf.disconnectWallet();
|
|
570
|
-
}
|
|
571
|
-
this.connectedAddress = null;
|
|
572
|
-
}
|
|
573
|
-
async activateAgent(state) {
|
|
574
|
-
await this.connect(state);
|
|
575
|
-
}
|
|
576
|
-
// --- IAgent: funds (user-pays; asset is always USDC, callback ignored) ---
|
|
577
|
-
async deposit(state, _chainId, amount, _asset, _depositCallback) {
|
|
578
|
-
const surf = await this.connect(state);
|
|
579
|
-
const human = (0, import_viem6.formatUnits)(BigInt(amount), SURFLIQUID_USDC_DECIMALS);
|
|
580
|
-
const smartWallet = await this.resolveVaultAddress(
|
|
581
|
-
surf,
|
|
582
|
-
state.walletAddress
|
|
583
|
-
);
|
|
584
|
-
await this.ensureVaultAllowance(state, smartWallet, BigInt(amount));
|
|
585
|
-
const tx = await surf.deposit({
|
|
586
|
-
asset: SURFLIQUID_USDC_ADDRESS,
|
|
587
|
-
amount: human
|
|
588
|
-
});
|
|
589
|
-
await tx.wait();
|
|
590
|
-
return { txHash: tx.hash, smartWallet, amount };
|
|
591
|
-
}
|
|
592
|
-
async withdraw(state, _chainId, _token, amount) {
|
|
593
|
-
const surf = await this.connect(state);
|
|
594
|
-
const human = amount != null ? (0, import_viem6.formatUnits)(BigInt(amount), SURFLIQUID_USDC_DECIMALS) : void 0;
|
|
595
|
-
try {
|
|
596
|
-
const tx = await surf.withdraw({
|
|
597
|
-
asset: SURFLIQUID_USDC_ADDRESS,
|
|
598
|
-
amount: human
|
|
599
|
-
});
|
|
600
|
-
await tx.wait();
|
|
601
|
-
return {
|
|
602
|
-
txHash: tx.hash,
|
|
603
|
-
type: amount != null ? "partial" : "full",
|
|
604
|
-
amount: amount ?? "0"
|
|
605
|
-
};
|
|
606
|
-
} catch (error) {
|
|
607
|
-
throw new OwneyError(
|
|
608
|
-
"WITHDRAW_FAILED",
|
|
609
|
-
error instanceof Error ? error.message : "SurfLiquid withdraw failed.",
|
|
610
|
-
{ chainId: SURFLIQUID_CHAIN_ID, amount },
|
|
611
|
-
this.id
|
|
612
|
-
);
|
|
613
|
-
}
|
|
614
|
-
}
|
|
615
|
-
// --- IAgent: portfolio reads ---
|
|
616
|
-
async getBalances(state, chainId) {
|
|
617
|
-
const surf = await this.connect(state);
|
|
618
|
-
const vault = await surf.getVault(state.walletAddress);
|
|
619
|
-
const morphoVaultAddresses = (vault.assets ?? []).filter((asset) => asset.assetSymbol === "USDC" && asset.chainId === chainId).map((asset) => asset.morphoVaultAddress).filter((address) => Boolean(address));
|
|
620
|
-
const morphoStats = await fetchMorphoStatsByVault(
|
|
621
|
-
morphoVaultAddresses,
|
|
622
|
-
chainId
|
|
623
|
-
);
|
|
624
|
-
return mapBalances2(vault, chainId, morphoStats);
|
|
625
|
-
}
|
|
626
|
-
async getEarnings(state) {
|
|
627
|
-
const surf = await this.connect(state);
|
|
628
|
-
const vault = await surf.getVault(state.walletAddress);
|
|
629
|
-
return mapEarnings2(vault, vault.userVaultAddress ?? state.walletAddress);
|
|
630
|
-
}
|
|
631
|
-
async getAccountApy(state, _chainId, days, _tokenSymbol) {
|
|
632
|
-
const surf = await this.connect(state);
|
|
633
|
-
const vault = await surf.getVault(state.walletAddress);
|
|
634
|
-
return mapAccountApy(vault, days);
|
|
635
|
-
}
|
|
636
|
-
async getHistory(state, chainId, options) {
|
|
637
|
-
const surf = await this.connect(state);
|
|
638
|
-
const page = options?.cursor ? Number(options.cursor) : 1;
|
|
639
|
-
const limit = options?.limit ?? 10;
|
|
640
|
-
const result = await surf.getAgentMessages(
|
|
641
|
-
state.walletAddress,
|
|
642
|
-
page,
|
|
643
|
-
limit,
|
|
644
|
-
options?.fromDate,
|
|
645
|
-
options?.toDate
|
|
646
|
-
);
|
|
647
|
-
return mapHistory(result, chainId);
|
|
648
|
-
}
|
|
649
|
-
async getUserProfile(state) {
|
|
650
|
-
const surf = await this.connect(state);
|
|
651
|
-
const vault = await surf.getVault(state.walletAddress);
|
|
652
|
-
return mapUserProfile2(vault, state.walletAddress);
|
|
653
|
-
}
|
|
654
|
-
// --- IAgent: discovery (no wallet) ---
|
|
655
|
-
async getAgentApy(days, _options) {
|
|
656
|
-
const surf = this.ensureSurf();
|
|
657
|
-
const assets = await surf.getSupportedAssets(SURFLIQUID_CHAIN_ID);
|
|
658
|
-
const usdc = assets.find((asset) => asset.assetSymbol === "USDC");
|
|
659
|
-
if (!usdc) return { averageApy: 0 };
|
|
660
|
-
const windowed = usdc[APY_WINDOW_KEY2[days]];
|
|
661
|
-
return { averageApy: windowed != null ? windowed : usdc.currentAPY };
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
}
|
|
665
|
-
});
|
|
666
|
-
|
|
667
20
|
// src/index.ts
|
|
668
21
|
var index_exports = {};
|
|
669
22
|
__export(index_exports, {
|
|
@@ -736,8 +89,56 @@ var SupportedAssets = [
|
|
|
736
89
|
}
|
|
737
90
|
];
|
|
738
91
|
|
|
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
|
+
|
|
739
141
|
// src/lib/utils.ts
|
|
740
|
-
init_errors();
|
|
741
142
|
var isValidChainId = (chainId) => {
|
|
742
143
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
743
144
|
throw new OwneyError(
|
|
@@ -748,12 +149,6 @@ var isValidChainId = (chainId) => {
|
|
|
748
149
|
}
|
|
749
150
|
return chainId;
|
|
750
151
|
};
|
|
751
|
-
function isSameAsset(tokenSymbol, asset) {
|
|
752
|
-
const token = tokenSymbol.toLowerCase();
|
|
753
|
-
const target = asset.toLowerCase();
|
|
754
|
-
if (token === target) return true;
|
|
755
|
-
return target === "weth" && token === "eth" || target === "eth" && token === "weth";
|
|
756
|
-
}
|
|
757
152
|
function hexToDecimal(hex, decimals = 6) {
|
|
758
153
|
const normalized = hex.startsWith("0x") || hex.startsWith("0X") ? hex : `0x${hex}`;
|
|
759
154
|
const parsed = BigInt(normalized);
|
|
@@ -787,10 +182,6 @@ var DECIMALS_BY_SYMBOL = {
|
|
|
787
182
|
wbtc: 8,
|
|
788
183
|
cbbtc: 8
|
|
789
184
|
};
|
|
790
|
-
function canonicalSymbol(symbol) {
|
|
791
|
-
const upper = symbol.toUpperCase();
|
|
792
|
-
return upper === "ETH" ? "WETH" : upper;
|
|
793
|
-
}
|
|
794
185
|
function tokenDecimals(symbol, explicit) {
|
|
795
186
|
if (typeof explicit === "number" && Number.isFinite(explicit))
|
|
796
187
|
return explicit;
|
|
@@ -855,89 +246,55 @@ function mapPendingAllocations(raw) {
|
|
|
855
246
|
function mapBalances(raw, _chainId, smartWallet) {
|
|
856
247
|
const portfolio = raw.portfolio;
|
|
857
248
|
const portfolioByChain = portfolio.portfolioByChain ?? {};
|
|
858
|
-
const rawPositions = portfolio.positions ?? [];
|
|
859
|
-
const detailByKey = /* @__PURE__ */ new Map();
|
|
860
|
-
for (const p of rawPositions) {
|
|
861
|
-
const cid = resolveChainId(p.chain ?? "");
|
|
862
|
-
const symbol = canonicalSymbol(p.token_symbol ?? "");
|
|
863
|
-
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
864
|
-
}
|
|
865
249
|
let totalBalance = 0;
|
|
866
250
|
const tokens = [];
|
|
867
|
-
const positions = [];
|
|
868
251
|
for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
|
|
869
252
|
const positionChainId = Number(chainIdKey);
|
|
870
|
-
const chainName2 = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
|
|
871
253
|
for (const [
|
|
872
254
|
symbol,
|
|
873
255
|
{ balance, balanceWithFee, decimals }
|
|
874
256
|
] of Object.entries(tokensBySymbol ?? {})) {
|
|
875
|
-
const amount = hexToDecimal(
|
|
876
|
-
balanceWithFee ?? balance ?? "0",
|
|
877
|
-
tokenDecimals(symbol, decimals)
|
|
878
|
-
);
|
|
257
|
+
const amount = hexToDecimal(balanceWithFee ?? balance ?? "0", decimals);
|
|
879
258
|
totalBalance += amount;
|
|
880
259
|
tokens.push({
|
|
881
|
-
chain:
|
|
260
|
+
chain: CHAIN_ID_TO_NAME[positionChainId] ?? "BASE",
|
|
882
261
|
chainId: positionChainId,
|
|
883
262
|
asset: symbol,
|
|
884
263
|
amount: String(amount)
|
|
885
264
|
});
|
|
886
|
-
const detail = detailByKey.get(
|
|
887
|
-
`${positionChainId}:${canonicalSymbol(symbol)}`
|
|
888
|
-
);
|
|
889
|
-
positions.push({
|
|
890
|
-
chain: chainName2,
|
|
891
|
-
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
892
|
-
protocolId: detail?.protocol_id,
|
|
893
|
-
pool: detail?.pool,
|
|
894
|
-
// Report the token the way the rest of owney spells it ("WETH", as the
|
|
895
|
-
// pre-portfolioByChain mapper did), not Zyfai's internal "eth".
|
|
896
|
-
asset: canonicalSymbol(symbol),
|
|
897
|
-
amount: String(amount),
|
|
898
|
-
apy: detail?.pool_apy,
|
|
899
|
-
tvl: detail?.pool_tvl,
|
|
900
|
-
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
901
|
-
// structural read keeps it undefined today and auto-populates later.
|
|
902
|
-
liquidity: detail?.liquidity
|
|
903
|
-
});
|
|
904
265
|
}
|
|
905
266
|
}
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
liquidity: p.liquidity
|
|
938
|
-
}))
|
|
939
|
-
);
|
|
940
|
-
}
|
|
267
|
+
const positions = (portfolio.positions ?? []).map((p) => ({
|
|
268
|
+
chain: p.chain ?? "",
|
|
269
|
+
protocol: p.protocol_name ?? p.protocol_id ?? "",
|
|
270
|
+
protocolId: p.protocol_id,
|
|
271
|
+
pool: p.pool,
|
|
272
|
+
asset: p.token_symbol ?? "",
|
|
273
|
+
// Fee-adjusted underlying amounts are decimal base-unit strings. The
|
|
274
|
+
// legacy `amount` fallback is hex. Runtime
|
|
275
|
+
// getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
|
|
276
|
+
// when present, otherwise fall back to the per-symbol lookup.
|
|
277
|
+
amount: String(
|
|
278
|
+
p.underlyingAmountWithFee ?? p.underlyingAmount ? normalizeDecimalPlace(
|
|
279
|
+
p.underlyingAmountWithFee ?? p.underlyingAmount ?? "0",
|
|
280
|
+
tokenDecimals(
|
|
281
|
+
p.token_symbol,
|
|
282
|
+
p.decimals
|
|
283
|
+
)
|
|
284
|
+
) : hexToDecimal(
|
|
285
|
+
p.amount || "0",
|
|
286
|
+
tokenDecimals(
|
|
287
|
+
p.token_symbol,
|
|
288
|
+
p.decimals
|
|
289
|
+
)
|
|
290
|
+
)
|
|
291
|
+
),
|
|
292
|
+
apy: p.pool_apy,
|
|
293
|
+
tvl: p.pool_tvl,
|
|
294
|
+
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
295
|
+
// structural read keeps it undefined today and auto-populates later.
|
|
296
|
+
liquidity: p.liquidity
|
|
297
|
+
}));
|
|
941
298
|
const pendingAllocations = mapPendingAllocations(
|
|
942
299
|
portfolio.staleBalances
|
|
943
300
|
);
|
|
@@ -1232,9 +589,6 @@ function decodeHistoryCursor(token) {
|
|
|
1232
589
|
return parsed;
|
|
1233
590
|
}
|
|
1234
591
|
|
|
1235
|
-
// src/agents/zyfai/zyfai.agent.ts
|
|
1236
|
-
init_errors();
|
|
1237
|
-
|
|
1238
592
|
// src/agents/zyfai/zyfai.auth-cache.ts
|
|
1239
593
|
var KEY_PREFIX = "owney.zyfai.session";
|
|
1240
594
|
var storage = () => {
|
|
@@ -1531,7 +885,7 @@ var VIEM_CHAIN = { 8453: import_chains.base, 42161: import_chains.arbitrum, 1: i
|
|
|
1531
885
|
var SPLITTING_ASSETS = ["USDC", "WETH"];
|
|
1532
886
|
var POOL_POLICY_CHAIN_IDS = [8453, 42161, 1];
|
|
1533
887
|
var EARNINGS_REFRESH_COOLDOWN_MS = 60 * 60 * 1e3;
|
|
1534
|
-
var ZyfaiAgent = class {
|
|
888
|
+
var ZyfaiAgent = class _ZyfaiAgent {
|
|
1535
889
|
id = "zyfai";
|
|
1536
890
|
supportedChainIds = [8453, 42161, 1];
|
|
1537
891
|
supportedAssets = [
|
|
@@ -2023,37 +1377,6 @@ var ZyfaiAgent = class {
|
|
|
2023
1377
|
);
|
|
2024
1378
|
}
|
|
2025
1379
|
}
|
|
2026
|
-
/**
|
|
2027
|
-
* Records the deposit with Zyfai, retrying transient failures.
|
|
2028
|
-
*
|
|
2029
|
-
* This runs AFTER the transfer has already landed on-chain, so it must never
|
|
2030
|
-
* fail the deposit — the funds moved. But it is also the ONLY source of the
|
|
2031
|
-
* "Top up wallet" entry the history is built from: Zyfai auto-deploys the
|
|
2032
|
-
* balance it detects either way, so when this call is lost the user's deposit
|
|
2033
|
-
* never appears in Activity (an earlier withdrawal stays the newest row) and
|
|
2034
|
-
* nothing ever backfills it. Retry, then log loudly enough to be recoverable.
|
|
2035
|
-
*/
|
|
2036
|
-
async logDepositWithRetry(chainId, txHash, amount, tokenAddress) {
|
|
2037
|
-
const ATTEMPTS = 3;
|
|
2038
|
-
const RETRY_DELAY_MS = 1e3;
|
|
2039
|
-
for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
|
|
2040
|
-
try {
|
|
2041
|
-
await (tokenAddress ? this.sdk.logDeposit(chainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(chainId, txHash, amount));
|
|
2042
|
-
return;
|
|
2043
|
-
} catch (logError) {
|
|
2044
|
-
if (attempt === ATTEMPTS) {
|
|
2045
|
-
console.error(
|
|
2046
|
-
"[owney-sdk] Deposit landed on-chain but logDeposit failed \u2014 it will be missing from Zyfai history:",
|
|
2047
|
-
{ txHash, chainId, amount, tokenAddress, error: logError }
|
|
2048
|
-
);
|
|
2049
|
-
return;
|
|
2050
|
-
}
|
|
2051
|
-
await new Promise(
|
|
2052
|
-
(resolve) => setTimeout(resolve, RETRY_DELAY_MS * attempt)
|
|
2053
|
-
);
|
|
2054
|
-
}
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
1380
|
/**
|
|
2058
1381
|
* True when `smartWallet` is the backend-managed pool wallet Zyfai assigned
|
|
2059
1382
|
* to this EOA — the "new wallet" kind that is predeployed on the chains it
|
|
@@ -2357,12 +1680,14 @@ var ZyfaiAgent = class {
|
|
|
2357
1680
|
);
|
|
2358
1681
|
const txHash = await depositCallback(smartWallet, validChainId, amount);
|
|
2359
1682
|
const tokenAddress = asset === "WETH" ? WETH_ADDRESS_BY_CHAIN[validChainId] : void 0;
|
|
2360
|
-
|
|
2361
|
-
validChainId,
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
1683
|
+
try {
|
|
1684
|
+
await (tokenAddress ? this.sdk.logDeposit(validChainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(validChainId, txHash, amount));
|
|
1685
|
+
} catch (logError) {
|
|
1686
|
+
console.warn(
|
|
1687
|
+
"[owney-sdk] Deposit landed on-chain but logDeposit failed (non-fatal):",
|
|
1688
|
+
logError
|
|
1689
|
+
);
|
|
1690
|
+
}
|
|
2366
1691
|
return { txHash, smartWallet, amount };
|
|
2367
1692
|
}
|
|
2368
1693
|
await this.ensureWalletDeployed(this.getAddress(), validChainId);
|
|
@@ -2430,9 +1755,30 @@ var ZyfaiAgent = class {
|
|
|
2430
1755
|
const raw = await this.sdk.getDailyApyHistory(smartWallet, days);
|
|
2431
1756
|
return mapApyHistory(raw, chainId, tokenSymbol);
|
|
2432
1757
|
}
|
|
1758
|
+
/**
|
|
1759
|
+
* Owney speaks asset symbols ("USDC" / "WETH"); Zyfai's history endpoint
|
|
1760
|
+
* takes lowercase `assetType` and denominates WETH as "eth" (the same
|
|
1761
|
+
* spelling `resolveWithdrawnAmounts` normalizes on the way in). Anything
|
|
1762
|
+
* unrecognised returns undefined so the request stays unfiltered rather
|
|
1763
|
+
* than silently narrowing to nothing.
|
|
1764
|
+
*/
|
|
1765
|
+
static toZyfaiAssetType(tokenSymbol) {
|
|
1766
|
+
switch (tokenSymbol?.toUpperCase()) {
|
|
1767
|
+
case "USDC":
|
|
1768
|
+
return "usdc";
|
|
1769
|
+
case "WETH":
|
|
1770
|
+
case "ETH":
|
|
1771
|
+
return "eth";
|
|
1772
|
+
case "EURC":
|
|
1773
|
+
return "eurc";
|
|
1774
|
+
default:
|
|
1775
|
+
return void 0;
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
2433
1778
|
async getHistory(state, chainId, options) {
|
|
2434
1779
|
const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
|
|
2435
1780
|
const limit = options?.limit ?? 10;
|
|
1781
|
+
const assetType = _ZyfaiAgent.toZyfaiAssetType(options?.tokenSymbol);
|
|
2436
1782
|
const cursor = options?.cursor ? decodeHistoryCursor(options.cursor) : null;
|
|
2437
1783
|
const toDate = cursor?.toDate ?? options?.toDate ?? (/* @__PURE__ */ new Date()).toISOString();
|
|
2438
1784
|
let offset = cursor?.rawOffset ?? 0;
|
|
@@ -2446,7 +1792,12 @@ var ZyfaiAgent = class {
|
|
|
2446
1792
|
limit: backendPageSize,
|
|
2447
1793
|
offset,
|
|
2448
1794
|
fromDate: options?.fromDate,
|
|
2449
|
-
toDate
|
|
1795
|
+
toDate,
|
|
1796
|
+
// Filtering server-side means the pages coming back are already the
|
|
1797
|
+
// asset the caller asked for, so the loop below fills `limit` from
|
|
1798
|
+
// relevant entries instead of spending its budget on the other
|
|
1799
|
+
// asset's rows and handing back a page that filters to nothing.
|
|
1800
|
+
assetType
|
|
2450
1801
|
});
|
|
2451
1802
|
raw.data.forEach((entry, idx) => {
|
|
2452
1803
|
if (entry.chainId === validChainId) {
|
|
@@ -2517,11 +1868,7 @@ var ZyfaiAgent = class {
|
|
|
2517
1868
|
}
|
|
2518
1869
|
};
|
|
2519
1870
|
|
|
2520
|
-
// src/client.ts
|
|
2521
|
-
init_errors();
|
|
2522
|
-
|
|
2523
1871
|
// src/lib/routing-api.ts
|
|
2524
|
-
init_errors();
|
|
2525
1872
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
2526
1873
|
async function fetchOrgAgentConfig(apiKey) {
|
|
2527
1874
|
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/org-config`;
|
|
@@ -2586,7 +1933,6 @@ async function fetchAgentKeys(apiKey) {
|
|
|
2586
1933
|
}
|
|
2587
1934
|
|
|
2588
1935
|
// src/lib/health-report.ts
|
|
2589
|
-
init_errors();
|
|
2590
1936
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
2591
1937
|
async function reportAgentFailure(apiKey, agentType, errorCode) {
|
|
2592
1938
|
try {
|
|
@@ -2622,10 +1968,11 @@ async function withFailureReporting(apiKey, agentType, fn) {
|
|
|
2622
1968
|
// src/lib/helpers/withdraw-helper.ts
|
|
2623
1969
|
var import_viem2 = require("viem");
|
|
2624
1970
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
1971
|
+
const target = asset.toUpperCase();
|
|
2625
1972
|
return agents.map((agent) => {
|
|
2626
1973
|
const agentBalance = aggregated[agent.id];
|
|
2627
1974
|
const tokenBalance = agentBalance?.tokens.find(
|
|
2628
|
-
(t) => t.chainId === chainId &&
|
|
1975
|
+
(t) => t.chainId === chainId && t.asset.toUpperCase() === target
|
|
2629
1976
|
);
|
|
2630
1977
|
if (!tokenBalance) return { agent, balance: 0n };
|
|
2631
1978
|
return { agent, balance: (0, import_viem2.parseUnits)(tokenBalance.amount, decimals) };
|
|
@@ -2735,11 +2082,8 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
2735
2082
|
}
|
|
2736
2083
|
|
|
2737
2084
|
// src/client.ts
|
|
2738
|
-
var
|
|
2739
|
-
var
|
|
2740
|
-
|
|
2741
|
-
// src/lib/sponsored-deposit.ts
|
|
2742
|
-
init_errors();
|
|
2085
|
+
var import_viem6 = require("viem");
|
|
2086
|
+
var import_chains2 = require("viem/chains");
|
|
2743
2087
|
|
|
2744
2088
|
// src/lib/transfer-auth.ts
|
|
2745
2089
|
var import_viem3 = require("viem");
|
|
@@ -2778,13 +2122,12 @@ function randomAuthNonce() {
|
|
|
2778
2122
|
}
|
|
2779
2123
|
|
|
2780
2124
|
// src/lib/sponsor-client.ts
|
|
2781
|
-
init_errors();
|
|
2782
2125
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
2783
2126
|
async function postSponsorTransferAuth(input) {
|
|
2784
|
-
const
|
|
2127
|
+
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
2785
2128
|
let res;
|
|
2786
2129
|
try {
|
|
2787
|
-
res = await fetch(`${
|
|
2130
|
+
res = await fetch(`${base3}/api/v1/sponsor/erc20-transfer-auth`, {
|
|
2788
2131
|
method: "POST",
|
|
2789
2132
|
headers: {
|
|
2790
2133
|
"content-type": "application/json",
|
|
@@ -2821,10 +2164,10 @@ async function postSponsorTransferAuth(input) {
|
|
|
2821
2164
|
return parsed.data;
|
|
2822
2165
|
}
|
|
2823
2166
|
async function postSponsorPermit2Transfer(input) {
|
|
2824
|
-
const
|
|
2167
|
+
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
2825
2168
|
let res;
|
|
2826
2169
|
try {
|
|
2827
|
-
res = await fetch(`${
|
|
2170
|
+
res = await fetch(`${base3}/api/v1/sponsor/permit2-transfer`, {
|
|
2828
2171
|
method: "POST",
|
|
2829
2172
|
headers: {
|
|
2830
2173
|
"content-type": "application/json",
|
|
@@ -2859,11 +2202,11 @@ async function postSponsorPermit2Transfer(input) {
|
|
|
2859
2202
|
return parsed.data;
|
|
2860
2203
|
}
|
|
2861
2204
|
async function getSponsorRelayerAddress(input) {
|
|
2862
|
-
const
|
|
2205
|
+
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
2863
2206
|
let res;
|
|
2864
2207
|
try {
|
|
2865
2208
|
res = await fetch(
|
|
2866
|
-
`${
|
|
2209
|
+
`${base3}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
|
|
2867
2210
|
{
|
|
2868
2211
|
headers: { "x-owney-api-key": input.apiKey }
|
|
2869
2212
|
}
|
|
@@ -2895,11 +2238,85 @@ async function getSponsorRelayerAddress(input) {
|
|
|
2895
2238
|
return parsed.data.relayer;
|
|
2896
2239
|
}
|
|
2897
2240
|
|
|
2898
|
-
// src/lib/
|
|
2899
|
-
|
|
2241
|
+
// src/lib/permit2.ts
|
|
2242
|
+
var import_viem4 = require("viem");
|
|
2243
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
2244
|
+
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
2245
|
+
var ERC20_ALLOWANCE_ABI = [
|
|
2246
|
+
{
|
|
2247
|
+
type: "function",
|
|
2248
|
+
name: "allowance",
|
|
2249
|
+
stateMutability: "view",
|
|
2250
|
+
inputs: [
|
|
2251
|
+
{ name: "owner", type: "address" },
|
|
2252
|
+
{ name: "spender", type: "address" }
|
|
2253
|
+
],
|
|
2254
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
2255
|
+
},
|
|
2256
|
+
{
|
|
2257
|
+
type: "function",
|
|
2258
|
+
name: "approve",
|
|
2259
|
+
stateMutability: "nonpayable",
|
|
2260
|
+
inputs: [
|
|
2261
|
+
{ name: "spender", type: "address" },
|
|
2262
|
+
{ name: "amount", type: "uint256" }
|
|
2263
|
+
],
|
|
2264
|
+
outputs: [{ name: "", type: "bool" }]
|
|
2265
|
+
},
|
|
2266
|
+
{
|
|
2267
|
+
type: "function",
|
|
2268
|
+
name: "balanceOf",
|
|
2269
|
+
stateMutability: "view",
|
|
2270
|
+
inputs: [{ name: "account", type: "address" }],
|
|
2271
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
2272
|
+
}
|
|
2273
|
+
];
|
|
2274
|
+
function buildPermitTransferFromTypedData(input) {
|
|
2275
|
+
return {
|
|
2276
|
+
domain: {
|
|
2277
|
+
name: "Permit2",
|
|
2278
|
+
chainId: input.chainId,
|
|
2279
|
+
verifyingContract: PERMIT2_ADDRESS
|
|
2280
|
+
},
|
|
2281
|
+
types: {
|
|
2282
|
+
PermitTransferFrom: [
|
|
2283
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
2284
|
+
{ name: "spender", type: "address" },
|
|
2285
|
+
{ name: "nonce", type: "uint256" },
|
|
2286
|
+
{ name: "deadline", type: "uint256" }
|
|
2287
|
+
],
|
|
2288
|
+
TokenPermissions: [
|
|
2289
|
+
{ name: "token", type: "address" },
|
|
2290
|
+
{ name: "amount", type: "uint256" }
|
|
2291
|
+
]
|
|
2292
|
+
},
|
|
2293
|
+
primaryType: "PermitTransferFrom",
|
|
2294
|
+
message: input.message
|
|
2295
|
+
};
|
|
2296
|
+
}
|
|
2297
|
+
function randomPermit2Nonce() {
|
|
2298
|
+
const bytes = new Uint8Array(32);
|
|
2299
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
2300
|
+
return BigInt((0, import_viem4.bytesToHex)(bytes));
|
|
2301
|
+
}
|
|
2302
|
+
async function readPermit2Allowance(publicClient, token, owner) {
|
|
2303
|
+
return publicClient.readContract({
|
|
2304
|
+
address: token,
|
|
2305
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
2306
|
+
functionName: "allowance",
|
|
2307
|
+
args: [owner, PERMIT2_ADDRESS]
|
|
2308
|
+
});
|
|
2309
|
+
}
|
|
2310
|
+
async function readErc20Balance(publicClient, token, owner) {
|
|
2311
|
+
return publicClient.readContract({
|
|
2312
|
+
address: token,
|
|
2313
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
2314
|
+
functionName: "balanceOf",
|
|
2315
|
+
args: [owner]
|
|
2316
|
+
});
|
|
2317
|
+
}
|
|
2900
2318
|
|
|
2901
2319
|
// src/lib/chain-guard.ts
|
|
2902
|
-
init_errors();
|
|
2903
2320
|
var CHAIN_NAMES = {
|
|
2904
2321
|
1: "Ethereum",
|
|
2905
2322
|
8453: "Base",
|
|
@@ -3013,8 +2430,6 @@ function makeSponsoredDepositCallback(deps) {
|
|
|
3013
2430
|
}
|
|
3014
2431
|
|
|
3015
2432
|
// src/lib/sponsored-weth-deposit.ts
|
|
3016
|
-
init_errors();
|
|
3017
|
-
init_permit2();
|
|
3018
2433
|
var PERMIT_WINDOW_SECONDS = 15 * 60;
|
|
3019
2434
|
function makeSponsoredWethCallback(deps) {
|
|
3020
2435
|
const get = deps.httpGet ?? getSponsorRelayerAddress;
|
|
@@ -3099,7 +2514,6 @@ function makeSponsoredWethCallback(deps) {
|
|
|
3099
2514
|
|
|
3100
2515
|
// src/lib/sponsored-calls-deposit.ts
|
|
3101
2516
|
var import_viem5 = require("viem");
|
|
3102
|
-
init_errors();
|
|
3103
2517
|
var DEFAULT_POLL_INTERVAL_MS = 1500;
|
|
3104
2518
|
var DEFAULT_MAX_POLLS = 30;
|
|
3105
2519
|
async function paymasterSupported(provider, owner, chainId) {
|
|
@@ -3190,7 +2604,6 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
3190
2604
|
}
|
|
3191
2605
|
|
|
3192
2606
|
// src/client.ts
|
|
3193
|
-
init_permit2();
|
|
3194
2607
|
function encodeMultiAgentCursor(map) {
|
|
3195
2608
|
return Buffer.from(JSON.stringify(map), "utf8").toString("base64");
|
|
3196
2609
|
}
|
|
@@ -3217,11 +2630,10 @@ var SPONSORED_USDC_BY_CHAIN = {
|
|
|
3217
2630
|
1: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
|
|
3218
2631
|
};
|
|
3219
2632
|
var VIEM_CHAIN2 = {
|
|
3220
|
-
8453:
|
|
3221
|
-
42161:
|
|
3222
|
-
1:
|
|
2633
|
+
8453: import_chains2.base,
|
|
2634
|
+
42161: import_chains2.arbitrum,
|
|
2635
|
+
1: import_chains2.mainnet
|
|
3223
2636
|
};
|
|
3224
|
-
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
3225
2637
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
3226
2638
|
8453: "0x4200000000000000000000000000000000000006",
|
|
3227
2639
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -3250,7 +2662,6 @@ var OwneySDK = class {
|
|
|
3250
2662
|
zyfaiRpcUrls;
|
|
3251
2663
|
routingApiBaseUrl;
|
|
3252
2664
|
referralSource;
|
|
3253
|
-
surfliquidApiBaseUrl;
|
|
3254
2665
|
cachedSponsoredCallback = null;
|
|
3255
2666
|
cachedWethSponsoredCallback = null;
|
|
3256
2667
|
paymasterServiceUrl;
|
|
@@ -3263,7 +2674,6 @@ var OwneySDK = class {
|
|
|
3263
2674
|
this.routingApiBaseUrl = config.routingApiBaseUrl;
|
|
3264
2675
|
this.paymasterServiceUrl = config.paymasterServiceUrl;
|
|
3265
2676
|
this.referralSource = config.referralSource;
|
|
3266
|
-
this.surfliquidApiBaseUrl = config.surfliquidApiBaseUrl;
|
|
3267
2677
|
}
|
|
3268
2678
|
/**
|
|
3269
2679
|
* Establish connection state for all subsequent SDK calls.
|
|
@@ -3363,14 +2773,14 @@ var OwneySDK = class {
|
|
|
3363
2773
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
3364
2774
|
// PublicClient/WalletClient param types — structurally identical at
|
|
3365
2775
|
// runtime, but the two share a name TS treats as unrelated.
|
|
3366
|
-
getPublicClient: (cid) => (0,
|
|
2776
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
3367
2777
|
chain: VIEM_CHAIN2[cid],
|
|
3368
|
-
transport: (0,
|
|
2778
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3369
2779
|
}),
|
|
3370
|
-
getWalletClient: (cid) => (0,
|
|
2780
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
3371
2781
|
account: owner,
|
|
3372
2782
|
chain: VIEM_CHAIN2[cid],
|
|
3373
|
-
transport: (0,
|
|
2783
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3374
2784
|
})
|
|
3375
2785
|
});
|
|
3376
2786
|
if (!onApproved) this.cachedSponsoredCallback = callback;
|
|
@@ -3416,14 +2826,14 @@ var OwneySDK = class {
|
|
|
3416
2826
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
3417
2827
|
// PublicClient/WalletClient param types — structurally identical at
|
|
3418
2828
|
// runtime, but the two share a name TS treats as unrelated.
|
|
3419
|
-
getPublicClient: (cid) => (0,
|
|
2829
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
3420
2830
|
chain: VIEM_CHAIN2[cid],
|
|
3421
|
-
transport: (0,
|
|
2831
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3422
2832
|
}),
|
|
3423
|
-
getWalletClient: (cid) => (0,
|
|
2833
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
3424
2834
|
account: owner,
|
|
3425
2835
|
chain: VIEM_CHAIN2[cid],
|
|
3426
|
-
transport: (0,
|
|
2836
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3427
2837
|
})
|
|
3428
2838
|
});
|
|
3429
2839
|
if (!onApproved) this.cachedWethSponsoredCallback = callback;
|
|
@@ -3493,8 +2903,8 @@ var OwneySDK = class {
|
|
|
3493
2903
|
this.initializingAgentsPromise = (async () => {
|
|
3494
2904
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
3495
2905
|
this.disabledAgents.clear();
|
|
3496
|
-
for (const { key: key2, agent_type,
|
|
3497
|
-
const agent =
|
|
2906
|
+
for (const { key: key2, agent_type, is_enabled } of agentKeys) {
|
|
2907
|
+
const agent = this.createAgent(agent_type, key2);
|
|
3498
2908
|
if (!agent) continue;
|
|
3499
2909
|
this.agents.set(agent_type, agent);
|
|
3500
2910
|
if (is_enabled === false) {
|
|
@@ -3515,22 +2925,10 @@ var OwneySDK = class {
|
|
|
3515
2925
|
this.initializingAgentsPromise = null;
|
|
3516
2926
|
}
|
|
3517
2927
|
}
|
|
3518
|
-
|
|
2928
|
+
createAgent(agentId, key2) {
|
|
3519
2929
|
if (agentId === "zyfai") {
|
|
3520
2930
|
return new ZyfaiAgent(key2, this.zyfaiRpcUrls, this.referralSource);
|
|
3521
2931
|
}
|
|
3522
|
-
if (agentId === "surfliquid") {
|
|
3523
|
-
if (!projectName) return null;
|
|
3524
|
-
const { SurfLiquidAgent: SurfLiquidAgent2 } = await Promise.resolve().then(() => (init_surfliquid_agent(), surfliquid_agent_exports));
|
|
3525
|
-
return new SurfLiquidAgent2({
|
|
3526
|
-
projectName,
|
|
3527
|
-
appId: key2,
|
|
3528
|
-
// Same-origin proxy override — SurfLiquid auth is an httpOnly cookie,
|
|
3529
|
-
// which WebKit (iOS) discards when it is third-party. See
|
|
3530
|
-
// OwneySDKConfig.surfliquidApiBaseUrl.
|
|
3531
|
-
apiBaseUrl: this.surfliquidApiBaseUrl
|
|
3532
|
-
});
|
|
3533
|
-
}
|
|
3534
2932
|
return null;
|
|
3535
2933
|
}
|
|
3536
2934
|
// --- Account lifecycle ---
|
|
@@ -3685,30 +3083,18 @@ var OwneySDK = class {
|
|
|
3685
3083
|
);
|
|
3686
3084
|
}
|
|
3687
3085
|
const agentResults = {};
|
|
3688
|
-
const agentErrors = {};
|
|
3689
3086
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
3690
|
-
|
|
3691
|
-
|
|
3692
|
-
|
|
3693
|
-
|
|
3694
|
-
|
|
3695
|
-
|
|
3696
|
-
|
|
3697
|
-
|
|
3698
|
-
depositCallback
|
|
3699
|
-
);
|
|
3700
|
-
} catch (error) {
|
|
3701
|
-
agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
|
|
3702
|
-
}
|
|
3703
|
-
}
|
|
3704
|
-
if (Object.keys(agentResults).length === 0) {
|
|
3705
|
-
throw new OwneyError(
|
|
3706
|
-
"DEPOSIT_ALL_FAILED",
|
|
3707
|
-
`All ${agentAmounts.length} agent deposit(s) failed.`,
|
|
3708
|
-
{ agentErrors }
|
|
3087
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
3088
|
+
agent,
|
|
3089
|
+
state,
|
|
3090
|
+
chainId,
|
|
3091
|
+
agentAmount,
|
|
3092
|
+
asset,
|
|
3093
|
+
effectiveCallback,
|
|
3094
|
+
depositCallback
|
|
3709
3095
|
);
|
|
3710
3096
|
}
|
|
3711
|
-
return
|
|
3097
|
+
return { agentResults };
|
|
3712
3098
|
}
|
|
3713
3099
|
/**
|
|
3714
3100
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -3824,8 +3210,9 @@ var OwneySDK = class {
|
|
|
3824
3210
|
async hasExistingBalance(agent, state, chainId, asset) {
|
|
3825
3211
|
try {
|
|
3826
3212
|
const balance = await agent.getBalances(state, chainId);
|
|
3213
|
+
const target = asset.toLowerCase();
|
|
3827
3214
|
const token = balance.tokens.find(
|
|
3828
|
-
(t) => t.chainId === chainId &&
|
|
3215
|
+
(t) => t.chainId === chainId && t.asset.toLowerCase() === target
|
|
3829
3216
|
);
|
|
3830
3217
|
return !!token && Number(token.amount) > 0;
|
|
3831
3218
|
} catch {
|
|
@@ -3864,34 +3251,6 @@ var OwneySDK = class {
|
|
|
3864
3251
|
}
|
|
3865
3252
|
return eligible;
|
|
3866
3253
|
}
|
|
3867
|
-
/**
|
|
3868
|
-
* Agent ids the routing API provisioned for this org that support the given
|
|
3869
|
-
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
3870
|
-
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
3871
|
-
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
3872
|
-
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
3873
|
-
*
|
|
3874
|
-
* This is the source of truth for agent availability: an agent appears here
|
|
3875
|
-
* iff the routing API returned its key. No per-app feature flags.
|
|
3876
|
-
*/
|
|
3877
|
-
async getEligibleAgentIds(chainId, asset) {
|
|
3878
|
-
try {
|
|
3879
|
-
await this.ensureAgentsInitialized();
|
|
3880
|
-
} catch (error) {
|
|
3881
|
-
if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
|
|
3882
|
-
return [];
|
|
3883
|
-
}
|
|
3884
|
-
throw error;
|
|
3885
|
-
}
|
|
3886
|
-
return [...this.agents.values()].filter((agent) => {
|
|
3887
|
-
const chainAssets = agent.supportedAssets.find(
|
|
3888
|
-
(sa) => sa.chainId === chainId
|
|
3889
|
-
);
|
|
3890
|
-
return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
|
|
3891
|
-
}).map((agent) => agent.id).sort(
|
|
3892
|
-
(a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
|
|
3893
|
-
);
|
|
3894
|
-
}
|
|
3895
3254
|
// --- Fund operations ---
|
|
3896
3255
|
/**
|
|
3897
3256
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -3927,17 +3286,9 @@ var OwneySDK = class {
|
|
|
3927
3286
|
}
|
|
3928
3287
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
3929
3288
|
if (!amount) {
|
|
3930
|
-
const aggregated2 = await this.getBalances();
|
|
3931
|
-
const funded = projectAgentBalancesForAsset(
|
|
3932
|
-
eligibleAgents,
|
|
3933
|
-
aggregated2.agentBalances,
|
|
3934
|
-
chainId,
|
|
3935
|
-
asset,
|
|
3936
|
-
assetInfo.decimals
|
|
3937
|
-
).filter((b) => b.balance > 0n);
|
|
3938
3289
|
const results2 = {};
|
|
3939
3290
|
const agentErrors2 = {};
|
|
3940
|
-
for (const
|
|
3291
|
+
for (const agent of eligibleAgents) {
|
|
3941
3292
|
try {
|
|
3942
3293
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
3943
3294
|
} catch (err) {
|
|
@@ -3954,10 +3305,9 @@ var OwneySDK = class {
|
|
|
3954
3305
|
{ asset, agentErrors: agentErrors2 }
|
|
3955
3306
|
);
|
|
3956
3307
|
}
|
|
3957
|
-
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
3958
3308
|
return {
|
|
3959
3309
|
agentResult: results2,
|
|
3960
|
-
totalWithdrawn:
|
|
3310
|
+
totalWithdrawn: sumWithdrawnAmount(results2).toString()
|
|
3961
3311
|
};
|
|
3962
3312
|
}
|
|
3963
3313
|
const requested = BigInt(amount);
|
|
@@ -4349,10 +3699,10 @@ var OwneySDK = class {
|
|
|
4349
3699
|
);
|
|
4350
3700
|
}
|
|
4351
3701
|
const provider = this.requireConnectedProvider();
|
|
4352
|
-
const wallet = (0,
|
|
3702
|
+
const wallet = (0, import_viem6.createWalletClient)({
|
|
4353
3703
|
account: state.walletAddress,
|
|
4354
3704
|
chain: VIEM_CHAIN2[chainId],
|
|
4355
|
-
transport: (0,
|
|
3705
|
+
transport: (0, import_viem6.custom)(provider)
|
|
4356
3706
|
});
|
|
4357
3707
|
const hash = await wallet.writeContract({
|
|
4358
3708
|
address: token,
|
|
@@ -4362,9 +3712,9 @@ var OwneySDK = class {
|
|
|
4362
3712
|
account: state.walletAddress,
|
|
4363
3713
|
chain: VIEM_CHAIN2[chainId]
|
|
4364
3714
|
});
|
|
4365
|
-
const publicClient = (0,
|
|
3715
|
+
const publicClient = (0, import_viem6.createPublicClient)({
|
|
4366
3716
|
chain: VIEM_CHAIN2[chainId],
|
|
4367
|
-
transport: (0,
|
|
3717
|
+
transport: (0, import_viem6.custom)(provider)
|
|
4368
3718
|
});
|
|
4369
3719
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
4370
3720
|
hash,
|
|
@@ -4472,11 +3822,8 @@ var OwneySDK = class {
|
|
|
4472
3822
|
}
|
|
4473
3823
|
};
|
|
4474
3824
|
|
|
4475
|
-
// src/index.ts
|
|
4476
|
-
init_errors();
|
|
4477
|
-
|
|
4478
3825
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
4479
|
-
var
|
|
3826
|
+
var import_viem7 = require("viem");
|
|
4480
3827
|
var import_siwe = require("siwe");
|
|
4481
3828
|
var import_sdk2 = require("@zyfai/sdk");
|
|
4482
3829
|
|
|
@@ -4603,7 +3950,7 @@ function buildSIWXConfig(deps) {
|
|
|
4603
3950
|
issuedAt,
|
|
4604
3951
|
toString() {
|
|
4605
3952
|
return new import_siwe.SiweMessage({
|
|
4606
|
-
address: (0,
|
|
3953
|
+
address: (0, import_viem7.getAddress)(accountAddress),
|
|
4607
3954
|
chainId: numericChainId(chainId),
|
|
4608
3955
|
domain,
|
|
4609
3956
|
uri,
|