@owney/sdk 0.7.26-beta.5 → 0.7.26-beta.7
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 +233 -31
- package/dist/index.d.cts +155 -4
- package/dist/index.d.ts +155 -4
- package/dist/index.js +227 -30
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -26,10 +26,15 @@ __export(index_exports, {
|
|
|
26
26
|
NotConnectedError: () => NotConnectedError,
|
|
27
27
|
OwneyError: () => OwneyError,
|
|
28
28
|
OwneySDK: () => OwneySDK,
|
|
29
|
+
clearWithdrawSwap: () => clearWithdrawSwap,
|
|
29
30
|
createOwneySIWX: () => createOwneySIWX,
|
|
30
31
|
listPendingDeposits: () => listPendingDeposits,
|
|
31
32
|
listPendingSwaps: () => listOrders,
|
|
32
|
-
|
|
33
|
+
listWithdrawSwaps: () => listWithdrawSwaps,
|
|
34
|
+
saveWithdrawSwap: () => saveWithdrawSwap,
|
|
35
|
+
setOwneyDebug: () => setOwneyDebug,
|
|
36
|
+
subscribeWithdrawSwaps: () => subscribeWithdrawSwaps,
|
|
37
|
+
updateWithdrawSwap: () => updateWithdrawSwap
|
|
33
38
|
});
|
|
34
39
|
module.exports = __toCommonJS(index_exports);
|
|
35
40
|
|
|
@@ -298,6 +303,15 @@ var DayFilterMapping = {
|
|
|
298
303
|
"7D": 7
|
|
299
304
|
};
|
|
300
305
|
|
|
306
|
+
// src/lib/helpers/asset-aliases.ts
|
|
307
|
+
function assetAliases(asset) {
|
|
308
|
+
const normalised = asset.toLowerCase();
|
|
309
|
+
return normalised === "weth" ? ["weth", "eth"] : [normalised];
|
|
310
|
+
}
|
|
311
|
+
function matchesAsset(symbol, asset) {
|
|
312
|
+
return assetAliases(asset).includes(symbol.toLowerCase());
|
|
313
|
+
}
|
|
314
|
+
|
|
301
315
|
// src/agents/zyfai/zyfai.mapper.ts
|
|
302
316
|
var DECIMALS_BY_SYMBOL = {
|
|
303
317
|
usdc: 6,
|
|
@@ -702,9 +716,8 @@ function computeAllocationApy(positions) {
|
|
|
702
716
|
function earningsForToken(bucket, chainId, asset) {
|
|
703
717
|
const tokens = bucket?.[String(chainId)];
|
|
704
718
|
if (!tokens) return null;
|
|
705
|
-
const wanted = asset.toUpperCase();
|
|
706
719
|
for (const [symbol, value] of Object.entries(tokens)) {
|
|
707
|
-
if (symbol
|
|
720
|
+
if (!matchesAsset(symbol, asset)) continue;
|
|
708
721
|
const amount = Number(value);
|
|
709
722
|
return Number.isFinite(amount) ? amount : null;
|
|
710
723
|
}
|
|
@@ -2329,7 +2342,7 @@ function createSwapApi(baseUrl, apiKey) {
|
|
|
2329
2342
|
baseUrl,
|
|
2330
2343
|
apiKey,
|
|
2331
2344
|
`/tokens/search?${new URLSearchParams({
|
|
2332
|
-
query: params.query,
|
|
2345
|
+
...params.query === void 0 ? {} : { query: params.query },
|
|
2333
2346
|
// Omitted, the routing API searches every supported chain — which is
|
|
2334
2347
|
// what a picker wants, since its rows already span all three.
|
|
2335
2348
|
...params.chainId === void 0 ? {} : { chainId: String(params.chainId) },
|
|
@@ -3122,6 +3135,10 @@ async function runSameChainFusion(deps, options, walletAddress) {
|
|
|
3122
3135
|
quoteId: built.quoteId,
|
|
3123
3136
|
...built.extension ? { extension: built.extension } : {}
|
|
3124
3137
|
});
|
|
3138
|
+
try {
|
|
3139
|
+
options.onOrderSubmitted?.(built.orderHash);
|
|
3140
|
+
} catch {
|
|
3141
|
+
}
|
|
3125
3142
|
await runSameChainOrder(deps.sameChainRunner ?? deps.runner, {
|
|
3126
3143
|
orderHash: built.orderHash,
|
|
3127
3144
|
...onStage ? { onStage } : {}
|
|
@@ -3220,6 +3237,10 @@ async function runFusion(deps, options, walletAddress) {
|
|
|
3220
3237
|
...built.extension ? { extension: built.extension } : {}
|
|
3221
3238
|
});
|
|
3222
3239
|
debugLog("owney-sdk", "swap: order submitted, polling escrows");
|
|
3240
|
+
try {
|
|
3241
|
+
options.onOrderSubmitted?.(built.orderHash);
|
|
3242
|
+
} catch {
|
|
3243
|
+
}
|
|
3223
3244
|
try {
|
|
3224
3245
|
await runFusionOrder(deps.runner, {
|
|
3225
3246
|
orderHash: built.orderHash,
|
|
@@ -3334,8 +3355,8 @@ async function buildErc2612Permit(reads, input) {
|
|
|
3334
3355
|
);
|
|
3335
3356
|
}
|
|
3336
3357
|
|
|
3337
|
-
// src/lib/swap/swap.
|
|
3338
|
-
var KEY_PREFIX3 = "owney.swap.
|
|
3358
|
+
// src/lib/swap/swap.withdraw-swap.ts
|
|
3359
|
+
var KEY_PREFIX3 = "owney.swap.withdraw";
|
|
3339
3360
|
var MAX_AGE_MS2 = 24 * 60 * 60 * 1e3;
|
|
3340
3361
|
var storage3 = () => {
|
|
3341
3362
|
if (typeof window === "undefined") return null;
|
|
@@ -3345,26 +3366,60 @@ var storage3 = () => {
|
|
|
3345
3366
|
return null;
|
|
3346
3367
|
}
|
|
3347
3368
|
};
|
|
3348
|
-
var keyFor2 = (
|
|
3349
|
-
|
|
3369
|
+
var keyFor2 = (orderHash) => `${KEY_PREFIX3}.${orderHash}`;
|
|
3370
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
3371
|
+
function subscribeWithdrawSwaps(listener) {
|
|
3372
|
+
listeners.add(listener);
|
|
3373
|
+
return () => {
|
|
3374
|
+
listeners.delete(listener);
|
|
3375
|
+
};
|
|
3376
|
+
}
|
|
3377
|
+
var notify = () => {
|
|
3378
|
+
for (const listener of listeners) {
|
|
3379
|
+
try {
|
|
3380
|
+
listener();
|
|
3381
|
+
} catch {
|
|
3382
|
+
}
|
|
3383
|
+
}
|
|
3384
|
+
};
|
|
3385
|
+
function saveWithdrawSwap(record) {
|
|
3350
3386
|
const store = storage3();
|
|
3351
3387
|
if (!store) return;
|
|
3352
3388
|
try {
|
|
3353
|
-
store.setItem(keyFor2(
|
|
3389
|
+
store.setItem(keyFor2(record.orderHash), JSON.stringify(record));
|
|
3354
3390
|
} catch {
|
|
3355
3391
|
return;
|
|
3356
3392
|
}
|
|
3393
|
+
notify();
|
|
3357
3394
|
}
|
|
3358
|
-
function
|
|
3395
|
+
function updateWithdrawSwap(orderHash, patch) {
|
|
3359
3396
|
const store = storage3();
|
|
3360
3397
|
if (!store) return;
|
|
3361
3398
|
try {
|
|
3362
|
-
store.
|
|
3399
|
+
const raw = store.getItem(keyFor2(orderHash));
|
|
3400
|
+
if (!raw) return;
|
|
3401
|
+
const current = JSON.parse(raw);
|
|
3402
|
+
const next = { ...current, ...patch };
|
|
3403
|
+
if (next.status !== "swapping" && current.status === "swapping" && next.settledAt === void 0) {
|
|
3404
|
+
next.settledAt = Date.now();
|
|
3405
|
+
}
|
|
3406
|
+
store.setItem(keyFor2(orderHash), JSON.stringify(next));
|
|
3363
3407
|
} catch {
|
|
3364
3408
|
return;
|
|
3365
3409
|
}
|
|
3410
|
+
notify();
|
|
3366
3411
|
}
|
|
3367
|
-
function
|
|
3412
|
+
function clearWithdrawSwap(orderHash) {
|
|
3413
|
+
const store = storage3();
|
|
3414
|
+
if (!store) return;
|
|
3415
|
+
try {
|
|
3416
|
+
store.removeItem(keyFor2(orderHash));
|
|
3417
|
+
} catch {
|
|
3418
|
+
return;
|
|
3419
|
+
}
|
|
3420
|
+
notify();
|
|
3421
|
+
}
|
|
3422
|
+
function listWithdrawSwaps(now = Date.now()) {
|
|
3368
3423
|
const store = storage3();
|
|
3369
3424
|
if (!store) return [];
|
|
3370
3425
|
const out = [];
|
|
@@ -3394,6 +3449,66 @@ function listPendingDeposits(now = Date.now()) {
|
|
|
3394
3449
|
return out.sort((a, b) => b.createdAt - a.createdAt);
|
|
3395
3450
|
}
|
|
3396
3451
|
|
|
3452
|
+
// src/lib/swap/swap.pending-deposit.ts
|
|
3453
|
+
var KEY_PREFIX4 = "owney.swap.pending-deposit";
|
|
3454
|
+
var MAX_AGE_MS3 = 24 * 60 * 60 * 1e3;
|
|
3455
|
+
var storage4 = () => {
|
|
3456
|
+
if (typeof window === "undefined") return null;
|
|
3457
|
+
try {
|
|
3458
|
+
return window.localStorage;
|
|
3459
|
+
} catch {
|
|
3460
|
+
return null;
|
|
3461
|
+
}
|
|
3462
|
+
};
|
|
3463
|
+
var keyFor3 = (id) => `${KEY_PREFIX4}.${id}`;
|
|
3464
|
+
function savePendingDeposit(entry) {
|
|
3465
|
+
const store = storage4();
|
|
3466
|
+
if (!store) return;
|
|
3467
|
+
try {
|
|
3468
|
+
store.setItem(keyFor3(entry.id), JSON.stringify(entry));
|
|
3469
|
+
} catch {
|
|
3470
|
+
return;
|
|
3471
|
+
}
|
|
3472
|
+
}
|
|
3473
|
+
function clearPendingDeposit(id) {
|
|
3474
|
+
const store = storage4();
|
|
3475
|
+
if (!store) return;
|
|
3476
|
+
try {
|
|
3477
|
+
store.removeItem(keyFor3(id));
|
|
3478
|
+
} catch {
|
|
3479
|
+
return;
|
|
3480
|
+
}
|
|
3481
|
+
}
|
|
3482
|
+
function listPendingDeposits(now = Date.now()) {
|
|
3483
|
+
const store = storage4();
|
|
3484
|
+
if (!store) return [];
|
|
3485
|
+
const out = [];
|
|
3486
|
+
try {
|
|
3487
|
+
const keys = [];
|
|
3488
|
+
for (let i = 0; i < store.length; i++) {
|
|
3489
|
+
const key2 = store.key(i);
|
|
3490
|
+
if (key2?.startsWith(`${KEY_PREFIX4}.`)) keys.push(key2);
|
|
3491
|
+
}
|
|
3492
|
+
for (const key2 of keys) {
|
|
3493
|
+
const raw = store.getItem(key2);
|
|
3494
|
+
if (!raw) continue;
|
|
3495
|
+
try {
|
|
3496
|
+
const parsed = JSON.parse(raw);
|
|
3497
|
+
if (now - parsed.createdAt > MAX_AGE_MS3) {
|
|
3498
|
+
store.removeItem(key2);
|
|
3499
|
+
continue;
|
|
3500
|
+
}
|
|
3501
|
+
out.push(parsed);
|
|
3502
|
+
} catch {
|
|
3503
|
+
store.removeItem(key2);
|
|
3504
|
+
}
|
|
3505
|
+
}
|
|
3506
|
+
} catch {
|
|
3507
|
+
return out;
|
|
3508
|
+
}
|
|
3509
|
+
return out.sort((a, b) => b.createdAt - a.createdAt);
|
|
3510
|
+
}
|
|
3511
|
+
|
|
3397
3512
|
// src/lib/health-report.ts
|
|
3398
3513
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
3399
3514
|
async function reportAgentFailure(apiKey, agentType, errorCode, baseUrl = ROUTING_API_BASE_URL2) {
|
|
@@ -3430,11 +3545,10 @@ async function withFailureReporting(apiKey, agentType, fn, baseUrl) {
|
|
|
3430
3545
|
// src/lib/helpers/withdraw-helper.ts
|
|
3431
3546
|
var import_viem6 = require("viem");
|
|
3432
3547
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
3433
|
-
const target = asset.toUpperCase();
|
|
3434
3548
|
return agents.map((agent) => {
|
|
3435
3549
|
const agentBalance = aggregated[agent.id];
|
|
3436
3550
|
const tokenBalance = agentBalance?.tokens.find(
|
|
3437
|
-
(t) => t.chainId === chainId && t.asset
|
|
3551
|
+
(t) => t.chainId === chainId && matchesAsset(t.asset, asset)
|
|
3438
3552
|
);
|
|
3439
3553
|
if (!tokenBalance) return { agent, balance: 0n };
|
|
3440
3554
|
return { agent, balance: (0, import_viem6.parseUnits)(tokenBalance.amount, decimals) };
|
|
@@ -4735,15 +4849,14 @@ var OwneySDK = class {
|
|
|
4735
4849
|
async hasExistingBalance(agent, state, chainId, asset, requireReliableRead = false) {
|
|
4736
4850
|
try {
|
|
4737
4851
|
const balance = await agent.getBalances(state, chainId);
|
|
4738
|
-
const target = asset.toLowerCase();
|
|
4739
4852
|
const token = balance.tokens.find(
|
|
4740
|
-
(t) => t.chainId === chainId && t.asset
|
|
4853
|
+
(t) => t.chainId === chainId && matchesAsset(t.asset, asset)
|
|
4741
4854
|
);
|
|
4742
4855
|
const targetChainName = agent.supportedAssets.find((entry) => entry.chainId === chainId)?.chain?.trim().toUpperCase();
|
|
4743
4856
|
const position = (balance.positions ?? []).find((p) => {
|
|
4744
4857
|
const positionChain = p.chain.trim().toUpperCase();
|
|
4745
4858
|
const matchesChain = positionChain === String(chainId) || targetChainName !== void 0 && positionChain === targetChainName;
|
|
4746
|
-
return matchesChain && p.asset
|
|
4859
|
+
return matchesChain && matchesAsset(p.asset, asset) && Number(p.amount) > 0;
|
|
4747
4860
|
});
|
|
4748
4861
|
return !!token && Number(token.amount) > 0 || !!position;
|
|
4749
4862
|
} catch (error) {
|
|
@@ -5148,6 +5261,25 @@ var OwneySDK = class {
|
|
|
5148
5261
|
listPendingDeposits() {
|
|
5149
5262
|
return listPendingDeposits();
|
|
5150
5263
|
}
|
|
5264
|
+
/**
|
|
5265
|
+
* Backgrounded withdrawal swaps and how they ended, newest first.
|
|
5266
|
+
*
|
|
5267
|
+
* Nothing to act on — unlike `listPendingDeposits`, which describes a job the
|
|
5268
|
+
* user can finish. This is a watch: the funds are in escrow and the only
|
|
5269
|
+
* open question is where they land. See `swap.withdraw-swap.ts`.
|
|
5270
|
+
*/
|
|
5271
|
+
listWithdrawSwaps() {
|
|
5272
|
+
return listWithdrawSwaps();
|
|
5273
|
+
}
|
|
5274
|
+
/**
|
|
5275
|
+
* Retire a settled record. The user has read the outcome.
|
|
5276
|
+
*
|
|
5277
|
+
* Only they do this — a record that disappears on its own takes with it the
|
|
5278
|
+
* only thing telling someone where their money went.
|
|
5279
|
+
*/
|
|
5280
|
+
dismissWithdrawSwap(orderHash) {
|
|
5281
|
+
clearWithdrawSwap(orderHash);
|
|
5282
|
+
}
|
|
5151
5283
|
/**
|
|
5152
5284
|
* Deposit a swap that already landed.
|
|
5153
5285
|
*
|
|
@@ -5194,7 +5326,10 @@ var OwneySDK = class {
|
|
|
5194
5326
|
*/
|
|
5195
5327
|
async resumePendingSwaps(options = {}) {
|
|
5196
5328
|
const pending = listOrders();
|
|
5197
|
-
if (pending.length === 0)
|
|
5329
|
+
if (pending.length === 0) {
|
|
5330
|
+
await this.resumeSameChainSwaps(options);
|
|
5331
|
+
return [];
|
|
5332
|
+
}
|
|
5198
5333
|
const runner = this.swapRunnerDeps();
|
|
5199
5334
|
const results = [];
|
|
5200
5335
|
for (const order of pending) {
|
|
@@ -5208,6 +5343,7 @@ var OwneySDK = class {
|
|
|
5208
5343
|
} : {}
|
|
5209
5344
|
});
|
|
5210
5345
|
clearOrder(order.orderHash);
|
|
5346
|
+
updateWithdrawSwap(order.orderHash, { status: "landed" });
|
|
5211
5347
|
results.push({
|
|
5212
5348
|
orderHash: order.orderHash,
|
|
5213
5349
|
status: "completed"
|
|
@@ -5215,6 +5351,9 @@ var OwneySDK = class {
|
|
|
5215
5351
|
} catch (error) {
|
|
5216
5352
|
if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED")) {
|
|
5217
5353
|
clearOrder(order.orderHash);
|
|
5354
|
+
updateWithdrawSwap(order.orderHash, { status: "refunded" });
|
|
5355
|
+
} else {
|
|
5356
|
+
updateWithdrawSwap(order.orderHash, { status: "unknown" });
|
|
5218
5357
|
}
|
|
5219
5358
|
results.push({
|
|
5220
5359
|
orderHash: order.orderHash,
|
|
@@ -5223,8 +5362,56 @@ var OwneySDK = class {
|
|
|
5223
5362
|
});
|
|
5224
5363
|
}
|
|
5225
5364
|
}
|
|
5365
|
+
await this.resumeSameChainSwaps(options);
|
|
5226
5366
|
return results;
|
|
5227
5367
|
}
|
|
5368
|
+
/**
|
|
5369
|
+
* Pick up SAME-CHAIN orders a previous session left in the auction.
|
|
5370
|
+
*
|
|
5371
|
+
* They are not in the secret store and never will be: that store exists to
|
|
5372
|
+
* keep preimages, and a same-chain fill needs none — the resolver takes the
|
|
5373
|
+
* maker's tokens and delivers the taker's in one transaction. So the only
|
|
5374
|
+
* record of one is the withdrawal record itself, which carries the order
|
|
5375
|
+
* hash, and that is all a resume needs here.
|
|
5376
|
+
*
|
|
5377
|
+
* Gentler than the Fusion+ case in the way that matters. Nothing is
|
|
5378
|
+
* escrowed, so an order nobody ever picks up leaves the wallet exactly as it
|
|
5379
|
+
* was — this is catching up on news, not rescuing funds.
|
|
5380
|
+
*
|
|
5381
|
+
* Same-chain is read off the record rather than stored as a rail: a
|
|
5382
|
+
* withdrawal whose source and destination share a chain could not have been
|
|
5383
|
+
* anything else.
|
|
5384
|
+
*/
|
|
5385
|
+
async resumeSameChainSwaps(options = {}) {
|
|
5386
|
+
const running = listWithdrawSwaps().filter(
|
|
5387
|
+
(record) => record.status === "swapping" && record.srcChainId === record.dstChainId
|
|
5388
|
+
);
|
|
5389
|
+
for (const record of running) {
|
|
5390
|
+
const runner = {
|
|
5391
|
+
// The chain bound in. That product keys its orders per chain, and the
|
|
5392
|
+
// Fusion+ endpoint answers 404 for one — which would read as an order
|
|
5393
|
+
// that vanished rather than one still in the auction.
|
|
5394
|
+
orderStatus: (h) => this.swapApi().orderStatus(h, record.srcChainId),
|
|
5395
|
+
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
5396
|
+
now: () => Date.now()
|
|
5397
|
+
};
|
|
5398
|
+
try {
|
|
5399
|
+
await runSameChainOrder(runner, {
|
|
5400
|
+
orderHash: record.orderHash,
|
|
5401
|
+
...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs },
|
|
5402
|
+
...options.onStage ? {
|
|
5403
|
+
onStage: (stage) => options.onStage(record.orderHash, stage)
|
|
5404
|
+
} : {}
|
|
5405
|
+
});
|
|
5406
|
+
updateWithdrawSwap(record.orderHash, { status: "landed" });
|
|
5407
|
+
} catch (error) {
|
|
5408
|
+
const code = error instanceof OwneyError ? error.code : void 0;
|
|
5409
|
+
updateWithdrawSwap(record.orderHash, {
|
|
5410
|
+
status: code === "SWAP_ORDER_EXPIRED" || code === "SWAP_ORDER_CANCELLED" ? "refunded" : "unknown"
|
|
5411
|
+
});
|
|
5412
|
+
}
|
|
5413
|
+
}
|
|
5414
|
+
}
|
|
5228
5415
|
/**
|
|
5229
5416
|
* What the wallet actually holds, across every supported chain, restricted
|
|
5230
5417
|
* to tokens a swap could use.
|
|
@@ -5271,13 +5458,16 @@ var OwneySDK = class {
|
|
|
5271
5458
|
* tokens can share a ticker, and `providers` (how many token lists carry the
|
|
5272
5459
|
* address) is the only usable signal for telling them apart. Surface it.
|
|
5273
5460
|
*
|
|
5274
|
-
*
|
|
5461
|
+
* A blank query WITH a chainId lists that chain's catalogue instead of
|
|
5462
|
+
* searching it — what a picker wants when someone selects a chain before
|
|
5463
|
+
* typing anything. Blank with no chain returns nothing: that would be asking
|
|
5464
|
+
* for the top of every catalogue at once, which is a download, not a list.
|
|
5275
5465
|
*/
|
|
5276
5466
|
async searchSwapTokens(params) {
|
|
5277
|
-
const query = params.query
|
|
5278
|
-
if (!query) return { tokens: [] };
|
|
5467
|
+
const query = params.query?.trim() ?? "";
|
|
5468
|
+
if (!query && params.chainId === void 0) return { tokens: [] };
|
|
5279
5469
|
return this.swapApi().searchTokens({
|
|
5280
|
-
query,
|
|
5470
|
+
...query ? { query } : {},
|
|
5281
5471
|
...params.chainId === void 0 ? {} : { chainId: params.chainId },
|
|
5282
5472
|
...params.limit === void 0 ? {} : { limit: params.limit },
|
|
5283
5473
|
...params.direction === void 0 ? {} : { direction: params.direction }
|
|
@@ -5457,7 +5647,14 @@ var OwneySDK = class {
|
|
|
5457
5647
|
walletAddress: state.walletAddress,
|
|
5458
5648
|
direction: "withdraw",
|
|
5459
5649
|
...options.slippage === void 0 ? {} : { slippage: options.slippage },
|
|
5460
|
-
...options.onSwapProgress ? { onStage: options.onSwapProgress } : {}
|
|
5650
|
+
...options.onSwapProgress ? { onStage: options.onSwapProgress } : {},
|
|
5651
|
+
...options.onOrderSubmitted ? {
|
|
5652
|
+
onOrderSubmitted: (orderHash) => options.onOrderSubmitted({
|
|
5653
|
+
orderHash,
|
|
5654
|
+
withdrawn,
|
|
5655
|
+
expected: quote.dst.amount
|
|
5656
|
+
})
|
|
5657
|
+
} : {}
|
|
5461
5658
|
});
|
|
5462
5659
|
return { withdraw, withdrawn, swap };
|
|
5463
5660
|
} catch (error) {
|
|
@@ -6216,8 +6413,8 @@ var import_siwe = require("siwe");
|
|
|
6216
6413
|
var import_sdk2 = require("@zyfai/sdk");
|
|
6217
6414
|
|
|
6218
6415
|
// src/agents/zyfai/zyfai.siwx-cache.ts
|
|
6219
|
-
var
|
|
6220
|
-
var
|
|
6416
|
+
var KEY_PREFIX5 = "owney.siwx.session";
|
|
6417
|
+
var storage5 = () => {
|
|
6221
6418
|
if (typeof window === "undefined") return null;
|
|
6222
6419
|
try {
|
|
6223
6420
|
return window.localStorage;
|
|
@@ -6225,8 +6422,8 @@ var storage4 = () => {
|
|
|
6225
6422
|
return null;
|
|
6226
6423
|
}
|
|
6227
6424
|
};
|
|
6228
|
-
var buildKey2 = (address) => `${
|
|
6229
|
-
var legacyKeyPrefix2 = (address) => `${
|
|
6425
|
+
var buildKey2 = (address) => `${KEY_PREFIX5}:${address.toLowerCase()}`;
|
|
6426
|
+
var legacyKeyPrefix2 = (address) => `${KEY_PREFIX5}:${address.toLowerCase()}:`;
|
|
6230
6427
|
var memorySiwxSessions = /* @__PURE__ */ new Map();
|
|
6231
6428
|
var readLegacySiwxSession = (store, address) => {
|
|
6232
6429
|
if (!store) return null;
|
|
@@ -6258,7 +6455,7 @@ var readLegacySiwxSession = (store, address) => {
|
|
|
6258
6455
|
var readSiwxSession = (address, chainId) => {
|
|
6259
6456
|
if (typeof window === "undefined") return null;
|
|
6260
6457
|
const key2 = buildKey2(address);
|
|
6261
|
-
const store =
|
|
6458
|
+
const store = storage5();
|
|
6262
6459
|
let raw = null;
|
|
6263
6460
|
try {
|
|
6264
6461
|
raw = store?.getItem(key2) ?? null;
|
|
@@ -6288,7 +6485,7 @@ var writeSiwxSession = (address, _chainId, session) => {
|
|
|
6288
6485
|
if (typeof window === "undefined") return;
|
|
6289
6486
|
const key2 = buildKey2(address);
|
|
6290
6487
|
memorySiwxSessions.set(key2, session);
|
|
6291
|
-
const store =
|
|
6488
|
+
const store = storage5();
|
|
6292
6489
|
try {
|
|
6293
6490
|
store?.setItem(key2, JSON.stringify(session));
|
|
6294
6491
|
} catch {
|
|
@@ -6297,7 +6494,7 @@ var writeSiwxSession = (address, _chainId, session) => {
|
|
|
6297
6494
|
var clearSiwxSession = (address, _chainId) => {
|
|
6298
6495
|
const key2 = buildKey2(address);
|
|
6299
6496
|
memorySiwxSessions.delete(key2);
|
|
6300
|
-
const store =
|
|
6497
|
+
const store = storage5();
|
|
6301
6498
|
try {
|
|
6302
6499
|
store?.removeItem(key2);
|
|
6303
6500
|
} catch {
|
|
@@ -6430,8 +6627,13 @@ function createOwneySIWX(config) {
|
|
|
6430
6627
|
NotConnectedError,
|
|
6431
6628
|
OwneyError,
|
|
6432
6629
|
OwneySDK,
|
|
6630
|
+
clearWithdrawSwap,
|
|
6433
6631
|
createOwneySIWX,
|
|
6434
6632
|
listPendingDeposits,
|
|
6435
6633
|
listPendingSwaps,
|
|
6436
|
-
|
|
6634
|
+
listWithdrawSwaps,
|
|
6635
|
+
saveWithdrawSwap,
|
|
6636
|
+
setOwneyDebug,
|
|
6637
|
+
subscribeWithdrawSwaps,
|
|
6638
|
+
updateWithdrawSwap
|
|
6437
6639
|
});
|
package/dist/index.d.cts
CHANGED
|
@@ -785,6 +785,94 @@ declare class AgentChainIncompatibleError extends OwneyError {
|
|
|
785
785
|
}>, connectedChainId: number);
|
|
786
786
|
}
|
|
787
787
|
|
|
788
|
+
/**
|
|
789
|
+
* Withdrawal swaps the user has walked away from, and how they ended.
|
|
790
|
+
*
|
|
791
|
+
* The deposit side has `swap.pending-deposit.ts` for the same shape of
|
|
792
|
+
* problem, but the two are not symmetrical. A pending deposit is a JOB: the
|
|
793
|
+
* money is in the wallet and an ordinary deposit finishes it. This is a
|
|
794
|
+
* WATCH — the funds are in escrow, nothing the user does moves them along,
|
|
795
|
+
* and the only question is where they ended up.
|
|
796
|
+
*
|
|
797
|
+
* That is the whole reason this exists. `withdrawAndSwap` used to hold the
|
|
798
|
+
* screen for the entire escrow lifecycle, which on a slow mainnet fill is
|
|
799
|
+
* minutes of a modal the user cannot leave (ROUT-242). Backgrounding it means
|
|
800
|
+
* the outcome arrives after the UI that started it has gone, so the outcome
|
|
801
|
+
* has to be written down somewhere the next render can find it.
|
|
802
|
+
*
|
|
803
|
+
* Only cross-chain swaps are recorded. A same-chain classic swap is one
|
|
804
|
+
* transaction and resolves in seconds; a same-chain fusion order has no stored
|
|
805
|
+
* preimages, so there would be nothing for a reloaded session to resume and
|
|
806
|
+
* the record would sit at `swapping` for ever.
|
|
807
|
+
*
|
|
808
|
+
* Kept deliberately separate from the secret store. Secrets are retired the
|
|
809
|
+
* moment an order reaches a verdict — that is a safety property, not a display
|
|
810
|
+
* one — and the record has to outlive them so the user can still be told what
|
|
811
|
+
* happened after they come back.
|
|
812
|
+
*/
|
|
813
|
+
/**
|
|
814
|
+
* `swapping` is the only non-terminal state. `unknown` is what a watch that
|
|
815
|
+
* gave up looks like: we stopped polling before the order spoke, so the order
|
|
816
|
+
* may well have filled. It is not a failure, and it must never be shown as
|
|
817
|
+
* one.
|
|
818
|
+
*/
|
|
819
|
+
type WithdrawSwapStatus = "swapping" | "landed" | "refunded" | "unknown";
|
|
820
|
+
type WithdrawSwapRecord = {
|
|
821
|
+
/** Identity. One record per Fusion+ order. */
|
|
822
|
+
orderHash: string;
|
|
823
|
+
status: WithdrawSwapStatus;
|
|
824
|
+
/**
|
|
825
|
+
* What actually left the agent, smallest unit of the SOURCE asset.
|
|
826
|
+
*
|
|
827
|
+
* The measured figure, not the requested one — a "MAX" withdrawal has no
|
|
828
|
+
* requested figure at all, and this is what a refund gives back.
|
|
829
|
+
*/
|
|
830
|
+
withdrawn: string;
|
|
831
|
+
srcSymbol: string;
|
|
832
|
+
srcChainId: number;
|
|
833
|
+
srcDecimals: number;
|
|
834
|
+
/**
|
|
835
|
+
* What the quote expected to arrive, smallest unit of the DESTINATION.
|
|
836
|
+
*
|
|
837
|
+
* `dst.amount` — the auction's start, not its floor. The bar reads "about",
|
|
838
|
+
* and quoting the floor understated every completed withdrawal by half a
|
|
839
|
+
* percent (ROUT-242, comment 16056).
|
|
840
|
+
*/
|
|
841
|
+
expected: string;
|
|
842
|
+
dstSymbol: string;
|
|
843
|
+
dstChainId: number;
|
|
844
|
+
dstDecimals: number;
|
|
845
|
+
/** Measured arrival. Set only on `landed`, and shown in place of `expected`. */
|
|
846
|
+
received?: string;
|
|
847
|
+
/** Epoch ms. */
|
|
848
|
+
createdAt: number;
|
|
849
|
+
/** Epoch ms, set when the status stopped being `swapping`. */
|
|
850
|
+
settledAt?: number;
|
|
851
|
+
};
|
|
852
|
+
declare function subscribeWithdrawSwaps(listener: () => void): () => void;
|
|
853
|
+
/**
|
|
854
|
+
* Write the record as the order is submitted, alongside the secrets.
|
|
855
|
+
*
|
|
856
|
+
* Not after the swap resolves: the point is to survive the gap between submit
|
|
857
|
+
* and settle, which is exactly when the user closes the tab.
|
|
858
|
+
*/
|
|
859
|
+
declare function saveWithdrawSwap(record: WithdrawSwapRecord): void;
|
|
860
|
+
/**
|
|
861
|
+
* Move a record to its outcome.
|
|
862
|
+
*
|
|
863
|
+
* A no-op for an order with no record, which is the normal case for deposit
|
|
864
|
+
* swaps — they share the secret store and so pass through the same resume
|
|
865
|
+
* loop, but they are not withdrawals and were never recorded here.
|
|
866
|
+
*
|
|
867
|
+
* `settledAt` is stamped here rather than by the caller so every writer agrees
|
|
868
|
+
* on what "settled" means: the moment the status stopped being `swapping`.
|
|
869
|
+
*/
|
|
870
|
+
declare function updateWithdrawSwap(orderHash: string, patch: Partial<Omit<WithdrawSwapRecord, "orderHash">>): void;
|
|
871
|
+
/** The user has read the outcome. Only they do this. */
|
|
872
|
+
declare function clearWithdrawSwap(orderHash: string): void;
|
|
873
|
+
/** Every record, newest first, sweeping anything past MAX_AGE_MS. */
|
|
874
|
+
declare function listWithdrawSwaps(now?: number): WithdrawSwapRecord[];
|
|
875
|
+
|
|
788
876
|
/**
|
|
789
877
|
* Swaps that landed but were never deposited.
|
|
790
878
|
*
|
|
@@ -1071,6 +1159,21 @@ declare class OwneySDK {
|
|
|
1071
1159
|
* describe. See `completePendingDeposit`.
|
|
1072
1160
|
*/
|
|
1073
1161
|
listPendingDeposits(): ReturnType<typeof listPendingDeposits>;
|
|
1162
|
+
/**
|
|
1163
|
+
* Backgrounded withdrawal swaps and how they ended, newest first.
|
|
1164
|
+
*
|
|
1165
|
+
* Nothing to act on — unlike `listPendingDeposits`, which describes a job the
|
|
1166
|
+
* user can finish. This is a watch: the funds are in escrow and the only
|
|
1167
|
+
* open question is where they land. See `swap.withdraw-swap.ts`.
|
|
1168
|
+
*/
|
|
1169
|
+
listWithdrawSwaps(): WithdrawSwapRecord[];
|
|
1170
|
+
/**
|
|
1171
|
+
* Retire a settled record. The user has read the outcome.
|
|
1172
|
+
*
|
|
1173
|
+
* Only they do this — a record that disappears on its own takes with it the
|
|
1174
|
+
* only thing telling someone where their money went.
|
|
1175
|
+
*/
|
|
1176
|
+
dismissWithdrawSwap(orderHash: string): void;
|
|
1074
1177
|
/**
|
|
1075
1178
|
* Deposit a swap that already landed.
|
|
1076
1179
|
*
|
|
@@ -1106,6 +1209,24 @@ declare class OwneySDK {
|
|
|
1106
1209
|
status: "completed" | "unfinished";
|
|
1107
1210
|
error?: OwneyError;
|
|
1108
1211
|
}[]>;
|
|
1212
|
+
/**
|
|
1213
|
+
* Pick up SAME-CHAIN orders a previous session left in the auction.
|
|
1214
|
+
*
|
|
1215
|
+
* They are not in the secret store and never will be: that store exists to
|
|
1216
|
+
* keep preimages, and a same-chain fill needs none — the resolver takes the
|
|
1217
|
+
* maker's tokens and delivers the taker's in one transaction. So the only
|
|
1218
|
+
* record of one is the withdrawal record itself, which carries the order
|
|
1219
|
+
* hash, and that is all a resume needs here.
|
|
1220
|
+
*
|
|
1221
|
+
* Gentler than the Fusion+ case in the way that matters. Nothing is
|
|
1222
|
+
* escrowed, so an order nobody ever picks up leaves the wallet exactly as it
|
|
1223
|
+
* was — this is catching up on news, not rescuing funds.
|
|
1224
|
+
*
|
|
1225
|
+
* Same-chain is read off the record rather than stored as a rail: a
|
|
1226
|
+
* withdrawal whose source and destination share a chain could not have been
|
|
1227
|
+
* anything else.
|
|
1228
|
+
*/
|
|
1229
|
+
private resumeSameChainSwaps;
|
|
1109
1230
|
/**
|
|
1110
1231
|
* What the wallet actually holds, across every supported chain, restricted
|
|
1111
1232
|
* to tokens a swap could use.
|
|
@@ -1137,12 +1258,16 @@ declare class OwneySDK {
|
|
|
1137
1258
|
* tokens can share a ticker, and `providers` (how many token lists carry the
|
|
1138
1259
|
* address) is the only usable signal for telling them apart. Surface it.
|
|
1139
1260
|
*
|
|
1140
|
-
*
|
|
1261
|
+
* A blank query WITH a chainId lists that chain's catalogue instead of
|
|
1262
|
+
* searching it — what a picker wants when someone selects a chain before
|
|
1263
|
+
* typing anything. Blank with no chain returns nothing: that would be asking
|
|
1264
|
+
* for the top of every catalogue at once, which is a download, not a list.
|
|
1141
1265
|
*/
|
|
1142
1266
|
searchSwapTokens(params: {
|
|
1143
|
-
/** Omit to search every supported chain. */
|
|
1267
|
+
/** Omit to search every supported chain. Required to list one. */
|
|
1144
1268
|
chainId?: number;
|
|
1145
|
-
|
|
1269
|
+
/** Omit, with a chainId, to list the chain rather than search it. */
|
|
1270
|
+
query?: string;
|
|
1146
1271
|
limit?: number;
|
|
1147
1272
|
/**
|
|
1148
1273
|
* Which picker is asking. A withdrawal ends in the user's own wallet, so
|
|
@@ -1246,6 +1371,32 @@ declare class OwneySDK {
|
|
|
1246
1371
|
/** Percent, classic rail only. Fusion+ prices through its auction. */
|
|
1247
1372
|
slippage?: number;
|
|
1248
1373
|
onSwapProgress?: (stage: SwapStage) => void;
|
|
1374
|
+
/**
|
|
1375
|
+
* Fires once the order is with the relayer, before the watch.
|
|
1376
|
+
*
|
|
1377
|
+
* Both resolver-filled rails reach it — cross-chain Fusion+ and the
|
|
1378
|
+
* same-chain auction. Not the classic rail, which is one transaction with
|
|
1379
|
+
* no order behind it and resolves in seconds either way.
|
|
1380
|
+
*
|
|
1381
|
+
* The seam a backgrounded withdrawal hangs off. Up to here the flow needs
|
|
1382
|
+
* the user in front of it; past here it is polling that a later page load
|
|
1383
|
+
* can take over — from the stored preimages on Fusion+, and from the
|
|
1384
|
+
* order hash alone on the same-chain rail. So a caller may stop awaiting
|
|
1385
|
+
* this promise and let the screen go. See `swap.withdraw-swap.ts` for what
|
|
1386
|
+
* the caller should write down when it does.
|
|
1387
|
+
*
|
|
1388
|
+
* Carries the two figures a status bar cannot get anywhere else. The
|
|
1389
|
+
* withdrawal has already happened by this point and `withdrawn` is what
|
|
1390
|
+
* MEASURABLY arrived, which on a "MAX" withdrawal is the only figure that
|
|
1391
|
+
* exists — and it is also what comes back if the order never fills.
|
|
1392
|
+
*/
|
|
1393
|
+
onOrderSubmitted?: (submitted: {
|
|
1394
|
+
orderHash: string;
|
|
1395
|
+
/** Smallest unit of the agent's asset. */
|
|
1396
|
+
withdrawn: string;
|
|
1397
|
+
/** Smallest unit of the destination — the auction's start, not its floor. */
|
|
1398
|
+
expected: string;
|
|
1399
|
+
}) => void;
|
|
1249
1400
|
/** How long to wait for the withdrawal to land before giving up on the swap. */
|
|
1250
1401
|
arrivalTimeoutMs?: number;
|
|
1251
1402
|
}): Promise<{
|
|
@@ -1447,4 +1598,4 @@ type StoredOrder = {
|
|
|
1447
1598
|
*/
|
|
1448
1599
|
declare function listOrders(now?: number): StoredOrder[];
|
|
1449
1600
|
|
|
1450
|
-
export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LookbackDays, NotConnectedError, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawResult, type PendingDeposit, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, setOwneyDebug };
|
|
1601
|
+
export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LookbackDays, NotConnectedError, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawResult, type PendingDeposit, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, type WithdrawSwapRecord, type WithdrawSwapStatus, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };
|
package/dist/index.d.ts
CHANGED
|
@@ -785,6 +785,94 @@ declare class AgentChainIncompatibleError extends OwneyError {
|
|
|
785
785
|
}>, connectedChainId: number);
|
|
786
786
|
}
|
|
787
787
|
|
|
788
|
+
/**
|
|
789
|
+
* Withdrawal swaps the user has walked away from, and how they ended.
|
|
790
|
+
*
|
|
791
|
+
* The deposit side has `swap.pending-deposit.ts` for the same shape of
|
|
792
|
+
* problem, but the two are not symmetrical. A pending deposit is a JOB: the
|
|
793
|
+
* money is in the wallet and an ordinary deposit finishes it. This is a
|
|
794
|
+
* WATCH — the funds are in escrow, nothing the user does moves them along,
|
|
795
|
+
* and the only question is where they ended up.
|
|
796
|
+
*
|
|
797
|
+
* That is the whole reason this exists. `withdrawAndSwap` used to hold the
|
|
798
|
+
* screen for the entire escrow lifecycle, which on a slow mainnet fill is
|
|
799
|
+
* minutes of a modal the user cannot leave (ROUT-242). Backgrounding it means
|
|
800
|
+
* the outcome arrives after the UI that started it has gone, so the outcome
|
|
801
|
+
* has to be written down somewhere the next render can find it.
|
|
802
|
+
*
|
|
803
|
+
* Only cross-chain swaps are recorded. A same-chain classic swap is one
|
|
804
|
+
* transaction and resolves in seconds; a same-chain fusion order has no stored
|
|
805
|
+
* preimages, so there would be nothing for a reloaded session to resume and
|
|
806
|
+
* the record would sit at `swapping` for ever.
|
|
807
|
+
*
|
|
808
|
+
* Kept deliberately separate from the secret store. Secrets are retired the
|
|
809
|
+
* moment an order reaches a verdict — that is a safety property, not a display
|
|
810
|
+
* one — and the record has to outlive them so the user can still be told what
|
|
811
|
+
* happened after they come back.
|
|
812
|
+
*/
|
|
813
|
+
/**
|
|
814
|
+
* `swapping` is the only non-terminal state. `unknown` is what a watch that
|
|
815
|
+
* gave up looks like: we stopped polling before the order spoke, so the order
|
|
816
|
+
* may well have filled. It is not a failure, and it must never be shown as
|
|
817
|
+
* one.
|
|
818
|
+
*/
|
|
819
|
+
type WithdrawSwapStatus = "swapping" | "landed" | "refunded" | "unknown";
|
|
820
|
+
type WithdrawSwapRecord = {
|
|
821
|
+
/** Identity. One record per Fusion+ order. */
|
|
822
|
+
orderHash: string;
|
|
823
|
+
status: WithdrawSwapStatus;
|
|
824
|
+
/**
|
|
825
|
+
* What actually left the agent, smallest unit of the SOURCE asset.
|
|
826
|
+
*
|
|
827
|
+
* The measured figure, not the requested one — a "MAX" withdrawal has no
|
|
828
|
+
* requested figure at all, and this is what a refund gives back.
|
|
829
|
+
*/
|
|
830
|
+
withdrawn: string;
|
|
831
|
+
srcSymbol: string;
|
|
832
|
+
srcChainId: number;
|
|
833
|
+
srcDecimals: number;
|
|
834
|
+
/**
|
|
835
|
+
* What the quote expected to arrive, smallest unit of the DESTINATION.
|
|
836
|
+
*
|
|
837
|
+
* `dst.amount` — the auction's start, not its floor. The bar reads "about",
|
|
838
|
+
* and quoting the floor understated every completed withdrawal by half a
|
|
839
|
+
* percent (ROUT-242, comment 16056).
|
|
840
|
+
*/
|
|
841
|
+
expected: string;
|
|
842
|
+
dstSymbol: string;
|
|
843
|
+
dstChainId: number;
|
|
844
|
+
dstDecimals: number;
|
|
845
|
+
/** Measured arrival. Set only on `landed`, and shown in place of `expected`. */
|
|
846
|
+
received?: string;
|
|
847
|
+
/** Epoch ms. */
|
|
848
|
+
createdAt: number;
|
|
849
|
+
/** Epoch ms, set when the status stopped being `swapping`. */
|
|
850
|
+
settledAt?: number;
|
|
851
|
+
};
|
|
852
|
+
declare function subscribeWithdrawSwaps(listener: () => void): () => void;
|
|
853
|
+
/**
|
|
854
|
+
* Write the record as the order is submitted, alongside the secrets.
|
|
855
|
+
*
|
|
856
|
+
* Not after the swap resolves: the point is to survive the gap between submit
|
|
857
|
+
* and settle, which is exactly when the user closes the tab.
|
|
858
|
+
*/
|
|
859
|
+
declare function saveWithdrawSwap(record: WithdrawSwapRecord): void;
|
|
860
|
+
/**
|
|
861
|
+
* Move a record to its outcome.
|
|
862
|
+
*
|
|
863
|
+
* A no-op for an order with no record, which is the normal case for deposit
|
|
864
|
+
* swaps — they share the secret store and so pass through the same resume
|
|
865
|
+
* loop, but they are not withdrawals and were never recorded here.
|
|
866
|
+
*
|
|
867
|
+
* `settledAt` is stamped here rather than by the caller so every writer agrees
|
|
868
|
+
* on what "settled" means: the moment the status stopped being `swapping`.
|
|
869
|
+
*/
|
|
870
|
+
declare function updateWithdrawSwap(orderHash: string, patch: Partial<Omit<WithdrawSwapRecord, "orderHash">>): void;
|
|
871
|
+
/** The user has read the outcome. Only they do this. */
|
|
872
|
+
declare function clearWithdrawSwap(orderHash: string): void;
|
|
873
|
+
/** Every record, newest first, sweeping anything past MAX_AGE_MS. */
|
|
874
|
+
declare function listWithdrawSwaps(now?: number): WithdrawSwapRecord[];
|
|
875
|
+
|
|
788
876
|
/**
|
|
789
877
|
* Swaps that landed but were never deposited.
|
|
790
878
|
*
|
|
@@ -1071,6 +1159,21 @@ declare class OwneySDK {
|
|
|
1071
1159
|
* describe. See `completePendingDeposit`.
|
|
1072
1160
|
*/
|
|
1073
1161
|
listPendingDeposits(): ReturnType<typeof listPendingDeposits>;
|
|
1162
|
+
/**
|
|
1163
|
+
* Backgrounded withdrawal swaps and how they ended, newest first.
|
|
1164
|
+
*
|
|
1165
|
+
* Nothing to act on — unlike `listPendingDeposits`, which describes a job the
|
|
1166
|
+
* user can finish. This is a watch: the funds are in escrow and the only
|
|
1167
|
+
* open question is where they land. See `swap.withdraw-swap.ts`.
|
|
1168
|
+
*/
|
|
1169
|
+
listWithdrawSwaps(): WithdrawSwapRecord[];
|
|
1170
|
+
/**
|
|
1171
|
+
* Retire a settled record. The user has read the outcome.
|
|
1172
|
+
*
|
|
1173
|
+
* Only they do this — a record that disappears on its own takes with it the
|
|
1174
|
+
* only thing telling someone where their money went.
|
|
1175
|
+
*/
|
|
1176
|
+
dismissWithdrawSwap(orderHash: string): void;
|
|
1074
1177
|
/**
|
|
1075
1178
|
* Deposit a swap that already landed.
|
|
1076
1179
|
*
|
|
@@ -1106,6 +1209,24 @@ declare class OwneySDK {
|
|
|
1106
1209
|
status: "completed" | "unfinished";
|
|
1107
1210
|
error?: OwneyError;
|
|
1108
1211
|
}[]>;
|
|
1212
|
+
/**
|
|
1213
|
+
* Pick up SAME-CHAIN orders a previous session left in the auction.
|
|
1214
|
+
*
|
|
1215
|
+
* They are not in the secret store and never will be: that store exists to
|
|
1216
|
+
* keep preimages, and a same-chain fill needs none — the resolver takes the
|
|
1217
|
+
* maker's tokens and delivers the taker's in one transaction. So the only
|
|
1218
|
+
* record of one is the withdrawal record itself, which carries the order
|
|
1219
|
+
* hash, and that is all a resume needs here.
|
|
1220
|
+
*
|
|
1221
|
+
* Gentler than the Fusion+ case in the way that matters. Nothing is
|
|
1222
|
+
* escrowed, so an order nobody ever picks up leaves the wallet exactly as it
|
|
1223
|
+
* was — this is catching up on news, not rescuing funds.
|
|
1224
|
+
*
|
|
1225
|
+
* Same-chain is read off the record rather than stored as a rail: a
|
|
1226
|
+
* withdrawal whose source and destination share a chain could not have been
|
|
1227
|
+
* anything else.
|
|
1228
|
+
*/
|
|
1229
|
+
private resumeSameChainSwaps;
|
|
1109
1230
|
/**
|
|
1110
1231
|
* What the wallet actually holds, across every supported chain, restricted
|
|
1111
1232
|
* to tokens a swap could use.
|
|
@@ -1137,12 +1258,16 @@ declare class OwneySDK {
|
|
|
1137
1258
|
* tokens can share a ticker, and `providers` (how many token lists carry the
|
|
1138
1259
|
* address) is the only usable signal for telling them apart. Surface it.
|
|
1139
1260
|
*
|
|
1140
|
-
*
|
|
1261
|
+
* A blank query WITH a chainId lists that chain's catalogue instead of
|
|
1262
|
+
* searching it — what a picker wants when someone selects a chain before
|
|
1263
|
+
* typing anything. Blank with no chain returns nothing: that would be asking
|
|
1264
|
+
* for the top of every catalogue at once, which is a download, not a list.
|
|
1141
1265
|
*/
|
|
1142
1266
|
searchSwapTokens(params: {
|
|
1143
|
-
/** Omit to search every supported chain. */
|
|
1267
|
+
/** Omit to search every supported chain. Required to list one. */
|
|
1144
1268
|
chainId?: number;
|
|
1145
|
-
|
|
1269
|
+
/** Omit, with a chainId, to list the chain rather than search it. */
|
|
1270
|
+
query?: string;
|
|
1146
1271
|
limit?: number;
|
|
1147
1272
|
/**
|
|
1148
1273
|
* Which picker is asking. A withdrawal ends in the user's own wallet, so
|
|
@@ -1246,6 +1371,32 @@ declare class OwneySDK {
|
|
|
1246
1371
|
/** Percent, classic rail only. Fusion+ prices through its auction. */
|
|
1247
1372
|
slippage?: number;
|
|
1248
1373
|
onSwapProgress?: (stage: SwapStage) => void;
|
|
1374
|
+
/**
|
|
1375
|
+
* Fires once the order is with the relayer, before the watch.
|
|
1376
|
+
*
|
|
1377
|
+
* Both resolver-filled rails reach it — cross-chain Fusion+ and the
|
|
1378
|
+
* same-chain auction. Not the classic rail, which is one transaction with
|
|
1379
|
+
* no order behind it and resolves in seconds either way.
|
|
1380
|
+
*
|
|
1381
|
+
* The seam a backgrounded withdrawal hangs off. Up to here the flow needs
|
|
1382
|
+
* the user in front of it; past here it is polling that a later page load
|
|
1383
|
+
* can take over — from the stored preimages on Fusion+, and from the
|
|
1384
|
+
* order hash alone on the same-chain rail. So a caller may stop awaiting
|
|
1385
|
+
* this promise and let the screen go. See `swap.withdraw-swap.ts` for what
|
|
1386
|
+
* the caller should write down when it does.
|
|
1387
|
+
*
|
|
1388
|
+
* Carries the two figures a status bar cannot get anywhere else. The
|
|
1389
|
+
* withdrawal has already happened by this point and `withdrawn` is what
|
|
1390
|
+
* MEASURABLY arrived, which on a "MAX" withdrawal is the only figure that
|
|
1391
|
+
* exists — and it is also what comes back if the order never fills.
|
|
1392
|
+
*/
|
|
1393
|
+
onOrderSubmitted?: (submitted: {
|
|
1394
|
+
orderHash: string;
|
|
1395
|
+
/** Smallest unit of the agent's asset. */
|
|
1396
|
+
withdrawn: string;
|
|
1397
|
+
/** Smallest unit of the destination — the auction's start, not its floor. */
|
|
1398
|
+
expected: string;
|
|
1399
|
+
}) => void;
|
|
1249
1400
|
/** How long to wait for the withdrawal to land before giving up on the swap. */
|
|
1250
1401
|
arrivalTimeoutMs?: number;
|
|
1251
1402
|
}): Promise<{
|
|
@@ -1447,4 +1598,4 @@ type StoredOrder = {
|
|
|
1447
1598
|
*/
|
|
1448
1599
|
declare function listOrders(now?: number): StoredOrder[];
|
|
1449
1600
|
|
|
1450
|
-
export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LookbackDays, NotConnectedError, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawResult, type PendingDeposit, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, setOwneyDebug };
|
|
1601
|
+
export { type AccountAgentApy, type AccountApyOptions, type AccountDailyEarnings, type AgentApy, type AgentApyDetails, type AgentBalance, AgentChainIncompatibleError, type AgentEarnings, type AgentHistoryEntry, type AgentHistoryPosition, type AgentId, AgentNotFoundError, type AgentSupportedAsset, type AgentSupportedAssets, type AgentUserProfile, type AgentWithdrawResult, type AgentsApyOptions, type AllocationAgentApy, type AllocationApyOptions, type ApyByChainAndAsset, type ApyHistoryPoint, type Asset, type AssetDailyEarnings, type AvailableAgent, type AvailableAgentsOptions, type ConnectionState, type DailyApyDays, type DailyEarningsOptions, type DailyEarningsPoint, type DepositCallback, type DepositOptions, type HistoryAction, type HistoryFilters, type HistoryOptions, type HistoryTransaction, type IAgent, InvalidHistoryCursorError, type LookbackDays, NotConnectedError, type OwneyAccountApy, type OwneyAgentApy, type OwneyAgentHistory, type OwneyAllocationApy, type OwneyBalances, type OwneyDepositResult, type OwneyEarnings, OwneyError, type OwneyErrorCode, type OwneyMultiDepositResult, type OwneyPosition, OwneySDK, type OwneySDKConfig, type OwneySIWXConfig, type OwneySupportedChainId, type OwneySupportedChains, type OwneySupportedTokens, type OwneyToken, type OwneyUserProfile, type OwneyWithdrawResult, type PendingDeposit, type RebalanceLog, type SwapChainTokens, type SwapDirection, type SwapOrderStatus, type SwapQuote, type SwapQuoteParams, type SwapRail, type SwapStage, type SwapTokenInfo, type SwapTokenSearchResult, type WithdrawOptions, type WithdrawSwapRecord, type WithdrawSwapStatus, clearWithdrawSwap, createOwneySIWX, listPendingDeposits, listOrders as listPendingSwaps, listWithdrawSwaps, saveWithdrawSwap, setOwneyDebug, subscribeWithdrawSwaps, updateWithdrawSwap };
|
package/dist/index.js
CHANGED
|
@@ -263,6 +263,15 @@ var DayFilterMapping = {
|
|
|
263
263
|
"7D": 7
|
|
264
264
|
};
|
|
265
265
|
|
|
266
|
+
// src/lib/helpers/asset-aliases.ts
|
|
267
|
+
function assetAliases(asset) {
|
|
268
|
+
const normalised = asset.toLowerCase();
|
|
269
|
+
return normalised === "weth" ? ["weth", "eth"] : [normalised];
|
|
270
|
+
}
|
|
271
|
+
function matchesAsset(symbol, asset) {
|
|
272
|
+
return assetAliases(asset).includes(symbol.toLowerCase());
|
|
273
|
+
}
|
|
274
|
+
|
|
266
275
|
// src/agents/zyfai/zyfai.mapper.ts
|
|
267
276
|
var DECIMALS_BY_SYMBOL = {
|
|
268
277
|
usdc: 6,
|
|
@@ -667,9 +676,8 @@ function computeAllocationApy(positions) {
|
|
|
667
676
|
function earningsForToken(bucket, chainId, asset) {
|
|
668
677
|
const tokens = bucket?.[String(chainId)];
|
|
669
678
|
if (!tokens) return null;
|
|
670
|
-
const wanted = asset.toUpperCase();
|
|
671
679
|
for (const [symbol, value] of Object.entries(tokens)) {
|
|
672
|
-
if (symbol
|
|
680
|
+
if (!matchesAsset(symbol, asset)) continue;
|
|
673
681
|
const amount = Number(value);
|
|
674
682
|
return Number.isFinite(amount) ? amount : null;
|
|
675
683
|
}
|
|
@@ -2294,7 +2302,7 @@ function createSwapApi(baseUrl, apiKey) {
|
|
|
2294
2302
|
baseUrl,
|
|
2295
2303
|
apiKey,
|
|
2296
2304
|
`/tokens/search?${new URLSearchParams({
|
|
2297
|
-
query: params.query,
|
|
2305
|
+
...params.query === void 0 ? {} : { query: params.query },
|
|
2298
2306
|
// Omitted, the routing API searches every supported chain — which is
|
|
2299
2307
|
// what a picker wants, since its rows already span all three.
|
|
2300
2308
|
...params.chainId === void 0 ? {} : { chainId: String(params.chainId) },
|
|
@@ -3097,6 +3105,10 @@ async function runSameChainFusion(deps, options, walletAddress) {
|
|
|
3097
3105
|
quoteId: built.quoteId,
|
|
3098
3106
|
...built.extension ? { extension: built.extension } : {}
|
|
3099
3107
|
});
|
|
3108
|
+
try {
|
|
3109
|
+
options.onOrderSubmitted?.(built.orderHash);
|
|
3110
|
+
} catch {
|
|
3111
|
+
}
|
|
3100
3112
|
await runSameChainOrder(deps.sameChainRunner ?? deps.runner, {
|
|
3101
3113
|
orderHash: built.orderHash,
|
|
3102
3114
|
...onStage ? { onStage } : {}
|
|
@@ -3195,6 +3207,10 @@ async function runFusion(deps, options, walletAddress) {
|
|
|
3195
3207
|
...built.extension ? { extension: built.extension } : {}
|
|
3196
3208
|
});
|
|
3197
3209
|
debugLog("owney-sdk", "swap: order submitted, polling escrows");
|
|
3210
|
+
try {
|
|
3211
|
+
options.onOrderSubmitted?.(built.orderHash);
|
|
3212
|
+
} catch {
|
|
3213
|
+
}
|
|
3198
3214
|
try {
|
|
3199
3215
|
await runFusionOrder(deps.runner, {
|
|
3200
3216
|
orderHash: built.orderHash,
|
|
@@ -3314,8 +3330,8 @@ async function buildErc2612Permit(reads, input) {
|
|
|
3314
3330
|
);
|
|
3315
3331
|
}
|
|
3316
3332
|
|
|
3317
|
-
// src/lib/swap/swap.
|
|
3318
|
-
var KEY_PREFIX3 = "owney.swap.
|
|
3333
|
+
// src/lib/swap/swap.withdraw-swap.ts
|
|
3334
|
+
var KEY_PREFIX3 = "owney.swap.withdraw";
|
|
3319
3335
|
var MAX_AGE_MS2 = 24 * 60 * 60 * 1e3;
|
|
3320
3336
|
var storage3 = () => {
|
|
3321
3337
|
if (typeof window === "undefined") return null;
|
|
@@ -3325,26 +3341,60 @@ var storage3 = () => {
|
|
|
3325
3341
|
return null;
|
|
3326
3342
|
}
|
|
3327
3343
|
};
|
|
3328
|
-
var keyFor2 = (
|
|
3329
|
-
|
|
3344
|
+
var keyFor2 = (orderHash) => `${KEY_PREFIX3}.${orderHash}`;
|
|
3345
|
+
var listeners = /* @__PURE__ */ new Set();
|
|
3346
|
+
function subscribeWithdrawSwaps(listener) {
|
|
3347
|
+
listeners.add(listener);
|
|
3348
|
+
return () => {
|
|
3349
|
+
listeners.delete(listener);
|
|
3350
|
+
};
|
|
3351
|
+
}
|
|
3352
|
+
var notify = () => {
|
|
3353
|
+
for (const listener of listeners) {
|
|
3354
|
+
try {
|
|
3355
|
+
listener();
|
|
3356
|
+
} catch {
|
|
3357
|
+
}
|
|
3358
|
+
}
|
|
3359
|
+
};
|
|
3360
|
+
function saveWithdrawSwap(record) {
|
|
3330
3361
|
const store = storage3();
|
|
3331
3362
|
if (!store) return;
|
|
3332
3363
|
try {
|
|
3333
|
-
store.setItem(keyFor2(
|
|
3364
|
+
store.setItem(keyFor2(record.orderHash), JSON.stringify(record));
|
|
3334
3365
|
} catch {
|
|
3335
3366
|
return;
|
|
3336
3367
|
}
|
|
3368
|
+
notify();
|
|
3337
3369
|
}
|
|
3338
|
-
function
|
|
3370
|
+
function updateWithdrawSwap(orderHash, patch) {
|
|
3339
3371
|
const store = storage3();
|
|
3340
3372
|
if (!store) return;
|
|
3341
3373
|
try {
|
|
3342
|
-
store.
|
|
3374
|
+
const raw = store.getItem(keyFor2(orderHash));
|
|
3375
|
+
if (!raw) return;
|
|
3376
|
+
const current = JSON.parse(raw);
|
|
3377
|
+
const next = { ...current, ...patch };
|
|
3378
|
+
if (next.status !== "swapping" && current.status === "swapping" && next.settledAt === void 0) {
|
|
3379
|
+
next.settledAt = Date.now();
|
|
3380
|
+
}
|
|
3381
|
+
store.setItem(keyFor2(orderHash), JSON.stringify(next));
|
|
3343
3382
|
} catch {
|
|
3344
3383
|
return;
|
|
3345
3384
|
}
|
|
3385
|
+
notify();
|
|
3346
3386
|
}
|
|
3347
|
-
function
|
|
3387
|
+
function clearWithdrawSwap(orderHash) {
|
|
3388
|
+
const store = storage3();
|
|
3389
|
+
if (!store) return;
|
|
3390
|
+
try {
|
|
3391
|
+
store.removeItem(keyFor2(orderHash));
|
|
3392
|
+
} catch {
|
|
3393
|
+
return;
|
|
3394
|
+
}
|
|
3395
|
+
notify();
|
|
3396
|
+
}
|
|
3397
|
+
function listWithdrawSwaps(now = Date.now()) {
|
|
3348
3398
|
const store = storage3();
|
|
3349
3399
|
if (!store) return [];
|
|
3350
3400
|
const out = [];
|
|
@@ -3374,6 +3424,66 @@ function listPendingDeposits(now = Date.now()) {
|
|
|
3374
3424
|
return out.sort((a, b) => b.createdAt - a.createdAt);
|
|
3375
3425
|
}
|
|
3376
3426
|
|
|
3427
|
+
// src/lib/swap/swap.pending-deposit.ts
|
|
3428
|
+
var KEY_PREFIX4 = "owney.swap.pending-deposit";
|
|
3429
|
+
var MAX_AGE_MS3 = 24 * 60 * 60 * 1e3;
|
|
3430
|
+
var storage4 = () => {
|
|
3431
|
+
if (typeof window === "undefined") return null;
|
|
3432
|
+
try {
|
|
3433
|
+
return window.localStorage;
|
|
3434
|
+
} catch {
|
|
3435
|
+
return null;
|
|
3436
|
+
}
|
|
3437
|
+
};
|
|
3438
|
+
var keyFor3 = (id) => `${KEY_PREFIX4}.${id}`;
|
|
3439
|
+
function savePendingDeposit(entry) {
|
|
3440
|
+
const store = storage4();
|
|
3441
|
+
if (!store) return;
|
|
3442
|
+
try {
|
|
3443
|
+
store.setItem(keyFor3(entry.id), JSON.stringify(entry));
|
|
3444
|
+
} catch {
|
|
3445
|
+
return;
|
|
3446
|
+
}
|
|
3447
|
+
}
|
|
3448
|
+
function clearPendingDeposit(id) {
|
|
3449
|
+
const store = storage4();
|
|
3450
|
+
if (!store) return;
|
|
3451
|
+
try {
|
|
3452
|
+
store.removeItem(keyFor3(id));
|
|
3453
|
+
} catch {
|
|
3454
|
+
return;
|
|
3455
|
+
}
|
|
3456
|
+
}
|
|
3457
|
+
function listPendingDeposits(now = Date.now()) {
|
|
3458
|
+
const store = storage4();
|
|
3459
|
+
if (!store) return [];
|
|
3460
|
+
const out = [];
|
|
3461
|
+
try {
|
|
3462
|
+
const keys = [];
|
|
3463
|
+
for (let i = 0; i < store.length; i++) {
|
|
3464
|
+
const key2 = store.key(i);
|
|
3465
|
+
if (key2?.startsWith(`${KEY_PREFIX4}.`)) keys.push(key2);
|
|
3466
|
+
}
|
|
3467
|
+
for (const key2 of keys) {
|
|
3468
|
+
const raw = store.getItem(key2);
|
|
3469
|
+
if (!raw) continue;
|
|
3470
|
+
try {
|
|
3471
|
+
const parsed = JSON.parse(raw);
|
|
3472
|
+
if (now - parsed.createdAt > MAX_AGE_MS3) {
|
|
3473
|
+
store.removeItem(key2);
|
|
3474
|
+
continue;
|
|
3475
|
+
}
|
|
3476
|
+
out.push(parsed);
|
|
3477
|
+
} catch {
|
|
3478
|
+
store.removeItem(key2);
|
|
3479
|
+
}
|
|
3480
|
+
}
|
|
3481
|
+
} catch {
|
|
3482
|
+
return out;
|
|
3483
|
+
}
|
|
3484
|
+
return out.sort((a, b) => b.createdAt - a.createdAt);
|
|
3485
|
+
}
|
|
3486
|
+
|
|
3377
3487
|
// src/lib/health-report.ts
|
|
3378
3488
|
var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
3379
3489
|
async function reportAgentFailure(apiKey, agentType, errorCode, baseUrl = ROUTING_API_BASE_URL2) {
|
|
@@ -3410,11 +3520,10 @@ async function withFailureReporting(apiKey, agentType, fn, baseUrl) {
|
|
|
3410
3520
|
// src/lib/helpers/withdraw-helper.ts
|
|
3411
3521
|
import { parseUnits } from "viem";
|
|
3412
3522
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
3413
|
-
const target = asset.toUpperCase();
|
|
3414
3523
|
return agents.map((agent) => {
|
|
3415
3524
|
const agentBalance = aggregated[agent.id];
|
|
3416
3525
|
const tokenBalance = agentBalance?.tokens.find(
|
|
3417
|
-
(t) => t.chainId === chainId && t.asset
|
|
3526
|
+
(t) => t.chainId === chainId && matchesAsset(t.asset, asset)
|
|
3418
3527
|
);
|
|
3419
3528
|
if (!tokenBalance) return { agent, balance: 0n };
|
|
3420
3529
|
return { agent, balance: parseUnits(tokenBalance.amount, decimals) };
|
|
@@ -4721,15 +4830,14 @@ var OwneySDK = class {
|
|
|
4721
4830
|
async hasExistingBalance(agent, state, chainId, asset, requireReliableRead = false) {
|
|
4722
4831
|
try {
|
|
4723
4832
|
const balance = await agent.getBalances(state, chainId);
|
|
4724
|
-
const target = asset.toLowerCase();
|
|
4725
4833
|
const token = balance.tokens.find(
|
|
4726
|
-
(t) => t.chainId === chainId && t.asset
|
|
4834
|
+
(t) => t.chainId === chainId && matchesAsset(t.asset, asset)
|
|
4727
4835
|
);
|
|
4728
4836
|
const targetChainName = agent.supportedAssets.find((entry) => entry.chainId === chainId)?.chain?.trim().toUpperCase();
|
|
4729
4837
|
const position = (balance.positions ?? []).find((p) => {
|
|
4730
4838
|
const positionChain = p.chain.trim().toUpperCase();
|
|
4731
4839
|
const matchesChain = positionChain === String(chainId) || targetChainName !== void 0 && positionChain === targetChainName;
|
|
4732
|
-
return matchesChain && p.asset
|
|
4840
|
+
return matchesChain && matchesAsset(p.asset, asset) && Number(p.amount) > 0;
|
|
4733
4841
|
});
|
|
4734
4842
|
return !!token && Number(token.amount) > 0 || !!position;
|
|
4735
4843
|
} catch (error) {
|
|
@@ -5134,6 +5242,25 @@ var OwneySDK = class {
|
|
|
5134
5242
|
listPendingDeposits() {
|
|
5135
5243
|
return listPendingDeposits();
|
|
5136
5244
|
}
|
|
5245
|
+
/**
|
|
5246
|
+
* Backgrounded withdrawal swaps and how they ended, newest first.
|
|
5247
|
+
*
|
|
5248
|
+
* Nothing to act on — unlike `listPendingDeposits`, which describes a job the
|
|
5249
|
+
* user can finish. This is a watch: the funds are in escrow and the only
|
|
5250
|
+
* open question is where they land. See `swap.withdraw-swap.ts`.
|
|
5251
|
+
*/
|
|
5252
|
+
listWithdrawSwaps() {
|
|
5253
|
+
return listWithdrawSwaps();
|
|
5254
|
+
}
|
|
5255
|
+
/**
|
|
5256
|
+
* Retire a settled record. The user has read the outcome.
|
|
5257
|
+
*
|
|
5258
|
+
* Only they do this — a record that disappears on its own takes with it the
|
|
5259
|
+
* only thing telling someone where their money went.
|
|
5260
|
+
*/
|
|
5261
|
+
dismissWithdrawSwap(orderHash) {
|
|
5262
|
+
clearWithdrawSwap(orderHash);
|
|
5263
|
+
}
|
|
5137
5264
|
/**
|
|
5138
5265
|
* Deposit a swap that already landed.
|
|
5139
5266
|
*
|
|
@@ -5180,7 +5307,10 @@ var OwneySDK = class {
|
|
|
5180
5307
|
*/
|
|
5181
5308
|
async resumePendingSwaps(options = {}) {
|
|
5182
5309
|
const pending = listOrders();
|
|
5183
|
-
if (pending.length === 0)
|
|
5310
|
+
if (pending.length === 0) {
|
|
5311
|
+
await this.resumeSameChainSwaps(options);
|
|
5312
|
+
return [];
|
|
5313
|
+
}
|
|
5184
5314
|
const runner = this.swapRunnerDeps();
|
|
5185
5315
|
const results = [];
|
|
5186
5316
|
for (const order of pending) {
|
|
@@ -5194,6 +5324,7 @@ var OwneySDK = class {
|
|
|
5194
5324
|
} : {}
|
|
5195
5325
|
});
|
|
5196
5326
|
clearOrder(order.orderHash);
|
|
5327
|
+
updateWithdrawSwap(order.orderHash, { status: "landed" });
|
|
5197
5328
|
results.push({
|
|
5198
5329
|
orderHash: order.orderHash,
|
|
5199
5330
|
status: "completed"
|
|
@@ -5201,6 +5332,9 @@ var OwneySDK = class {
|
|
|
5201
5332
|
} catch (error) {
|
|
5202
5333
|
if (error instanceof OwneyError && (error.code === "SWAP_ORDER_REFUNDED" || error.code === "SWAP_ORDER_CANCELLED")) {
|
|
5203
5334
|
clearOrder(order.orderHash);
|
|
5335
|
+
updateWithdrawSwap(order.orderHash, { status: "refunded" });
|
|
5336
|
+
} else {
|
|
5337
|
+
updateWithdrawSwap(order.orderHash, { status: "unknown" });
|
|
5204
5338
|
}
|
|
5205
5339
|
results.push({
|
|
5206
5340
|
orderHash: order.orderHash,
|
|
@@ -5209,8 +5343,56 @@ var OwneySDK = class {
|
|
|
5209
5343
|
});
|
|
5210
5344
|
}
|
|
5211
5345
|
}
|
|
5346
|
+
await this.resumeSameChainSwaps(options);
|
|
5212
5347
|
return results;
|
|
5213
5348
|
}
|
|
5349
|
+
/**
|
|
5350
|
+
* Pick up SAME-CHAIN orders a previous session left in the auction.
|
|
5351
|
+
*
|
|
5352
|
+
* They are not in the secret store and never will be: that store exists to
|
|
5353
|
+
* keep preimages, and a same-chain fill needs none — the resolver takes the
|
|
5354
|
+
* maker's tokens and delivers the taker's in one transaction. So the only
|
|
5355
|
+
* record of one is the withdrawal record itself, which carries the order
|
|
5356
|
+
* hash, and that is all a resume needs here.
|
|
5357
|
+
*
|
|
5358
|
+
* Gentler than the Fusion+ case in the way that matters. Nothing is
|
|
5359
|
+
* escrowed, so an order nobody ever picks up leaves the wallet exactly as it
|
|
5360
|
+
* was — this is catching up on news, not rescuing funds.
|
|
5361
|
+
*
|
|
5362
|
+
* Same-chain is read off the record rather than stored as a rail: a
|
|
5363
|
+
* withdrawal whose source and destination share a chain could not have been
|
|
5364
|
+
* anything else.
|
|
5365
|
+
*/
|
|
5366
|
+
async resumeSameChainSwaps(options = {}) {
|
|
5367
|
+
const running = listWithdrawSwaps().filter(
|
|
5368
|
+
(record) => record.status === "swapping" && record.srcChainId === record.dstChainId
|
|
5369
|
+
);
|
|
5370
|
+
for (const record of running) {
|
|
5371
|
+
const runner = {
|
|
5372
|
+
// The chain bound in. That product keys its orders per chain, and the
|
|
5373
|
+
// Fusion+ endpoint answers 404 for one — which would read as an order
|
|
5374
|
+
// that vanished rather than one still in the auction.
|
|
5375
|
+
orderStatus: (h) => this.swapApi().orderStatus(h, record.srcChainId),
|
|
5376
|
+
sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),
|
|
5377
|
+
now: () => Date.now()
|
|
5378
|
+
};
|
|
5379
|
+
try {
|
|
5380
|
+
await runSameChainOrder(runner, {
|
|
5381
|
+
orderHash: record.orderHash,
|
|
5382
|
+
...options.timeoutMs === void 0 ? {} : { timeoutMs: options.timeoutMs },
|
|
5383
|
+
...options.onStage ? {
|
|
5384
|
+
onStage: (stage) => options.onStage(record.orderHash, stage)
|
|
5385
|
+
} : {}
|
|
5386
|
+
});
|
|
5387
|
+
updateWithdrawSwap(record.orderHash, { status: "landed" });
|
|
5388
|
+
} catch (error) {
|
|
5389
|
+
const code = error instanceof OwneyError ? error.code : void 0;
|
|
5390
|
+
updateWithdrawSwap(record.orderHash, {
|
|
5391
|
+
status: code === "SWAP_ORDER_EXPIRED" || code === "SWAP_ORDER_CANCELLED" ? "refunded" : "unknown"
|
|
5392
|
+
});
|
|
5393
|
+
}
|
|
5394
|
+
}
|
|
5395
|
+
}
|
|
5214
5396
|
/**
|
|
5215
5397
|
* What the wallet actually holds, across every supported chain, restricted
|
|
5216
5398
|
* to tokens a swap could use.
|
|
@@ -5257,13 +5439,16 @@ var OwneySDK = class {
|
|
|
5257
5439
|
* tokens can share a ticker, and `providers` (how many token lists carry the
|
|
5258
5440
|
* address) is the only usable signal for telling them apart. Surface it.
|
|
5259
5441
|
*
|
|
5260
|
-
*
|
|
5442
|
+
* A blank query WITH a chainId lists that chain's catalogue instead of
|
|
5443
|
+
* searching it — what a picker wants when someone selects a chain before
|
|
5444
|
+
* typing anything. Blank with no chain returns nothing: that would be asking
|
|
5445
|
+
* for the top of every catalogue at once, which is a download, not a list.
|
|
5261
5446
|
*/
|
|
5262
5447
|
async searchSwapTokens(params) {
|
|
5263
|
-
const query = params.query
|
|
5264
|
-
if (!query) return { tokens: [] };
|
|
5448
|
+
const query = params.query?.trim() ?? "";
|
|
5449
|
+
if (!query && params.chainId === void 0) return { tokens: [] };
|
|
5265
5450
|
return this.swapApi().searchTokens({
|
|
5266
|
-
query,
|
|
5451
|
+
...query ? { query } : {},
|
|
5267
5452
|
...params.chainId === void 0 ? {} : { chainId: params.chainId },
|
|
5268
5453
|
...params.limit === void 0 ? {} : { limit: params.limit },
|
|
5269
5454
|
...params.direction === void 0 ? {} : { direction: params.direction }
|
|
@@ -5443,7 +5628,14 @@ var OwneySDK = class {
|
|
|
5443
5628
|
walletAddress: state.walletAddress,
|
|
5444
5629
|
direction: "withdraw",
|
|
5445
5630
|
...options.slippage === void 0 ? {} : { slippage: options.slippage },
|
|
5446
|
-
...options.onSwapProgress ? { onStage: options.onSwapProgress } : {}
|
|
5631
|
+
...options.onSwapProgress ? { onStage: options.onSwapProgress } : {},
|
|
5632
|
+
...options.onOrderSubmitted ? {
|
|
5633
|
+
onOrderSubmitted: (orderHash) => options.onOrderSubmitted({
|
|
5634
|
+
orderHash,
|
|
5635
|
+
withdrawn,
|
|
5636
|
+
expected: quote.dst.amount
|
|
5637
|
+
})
|
|
5638
|
+
} : {}
|
|
5447
5639
|
});
|
|
5448
5640
|
return { withdraw, withdrawn, swap };
|
|
5449
5641
|
} catch (error) {
|
|
@@ -6202,8 +6394,8 @@ import { SiweMessage } from "siwe";
|
|
|
6202
6394
|
import { ZyfaiSDK as ZyfaiSDK2 } from "@zyfai/sdk";
|
|
6203
6395
|
|
|
6204
6396
|
// src/agents/zyfai/zyfai.siwx-cache.ts
|
|
6205
|
-
var
|
|
6206
|
-
var
|
|
6397
|
+
var KEY_PREFIX5 = "owney.siwx.session";
|
|
6398
|
+
var storage5 = () => {
|
|
6207
6399
|
if (typeof window === "undefined") return null;
|
|
6208
6400
|
try {
|
|
6209
6401
|
return window.localStorage;
|
|
@@ -6211,8 +6403,8 @@ var storage4 = () => {
|
|
|
6211
6403
|
return null;
|
|
6212
6404
|
}
|
|
6213
6405
|
};
|
|
6214
|
-
var buildKey2 = (address) => `${
|
|
6215
|
-
var legacyKeyPrefix2 = (address) => `${
|
|
6406
|
+
var buildKey2 = (address) => `${KEY_PREFIX5}:${address.toLowerCase()}`;
|
|
6407
|
+
var legacyKeyPrefix2 = (address) => `${KEY_PREFIX5}:${address.toLowerCase()}:`;
|
|
6216
6408
|
var memorySiwxSessions = /* @__PURE__ */ new Map();
|
|
6217
6409
|
var readLegacySiwxSession = (store, address) => {
|
|
6218
6410
|
if (!store) return null;
|
|
@@ -6244,7 +6436,7 @@ var readLegacySiwxSession = (store, address) => {
|
|
|
6244
6436
|
var readSiwxSession = (address, chainId) => {
|
|
6245
6437
|
if (typeof window === "undefined") return null;
|
|
6246
6438
|
const key2 = buildKey2(address);
|
|
6247
|
-
const store =
|
|
6439
|
+
const store = storage5();
|
|
6248
6440
|
let raw = null;
|
|
6249
6441
|
try {
|
|
6250
6442
|
raw = store?.getItem(key2) ?? null;
|
|
@@ -6274,7 +6466,7 @@ var writeSiwxSession = (address, _chainId, session) => {
|
|
|
6274
6466
|
if (typeof window === "undefined") return;
|
|
6275
6467
|
const key2 = buildKey2(address);
|
|
6276
6468
|
memorySiwxSessions.set(key2, session);
|
|
6277
|
-
const store =
|
|
6469
|
+
const store = storage5();
|
|
6278
6470
|
try {
|
|
6279
6471
|
store?.setItem(key2, JSON.stringify(session));
|
|
6280
6472
|
} catch {
|
|
@@ -6283,7 +6475,7 @@ var writeSiwxSession = (address, _chainId, session) => {
|
|
|
6283
6475
|
var clearSiwxSession = (address, _chainId) => {
|
|
6284
6476
|
const key2 = buildKey2(address);
|
|
6285
6477
|
memorySiwxSessions.delete(key2);
|
|
6286
|
-
const store =
|
|
6478
|
+
const store = storage5();
|
|
6287
6479
|
try {
|
|
6288
6480
|
store?.removeItem(key2);
|
|
6289
6481
|
} catch {
|
|
@@ -6415,8 +6607,13 @@ export {
|
|
|
6415
6607
|
NotConnectedError,
|
|
6416
6608
|
OwneyError,
|
|
6417
6609
|
OwneySDK,
|
|
6610
|
+
clearWithdrawSwap,
|
|
6418
6611
|
createOwneySIWX,
|
|
6419
6612
|
listPendingDeposits,
|
|
6420
6613
|
listOrders as listPendingSwaps,
|
|
6421
|
-
|
|
6614
|
+
listWithdrawSwaps,
|
|
6615
|
+
saveWithdrawSwap,
|
|
6616
|
+
setOwneyDebug,
|
|
6617
|
+
subscribeWithdrawSwaps,
|
|
6618
|
+
updateWithdrawSwap
|
|
6422
6619
|
};
|