@owney/sdk 0.7.25-beta.20 → 0.7.25-beta.21
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 +368 -276
- package/dist/index.d.cts +8 -3
- package/dist/index.d.ts +8 -3
- package/dist/index.js +350 -258
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -286,6 +286,240 @@ var AgentChainIncompatibleError = class extends OwneyError {
|
|
|
286
286
|
}
|
|
287
287
|
};
|
|
288
288
|
|
|
289
|
+
// src/lib/transfer-auth.ts
|
|
290
|
+
var import_viem2 = require("viem");
|
|
291
|
+
|
|
292
|
+
// src/lib/sponsor-client.ts
|
|
293
|
+
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
294
|
+
async function postPaymasterIntent(input) {
|
|
295
|
+
const base6 = input.baseUrl ?? ROUTING_API_BASE_URL;
|
|
296
|
+
let res;
|
|
297
|
+
try {
|
|
298
|
+
res = await fetch(`${base6}/api/v1/sponsor/paymaster-intent`, {
|
|
299
|
+
method: "POST",
|
|
300
|
+
headers: {
|
|
301
|
+
"content-type": "application/json",
|
|
302
|
+
"x-owney-api-key": input.apiKey,
|
|
303
|
+
Authorization: `Signature ${input.yieldseekerSignature}`
|
|
304
|
+
},
|
|
305
|
+
body: JSON.stringify(input.body)
|
|
306
|
+
});
|
|
307
|
+
} catch (networkError) {
|
|
308
|
+
throw new OwneyError(
|
|
309
|
+
"SPONSOR_REQUEST_FAILED",
|
|
310
|
+
`Paymaster intent network error: ${networkError instanceof Error ? networkError.message : String(networkError)}`,
|
|
311
|
+
{ cause: String(networkError), safeToFallback: true }
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
const text = await res.text();
|
|
315
|
+
let parsed = null;
|
|
316
|
+
try {
|
|
317
|
+
parsed = JSON.parse(text);
|
|
318
|
+
} catch {
|
|
319
|
+
}
|
|
320
|
+
if (!res.ok || !parsed?.success || typeof parsed.data?.intent !== "string" || typeof parsed.data.expiresAt !== "number") {
|
|
321
|
+
throw new OwneyError(
|
|
322
|
+
"SPONSOR_REQUEST_FAILED",
|
|
323
|
+
`Paymaster intent API error ${res.status}: ${parsed?.message ?? text.slice(0, 500)}`,
|
|
324
|
+
{
|
|
325
|
+
statusCode: res.status,
|
|
326
|
+
responseBody: text.slice(0, 500),
|
|
327
|
+
safeToFallback: true
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
}
|
|
331
|
+
return parsed.data;
|
|
332
|
+
}
|
|
333
|
+
async function getSponsorRelayerAddress(input) {
|
|
334
|
+
const base6 = input.baseUrl ?? ROUTING_API_BASE_URL;
|
|
335
|
+
let res;
|
|
336
|
+
try {
|
|
337
|
+
res = await fetch(
|
|
338
|
+
`${base6}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
|
|
339
|
+
{
|
|
340
|
+
headers: { "x-owney-api-key": input.apiKey }
|
|
341
|
+
}
|
|
342
|
+
);
|
|
343
|
+
} catch (networkError) {
|
|
344
|
+
throw new OwneyError(
|
|
345
|
+
"SPONSOR_REQUEST_FAILED",
|
|
346
|
+
`Sponsor API network error: ${networkError instanceof Error ? networkError.message : String(networkError)}`,
|
|
347
|
+
{ cause: String(networkError), safeToFallback: true }
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
const text = await res.text();
|
|
351
|
+
let parsed = null;
|
|
352
|
+
try {
|
|
353
|
+
parsed = JSON.parse(text);
|
|
354
|
+
} catch {
|
|
355
|
+
}
|
|
356
|
+
if (!res.ok || !parsed?.success || !parsed.data?.relayer) {
|
|
357
|
+
throw new OwneyError(
|
|
358
|
+
"SPONSOR_REQUEST_FAILED",
|
|
359
|
+
`Sponsor API error ${res.status}: ${parsed?.message ?? text.slice(0, 500)}`,
|
|
360
|
+
{
|
|
361
|
+
statusCode: res.status,
|
|
362
|
+
responseBody: text.slice(0, 500),
|
|
363
|
+
safeToFallback: true
|
|
364
|
+
}
|
|
365
|
+
);
|
|
366
|
+
}
|
|
367
|
+
return parsed.data.relayer;
|
|
368
|
+
}
|
|
369
|
+
async function postSponsorBatchTransfer(input) {
|
|
370
|
+
let res;
|
|
371
|
+
try {
|
|
372
|
+
res = await fetch(
|
|
373
|
+
`${input.baseUrl ?? ROUTING_API_BASE_URL}/api/v1/sponsor/permit2-batch`,
|
|
374
|
+
{
|
|
375
|
+
method: "POST",
|
|
376
|
+
headers: {
|
|
377
|
+
"content-type": "application/json",
|
|
378
|
+
"x-owney-api-key": input.apiKey
|
|
379
|
+
},
|
|
380
|
+
body: JSON.stringify(input.body)
|
|
381
|
+
}
|
|
382
|
+
);
|
|
383
|
+
} catch {
|
|
384
|
+
throw new OwneyError(
|
|
385
|
+
"SPONSOR_REQUEST_FAILED",
|
|
386
|
+
"Deposit status is unknown. Retry the same amount to check it.",
|
|
387
|
+
{ safeToFallback: false }
|
|
388
|
+
);
|
|
389
|
+
}
|
|
390
|
+
const parsed = await res.json().catch(() => null);
|
|
391
|
+
if (!res.ok || !parsed?.success || !/^0x[0-9a-fA-F]{64}$/.test(parsed.data?.txHash ?? "")) {
|
|
392
|
+
throw new OwneyError(
|
|
393
|
+
"SPONSOR_REQUEST_FAILED",
|
|
394
|
+
"Deposit could not be confirmed. Retry the same amount to check its status.",
|
|
395
|
+
{
|
|
396
|
+
statusCode: res.status,
|
|
397
|
+
safeToFallback: false,
|
|
398
|
+
notSubmitted: parsed?.notSubmitted === true || parsed?.error?.notSubmitted === true || parsed?.error?.details?.notSubmitted === true
|
|
399
|
+
}
|
|
400
|
+
);
|
|
401
|
+
}
|
|
402
|
+
return parsed.data;
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
// src/lib/permit2.ts
|
|
406
|
+
var import_viem3 = require("viem");
|
|
407
|
+
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
408
|
+
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
409
|
+
function permit2ApprovalAmount(requiredAmount) {
|
|
410
|
+
if (requiredAmount <= 0n) {
|
|
411
|
+
throw new Error("Permit2 approval requires a positive deposit amount");
|
|
412
|
+
}
|
|
413
|
+
return MAX_UINT256;
|
|
414
|
+
}
|
|
415
|
+
var ERC20_ALLOWANCE_ABI = [
|
|
416
|
+
{
|
|
417
|
+
type: "function",
|
|
418
|
+
name: "allowance",
|
|
419
|
+
stateMutability: "view",
|
|
420
|
+
inputs: [
|
|
421
|
+
{ name: "owner", type: "address" },
|
|
422
|
+
{ name: "spender", type: "address" }
|
|
423
|
+
],
|
|
424
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
type: "function",
|
|
428
|
+
name: "approve",
|
|
429
|
+
stateMutability: "nonpayable",
|
|
430
|
+
inputs: [
|
|
431
|
+
{ name: "spender", type: "address" },
|
|
432
|
+
{ name: "amount", type: "uint256" }
|
|
433
|
+
],
|
|
434
|
+
outputs: [{ name: "", type: "bool" }]
|
|
435
|
+
},
|
|
436
|
+
{
|
|
437
|
+
type: "function",
|
|
438
|
+
name: "balanceOf",
|
|
439
|
+
stateMutability: "view",
|
|
440
|
+
inputs: [{ name: "account", type: "address" }],
|
|
441
|
+
outputs: [{ name: "", type: "uint256" }]
|
|
442
|
+
}
|
|
443
|
+
];
|
|
444
|
+
function randomPermit2Nonce() {
|
|
445
|
+
const bytes = new Uint8Array(32);
|
|
446
|
+
globalThis.crypto.getRandomValues(bytes);
|
|
447
|
+
return BigInt((0, import_viem3.bytesToHex)(bytes));
|
|
448
|
+
}
|
|
449
|
+
async function readPermit2Allowance(publicClient, token, owner, blockNumber) {
|
|
450
|
+
return publicClient.readContract({
|
|
451
|
+
address: token,
|
|
452
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
453
|
+
functionName: "allowance",
|
|
454
|
+
args: [owner, PERMIT2_ADDRESS],
|
|
455
|
+
...blockNumber === void 0 ? {} : { blockNumber }
|
|
456
|
+
});
|
|
457
|
+
}
|
|
458
|
+
async function readErc20Balance(publicClient, token, owner) {
|
|
459
|
+
return publicClient.readContract({
|
|
460
|
+
address: token,
|
|
461
|
+
abi: ERC20_ALLOWANCE_ABI,
|
|
462
|
+
functionName: "balanceOf",
|
|
463
|
+
args: [owner]
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
// src/lib/chain-guard.ts
|
|
468
|
+
var CHAIN_NAMES = {
|
|
469
|
+
1: "Ethereum",
|
|
470
|
+
8453: "Base",
|
|
471
|
+
42161: "Arbitrum"
|
|
472
|
+
};
|
|
473
|
+
function chainName(chainId) {
|
|
474
|
+
return CHAIN_NAMES[chainId] ?? `chain ${chainId}`;
|
|
475
|
+
}
|
|
476
|
+
async function ensureWalletOnChain(pub, wallet, expected) {
|
|
477
|
+
const actual = await pub.getChainId();
|
|
478
|
+
if (actual === expected) return;
|
|
479
|
+
try {
|
|
480
|
+
await wallet.switchChain({ id: expected });
|
|
481
|
+
} catch (error) {
|
|
482
|
+
throw new OwneyError(
|
|
483
|
+
"CHAIN_MISMATCH",
|
|
484
|
+
`Your wallet is on ${chainName(actual)}. Switch it to ${chainName(expected)} and try again.`,
|
|
485
|
+
{
|
|
486
|
+
expectedChainId: expected,
|
|
487
|
+
actualChainId: actual,
|
|
488
|
+
cause: error instanceof Error ? error.message : String(error)
|
|
489
|
+
}
|
|
490
|
+
);
|
|
491
|
+
}
|
|
492
|
+
const after = await pub.getChainId();
|
|
493
|
+
if (after !== expected) {
|
|
494
|
+
throw new OwneyError(
|
|
495
|
+
"CHAIN_MISMATCH",
|
|
496
|
+
`Your wallet is still on ${chainName(after)}. Switch it to ${chainName(expected)} and try again.`,
|
|
497
|
+
{ expectedChainId: expected, actualChainId: after }
|
|
498
|
+
);
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
// src/lib/sponsored-deposit.ts
|
|
503
|
+
var AUTH_WINDOW_SECONDS = 15 * 60;
|
|
504
|
+
var verificationSetter = /* @__PURE__ */ Symbol("owney.depositVerificationSetter");
|
|
505
|
+
function provideDepositVerificationContext(callback, context) {
|
|
506
|
+
callback[verificationSetter]?.(context);
|
|
507
|
+
}
|
|
508
|
+
function makeVerificationAwareDepositCallback(implementation) {
|
|
509
|
+
let nextVerification;
|
|
510
|
+
const callback = async (smartWallet, chainId, amount) => {
|
|
511
|
+
const verification = nextVerification;
|
|
512
|
+
nextVerification = void 0;
|
|
513
|
+
return implementation(smartWallet, chainId, amount, verification);
|
|
514
|
+
};
|
|
515
|
+
Object.defineProperty(callback, verificationSetter, {
|
|
516
|
+
value: (context) => {
|
|
517
|
+
nextVerification = context;
|
|
518
|
+
}
|
|
519
|
+
});
|
|
520
|
+
return callback;
|
|
521
|
+
}
|
|
522
|
+
|
|
289
523
|
// src/lib/rate-limit.ts
|
|
290
524
|
function rateLimitDelay(error, now = Date.now()) {
|
|
291
525
|
const seen = /* @__PURE__ */ new Set();
|
|
@@ -560,7 +794,7 @@ function hasEmptyWithdrawalSnapshot(raw2, chainId, token) {
|
|
|
560
794
|
}
|
|
561
795
|
|
|
562
796
|
// src/agents/zyfai/zyfai.deposit.ts
|
|
563
|
-
var
|
|
797
|
+
var import_viem4 = require("viem");
|
|
564
798
|
|
|
565
799
|
// src/types/config.ts
|
|
566
800
|
var P_SUPPORTED_CHAINS = {
|
|
@@ -610,20 +844,20 @@ var SupportedAssets = [
|
|
|
610
844
|
];
|
|
611
845
|
|
|
612
846
|
// src/agents/zyfai/zyfai.deposit.ts
|
|
613
|
-
async function submitZyfaiDeposit({ sdk, state, chain, amount, asset, smartWallet, assertCurrent }) {
|
|
847
|
+
async function submitZyfaiDeposit({ sdk, state, chain, amount, asset, smartWallet, assertCurrent, onBeforeSubmission }) {
|
|
614
848
|
const owner = state.walletAddress;
|
|
615
849
|
const provider = state.provider;
|
|
616
850
|
const token = SupportedAssets.find((value) => value.chainId === chain.id && value.symbol === asset);
|
|
617
|
-
if (!token || !(0,
|
|
851
|
+
if (!token || !(0, import_viem4.isAddress)(owner) || !(0, import_viem4.isAddress)(smartWallet) || !/^\d+$/.test(amount) || BigInt(amount) <= 0n)
|
|
618
852
|
throw new OwneyError("AGENT_INVALID_RESPONSE", "Invalid Zyfai deposit transfer.", { chainId: chain.id, asset }, "zyfai");
|
|
619
853
|
assertCurrent();
|
|
620
854
|
const prepared = await sdk.prepareEnterPosition({ userAddress: owner, chainId: chain.id, amount, asset, strategy: "aggressive" });
|
|
621
855
|
assertCurrent();
|
|
622
|
-
const expectedData = (0,
|
|
856
|
+
const expectedData = (0, import_viem4.encodeFunctionData)({ abi: import_viem4.erc20Abi, functionName: "transfer", args: [smartWallet, BigInt(amount)] });
|
|
623
857
|
const transfer = prepared?.transfer;
|
|
624
858
|
if (!transfer || transfer.safeAddress?.toLowerCase() !== smartWallet.toLowerCase() || transfer.tokenAddress?.toLowerCase() !== token.address.toLowerCase() || transfer.to?.toLowerCase() !== token.address.toLowerCase() || transfer.data?.toLowerCase() !== expectedData.toLowerCase() || transfer.value !== "0")
|
|
625
859
|
throw new OwneyError("AGENT_INVALID_RESPONSE", "Zyfai prepared a different deposit transfer.", { chainId: chain.id, asset }, "zyfai");
|
|
626
|
-
const wallet = (0,
|
|
860
|
+
const wallet = (0, import_viem4.createWalletClient)({ account: owner, chain, transport: (0, import_viem4.custom)({
|
|
627
861
|
request: async (args) => {
|
|
628
862
|
assertCurrent();
|
|
629
863
|
if (args.method === "eth_sendTransaction") {
|
|
@@ -634,6 +868,8 @@ async function submitZyfaiDeposit({ sdk, state, chain, amount, asset, smartWalle
|
|
|
634
868
|
assertCurrent();
|
|
635
869
|
if (!Array.isArray(accounts) || typeof accounts[0] !== "string" || accounts[0].toLowerCase() !== owner.toLowerCase() || Number(chainId) !== chain.id)
|
|
636
870
|
throw new OwneyError("NOT_CONNECTED", "Wallet changed while preparing Zyfai deposit.", void 0, "zyfai");
|
|
871
|
+
await onBeforeSubmission?.();
|
|
872
|
+
assertCurrent();
|
|
637
873
|
}
|
|
638
874
|
return provider.request(args);
|
|
639
875
|
}
|
|
@@ -643,7 +879,7 @@ async function submitZyfaiDeposit({ sdk, state, chain, amount, asset, smartWalle
|
|
|
643
879
|
|
|
644
880
|
// src/agents/zyfai/zyfai.agent.ts
|
|
645
881
|
var import_sdk = require("@zyfai/sdk");
|
|
646
|
-
var
|
|
882
|
+
var import_viem7 = require("viem");
|
|
647
883
|
var import_chains = require("viem/chains");
|
|
648
884
|
|
|
649
885
|
// src/lib/debug.ts
|
|
@@ -690,8 +926,8 @@ var DayFilterMapping = {
|
|
|
690
926
|
};
|
|
691
927
|
|
|
692
928
|
// src/agents/zyfai/zyfai.mapper.ts
|
|
693
|
-
var
|
|
694
|
-
var exactHexAmount = (raw2, decimals) => (0,
|
|
929
|
+
var import_viem5 = require("viem");
|
|
930
|
+
var exactHexAmount = (raw2, decimals) => (0, import_viem5.formatUnits)(BigInt(/^0x/i.test(raw2) ? raw2 : `0x${raw2}`), decimals);
|
|
695
931
|
var DECIMALS_BY_SYMBOL = {
|
|
696
932
|
usdc: 6,
|
|
697
933
|
weth: 18,
|
|
@@ -790,7 +1026,7 @@ function mapBalances(raw2, _chainId, smartWallet) {
|
|
|
790
1026
|
// legacy `amount` fallback is hex. Runtime
|
|
791
1027
|
// getBalances payloads often carry one (e.g. 18 for WETH) — prefer that
|
|
792
1028
|
// when present, otherwise fall back to the per-symbol lookup.
|
|
793
|
-
amount: p.underlyingAmountWithFee ?? p.underlyingAmount ? (0,
|
|
1029
|
+
amount: p.underlyingAmountWithFee ?? p.underlyingAmount ? (0, import_viem5.formatUnits)(
|
|
794
1030
|
BigInt(p.underlyingAmountWithFee ?? p.underlyingAmount ?? "0"),
|
|
795
1031
|
tokenDecimals(
|
|
796
1032
|
p.token_symbol,
|
|
@@ -1455,7 +1691,7 @@ function protocolsPolicyNeedsUpdate(current, desiredProtocols, desiredAutoSelect
|
|
|
1455
1691
|
}
|
|
1456
1692
|
|
|
1457
1693
|
// src/lib/paid-rpc.ts
|
|
1458
|
-
var
|
|
1694
|
+
var import_viem6 = require("viem");
|
|
1459
1695
|
var PAID_RPC_RETRY_COUNT = 3;
|
|
1460
1696
|
var PAID_RPC_RETRY_DELAY_MS = 1e3;
|
|
1461
1697
|
function configuredRpcProxyBaseUrl(baseUrl) {
|
|
@@ -1491,9 +1727,9 @@ function createPaidRpcClient(chain, rpcUrls) {
|
|
|
1491
1727
|
rpcUrls,
|
|
1492
1728
|
chain.id
|
|
1493
1729
|
);
|
|
1494
|
-
return (0,
|
|
1730
|
+
return (0, import_viem6.createPublicClient)({
|
|
1495
1731
|
chain,
|
|
1496
|
-
transport: (0,
|
|
1732
|
+
transport: (0, import_viem6.http)(url, {
|
|
1497
1733
|
retryCount: PAID_RPC_RETRY_COUNT,
|
|
1498
1734
|
retryDelay: PAID_RPC_RETRY_DELAY_MS
|
|
1499
1735
|
})
|
|
@@ -1590,7 +1826,7 @@ async function withPaidRpcDiagnostics(operation, chainId, rpcMethod, agentId) {
|
|
|
1590
1826
|
}
|
|
1591
1827
|
|
|
1592
1828
|
// src/agents/zyfai/zyfai.agent.ts
|
|
1593
|
-
var ERC7579_IS_MODULE_INSTALLED_ABI = (0,
|
|
1829
|
+
var ERC7579_IS_MODULE_INSTALLED_ABI = (0, import_viem7.parseAbi)([
|
|
1594
1830
|
"function isModuleInstalled(uint256 moduleTypeId, address module, bytes additionalContext) view returns (bool)"
|
|
1595
1831
|
]);
|
|
1596
1832
|
var WETH_ADDRESS_BY_CHAIN = {
|
|
@@ -1757,7 +1993,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1757
1993
|
}, asset.address, entry.action === "Withdraw" ? "withdraw" : "deposit");
|
|
1758
1994
|
if (evidence.transfer === "confirmed" && evidence.confirmedAmount) {
|
|
1759
1995
|
Object.assign(tx, {
|
|
1760
|
-
amount: (0,
|
|
1996
|
+
amount: (0, import_viem7.formatUnits)(BigInt(evidence.confirmedAmount), asset.decimals),
|
|
1761
1997
|
amountRaw: evidence.confirmedAmount,
|
|
1762
1998
|
blockNumber: evidence.blockNumber,
|
|
1763
1999
|
logIndexes: evidence.logIndexes,
|
|
@@ -2470,7 +2706,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2470
2706
|
await this.ensureSessionKey(ownerAddress, chainId, redeployed.address);
|
|
2471
2707
|
return redeployed.address;
|
|
2472
2708
|
}
|
|
2473
|
-
async deposit(state, chainId, amount, asset, depositCallback, onProgress) {
|
|
2709
|
+
async deposit(state, chainId, amount, asset, depositCallback, onProgress, onBeforeSubmission) {
|
|
2474
2710
|
const validChainId = isValidChainId(chainId);
|
|
2475
2711
|
const owner = state.walletAddress;
|
|
2476
2712
|
const provider = state.provider;
|
|
@@ -2503,7 +2739,18 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2503
2739
|
amount,
|
|
2504
2740
|
asset,
|
|
2505
2741
|
smartWallet,
|
|
2506
|
-
assertCurrent
|
|
2742
|
+
assertCurrent,
|
|
2743
|
+
onBeforeSubmission: onBeforeSubmission ? () => onBeforeSubmission({
|
|
2744
|
+
agentId: this.id,
|
|
2745
|
+
chainId,
|
|
2746
|
+
token: asset,
|
|
2747
|
+
walletAddress: owner,
|
|
2748
|
+
agentWallet: smartWallet,
|
|
2749
|
+
intendedAmount: amount,
|
|
2750
|
+
transfer: "pending",
|
|
2751
|
+
registration: "pending",
|
|
2752
|
+
delivery: "not-applicable"
|
|
2753
|
+
}) : void 0
|
|
2507
2754
|
});
|
|
2508
2755
|
let evidence = {
|
|
2509
2756
|
agentId: this.id,
|
|
@@ -2573,7 +2820,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2573
2820
|
this.sdk.getPortfolio(owner).catch(() => void 0)
|
|
2574
2821
|
]);
|
|
2575
2822
|
assertScope();
|
|
2576
|
-
if (!(0,
|
|
2823
|
+
if (!(0, import_viem7.isAddress)(wallet.address) || !registered.smartWallet || registered.smartWallet.toLowerCase() !== wallet.address.toLowerCase())
|
|
2577
2824
|
throw new OwneyError(
|
|
2578
2825
|
"AGENT_AUTH_FAILED",
|
|
2579
2826
|
"Could not verify Zyfai's withdrawal wallet.",
|
|
@@ -2584,7 +2831,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2584
2831
|
const asset = SupportedAssets.find((value) => value.chainId === chainId && value.symbol === token);
|
|
2585
2832
|
const idle = asset ? await this.getPublicClient(chainId).readContract({
|
|
2586
2833
|
address: asset.address,
|
|
2587
|
-
abi:
|
|
2834
|
+
abi: import_viem7.erc20Abi,
|
|
2588
2835
|
functionName: "balanceOf",
|
|
2589
2836
|
args: [wallet.address]
|
|
2590
2837
|
}).catch(() => void 0) : void 0;
|
|
@@ -2831,13 +3078,13 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2831
3078
|
this.sdk.getSmartWalletByEOA(owner)
|
|
2832
3079
|
]);
|
|
2833
3080
|
assertScope();
|
|
2834
|
-
if (!(0,
|
|
3081
|
+
if (!(0, import_viem7.isAddress)(wallet.address) || wallet.isDeployed !== false && (wallet.isDeployed !== true || wallet.isOwner !== true) || !registered.smartWallet || registered.smartWallet.toLowerCase() !== wallet.address.toLowerCase()) throw unavailable();
|
|
2835
3082
|
const client = this.getPublicClient(validChainId);
|
|
2836
3083
|
const blockNumber = await client.getBlockNumber({ cacheTime: 0 });
|
|
2837
3084
|
assertScope();
|
|
2838
3085
|
const idle = await client.readContract({
|
|
2839
3086
|
address: asset.address,
|
|
2840
|
-
abi:
|
|
3087
|
+
abi: import_viem7.erc20Abi,
|
|
2841
3088
|
functionName: "balanceOf",
|
|
2842
3089
|
args: [wallet.address],
|
|
2843
3090
|
blockNumber
|
|
@@ -2894,7 +3141,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2894
3141
|
if (blockNumber < BigInt(evidence.blockNumber)) return void 0;
|
|
2895
3142
|
const idle = await client.readContract({
|
|
2896
3143
|
address: asset.address,
|
|
2897
|
-
abi:
|
|
3144
|
+
abi: import_viem7.erc20Abi,
|
|
2898
3145
|
functionName: "balanceOf",
|
|
2899
3146
|
args: [balance.smartWallet],
|
|
2900
3147
|
blockNumber
|
|
@@ -3102,240 +3349,6 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
3102
3349
|
var import_viem13 = require("viem");
|
|
3103
3350
|
var import_chains4 = require("viem/chains");
|
|
3104
3351
|
|
|
3105
|
-
// src/lib/chain-guard.ts
|
|
3106
|
-
var CHAIN_NAMES = {
|
|
3107
|
-
1: "Ethereum",
|
|
3108
|
-
8453: "Base",
|
|
3109
|
-
42161: "Arbitrum"
|
|
3110
|
-
};
|
|
3111
|
-
function chainName(chainId) {
|
|
3112
|
-
return CHAIN_NAMES[chainId] ?? `chain ${chainId}`;
|
|
3113
|
-
}
|
|
3114
|
-
async function ensureWalletOnChain(pub, wallet, expected) {
|
|
3115
|
-
const actual = await pub.getChainId();
|
|
3116
|
-
if (actual === expected) return;
|
|
3117
|
-
try {
|
|
3118
|
-
await wallet.switchChain({ id: expected });
|
|
3119
|
-
} catch (error) {
|
|
3120
|
-
throw new OwneyError(
|
|
3121
|
-
"CHAIN_MISMATCH",
|
|
3122
|
-
`Your wallet is on ${chainName(actual)}. Switch it to ${chainName(expected)} and try again.`,
|
|
3123
|
-
{
|
|
3124
|
-
expectedChainId: expected,
|
|
3125
|
-
actualChainId: actual,
|
|
3126
|
-
cause: error instanceof Error ? error.message : String(error)
|
|
3127
|
-
}
|
|
3128
|
-
);
|
|
3129
|
-
}
|
|
3130
|
-
const after = await pub.getChainId();
|
|
3131
|
-
if (after !== expected) {
|
|
3132
|
-
throw new OwneyError(
|
|
3133
|
-
"CHAIN_MISMATCH",
|
|
3134
|
-
`Your wallet is still on ${chainName(after)}. Switch it to ${chainName(expected)} and try again.`,
|
|
3135
|
-
{ expectedChainId: expected, actualChainId: after }
|
|
3136
|
-
);
|
|
3137
|
-
}
|
|
3138
|
-
}
|
|
3139
|
-
|
|
3140
|
-
// src/lib/transfer-auth.ts
|
|
3141
|
-
var import_viem6 = require("viem");
|
|
3142
|
-
|
|
3143
|
-
// src/lib/sponsor-client.ts
|
|
3144
|
-
var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
|
|
3145
|
-
async function postPaymasterIntent(input) {
|
|
3146
|
-
const base6 = input.baseUrl ?? ROUTING_API_BASE_URL;
|
|
3147
|
-
let res;
|
|
3148
|
-
try {
|
|
3149
|
-
res = await fetch(`${base6}/api/v1/sponsor/paymaster-intent`, {
|
|
3150
|
-
method: "POST",
|
|
3151
|
-
headers: {
|
|
3152
|
-
"content-type": "application/json",
|
|
3153
|
-
"x-owney-api-key": input.apiKey,
|
|
3154
|
-
Authorization: `Signature ${input.yieldseekerSignature}`
|
|
3155
|
-
},
|
|
3156
|
-
body: JSON.stringify(input.body)
|
|
3157
|
-
});
|
|
3158
|
-
} catch (networkError) {
|
|
3159
|
-
throw new OwneyError(
|
|
3160
|
-
"SPONSOR_REQUEST_FAILED",
|
|
3161
|
-
`Paymaster intent network error: ${networkError instanceof Error ? networkError.message : String(networkError)}`,
|
|
3162
|
-
{ cause: String(networkError), safeToFallback: true }
|
|
3163
|
-
);
|
|
3164
|
-
}
|
|
3165
|
-
const text = await res.text();
|
|
3166
|
-
let parsed = null;
|
|
3167
|
-
try {
|
|
3168
|
-
parsed = JSON.parse(text);
|
|
3169
|
-
} catch {
|
|
3170
|
-
}
|
|
3171
|
-
if (!res.ok || !parsed?.success || typeof parsed.data?.intent !== "string" || typeof parsed.data.expiresAt !== "number") {
|
|
3172
|
-
throw new OwneyError(
|
|
3173
|
-
"SPONSOR_REQUEST_FAILED",
|
|
3174
|
-
`Paymaster intent API error ${res.status}: ${parsed?.message ?? text.slice(0, 500)}`,
|
|
3175
|
-
{
|
|
3176
|
-
statusCode: res.status,
|
|
3177
|
-
responseBody: text.slice(0, 500),
|
|
3178
|
-
safeToFallback: true
|
|
3179
|
-
}
|
|
3180
|
-
);
|
|
3181
|
-
}
|
|
3182
|
-
return parsed.data;
|
|
3183
|
-
}
|
|
3184
|
-
async function getSponsorRelayerAddress(input) {
|
|
3185
|
-
const base6 = input.baseUrl ?? ROUTING_API_BASE_URL;
|
|
3186
|
-
let res;
|
|
3187
|
-
try {
|
|
3188
|
-
res = await fetch(
|
|
3189
|
-
`${base6}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
|
|
3190
|
-
{
|
|
3191
|
-
headers: { "x-owney-api-key": input.apiKey }
|
|
3192
|
-
}
|
|
3193
|
-
);
|
|
3194
|
-
} catch (networkError) {
|
|
3195
|
-
throw new OwneyError(
|
|
3196
|
-
"SPONSOR_REQUEST_FAILED",
|
|
3197
|
-
`Sponsor API network error: ${networkError instanceof Error ? networkError.message : String(networkError)}`,
|
|
3198
|
-
{ cause: String(networkError), safeToFallback: true }
|
|
3199
|
-
);
|
|
3200
|
-
}
|
|
3201
|
-
const text = await res.text();
|
|
3202
|
-
let parsed = null;
|
|
3203
|
-
try {
|
|
3204
|
-
parsed = JSON.parse(text);
|
|
3205
|
-
} catch {
|
|
3206
|
-
}
|
|
3207
|
-
if (!res.ok || !parsed?.success || !parsed.data?.relayer) {
|
|
3208
|
-
throw new OwneyError(
|
|
3209
|
-
"SPONSOR_REQUEST_FAILED",
|
|
3210
|
-
`Sponsor API error ${res.status}: ${parsed?.message ?? text.slice(0, 500)}`,
|
|
3211
|
-
{
|
|
3212
|
-
statusCode: res.status,
|
|
3213
|
-
responseBody: text.slice(0, 500),
|
|
3214
|
-
safeToFallback: true
|
|
3215
|
-
}
|
|
3216
|
-
);
|
|
3217
|
-
}
|
|
3218
|
-
return parsed.data.relayer;
|
|
3219
|
-
}
|
|
3220
|
-
async function postSponsorBatchTransfer(input) {
|
|
3221
|
-
let res;
|
|
3222
|
-
try {
|
|
3223
|
-
res = await fetch(
|
|
3224
|
-
`${input.baseUrl ?? ROUTING_API_BASE_URL}/api/v1/sponsor/permit2-batch`,
|
|
3225
|
-
{
|
|
3226
|
-
method: "POST",
|
|
3227
|
-
headers: {
|
|
3228
|
-
"content-type": "application/json",
|
|
3229
|
-
"x-owney-api-key": input.apiKey
|
|
3230
|
-
},
|
|
3231
|
-
body: JSON.stringify(input.body)
|
|
3232
|
-
}
|
|
3233
|
-
);
|
|
3234
|
-
} catch {
|
|
3235
|
-
throw new OwneyError(
|
|
3236
|
-
"SPONSOR_REQUEST_FAILED",
|
|
3237
|
-
"Deposit status is unknown. Retry the same amount to check it.",
|
|
3238
|
-
{ safeToFallback: false }
|
|
3239
|
-
);
|
|
3240
|
-
}
|
|
3241
|
-
const parsed = await res.json().catch(() => null);
|
|
3242
|
-
if (!res.ok || !parsed?.success || !/^0x[0-9a-fA-F]{64}$/.test(parsed.data?.txHash ?? "")) {
|
|
3243
|
-
throw new OwneyError(
|
|
3244
|
-
"SPONSOR_REQUEST_FAILED",
|
|
3245
|
-
"Deposit could not be confirmed. Retry the same amount to check its status.",
|
|
3246
|
-
{
|
|
3247
|
-
statusCode: res.status,
|
|
3248
|
-
safeToFallback: false,
|
|
3249
|
-
notSubmitted: parsed?.notSubmitted === true || parsed?.error?.notSubmitted === true || parsed?.error?.details?.notSubmitted === true
|
|
3250
|
-
}
|
|
3251
|
-
);
|
|
3252
|
-
}
|
|
3253
|
-
return parsed.data;
|
|
3254
|
-
}
|
|
3255
|
-
|
|
3256
|
-
// src/lib/permit2.ts
|
|
3257
|
-
var import_viem7 = require("viem");
|
|
3258
|
-
var PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
3259
|
-
var MAX_UINT256 = 2n ** 256n - 1n;
|
|
3260
|
-
function permit2ApprovalAmount(requiredAmount) {
|
|
3261
|
-
if (requiredAmount <= 0n) {
|
|
3262
|
-
throw new Error("Permit2 approval requires a positive deposit amount");
|
|
3263
|
-
}
|
|
3264
|
-
return MAX_UINT256;
|
|
3265
|
-
}
|
|
3266
|
-
var ERC20_ALLOWANCE_ABI = [
|
|
3267
|
-
{
|
|
3268
|
-
type: "function",
|
|
3269
|
-
name: "allowance",
|
|
3270
|
-
stateMutability: "view",
|
|
3271
|
-
inputs: [
|
|
3272
|
-
{ name: "owner", type: "address" },
|
|
3273
|
-
{ name: "spender", type: "address" }
|
|
3274
|
-
],
|
|
3275
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
3276
|
-
},
|
|
3277
|
-
{
|
|
3278
|
-
type: "function",
|
|
3279
|
-
name: "approve",
|
|
3280
|
-
stateMutability: "nonpayable",
|
|
3281
|
-
inputs: [
|
|
3282
|
-
{ name: "spender", type: "address" },
|
|
3283
|
-
{ name: "amount", type: "uint256" }
|
|
3284
|
-
],
|
|
3285
|
-
outputs: [{ name: "", type: "bool" }]
|
|
3286
|
-
},
|
|
3287
|
-
{
|
|
3288
|
-
type: "function",
|
|
3289
|
-
name: "balanceOf",
|
|
3290
|
-
stateMutability: "view",
|
|
3291
|
-
inputs: [{ name: "account", type: "address" }],
|
|
3292
|
-
outputs: [{ name: "", type: "uint256" }]
|
|
3293
|
-
}
|
|
3294
|
-
];
|
|
3295
|
-
function randomPermit2Nonce() {
|
|
3296
|
-
const bytes = new Uint8Array(32);
|
|
3297
|
-
globalThis.crypto.getRandomValues(bytes);
|
|
3298
|
-
return BigInt((0, import_viem7.bytesToHex)(bytes));
|
|
3299
|
-
}
|
|
3300
|
-
async function readPermit2Allowance(publicClient, token, owner, blockNumber) {
|
|
3301
|
-
return publicClient.readContract({
|
|
3302
|
-
address: token,
|
|
3303
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
3304
|
-
functionName: "allowance",
|
|
3305
|
-
args: [owner, PERMIT2_ADDRESS],
|
|
3306
|
-
...blockNumber === void 0 ? {} : { blockNumber }
|
|
3307
|
-
});
|
|
3308
|
-
}
|
|
3309
|
-
async function readErc20Balance(publicClient, token, owner) {
|
|
3310
|
-
return publicClient.readContract({
|
|
3311
|
-
address: token,
|
|
3312
|
-
abi: ERC20_ALLOWANCE_ABI,
|
|
3313
|
-
functionName: "balanceOf",
|
|
3314
|
-
args: [owner]
|
|
3315
|
-
});
|
|
3316
|
-
}
|
|
3317
|
-
|
|
3318
|
-
// src/lib/sponsored-deposit.ts
|
|
3319
|
-
var AUTH_WINDOW_SECONDS = 15 * 60;
|
|
3320
|
-
var verificationSetter = /* @__PURE__ */ Symbol("owney.depositVerificationSetter");
|
|
3321
|
-
function provideDepositVerificationContext(callback, context) {
|
|
3322
|
-
callback[verificationSetter]?.(context);
|
|
3323
|
-
}
|
|
3324
|
-
function makeVerificationAwareDepositCallback(implementation) {
|
|
3325
|
-
let nextVerification;
|
|
3326
|
-
const callback = async (smartWallet, chainId, amount) => {
|
|
3327
|
-
const verification = nextVerification;
|
|
3328
|
-
nextVerification = void 0;
|
|
3329
|
-
return implementation(smartWallet, chainId, amount, verification);
|
|
3330
|
-
};
|
|
3331
|
-
Object.defineProperty(callback, verificationSetter, {
|
|
3332
|
-
value: (context) => {
|
|
3333
|
-
nextVerification = context;
|
|
3334
|
-
}
|
|
3335
|
-
});
|
|
3336
|
-
return callback;
|
|
3337
|
-
}
|
|
3338
|
-
|
|
3339
3352
|
// src/agents/yieldseeker/yieldseeker.auth.ts
|
|
3340
3353
|
var import_siwe = require("siwe");
|
|
3341
3354
|
var import_viem8 = require("viem");
|
|
@@ -5387,7 +5400,7 @@ var YieldseekerAgent = class {
|
|
|
5387
5400
|
this.assertAsset(targetAsset);
|
|
5388
5401
|
await this.ensureAgent(state, chainId, targetAsset);
|
|
5389
5402
|
}
|
|
5390
|
-
async deposit(state, chainId, amount, asset, depositCallback, onProgress) {
|
|
5403
|
+
async deposit(state, chainId, amount, asset, depositCallback, onProgress, onBeforeSubmission) {
|
|
5391
5404
|
this.assertChain(chainId);
|
|
5392
5405
|
this.assertAsset(asset);
|
|
5393
5406
|
if (BigInt(amount) <= 0n) {
|
|
@@ -5443,7 +5456,17 @@ var YieldseekerAgent = class {
|
|
|
5443
5456
|
chainId
|
|
5444
5457
|
}, submitted, (value) => {
|
|
5445
5458
|
receipt = value;
|
|
5446
|
-
})
|
|
5459
|
+
}, onBeforeSubmission ? () => onBeforeSubmission({
|
|
5460
|
+
agentId: this.id,
|
|
5461
|
+
chainId,
|
|
5462
|
+
token: asset,
|
|
5463
|
+
walletAddress: state.walletAddress,
|
|
5464
|
+
agentWallet: context.wallet.walletAddress,
|
|
5465
|
+
intendedAmount: amount,
|
|
5466
|
+
transfer: "pending",
|
|
5467
|
+
registration: "not-applicable",
|
|
5468
|
+
delivery: "not-applicable"
|
|
5469
|
+
}) : void 0);
|
|
5447
5470
|
} catch (error) {
|
|
5448
5471
|
if (error instanceof OwneyError && error.details?.ownerTransferNotExecuted === true && error.details.reason === "TRANSACTION_REPLACED_WITH_DIFFERENT_CALL") {
|
|
5449
5472
|
notifyFunding(onProgress, {
|
|
@@ -7039,8 +7062,9 @@ var YieldseekerAgent = class {
|
|
|
7039
7062
|
this.id
|
|
7040
7063
|
);
|
|
7041
7064
|
}
|
|
7042
|
-
async submitTransaction(state, chainId, transaction, onSubmitted, onReceipt) {
|
|
7065
|
+
async submitTransaction(state, chainId, transaction, onSubmitted, onReceipt, onBeforeSubmission) {
|
|
7043
7066
|
if (this.transactionExecutor) {
|
|
7067
|
+
await onBeforeSubmission?.();
|
|
7044
7068
|
const hash2 = await this.transactionExecutor(state, chainId, transaction, onReceipt);
|
|
7045
7069
|
onSubmitted?.(hash2);
|
|
7046
7070
|
return hash2;
|
|
@@ -7050,7 +7074,10 @@ var YieldseekerAgent = class {
|
|
|
7050
7074
|
const walletClient = (0, import_viem13.createWalletClient)({
|
|
7051
7075
|
account,
|
|
7052
7076
|
chain: import_chains4.base,
|
|
7053
|
-
transport: (0, import_viem13.custom)(
|
|
7077
|
+
transport: onBeforeSubmission ? (0, import_viem13.custom)({ request: async (args) => {
|
|
7078
|
+
if (args.method === "eth_sendTransaction") await onBeforeSubmission();
|
|
7079
|
+
return state.provider.request(args);
|
|
7080
|
+
} }, { retryCount: 0 }) : (0, import_viem13.custom)(state.provider)
|
|
7054
7081
|
});
|
|
7055
7082
|
const walletChainClient = (0, import_viem13.createPublicClient)({
|
|
7056
7083
|
chain: import_chains4.base,
|
|
@@ -7891,6 +7918,7 @@ async function execute(i, key2, plan) {
|
|
|
7891
7918
|
};
|
|
7892
7919
|
save(key2, body);
|
|
7893
7920
|
}
|
|
7921
|
+
await i.onBeforeSubmission?.((0, import_viem16.keccak256)(body.serializedTransaction));
|
|
7894
7922
|
try {
|
|
7895
7923
|
i.onSubmitted?.((0, import_viem16.keccak256)(body.serializedTransaction));
|
|
7896
7924
|
} catch {
|
|
@@ -7918,6 +7946,13 @@ async function execute(i, key2, plan) {
|
|
|
7918
7946
|
clear(key2, body);
|
|
7919
7947
|
return hash;
|
|
7920
7948
|
} catch (error) {
|
|
7949
|
+
if (initial.serializedTransaction && error instanceof OwneyError && error.code === "DEPOSIT_CHECKPOINT_FAILED") {
|
|
7950
|
+
throw new OwneyError(
|
|
7951
|
+
error.code,
|
|
7952
|
+
"Could not save recovery of the existing deposit.",
|
|
7953
|
+
{ ...error.details, notSubmitted: false, safeToFallback: false }
|
|
7954
|
+
);
|
|
7955
|
+
}
|
|
7921
7956
|
if (!body.serializedTransaction && !body.serializedPermitTransaction || rejectedPreparation(error) || error instanceof OwneyError && error.details?.notSubmitted === true)
|
|
7922
7957
|
clear(key2, body);
|
|
7923
7958
|
throw error;
|
|
@@ -8044,6 +8079,7 @@ function makeSponsoredTokenCallback(deps) {
|
|
|
8044
8079
|
wallet,
|
|
8045
8080
|
onApproved: deps.onApproved,
|
|
8046
8081
|
onSubmitted: (hash) => deps.onSubmitted?.(hash, transfers),
|
|
8082
|
+
onBeforeSubmission: (hash) => deps.onBeforeSubmission?.(hash, transfers),
|
|
8047
8083
|
resumeTxHash: deps.resumeTxHash
|
|
8048
8084
|
});
|
|
8049
8085
|
};
|
|
@@ -8215,6 +8251,7 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
8215
8251
|
} catch {
|
|
8216
8252
|
}
|
|
8217
8253
|
};
|
|
8254
|
+
await deps.onBeforeSubmission?.(requestedId, transfers);
|
|
8218
8255
|
progress(requestedId, "pending");
|
|
8219
8256
|
let sendResult;
|
|
8220
8257
|
try {
|
|
@@ -8512,8 +8549,8 @@ var OwneySDK = class {
|
|
|
8512
8549
|
return createPaidRpcClient(VIEM_CHAIN2[chainId], this.rpcUrls);
|
|
8513
8550
|
}
|
|
8514
8551
|
/** Builds the default USDC batch callback for the connected wallet. */
|
|
8515
|
-
getDefaultSponsoredCallback(onApproved, onSubmitted, resumeTxHash) {
|
|
8516
|
-
if (!onApproved && !onSubmitted && !resumeTxHash && this.cachedSponsoredCallback)
|
|
8552
|
+
getDefaultSponsoredCallback(onApproved, onSubmitted, resumeTxHash, onBeforeSubmission) {
|
|
8553
|
+
if (!onApproved && !onSubmitted && !resumeTxHash && !onBeforeSubmission && this.cachedSponsoredCallback)
|
|
8517
8554
|
return this.cachedSponsoredCallback;
|
|
8518
8555
|
const provider = this.requireConnectedProvider();
|
|
8519
8556
|
const owner = this.state.walletAddress;
|
|
@@ -8523,6 +8560,7 @@ var OwneySDK = class {
|
|
|
8523
8560
|
ownerAddress: owner,
|
|
8524
8561
|
onApproved,
|
|
8525
8562
|
onSubmitted,
|
|
8563
|
+
onBeforeSubmission,
|
|
8526
8564
|
resumeTxHash,
|
|
8527
8565
|
tokenAddressByChain: SPONSORED_USDC_BY_CHAIN,
|
|
8528
8566
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
@@ -8539,13 +8577,13 @@ var OwneySDK = class {
|
|
|
8539
8577
|
transport: (0, import_viem18.custom)(provider)
|
|
8540
8578
|
})
|
|
8541
8579
|
});
|
|
8542
|
-
if (!onApproved && !onSubmitted && !resumeTxHash) this.cachedSponsoredCallback = callback;
|
|
8580
|
+
if (!onApproved && !onSubmitted && !resumeTxHash && !onBeforeSubmission) this.cachedSponsoredCallback = callback;
|
|
8543
8581
|
return callback;
|
|
8544
8582
|
}
|
|
8545
8583
|
/** Builds the wallet-native sponsored calls callback for compatible paymasters. */
|
|
8546
|
-
getDefaultSponsoredCallsCallback(asset, onApproved, onSubmitted, onCallsProgress) {
|
|
8584
|
+
getDefaultSponsoredCallsCallback(asset, onApproved, onSubmitted, onCallsProgress, onBeforeSubmission) {
|
|
8547
8585
|
const cached = this.cachedSponsoredCallsCallbacks.get(asset);
|
|
8548
|
-
if (!onApproved && !onSubmitted && !onCallsProgress && cached) return cached;
|
|
8586
|
+
if (!onApproved && !onSubmitted && !onCallsProgress && !onBeforeSubmission && cached) return cached;
|
|
8549
8587
|
const provider = this.requireConnectedProvider();
|
|
8550
8588
|
const callback = makeSponsoredCallsCallback({
|
|
8551
8589
|
apiKey: this.apiKey,
|
|
@@ -8556,9 +8594,10 @@ var OwneySDK = class {
|
|
|
8556
8594
|
onApproved,
|
|
8557
8595
|
onSubmitted,
|
|
8558
8596
|
onCallsProgress,
|
|
8597
|
+
onBeforeSubmission,
|
|
8559
8598
|
tokenAddressByChain: sponsoredTokensFor(asset)
|
|
8560
8599
|
});
|
|
8561
|
-
if (!onApproved && !onSubmitted && !onCallsProgress) this.cachedSponsoredCallsCallbacks.set(asset, callback);
|
|
8600
|
+
if (!onApproved && !onSubmitted && !onCallsProgress && !onBeforeSubmission) this.cachedSponsoredCallsCallbacks.set(asset, callback);
|
|
8562
8601
|
return callback;
|
|
8563
8602
|
}
|
|
8564
8603
|
/**
|
|
@@ -8567,8 +8606,8 @@ var OwneySDK = class {
|
|
|
8567
8606
|
* Mirrors `getDefaultSponsoredCallback()` but signs a Permit2
|
|
8568
8607
|
* single-use batch authorization instead of an EIP-3009 authorization.
|
|
8569
8608
|
*/
|
|
8570
|
-
getDefaultWethSponsoredCallback(onApproved, onSubmitted, resumeTxHash) {
|
|
8571
|
-
if (!onApproved && !onSubmitted && !resumeTxHash && this.cachedWethSponsoredCallback)
|
|
8609
|
+
getDefaultWethSponsoredCallback(onApproved, onSubmitted, resumeTxHash, onBeforeSubmission) {
|
|
8610
|
+
if (!onApproved && !onSubmitted && !resumeTxHash && !onBeforeSubmission && this.cachedWethSponsoredCallback)
|
|
8572
8611
|
return this.cachedWethSponsoredCallback;
|
|
8573
8612
|
const provider = this.requireConnectedProvider();
|
|
8574
8613
|
const owner = this.state.walletAddress;
|
|
@@ -8578,6 +8617,7 @@ var OwneySDK = class {
|
|
|
8578
8617
|
ownerAddress: owner,
|
|
8579
8618
|
onApproved,
|
|
8580
8619
|
onSubmitted,
|
|
8620
|
+
onBeforeSubmission,
|
|
8581
8621
|
resumeTxHash,
|
|
8582
8622
|
tokenAddressByChain: SPONSORED_WETH_BY_CHAIN,
|
|
8583
8623
|
// Casts work around viem's chain-narrowed Client vs the generic
|
|
@@ -8594,7 +8634,7 @@ var OwneySDK = class {
|
|
|
8594
8634
|
transport: (0, import_viem18.custom)(provider)
|
|
8595
8635
|
})
|
|
8596
8636
|
});
|
|
8597
|
-
if (!onApproved && !onSubmitted && !resumeTxHash) this.cachedWethSponsoredCallback = callback;
|
|
8637
|
+
if (!onApproved && !onSubmitted && !resumeTxHash && !onBeforeSubmission) this.cachedWethSponsoredCallback = callback;
|
|
8598
8638
|
return callback;
|
|
8599
8639
|
}
|
|
8600
8640
|
getAgent(agentId) {
|
|
@@ -8910,8 +8950,12 @@ var OwneySDK = class {
|
|
|
8910
8950
|
);
|
|
8911
8951
|
const prepared = /* @__PURE__ */ new Map();
|
|
8912
8952
|
const paidFallbackAgents = /* @__PURE__ */ new Set();
|
|
8913
|
-
const onProgress = options.onProgress ? (evidence) => {
|
|
8914
|
-
if (evidence.agentWallet)
|
|
8953
|
+
const onProgress = options.onProgress || options.onBeforeSubmission ? (evidence) => {
|
|
8954
|
+
if (evidence.agentWallet) {
|
|
8955
|
+
const wallet = evidence.agentWallet.toLowerCase();
|
|
8956
|
+
evidence = { ...prepared.get(wallet), ...evidence };
|
|
8957
|
+
prepared.set(wallet, evidence);
|
|
8958
|
+
}
|
|
8915
8959
|
notifyFunding(options.onProgress, evidence);
|
|
8916
8960
|
} : void 0;
|
|
8917
8961
|
const onSubmitted = onProgress ? (hash, destinations) => {
|
|
@@ -8931,9 +8975,45 @@ var OwneySDK = class {
|
|
|
8931
8975
|
}
|
|
8932
8976
|
const state = this.requireState();
|
|
8933
8977
|
const chainId = this.requireChainId();
|
|
8978
|
+
let checkpointFailure;
|
|
8979
|
+
let checkpointFailedEvidence = [];
|
|
8980
|
+
const checkpoint2 = options.onBeforeSubmission ? async (evidence) => {
|
|
8981
|
+
try {
|
|
8982
|
+
if (this.state !== state || state.chainId !== chainId) throw new Error("Wallet changed before deposit submission.");
|
|
8983
|
+
const submitting = evidence.map((leg) => ({ ...leg, depositSubmission: "started" }));
|
|
8984
|
+
await options.onBeforeSubmission(submitting);
|
|
8985
|
+
if (this.state !== state || state.chainId !== chainId) throw new Error("Wallet changed before deposit submission.");
|
|
8986
|
+
submitting.forEach((leg) => notifyFunding(onProgress, leg));
|
|
8987
|
+
} catch (cause) {
|
|
8988
|
+
checkpointFailedEvidence = evidence;
|
|
8989
|
+
checkpointFailure = new OwneyError(
|
|
8990
|
+
"DEPOSIT_CHECKPOINT_FAILED",
|
|
8991
|
+
"Could not safely save this deposit before submission.",
|
|
8992
|
+
{ notSubmitted: !options.resumeTxHash, safeToFallback: false, cause }
|
|
8993
|
+
);
|
|
8994
|
+
throw checkpointFailure;
|
|
8995
|
+
}
|
|
8996
|
+
} : void 0;
|
|
8997
|
+
const checkpointDestinations = checkpoint2 ? async (destinations, identifier) => {
|
|
8998
|
+
const evidence = destinations.map((destination) => {
|
|
8999
|
+
const leg = prepared.get(destination.to.toLowerCase());
|
|
9000
|
+
if (!leg || leg.intendedAmount !== destination.amount)
|
|
9001
|
+
throw new OwneyError("DEPOSIT_CHECKPOINT_FAILED", "Missing prepared deposit destination.", { notSubmitted: true, safeToFallback: false });
|
|
9002
|
+
return { ...leg, ...identifier, transfer: "pending" };
|
|
9003
|
+
});
|
|
9004
|
+
await checkpoint2(evidence);
|
|
9005
|
+
} : void 0;
|
|
9006
|
+
const checkpointHash = checkpointDestinations ? (hash, destinations) => checkpointDestinations(destinations, { txHash: hash }) : void 0;
|
|
9007
|
+
const checkpointCalls = checkpointDestinations ? (id, destinations) => checkpointDestinations(destinations, { callsId: id }) : void 0;
|
|
9008
|
+
const checkpointPaid = checkpoint2 ? (evidence) => checkpoint2([evidence]) : void 0;
|
|
9009
|
+
const customCallback = depositCallback && checkpointDestinations ? makeVerificationAwareDepositCallback(async (to, cid, value, verification) => {
|
|
9010
|
+
if (verification) provideDepositVerificationContext(depositCallback, verification);
|
|
9011
|
+
await checkpointDestinations([{ to, amount: value }], {});
|
|
9012
|
+
return depositCallback(to, cid, value);
|
|
9013
|
+
}) : depositCallback;
|
|
8934
9014
|
if (options.resumeTxHash && (depositCallback || this.paymasterServiceUrl || !/^0x[\da-f]{64}$/i.test(options.resumeTxHash)))
|
|
8935
9015
|
throw new OwneyError("DEPOSIT_IN_PROGRESS", "This deposit cannot resume the saved relayer transaction.");
|
|
8936
|
-
const effectiveCallback =
|
|
9016
|
+
const effectiveCallback = customCallback ?? (this.paymasterServiceUrl ? this.getDefaultSponsoredCallsCallback(asset, onApproved, onSubmitted, onCallsProgress, checkpointCalls) : asset === "WETH" ? this.getDefaultWethSponsoredCallback(onApproved, onSubmitted, options.resumeTxHash, checkpointHash) : this.getDefaultSponsoredCallback(onApproved, onSubmitted, options.resumeTxHash, checkpointHash));
|
|
8937
9017
|
try {
|
|
8938
9018
|
if (options.resumeTxHash) {
|
|
8939
9019
|
const token = SupportedAssets.find((value) => value.chainId === chainId && value.symbol === asset);
|
|
@@ -8997,7 +9077,8 @@ var OwneySDK = class {
|
|
|
8997
9077
|
depositCallback,
|
|
8998
9078
|
onProgress,
|
|
8999
9079
|
() => paidFallbackAgents.add(agent.id),
|
|
9000
|
-
!!options.resumeTxHash
|
|
9080
|
+
!!options.resumeTxHash,
|
|
9081
|
+
checkpointPaid
|
|
9001
9082
|
);
|
|
9002
9083
|
}
|
|
9003
9084
|
const totalAmount = BigInt(amount);
|
|
@@ -9099,7 +9180,8 @@ var OwneySDK = class {
|
|
|
9099
9180
|
depositCallback,
|
|
9100
9181
|
onProgress,
|
|
9101
9182
|
() => paidFallbackAgents.add(agent.id),
|
|
9102
|
-
!!options.resumeTxHash
|
|
9183
|
+
!!options.resumeTxHash,
|
|
9184
|
+
checkpointPaid
|
|
9103
9185
|
);
|
|
9104
9186
|
} catch (error) {
|
|
9105
9187
|
if (Object.keys(agentResults).length === 0) throw error;
|
|
@@ -9119,12 +9201,22 @@ var OwneySDK = class {
|
|
|
9119
9201
|
}
|
|
9120
9202
|
return { agentResults };
|
|
9121
9203
|
} catch (error) {
|
|
9204
|
+
if (checkpointFailure && !(error instanceof OwneyError && error.details?.notSubmitted === false)) {
|
|
9205
|
+
error = error instanceof OwneyError && error.code === "DEPOSIT_PARTIAL_FAILURE" ? new OwneyError(
|
|
9206
|
+
error.code,
|
|
9207
|
+
"Some deposits completed before another agent could be submitted.",
|
|
9208
|
+
{ ...error.details, cause: checkpointFailure },
|
|
9209
|
+
error.agentId
|
|
9210
|
+
) : checkpointFailure;
|
|
9211
|
+
if (!options.resumeTxHash) for (const evidence of checkpointFailedEvidence)
|
|
9212
|
+
notifyFunding(onProgress, { ...evidence, transfer: "failed" });
|
|
9213
|
+
}
|
|
9122
9214
|
if (!depositCallback && onProgress && !options.resumeTxHash) {
|
|
9123
9215
|
const ids = agentId ? [agentId] : this.getEligibleAgents(chainId, asset).map((agent) => agent.id);
|
|
9124
9216
|
for (const id of ids) {
|
|
9125
9217
|
const evidence = [...prepared.values()].find((value) => value.agentId === id);
|
|
9126
|
-
if (paidFallbackAgents.has(id) || evidence?.transfer === "confirmed" || evidence?.transfer === "failed") continue;
|
|
9127
9218
|
const rejected = error instanceof OwneyError && error.details?.notSubmitted === true;
|
|
9219
|
+
if (!rejected && paidFallbackAgents.has(id) || evidence?.transfer === "confirmed" || evidence?.transfer === "failed") continue;
|
|
9128
9220
|
if (!rejected && (evidence?.txHash || evidence?.userOpHash || evidence?.callsId)) continue;
|
|
9129
9221
|
notifyFunding(onProgress, { ...evidence ?? {
|
|
9130
9222
|
agentId: id,
|
|
@@ -9167,11 +9259,11 @@ var OwneySDK = class {
|
|
|
9167
9259
|
* propagates unchanged. Scoped per agent invocation so one agent's failure
|
|
9168
9260
|
* doesn't force a retry of sibling agents in a multi-agent split.
|
|
9169
9261
|
*/
|
|
9170
|
-
async depositWithFallback(agent, state, chainId, amount, asset, effectiveCallback, appCallback, onProgress, onPaidFallback, resumeOnly = false) {
|
|
9262
|
+
async depositWithFallback(agent, state, chainId, amount, asset, effectiveCallback, appCallback, onProgress, onPaidFallback, resumeOnly = false, onBeforeSubmission) {
|
|
9171
9263
|
const attempt = (callback) => withFailureReporting(
|
|
9172
9264
|
this.apiKey,
|
|
9173
9265
|
agent.id,
|
|
9174
|
-
() => onProgress ? agent.deposit(state, chainId, amount, asset, callback, onProgress) : agent.deposit(state, chainId, amount, asset, callback),
|
|
9266
|
+
() => onBeforeSubmission ? agent.deposit(state, chainId, amount, asset, callback, onProgress, onBeforeSubmission) : onProgress ? agent.deposit(state, chainId, amount, asset, callback, onProgress) : agent.deposit(state, chainId, amount, asset, callback),
|
|
9175
9267
|
this.routingApiBaseUrl
|
|
9176
9268
|
);
|
|
9177
9269
|
let approvalAttempted = false;
|