@owney/sdk 0.7.23-beta.0 → 0.7.23
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 +268 -831
- package/dist/index.d.cts +59 -213
- package/dist/index.d.ts +59 -213
- package/dist/index.js +249 -813
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -27,7 +27,7 @@ __export(index_exports, {
|
|
|
27
27
|
OwneyError: () => OwneyError,
|
|
28
28
|
OwneySDK: () => OwneySDK,
|
|
29
29
|
createOwneySIWX: () => createOwneySIWX,
|
|
30
|
-
|
|
30
|
+
recentEarningsFromPoints: () => recentEarningsFromPoints,
|
|
31
31
|
setOwneyDebug: () => setOwneyDebug
|
|
32
32
|
});
|
|
33
33
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -698,6 +698,63 @@ function computeAllocationApy(positions) {
|
|
|
698
698
|
const totalApy = totalValue > 0 ? String(weightedSum / totalValue) : "0";
|
|
699
699
|
return { totalApy, apyByChainAndAsset };
|
|
700
700
|
}
|
|
701
|
+
var ZYFAI_NET_OF_FEE_MULTIPLIER = 0.9;
|
|
702
|
+
function sumEarningsBucket(bucket, chainId, tokenSymbol) {
|
|
703
|
+
const tokens = bucket?.[String(chainId)];
|
|
704
|
+
if (!tokens) return null;
|
|
705
|
+
const wanted = tokenSymbol?.toUpperCase();
|
|
706
|
+
let total = 0;
|
|
707
|
+
let matched = false;
|
|
708
|
+
for (const [symbol, value] of Object.entries(tokens)) {
|
|
709
|
+
if (wanted && symbol.toUpperCase() !== wanted) continue;
|
|
710
|
+
matched = true;
|
|
711
|
+
const amount = Number(value);
|
|
712
|
+
if (!Number.isFinite(amount)) continue;
|
|
713
|
+
total += amount;
|
|
714
|
+
}
|
|
715
|
+
return matched ? total : null;
|
|
716
|
+
}
|
|
717
|
+
function netEarningsForSnapshot(entry, chainId, tokenSymbol) {
|
|
718
|
+
const lifetime = sumEarningsBucket(entry.lifetime_earnings_by_token, chainId, tokenSymbol);
|
|
719
|
+
const unrealized = sumEarningsBucket(entry.unrealized_earnings_by_token, chainId, tokenSymbol);
|
|
720
|
+
const current = sumEarningsBucket(entry.current_earnings_by_token, chainId, tokenSymbol);
|
|
721
|
+
if (lifetime === null && unrealized === null && current === null) {
|
|
722
|
+
const gross = sumEarningsBucket(entry.total_earnings_by_token, chainId, tokenSymbol);
|
|
723
|
+
if (gross === null) return null;
|
|
724
|
+
if (!warnedGrossApyFallbacks.has("daily_earnings_net_components")) {
|
|
725
|
+
warnedGrossApyFallbacks.add("daily_earnings_net_components");
|
|
726
|
+
console.warn(
|
|
727
|
+
`[owney] @zyfai/sdk omitted the daily net-earnings components; falling back to gross totals, which do not deduct Zyfai's performance fee and so read high.`
|
|
728
|
+
);
|
|
729
|
+
}
|
|
730
|
+
debugLog("zyfai:earnings", "gross fallback for daily earnings", { gross });
|
|
731
|
+
return gross;
|
|
732
|
+
}
|
|
733
|
+
return (lifetime ?? 0) + (unrealized ?? 0) + (current ?? 0) * ZYFAI_NET_OF_FEE_MULTIPLIER;
|
|
734
|
+
}
|
|
735
|
+
function mapDailyEarnings(raw, chainId, tokenSymbol) {
|
|
736
|
+
const points = (raw.data ?? []).map((entry) => ({
|
|
737
|
+
date: entry.snapshot_date,
|
|
738
|
+
net: netEarningsForSnapshot(entry, chainId, tokenSymbol)
|
|
739
|
+
})).filter((p) => p.net !== null).sort((a, b) => a.date.localeCompare(b.date));
|
|
740
|
+
return { walletAddress: raw.walletAddress, points };
|
|
741
|
+
}
|
|
742
|
+
var MS_PER_DAY = 24 * 60 * 60 * 1e3;
|
|
743
|
+
function recentEarningsFromPoints(points, requestedDays) {
|
|
744
|
+
if (points.length === 0) return null;
|
|
745
|
+
const first = points[0];
|
|
746
|
+
const last = points[points.length - 1];
|
|
747
|
+
const spanDays = Math.round(
|
|
748
|
+
(Date.parse(last.date) - Date.parse(first.date)) / MS_PER_DAY
|
|
749
|
+
);
|
|
750
|
+
const amount = Math.max(0, last.net - first.net);
|
|
751
|
+
return {
|
|
752
|
+
amount,
|
|
753
|
+
spanDays: Number.isFinite(spanDays) ? spanDays : 0,
|
|
754
|
+
// A single snapshot spans no window at all, so it is always truncated.
|
|
755
|
+
isTruncated: requestedDays === void 0 ? points.length < 2 : spanDays < requestedDays
|
|
756
|
+
};
|
|
757
|
+
}
|
|
701
758
|
|
|
702
759
|
// src/agents/zyfai/zyfai.withdraw-amount.ts
|
|
703
760
|
var TRANSFER_TOPIC = "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef";
|
|
@@ -1944,6 +2001,15 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1944
2001
|
const raw = await this.sdk.getDailyApyHistory(smartWallet, days);
|
|
1945
2002
|
return mapApyHistory(raw, chainId, tokenSymbol);
|
|
1946
2003
|
}
|
|
2004
|
+
async getDailyEarnings(state, chainId, days, tokenSymbol) {
|
|
2005
|
+
const { smartWallet } = await this.resolveSmartWallet(state, chainId);
|
|
2006
|
+
const start = new Date(Date.now() - (DayFilterMapping[days] + 1) * 864e5);
|
|
2007
|
+
const raw = await this.sdk.getDailyEarnings(
|
|
2008
|
+
smartWallet,
|
|
2009
|
+
start.toISOString().slice(0, 10)
|
|
2010
|
+
);
|
|
2011
|
+
return mapDailyEarnings(raw, chainId, tokenSymbol);
|
|
2012
|
+
}
|
|
1947
2013
|
/**
|
|
1948
2014
|
* Owney speaks asset symbols ("USDC" / "WETH"); Zyfai's history endpoint
|
|
1949
2015
|
* takes lowercase `assetType` and denominates WETH as "eth" (the same
|
|
@@ -2121,597 +2187,6 @@ async function fetchAgentKeys(apiKey, baseUrl = ROUTING_API_BASE_URL) {
|
|
|
2121
2187
|
return json.data;
|
|
2122
2188
|
}
|
|
2123
2189
|
|
|
2124
|
-
// src/lib/chain-guard.ts
|
|
2125
|
-
var CHAIN_NAMES = {
|
|
2126
|
-
1: "Ethereum",
|
|
2127
|
-
8453: "Base",
|
|
2128
|
-
42161: "Arbitrum"
|
|
2129
|
-
};
|
|
2130
|
-
function chainName(chainId) {
|
|
2131
|
-
return CHAIN_NAMES[chainId] ?? `chain ${chainId}`;
|
|
2132
|
-
}
|
|
2133
|
-
async function ensureWalletOnChain(pub, wallet, expected) {
|
|
2134
|
-
const actual = await pub.getChainId();
|
|
2135
|
-
if (actual === expected) return;
|
|
2136
|
-
try {
|
|
2137
|
-
await wallet.switchChain({ id: expected });
|
|
2138
|
-
} catch (error) {
|
|
2139
|
-
throw new OwneyError(
|
|
2140
|
-
"CHAIN_MISMATCH",
|
|
2141
|
-
`Your wallet is on ${chainName(actual)}. Switch it to ${chainName(expected)} and try again.`,
|
|
2142
|
-
{
|
|
2143
|
-
expectedChainId: expected,
|
|
2144
|
-
actualChainId: actual,
|
|
2145
|
-
cause: error instanceof Error ? error.message : String(error)
|
|
2146
|
-
}
|
|
2147
|
-
);
|
|
2148
|
-
}
|
|
2149
|
-
const after = await pub.getChainId();
|
|
2150
|
-
if (after !== expected) {
|
|
2151
|
-
throw new OwneyError(
|
|
2152
|
-
"CHAIN_MISMATCH",
|
|
2153
|
-
`Your wallet is still on ${chainName(after)}. Switch it to ${chainName(expected)} and try again.`,
|
|
2154
|
-
{ expectedChainId: expected, actualChainId: after }
|
|
2155
|
-
);
|
|
2156
|
-
}
|
|
2157
|
-
}
|
|
2158
|
-
|
|
2159
|
-
// src/lib/swap/swap-api.ts
|
|
2160
|
-
async function request(baseUrl, apiKey, path, init) {
|
|
2161
|
-
const url = `${baseUrl}/api/v1/swap${path}`;
|
|
2162
|
-
const res = await fetch(url, {
|
|
2163
|
-
method: init?.method ?? "GET",
|
|
2164
|
-
headers: {
|
|
2165
|
-
"Content-Type": "application/json",
|
|
2166
|
-
"x-owney-api-key": apiKey
|
|
2167
|
-
},
|
|
2168
|
-
...init ? { body: JSON.stringify(init.body) } : {}
|
|
2169
|
-
});
|
|
2170
|
-
if (!res.ok) {
|
|
2171
|
-
const text = await res.text().catch(() => "");
|
|
2172
|
-
if (res.status === 429) {
|
|
2173
|
-
throw new OwneyError(
|
|
2174
|
-
"SWAP_RATE_LIMITED",
|
|
2175
|
-
"Swap provider is rate limiting, retry shortly",
|
|
2176
|
-
{ statusCode: res.status }
|
|
2177
|
-
);
|
|
2178
|
-
}
|
|
2179
|
-
if (res.status === 403) {
|
|
2180
|
-
throw new OwneyError(
|
|
2181
|
-
"SWAP_DISABLED",
|
|
2182
|
-
"Swap is not enabled for this organization",
|
|
2183
|
-
{ statusCode: res.status }
|
|
2184
|
-
);
|
|
2185
|
-
}
|
|
2186
|
-
throw new OwneyError(
|
|
2187
|
-
"SWAP_REQUEST_FAILED",
|
|
2188
|
-
`Swap API error ${res.status}: ${text}`,
|
|
2189
|
-
{ statusCode: res.status, responseBody: text }
|
|
2190
|
-
);
|
|
2191
|
-
}
|
|
2192
|
-
const json = await res.json();
|
|
2193
|
-
if (!json.success) {
|
|
2194
|
-
throw new OwneyError(
|
|
2195
|
-
"SWAP_REQUEST_FAILED",
|
|
2196
|
-
`Swap API request failed: ${json.message ?? "unknown error"}`,
|
|
2197
|
-
{ message: json.message }
|
|
2198
|
-
);
|
|
2199
|
-
}
|
|
2200
|
-
return json.data;
|
|
2201
|
-
}
|
|
2202
|
-
function createSwapApi(baseUrl, apiKey) {
|
|
2203
|
-
return {
|
|
2204
|
-
/** Source assets the user may pay with, and each chain's deposit targets. */
|
|
2205
|
-
listTokens: () => request(baseUrl, apiKey, "/tokens"),
|
|
2206
|
-
/**
|
|
2207
|
-
* `walletAddress` is required even though the routing API could not infer
|
|
2208
|
-
* it: the Fusion+ quoter binds a quote to whoever will sign the order and
|
|
2209
|
-
* rejects the request without it.
|
|
2210
|
-
*/
|
|
2211
|
-
quote: (params) => request(baseUrl, apiKey, "/quote", {
|
|
2212
|
-
method: "POST",
|
|
2213
|
-
body: {
|
|
2214
|
-
srcChainId: params.from.chainId,
|
|
2215
|
-
srcSymbol: params.from.symbol,
|
|
2216
|
-
dstChainId: params.to.chainId,
|
|
2217
|
-
dstSymbol: params.to.symbol,
|
|
2218
|
-
amount: params.from.amount,
|
|
2219
|
-
walletAddress: params.walletAddress
|
|
2220
|
-
}
|
|
2221
|
-
}),
|
|
2222
|
-
/** Ready-to-send calldata for a same-chain swap. */
|
|
2223
|
-
swapTx: (params) => request(baseUrl, apiKey, "/tx", {
|
|
2224
|
-
method: "POST",
|
|
2225
|
-
body: {
|
|
2226
|
-
srcChainId: params.from.chainId,
|
|
2227
|
-
srcSymbol: params.from.symbol,
|
|
2228
|
-
dstChainId: params.to.chainId,
|
|
2229
|
-
dstSymbol: params.to.symbol,
|
|
2230
|
-
amount: params.from.amount,
|
|
2231
|
-
walletAddress: params.walletAddress,
|
|
2232
|
-
slippage: params.slippage
|
|
2233
|
-
}
|
|
2234
|
-
}),
|
|
2235
|
-
/**
|
|
2236
|
-
* Builds a Fusion+ order server-side and returns EIP-712 typed data.
|
|
2237
|
-
*
|
|
2238
|
-
* Only HASHES go over the wire. The preimages never leave the browser —
|
|
2239
|
-
* see swap.secrets.
|
|
2240
|
-
*/
|
|
2241
|
-
buildOrder: (params) => request(baseUrl, apiKey, "/order/build", {
|
|
2242
|
-
method: "POST",
|
|
2243
|
-
body: {
|
|
2244
|
-
srcChainId: params.from.chainId,
|
|
2245
|
-
srcSymbol: params.from.symbol,
|
|
2246
|
-
dstChainId: params.to.chainId,
|
|
2247
|
-
dstSymbol: params.to.symbol,
|
|
2248
|
-
amount: params.from.amount,
|
|
2249
|
-
walletAddress: params.walletAddress,
|
|
2250
|
-
secretHashes: params.secretHashes,
|
|
2251
|
-
...params.receiver ? { receiver: params.receiver } : {}
|
|
2252
|
-
}
|
|
2253
|
-
}),
|
|
2254
|
-
submitOrder: (body) => request(baseUrl, apiKey, "/order", { method: "POST", body }),
|
|
2255
|
-
/**
|
|
2256
|
-
* Only call once `readyForSecrets` reports the escrow deployed. Publishing
|
|
2257
|
-
* earlier hands a resolver the preimage while the user's funds are locked
|
|
2258
|
-
* and nothing has been posted on the destination chain.
|
|
2259
|
-
*/
|
|
2260
|
-
submitSecret: (orderHash, secret) => request(baseUrl, apiKey, "/order/secret", {
|
|
2261
|
-
method: "POST",
|
|
2262
|
-
body: { orderHash, secret }
|
|
2263
|
-
}),
|
|
2264
|
-
orderStatus: (orderHash) => request(baseUrl, apiKey, `/order/${orderHash}`),
|
|
2265
|
-
readyForSecrets: (orderHash) => request(
|
|
2266
|
-
baseUrl,
|
|
2267
|
-
apiKey,
|
|
2268
|
-
`/order/${orderHash}/ready-for-secrets`
|
|
2269
|
-
)
|
|
2270
|
-
};
|
|
2271
|
-
}
|
|
2272
|
-
|
|
2273
|
-
// src/lib/swap/swap.rpc.ts
|
|
2274
|
-
var import_viem2 = require("viem");
|
|
2275
|
-
var DEFAULT_RPC_URLS = {
|
|
2276
|
-
1: ["https://cloudflare-eth.com", "https://ethereum-rpc.publicnode.com"],
|
|
2277
|
-
8453: ["https://mainnet.base.org", "https://base-rpc.publicnode.com"],
|
|
2278
|
-
42161: [
|
|
2279
|
-
"https://arb1.arbitrum.io/rpc",
|
|
2280
|
-
"https://arbitrum-one-rpc.publicnode.com"
|
|
2281
|
-
]
|
|
2282
|
-
};
|
|
2283
|
-
function swapReadTransport(chainId, overrides) {
|
|
2284
|
-
const override = overrides?.[chainId];
|
|
2285
|
-
if (override) return (0, import_viem2.http)(override);
|
|
2286
|
-
const urls = DEFAULT_RPC_URLS[chainId];
|
|
2287
|
-
if (!urls || urls.length === 0) return (0, import_viem2.http)();
|
|
2288
|
-
return (0, import_viem2.fallback)(urls.map((url) => (0, import_viem2.http)(url)));
|
|
2289
|
-
}
|
|
2290
|
-
function receiptTimeoutMs(chainId) {
|
|
2291
|
-
return chainId === 1 ? 6e5 : 18e4;
|
|
2292
|
-
}
|
|
2293
|
-
|
|
2294
|
-
// src/lib/permit2.ts
|
|
2295
|
-
var import_viem3 = require("viem");
|
|
2296
|
-
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
2297
|
-
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
2298
|
-
var ERC20_ALLOWANCE_ABI = [
|
|
2299
|
-
{
|
|
2300
|
-
type: "function",
|
|
2301
|
-
name: "allowance",
|
|
2302
|
-
stateMutability: "view",
|
|
2303
|
-
inputs: [
|
|
2304
|
-
{ name: "owner", type: "address" },
|
|
2305
|
-
{ name: "spender", type: "address" }
|
|
2306
|
-
],
|
|
2307
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
2308
|
-
},
|
|
2309
|
-
{
|
|
2310
|
-
type: "function",
|
|
2311
|
-
name: "approve",
|
|
2312
|
-
stateMutability: "nonpayable",
|
|
2313
|
-
inputs: [
|
|
2314
|
-
{ name: "spender", type: "address" },
|
|
2315
|
-
{ name: "amount", type: "uint256" }
|
|
2316
|
-
],
|
|
2317
|
-
outputs: [{ name: "", type: "bool" }]
|
|
2318
|
-
},
|
|
2319
|
-
{
|
|
2320
|
-
type: "function",
|
|
2321
|
-
name: "balanceOf",
|
|
2322
|
-
stateMutability: "view",
|
|
2323
|
-
inputs: [{ name: "account", type: "address" }],
|
|
2324
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
2325
|
-
}
|
|
2326
|
-
];
|
|
2327
|
-
function buildPermitTransferFromTypedData(input) {
|
|
2328
|
-
return {
|
|
2329
|
-
domain: {
|
|
2330
|
-
name: "Permit2",
|
|
2331
|
-
chainId: input.chainId,
|
|
2332
|
-
verifyingContract: PERMIT2_ADDRESS
|
|
2333
|
-
},
|
|
2334
|
-
types: {
|
|
2335
|
-
PermitTransferFrom: [
|
|
2336
|
-
{ name: "permitted", type: "TokenPermissions" },
|
|
2337
|
-
{ name: "spender", type: "address" },
|
|
2338
|
-
{ name: "nonce", type: "uint256" },
|
|
2339
|
-
{ name: "deadline", type: "uint256" }
|
|
2340
|
-
],
|
|
2341
|
-
TokenPermissions: [
|
|
2342
|
-
{ name: "token", type: "address" },
|
|
2343
|
-
{ name: "amount", type: "uint256" }
|
|
2344
|
-
]
|
|
2345
|
-
},
|
|
2346
|
-
primaryType: "PermitTransferFrom",
|
|
2347
|
-
message: input.message
|
|
2348
|
-
};
|
|
2349
|
-
}
|
|
2350
|
-
function randomPermit2Nonce() {
|
|
2351
|
-
const bytes = new Uint8Array(32);
|
|
2352
|
-
globalThis.crypto.getRandomValues(bytes);
|
|
2353
|
-
return BigInt((0, import_viem3.bytesToHex)(bytes));
|
|
2354
|
-
}
|
|
2355
|
-
async function readPermit2Allowance(publicClient, token, owner) {
|
|
2356
|
-
return publicClient.readContract({
|
|
2357
|
-
address: token,
|
|
2358
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
2359
|
-
functionName: "allowance",
|
|
2360
|
-
args: [owner, PERMIT2_ADDRESS]
|
|
2361
|
-
});
|
|
2362
|
-
}
|
|
2363
|
-
async function readErc20Balance(publicClient, token, owner) {
|
|
2364
|
-
return publicClient.readContract({
|
|
2365
|
-
address: token,
|
|
2366
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
2367
|
-
functionName: "balanceOf",
|
|
2368
|
-
args: [owner]
|
|
2369
|
-
});
|
|
2370
|
-
}
|
|
2371
|
-
|
|
2372
|
-
// src/lib/swap/swap.secrets.ts
|
|
2373
|
-
var import_viem4 = require("viem");
|
|
2374
|
-
var SECRET_BYTES = 32;
|
|
2375
|
-
function randomBytes(length) {
|
|
2376
|
-
const bytes = new Uint8Array(length);
|
|
2377
|
-
const cryptoObj = typeof globalThis !== "undefined" ? globalThis.crypto : void 0;
|
|
2378
|
-
if (!cryptoObj?.getRandomValues) {
|
|
2379
|
-
throw new Error(
|
|
2380
|
-
"[owney-sdk] Secure randomness is unavailable, so a swap secret cannot be generated safely."
|
|
2381
|
-
);
|
|
2382
|
-
}
|
|
2383
|
-
cryptoObj.getRandomValues(bytes);
|
|
2384
|
-
return bytes;
|
|
2385
|
-
}
|
|
2386
|
-
function mintSecrets(count) {
|
|
2387
|
-
if (!Number.isInteger(count) || count < 1) {
|
|
2388
|
-
throw new Error(
|
|
2389
|
-
`[owney-sdk] A swap needs at least one secret, got ${String(count)}.`
|
|
2390
|
-
);
|
|
2391
|
-
}
|
|
2392
|
-
const secrets = [];
|
|
2393
|
-
const secretHashes = [];
|
|
2394
|
-
for (let i = 0; i < count; i++) {
|
|
2395
|
-
const secret = (0, import_viem4.toHex)(randomBytes(SECRET_BYTES));
|
|
2396
|
-
secrets.push(secret);
|
|
2397
|
-
secretHashes.push((0, import_viem4.keccak256)(secret));
|
|
2398
|
-
}
|
|
2399
|
-
return { secrets, secretHashes };
|
|
2400
|
-
}
|
|
2401
|
-
|
|
2402
|
-
// src/lib/swap/swap.types.ts
|
|
2403
|
-
var SWAP_TERMINAL_STATUSES = [
|
|
2404
|
-
"executed",
|
|
2405
|
-
"expired",
|
|
2406
|
-
"cancelled",
|
|
2407
|
-
"refunded"
|
|
2408
|
-
];
|
|
2409
|
-
var isSwapTerminal = (status) => SWAP_TERMINAL_STATUSES.includes(status);
|
|
2410
|
-
|
|
2411
|
-
// src/lib/swap/swap.order-runner.ts
|
|
2412
|
-
var DEFAULT_POLL_MS = 5e3;
|
|
2413
|
-
var MAX_BACKOFF_MS = 3e4;
|
|
2414
|
-
var backoffFor = (failures, base3) => Math.min(base3 * 2 ** Math.min(failures, 5), MAX_BACKOFF_MS);
|
|
2415
|
-
var DEFAULT_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
2416
|
-
async function runFusionOrder(deps, options) {
|
|
2417
|
-
const {
|
|
2418
|
-
orderHash,
|
|
2419
|
-
secrets,
|
|
2420
|
-
onStage,
|
|
2421
|
-
pollIntervalMs = DEFAULT_POLL_MS,
|
|
2422
|
-
timeoutMs = DEFAULT_TIMEOUT_MS
|
|
2423
|
-
} = options;
|
|
2424
|
-
const deadline = deps.now() + timeoutMs;
|
|
2425
|
-
let failures = 0;
|
|
2426
|
-
const published = /* @__PURE__ */ new Set();
|
|
2427
|
-
onStage?.("swapping");
|
|
2428
|
-
for (; ; ) {
|
|
2429
|
-
if (deps.now() >= deadline) {
|
|
2430
|
-
throw new OwneyError(
|
|
2431
|
-
"SWAP_REQUEST_FAILED",
|
|
2432
|
-
"Timed out waiting for the swap to settle. It may still complete \u2014 check the order status before retrying.",
|
|
2433
|
-
{ orderHash }
|
|
2434
|
-
);
|
|
2435
|
-
}
|
|
2436
|
-
let ready;
|
|
2437
|
-
try {
|
|
2438
|
-
ready = await deps.readyForSecrets(orderHash);
|
|
2439
|
-
} catch {
|
|
2440
|
-
ready = {};
|
|
2441
|
-
}
|
|
2442
|
-
for (const fill of ready.fills ?? []) {
|
|
2443
|
-
if (published.has(fill.idx)) continue;
|
|
2444
|
-
const secret = secrets[fill.idx];
|
|
2445
|
-
if (secret === void 0) {
|
|
2446
|
-
throw new OwneyError(
|
|
2447
|
-
"SWAP_REQUEST_FAILED",
|
|
2448
|
-
`Swap needs a secret for fill ${fill.idx} that this session does not have. The order will refund once its timelock expires.`,
|
|
2449
|
-
{ orderHash, fillIndex: fill.idx }
|
|
2450
|
-
);
|
|
2451
|
-
}
|
|
2452
|
-
try {
|
|
2453
|
-
await deps.submitSecret(orderHash, secret);
|
|
2454
|
-
published.add(fill.idx);
|
|
2455
|
-
} catch {
|
|
2456
|
-
failures += 1;
|
|
2457
|
-
}
|
|
2458
|
-
}
|
|
2459
|
-
let status;
|
|
2460
|
-
try {
|
|
2461
|
-
({ status } = await deps.orderStatus(orderHash));
|
|
2462
|
-
failures = 0;
|
|
2463
|
-
} catch {
|
|
2464
|
-
failures += 1;
|
|
2465
|
-
await deps.sleep(backoffFor(failures, pollIntervalMs));
|
|
2466
|
-
continue;
|
|
2467
|
-
}
|
|
2468
|
-
if (status === "refunding") onStage?.("refunding");
|
|
2469
|
-
if (isSwapTerminal(status)) {
|
|
2470
|
-
if (status === "executed") {
|
|
2471
|
-
onStage?.("swapped");
|
|
2472
|
-
return { status, filled: true };
|
|
2473
|
-
}
|
|
2474
|
-
if (status === "refunded") onStage?.("refunded");
|
|
2475
|
-
throw new OwneyError(
|
|
2476
|
-
status === "refunded" ? "SWAP_ORDER_REFUNDED" : status === "cancelled" ? "SWAP_ORDER_CANCELLED" : "SWAP_ORDER_EXPIRED",
|
|
2477
|
-
status === "refunded" ? "The swap did not complete and your funds have been returned." : "The swap did not complete in time. Your funds will be returned once the timelock expires.",
|
|
2478
|
-
{ orderHash, status }
|
|
2479
|
-
);
|
|
2480
|
-
}
|
|
2481
|
-
await deps.sleep(pollIntervalMs);
|
|
2482
|
-
}
|
|
2483
|
-
}
|
|
2484
|
-
|
|
2485
|
-
// src/lib/swap/swap.secret-store.ts
|
|
2486
|
-
var KEY_PREFIX2 = "owney.swap.order";
|
|
2487
|
-
var MAX_AGE_MS = 24 * 60 * 60 * 1e3;
|
|
2488
|
-
var storage2 = () => {
|
|
2489
|
-
if (typeof window === "undefined") return null;
|
|
2490
|
-
try {
|
|
2491
|
-
return window.localStorage;
|
|
2492
|
-
} catch {
|
|
2493
|
-
return null;
|
|
2494
|
-
}
|
|
2495
|
-
};
|
|
2496
|
-
var keyFor = (orderHash) => `${KEY_PREFIX2}.${orderHash}`;
|
|
2497
|
-
function saveOrder(order) {
|
|
2498
|
-
const store = storage2();
|
|
2499
|
-
if (!store) return;
|
|
2500
|
-
try {
|
|
2501
|
-
store.setItem(keyFor(order.orderHash), JSON.stringify(order));
|
|
2502
|
-
} catch {
|
|
2503
|
-
}
|
|
2504
|
-
}
|
|
2505
|
-
function clearOrder(orderHash) {
|
|
2506
|
-
const store = storage2();
|
|
2507
|
-
if (!store) return;
|
|
2508
|
-
try {
|
|
2509
|
-
store.removeItem(keyFor(orderHash));
|
|
2510
|
-
} catch {
|
|
2511
|
-
}
|
|
2512
|
-
}
|
|
2513
|
-
function listOrders(now = Date.now()) {
|
|
2514
|
-
const store = storage2();
|
|
2515
|
-
if (!store) return [];
|
|
2516
|
-
const out = [];
|
|
2517
|
-
try {
|
|
2518
|
-
const keys = [];
|
|
2519
|
-
for (let i = 0; i < store.length; i++) {
|
|
2520
|
-
const key2 = store.key(i);
|
|
2521
|
-
if (key2?.startsWith(`${KEY_PREFIX2}.`)) keys.push(key2);
|
|
2522
|
-
}
|
|
2523
|
-
for (const key2 of keys) {
|
|
2524
|
-
const raw = store.getItem(key2);
|
|
2525
|
-
if (!raw) continue;
|
|
2526
|
-
try {
|
|
2527
|
-
const parsed = JSON.parse(raw);
|
|
2528
|
-
if (now - parsed.createdAt > MAX_AGE_MS) {
|
|
2529
|
-
store.removeItem(key2);
|
|
2530
|
-
continue;
|
|
2531
|
-
}
|
|
2532
|
-
if (Array.isArray(parsed.secrets) && parsed.secrets.length > 0) {
|
|
2533
|
-
out.push(parsed);
|
|
2534
|
-
}
|
|
2535
|
-
} catch {
|
|
2536
|
-
store.removeItem(key2);
|
|
2537
|
-
}
|
|
2538
|
-
}
|
|
2539
|
-
} catch {
|
|
2540
|
-
return out;
|
|
2541
|
-
}
|
|
2542
|
-
return out.sort((a, b) => b.createdAt - a.createdAt);
|
|
2543
|
-
}
|
|
2544
|
-
|
|
2545
|
-
// src/lib/swap/swap.executor.ts
|
|
2546
|
-
var DEFAULT_SLIPPAGE = 1;
|
|
2547
|
-
async function affordableAmount(deps, quoted) {
|
|
2548
|
-
const balance = await deps.readSourceBalance();
|
|
2549
|
-
if (balance >= quoted) return quoted;
|
|
2550
|
-
debugLog("owney-sdk", "swap: trimming to the current source balance", {
|
|
2551
|
-
quoted: quoted.toString(),
|
|
2552
|
-
balance: balance.toString(),
|
|
2553
|
-
short: (quoted - balance).toString()
|
|
2554
|
-
});
|
|
2555
|
-
return balance;
|
|
2556
|
-
}
|
|
2557
|
-
async function executeSwap(deps, options) {
|
|
2558
|
-
const { quote, walletAddress, onStage } = options;
|
|
2559
|
-
debugLog("owney-sdk", "swap: start", {
|
|
2560
|
-
rail: quote.rail,
|
|
2561
|
-
from: `${quote.src.amount} ${quote.src.symbol} on ${quote.src.chainId}`,
|
|
2562
|
-
to: `${quote.dst.symbol} on ${quote.dst.chainId}`,
|
|
2563
|
-
expected: quote.dst.amount,
|
|
2564
|
-
floor: quote.dstAmountMin
|
|
2565
|
-
});
|
|
2566
|
-
const before = await deps.readTargetBalance();
|
|
2567
|
-
debugLog("owney-sdk", "swap: target balance before", before.toString());
|
|
2568
|
-
const result = quote.rail === "classic" ? await runClassic(deps, options) : await runFusion(deps, options, walletAddress);
|
|
2569
|
-
const after = await deps.readTargetBalance();
|
|
2570
|
-
const received = after - before;
|
|
2571
|
-
debugLog("owney-sdk", "swap: target balance after", {
|
|
2572
|
-
after: after.toString(),
|
|
2573
|
-
received: received.toString()
|
|
2574
|
-
});
|
|
2575
|
-
if (received <= 0n) {
|
|
2576
|
-
throw new OwneyError(
|
|
2577
|
-
"SWAP_REQUEST_FAILED",
|
|
2578
|
-
"The swap completed but no funds arrived in the wallet. Check the transaction before retrying.",
|
|
2579
|
-
{ rail: quote.rail, ...result }
|
|
2580
|
-
);
|
|
2581
|
-
}
|
|
2582
|
-
return { received: received.toString(), ...result };
|
|
2583
|
-
}
|
|
2584
|
-
async function runClassic(deps, options) {
|
|
2585
|
-
const {
|
|
2586
|
-
quote,
|
|
2587
|
-
walletAddress,
|
|
2588
|
-
slippage = DEFAULT_SLIPPAGE,
|
|
2589
|
-
onStage
|
|
2590
|
-
} = options;
|
|
2591
|
-
const isNativeSource = quote.src.address.toLowerCase().startsWith("0xeeee");
|
|
2592
|
-
const amount = isNativeSource ? BigInt(quote.src.amount) : await affordableAmount(deps, BigInt(quote.src.amount));
|
|
2593
|
-
onStage?.("quoting");
|
|
2594
|
-
debugLog("owney-sdk", "swap: fetching classic calldata");
|
|
2595
|
-
const { tx } = await deps.api.swapTx({
|
|
2596
|
-
from: {
|
|
2597
|
-
chainId: quote.src.chainId,
|
|
2598
|
-
symbol: quote.src.symbol,
|
|
2599
|
-
amount: amount.toString()
|
|
2600
|
-
},
|
|
2601
|
-
to: { chainId: quote.dst.chainId, symbol: quote.dst.symbol },
|
|
2602
|
-
walletAddress,
|
|
2603
|
-
slippage
|
|
2604
|
-
});
|
|
2605
|
-
const isNative = BigInt(tx.value ?? "0") > 0n;
|
|
2606
|
-
if (!isNative) {
|
|
2607
|
-
const needed = amount;
|
|
2608
|
-
const current = await deps.readAllowance(tx.to);
|
|
2609
|
-
debugLog("owney-sdk", "swap: allowance", {
|
|
2610
|
-
spender: tx.to,
|
|
2611
|
-
current: current.toString(),
|
|
2612
|
-
needed: needed.toString()
|
|
2613
|
-
});
|
|
2614
|
-
if (current < needed) {
|
|
2615
|
-
onStage?.("approving");
|
|
2616
|
-
await deps.ensureChain(quote.src.chainId);
|
|
2617
|
-
await deps.approve(tx.to, MAX_UINT256);
|
|
2618
|
-
}
|
|
2619
|
-
}
|
|
2620
|
-
onStage?.("signing");
|
|
2621
|
-
await deps.ensureChain(quote.src.chainId);
|
|
2622
|
-
debugLog("owney-sdk", "swap: sending classic swap tx", { to: tx.to });
|
|
2623
|
-
const txHash = await deps.sendTransaction({
|
|
2624
|
-
to: tx.to,
|
|
2625
|
-
data: tx.data,
|
|
2626
|
-
value: tx.value ?? "0"
|
|
2627
|
-
});
|
|
2628
|
-
onStage?.("swapped");
|
|
2629
|
-
return { txHash };
|
|
2630
|
-
}
|
|
2631
|
-
async function runFusion(deps, options, walletAddress) {
|
|
2632
|
-
const { quote, onStage } = options;
|
|
2633
|
-
const isNativeSource = quote.src.address.toLowerCase().startsWith("0xeeee");
|
|
2634
|
-
const amount = isNativeSource ? BigInt(quote.src.amount) : await affordableAmount(deps, BigInt(quote.src.amount));
|
|
2635
|
-
if (quote.spender && !isNativeSource) {
|
|
2636
|
-
const needed = amount;
|
|
2637
|
-
const current = await deps.readAllowance(quote.spender);
|
|
2638
|
-
debugLog("owney-sdk", "swap: fusion allowance", {
|
|
2639
|
-
spender: quote.spender,
|
|
2640
|
-
current: current.toString(),
|
|
2641
|
-
needed: needed.toString()
|
|
2642
|
-
});
|
|
2643
|
-
if (current < needed) {
|
|
2644
|
-
onStage?.("approving");
|
|
2645
|
-
await deps.ensureChain(quote.src.chainId);
|
|
2646
|
-
await deps.approve(quote.spender, MAX_UINT256);
|
|
2647
|
-
debugLog("owney-sdk", "swap: approved limit order protocol");
|
|
2648
|
-
}
|
|
2649
|
-
}
|
|
2650
|
-
const { secrets, secretHashes } = mintSecrets(quote.secretsCount ?? 1);
|
|
2651
|
-
onStage?.("quoting");
|
|
2652
|
-
debugLog("owney-sdk", "swap: building fusion order", {
|
|
2653
|
-
secrets: secretHashes.length
|
|
2654
|
-
});
|
|
2655
|
-
const built = await deps.api.buildOrder({
|
|
2656
|
-
from: {
|
|
2657
|
-
chainId: quote.src.chainId,
|
|
2658
|
-
symbol: quote.src.symbol,
|
|
2659
|
-
// The trimmed amount — the order is re-quoted at this size server-side.
|
|
2660
|
-
amount: amount.toString()
|
|
2661
|
-
},
|
|
2662
|
-
to: { chainId: quote.dst.chainId, symbol: quote.dst.symbol },
|
|
2663
|
-
walletAddress,
|
|
2664
|
-
secretHashes
|
|
2665
|
-
});
|
|
2666
|
-
saveOrder({
|
|
2667
|
-
orderHash: built.orderHash,
|
|
2668
|
-
secrets,
|
|
2669
|
-
srcChainId: quote.src.chainId,
|
|
2670
|
-
srcSymbol: quote.src.symbol,
|
|
2671
|
-
dstChainId: quote.dst.chainId,
|
|
2672
|
-
dstSymbol: quote.dst.symbol,
|
|
2673
|
-
amount: amount.toString(),
|
|
2674
|
-
createdAt: Date.now()
|
|
2675
|
-
});
|
|
2676
|
-
debugLog("owney-sdk", "swap: order built", { orderHash: built.orderHash });
|
|
2677
|
-
onStage?.("signing");
|
|
2678
|
-
await deps.ensureChain(quote.src.chainId);
|
|
2679
|
-
debugLog("owney-sdk", "swap: awaiting signature in wallet", {
|
|
2680
|
-
signingOnChain: quote.src.chainId
|
|
2681
|
-
});
|
|
2682
|
-
const signature = await deps.signTypedData(built.typedData);
|
|
2683
|
-
debugLog("owney-sdk", "swap: signed, submitting to relayer");
|
|
2684
|
-
await deps.api.submitOrder({
|
|
2685
|
-
srcChainId: quote.src.chainId,
|
|
2686
|
-
// The ORDER STRUCT, not the typed-data envelope we just signed. Sending
|
|
2687
|
-
// the envelope here gets a bare 500 from the relayer.
|
|
2688
|
-
order: built.order,
|
|
2689
|
-
signature,
|
|
2690
|
-
quoteId: built.quoteId,
|
|
2691
|
-
// Single-fill orders must NOT carry secretHashes — the relayer rejects
|
|
2692
|
-
// them with SECRET_HASHES_NOT_REQUIRED. The one hash is already inside the
|
|
2693
|
-
// order's hashlock, so repeating it here is redundant, and only a
|
|
2694
|
-
// multi-fill order (a Merkle tree of hashes) needs them listed.
|
|
2695
|
-
...secretHashes.length > 1 ? { secretHashes } : {},
|
|
2696
|
-
...built.extension ? { extension: built.extension } : {}
|
|
2697
|
-
});
|
|
2698
|
-
debugLog("owney-sdk", "swap: order submitted, polling escrows");
|
|
2699
|
-
try {
|
|
2700
|
-
await runFusionOrder(deps.runner, {
|
|
2701
|
-
orderHash: built.orderHash,
|
|
2702
|
-
secrets,
|
|
2703
|
-
...onStage ? { onStage } : {}
|
|
2704
|
-
});
|
|
2705
|
-
} catch (error) {
|
|
2706
|
-
if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED")) {
|
|
2707
|
-
clearOrder(built.orderHash);
|
|
2708
|
-
}
|
|
2709
|
-
throw error;
|
|
2710
|
-
}
|
|
2711
|
-
clearOrder(built.orderHash);
|
|
2712
|
-
return { orderHash: built.orderHash };
|
|
2713
|
-
}
|
|
2714
|
-
|
|
2715
2190
|
// src/lib/health-report.ts
|
|
2716
2191
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
2717
2192
|
async function reportAgentFailure(apiKey, agentType, errorCode, baseUrl = ROUTING_API_BASE_URL2) {
|
|
@@ -2746,7 +2221,7 @@ async function withFailureReporting(apiKey, agentType, fn, baseUrl) {
|
|
|
2746
2221
|
}
|
|
2747
2222
|
|
|
2748
2223
|
// src/lib/helpers/withdraw-helper.ts
|
|
2749
|
-
var
|
|
2224
|
+
var import_viem2 = require("viem");
|
|
2750
2225
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
2751
2226
|
const target = asset.toUpperCase();
|
|
2752
2227
|
return agents.map((agent) => {
|
|
@@ -2755,7 +2230,7 @@ function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decima
|
|
|
2755
2230
|
(t) => t.chainId === chainId && t.asset.toUpperCase() === target
|
|
2756
2231
|
);
|
|
2757
2232
|
if (!tokenBalance) return { agent, balance: 0n };
|
|
2758
|
-
return { agent, balance: (0,
|
|
2233
|
+
return { agent, balance: (0, import_viem2.parseUnits)(tokenBalance.amount, decimals) };
|
|
2759
2234
|
});
|
|
2760
2235
|
}
|
|
2761
2236
|
function planProportionalShares(balances, requested, totalAvailable) {
|
|
@@ -2902,11 +2377,11 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
2902
2377
|
}
|
|
2903
2378
|
|
|
2904
2379
|
// src/client.ts
|
|
2905
|
-
var
|
|
2380
|
+
var import_viem6 = require("viem");
|
|
2906
2381
|
var import_chains2 = require("viem/chains");
|
|
2907
2382
|
|
|
2908
2383
|
// src/lib/transfer-auth.ts
|
|
2909
|
-
var
|
|
2384
|
+
var import_viem3 = require("viem");
|
|
2910
2385
|
var ERC20_META_ABI = [
|
|
2911
2386
|
{ type: "function", name: "name", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "string" }] },
|
|
2912
2387
|
{ type: "function", name: "version", stateMutability: "view", inputs: [], outputs: [{ name: "", type: "string" }] }
|
|
@@ -2938,7 +2413,7 @@ async function readTokenMeta(publicClient, token) {
|
|
|
2938
2413
|
function randomAuthNonce() {
|
|
2939
2414
|
const bytes = new Uint8Array(32);
|
|
2940
2415
|
globalThis.crypto.getRandomValues(bytes);
|
|
2941
|
-
return (0,
|
|
2416
|
+
return (0, import_viem3.bytesToHex)(bytes);
|
|
2942
2417
|
}
|
|
2943
2418
|
|
|
2944
2419
|
// src/lib/sponsor-client.ts
|
|
@@ -3058,6 +2533,119 @@ async function getSponsorRelayerAddress(input) {
|
|
|
3058
2533
|
return parsed.data.relayer;
|
|
3059
2534
|
}
|
|
3060
2535
|
|
|
2536
|
+
// src/lib/permit2.ts
|
|
2537
|
+
var import_viem4 = require("viem");
|
|
2538
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
2539
|
+
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
2540
|
+
var ERC20_ALLOWANCE_ABI = [
|
|
2541
|
+
{
|
|
2542
|
+
type: "function",
|
|
2543
|
+
name: "allowance",
|
|
2544
|
+
stateMutability: "view",
|
|
2545
|
+
inputs: [
|
|
2546
|
+
{ name: "owner", type: "address" },
|
|
2547
|
+
{ name: "spender", type: "address" }
|
|
2548
|
+
],
|
|
2549
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
2550
|
+
},
|
|
2551
|
+
{
|
|
2552
|
+
type: "function",
|
|
2553
|
+
name: "approve",
|
|
2554
|
+
stateMutability: "nonpayable",
|
|
2555
|
+
inputs: [
|
|
2556
|
+
{ name: "spender", type: "address" },
|
|
2557
|
+
{ name: "amount", type: "uint256" }
|
|
2558
|
+
],
|
|
2559
|
+
outputs: [{ name: "", type: "bool" }]
|
|
2560
|
+
},
|
|
2561
|
+
{
|
|
2562
|
+
type: "function",
|
|
2563
|
+
name: "balanceOf",
|
|
2564
|
+
stateMutability: "view",
|
|
2565
|
+
inputs: [{ name: "account", type: "address" }],
|
|
2566
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
2567
|
+
}
|
|
2568
|
+
];
|
|
2569
|
+
function buildPermitTransferFromTypedData(input) {
|
|
2570
|
+
return {
|
|
2571
|
+
domain: {
|
|
2572
|
+
name: "Permit2",
|
|
2573
|
+
chainId: input.chainId,
|
|
2574
|
+
verifyingContract: PERMIT2_ADDRESS
|
|
2575
|
+
},
|
|
2576
|
+
types: {
|
|
2577
|
+
PermitTransferFrom: [
|
|
2578
|
+
{ name: "permitted", type: "TokenPermissions" },
|
|
2579
|
+
{ name: "spender", type: "address" },
|
|
2580
|
+
{ name: "nonce", type: "uint256" },
|
|
2581
|
+
{ name: "deadline", type: "uint256" }
|
|
2582
|
+
],
|
|
2583
|
+
TokenPermissions: [
|
|
2584
|
+
{ name: "token", type: "address" },
|
|
2585
|
+
{ name: "amount", type: "uint256" }
|
|
2586
|
+
]
|
|
2587
|
+
},
|
|
2588
|
+
primaryType: "PermitTransferFrom",
|
|
2589
|
+
message: input.message
|
|
2590
|
+
};
|
|
2591
|
+
}
|
|
2592
|
+
function randomPermit2Nonce() {
|
|
2593
|
+
const bytes = new Uint8Array(32);
|
|
2594
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
2595
|
+
return BigInt((0, import_viem4.bytesToHex)(bytes));
|
|
2596
|
+
}
|
|
2597
|
+
async function readPermit2Allowance(publicClient, token, owner) {
|
|
2598
|
+
return publicClient.readContract({
|
|
2599
|
+
address: token,
|
|
2600
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
2601
|
+
functionName: "allowance",
|
|
2602
|
+
args: [owner, PERMIT2_ADDRESS]
|
|
2603
|
+
});
|
|
2604
|
+
}
|
|
2605
|
+
async function readErc20Balance(publicClient, token, owner) {
|
|
2606
|
+
return publicClient.readContract({
|
|
2607
|
+
address: token,
|
|
2608
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
2609
|
+
functionName: "balanceOf",
|
|
2610
|
+
args: [owner]
|
|
2611
|
+
});
|
|
2612
|
+
}
|
|
2613
|
+
|
|
2614
|
+
// src/lib/chain-guard.ts
|
|
2615
|
+
var CHAIN_NAMES = {
|
|
2616
|
+
1: "Ethereum",
|
|
2617
|
+
8453: "Base",
|
|
2618
|
+
42161: "Arbitrum"
|
|
2619
|
+
};
|
|
2620
|
+
function chainName(chainId) {
|
|
2621
|
+
return CHAIN_NAMES[chainId] ?? `chain ${chainId}`;
|
|
2622
|
+
}
|
|
2623
|
+
async function ensureWalletOnChain(pub, wallet, expected) {
|
|
2624
|
+
const actual = await pub.getChainId();
|
|
2625
|
+
if (actual === expected) return;
|
|
2626
|
+
try {
|
|
2627
|
+
await wallet.switchChain({ id: expected });
|
|
2628
|
+
} catch (error) {
|
|
2629
|
+
throw new OwneyError(
|
|
2630
|
+
"CHAIN_MISMATCH",
|
|
2631
|
+
`Your wallet is on ${chainName(actual)}. Switch it to ${chainName(expected)} and try again.`,
|
|
2632
|
+
{
|
|
2633
|
+
expectedChainId: expected,
|
|
2634
|
+
actualChainId: actual,
|
|
2635
|
+
cause: error instanceof Error ? error.message : String(error)
|
|
2636
|
+
}
|
|
2637
|
+
);
|
|
2638
|
+
}
|
|
2639
|
+
const after = await pub.getChainId();
|
|
2640
|
+
if (after !== expected) {
|
|
2641
|
+
throw new OwneyError(
|
|
2642
|
+
"CHAIN_MISMATCH",
|
|
2643
|
+
`Your wallet is still on ${chainName(after)}. Switch it to ${chainName(expected)} and try again.`,
|
|
2644
|
+
{ expectedChainId: expected, actualChainId: after }
|
|
2645
|
+
);
|
|
2646
|
+
}
|
|
2647
|
+
}
|
|
2648
|
+
|
|
3061
2649
|
// src/lib/sponsored-deposit.ts
|
|
3062
2650
|
var AUTH_WINDOW_SECONDS = 15 * 60;
|
|
3063
2651
|
function makeSponsoredDepositCallback(deps) {
|
|
@@ -3220,7 +2808,7 @@ function makeSponsoredWethCallback(deps) {
|
|
|
3220
2808
|
}
|
|
3221
2809
|
|
|
3222
2810
|
// src/lib/sponsored-calls-deposit.ts
|
|
3223
|
-
var
|
|
2811
|
+
var import_viem5 = require("viem");
|
|
3224
2812
|
var DEFAULT_POLL_INTERVAL_MS = 1500;
|
|
3225
2813
|
var DEFAULT_MAX_POLLS = 30;
|
|
3226
2814
|
async function paymasterSupported(provider, owner, chainId) {
|
|
@@ -3228,7 +2816,7 @@ async function paymasterSupported(provider, owner, chainId) {
|
|
|
3228
2816
|
method: "wallet_getCapabilities",
|
|
3229
2817
|
params: [owner]
|
|
3230
2818
|
});
|
|
3231
|
-
const forChain = caps?.[(0,
|
|
2819
|
+
const forChain = caps?.[(0, import_viem5.toHex)(chainId)] ?? caps?.[String(chainId)];
|
|
3232
2820
|
return Boolean(forChain?.paymasterService?.supported);
|
|
3233
2821
|
}
|
|
3234
2822
|
function makeSponsoredCallsCallback(deps) {
|
|
@@ -3262,8 +2850,8 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
3262
2850
|
{ chainId }
|
|
3263
2851
|
);
|
|
3264
2852
|
}
|
|
3265
|
-
const data = (0,
|
|
3266
|
-
abi:
|
|
2853
|
+
const data = (0, import_viem5.encodeFunctionData)({
|
|
2854
|
+
abi: import_viem5.erc20Abi,
|
|
3267
2855
|
functionName: "transfer",
|
|
3268
2856
|
args: [smartWallet, BigInt(amount)]
|
|
3269
2857
|
});
|
|
@@ -3273,7 +2861,7 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
3273
2861
|
{
|
|
3274
2862
|
version: "2.0.0",
|
|
3275
2863
|
from: deps.ownerAddress,
|
|
3276
|
-
chainId: (0,
|
|
2864
|
+
chainId: (0, import_viem5.toHex)(chainId),
|
|
3277
2865
|
atomicRequired: false,
|
|
3278
2866
|
calls: [{ to: token, value: "0x0", data }],
|
|
3279
2867
|
capabilities: {
|
|
@@ -3495,14 +3083,14 @@ var OwneySDK = class {
|
|
|
3495
3083
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
3496
3084
|
// PublicClient/WalletClient param types — structurally identical at
|
|
3497
3085
|
// runtime, but the two share a name TS treats as unrelated.
|
|
3498
|
-
getPublicClient: (cid) => (0,
|
|
3086
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
3499
3087
|
chain: VIEM_CHAIN2[cid],
|
|
3500
|
-
transport: (0,
|
|
3088
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3501
3089
|
}),
|
|
3502
|
-
getWalletClient: (cid) => (0,
|
|
3090
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
3503
3091
|
account: owner,
|
|
3504
3092
|
chain: VIEM_CHAIN2[cid],
|
|
3505
|
-
transport: (0,
|
|
3093
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3506
3094
|
})
|
|
3507
3095
|
});
|
|
3508
3096
|
if (!onApproved) this.cachedSponsoredCallback = callback;
|
|
@@ -3548,14 +3136,14 @@ var OwneySDK = class {
|
|
|
3548
3136
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
3549
3137
|
// PublicClient/WalletClient param types — structurally identical at
|
|
3550
3138
|
// runtime, but the two share a name TS treats as unrelated.
|
|
3551
|
-
getPublicClient: (cid) => (0,
|
|
3139
|
+
getPublicClient: (cid) => (0, import_viem6.createPublicClient)({
|
|
3552
3140
|
chain: VIEM_CHAIN2[cid],
|
|
3553
|
-
transport: (0,
|
|
3141
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3554
3142
|
}),
|
|
3555
|
-
getWalletClient: (cid) => (0,
|
|
3143
|
+
getWalletClient: (cid) => (0, import_viem6.createWalletClient)({
|
|
3556
3144
|
account: owner,
|
|
3557
3145
|
chain: VIEM_CHAIN2[cid],
|
|
3558
|
-
transport: (0,
|
|
3146
|
+
transport: (0, import_viem6.custom)(provider)
|
|
3559
3147
|
})
|
|
3560
3148
|
});
|
|
3561
3149
|
if (!onApproved) this.cachedWethSponsoredCallback = callback;
|
|
@@ -4110,211 +3698,6 @@ var OwneySDK = class {
|
|
|
4110
3698
|
return eligible;
|
|
4111
3699
|
}
|
|
4112
3700
|
// --- Fund operations ---
|
|
4113
|
-
// --- Swap to yield (ROUT-242) ---
|
|
4114
|
-
/** Lazily built so an app that never swaps pays nothing for it. */
|
|
4115
|
-
swapApiClient;
|
|
4116
|
-
swapApi() {
|
|
4117
|
-
this.swapApiClient ??= createSwapApi(
|
|
4118
|
-
this.routingApiBaseUrl ?? ROUTING_API_BASE_URL,
|
|
4119
|
-
this.apiKey
|
|
4120
|
-
);
|
|
4121
|
-
return this.swapApiClient;
|
|
4122
|
-
}
|
|
4123
|
-
/**
|
|
4124
|
-
* Put the wallet on `chainId`, or fail with something actionable.
|
|
4125
|
-
*
|
|
4126
|
-
* Reuses the same guard the deposit rail uses, which re-reads the chain after
|
|
4127
|
-
* switching — some wallets resolve wallet_switchEthereumChain before the
|
|
4128
|
-
* network has actually changed.
|
|
4129
|
-
*/
|
|
4130
|
-
async ensureSwapChain(chainId) {
|
|
4131
|
-
const provider = this.requireConnectedProvider();
|
|
4132
|
-
const state = this.requireState();
|
|
4133
|
-
const chain = VIEM_CHAIN2[chainId];
|
|
4134
|
-
if (!chain) {
|
|
4135
|
-
throw new OwneyError(
|
|
4136
|
-
"CHAIN_UNSUPPORTED",
|
|
4137
|
-
`Chain ${chainId} is not supported`,
|
|
4138
|
-
{ chainId }
|
|
4139
|
-
);
|
|
4140
|
-
}
|
|
4141
|
-
await ensureWalletOnChain(
|
|
4142
|
-
(0, import_viem8.createPublicClient)({ chain, transport: (0, import_viem8.custom)(provider) }),
|
|
4143
|
-
(0, import_viem8.createWalletClient)({
|
|
4144
|
-
account: state.walletAddress,
|
|
4145
|
-
chain,
|
|
4146
|
-
transport: (0, import_viem8.custom)(provider)
|
|
4147
|
-
}),
|
|
4148
|
-
chainId
|
|
4149
|
-
);
|
|
4150
|
-
}
|
|
4151
|
-
/**
|
|
4152
|
-
* Binds the executor's abstract deps to this client's wallet.
|
|
4153
|
-
*
|
|
4154
|
-
* Kept as a builder rather than baked into the executor so the whole swap
|
|
4155
|
-
* flow stays testable without a provider — the executor never imports viem.
|
|
4156
|
-
*/
|
|
4157
|
-
buildSwapDeps(quote) {
|
|
4158
|
-
const state = this.requireState();
|
|
4159
|
-
const provider = this.requireConnectedProvider();
|
|
4160
|
-
const srcChain = VIEM_CHAIN2[quote.src.chainId];
|
|
4161
|
-
const dstChain = VIEM_CHAIN2[quote.dst.chainId];
|
|
4162
|
-
const wallet = (0, import_viem8.createWalletClient)({
|
|
4163
|
-
account: state.walletAddress,
|
|
4164
|
-
chain: srcChain,
|
|
4165
|
-
transport: (0, import_viem8.custom)(provider)
|
|
4166
|
-
});
|
|
4167
|
-
const srcPublic = (0, import_viem8.createPublicClient)({
|
|
4168
|
-
chain: srcChain,
|
|
4169
|
-
transport: swapReadTransport(quote.src.chainId, this.zyfaiRpcUrls)
|
|
4170
|
-
});
|
|
4171
|
-
const dstPublic = (0, import_viem8.createPublicClient)({
|
|
4172
|
-
chain: dstChain,
|
|
4173
|
-
transport: swapReadTransport(quote.dst.chainId, this.zyfaiRpcUrls)
|
|
4174
|
-
});
|
|
4175
|
-
return {
|
|
4176
|
-
api: this.swapApi(),
|
|
4177
|
-
readTargetBalance: () => dstPublic.readContract({
|
|
4178
|
-
address: quote.dst.address,
|
|
4179
|
-
abi: import_viem8.erc20Abi,
|
|
4180
|
-
functionName: "balanceOf",
|
|
4181
|
-
args: [state.walletAddress]
|
|
4182
|
-
}),
|
|
4183
|
-
sendTransaction: async (tx) => {
|
|
4184
|
-
const hash = await wallet.sendTransaction({
|
|
4185
|
-
to: tx.to,
|
|
4186
|
-
data: tx.data,
|
|
4187
|
-
value: BigInt(tx.value || "0"),
|
|
4188
|
-
account: state.walletAddress,
|
|
4189
|
-
chain: srcChain
|
|
4190
|
-
});
|
|
4191
|
-
const receipt = await srcPublic.waitForTransactionReceipt({
|
|
4192
|
-
timeout: receiptTimeoutMs(quote.src.chainId),
|
|
4193
|
-
hash,
|
|
4194
|
-
confirmations: 1
|
|
4195
|
-
});
|
|
4196
|
-
if (receipt.status !== "success") {
|
|
4197
|
-
throw new OwneyError(
|
|
4198
|
-
"SWAP_REQUEST_FAILED",
|
|
4199
|
-
`Swap transaction reverted (tx ${hash})`,
|
|
4200
|
-
{ hash }
|
|
4201
|
-
);
|
|
4202
|
-
}
|
|
4203
|
-
return hash;
|
|
4204
|
-
},
|
|
4205
|
-
signTypedData: (typedData) => wallet.signTypedData({
|
|
4206
|
-
account: state.walletAddress,
|
|
4207
|
-
...typedData
|
|
4208
|
-
}),
|
|
4209
|
-
// Chain-bound like every other read here: the wallet provider's chain is
|
|
4210
|
-
// not ours to rely on mid-swap.
|
|
4211
|
-
readSourceBalance: async () => {
|
|
4212
|
-
const src = quote.src.address;
|
|
4213
|
-
if (src.toLowerCase().startsWith("0xeeee")) {
|
|
4214
|
-
return srcPublic.getBalance({ address: state.walletAddress });
|
|
4215
|
-
}
|
|
4216
|
-
return srcPublic.readContract({
|
|
4217
|
-
address: src,
|
|
4218
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
4219
|
-
functionName: "balanceOf",
|
|
4220
|
-
args: [state.walletAddress]
|
|
4221
|
-
});
|
|
4222
|
-
},
|
|
4223
|
-
readAllowance: (spender) => srcPublic.readContract({
|
|
4224
|
-
address: quote.src.address,
|
|
4225
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
4226
|
-
functionName: "allowance",
|
|
4227
|
-
args: [state.walletAddress, spender]
|
|
4228
|
-
}),
|
|
4229
|
-
approve: async (spender, amount) => {
|
|
4230
|
-
const hash = await wallet.writeContract({
|
|
4231
|
-
address: quote.src.address,
|
|
4232
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
4233
|
-
functionName: "approve",
|
|
4234
|
-
args: [spender, amount],
|
|
4235
|
-
account: state.walletAddress,
|
|
4236
|
-
chain: srcChain
|
|
4237
|
-
});
|
|
4238
|
-
await srcPublic.waitForTransactionReceipt({
|
|
4239
|
-
hash,
|
|
4240
|
-
confirmations: 1,
|
|
4241
|
-
timeout: receiptTimeoutMs(quote.src.chainId)
|
|
4242
|
-
});
|
|
4243
|
-
return hash;
|
|
4244
|
-
},
|
|
4245
|
-
ensureChain: (chainId) => this.ensureSwapChain(chainId),
|
|
4246
|
-
runner: {
|
|
4247
|
-
readyForSecrets: (h) => this.swapApi().readyForSecrets(h),
|
|
4248
|
-
submitSecret: (h, secret) => this.swapApi().submitSecret(h, secret),
|
|
4249
|
-
orderStatus: (h) => this.swapApi().orderStatus(h),
|
|
4250
|
-
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
4251
|
-
now: () => Date.now()
|
|
4252
|
-
}
|
|
4253
|
-
};
|
|
4254
|
-
}
|
|
4255
|
-
/**
|
|
4256
|
-
* Assets the user may pay with, and what each chain deposits into.
|
|
4257
|
-
*
|
|
4258
|
-
* The source list is deliberately wider than the deposit list: it includes
|
|
4259
|
-
* native ETH and USDT, which Owney never holds but users often do.
|
|
4260
|
-
*/
|
|
4261
|
-
async getSwapTokens() {
|
|
4262
|
-
return this.swapApi().listTokens();
|
|
4263
|
-
}
|
|
4264
|
-
/**
|
|
4265
|
-
* Price a swap without committing to it.
|
|
4266
|
-
*
|
|
4267
|
-
* `dstAmountMin` is the number to validate against a deposit minimum —
|
|
4268
|
-
* `dst.amount` is an estimate that a decaying auction or slippage can undercut,
|
|
4269
|
-
* and a swap landing below the floor leaves the user swapped but not
|
|
4270
|
-
* deposited.
|
|
4271
|
-
*/
|
|
4272
|
-
async getSwapQuote(params) {
|
|
4273
|
-
const state = this.requireState();
|
|
4274
|
-
return this.swapApi().quote({ ...params, walletAddress: state.walletAddress });
|
|
4275
|
-
}
|
|
4276
|
-
/**
|
|
4277
|
-
* Swap an asset the user holds into a deposit asset, then deposit it.
|
|
4278
|
-
*
|
|
4279
|
-
* Kept separate from `deposit()` rather than bolted on as an option: the
|
|
4280
|
-
* return shape differs, the staging callback is meaningless on the plain
|
|
4281
|
-
* path, and integrators who never swap should not have to reason about any
|
|
4282
|
-
* of it.
|
|
4283
|
-
*
|
|
4284
|
-
* The deposit runs on the MEASURED arrival, not the quote. A quote is an
|
|
4285
|
-
* estimate, so depositing the quoted figure would either strand dust or try
|
|
4286
|
-
* to move funds that never came.
|
|
4287
|
-
*
|
|
4288
|
-
* Failure modes differ in a way callers must respect. A same-chain swap is
|
|
4289
|
-
* atomic — if it fails, nothing moved. A cross-chain swap escrows the user's
|
|
4290
|
-
* funds first, so SWAP_ORDER_EXPIRED / REFUNDED / CANCELLED all mean the
|
|
4291
|
-
* money left the wallet. Only the former can honestly say "nothing has left
|
|
4292
|
-
* your wallet".
|
|
4293
|
-
*/
|
|
4294
|
-
async swapAndDeposit(options) {
|
|
4295
|
-
const state = this.requireState();
|
|
4296
|
-
const api = this.swapApi();
|
|
4297
|
-
const quote = await api.quote({
|
|
4298
|
-
from: options.from,
|
|
4299
|
-
to: options.to,
|
|
4300
|
-
walletAddress: state.walletAddress
|
|
4301
|
-
});
|
|
4302
|
-
await this.ensureSwapChain(quote.src.chainId);
|
|
4303
|
-
const swap = await executeSwap(this.buildSwapDeps(quote), {
|
|
4304
|
-
quote,
|
|
4305
|
-
walletAddress: state.walletAddress,
|
|
4306
|
-
...options.slippage === void 0 ? {} : { slippage: options.slippage },
|
|
4307
|
-
...options.onSwapProgress ? { onStage: options.onSwapProgress } : {}
|
|
4308
|
-
});
|
|
4309
|
-
options.onSwapProgress?.("depositing");
|
|
4310
|
-
await this.ensureSwapChain(quote.dst.chainId);
|
|
4311
|
-
const deposit = await this.deposit({
|
|
4312
|
-
amount: swap.received,
|
|
4313
|
-
asset: options.to.symbol,
|
|
4314
|
-
...options.agentId ? { agentId: options.agentId } : {}
|
|
4315
|
-
});
|
|
4316
|
-
return { swap, deposit };
|
|
4317
|
-
}
|
|
4318
3701
|
/**
|
|
4319
3702
|
* Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
|
|
4320
3703
|
* Validates that the asset is supported by the target agent(s) on the active chain.
|
|
@@ -4595,6 +3978,60 @@ var OwneySDK = class {
|
|
|
4595
3978
|
* @param options.days - Lookback period: "7D", "14D", or "30D"
|
|
4596
3979
|
* @returns {AccountAgentApy} for a single agent, or {OwneyAccountApy} with totalApy and per-agent breakdown
|
|
4597
3980
|
*/
|
|
3981
|
+
/**
|
|
3982
|
+
* Daily cumulative NET earnings for the selected chain/asset, backing the
|
|
3983
|
+
* "recent earnings" subline. Net is computed as Zyfai's own
|
|
3984
|
+
* `lifetime + unrealized + current x 0.9`, so the figure reconciles with the
|
|
3985
|
+
* balance headline rather than reading ~11% high. (ROUT-452)
|
|
3986
|
+
*
|
|
3987
|
+
* Unlike getAccountApy this does NOT blend across agents: earnings are
|
|
3988
|
+
* summed, not weighted, and an agent that fails to report must not silently
|
|
3989
|
+
* subtract from the total. Without an agentId the series is the sum of the
|
|
3990
|
+
* agents that answered.
|
|
3991
|
+
*/
|
|
3992
|
+
async getDailyEarnings({
|
|
3993
|
+
agentId,
|
|
3994
|
+
days,
|
|
3995
|
+
tokenSymbol
|
|
3996
|
+
}) {
|
|
3997
|
+
const state = this.requireState();
|
|
3998
|
+
const chainId = this.requireChainId();
|
|
3999
|
+
if (agentId) {
|
|
4000
|
+
const agent = this.getAgent(agentId);
|
|
4001
|
+
if (!agent.getDailyEarnings) {
|
|
4002
|
+
return { walletAddress: state.walletAddress ?? "", points: [] };
|
|
4003
|
+
}
|
|
4004
|
+
return this.readAgent(
|
|
4005
|
+
agent,
|
|
4006
|
+
"dailyEarnings",
|
|
4007
|
+
() => agent.getDailyEarnings(state, chainId, days, tokenSymbol),
|
|
4008
|
+
{ days, tokenSymbol }
|
|
4009
|
+
);
|
|
4010
|
+
}
|
|
4011
|
+
const entries = [...this.getActiveAgents().entries()].filter(
|
|
4012
|
+
([, agent]) => agent.getDailyEarnings
|
|
4013
|
+
);
|
|
4014
|
+
const series = await Promise.all(
|
|
4015
|
+
entries.map(
|
|
4016
|
+
([, agent]) => this.readAgent(
|
|
4017
|
+
agent,
|
|
4018
|
+
"dailyEarnings",
|
|
4019
|
+
() => agent.getDailyEarnings(state, chainId, days, tokenSymbol),
|
|
4020
|
+
{ days, tokenSymbol }
|
|
4021
|
+
)
|
|
4022
|
+
)
|
|
4023
|
+
);
|
|
4024
|
+
const byDate = /* @__PURE__ */ new Map();
|
|
4025
|
+
for (const s of series) {
|
|
4026
|
+
for (const point of s.points) {
|
|
4027
|
+
byDate.set(point.date, (byDate.get(point.date) ?? 0) + point.net);
|
|
4028
|
+
}
|
|
4029
|
+
}
|
|
4030
|
+
return {
|
|
4031
|
+
walletAddress: series[0]?.walletAddress ?? state.walletAddress ?? "",
|
|
4032
|
+
points: [...byDate.entries()].map(([date, net]) => ({ date, net })).sort((a, b) => a.date.localeCompare(b.date))
|
|
4033
|
+
};
|
|
4034
|
+
}
|
|
4598
4035
|
async getAccountApy({
|
|
4599
4036
|
agentId,
|
|
4600
4037
|
days,
|
|
@@ -4809,10 +4246,10 @@ var OwneySDK = class {
|
|
|
4809
4246
|
);
|
|
4810
4247
|
}
|
|
4811
4248
|
const provider = this.requireConnectedProvider();
|
|
4812
|
-
const wallet = (0,
|
|
4249
|
+
const wallet = (0, import_viem6.createWalletClient)({
|
|
4813
4250
|
account: state.walletAddress,
|
|
4814
4251
|
chain: VIEM_CHAIN2[chainId],
|
|
4815
|
-
transport: (0,
|
|
4252
|
+
transport: (0, import_viem6.custom)(provider)
|
|
4816
4253
|
});
|
|
4817
4254
|
const hash = await wallet.writeContract({
|
|
4818
4255
|
address: token,
|
|
@@ -4822,9 +4259,9 @@ var OwneySDK = class {
|
|
|
4822
4259
|
account: state.walletAddress,
|
|
4823
4260
|
chain: VIEM_CHAIN2[chainId]
|
|
4824
4261
|
});
|
|
4825
|
-
const publicClient = (0,
|
|
4262
|
+
const publicClient = (0, import_viem6.createPublicClient)({
|
|
4826
4263
|
chain: VIEM_CHAIN2[chainId],
|
|
4827
|
-
transport: (0,
|
|
4264
|
+
transport: (0, import_viem6.custom)(provider)
|
|
4828
4265
|
});
|
|
4829
4266
|
const receipt = await publicClient.waitForTransactionReceipt({
|
|
4830
4267
|
hash,
|
|
@@ -4936,13 +4373,13 @@ var OwneySDK = class {
|
|
|
4936
4373
|
};
|
|
4937
4374
|
|
|
4938
4375
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
4939
|
-
var
|
|
4376
|
+
var import_viem7 = require("viem");
|
|
4940
4377
|
var import_siwe = require("siwe");
|
|
4941
4378
|
var import_sdk2 = require("@zyfai/sdk");
|
|
4942
4379
|
|
|
4943
4380
|
// src/agents/zyfai/zyfai.siwx-cache.ts
|
|
4944
|
-
var
|
|
4945
|
-
var
|
|
4381
|
+
var KEY_PREFIX2 = "owney.siwx.session";
|
|
4382
|
+
var storage2 = () => {
|
|
4946
4383
|
if (typeof window === "undefined") return null;
|
|
4947
4384
|
try {
|
|
4948
4385
|
return window.localStorage;
|
|
@@ -4950,8 +4387,8 @@ var storage3 = () => {
|
|
|
4950
4387
|
return null;
|
|
4951
4388
|
}
|
|
4952
4389
|
};
|
|
4953
|
-
var buildKey2 = (address) => `${
|
|
4954
|
-
var legacyKeyPrefix2 = (address) => `${
|
|
4390
|
+
var buildKey2 = (address) => `${KEY_PREFIX2}:${address.toLowerCase()}`;
|
|
4391
|
+
var legacyKeyPrefix2 = (address) => `${KEY_PREFIX2}:${address.toLowerCase()}:`;
|
|
4955
4392
|
var memorySiwxSessions = /* @__PURE__ */ new Map();
|
|
4956
4393
|
var readLegacySiwxSession = (store, address) => {
|
|
4957
4394
|
if (!store) return null;
|
|
@@ -4983,7 +4420,7 @@ var readLegacySiwxSession = (store, address) => {
|
|
|
4983
4420
|
var readSiwxSession = (address, chainId) => {
|
|
4984
4421
|
if (typeof window === "undefined") return null;
|
|
4985
4422
|
const key2 = buildKey2(address);
|
|
4986
|
-
const store =
|
|
4423
|
+
const store = storage2();
|
|
4987
4424
|
let raw = null;
|
|
4988
4425
|
try {
|
|
4989
4426
|
raw = store?.getItem(key2) ?? null;
|
|
@@ -5013,7 +4450,7 @@ var writeSiwxSession = (address, _chainId, session) => {
|
|
|
5013
4450
|
if (typeof window === "undefined") return;
|
|
5014
4451
|
const key2 = buildKey2(address);
|
|
5015
4452
|
memorySiwxSessions.set(key2, session);
|
|
5016
|
-
const store =
|
|
4453
|
+
const store = storage2();
|
|
5017
4454
|
try {
|
|
5018
4455
|
store?.setItem(key2, JSON.stringify(session));
|
|
5019
4456
|
} catch {
|
|
@@ -5022,7 +4459,7 @@ var writeSiwxSession = (address, _chainId, session) => {
|
|
|
5022
4459
|
var clearSiwxSession = (address, _chainId) => {
|
|
5023
4460
|
const key2 = buildKey2(address);
|
|
5024
4461
|
memorySiwxSessions.delete(key2);
|
|
5025
|
-
const store =
|
|
4462
|
+
const store = storage2();
|
|
5026
4463
|
try {
|
|
5027
4464
|
store?.removeItem(key2);
|
|
5028
4465
|
} catch {
|
|
@@ -5063,7 +4500,7 @@ function buildSIWXConfig(deps) {
|
|
|
5063
4500
|
issuedAt,
|
|
5064
4501
|
toString() {
|
|
5065
4502
|
return new import_siwe.SiweMessage({
|
|
5066
|
-
address: (0,
|
|
4503
|
+
address: (0, import_viem7.getAddress)(accountAddress),
|
|
5067
4504
|
chainId: numericChainId(chainId),
|
|
5068
4505
|
domain,
|
|
5069
4506
|
uri,
|
|
@@ -5141,9 +4578,9 @@ function buildSIWXConfig(deps) {
|
|
|
5141
4578
|
}
|
|
5142
4579
|
function createOwneySIWX(config) {
|
|
5143
4580
|
const zyfai = new import_sdk2.ZyfaiSDK({ apiKey: config.apiKey });
|
|
5144
|
-
const
|
|
4581
|
+
const http2 = zyfai.httpClient;
|
|
5145
4582
|
return buildSIWXConfig({
|
|
5146
|
-
post: (url, data) =>
|
|
4583
|
+
post: (url, data) => http2.post(url, data),
|
|
5147
4584
|
referralSource: config.referralSource
|
|
5148
4585
|
});
|
|
5149
4586
|
}
|
|
@@ -5156,6 +4593,6 @@ function createOwneySIWX(config) {
|
|
|
5156
4593
|
OwneyError,
|
|
5157
4594
|
OwneySDK,
|
|
5158
4595
|
createOwneySIWX,
|
|
5159
|
-
|
|
4596
|
+
recentEarningsFromPoints,
|
|
5160
4597
|
setOwneyDebug
|
|
5161
4598
|
});
|