@owney/sdk 0.6.9-beta.8 → 0.7.0-beta.1
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/README.md +1 -1
- package/dist/index.cjs +255 -1362
- package/dist/index.d.cts +3 -138
- package/dist/index.d.ts +3 -138
- package/dist/index.js +226 -679
- package/package.json +3 -5
- package/dist/chunk-PWIKIQOX.js +0 -140
- package/dist/surfliquid.agent-VNGQUSXN.js +0 -473
package/dist/index.cjs
CHANGED
|
@@ -3,667 +3,20 @@ 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 });
|
|
17
9
|
};
|
|
18
10
|
var __copyProps = (to, from, except, desc) => {
|
|
19
11
|
if (from && typeof from === "object" || typeof from === "function") {
|
|
20
|
-
for (let
|
|
21
|
-
if (!__hasOwnProp.call(to,
|
|
22
|
-
__defProp(to,
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
23
15
|
}
|
|
24
16
|
return to;
|
|
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_viem5, 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_viem5 = 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_viem5.custom)(state.provider);
|
|
527
|
-
const publicClient = (0, import_viem5.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_viem5.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_viem5.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_viem5.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, {
|
|
@@ -673,8 +26,7 @@ __export(index_exports, {
|
|
|
673
26
|
NotConnectedError: () => NotConnectedError,
|
|
674
27
|
OwneyError: () => OwneyError,
|
|
675
28
|
OwneySDK: () => OwneySDK,
|
|
676
|
-
createOwneySIWX: () => createOwneySIWX
|
|
677
|
-
setOwneyDebug: () => setOwneyDebug
|
|
29
|
+
createOwneySIWX: () => createOwneySIWX
|
|
678
30
|
});
|
|
679
31
|
module.exports = __toCommonJS(index_exports);
|
|
680
32
|
|
|
@@ -736,8 +88,56 @@ var SupportedAssets = [
|
|
|
736
88
|
}
|
|
737
89
|
];
|
|
738
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
|
+
|
|
739
140
|
// src/lib/utils.ts
|
|
740
|
-
init_errors();
|
|
741
141
|
var isValidChainId = (chainId) => {
|
|
742
142
|
if (!SUPPORTED_CHAIN_IDS.includes(chainId)) {
|
|
743
143
|
throw new OwneyError(
|
|
@@ -748,12 +148,6 @@ var isValidChainId = (chainId) => {
|
|
|
748
148
|
}
|
|
749
149
|
return chainId;
|
|
750
150
|
};
|
|
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
151
|
function hexToDecimal(hex, decimals = 6) {
|
|
758
152
|
const normalized = hex.startsWith("0x") || hex.startsWith("0X") ? hex : `0x${hex}`;
|
|
759
153
|
const parsed = BigInt(normalized);
|
|
@@ -817,46 +211,46 @@ function resolveChainId(chain) {
|
|
|
817
211
|
function mapBalances(raw, _chainId, smartWallet) {
|
|
818
212
|
const portfolio = raw.portfolio;
|
|
819
213
|
const portfolioByChain = portfolio.portfolioByChain ?? {};
|
|
820
|
-
const rawPositions = portfolio.positions ?? [];
|
|
821
|
-
const detailByKey = /* @__PURE__ */ new Map();
|
|
822
|
-
for (const p of rawPositions) {
|
|
823
|
-
const cid = resolveChainId(p.chain ?? "");
|
|
824
|
-
const symbol = (p.token_symbol ?? "").toUpperCase();
|
|
825
|
-
if (Number.isFinite(cid) && symbol) detailByKey.set(`${cid}:${symbol}`, p);
|
|
826
|
-
}
|
|
827
214
|
let totalBalance = 0;
|
|
828
215
|
const tokens = [];
|
|
829
|
-
const positions = [];
|
|
830
216
|
for (const [chainIdKey, tokensBySymbol] of Object.entries(portfolioByChain)) {
|
|
831
217
|
const positionChainId = Number(chainIdKey);
|
|
832
|
-
const chainName = CHAIN_ID_TO_NAME[positionChainId] ?? "BASE";
|
|
833
218
|
for (const [symbol, { balance, decimals }] of Object.entries(
|
|
834
219
|
tokensBySymbol ?? {}
|
|
835
220
|
)) {
|
|
836
|
-
const amount = hexToDecimal(balance || "0",
|
|
221
|
+
const amount = hexToDecimal(balance || "0", decimals);
|
|
837
222
|
totalBalance += amount;
|
|
838
223
|
tokens.push({
|
|
839
|
-
chain:
|
|
224
|
+
chain: CHAIN_ID_TO_NAME[positionChainId] ?? "BASE",
|
|
840
225
|
chainId: positionChainId,
|
|
841
226
|
asset: symbol,
|
|
842
227
|
amount: String(amount)
|
|
843
228
|
});
|
|
844
|
-
const detail = detailByKey.get(`${positionChainId}:${symbol.toUpperCase()}`);
|
|
845
|
-
positions.push({
|
|
846
|
-
chain: chainName,
|
|
847
|
-
protocol: detail?.protocol_name ?? detail?.protocol_id ?? "",
|
|
848
|
-
protocolId: detail?.protocol_id,
|
|
849
|
-
pool: detail?.pool,
|
|
850
|
-
asset: symbol,
|
|
851
|
-
amount: String(amount),
|
|
852
|
-
apy: detail?.pool_apy,
|
|
853
|
-
tvl: detail?.pool_tvl,
|
|
854
|
-
// PositionSlot has no `liquidity` field yet; Zyfai will add it. Narrow
|
|
855
|
-
// structural read keeps it undefined today and auto-populates later.
|
|
856
|
-
liquidity: detail?.liquidity
|
|
857
|
-
});
|
|
858
229
|
}
|
|
859
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
|
+
}));
|
|
860
254
|
return {
|
|
861
255
|
smartWallet,
|
|
862
256
|
totalBalance: String(totalBalance),
|
|
@@ -1018,9 +412,7 @@ function mapUserProfile(raw, userAddress) {
|
|
|
1018
412
|
chains: raw.chains || [],
|
|
1019
413
|
strategy: raw.strategy,
|
|
1020
414
|
hasActiveSessionKey: raw.hasActiveSessionKey || false,
|
|
1021
|
-
protocols: raw.protocols || []
|
|
1022
|
-
splitting: raw.splitting,
|
|
1023
|
-
minSplits: raw.minSplits
|
|
415
|
+
protocols: raw.protocols || []
|
|
1024
416
|
};
|
|
1025
417
|
}
|
|
1026
418
|
function mapApyByStrategy(raw) {
|
|
@@ -1133,9 +525,6 @@ function decodeHistoryCursor(token) {
|
|
|
1133
525
|
return parsed;
|
|
1134
526
|
}
|
|
1135
527
|
|
|
1136
|
-
// src/agents/zyfai/zyfai.agent.ts
|
|
1137
|
-
init_errors();
|
|
1138
|
-
|
|
1139
528
|
// src/agents/zyfai/zyfai.auth-cache.ts
|
|
1140
529
|
var KEY_PREFIX = "owney.zyfai.session";
|
|
1141
530
|
var storage = () => {
|
|
@@ -1170,23 +559,23 @@ var readLegacySession = (store, address) => {
|
|
|
1170
559
|
const legacyKeys = [];
|
|
1171
560
|
try {
|
|
1172
561
|
for (let i = 0; i < store.length; i++) {
|
|
1173
|
-
const
|
|
1174
|
-
if (
|
|
562
|
+
const key = store.key(i);
|
|
563
|
+
if (key?.startsWith(prefix)) legacyKeys.push(key);
|
|
1175
564
|
}
|
|
1176
565
|
} catch {
|
|
1177
566
|
return null;
|
|
1178
567
|
}
|
|
1179
568
|
let adopted = null;
|
|
1180
|
-
for (const
|
|
569
|
+
for (const key of legacyKeys) {
|
|
1181
570
|
if (!adopted) {
|
|
1182
571
|
try {
|
|
1183
|
-
const parsed = JSON.parse(store.getItem(
|
|
572
|
+
const parsed = JSON.parse(store.getItem(key) ?? "");
|
|
1184
573
|
if (isFreshSession(parsed)) adopted = parsed;
|
|
1185
574
|
} catch {
|
|
1186
575
|
}
|
|
1187
576
|
}
|
|
1188
577
|
try {
|
|
1189
|
-
store.removeItem(
|
|
578
|
+
store.removeItem(key);
|
|
1190
579
|
} catch {
|
|
1191
580
|
}
|
|
1192
581
|
}
|
|
@@ -1194,11 +583,11 @@ var readLegacySession = (store, address) => {
|
|
|
1194
583
|
};
|
|
1195
584
|
var readSession = (address, _chainId) => {
|
|
1196
585
|
if (typeof window === "undefined") return null;
|
|
1197
|
-
const
|
|
586
|
+
const key = buildKey(address);
|
|
1198
587
|
const store = storage();
|
|
1199
588
|
let raw = null;
|
|
1200
589
|
try {
|
|
1201
|
-
raw = store?.getItem(
|
|
590
|
+
raw = store?.getItem(key) ?? null;
|
|
1202
591
|
} catch {
|
|
1203
592
|
raw = null;
|
|
1204
593
|
}
|
|
@@ -1208,9 +597,9 @@ var readSession = (address, _chainId) => {
|
|
|
1208
597
|
if (isFreshSession(parsed)) return parsed;
|
|
1209
598
|
} catch {
|
|
1210
599
|
}
|
|
1211
|
-
memorySessions.delete(
|
|
600
|
+
memorySessions.delete(key);
|
|
1212
601
|
try {
|
|
1213
|
-
store?.removeItem(
|
|
602
|
+
store?.removeItem(key);
|
|
1214
603
|
} catch {
|
|
1215
604
|
}
|
|
1216
605
|
return null;
|
|
@@ -1220,27 +609,27 @@ var readSession = (address, _chainId) => {
|
|
|
1220
609
|
writeSession(address, _chainId, legacy);
|
|
1221
610
|
return legacy;
|
|
1222
611
|
}
|
|
1223
|
-
const cached = memorySessions.get(
|
|
612
|
+
const cached = memorySessions.get(key);
|
|
1224
613
|
if (isFreshSession(cached)) return cached;
|
|
1225
|
-
if (cached) memorySessions.delete(
|
|
614
|
+
if (cached) memorySessions.delete(key);
|
|
1226
615
|
return null;
|
|
1227
616
|
};
|
|
1228
617
|
var writeSession = (address, _chainId, session) => {
|
|
1229
618
|
if (typeof window === "undefined") return;
|
|
1230
|
-
const
|
|
1231
|
-
memorySessions.set(
|
|
619
|
+
const key = buildKey(address);
|
|
620
|
+
memorySessions.set(key, session);
|
|
1232
621
|
const store = storage();
|
|
1233
622
|
try {
|
|
1234
|
-
store?.setItem(
|
|
623
|
+
store?.setItem(key, JSON.stringify(session));
|
|
1235
624
|
} catch {
|
|
1236
625
|
}
|
|
1237
626
|
};
|
|
1238
627
|
var clearSession = (address, _chainId) => {
|
|
1239
|
-
const
|
|
1240
|
-
memorySessions.delete(
|
|
628
|
+
const key = buildKey(address);
|
|
629
|
+
memorySessions.delete(key);
|
|
1241
630
|
const store = storage();
|
|
1242
631
|
try {
|
|
1243
|
-
store?.removeItem(
|
|
632
|
+
store?.removeItem(key);
|
|
1244
633
|
} catch {
|
|
1245
634
|
}
|
|
1246
635
|
readLegacySession(store, address);
|
|
@@ -1271,149 +660,6 @@ function buildProtocolMergeUpdate(available, current, asset) {
|
|
|
1271
660
|
};
|
|
1272
661
|
}
|
|
1273
662
|
|
|
1274
|
-
// src/agents/zyfai/splitting.ts
|
|
1275
|
-
var MAX_MIN_SPLITS = 4;
|
|
1276
|
-
var MIN_FORCE_SPLITS = 2;
|
|
1277
|
-
var AUTOMATIC_MIN_SPLITS = 1;
|
|
1278
|
-
function toZyfaiSplitting(policy) {
|
|
1279
|
-
switch (policy.splittingMode) {
|
|
1280
|
-
case "none":
|
|
1281
|
-
return { splitting: false };
|
|
1282
|
-
case "automatic":
|
|
1283
|
-
return { splitting: true, minSplits: AUTOMATIC_MIN_SPLITS };
|
|
1284
|
-
case "force":
|
|
1285
|
-
return {
|
|
1286
|
-
splitting: true,
|
|
1287
|
-
minSplits: clampForceSplits(policy.minSplits)
|
|
1288
|
-
};
|
|
1289
|
-
}
|
|
1290
|
-
}
|
|
1291
|
-
function clampForceSplits(minSplits) {
|
|
1292
|
-
if (typeof minSplits !== "number" || !Number.isFinite(minSplits)) {
|
|
1293
|
-
return MIN_FORCE_SPLITS;
|
|
1294
|
-
}
|
|
1295
|
-
const rounded = Math.round(minSplits);
|
|
1296
|
-
if (rounded < MIN_FORCE_SPLITS) return MIN_FORCE_SPLITS;
|
|
1297
|
-
if (rounded > MAX_MIN_SPLITS) return MAX_MIN_SPLITS;
|
|
1298
|
-
return rounded;
|
|
1299
|
-
}
|
|
1300
|
-
function splittingNeedsUpdate(current, desired) {
|
|
1301
|
-
if (!current) return true;
|
|
1302
|
-
if (current.splitting !== desired.splitting) return true;
|
|
1303
|
-
if (desired.minSplits === void 0) return false;
|
|
1304
|
-
return current.minSplits !== desired.minSplits;
|
|
1305
|
-
}
|
|
1306
|
-
|
|
1307
|
-
// src/agents/zyfai/pool-policy.ts
|
|
1308
|
-
function toZyfaiCustomizations(policy, availableByProtocol, chainsByProtocol) {
|
|
1309
|
-
const selectionByKey = /* @__PURE__ */ new Map();
|
|
1310
|
-
for (const selection of policy.selections) {
|
|
1311
|
-
selectionByKey.set(key(selection.protocolId, selection.chainId), selection);
|
|
1312
|
-
}
|
|
1313
|
-
const customizations = [];
|
|
1314
|
-
for (const [protocolId, chainIds] of Object.entries(chainsByProtocol)) {
|
|
1315
|
-
const available = availableByProtocol.get(protocolId);
|
|
1316
|
-
if (available === void 0) {
|
|
1317
|
-
continue;
|
|
1318
|
-
}
|
|
1319
|
-
const availableSet = new Set(available);
|
|
1320
|
-
for (const chainId of chainIds) {
|
|
1321
|
-
const stored = selectionByKey.get(key(protocolId, chainId));
|
|
1322
|
-
if (stored === void 0) {
|
|
1323
|
-
customizations.push({
|
|
1324
|
-
protocolId,
|
|
1325
|
-
chainId,
|
|
1326
|
-
pools: [],
|
|
1327
|
-
autoselect: true
|
|
1328
|
-
});
|
|
1329
|
-
continue;
|
|
1330
|
-
}
|
|
1331
|
-
const pools = stored.pools.filter((pool) => availableSet.has(pool));
|
|
1332
|
-
customizations.push({
|
|
1333
|
-
protocolId,
|
|
1334
|
-
chainId,
|
|
1335
|
-
pools,
|
|
1336
|
-
autoselect: false
|
|
1337
|
-
});
|
|
1338
|
-
}
|
|
1339
|
-
}
|
|
1340
|
-
return customizations;
|
|
1341
|
-
}
|
|
1342
|
-
function deriveProtocols(policy, universe, chainsByProtocol) {
|
|
1343
|
-
if (policy.selections.length === 0) {
|
|
1344
|
-
return null;
|
|
1345
|
-
}
|
|
1346
|
-
const selectionByKey = /* @__PURE__ */ new Map();
|
|
1347
|
-
for (const selection of policy.selections) {
|
|
1348
|
-
selectionByKey.set(key(selection.protocolId, selection.chainId), selection);
|
|
1349
|
-
}
|
|
1350
|
-
return universe.filter((protocolId) => {
|
|
1351
|
-
const chainIds = chainsByProtocol[protocolId];
|
|
1352
|
-
if (chainIds === void 0 || chainIds.length === 0) {
|
|
1353
|
-
return true;
|
|
1354
|
-
}
|
|
1355
|
-
const fullyDisabled = chainIds.every((chainId) => {
|
|
1356
|
-
const stored = selectionByKey.get(key(protocolId, chainId));
|
|
1357
|
-
return stored !== void 0 && stored.pools.length === 0;
|
|
1358
|
-
});
|
|
1359
|
-
return !fullyDisabled;
|
|
1360
|
-
});
|
|
1361
|
-
}
|
|
1362
|
-
function key(protocolId, chainId) {
|
|
1363
|
-
return `${protocolId}:${chainId}`;
|
|
1364
|
-
}
|
|
1365
|
-
function buildChainsByProtocol(protocols, dashboardChainIds) {
|
|
1366
|
-
const allowed = new Set(dashboardChainIds);
|
|
1367
|
-
const result = {};
|
|
1368
|
-
for (const protocol of protocols) {
|
|
1369
|
-
result[protocol.id] = (protocol.chains ?? []).filter(
|
|
1370
|
-
(chainId) => allowed.has(chainId)
|
|
1371
|
-
);
|
|
1372
|
-
}
|
|
1373
|
-
return result;
|
|
1374
|
-
}
|
|
1375
|
-
function flattenAvailablePools(raw) {
|
|
1376
|
-
const byChain = raw ?? {};
|
|
1377
|
-
const names = [];
|
|
1378
|
-
for (const byToken of Object.values(byChain ?? {})) {
|
|
1379
|
-
for (const entry of Object.values(byToken ?? {})) {
|
|
1380
|
-
for (const pool of entry?.pools ?? []) {
|
|
1381
|
-
if (pool?.name) names.push(pool.name);
|
|
1382
|
-
}
|
|
1383
|
-
}
|
|
1384
|
-
}
|
|
1385
|
-
return names;
|
|
1386
|
-
}
|
|
1387
|
-
function protocolListsEqual(a, b) {
|
|
1388
|
-
const left = [...a ?? []].sort();
|
|
1389
|
-
const right = [...b ?? []].sort();
|
|
1390
|
-
if (left.length !== right.length) return false;
|
|
1391
|
-
return left.every((value, index) => value === right[index]);
|
|
1392
|
-
}
|
|
1393
|
-
function protocolsPolicyNeedsUpdate(current, desiredProtocols, desiredAutoSelect) {
|
|
1394
|
-
if (!current) return true;
|
|
1395
|
-
if (current.autoSelectProtocols !== desiredAutoSelect) return true;
|
|
1396
|
-
if (desiredProtocols === null) return false;
|
|
1397
|
-
return !protocolListsEqual(current.protocols, desiredProtocols);
|
|
1398
|
-
}
|
|
1399
|
-
|
|
1400
|
-
// src/lib/debug.ts
|
|
1401
|
-
var configuredDebug = false;
|
|
1402
|
-
function setOwneyDebug(enabled) {
|
|
1403
|
-
configuredDebug = enabled;
|
|
1404
|
-
}
|
|
1405
|
-
function isOwneyDebug() {
|
|
1406
|
-
return globalThis.__OWNEY_DEBUG__ === true || configuredDebug;
|
|
1407
|
-
}
|
|
1408
|
-
function debugLog(scope, message, data) {
|
|
1409
|
-
if (!isOwneyDebug()) return;
|
|
1410
|
-
if (data === void 0) {
|
|
1411
|
-
console.log(`[${scope}] ${message}`);
|
|
1412
|
-
} else {
|
|
1413
|
-
console.log(`[${scope}] ${message}`, data);
|
|
1414
|
-
}
|
|
1415
|
-
}
|
|
1416
|
-
|
|
1417
663
|
// src/agents/zyfai/zyfai.agent.ts
|
|
1418
664
|
var DEFAULT_ZYFAI_RPC_URLS = {
|
|
1419
665
|
8453: "https://base-mainnet.g.alchemy.com/v2/ZWyVU-9XfS3z8Rn-xkq7V",
|
|
@@ -1426,12 +672,6 @@ var WETH_ADDRESS_BY_CHAIN = {
|
|
|
1426
672
|
1: "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
|
|
1427
673
|
};
|
|
1428
674
|
var VIEM_CHAIN = { 8453: import_chains.base, 42161: import_chains.arbitrum, 1: import_chains.mainnet };
|
|
1429
|
-
var SPLITTING_ASSETS = ["USDC", "WETH"];
|
|
1430
|
-
var POOL_POLICY_CHAIN_IDS = [8453, 42161, 1];
|
|
1431
|
-
function isAlreadyActiveSessionKeyError(error) {
|
|
1432
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
1433
|
-
return /already has an active session key/i.test(message);
|
|
1434
|
-
}
|
|
1435
675
|
var ZyfaiAgent = class {
|
|
1436
676
|
id = "zyfai";
|
|
1437
677
|
supportedChainIds = [8453, 42161, 1];
|
|
@@ -1658,71 +898,21 @@ var ZyfaiAgent = class {
|
|
|
1658
898
|
return await this.sdk.connectAccount(provider, chainId);
|
|
1659
899
|
}
|
|
1660
900
|
}
|
|
1661
|
-
/** Full connect: SIWE auth + Safe deploy check + session key. */
|
|
1662
|
-
async connectFull(state, chainId) {
|
|
1663
|
-
await this.connectAuth(state, chainId);
|
|
1664
|
-
const validChainId = isValidChainId(chainId);
|
|
1665
|
-
const address = this.getAddress();
|
|
1666
|
-
const wallet = await this.sdk.getSmartWalletAddress(address, validChainId);
|
|
1667
|
-
this.smartWalletCache.set(`${address}_${validChainId}`, wallet.address);
|
|
1668
|
-
if (!wallet.isDeployed) {
|
|
1669
|
-
await this.sdk.deploySafe(address, validChainId, "aggressive", false);
|
|
1670
|
-
try {
|
|
1671
|
-
if (validChainId === 42161) {
|
|
1672
|
-
await this.sdk.updateUserProfile({
|
|
1673
|
-
asset: "WETH",
|
|
1674
|
-
chains: [validChainId],
|
|
1675
|
-
protocols: ["c24a33fa-4a87-4376-b756-93bd3957d3ea"],
|
|
1676
|
-
// AAVE protocol ID
|
|
1677
|
-
autoSelectProtocols: false
|
|
1678
|
-
});
|
|
1679
|
-
}
|
|
1680
|
-
} catch (err) {
|
|
1681
|
-
console.warn(
|
|
1682
|
-
"Failed to configure AAVE protocol after Safe deployment:",
|
|
1683
|
-
err instanceof Error ? err.message : String(err)
|
|
1684
|
-
);
|
|
1685
|
-
}
|
|
1686
|
-
}
|
|
1687
|
-
await this.ensureSessionKey(state, address, validChainId);
|
|
1688
|
-
}
|
|
1689
901
|
/**
|
|
1690
|
-
*
|
|
1691
|
-
*
|
|
1692
|
-
*
|
|
1693
|
-
*
|
|
1694
|
-
*
|
|
1695
|
-
*
|
|
1696
|
-
* to (re)create a key per chain — that 400s and blocks the deposit. We only
|
|
1697
|
-
* create when the user has none.
|
|
1698
|
-
*
|
|
1699
|
-
* The one wrapper-side hardening that IS needed: a chain/account switch can
|
|
1700
|
-
* fire the provider's `accountsChanged` → `disconnectAccount`, tearing down
|
|
1701
|
-
* the zyfai connection (walletClient + authenticatedUserId both null) while
|
|
1702
|
-
* our own `connectAuth` guard still believes this chain is connected and
|
|
1703
|
-
* early-returns without reconnecting. `createSessionKey` then fails with
|
|
1704
|
-
* "No account connected". Detect that and reconnect first.
|
|
1705
|
-
*
|
|
1706
|
-
* NOTE: whether a globally-active session key actually authorizes activity on
|
|
1707
|
-
* a freshly-deployed Safe on a new chain is a backend/zyf question — the
|
|
1708
|
-
* wrapper cannot force per-chain activation given the global 400 guard.
|
|
1709
|
-
* See [[zyfai-per-chain-session-key]].
|
|
902
|
+
* Reconnect if the Zyfai connection was torn down behind our back: a
|
|
903
|
+
* chain/account switch fires the provider's `accountsChanged` →
|
|
904
|
+
* `disconnectAccount` (nulls walletClient + authenticatedUserId) while our
|
|
905
|
+
* own `connectAuth` guard still believes this chain is connected and
|
|
906
|
+
* early-returns. Without this, authenticated calls (depositFunds,
|
|
907
|
+
* withdrawFunds) fail with "No account connected".
|
|
1710
908
|
*/
|
|
1711
|
-
async
|
|
909
|
+
async ensureConnected(state, chainId) {
|
|
910
|
+
await this.connectAuth(state, chainId);
|
|
1712
911
|
const internals = this.sdk;
|
|
1713
912
|
if (!internals.walletClient || internals.authenticatedUserId === null) {
|
|
1714
913
|
this.connectedChainId = null;
|
|
1715
914
|
await this.connectAuth(state, chainId);
|
|
1716
915
|
}
|
|
1717
|
-
const user = await this.sdk.getUserDetails();
|
|
1718
|
-
if (!user.hasActiveSessionKey) {
|
|
1719
|
-
try {
|
|
1720
|
-
await this.sdk.createSessionKey(address, chainId);
|
|
1721
|
-
} catch (error) {
|
|
1722
|
-
if (!isAlreadyActiveSessionKeyError(error)) throw error;
|
|
1723
|
-
internals.hasActiveSessionKey = true;
|
|
1724
|
-
}
|
|
1725
|
-
}
|
|
1726
916
|
}
|
|
1727
917
|
/**
|
|
1728
918
|
* Sync newly-available protocols onto an existing user's profile at wallet
|
|
@@ -1792,211 +982,10 @@ var ZyfaiAgent = class {
|
|
|
1792
982
|
throw error;
|
|
1793
983
|
}
|
|
1794
984
|
}
|
|
1795
|
-
/**
|
|
1796
|
-
* Apply the org's capital splitting policy to this user's Zyfai profile.
|
|
1797
|
-
*
|
|
1798
|
-
* Per ASSET, not per chain: Zyfai stores splitting under
|
|
1799
|
-
* `assetTypeSettings[asset]`, so one call would only configure USDC and leave a
|
|
1800
|
-
* WETH holder's real setting untouched.
|
|
1801
|
-
*
|
|
1802
|
-
* Non-fatal throughout. This is a side effect of connecting, so a Zyfai hiccup
|
|
1803
|
-
* must leave the user connected with their profile unchanged, never fail
|
|
1804
|
-
* activation.
|
|
1805
|
-
*/
|
|
1806
|
-
async applyOrgPolicy(_state, _chainId, policy) {
|
|
1807
|
-
debugLog("zyfai:splitting", "applying org policy", {
|
|
1808
|
-
policy,
|
|
1809
|
-
// Per asset because Zyfai stores splitting under assetTypeSettings[asset].
|
|
1810
|
-
assets: SPLITTING_ASSETS
|
|
1811
|
-
});
|
|
1812
|
-
await Promise.all(
|
|
1813
|
-
SPLITTING_ASSETS.map((asset) => this.applySplitting(asset, policy))
|
|
1814
|
-
);
|
|
1815
|
-
if (policy.poolPolicy) {
|
|
1816
|
-
await this.applyPoolPolicy(policy.poolPolicy);
|
|
1817
|
-
}
|
|
1818
|
-
}
|
|
1819
|
-
async applySplitting(asset, policy) {
|
|
1820
|
-
try {
|
|
1821
|
-
const desired = toZyfaiSplitting(policy);
|
|
1822
|
-
const current = await this.sdk.getUserDetails(asset);
|
|
1823
|
-
const currentSplitting = {
|
|
1824
|
-
splitting: current?.splitting,
|
|
1825
|
-
minSplits: current?.minSplits
|
|
1826
|
-
};
|
|
1827
|
-
const needsUpdate = splittingNeedsUpdate(current, desired);
|
|
1828
|
-
debugLog("zyfai:splitting", `${asset}: comparing`, {
|
|
1829
|
-
mode: policy.splittingMode,
|
|
1830
|
-
current: currentSplitting,
|
|
1831
|
-
desired,
|
|
1832
|
-
// Spelled out because the "why" is the non-obvious part: minSplits is
|
|
1833
|
-
// what separates automatic (1) from force (2-4), not `splitting`.
|
|
1834
|
-
decision: needsUpdate ? "will write \u2014 profile differs from the org policy" : "skipping \u2014 profile already matches"
|
|
1835
|
-
});
|
|
1836
|
-
if (!needsUpdate) return;
|
|
1837
|
-
const result = await this.sdk.updateUserProfile({ asset, ...desired });
|
|
1838
|
-
debugLog("zyfai:splitting", `${asset}: wrote updateUserProfile`, {
|
|
1839
|
-
sent: { asset, ...desired },
|
|
1840
|
-
// updateUserProfile re-reads the profile after PATCHing, so this is
|
|
1841
|
-
// Zyfai's own view of the result rather than an echo of what we sent.
|
|
1842
|
-
zyfaiNowReports: {
|
|
1843
|
-
splitting: result?.splitting,
|
|
1844
|
-
minSplits: result?.minSplits
|
|
1845
|
-
}
|
|
1846
|
-
});
|
|
1847
|
-
} catch (error) {
|
|
1848
|
-
console.warn(
|
|
1849
|
-
`[zyfai] applyOrgPolicy(${asset}) failed (non-fatal):`,
|
|
1850
|
-
error instanceof Error ? error.message : String(error)
|
|
1851
|
-
);
|
|
1852
|
-
}
|
|
1853
|
-
}
|
|
1854
|
-
/**
|
|
1855
|
-
* Apply the org's protocol/pool policy to this user's Zyfai profile.
|
|
1856
|
-
*
|
|
1857
|
-
* Two Zyfai writes, in a strict order:
|
|
1858
|
-
* 1. `updateUserProfile({ protocols, autoSelectProtocols })` per asset —
|
|
1859
|
-
* the explicit allow-list. Chain-agnostic, mirrors `applySplitting`.
|
|
1860
|
-
* 2. `customizeBatch(...)` once — per (protocol, chain), asset-agnostic
|
|
1861
|
-
* pool narrowing.
|
|
1862
|
-
*
|
|
1863
|
-
* Order matters: constraining a protocol's pools (step 2) while that
|
|
1864
|
-
* protocol is not yet in the allow-list (step 1 not yet applied) lands the
|
|
1865
|
-
* constraint on something the rebalance engine isn't considering.
|
|
1866
|
-
*
|
|
1867
|
-
* Wrapped so a failure anywhere is non-fatal — this runs as a side effect of
|
|
1868
|
-
* connecting, so a Zyfai hiccup must leave the user connected with their
|
|
1869
|
-
* profile unchanged, never fail activation.
|
|
1870
|
-
*/
|
|
1871
|
-
async applyPoolPolicy(policy) {
|
|
1872
|
-
try {
|
|
1873
|
-
const { protocols: universe } = await this.sdk.getAvailableProtocols(
|
|
1874
|
-
this.supportedChainIds[0]
|
|
1875
|
-
);
|
|
1876
|
-
const universeIds = universe.map((p) => p.id);
|
|
1877
|
-
const chainsByProtocol = buildChainsByProtocol(
|
|
1878
|
-
universe,
|
|
1879
|
-
POOL_POLICY_CHAIN_IDS
|
|
1880
|
-
);
|
|
1881
|
-
debugLog("zyfai:pools", "protocol universe", {
|
|
1882
|
-
universeIds,
|
|
1883
|
-
chainsByProtocol
|
|
1884
|
-
});
|
|
1885
|
-
let strategy;
|
|
1886
|
-
const desiredProtocols = deriveProtocols(
|
|
1887
|
-
policy,
|
|
1888
|
-
universeIds,
|
|
1889
|
-
chainsByProtocol
|
|
1890
|
-
);
|
|
1891
|
-
const desiredAutoSelect = policy.autoApproveProtocols;
|
|
1892
|
-
for (const asset of SPLITTING_ASSETS) {
|
|
1893
|
-
const current = await this.sdk.getUserDetails(asset);
|
|
1894
|
-
if (strategy === void 0 && (current.strategy === "conservative" || current.strategy === "aggressive")) {
|
|
1895
|
-
strategy = current.strategy;
|
|
1896
|
-
}
|
|
1897
|
-
const needsUpdate = protocolsPolicyNeedsUpdate(
|
|
1898
|
-
current,
|
|
1899
|
-
desiredProtocols,
|
|
1900
|
-
desiredAutoSelect
|
|
1901
|
-
);
|
|
1902
|
-
debugLog("zyfai:pools", `${asset}: comparing protocols`, {
|
|
1903
|
-
current: {
|
|
1904
|
-
protocols: current.protocols,
|
|
1905
|
-
autoSelectProtocols: current.autoSelectProtocols
|
|
1906
|
-
},
|
|
1907
|
-
desired: {
|
|
1908
|
-
protocols: desiredProtocols,
|
|
1909
|
-
autoSelectProtocols: desiredAutoSelect
|
|
1910
|
-
},
|
|
1911
|
-
decision: needsUpdate ? "will write \u2014 profile differs from the org policy" : "skipping \u2014 profile already matches"
|
|
1912
|
-
});
|
|
1913
|
-
if (!needsUpdate) continue;
|
|
1914
|
-
const update = {
|
|
1915
|
-
asset,
|
|
1916
|
-
autoSelectProtocols: desiredAutoSelect
|
|
1917
|
-
};
|
|
1918
|
-
if (desiredProtocols !== null) update.protocols = desiredProtocols;
|
|
1919
|
-
await this.sdk.updateUserProfile(update);
|
|
1920
|
-
debugLog("zyfai:pools", `${asset}: wrote protocols update`, update);
|
|
1921
|
-
}
|
|
1922
|
-
const poolResults = await Promise.all(
|
|
1923
|
-
universe.map(async (protocol) => {
|
|
1924
|
-
try {
|
|
1925
|
-
const raw = await this.sdk.getAvailablePools(protocol.id, strategy);
|
|
1926
|
-
return [protocol.id, flattenAvailablePools(raw)];
|
|
1927
|
-
} catch (error) {
|
|
1928
|
-
console.warn(
|
|
1929
|
-
`[zyfai] applyPoolPolicy: getAvailablePools(${protocol.id}) failed, skipping this protocol (non-fatal):`,
|
|
1930
|
-
error instanceof Error ? error.message : String(error)
|
|
1931
|
-
);
|
|
1932
|
-
return null;
|
|
1933
|
-
}
|
|
1934
|
-
})
|
|
1935
|
-
);
|
|
1936
|
-
const availableByProtocol = /* @__PURE__ */ new Map();
|
|
1937
|
-
for (const result of poolResults) {
|
|
1938
|
-
if (result) availableByProtocol.set(result[0], result[1]);
|
|
1939
|
-
}
|
|
1940
|
-
const customizations = toZyfaiCustomizations(
|
|
1941
|
-
policy,
|
|
1942
|
-
availableByProtocol,
|
|
1943
|
-
chainsByProtocol
|
|
1944
|
-
);
|
|
1945
|
-
debugLog("zyfai:pools", "derived customizeBatch payload", {
|
|
1946
|
-
strategy,
|
|
1947
|
-
availableProtocolCount: availableByProtocol.size,
|
|
1948
|
-
customizations
|
|
1949
|
-
});
|
|
1950
|
-
if (customizations.length === 0) {
|
|
1951
|
-
debugLog("zyfai:pools", "skipping customizeBatch \u2014 nothing to send");
|
|
1952
|
-
return;
|
|
1953
|
-
}
|
|
1954
|
-
await this.sdk.customizeBatch(customizations);
|
|
1955
|
-
debugLog("zyfai:pools", "wrote customizeBatch", {
|
|
1956
|
-
count: customizations.length
|
|
1957
|
-
});
|
|
1958
|
-
} catch (error) {
|
|
1959
|
-
console.warn(
|
|
1960
|
-
"[zyfai] applyPoolPolicy failed (non-fatal):",
|
|
1961
|
-
error instanceof Error ? error.message : String(error)
|
|
1962
|
-
);
|
|
1963
|
-
}
|
|
1964
|
-
}
|
|
1965
|
-
/**
|
|
1966
|
-
* Records the deposit with Zyfai, retrying transient failures.
|
|
1967
|
-
*
|
|
1968
|
-
* This runs AFTER the transfer has already landed on-chain, so it must never
|
|
1969
|
-
* fail the deposit — the funds moved. But it is also the ONLY source of the
|
|
1970
|
-
* "Top up wallet" entry the history is built from: Zyfai auto-deploys the
|
|
1971
|
-
* balance it detects either way, so when this call is lost the user's deposit
|
|
1972
|
-
* never appears in Activity (an earlier withdrawal stays the newest row) and
|
|
1973
|
-
* nothing ever backfills it. Retry, then log loudly enough to be recoverable.
|
|
1974
|
-
*/
|
|
1975
|
-
async logDepositWithRetry(chainId, txHash, amount, tokenAddress) {
|
|
1976
|
-
const ATTEMPTS = 3;
|
|
1977
|
-
const RETRY_DELAY_MS = 1e3;
|
|
1978
|
-
for (let attempt = 1; attempt <= ATTEMPTS; attempt++) {
|
|
1979
|
-
try {
|
|
1980
|
-
await (tokenAddress ? this.sdk.logDeposit(chainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(chainId, txHash, amount));
|
|
1981
|
-
return;
|
|
1982
|
-
} catch (logError) {
|
|
1983
|
-
if (attempt === ATTEMPTS) {
|
|
1984
|
-
console.error(
|
|
1985
|
-
"[owney-sdk] Deposit landed on-chain but logDeposit failed \u2014 it will be missing from Zyfai history:",
|
|
1986
|
-
{ txHash, chainId, amount, tokenAddress, error: logError }
|
|
1987
|
-
);
|
|
1988
|
-
return;
|
|
1989
|
-
}
|
|
1990
|
-
await new Promise(
|
|
1991
|
-
(resolve) => setTimeout(resolve, RETRY_DELAY_MS * attempt)
|
|
1992
|
-
);
|
|
1993
|
-
}
|
|
1994
|
-
}
|
|
1995
|
-
}
|
|
1996
985
|
async deposit(state, chainId, amount, asset, depositCallback) {
|
|
1997
986
|
try {
|
|
1998
|
-
await this.connectFull(state, chainId);
|
|
1999
987
|
const validChainId = isValidChainId(chainId);
|
|
988
|
+
await this.ensureConnected(state, validChainId);
|
|
2000
989
|
if (depositCallback) {
|
|
2001
990
|
const wallet = await this.sdk.getSmartWalletAddress(
|
|
2002
991
|
this.getAddress(),
|
|
@@ -2008,19 +997,22 @@ var ZyfaiAgent = class {
|
|
|
2008
997
|
amount
|
|
2009
998
|
);
|
|
2010
999
|
const tokenAddress = asset === "WETH" ? WETH_ADDRESS_BY_CHAIN[validChainId] : void 0;
|
|
2011
|
-
|
|
2012
|
-
validChainId,
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
1000
|
+
try {
|
|
1001
|
+
await (tokenAddress ? this.sdk.logDeposit(validChainId, txHash, amount, tokenAddress) : this.sdk.logDeposit(validChainId, txHash, amount));
|
|
1002
|
+
} catch (logError) {
|
|
1003
|
+
console.warn(
|
|
1004
|
+
"[owney-sdk] Deposit landed on-chain but logDeposit failed (non-fatal):",
|
|
1005
|
+
logError
|
|
1006
|
+
);
|
|
1007
|
+
}
|
|
2017
1008
|
return { txHash, smartWallet: wallet.address, amount };
|
|
2018
1009
|
}
|
|
2019
1010
|
const raw = await this.sdk.depositFunds(
|
|
2020
1011
|
this.getAddress(),
|
|
2021
1012
|
validChainId,
|
|
2022
1013
|
amount,
|
|
2023
|
-
asset
|
|
1014
|
+
asset,
|
|
1015
|
+
"aggressive"
|
|
2024
1016
|
);
|
|
2025
1017
|
return mapDeposit(raw);
|
|
2026
1018
|
} catch (error) {
|
|
@@ -2029,8 +1021,8 @@ var ZyfaiAgent = class {
|
|
|
2029
1021
|
}
|
|
2030
1022
|
// --- IAgent: Fund operations ---
|
|
2031
1023
|
async withdraw(state, chainId, token, amount) {
|
|
2032
|
-
await this.connectFull(state, chainId);
|
|
2033
1024
|
const validChainId = isValidChainId(chainId);
|
|
1025
|
+
await this.ensureConnected(state, validChainId);
|
|
2034
1026
|
const raw = await this.sdk.withdrawFunds(
|
|
2035
1027
|
this.getAddress(),
|
|
2036
1028
|
validChainId,
|
|
@@ -2109,19 +1101,7 @@ var ZyfaiAgent = class {
|
|
|
2109
1101
|
}
|
|
2110
1102
|
async getUserProfile(state, chainId) {
|
|
2111
1103
|
await this.connectAuth(state, chainId);
|
|
2112
|
-
const validChainId = isValidChainId(chainId);
|
|
2113
1104
|
const raw = await this.sdk.getUserDetails();
|
|
2114
|
-
debugLog("zyfai:profile", "getUserProfile \u2014 Zyfai reports", {
|
|
2115
|
-
asset: "USDC (default \u2014 no asset passed)",
|
|
2116
|
-
splitting: raw.splitting,
|
|
2117
|
-
minSplits: raw.minSplits,
|
|
2118
|
-
strategy: raw.strategy,
|
|
2119
|
-
chains: raw.chains,
|
|
2120
|
-
protocolCount: raw.protocols?.length,
|
|
2121
|
-
hasActiveSessionKey: raw.hasActiveSessionKey,
|
|
2122
|
-
smartWallet: raw.smartWallet
|
|
2123
|
-
});
|
|
2124
|
-
await this.ensureSessionKey(state, this.getAddress(), validChainId);
|
|
2125
1105
|
return mapUserProfile(raw, this.connectedAddress);
|
|
2126
1106
|
}
|
|
2127
1107
|
async ensureAutoSelectProtocols(state, chainId, asset) {
|
|
@@ -2152,46 +1132,8 @@ var ZyfaiAgent = class {
|
|
|
2152
1132
|
}
|
|
2153
1133
|
};
|
|
2154
1134
|
|
|
2155
|
-
// src/client.ts
|
|
2156
|
-
init_errors();
|
|
2157
|
-
|
|
2158
1135
|
// src/lib/routing-api.ts
|
|
2159
|
-
init_errors();
|
|
2160
1136
|
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
2161
|
-
async function fetchOrgAgentConfig(apiKey) {
|
|
2162
|
-
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/org-config`;
|
|
2163
|
-
try {
|
|
2164
|
-
const res = await fetch(url, {
|
|
2165
|
-
method: "GET",
|
|
2166
|
-
headers: {
|
|
2167
|
-
"Content-Type": "application/json",
|
|
2168
|
-
"x-owney-api-key": `${apiKey}`
|
|
2169
|
-
}
|
|
2170
|
-
});
|
|
2171
|
-
if (!res.ok) {
|
|
2172
|
-
if (res.status !== 404) {
|
|
2173
|
-
console.warn(
|
|
2174
|
-
`[owney-sdk] Could not read org agent config (${res.status}); leaving user profiles unchanged.`
|
|
2175
|
-
);
|
|
2176
|
-
}
|
|
2177
|
-
return null;
|
|
2178
|
-
}
|
|
2179
|
-
const json = await res.json();
|
|
2180
|
-
const policy = json.success ? json.data ?? null : null;
|
|
2181
|
-
debugLog(
|
|
2182
|
-
"owney-sdk",
|
|
2183
|
-
policy ? "org agent config: loaded" : "org agent config: none set by this partner \u2014 user profiles will be left as they are",
|
|
2184
|
-
policy ?? void 0
|
|
2185
|
-
);
|
|
2186
|
-
return policy;
|
|
2187
|
-
} catch (error) {
|
|
2188
|
-
console.warn(
|
|
2189
|
-
"[owney-sdk] Could not read org agent config (non-fatal):",
|
|
2190
|
-
error instanceof Error ? error.message : String(error)
|
|
2191
|
-
);
|
|
2192
|
-
return null;
|
|
2193
|
-
}
|
|
2194
|
-
}
|
|
2195
1137
|
async function fetchAgentKeys(apiKey) {
|
|
2196
1138
|
const url = `${ROUTING_API_BASE_URL}/api/v1/agent/keys`;
|
|
2197
1139
|
const res = await fetch(url, {
|
|
@@ -2221,7 +1163,6 @@ async function fetchAgentKeys(apiKey) {
|
|
|
2221
1163
|
}
|
|
2222
1164
|
|
|
2223
1165
|
// src/lib/health-report.ts
|
|
2224
|
-
init_errors();
|
|
2225
1166
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
2226
1167
|
async function reportAgentFailure(apiKey, agentType, errorCode) {
|
|
2227
1168
|
try {
|
|
@@ -2257,10 +1198,11 @@ async function withFailureReporting(apiKey, agentType, fn) {
|
|
|
2257
1198
|
// src/lib/helpers/withdraw-helper.ts
|
|
2258
1199
|
var import_viem2 = require("viem");
|
|
2259
1200
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
1201
|
+
const target = asset.toUpperCase();
|
|
2260
1202
|
return agents.map((agent) => {
|
|
2261
1203
|
const agentBalance = aggregated[agent.id];
|
|
2262
1204
|
const tokenBalance = agentBalance?.tokens.find(
|
|
2263
|
-
(t) => t.chainId === chainId &&
|
|
1205
|
+
(t) => t.chainId === chainId && t.asset.toUpperCase() === target
|
|
2264
1206
|
);
|
|
2265
1207
|
if (!tokenBalance) return { agent, balance: 0n };
|
|
2266
1208
|
return { agent, balance: (0, import_viem2.parseUnits)(tokenBalance.amount, decimals) };
|
|
@@ -2370,11 +1312,8 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
2370
1312
|
}
|
|
2371
1313
|
|
|
2372
1314
|
// src/client.ts
|
|
2373
|
-
var
|
|
2374
|
-
var
|
|
2375
|
-
|
|
2376
|
-
// src/lib/sponsored-deposit.ts
|
|
2377
|
-
init_errors();
|
|
1315
|
+
var import_viem5 = require("viem");
|
|
1316
|
+
var import_chains2 = require("viem/chains");
|
|
2378
1317
|
|
|
2379
1318
|
// src/lib/transfer-auth.ts
|
|
2380
1319
|
var import_viem3 = require("viem");
|
|
@@ -2413,13 +1352,12 @@ function randomAuthNonce() {
|
|
|
2413
1352
|
}
|
|
2414
1353
|
|
|
2415
1354
|
// src/lib/sponsor-client.ts
|
|
2416
|
-
init_errors();
|
|
2417
1355
|
var ROUTING_API_BASE_URL3 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
2418
1356
|
async function postSponsorTransferAuth(input) {
|
|
2419
|
-
const
|
|
1357
|
+
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
2420
1358
|
let res;
|
|
2421
1359
|
try {
|
|
2422
|
-
res = await fetch(`${
|
|
1360
|
+
res = await fetch(`${base3}/api/v1/sponsor/erc20-transfer-auth`, {
|
|
2423
1361
|
method: "POST",
|
|
2424
1362
|
headers: {
|
|
2425
1363
|
"content-type": "application/json",
|
|
@@ -2456,10 +1394,10 @@ async function postSponsorTransferAuth(input) {
|
|
|
2456
1394
|
return parsed.data;
|
|
2457
1395
|
}
|
|
2458
1396
|
async function postSponsorPermit2Transfer(input) {
|
|
2459
|
-
const
|
|
1397
|
+
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
2460
1398
|
let res;
|
|
2461
1399
|
try {
|
|
2462
|
-
res = await fetch(`${
|
|
1400
|
+
res = await fetch(`${base3}/api/v1/sponsor/permit2-transfer`, {
|
|
2463
1401
|
method: "POST",
|
|
2464
1402
|
headers: {
|
|
2465
1403
|
"content-type": "application/json",
|
|
@@ -2494,11 +1432,11 @@ async function postSponsorPermit2Transfer(input) {
|
|
|
2494
1432
|
return parsed.data;
|
|
2495
1433
|
}
|
|
2496
1434
|
async function getSponsorRelayerAddress(input) {
|
|
2497
|
-
const
|
|
1435
|
+
const base3 = input.baseUrl ?? ROUTING_API_BASE_URL3;
|
|
2498
1436
|
let res;
|
|
2499
1437
|
try {
|
|
2500
1438
|
res = await fetch(
|
|
2501
|
-
`${
|
|
1439
|
+
`${base3}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
|
|
2502
1440
|
{
|
|
2503
1441
|
headers: { "x-owney-api-key": input.apiKey }
|
|
2504
1442
|
}
|
|
@@ -2530,8 +1468,85 @@ async function getSponsorRelayerAddress(input) {
|
|
|
2530
1468
|
return parsed.data.relayer;
|
|
2531
1469
|
}
|
|
2532
1470
|
|
|
1471
|
+
// src/lib/permit2.ts
|
|
1472
|
+
var import_viem4 = require("viem");
|
|
1473
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
1474
|
+
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
1475
|
+
var ERC20_ALLOWANCE_ABI = [
|
|
1476
|
+
{
|
|
1477
|
+
type: "function",
|
|
1478
|
+
name: "allowance",
|
|
1479
|
+
stateMutability: "view",
|
|
1480
|
+
inputs: [
|
|
1481
|
+
{ name: "owner", type: "address" },
|
|
1482
|
+
{ name: "spender", type: "address" }
|
|
1483
|
+
],
|
|
1484
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
1485
|
+
},
|
|
1486
|
+
{
|
|
1487
|
+
type: "function",
|
|
1488
|
+
name: "approve",
|
|
1489
|
+
stateMutability: "nonpayable",
|
|
1490
|
+
inputs: [
|
|
1491
|
+
{ name: "spender", type: "address" },
|
|
1492
|
+
{ name: "amount", type: "uint256" }
|
|
1493
|
+
],
|
|
1494
|
+
outputs: [{ name: "", type: "bool" }]
|
|
1495
|
+
},
|
|
1496
|
+
{
|
|
1497
|
+
type: "function",
|
|
1498
|
+
name: "balanceOf",
|
|
1499
|
+
stateMutability: "view",
|
|
1500
|
+
inputs: [{ name: "account", type: "address" }],
|
|
1501
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
1502
|
+
}
|
|
1503
|
+
];
|
|
1504
|
+
function buildPermitTransferFromTypedData(input) {
|
|
1505
|
+
return {
|
|
1506
|
+
domain: {
|
|
1507
|
+
name: "Permit2",
|
|
1508
|
+
chainId: input.chainId,
|
|
1509
|
+
verifyingContract: PERMIT2_ADDRESS
|
|
1510
|
+
},
|
|
1511
|
+
types: {
|
|
1512
|
+
PermitTransferFrom: [
|
|
1513
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
1514
|
+
{ name: "spender", type: "address" },
|
|
1515
|
+
{ name: "nonce", type: "uint256" },
|
|
1516
|
+
{ name: "deadline", type: "uint256" }
|
|
1517
|
+
],
|
|
1518
|
+
TokenPermissions: [
|
|
1519
|
+
{ name: "token", type: "address" },
|
|
1520
|
+
{ name: "amount", type: "uint256" }
|
|
1521
|
+
]
|
|
1522
|
+
},
|
|
1523
|
+
primaryType: "PermitTransferFrom",
|
|
1524
|
+
message: input.message
|
|
1525
|
+
};
|
|
1526
|
+
}
|
|
1527
|
+
function randomPermit2Nonce() {
|
|
1528
|
+
const bytes = new Uint8Array(32);
|
|
1529
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
1530
|
+
return BigInt((0, import_viem4.bytesToHex)(bytes));
|
|
1531
|
+
}
|
|
1532
|
+
async function readPermit2Allowance(publicClient, token, owner) {
|
|
1533
|
+
return publicClient.readContract({
|
|
1534
|
+
address: token,
|
|
1535
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
1536
|
+
functionName: "allowance",
|
|
1537
|
+
args: [owner, PERMIT2_ADDRESS]
|
|
1538
|
+
});
|
|
1539
|
+
}
|
|
1540
|
+
async function readErc20Balance(publicClient, token, owner) {
|
|
1541
|
+
return publicClient.readContract({
|
|
1542
|
+
address: token,
|
|
1543
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
1544
|
+
functionName: "balanceOf",
|
|
1545
|
+
args: [owner]
|
|
1546
|
+
});
|
|
1547
|
+
}
|
|
1548
|
+
|
|
2533
1549
|
// src/lib/sponsored-deposit.ts
|
|
2534
|
-
init_permit2();
|
|
2535
1550
|
var AUTH_WINDOW_SECONDS = 15 * 60;
|
|
2536
1551
|
function makeSponsoredDepositCallback(deps) {
|
|
2537
1552
|
const post = deps.httpPost ?? postSponsorTransferAuth;
|
|
@@ -2605,8 +1620,6 @@ function makeSponsoredDepositCallback(deps) {
|
|
|
2605
1620
|
}
|
|
2606
1621
|
|
|
2607
1622
|
// src/lib/sponsored-weth-deposit.ts
|
|
2608
|
-
init_errors();
|
|
2609
|
-
init_permit2();
|
|
2610
1623
|
var PERMIT_WINDOW_SECONDS = 15 * 60;
|
|
2611
1624
|
function makeSponsoredWethCallback(deps) {
|
|
2612
1625
|
const get = deps.httpGet ?? getSponsorRelayerAddress;
|
|
@@ -2685,7 +1698,6 @@ function makeSponsoredWethCallback(deps) {
|
|
|
2685
1698
|
}
|
|
2686
1699
|
|
|
2687
1700
|
// src/client.ts
|
|
2688
|
-
init_permit2();
|
|
2689
1701
|
function encodeMultiAgentCursor(map) {
|
|
2690
1702
|
return Buffer.from(JSON.stringify(map), "utf8").toString("base64");
|
|
2691
1703
|
}
|
|
@@ -2712,11 +1724,10 @@ var SPONSORED_USDC_BY_CHAIN = {
|
|
|
2712
1724
|
1: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
|
|
2713
1725
|
};
|
|
2714
1726
|
var VIEM_CHAIN2 = {
|
|
2715
|
-
8453:
|
|
2716
|
-
42161:
|
|
2717
|
-
1:
|
|
1727
|
+
8453: import_chains2.base,
|
|
1728
|
+
42161: import_chains2.arbitrum,
|
|
1729
|
+
1: import_chains2.mainnet
|
|
2718
1730
|
};
|
|
2719
|
-
var AGENT_ELIGIBILITY_ORDER = ["surfliquid", "zyfai", "sail"];
|
|
2720
1731
|
var SPONSORED_WETH_BY_CHAIN = {
|
|
2721
1732
|
8453: "0x4200000000000000000000000000000000000006",
|
|
2722
1733
|
42161: "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1",
|
|
@@ -2736,26 +1747,17 @@ var OwneySDK = class {
|
|
|
2736
1747
|
disabledAgents = /* @__PURE__ */ new Set();
|
|
2737
1748
|
state = null;
|
|
2738
1749
|
apiKey;
|
|
2739
|
-
// The org's agent policy, fetched once per client. Applied to each agent on
|
|
2740
|
-
// activation (ROUT-229). `undefined` means "not fetched yet", `null` means
|
|
2741
|
-
// "fetched, and the partner has no policy" — which is a real answer meaning
|
|
2742
|
-
// leave every user's agent profile alone.
|
|
2743
|
-
orgAgentConfig;
|
|
2744
|
-
orgAgentConfigPromise = null;
|
|
2745
1750
|
zyfaiRpcUrls;
|
|
2746
1751
|
routingApiBaseUrl;
|
|
2747
1752
|
referralSource;
|
|
2748
|
-
surfliquidApiBaseUrl;
|
|
2749
1753
|
cachedSponsoredCallback = null;
|
|
2750
1754
|
cachedWethSponsoredCallback = null;
|
|
2751
1755
|
initializingAgentsPromise = null;
|
|
2752
1756
|
constructor(config) {
|
|
2753
1757
|
this.apiKey = config.apiKey;
|
|
2754
|
-
if (config.debug) setOwneyDebug(true);
|
|
2755
1758
|
this.zyfaiRpcUrls = config.zyfaiRpcUrls;
|
|
2756
1759
|
this.routingApiBaseUrl = config.routingApiBaseUrl;
|
|
2757
1760
|
this.referralSource = config.referralSource;
|
|
2758
|
-
this.surfliquidApiBaseUrl = config.surfliquidApiBaseUrl;
|
|
2759
1761
|
}
|
|
2760
1762
|
/**
|
|
2761
1763
|
* Establish connection state for all subsequent SDK calls.
|
|
@@ -2853,14 +1855,14 @@ var OwneySDK = class {
|
|
|
2853
1855
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2854
1856
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2855
1857
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2856
|
-
getPublicClient: (cid) => (0,
|
|
1858
|
+
getPublicClient: (cid) => (0, import_viem5.createPublicClient)({
|
|
2857
1859
|
chain: VIEM_CHAIN2[cid],
|
|
2858
|
-
transport: (0,
|
|
1860
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2859
1861
|
}),
|
|
2860
|
-
getWalletClient: (cid) => (0,
|
|
1862
|
+
getWalletClient: (cid) => (0, import_viem5.createWalletClient)({
|
|
2861
1863
|
account: owner,
|
|
2862
1864
|
chain: VIEM_CHAIN2[cid],
|
|
2863
|
-
transport: (0,
|
|
1865
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2864
1866
|
})
|
|
2865
1867
|
});
|
|
2866
1868
|
if (!onApproved) this.cachedSponsoredCallback = callback;
|
|
@@ -2886,14 +1888,14 @@ var OwneySDK = class {
|
|
|
2886
1888
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
2887
1889
|
// PublicClient/WalletClient param types — structurally identical at
|
|
2888
1890
|
// runtime, but the two share a name TS treats as unrelated.
|
|
2889
|
-
getPublicClient: (cid) => (0,
|
|
1891
|
+
getPublicClient: (cid) => (0, import_viem5.createPublicClient)({
|
|
2890
1892
|
chain: VIEM_CHAIN2[cid],
|
|
2891
|
-
transport: (0,
|
|
1893
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2892
1894
|
}),
|
|
2893
|
-
getWalletClient: (cid) => (0,
|
|
1895
|
+
getWalletClient: (cid) => (0, import_viem5.createWalletClient)({
|
|
2894
1896
|
account: owner,
|
|
2895
1897
|
chain: VIEM_CHAIN2[cid],
|
|
2896
|
-
transport: (0,
|
|
1898
|
+
transport: (0, import_viem5.custom)(provider)
|
|
2897
1899
|
})
|
|
2898
1900
|
});
|
|
2899
1901
|
if (!onApproved) this.cachedWethSponsoredCallback = callback;
|
|
@@ -2914,57 +1916,14 @@ var OwneySDK = class {
|
|
|
2914
1916
|
}
|
|
2915
1917
|
return active;
|
|
2916
1918
|
}
|
|
2917
|
-
/**
|
|
2918
|
-
* Read the org's agent policy once and reuse it. fetchOrgAgentConfig never
|
|
2919
|
-
* throws — it degrades to null — so this cannot break activation.
|
|
2920
|
-
*/
|
|
2921
|
-
async getOrgAgentConfig() {
|
|
2922
|
-
if (this.orgAgentConfig !== void 0) return this.orgAgentConfig;
|
|
2923
|
-
if (!this.orgAgentConfigPromise) {
|
|
2924
|
-
this.orgAgentConfigPromise = fetchOrgAgentConfig(this.apiKey).then(
|
|
2925
|
-
(config) => {
|
|
2926
|
-
this.orgAgentConfig = config;
|
|
2927
|
-
return config;
|
|
2928
|
-
}
|
|
2929
|
-
);
|
|
2930
|
-
}
|
|
2931
|
-
return this.orgAgentConfigPromise;
|
|
2932
|
-
}
|
|
2933
|
-
/**
|
|
2934
|
-
* Apply the org policy to one agent, after it has activated.
|
|
2935
|
-
*
|
|
2936
|
-
* Sequenced after activation rather than alongside it because applying the
|
|
2937
|
-
* policy needs the authenticated session activation establishes. Every failure
|
|
2938
|
-
* mode is swallowed: a partner's splitting preference is not worth failing a
|
|
2939
|
-
* user's connect over.
|
|
2940
|
-
*/
|
|
2941
|
-
async applyOrgPolicyTo(agent, state, chainId) {
|
|
2942
|
-
if (!agent.applyOrgPolicy) {
|
|
2943
|
-
debugLog(
|
|
2944
|
-
"owney-sdk",
|
|
2945
|
-
`${agent.id}: no applyOrgPolicy \u2014 agent has no org-level knobs, skipping`
|
|
2946
|
-
);
|
|
2947
|
-
return;
|
|
2948
|
-
}
|
|
2949
|
-
try {
|
|
2950
|
-
const policy = await this.getOrgAgentConfig();
|
|
2951
|
-
if (!policy) return;
|
|
2952
|
-
await agent.applyOrgPolicy(state, chainId, policy);
|
|
2953
|
-
} catch (error) {
|
|
2954
|
-
console.warn(
|
|
2955
|
-
`[owney-sdk] applyOrgPolicy(${agent.id}) failed (non-fatal):`,
|
|
2956
|
-
error instanceof Error ? error.message : String(error)
|
|
2957
|
-
);
|
|
2958
|
-
}
|
|
2959
|
-
}
|
|
2960
1919
|
async ensureAgentsInitialized() {
|
|
2961
1920
|
if (this.agents.size > 0) return;
|
|
2962
1921
|
if (!this.initializingAgentsPromise) {
|
|
2963
1922
|
this.initializingAgentsPromise = (async () => {
|
|
2964
1923
|
const agentKeys = await fetchAgentKeys(this.apiKey);
|
|
2965
1924
|
this.disabledAgents.clear();
|
|
2966
|
-
for (const { key
|
|
2967
|
-
const agent =
|
|
1925
|
+
for (const { key, agent_type, is_enabled } of agentKeys) {
|
|
1926
|
+
const agent = this.createAgent(agent_type, key);
|
|
2968
1927
|
if (!agent) continue;
|
|
2969
1928
|
this.agents.set(agent_type, agent);
|
|
2970
1929
|
if (is_enabled === false) {
|
|
@@ -2985,21 +1944,9 @@ var OwneySDK = class {
|
|
|
2985
1944
|
this.initializingAgentsPromise = null;
|
|
2986
1945
|
}
|
|
2987
1946
|
}
|
|
2988
|
-
|
|
1947
|
+
createAgent(agentId, key) {
|
|
2989
1948
|
if (agentId === "zyfai") {
|
|
2990
|
-
return new ZyfaiAgent(
|
|
2991
|
-
}
|
|
2992
|
-
if (agentId === "surfliquid") {
|
|
2993
|
-
if (!projectName) return null;
|
|
2994
|
-
const { SurfLiquidAgent: SurfLiquidAgent2 } = await Promise.resolve().then(() => (init_surfliquid_agent(), surfliquid_agent_exports));
|
|
2995
|
-
return new SurfLiquidAgent2({
|
|
2996
|
-
projectName,
|
|
2997
|
-
appId: key2,
|
|
2998
|
-
// Same-origin proxy override — SurfLiquid auth is an httpOnly cookie,
|
|
2999
|
-
// which WebKit (iOS) discards when it is third-party. See
|
|
3000
|
-
// OwneySDKConfig.surfliquidApiBaseUrl.
|
|
3001
|
-
apiBaseUrl: this.surfliquidApiBaseUrl
|
|
3002
|
-
});
|
|
1949
|
+
return new ZyfaiAgent(key, this.zyfaiRpcUrls, this.referralSource);
|
|
3003
1950
|
}
|
|
3004
1951
|
return null;
|
|
3005
1952
|
}
|
|
@@ -3053,7 +2000,6 @@ var OwneySDK = class {
|
|
|
3053
2000
|
Promise.all(
|
|
3054
2001
|
agents.map(async (agent) => {
|
|
3055
2002
|
await agent.activateAgent(state, chainId);
|
|
3056
|
-
await this.applyOrgPolicyTo(agent, state, chainId);
|
|
3057
2003
|
})
|
|
3058
2004
|
).catch((error) => {
|
|
3059
2005
|
console.error("activateAgent background init failed:", error);
|
|
@@ -3081,7 +2027,6 @@ var OwneySDK = class {
|
|
|
3081
2027
|
Promise.all(
|
|
3082
2028
|
enabledCompatible.map(async (agent) => {
|
|
3083
2029
|
await agent.activateAgent(state, chainId);
|
|
3084
|
-
await this.applyOrgPolicyTo(agent, state, chainId);
|
|
3085
2030
|
})
|
|
3086
2031
|
).catch((error) => {
|
|
3087
2032
|
console.error("activateAgent background init failed:", error);
|
|
@@ -3155,30 +2100,18 @@ var OwneySDK = class {
|
|
|
3155
2100
|
);
|
|
3156
2101
|
}
|
|
3157
2102
|
const agentResults = {};
|
|
3158
|
-
const agentErrors = {};
|
|
3159
2103
|
for (const { agent, amount: agentAmount } of agentAmounts) {
|
|
3160
|
-
|
|
3161
|
-
|
|
3162
|
-
|
|
3163
|
-
|
|
3164
|
-
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
depositCallback
|
|
3169
|
-
);
|
|
3170
|
-
} catch (error) {
|
|
3171
|
-
agentErrors[agent.id] = error instanceof Error ? error.message : String(error);
|
|
3172
|
-
}
|
|
3173
|
-
}
|
|
3174
|
-
if (Object.keys(agentResults).length === 0) {
|
|
3175
|
-
throw new OwneyError(
|
|
3176
|
-
"DEPOSIT_ALL_FAILED",
|
|
3177
|
-
`All ${agentAmounts.length} agent deposit(s) failed.`,
|
|
3178
|
-
{ agentErrors }
|
|
2104
|
+
agentResults[agent.id] = await this.depositWithFallback(
|
|
2105
|
+
agent,
|
|
2106
|
+
state,
|
|
2107
|
+
chainId,
|
|
2108
|
+
agentAmount,
|
|
2109
|
+
asset,
|
|
2110
|
+
effectiveCallback,
|
|
2111
|
+
depositCallback
|
|
3179
2112
|
);
|
|
3180
2113
|
}
|
|
3181
|
-
return
|
|
2114
|
+
return { agentResults };
|
|
3182
2115
|
}
|
|
3183
2116
|
/**
|
|
3184
2117
|
* Invokes `agent.deposit` with the resolved sponsored callback, composing
|
|
@@ -3294,8 +2227,9 @@ var OwneySDK = class {
|
|
|
3294
2227
|
async hasExistingBalance(agent, state, chainId, asset) {
|
|
3295
2228
|
try {
|
|
3296
2229
|
const balance = await agent.getBalances(state, chainId);
|
|
2230
|
+
const target = asset.toLowerCase();
|
|
3297
2231
|
const token = balance.tokens.find(
|
|
3298
|
-
(t) => t.chainId === chainId &&
|
|
2232
|
+
(t) => t.chainId === chainId && t.asset.toLowerCase() === target
|
|
3299
2233
|
);
|
|
3300
2234
|
return !!token && Number(token.amount) > 0;
|
|
3301
2235
|
} catch {
|
|
@@ -3334,34 +2268,6 @@ var OwneySDK = class {
|
|
|
3334
2268
|
}
|
|
3335
2269
|
return eligible;
|
|
3336
2270
|
}
|
|
3337
|
-
/**
|
|
3338
|
-
* Agent ids the routing API provisioned for this org that support the given
|
|
3339
|
-
* chain + asset, ordered by preference ({@link AGENT_ELIGIBILITY_ORDER},
|
|
3340
|
-
* surfliquid first). Returns `[]` when the org has no compatible agent — never
|
|
3341
|
-
* throws on an empty org. Loads agent keys on first call (apiKey only, no
|
|
3342
|
-
* wallet), so the UI can resolve which agent to use before the user connects.
|
|
3343
|
-
*
|
|
3344
|
-
* This is the source of truth for agent availability: an agent appears here
|
|
3345
|
-
* iff the routing API returned its key. No per-app feature flags.
|
|
3346
|
-
*/
|
|
3347
|
-
async getEligibleAgentIds(chainId, asset) {
|
|
3348
|
-
try {
|
|
3349
|
-
await this.ensureAgentsInitialized();
|
|
3350
|
-
} catch (error) {
|
|
3351
|
-
if (error instanceof OwneyError && error.code === "API_NO_AGENTS") {
|
|
3352
|
-
return [];
|
|
3353
|
-
}
|
|
3354
|
-
throw error;
|
|
3355
|
-
}
|
|
3356
|
-
return [...this.agents.values()].filter((agent) => {
|
|
3357
|
-
const chainAssets = agent.supportedAssets.find(
|
|
3358
|
-
(sa) => sa.chainId === chainId
|
|
3359
|
-
);
|
|
3360
|
-
return chainAssets?.assets.some((a) => a.symbol === asset) ?? false;
|
|
3361
|
-
}).map((agent) => agent.id).sort(
|
|
3362
|
-
(a, b) => AGENT_ELIGIBILITY_ORDER.indexOf(a) - AGENT_ELIGIBILITY_ORDER.indexOf(b)
|
|
3363
|
-
);
|
|
3364
|
-
}
|
|
3365
2271
|
// --- Fund operations ---
|
|
3366
2272
|
/**
|
|
3367
2273
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
@@ -3397,17 +2303,9 @@ var OwneySDK = class {
|
|
|
3397
2303
|
}
|
|
3398
2304
|
const eligibleAgents = this.getEligibleAgents(chainId, asset);
|
|
3399
2305
|
if (!amount) {
|
|
3400
|
-
const aggregated2 = await this.getBalances();
|
|
3401
|
-
const funded = projectAgentBalancesForAsset(
|
|
3402
|
-
eligibleAgents,
|
|
3403
|
-
aggregated2.agentBalances,
|
|
3404
|
-
chainId,
|
|
3405
|
-
asset,
|
|
3406
|
-
assetInfo.decimals
|
|
3407
|
-
).filter((b) => b.balance > 0n);
|
|
3408
2306
|
const results2 = {};
|
|
3409
2307
|
const agentErrors2 = {};
|
|
3410
|
-
for (const
|
|
2308
|
+
for (const agent of eligibleAgents) {
|
|
3411
2309
|
try {
|
|
3412
2310
|
results2[agent.id] = await agent.withdraw(state, chainId, token);
|
|
3413
2311
|
} catch (err) {
|
|
@@ -3424,10 +2322,9 @@ var OwneySDK = class {
|
|
|
3424
2322
|
{ asset, agentErrors: agentErrors2 }
|
|
3425
2323
|
);
|
|
3426
2324
|
}
|
|
3427
|
-
const totalWithdrawn = funded.filter(({ agent }) => results2[agent.id] !== void 0).reduce((sum, { balance }) => sum + balance, 0n);
|
|
3428
2325
|
return {
|
|
3429
2326
|
agentResult: results2,
|
|
3430
|
-
totalWithdrawn:
|
|
2327
|
+
totalWithdrawn: sumWithdrawnAmount(results2).toString()
|
|
3431
2328
|
};
|
|
3432
2329
|
}
|
|
3433
2330
|
const requested = BigInt(amount);
|
|
@@ -3797,10 +2694,10 @@ var OwneySDK = class {
|
|
|
3797
2694
|
);
|
|
3798
2695
|
}
|
|
3799
2696
|
const provider = this.requireConnectedProvider();
|
|
3800
|
-
const wallet = (0,
|
|
2697
|
+
const wallet = (0, import_viem5.createWalletClient)({
|
|
3801
2698
|
account: state.walletAddress,
|
|
3802
2699
|
chain: VIEM_CHAIN2[chainId],
|
|
3803
|
-
transport: (0,
|
|
2700
|
+
transport: (0, import_viem5.custom)(provider)
|
|
3804
2701
|
});
|
|
3805
2702
|
const hash = await wallet.writeContract({
|
|
3806
2703
|
address: token,
|
|
@@ -3810,9 +2707,9 @@ var OwneySDK = class {
|
|
|
3810
2707
|
account: state.walletAddress,
|
|
3811
2708
|
chain: VIEM_CHAIN2[chainId]
|
|
3812
2709
|
});
|
|
3813
|
-
const publicClient = (0,
|
|
2710
|
+
const publicClient = (0, import_viem5.createPublicClient)({
|
|
3814
2711
|
chain: VIEM_CHAIN2[chainId],
|
|
3815
|
-
transport: (0,
|
|
2712
|
+
transport: (0, import_viem5.custom)(provider)
|
|
3816
2713
|
});
|
|
3817
2714
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
3818
2715
|
hash,
|
|
@@ -3920,11 +2817,8 @@ var OwneySDK = class {
|
|
|
3920
2817
|
}
|
|
3921
2818
|
};
|
|
3922
2819
|
|
|
3923
|
-
// src/index.ts
|
|
3924
|
-
init_errors();
|
|
3925
|
-
|
|
3926
2820
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
3927
|
-
var
|
|
2821
|
+
var import_viem6 = require("viem");
|
|
3928
2822
|
var import_siwe = require("siwe");
|
|
3929
2823
|
var import_sdk2 = require("@zyfai/sdk");
|
|
3930
2824
|
|
|
@@ -3947,22 +2841,22 @@ var readLegacySiwxSession = (store, address) => {
|
|
|
3947
2841
|
const legacyKeys = [];
|
|
3948
2842
|
try {
|
|
3949
2843
|
for (let i = 0; i < store.length; i++) {
|
|
3950
|
-
const
|
|
3951
|
-
if (
|
|
2844
|
+
const key = store.key(i);
|
|
2845
|
+
if (key?.startsWith(prefix)) legacyKeys.push(key);
|
|
3952
2846
|
}
|
|
3953
2847
|
} catch {
|
|
3954
2848
|
return null;
|
|
3955
2849
|
}
|
|
3956
2850
|
let adopted = null;
|
|
3957
|
-
for (const
|
|
2851
|
+
for (const key of legacyKeys) {
|
|
3958
2852
|
if (!adopted) {
|
|
3959
2853
|
try {
|
|
3960
|
-
adopted = JSON.parse(store.getItem(
|
|
2854
|
+
adopted = JSON.parse(store.getItem(key) ?? "");
|
|
3961
2855
|
} catch {
|
|
3962
2856
|
}
|
|
3963
2857
|
}
|
|
3964
2858
|
try {
|
|
3965
|
-
store.removeItem(
|
|
2859
|
+
store.removeItem(key);
|
|
3966
2860
|
} catch {
|
|
3967
2861
|
}
|
|
3968
2862
|
}
|
|
@@ -3970,11 +2864,11 @@ var readLegacySiwxSession = (store, address) => {
|
|
|
3970
2864
|
};
|
|
3971
2865
|
var readSiwxSession = (address, chainId) => {
|
|
3972
2866
|
if (typeof window === "undefined") return null;
|
|
3973
|
-
const
|
|
2867
|
+
const key = buildKey2(address);
|
|
3974
2868
|
const store = storage2();
|
|
3975
2869
|
let raw = null;
|
|
3976
2870
|
try {
|
|
3977
|
-
raw = store?.getItem(
|
|
2871
|
+
raw = store?.getItem(key) ?? null;
|
|
3978
2872
|
} catch {
|
|
3979
2873
|
raw = null;
|
|
3980
2874
|
}
|
|
@@ -3982,9 +2876,9 @@ var readSiwxSession = (address, chainId) => {
|
|
|
3982
2876
|
try {
|
|
3983
2877
|
return JSON.parse(raw);
|
|
3984
2878
|
} catch {
|
|
3985
|
-
memorySiwxSessions.delete(
|
|
2879
|
+
memorySiwxSessions.delete(key);
|
|
3986
2880
|
try {
|
|
3987
|
-
store?.removeItem(
|
|
2881
|
+
store?.removeItem(key);
|
|
3988
2882
|
} catch {
|
|
3989
2883
|
}
|
|
3990
2884
|
return null;
|
|
@@ -3995,24 +2889,24 @@ var readSiwxSession = (address, chainId) => {
|
|
|
3995
2889
|
writeSiwxSession(address, chainId, legacy);
|
|
3996
2890
|
return legacy;
|
|
3997
2891
|
}
|
|
3998
|
-
return memorySiwxSessions.get(
|
|
2892
|
+
return memorySiwxSessions.get(key) ?? null;
|
|
3999
2893
|
};
|
|
4000
2894
|
var writeSiwxSession = (address, _chainId, session) => {
|
|
4001
2895
|
if (typeof window === "undefined") return;
|
|
4002
|
-
const
|
|
4003
|
-
memorySiwxSessions.set(
|
|
2896
|
+
const key = buildKey2(address);
|
|
2897
|
+
memorySiwxSessions.set(key, session);
|
|
4004
2898
|
const store = storage2();
|
|
4005
2899
|
try {
|
|
4006
|
-
store?.setItem(
|
|
2900
|
+
store?.setItem(key, JSON.stringify(session));
|
|
4007
2901
|
} catch {
|
|
4008
2902
|
}
|
|
4009
2903
|
};
|
|
4010
2904
|
var clearSiwxSession = (address, _chainId) => {
|
|
4011
|
-
const
|
|
4012
|
-
memorySiwxSessions.delete(
|
|
2905
|
+
const key = buildKey2(address);
|
|
2906
|
+
memorySiwxSessions.delete(key);
|
|
4013
2907
|
const store = storage2();
|
|
4014
2908
|
try {
|
|
4015
|
-
store?.removeItem(
|
|
2909
|
+
store?.removeItem(key);
|
|
4016
2910
|
} catch {
|
|
4017
2911
|
}
|
|
4018
2912
|
readLegacySiwxSession(store, address);
|
|
@@ -4051,7 +2945,7 @@ function buildSIWXConfig(deps) {
|
|
|
4051
2945
|
issuedAt,
|
|
4052
2946
|
toString() {
|
|
4053
2947
|
return new import_siwe.SiweMessage({
|
|
4054
|
-
address: (0,
|
|
2948
|
+
address: (0, import_viem6.getAddress)(accountAddress),
|
|
4055
2949
|
chainId: numericChainId(chainId),
|
|
4056
2950
|
domain,
|
|
4057
2951
|
uri,
|
|
@@ -4142,6 +3036,5 @@ function createOwneySIWX(config) {
|
|
|
4142
3036
|
NotConnectedError,
|
|
4143
3037
|
OwneyError,
|
|
4144
3038
|
OwneySDK,
|
|
4145
|
-
createOwneySIWX
|
|
4146
|
-
setOwneyDebug
|
|
3039
|
+
createOwneySIWX
|
|
4147
3040
|
});
|