@owney/sdk 0.7.25-beta.12 → 0.7.25-beta.13

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 CHANGED
@@ -2632,8 +2632,8 @@ var ZyfaiAgent = class _ZyfaiAgent {
2632
2632
  };
2633
2633
 
2634
2634
  // src/agents/yieldseeker/yieldseeker.agent.ts
2635
- var import_viem8 = require("viem");
2636
- var import_chains3 = require("viem/chains");
2635
+ var import_viem10 = require("viem");
2636
+ var import_chains4 = require("viem/chains");
2637
2637
 
2638
2638
  // src/lib/chain-guard.ts
2639
2639
  var CHAIN_NAMES = {
@@ -2676,10 +2676,10 @@ var import_viem4 = require("viem");
2676
2676
  // src/lib/sponsor-client.ts
2677
2677
  var ROUTING_API_BASE_URL = "https://owney-routing-api-243946518160.europe-west4.run.app";
2678
2678
  async function postPaymasterIntent(input) {
2679
- const base5 = input.baseUrl ?? ROUTING_API_BASE_URL;
2679
+ const base6 = input.baseUrl ?? ROUTING_API_BASE_URL;
2680
2680
  let res;
2681
2681
  try {
2682
- res = await fetch(`${base5}/api/v1/sponsor/paymaster-intent`, {
2682
+ res = await fetch(`${base6}/api/v1/sponsor/paymaster-intent`, {
2683
2683
  method: "POST",
2684
2684
  headers: {
2685
2685
  "content-type": "application/json",
@@ -2715,11 +2715,11 @@ async function postPaymasterIntent(input) {
2715
2715
  return parsed.data;
2716
2716
  }
2717
2717
  async function getSponsorRelayerAddress(input) {
2718
- const base5 = input.baseUrl ?? ROUTING_API_BASE_URL;
2718
+ const base6 = input.baseUrl ?? ROUTING_API_BASE_URL;
2719
2719
  let res;
2720
2720
  try {
2721
2721
  res = await fetch(
2722
- `${base5}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
2722
+ `${base6}/api/v1/sponsor/relayer-address?chainId=${input.chainId}`,
2723
2723
  {
2724
2724
  headers: { "x-owney-api-key": input.apiKey }
2725
2725
  }
@@ -3740,6 +3740,395 @@ function mapYieldseekerAgentApy(options, days) {
3740
3740
  };
3741
3741
  }
3742
3742
 
3743
+ // src/agents/yieldseeker/yieldseeker.wallet-version.ts
3744
+ var import_viem8 = require("viem");
3745
+ var YIELDSEEKER_FACTORY = "0x9c7410a0faCAC60850C46eE5b58B518daec95130";
3746
+ var YIELDSEEKER_V1_IMPLEMENTATION = "0x32403455357589523435dB18b414057D7cE05051";
3747
+ var YIELDSEEKER_V2_IMPLEMENTATION = "0x613Db9c924ADB7A7A90c11b02Cce20c913E3Fe50";
3748
+ var ERC1967_IMPLEMENTATION_SLOT = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
3749
+ var walletAbi = (0, import_viem8.parseAbi)([
3750
+ "function owner() view returns (address)",
3751
+ "function ownerAgentIndex() view returns (uint256)",
3752
+ "function baseAsset() view returns (address)",
3753
+ "function FACTORY() view returns (address)",
3754
+ "function upgradeToLatest()"
3755
+ ]);
3756
+ var factoryAbi = (0, import_viem8.parseAbi)([
3757
+ "function userWallets(address owner, uint256 index) view returns (address)",
3758
+ "function agentWalletImplementation() view returns (address)"
3759
+ ]);
3760
+ function yieldseekerOwnerPath(code) {
3761
+ return !code || code === "0x" || /^0xef0100[0-9a-f]{40}$/i.test(code) ? "eoa" : "smart";
3762
+ }
3763
+ async function readYieldseekerWalletStatus(client, wallet, owner, asset) {
3764
+ const agentWallet = (0, import_viem8.getAddress)(wallet);
3765
+ const expectedOwner = (0, import_viem8.getAddress)(owner);
3766
+ const expectedAsset = (0, import_viem8.getAddress)(asset);
3767
+ const [code, ownerCode, slot, actualOwner, index, actualAsset, actualFactory, latest] = await Promise.all([
3768
+ client.getBytecode({ address: agentWallet }),
3769
+ client.getBytecode({ address: expectedOwner }),
3770
+ client.getStorageAt({ address: agentWallet, slot: ERC1967_IMPLEMENTATION_SLOT }),
3771
+ client.readContract({ address: agentWallet, abi: walletAbi, functionName: "owner" }),
3772
+ client.readContract({ address: agentWallet, abi: walletAbi, functionName: "ownerAgentIndex" }),
3773
+ client.readContract({ address: agentWallet, abi: walletAbi, functionName: "baseAsset" }),
3774
+ client.readContract({ address: agentWallet, abi: walletAbi, functionName: "FACTORY" }),
3775
+ client.readContract({ address: YIELDSEEKER_FACTORY, abi: factoryAbi, functionName: "agentWalletImplementation" })
3776
+ ]);
3777
+ if (!code || code === "0x" || !slot || /^0x0+$/.test(slot)) {
3778
+ throw new Error("Yieldseeker wallet is not a deployed ERC1967 proxy");
3779
+ }
3780
+ const implementation = (0, import_viem8.getAddress)(`0x${slot.slice(-40)}`);
3781
+ const mapped = await client.readContract({
3782
+ address: YIELDSEEKER_FACTORY,
3783
+ abi: factoryAbi,
3784
+ functionName: "userWallets",
3785
+ args: [expectedOwner, index]
3786
+ });
3787
+ const verified = (0, import_viem8.isAddressEqual)(actualOwner, expectedOwner) && (0, import_viem8.isAddressEqual)(actualAsset, expectedAsset) && (0, import_viem8.isAddressEqual)(actualFactory, YIELDSEEKER_FACTORY) && (0, import_viem8.isAddressEqual)(mapped, agentWallet);
3788
+ const version = !verified ? "unknown" : (0, import_viem8.isAddressEqual)(implementation, YIELDSEEKER_V2_IMPLEMENTATION) ? "v2" : (0, import_viem8.isAddressEqual)(implementation, YIELDSEEKER_V1_IMPLEMENTATION) ? "v1" : "unknown";
3789
+ return {
3790
+ agentWallet,
3791
+ owner: actualOwner,
3792
+ ownerPath: yieldseekerOwnerPath(ownerCode),
3793
+ asset: actualAsset,
3794
+ implementation,
3795
+ version,
3796
+ verified,
3797
+ upgradeAvailable: version === "v1" && (0, import_viem8.isAddressEqual)(latest, YIELDSEEKER_V2_IMPLEMENTATION)
3798
+ };
3799
+ }
3800
+ var YIELDSEEKER_UPGRADE_ABI = walletAbi;
3801
+
3802
+ // src/agents/yieldseeker/yieldseeker.sponsored-withdraw.ts
3803
+ var import_viem9 = require("viem");
3804
+ var import_account_abstraction = require("viem/account-abstraction");
3805
+ var import_accounts = require("viem/accounts");
3806
+ var import_chains3 = require("viem/chains");
3807
+ var ENTRY_POINT_V06 = "0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789";
3808
+ var USER_OP_FEE_HEADROOM = 2n;
3809
+ var ENTRY_POINT_NONCE_ABI = [
3810
+ { type: "function", name: "getNonce", stateMutability: "view", inputs: [
3811
+ { name: "sender", type: "address" },
3812
+ { name: "key", type: "uint192" }
3813
+ ], outputs: [{ type: "uint256" }] }
3814
+ ];
3815
+ var DEFAULT_ROUTING_API = "https://owney-routing-api-243946518160.europe-west4.run.app";
3816
+ var SIMULATION_ACCOUNT = (0, import_accounts.privateKeyToAccount)((0, import_accounts.generatePrivateKey)());
3817
+ function operationHash(operation) {
3818
+ return (0, import_account_abstraction.getUserOperationHash)({
3819
+ chainId: 8453,
3820
+ entryPointAddress: ENTRY_POINT_V06,
3821
+ entryPointVersion: "0.6",
3822
+ userOperation: {
3823
+ sender: operation.sender,
3824
+ nonce: BigInt(operation.nonce),
3825
+ initCode: operation.initCode,
3826
+ callData: operation.callData,
3827
+ callGasLimit: BigInt(operation.callGasLimit),
3828
+ verificationGasLimit: BigInt(operation.verificationGasLimit),
3829
+ preVerificationGas: BigInt(operation.preVerificationGas),
3830
+ maxFeePerGas: BigInt(operation.maxFeePerGas),
3831
+ maxPriorityFeePerGas: BigInt(operation.maxPriorityFeePerGas),
3832
+ paymasterAndData: operation.paymasterAndData,
3833
+ signature: operation.signature
3834
+ }
3835
+ });
3836
+ }
3837
+ function sponsorError(message, safeToFallback, details = {}) {
3838
+ return new OwneyError(
3839
+ "SPONSOR_REQUEST_FAILED",
3840
+ message,
3841
+ { safeToFallback, ...details },
3842
+ "yieldseeker"
3843
+ );
3844
+ }
3845
+ async function requestIntent(input) {
3846
+ const baseUrl = (input.routingApiBaseUrl ?? DEFAULT_ROUTING_API).replace(/\/$/, "");
3847
+ let response;
3848
+ try {
3849
+ response = await fetch(`${baseUrl}/api/v1/sponsor/yieldseeker-withdraw/intent`, {
3850
+ method: "POST",
3851
+ headers: {
3852
+ "content-type": "application/json",
3853
+ "x-owney-api-key": input.apiKey,
3854
+ Authorization: `Signature ${input.yieldseekerSignature}`
3855
+ },
3856
+ body: JSON.stringify({
3857
+ chainId: 8453,
3858
+ owner: input.owner,
3859
+ recipient: input.owner,
3860
+ agentWallet: input.agentWallet,
3861
+ asset: input.asset,
3862
+ callData: input.callData,
3863
+ action: input.action,
3864
+ yieldseekerUserId: input.userId,
3865
+ yieldseekerAgentId: input.agentId
3866
+ })
3867
+ });
3868
+ } catch {
3869
+ throw sponsorError("Withdrawal sponsorship could not be requested.", true);
3870
+ }
3871
+ const envelope = await response.json().catch(() => null);
3872
+ const intent = envelope?.data;
3873
+ if (!response.ok || !envelope?.success || !intent?.intent || !["eoa", "smart"].includes(intent.ownerPath)) {
3874
+ throw sponsorError(
3875
+ "Withdrawal sponsorship is currently unavailable.",
3876
+ true,
3877
+ { statusCode: response.status }
3878
+ );
3879
+ }
3880
+ const url = new URL(`${baseUrl}/api/v1/sponsor/yieldseeker-withdraw/rpc`);
3881
+ url.searchParams.set("intent", intent.intent);
3882
+ return { intent, rpcUrl: url.toString() };
3883
+ }
3884
+ async function rpc(url, method, params, phase) {
3885
+ let response;
3886
+ try {
3887
+ response = await fetch(url, {
3888
+ method: "POST",
3889
+ headers: { "content-type": "application/json" },
3890
+ body: JSON.stringify({ jsonrpc: "2.0", id: 1, method, params })
3891
+ });
3892
+ } catch {
3893
+ throw sponsorError("Withdrawal sponsorship request status is unknown.", phase === "prepare");
3894
+ }
3895
+ const payload = await response.json().catch(() => null);
3896
+ if (!response.ok || payload?.error || payload?.result === void 0) {
3897
+ const rejection = payload?.error;
3898
+ const definitiveRejection = phase === "send" && response.status < 500 && !!rejection && (rejection.data?.rejectedBeforeSubmission === true || [-32501, -32502, -32503, -32504, -32505, -32507].includes(rejection.code ?? 0) || /maxFeePerGas.*(?:too low|lower than|less than|must be at least)/i.test(rejection.message ?? ""));
3899
+ throw sponsorError(
3900
+ phase !== "prepare" && !definitiveRejection ? "Sponsored withdrawal submission status is unknown." : "Withdrawal sponsorship was declined before submission.",
3901
+ phase === "prepare" || definitiveRejection,
3902
+ { statusCode: response.status, rpcCode: payload?.error?.code, rpcMethod: method }
3903
+ );
3904
+ }
3905
+ return payload.result;
3906
+ }
3907
+ async function waitForTransaction(client, txHash) {
3908
+ const receipt = await client.waitForTransactionReceipt({ hash: txHash, confirmations: 1 });
3909
+ if (receipt.status !== "success")
3910
+ throw new OwneyError(
3911
+ "AGENT_TRANSACTION_REVERTED",
3912
+ `Yieldseeker withdrawal reverted (${txHash}).`,
3913
+ { transactionHash: txHash },
3914
+ "yieldseeker"
3915
+ );
3916
+ return receipt;
3917
+ }
3918
+ async function submitEoa(input) {
3919
+ let nonce;
3920
+ let fees;
3921
+ try {
3922
+ nonce = await input.client.readContract({
3923
+ address: ENTRY_POINT_V06,
3924
+ abi: ENTRY_POINT_NONCE_ABI,
3925
+ functionName: "getNonce",
3926
+ args: [input.agentWallet, 0n]
3927
+ });
3928
+ fees = await input.client.estimateFeesPerGas();
3929
+ } catch {
3930
+ throw sponsorError("Could not prepare the sponsored withdrawal.", true);
3931
+ }
3932
+ if (fees.maxFeePerGas === void 0 || fees.maxPriorityFeePerGas === void 0)
3933
+ throw sponsorError("Base did not return EIP-1559 gas fees.", true);
3934
+ let operation = {
3935
+ sender: input.agentWallet,
3936
+ nonce: (0, import_viem9.toHex)(nonce),
3937
+ initCode: "0x",
3938
+ callData: input.callData,
3939
+ callGasLimit: (0, import_viem9.toHex)(3e5),
3940
+ verificationGasLimit: (0, import_viem9.toHex)(3e5),
3941
+ preVerificationGas: (0, import_viem9.toHex)(6e4),
3942
+ maxFeePerGas: (0, import_viem9.toHex)(fees.maxFeePerGas * USER_OP_FEE_HEADROOM),
3943
+ maxPriorityFeePerGas: (0, import_viem9.toHex)(fees.maxPriorityFeePerGas),
3944
+ paymasterAndData: "0x",
3945
+ signature: "0x"
3946
+ };
3947
+ operation.signature = await SIMULATION_ACCOUNT.signMessage({ message: { raw: operationHash(operation) } });
3948
+ const stub = await rpc(
3949
+ input.rpcUrl,
3950
+ "pm_getPaymasterStubData",
3951
+ [operation, ENTRY_POINT_V06, (0, import_viem9.toHex)(8453), {}],
3952
+ "prepare"
3953
+ );
3954
+ if (!stub.paymasterAndData?.startsWith("0x"))
3955
+ throw sponsorError("CDP did not return v0.6 paymaster data.", true);
3956
+ operation = { ...operation, paymasterAndData: stub.paymasterAndData };
3957
+ operation.signature = await SIMULATION_ACCOUNT.signMessage({ message: { raw: operationHash(operation) } });
3958
+ const gas = await rpc(input.rpcUrl, "eth_estimateUserOperationGas", [operation, ENTRY_POINT_V06], "prepare");
3959
+ if (!gas.callGasLimit || !gas.verificationGasLimit || !gas.preVerificationGas)
3960
+ throw sponsorError("CDP did not return UserOperation gas estimates.", true);
3961
+ operation = { ...operation, ...gas };
3962
+ if (!stub.isFinal) {
3963
+ const final = await rpc(
3964
+ input.rpcUrl,
3965
+ "pm_getPaymasterData",
3966
+ [operation, ENTRY_POINT_V06, (0, import_viem9.toHex)(8453), {}],
3967
+ "prepare"
3968
+ );
3969
+ if (!final.paymasterAndData?.startsWith("0x"))
3970
+ throw sponsorError("CDP did not return final paymaster data.", true);
3971
+ operation = { ...operation, paymasterAndData: final.paymasterAndData };
3972
+ }
3973
+ const userOpHash = operationHash(operation);
3974
+ const wallet = (0, import_viem9.createWalletClient)({
3975
+ account: input.owner,
3976
+ chain: import_chains3.base,
3977
+ transport: (0, import_viem9.custom)(input.state.provider)
3978
+ });
3979
+ const signature = await wallet.signMessage({ message: { raw: userOpHash } });
3980
+ operation = { ...operation, signature };
3981
+ input.onPending?.({ userOpHash });
3982
+ const submittedHash = await rpc(
3983
+ input.rpcUrl,
3984
+ "eth_sendUserOperation",
3985
+ [operation, ENTRY_POINT_V06],
3986
+ "send"
3987
+ );
3988
+ if (submittedHash.toLowerCase() !== userOpHash.toLowerCase())
3989
+ throw sponsorError(
3990
+ "Bundler returned a different UserOperation hash.",
3991
+ false,
3992
+ { userOpHash, submittedHash }
3993
+ );
3994
+ for (let poll = 0; poll < 40; poll++) {
3995
+ const response = await rpc(input.rpcUrl, "eth_getUserOperationReceipt", [userOpHash], "observe");
3996
+ const txHash = response?.receipt?.transactionHash;
3997
+ if (txHash) {
3998
+ input.onPending?.({ userOpHash, txHash });
3999
+ if (response?.success === false)
4000
+ throw new OwneyError(
4001
+ "AGENT_TRANSACTION_REVERTED",
4002
+ "Sponsored withdrawal execution reverted.",
4003
+ { userOpHash, transactionHash: txHash },
4004
+ "yieldseeker"
4005
+ );
4006
+ return { txHash, receipt: await waitForTransaction(input.client, txHash) };
4007
+ }
4008
+ await new Promise((resolve) => setTimeout(resolve, 1500));
4009
+ }
4010
+ throw sponsorError(
4011
+ "Sponsored withdrawal is still pending; check status before retrying.",
4012
+ false,
4013
+ { userOpHash }
4014
+ );
4015
+ }
4016
+ async function submitSmart(input) {
4017
+ let capabilities;
4018
+ try {
4019
+ capabilities = await input.state.provider.request({
4020
+ method: "wallet_getCapabilities",
4021
+ params: [input.owner]
4022
+ });
4023
+ } catch {
4024
+ throw sponsorError("This account cannot check paymaster support on Base.", true);
4025
+ }
4026
+ if (!capabilities?.[(0, import_viem9.toHex)(8453)]?.paymasterService?.supported && !capabilities?.["8453"]?.paymasterService?.supported)
4027
+ throw sponsorError("This account cannot use a paymaster on Base.", true);
4028
+ let sent;
4029
+ try {
4030
+ input.onPending?.({});
4031
+ } catch {
4032
+ throw sponsorError("Upgrade or withdrawal status cannot be saved.", true);
4033
+ }
4034
+ try {
4035
+ sent = await input.state.provider.request({
4036
+ method: "wallet_sendCalls",
4037
+ params: [{
4038
+ version: "2.0.0",
4039
+ from: input.owner,
4040
+ chainId: (0, import_viem9.toHex)(8453),
4041
+ atomicRequired: false,
4042
+ calls: [{ to: input.agentWallet, value: "0x0", data: input.callData }],
4043
+ capabilities: { paymasterService: { url: input.rpcUrl } }
4044
+ }]
4045
+ });
4046
+ } catch (error) {
4047
+ if (error?.code === 4001) throw error;
4048
+ if ([4200, -32601].includes(Number(error?.code)))
4049
+ throw sponsorError("This account does not support sponsored calls.", true);
4050
+ throw sponsorError("Wallet submission status is unknown. Check activity before retrying.", false);
4051
+ }
4052
+ const callsId = typeof sent === "string" ? sent : sent?.id;
4053
+ if (!callsId) throw sponsorError("Wallet returned no calls ID; submission status is unknown.", false);
4054
+ try {
4055
+ input.onPending?.({ callsId });
4056
+ } catch {
4057
+ throw sponsorError("Submitted call status could not be saved.", false, { callsId });
4058
+ }
4059
+ for (let poll = 0; poll < 40; poll++) {
4060
+ let status;
4061
+ try {
4062
+ status = await input.state.provider.request({
4063
+ method: "wallet_getCallsStatus",
4064
+ params: [callsId]
4065
+ });
4066
+ } catch {
4067
+ throw sponsorError("Sponsored withdrawal status is unknown.", false, { callsId });
4068
+ }
4069
+ if (status?.status === 400 || status?.status === 500)
4070
+ throw sponsorError(
4071
+ "Sponsored withdrawal failed in the wallet.",
4072
+ false,
4073
+ { callsId, executionFailed: true }
4074
+ );
4075
+ const txHash = status?.receipts?.[0]?.transactionHash;
4076
+ if (txHash) {
4077
+ try {
4078
+ input.onPending?.({ callsId, txHash });
4079
+ } catch {
4080
+ throw sponsorError(
4081
+ "Submitted call receipt could not be saved.",
4082
+ false,
4083
+ { callsId, txHash }
4084
+ );
4085
+ }
4086
+ return { txHash, receipt: await waitForTransaction(input.client, txHash) };
4087
+ }
4088
+ await new Promise((resolve) => setTimeout(resolve, 1500));
4089
+ }
4090
+ throw sponsorError(
4091
+ "Sponsored withdrawal is still pending; check status before retrying.",
4092
+ false,
4093
+ { callsId }
4094
+ );
4095
+ }
4096
+ async function submitYieldseekerSponsoredWithdrawal(input) {
4097
+ const owner = (0, import_viem9.getAddress)(input.state.walletAddress);
4098
+ const { intent, rpcUrl } = await requestIntent({
4099
+ apiKey: input.apiKey,
4100
+ routingApiBaseUrl: input.routingApiBaseUrl,
4101
+ yieldseekerSignature: input.yieldseekerSignature,
4102
+ userId: input.userId,
4103
+ agentId: input.agentId,
4104
+ owner,
4105
+ agentWallet: input.agentWallet,
4106
+ asset: input.asset,
4107
+ callData: input.callData,
4108
+ action: "withdraw"
4109
+ });
4110
+ const args = { ...input, owner, rpcUrl };
4111
+ return intent.ownerPath === "eoa" ? submitEoa(args) : submitSmart(args);
4112
+ }
4113
+ async function submitYieldseekerSponsoredUpgrade(input) {
4114
+ const owner = (0, import_viem9.getAddress)(input.state.walletAddress);
4115
+ const { intent, rpcUrl } = await requestIntent({
4116
+ apiKey: input.apiKey,
4117
+ routingApiBaseUrl: input.routingApiBaseUrl,
4118
+ yieldseekerSignature: input.yieldseekerSignature,
4119
+ userId: input.userId,
4120
+ agentId: input.agentId,
4121
+ owner,
4122
+ agentWallet: input.agentWallet,
4123
+ asset: input.asset,
4124
+ callData: input.callData,
4125
+ action: "upgrade"
4126
+ });
4127
+ if (intent.ownerPath !== "smart")
4128
+ throw sponsorError("V1 upgrade sponsorship requires a Base Account owner.", true);
4129
+ return submitSmart({ ...input, owner, rpcUrl });
4130
+ }
4131
+
3743
4132
  // src/agents/yieldseeker/yieldseeker.agent.ts
3744
4133
  var OWNEY_AGENT_NAME = "owney";
3745
4134
  var OWNEY_AGENT_RULE_PRESET = "explorative";
@@ -3812,7 +4201,11 @@ var YieldseekerAgent = class {
3812
4201
  api;
3813
4202
  auth;
3814
4203
  rpcUrls;
4204
+ owneyApiKey;
4205
+ routingApiBaseUrl;
3815
4206
  receiptClient;
4207
+ // A client preparation hint only; the routing API still checks live identity.
4208
+ withdrawalVersionCache = /* @__PURE__ */ new Map();
3816
4209
  transactionExecutor;
3817
4210
  unwindReceiptWaiter;
3818
4211
  agentContexts = /* @__PURE__ */ new Map();
@@ -3834,6 +4227,8 @@ var YieldseekerAgent = class {
3834
4227
  yieldOptions = /* @__PURE__ */ new Map();
3835
4228
  pendingYieldOptions = /* @__PURE__ */ new Map();
3836
4229
  constructor(owneyApiKey, options = {}) {
4230
+ this.owneyApiKey = owneyApiKey;
4231
+ this.routingApiBaseUrl = options.routingApiBaseUrl;
3837
4232
  this.api = new YieldseekerApiClient(
3838
4233
  owneyApiKey,
3839
4234
  options.baseUrl ?? getYieldseekerProxyBaseUrl(),
@@ -3845,10 +4240,182 @@ var YieldseekerAgent = class {
3845
4240
  this.unwindReceiptWaiter = options.unwindReceiptWaiter;
3846
4241
  }
3847
4242
  getReceiptClient() {
3848
- this.receiptClient ??= createPaidRpcClient(import_chains3.base, this.rpcUrls);
4243
+ this.receiptClient ??= createPaidRpcClient(import_chains4.base, this.rpcUrls);
3849
4244
  return this.receiptClient;
3850
4245
  }
4246
+ /** Reads the actual proxy implementation; Yieldseeker's API walletType is not a version check. */
4247
+ async getWalletStatus(state, chainId, asset, useCachedV2 = false) {
4248
+ this.assertChain(chainId);
4249
+ this.assertAsset(asset);
4250
+ const context = await this.findAgent(state, chainId, asset);
4251
+ if (!context) return null;
4252
+ const key2 = `${chainId}:${state.walletAddress.toLowerCase()}:${context.wallet.walletAddress.toLowerCase()}:${asset}`;
4253
+ const cached = this.withdrawalVersionCache.get(key2);
4254
+ if (useCachedV2 && cached && Date.now() - cached.at < 15 * 6e4) return { ...cached.status };
4255
+ const status = await readYieldseekerWalletStatus(
4256
+ this.getReceiptClient(),
4257
+ (0, import_viem10.getAddress)(context.wallet.walletAddress),
4258
+ (0, import_viem10.getAddress)(state.walletAddress),
4259
+ YIELDSEEKER_ASSET_METADATA[asset].address
4260
+ );
4261
+ if (status.verified && status.version === "v2") {
4262
+ this.withdrawalVersionCache.set(key2, { at: Date.now(), status: { ...status } });
4263
+ if (this.withdrawalVersionCache.size > 128)
4264
+ this.withdrawalVersionCache.delete(this.withdrawalVersionCache.keys().next().value);
4265
+ } else this.withdrawalVersionCache.delete(key2);
4266
+ return status;
4267
+ }
4268
+ /** Explicit owner action. This never runs as a side effect of withdrawal. */
4269
+ async upgradeWallet(state, chainId, asset, gasMode = "paid") {
4270
+ const before = await this.getWalletStatus(state, chainId, asset);
4271
+ if (!before?.verified || !before.upgradeAvailable) {
4272
+ throw new OwneyError(
4273
+ "WITHDRAW_FAILED",
4274
+ "This Yieldseeker wallet cannot be upgraded to the reviewed V2 implementation.",
4275
+ { version: before?.version ?? "missing" },
4276
+ this.id
4277
+ );
4278
+ }
4279
+ const data = (0, import_viem10.encodeFunctionData)({ abi: YIELDSEEKER_UPGRADE_ABI, functionName: "upgradeToLatest" });
4280
+ let txHash;
4281
+ if (gasMode === "sponsored") {
4282
+ if (before.ownerPath !== "smart")
4283
+ throw new OwneyError(
4284
+ "SPONSOR_REQUEST_FAILED",
4285
+ "EOA owners pay Base gas for the V1 upgrade.",
4286
+ { safeToFallback: true },
4287
+ this.id
4288
+ );
4289
+ let storage5;
4290
+ try {
4291
+ storage5 = typeof window === "undefined" ? void 0 : window.localStorage;
4292
+ } catch {
4293
+ storage5 = void 0;
4294
+ }
4295
+ if (!storage5)
4296
+ throw new OwneyError(
4297
+ "SPONSOR_REQUEST_FAILED",
4298
+ "Upgrade status cannot be saved in this browser.",
4299
+ { safeToFallback: true },
4300
+ this.id
4301
+ );
4302
+ const pendingKey = `owney.yieldseeker.upgrade:${state.walletAddress.toLowerCase()}:${before.agentWallet.toLowerCase()}`;
4303
+ let prior = null;
4304
+ let saved;
4305
+ try {
4306
+ saved = storage5.getItem(pendingKey);
4307
+ } catch {
4308
+ throw new OwneyError(
4309
+ "SPONSOR_REQUEST_FAILED",
4310
+ "Upgrade status cannot be read in this browser.",
4311
+ { safeToFallback: true },
4312
+ this.id
4313
+ );
4314
+ }
4315
+ try {
4316
+ prior = JSON.parse(saved ?? "null");
4317
+ } catch {
4318
+ prior = { callsId: void 0 };
4319
+ }
4320
+ if (prior) {
4321
+ if (!prior.callsId)
4322
+ throw new OwneyError(
4323
+ "SPONSOR_REQUEST_FAILED",
4324
+ "An earlier upgrade submission is unresolved. Check wallet activity before retrying.",
4325
+ { safeToFallback: false },
4326
+ this.id
4327
+ );
4328
+ let callsStatus;
4329
+ try {
4330
+ callsStatus = await state.provider.request({
4331
+ method: "wallet_getCallsStatus",
4332
+ params: [prior.callsId]
4333
+ });
4334
+ } catch {
4335
+ throw new OwneyError(
4336
+ "SPONSOR_REQUEST_FAILED",
4337
+ "The earlier upgrade status could not be checked.",
4338
+ { safeToFallback: false, callsId: prior.callsId },
4339
+ this.id
4340
+ );
4341
+ }
4342
+ if (callsStatus?.status === 400 || callsStatus?.status === 500) {
4343
+ storage5.removeItem(pendingKey);
4344
+ throw new OwneyError(
4345
+ "SPONSOR_REQUEST_FAILED",
4346
+ "The earlier sponsored upgrade failed.",
4347
+ { safeToFallback: true, callsId: prior.callsId },
4348
+ this.id
4349
+ );
4350
+ }
4351
+ const earlierHash = callsStatus?.receipts?.[0]?.transactionHash;
4352
+ if (earlierHash) {
4353
+ await this.waitForReceipt(state, chainId, earlierHash);
4354
+ const earlierStatus = await this.getWalletStatus(state, chainId, asset);
4355
+ if (earlierStatus?.version === "v2" && earlierStatus.verified) {
4356
+ storage5.removeItem(pendingKey);
4357
+ return { txHash: earlierHash, status: earlierStatus };
4358
+ }
4359
+ }
4360
+ throw new OwneyError(
4361
+ "SPONSOR_REQUEST_FAILED",
4362
+ "An earlier upgrade is still pending.",
4363
+ { safeToFallback: false, callsId: prior.callsId },
4364
+ this.id
4365
+ );
4366
+ }
4367
+ const context = await this.findAgent(state, chainId, asset);
4368
+ if (!context) throw new OwneyError("NOT_CONNECTED", "Yieldseeker agent is unavailable.");
4369
+ try {
4370
+ const upgraded = await submitYieldseekerSponsoredUpgrade({
4371
+ state,
4372
+ client: this.getReceiptClient(),
4373
+ apiKey: this.owneyApiKey,
4374
+ routingApiBaseUrl: this.routingApiBaseUrl,
4375
+ yieldseekerSignature: await this.auth.getToken(state, chainId),
4376
+ userId: context.user.userId,
4377
+ agentId: context.agent.agentId,
4378
+ agentWallet: before.agentWallet,
4379
+ asset: YIELDSEEKER_ASSET_METADATA[asset].address,
4380
+ callData: data,
4381
+ onPending: (pending) => {
4382
+ const current = storage5.getItem(pendingKey);
4383
+ storage5.setItem(pendingKey, JSON.stringify({
4384
+ startedAt: Date.now(),
4385
+ ...current ? JSON.parse(current) : {},
4386
+ ...pending
4387
+ }));
4388
+ }
4389
+ });
4390
+ txHash = upgraded.txHash;
4391
+ } catch (error) {
4392
+ if (error?.code === 4001 || error instanceof OwneyError && error.code === "SPONSOR_REQUEST_FAILED" && (error.details?.safeToFallback === true || error.details?.executionFailed === true)) storage5.removeItem(pendingKey);
4393
+ throw error;
4394
+ }
4395
+ } else {
4396
+ txHash = await this.submitTransaction(state, chainId, {
4397
+ from: (0, import_viem10.getAddress)(state.walletAddress),
4398
+ to: before.agentWallet,
4399
+ data,
4400
+ value: "0",
4401
+ chainId
4402
+ });
4403
+ }
4404
+ const status = await this.getWalletStatus(state, chainId, asset);
4405
+ if (!status?.verified || status.version !== "v2") {
4406
+ throw new OwneyError(
4407
+ "WITHDRAW_FAILED",
4408
+ "Yieldseeker wallet upgrade was not confirmed as V2.",
4409
+ { txHash, version: status?.version ?? "missing" },
4410
+ this.id
4411
+ );
4412
+ }
4413
+ if (gasMode === "sponsored" && typeof window !== "undefined")
4414
+ window.localStorage.removeItem(`owney.yieldseeker.upgrade:${state.walletAddress.toLowerCase()}:${before.agentWallet.toLowerCase()}`);
4415
+ return { txHash, status };
4416
+ }
3851
4417
  async disconnect() {
4418
+ this.withdrawalVersionCache.clear();
3852
4419
  this.readGeneration += 1;
3853
4420
  this.auth.clear();
3854
4421
  for (const key2 of this.users.keys()) {
@@ -3919,12 +4486,12 @@ var YieldseekerAgent = class {
3919
4486
  receipt = await this.waitForReceipt(state, chainId, txHash);
3920
4487
  } else {
3921
4488
  txHash = await this.submitTransaction(state, chainId, {
3922
- from: (0, import_viem8.getAddress)(state.walletAddress),
4489
+ from: (0, import_viem10.getAddress)(state.walletAddress),
3923
4490
  to: YIELDSEEKER_ASSET_METADATA[asset].address,
3924
- data: (0, import_viem8.encodeFunctionData)({
3925
- abi: import_viem8.erc20Abi,
4491
+ data: (0, import_viem10.encodeFunctionData)({
4492
+ abi: import_viem10.erc20Abi,
3926
4493
  functionName: "transfer",
3927
- args: [(0, import_viem8.getAddress)(context.wallet.walletAddress), BigInt(amount)]
4494
+ args: [(0, import_viem10.getAddress)(context.wallet.walletAddress), BigInt(amount)]
3928
4495
  }),
3929
4496
  value: "0",
3930
4497
  chainId
@@ -3935,12 +4502,12 @@ var YieldseekerAgent = class {
3935
4502
  if (this.readGeneration === generation) {
3936
4503
  void this.refreshSnapshotAfterMovement(state, chainId, context, "deposit", movement);
3937
4504
  }
3938
- const base5 = { agentId: this.id, chainId, token: asset, walletAddress: state.walletAddress, agentWallet: context.wallet.walletAddress, intendedAmount: amount, confirmedAmount: amount, txHash, transfer: "confirmed", registration: "not-applicable", delivery: "not-applicable" };
3939
- const evidence = receipt ? inspectFundingReceipt(receipt, base5, YIELDSEEKER_ASSET_METADATA[asset].address, "deposit") : base5;
4505
+ const base6 = { agentId: this.id, chainId, token: asset, walletAddress: state.walletAddress, agentWallet: context.wallet.walletAddress, intendedAmount: amount, confirmedAmount: amount, txHash, transfer: "confirmed", registration: "not-applicable", delivery: "not-applicable" };
4506
+ const evidence = receipt ? inspectFundingReceipt(receipt, base6, YIELDSEEKER_ASSET_METADATA[asset].address, "deposit") : base6;
3940
4507
  notifyFunding(onProgress, evidence);
3941
4508
  return { txHash, smartWallet: context.wallet.walletAddress, amount, evidence };
3942
4509
  }
3943
- async withdraw(state, chainId, asset, amount, onProgress) {
4510
+ async withdraw(state, chainId, asset, amount, onProgress, gasMode = "auto") {
3944
4511
  let ownerTransferAttempted = false;
3945
4512
  let evidence = {
3946
4513
  agentId: this.id,
@@ -3958,14 +4525,20 @@ var YieldseekerAgent = class {
3958
4525
  notifyFunding(onProgress, evidence);
3959
4526
  }, () => {
3960
4527
  ownerTransferAttempted = true;
3961
- });
4528
+ }, gasMode);
3962
4529
  } catch (error) {
3963
- if (!ownerTransferAttempted || error instanceof OwneyError && error.code === "AGENT_TRANSACTION_REVERTED")
3964
- notifyFunding(onProgress, { ...evidence, transfer: "failed", delivery: "failed" });
4530
+ if (error instanceof OwneyError && error.code === "SPONSOR_REQUEST_FAILED") this.withdrawalVersionCache.clear();
4531
+ if (!ownerTransferAttempted || error?.code === 4001 || error instanceof OwneyError && (error.code === "AGENT_TRANSACTION_REVERTED" || error.code === "SPONSOR_REQUEST_FAILED" && (error.details?.safeToFallback === true || error.details?.executionFailed === true)))
4532
+ notifyFunding(onProgress, {
4533
+ ...evidence,
4534
+ ...error instanceof OwneyError && error.code === "SPONSOR_REQUEST_FAILED" && error.details?.safeToFallback === true ? { userOpHash: void 0, callsId: void 0 } : {},
4535
+ transfer: "failed",
4536
+ delivery: "failed"
4537
+ });
3965
4538
  throw error;
3966
4539
  }
3967
4540
  }
3968
- async withdrawInternal(state, chainId, asset, amount, onProgress, onOwnerTransferAttempted) {
4541
+ async withdrawInternal(state, chainId, asset, amount, onProgress, onOwnerTransferAttempted, gasMode = "auto") {
3969
4542
  this.assertChain(chainId);
3970
4543
  this.assertAsset(asset);
3971
4544
  if (amount !== void 0 && BigInt(amount) <= 0n) {
@@ -3985,6 +4558,27 @@ var YieldseekerAgent = class {
3985
4558
  this.id
3986
4559
  );
3987
4560
  }
4561
+ let sponsor = false;
4562
+ if (gasMode !== "paid") {
4563
+ const status = await this.getWalletStatus(state, chainId, asset, true).catch(() => {
4564
+ if (gasMode === "sponsored")
4565
+ throw new OwneyError(
4566
+ "SPONSOR_REQUEST_FAILED",
4567
+ "Could not verify the Yieldseeker wallet for sponsorship.",
4568
+ { safeToFallback: true, version: "unknown" },
4569
+ this.id
4570
+ );
4571
+ return null;
4572
+ });
4573
+ sponsor = !!status?.verified && status.version === "v2";
4574
+ if (gasMode === "sponsored" && !sponsor)
4575
+ throw new OwneyError(
4576
+ "SPONSOR_REQUEST_FAILED",
4577
+ "Only a verified Yieldseeker V2 Agent Wallet can use sponsored withdrawals.",
4578
+ { safeToFallback: true, version: status?.version ?? "unknown" },
4579
+ this.id
4580
+ );
4581
+ }
3988
4582
  const generation = this.readGeneration;
3989
4583
  let confirmedMovement = false;
3990
4584
  let settlement = null;
@@ -3998,9 +4592,9 @@ var YieldseekerAgent = class {
3998
4592
  const readIdle = async () => {
3999
4593
  const balance = await withPaidRpcDiagnostics(() => this.getReceiptClient().readContract({
4000
4594
  address: metadata.address,
4001
- abi: import_viem8.erc20Abi,
4595
+ abi: import_viem10.erc20Abi,
4002
4596
  functionName: "balanceOf",
4003
- args: [(0, import_viem8.getAddress)(context.wallet.walletAddress)]
4597
+ args: [(0, import_viem10.getAddress)(context.wallet.walletAddress)]
4004
4598
  }), chainId, "eth_call", this.id);
4005
4599
  this.assertSession(generation, chainId, asset);
4006
4600
  return balance;
@@ -4034,6 +4628,7 @@ var YieldseekerAgent = class {
4034
4628
  );
4035
4629
  }
4036
4630
  let remaining = requested > idle ? requested - idle : 0n;
4631
+ let grossUnwound = 0n;
4037
4632
  for (const position2 of portfolio.positions) {
4038
4633
  if (remaining === 0n) break;
4039
4634
  const available = BigInt(position2.withdrawableAssetsRaw);
@@ -4057,6 +4652,7 @@ var YieldseekerAgent = class {
4057
4652
  }
4058
4653
  await this.waitForReceipt(state, chainId, response.transactionHash);
4059
4654
  confirmedMovement = true;
4655
+ grossUnwound += assetsRaw;
4060
4656
  remaining -= assetsRaw;
4061
4657
  }
4062
4658
  if (remaining > 0n) {
@@ -4066,7 +4662,10 @@ var YieldseekerAgent = class {
4066
4662
  });
4067
4663
  }
4068
4664
  const availableForOwner = confirmedMovement ? await readIdle() : idle;
4069
- if (availableForOwner === 0n || amount !== void 0 && availableForOwner < requested) {
4665
+ const feeRate = portfolio.snapshot.feeRateBps;
4666
+ const maxFee = confirmedMovement && Number.isInteger(feeRate) && feeRate >= 0 && feeRate <= 1e3 ? (grossUnwound * BigInt(feeRate) + 9999n) / 10000n : 0n;
4667
+ const shortfall = availableForOwner < requested ? requested - availableForOwner : 0n;
4668
+ if (availableForOwner === 0n || amount !== void 0 && shortfall > maxFee) {
4070
4669
  this.invalidateFundingRead(state, chainId, asset);
4071
4670
  throw new OwneyError(
4072
4671
  "WITHDRAW_INSUFFICIENT_BALANCE",
@@ -4075,32 +4674,52 @@ var YieldseekerAgent = class {
4075
4674
  this.id
4076
4675
  );
4077
4676
  }
4078
- const payout = amount === void 0 ? availableForOwner : requested;
4677
+ const payout = amount === void 0 || availableForOwner < requested ? availableForOwner : requested;
4079
4678
  const plannedMovement = this.snapshotMovement(state, chainId, context, -payout);
4080
- const account = (0, import_viem8.getAddress)(state.walletAddress);
4679
+ const account = (0, import_viem10.getAddress)(state.walletAddress);
4081
4680
  let receipt;
4082
- const base5 = { agentId: this.id, chainId, token: asset, walletAddress: state.walletAddress, agentWallet: context.wallet.walletAddress, intendedAmount: amount === void 0 ? "MAX" : requested.toString(), transfer: "pending", registration: "not-applicable", delivery: "pending" };
4083
- onOwnerTransferAttempted?.();
4084
- const txHash = await this.submitTransaction(state, chainId, {
4085
- from: account,
4086
- to: (0, import_viem8.getAddress)(context.wallet.walletAddress),
4087
- data: amount === void 0 ? (0, import_viem8.encodeFunctionData)({
4088
- abi: YIELDSEEKER_AGENT_WALLET_ABI,
4089
- functionName: "withdrawAllAssetToUser",
4090
- args: [account, metadata.address]
4091
- }) : (0, import_viem8.encodeFunctionData)({
4092
- abi: YIELDSEEKER_AGENT_WALLET_ABI,
4093
- functionName: "withdrawAssetToUser",
4094
- args: [account, metadata.address, requested]
4095
- }),
4096
- value: "0",
4097
- chainId
4098
- }, (hash) => notifyFunding(onProgress, { ...base5, txHash: hash }), (value) => {
4099
- receipt = value;
4681
+ const base6 = { agentId: this.id, chainId, token: asset, walletAddress: state.walletAddress, agentWallet: context.wallet.walletAddress, intendedAmount: amount === void 0 ? "MAX" : payout.toString(), transfer: "pending", registration: "not-applicable", delivery: "pending" };
4682
+ const data = amount === void 0 ? (0, import_viem10.encodeFunctionData)({
4683
+ abi: YIELDSEEKER_AGENT_WALLET_ABI,
4684
+ functionName: "withdrawAllAssetToUser",
4685
+ args: [account, metadata.address]
4686
+ }) : (0, import_viem10.encodeFunctionData)({
4687
+ abi: YIELDSEEKER_AGENT_WALLET_ABI,
4688
+ functionName: "withdrawAssetToUser",
4689
+ args: [account, metadata.address, payout]
4100
4690
  });
4691
+ onOwnerTransferAttempted?.();
4692
+ let txHash;
4693
+ if (sponsor) {
4694
+ const submitted = await submitYieldseekerSponsoredWithdrawal({
4695
+ state,
4696
+ client: this.getReceiptClient(),
4697
+ apiKey: this.owneyApiKey,
4698
+ routingApiBaseUrl: this.routingApiBaseUrl,
4699
+ yieldseekerSignature: await this.auth.getToken(state, chainId),
4700
+ userId: context.user.userId,
4701
+ agentId: context.agent.agentId,
4702
+ agentWallet: (0, import_viem10.getAddress)(context.wallet.walletAddress),
4703
+ asset: metadata.address,
4704
+ callData: data,
4705
+ onPending: (pending) => notifyFunding(onProgress, { ...base6, ...pending })
4706
+ });
4707
+ txHash = submitted.txHash;
4708
+ receipt = submitted.receipt;
4709
+ } else {
4710
+ txHash = await this.submitTransaction(state, chainId, {
4711
+ from: account,
4712
+ to: (0, import_viem10.getAddress)(context.wallet.walletAddress),
4713
+ data,
4714
+ value: "0",
4715
+ chainId
4716
+ }, (hash) => notifyFunding(onProgress, { ...base6, txHash: hash }), (value) => {
4717
+ receipt = value;
4718
+ });
4719
+ }
4101
4720
  confirmedMovement = true;
4102
4721
  settlement = plannedMovement;
4103
- const evidence = receipt ? inspectFundingReceipt(receipt, { ...base5, txHash }, metadata.address, "withdraw") : { ...base5, txHash, confirmedAmount: payout.toString(), transfer: "confirmed", delivery: "confirmed" };
4722
+ const evidence = receipt ? inspectFundingReceipt(receipt, { ...base6, txHash }, metadata.address, "withdraw") : { ...base6, txHash, confirmedAmount: payout.toString(), transfer: "confirmed", delivery: "confirmed" };
4104
4723
  notifyFunding(onProgress, evidence);
4105
4724
  if (evidence.transfer === "failed" && evidence.confirmedAmount === "0")
4106
4725
  throw new OwneyError(
@@ -4186,7 +4805,7 @@ var YieldseekerAgent = class {
4186
4805
  );
4187
4806
  const vaultAddresses = new Set(
4188
4807
  catalog.flat().filter(
4189
- (yieldOption) => yieldOption.chainId === chainId && (0, import_viem8.isAddress)(yieldOption.address)
4808
+ (yieldOption) => yieldOption.chainId === chainId && (0, import_viem10.isAddress)(yieldOption.address)
4190
4809
  ).map((yieldOption) => yieldOption.address.toLowerCase())
4191
4810
  );
4192
4811
  return mapYieldseekerHistory(contexts, {
@@ -4313,7 +4932,7 @@ var YieldseekerAgent = class {
4313
4932
  `/users/${user.userId}/agents/${agent.agentId}/wallet`
4314
4933
  ).then((walletResponse) => {
4315
4934
  this.assertSession(generation, chainId, asset);
4316
- if (!walletResponse?.agentWallet || !(0, import_viem8.isAddress)(walletResponse.agentWallet.walletAddress)) {
4935
+ if (!walletResponse?.agentWallet || !(0, import_viem10.isAddress)(walletResponse.agentWallet.walletAddress)) {
4317
4936
  throw this.invalidResponse("agent wallet");
4318
4937
  }
4319
4938
  const context = {
@@ -4343,7 +4962,7 @@ var YieldseekerAgent = class {
4343
4962
  this.users.set(key2, persisted);
4344
4963
  return persisted;
4345
4964
  }
4346
- const walletAddress = (0, import_viem8.getAddress)(state.walletAddress);
4965
+ const walletAddress = (0, import_viem10.getAddress)(state.walletAddress);
4347
4966
  const generation = this.readGeneration;
4348
4967
  let user = null;
4349
4968
  try {
@@ -4726,7 +5345,7 @@ var YieldseekerAgent = class {
4726
5345
  this.agentPath(context, "deploy"),
4727
5346
  { method: "POST", body: {} }
4728
5347
  );
4729
- if (!deployed?.agentWallet || !(0, import_viem8.isAddress)(deployed.agentWallet.walletAddress) || deployed.agentWallet.walletAddress.toLowerCase() !== walletAddress) {
5348
+ if (!deployed?.agentWallet || !(0, import_viem10.isAddress)(deployed.agentWallet.walletAddress) || deployed.agentWallet.walletAddress.toLowerCase() !== walletAddress) {
4730
5349
  throw this.invalidResponse("agent deployment", {
4731
5350
  reason: "Deploy did not return the expected Agent Wallet."
4732
5351
  });
@@ -4834,15 +5453,15 @@ var YieldseekerAgent = class {
4834
5453
  return hash2;
4835
5454
  }
4836
5455
  this.assertTransaction(transaction, state, chainId);
4837
- const account = (0, import_viem8.getAddress)(state.walletAddress);
4838
- const walletClient = (0, import_viem8.createWalletClient)({
5456
+ const account = (0, import_viem10.getAddress)(state.walletAddress);
5457
+ const walletClient = (0, import_viem10.createWalletClient)({
4839
5458
  account,
4840
- chain: import_chains3.base,
4841
- transport: (0, import_viem8.custom)(state.provider)
5459
+ chain: import_chains4.base,
5460
+ transport: (0, import_viem10.custom)(state.provider)
4842
5461
  });
4843
- const walletChainClient = (0, import_viem8.createPublicClient)({
4844
- chain: import_chains3.base,
4845
- transport: (0, import_viem8.custom)(state.provider)
5462
+ const walletChainClient = (0, import_viem10.createPublicClient)({
5463
+ chain: import_chains4.base,
5464
+ transport: (0, import_viem10.custom)(state.provider)
4846
5465
  });
4847
5466
  await ensureWalletOnChain(
4848
5467
  walletChainClient,
@@ -4851,8 +5470,8 @@ var YieldseekerAgent = class {
4851
5470
  );
4852
5471
  const hash = await walletClient.sendTransaction({
4853
5472
  account,
4854
- chain: import_chains3.base,
4855
- to: (0, import_viem8.getAddress)(transaction.to),
5473
+ chain: import_chains4.base,
5474
+ to: (0, import_viem10.getAddress)(transaction.to),
4856
5475
  data: transaction.data,
4857
5476
  value: BigInt(transaction.value)
4858
5477
  });
@@ -4902,12 +5521,12 @@ var YieldseekerAgent = class {
4902
5521
  return receipt;
4903
5522
  }
4904
5523
  assertTransaction(transaction, state, chainId) {
4905
- if (!transaction || typeof transaction.from !== "string" || !(0, import_viem8.isAddress)(transaction.from) || typeof transaction.to !== "string" || !(0, import_viem8.isAddress)(transaction.to) || typeof transaction.data !== "string" || !/^0x[a-fA-F0-9]*$/.test(transaction.data) || typeof transaction.value !== "string" || !/^[0-9]+$/.test(transaction.value) || transaction.chainId !== chainId || (0, import_viem8.getAddress)(transaction.from) !== (0, import_viem8.getAddress)(state.walletAddress)) {
5524
+ if (!transaction || typeof transaction.from !== "string" || !(0, import_viem10.isAddress)(transaction.from) || typeof transaction.to !== "string" || !(0, import_viem10.isAddress)(transaction.to) || typeof transaction.data !== "string" || !/^0x[a-fA-F0-9]*$/.test(transaction.data) || typeof transaction.value !== "string" || !/^[0-9]+$/.test(transaction.value) || transaction.chainId !== chainId || (0, import_viem10.getAddress)(transaction.from) !== (0, import_viem10.getAddress)(state.walletAddress)) {
4906
5525
  throw this.invalidResponse("transaction");
4907
5526
  }
4908
5527
  }
4909
5528
  assertAgent(agent) {
4910
- if (typeof agent.agentId !== "string" || typeof agent.assetAddress !== "string" || !(0, import_viem8.isAddress)(agent.assetAddress) || agent.chainId !== 8453) {
5529
+ if (typeof agent.agentId !== "string" || typeof agent.assetAddress !== "string" || !(0, import_viem10.isAddress)(agent.assetAddress) || agent.chainId !== 8453) {
4911
5530
  throw this.invalidResponse("agent");
4912
5531
  }
4913
5532
  }
@@ -4964,6 +5583,7 @@ var YieldseekerAgent = class {
4964
5583
 
4965
5584
  // src/lib/routing-api.ts
4966
5585
  var ROUTING_API_BASE_URL2 = "https://owney-routing-api-243946518160.europe-west4.run.app";
5586
+ var getRoutingApiBaseUrl = (override) => override ?? ROUTING_API_BASE_URL2;
4967
5587
  async function fetchOrgAgentConfig(apiKey, baseUrl = ROUTING_API_BASE_URL2) {
4968
5588
  const url = `${baseUrl}/api/v1/agent/org-config`;
4969
5589
  try {
@@ -5060,7 +5680,7 @@ async function withFailureReporting(apiKey, agentType, fn, baseUrl) {
5060
5680
  }
5061
5681
 
5062
5682
  // src/lib/helpers/withdraw-helper.ts
5063
- var import_viem9 = require("viem");
5683
+ var import_viem11 = require("viem");
5064
5684
  function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
5065
5685
  const target = asset.toUpperCase();
5066
5686
  return agents.map((agent) => {
@@ -5068,7 +5688,7 @@ function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decima
5068
5688
  const tokenBalance = agentBalance?.tokens.find(
5069
5689
  (t) => t.chainId === chainId && t.asset.toUpperCase() === target
5070
5690
  );
5071
- let balance = tokenBalance ? (0, import_viem9.parseUnits)(tokenBalance.amount, decimals) : 0n;
5691
+ let balance = tokenBalance ? (0, import_viem11.parseUnits)(tokenBalance.amount, decimals) : 0n;
5072
5692
  if (agent.balanceComposition === "tokens-plus-positions") {
5073
5693
  const chainNameById = {
5074
5694
  1: "ETHEREUM",
@@ -5080,14 +5700,14 @@ function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decima
5080
5700
  const positionChain = position2.chain.trim().toUpperCase();
5081
5701
  const matchesChain = positionChain === String(chainId) || targetChain !== void 0 && positionChain === targetChain;
5082
5702
  if (!matchesChain || position2.asset.toUpperCase() !== target) continue;
5083
- balance += position2.withdrawableAmountRaw !== void 0 ? BigInt(position2.withdrawableAmountRaw) : (0, import_viem9.parseUnits)(position2.amount, decimals);
5703
+ balance += position2.withdrawableAmountRaw !== void 0 ? BigInt(position2.withdrawableAmountRaw) : (0, import_viem11.parseUnits)(position2.amount, decimals);
5084
5704
  }
5085
5705
  }
5086
5706
  const assetTotal = agentBalance?.assetBalances?.find(
5087
5707
  (t) => t.chainId === chainId && t.asset.toUpperCase() === target
5088
5708
  );
5089
5709
  if (assetTotal) {
5090
- const total = (0, import_viem9.parseUnits)(assetTotal.amount, decimals);
5710
+ const total = (0, import_viem11.parseUnits)(assetTotal.amount, decimals);
5091
5711
  if (total < balance) balance = total > 0n ? total : 0n;
5092
5712
  }
5093
5713
  return { agent, balance };
@@ -5246,14 +5866,14 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
5246
5866
  }
5247
5867
 
5248
5868
  // src/client.ts
5249
- var import_viem13 = require("viem");
5250
- var import_chains4 = require("viem/chains");
5869
+ var import_viem15 = require("viem");
5870
+ var import_chains5 = require("viem/chains");
5251
5871
 
5252
5872
  // src/lib/sponsored-token-batch.ts
5253
- var import_viem11 = require("viem");
5873
+ var import_viem13 = require("viem");
5254
5874
 
5255
5875
  // src/lib/permit2-batch.ts
5256
- var import_viem10 = require("viem");
5876
+ var import_viem12 = require("viem");
5257
5877
  var BATCH_PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
5258
5878
  var BASE_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
5259
5879
  var ERC2612_PERMIT_TYPES = {
@@ -5265,7 +5885,7 @@ var ERC2612_PERMIT_TYPES = {
5265
5885
  { name: "deadline", type: "uint256" }
5266
5886
  ]
5267
5887
  };
5268
- var ERC2612_READ_ABI = (0, import_viem10.parseAbi)([
5888
+ var ERC2612_READ_ABI = (0, import_viem12.parseAbi)([
5269
5889
  "function name() view returns (string)",
5270
5890
  "function version() view returns (string)",
5271
5891
  "function nonces(address owner) view returns (uint256)"
@@ -5303,7 +5923,7 @@ var PERMIT_BATCH_TYPES = {
5303
5923
  { name: "amount", type: "uint256" }
5304
5924
  ]
5305
5925
  };
5306
- var PERMIT2_BATCH_ABI = (0, import_viem10.parseAbi)([
5926
+ var PERMIT2_BATCH_ABI = (0, import_viem12.parseAbi)([
5307
5927
  "struct TokenPermissions { address token; uint256 amount; }",
5308
5928
  "struct PermitBatchTransferFrom { TokenPermissions[] permitted; uint256 nonce; uint256 deadline; }",
5309
5929
  "struct SignatureTransferDetails { address to; uint256 requestedAmount; }",
@@ -5362,7 +5982,7 @@ function clear(key2) {
5362
5982
  else window.localStorage.removeItem(key2);
5363
5983
  }
5364
5984
  function sponsorTokenBatch(i) {
5365
- const key2 = `owney.token-batch.v1:${(0, import_viem11.keccak256)((0, import_viem11.toBytes)(i.apiKey))}:${i.baseUrl ?? "default"}:${i.chainId}:${i.owner.toLowerCase()}:${i.token.toLowerCase()}`;
5985
+ const key2 = `owney.token-batch.v1:${(0, import_viem13.keccak256)((0, import_viem13.toBytes)(i.apiKey))}:${i.baseUrl ?? "default"}:${i.chainId}:${i.owner.toLowerCase()}:${i.token.toLowerCase()}`;
5366
5986
  const plan = planOf(i.transfers);
5367
5987
  const active = inflight.get(key2);
5368
5988
  if (active) {
@@ -5393,7 +6013,7 @@ async function execute(i, key2, plan) {
5393
6013
  baseUrl: i.baseUrl,
5394
6014
  body
5395
6015
  });
5396
- if (!preparedPermit.serializedPermitTransaction || !preparedPermit.permitTxHash || (0, import_viem11.keccak256)(preparedPermit.serializedPermitTransaction) !== preparedPermit.permitTxHash)
6016
+ if (!preparedPermit.serializedPermitTransaction || !preparedPermit.permitTxHash || (0, import_viem13.keccak256)(preparedPermit.serializedPermitTransaction) !== preparedPermit.permitTxHash)
5397
6017
  throw new Error(
5398
6018
  "Sponsorship API did not return a valid prepared permit transaction."
5399
6019
  );
@@ -5409,7 +6029,7 @@ async function execute(i, key2, plan) {
5409
6029
  baseUrl: i.baseUrl,
5410
6030
  body
5411
6031
  });
5412
- if (!prepared.serializedTransaction || (0, import_viem11.keccak256)(prepared.serializedTransaction) !== prepared.txHash)
6032
+ if (!prepared.serializedTransaction || (0, import_viem13.keccak256)(prepared.serializedTransaction) !== prepared.txHash)
5413
6033
  throw new Error(
5414
6034
  "Sponsorship API did not return a valid prepared transaction."
5415
6035
  );
@@ -5420,7 +6040,7 @@ async function execute(i, key2, plan) {
5420
6040
  save(key2, body);
5421
6041
  }
5422
6042
  try {
5423
- i.onSubmitted?.((0, import_viem11.keccak256)(body.serializedTransaction));
6043
+ i.onSubmitted?.((0, import_viem13.keccak256)(body.serializedTransaction));
5424
6044
  } catch {
5425
6045
  }
5426
6046
  const result = await postSponsorBatchTransfer({
@@ -5428,7 +6048,7 @@ async function execute(i, key2, plan) {
5428
6048
  baseUrl: i.baseUrl,
5429
6049
  body
5430
6050
  });
5431
- if (result.txHash !== (0, import_viem11.keccak256)(body.serializedTransaction))
6051
+ if (result.txHash !== (0, import_viem13.keccak256)(body.serializedTransaction))
5432
6052
  throw new Error(
5433
6053
  "Sponsorship receipt does not match the pending transaction."
5434
6054
  );
@@ -5443,7 +6063,7 @@ async function execute(i, key2, plan) {
5443
6063
  const saved = read(key2);
5444
6064
  if (saved) {
5445
6065
  const previous = JSON.parse(saved);
5446
- if (previous.chainId !== i.chainId || !(0, import_viem11.isAddressEqual)(previous.from, i.owner) || !(0, import_viem11.isAddressEqual)(previous.token, i.token) || planOf(previous.transfers) !== plan)
6066
+ if (previous.chainId !== i.chainId || !(0, import_viem13.isAddressEqual)(previous.from, i.owner) || !(0, import_viem13.isAddressEqual)(previous.token, i.token) || planOf(previous.transfers) !== plan)
5447
6067
  throw new Error(
5448
6068
  "Retry the previous token deposit and agent split first to reconcile its status."
5449
6069
  );
@@ -5460,7 +6080,7 @@ async function execute(i, key2, plan) {
5460
6080
  "DEPOSIT_INSUFFICIENT_BALANCE",
5461
6081
  "Insufficient token balance for this deposit."
5462
6082
  );
5463
- if (allowance < total && (i.chainId !== 8453 || !(0, import_viem11.isAddressEqual)(i.token, BASE_USDC_ADDRESS)))
6083
+ if (allowance < total && (i.chainId !== 8453 || !(0, import_viem13.isAddressEqual)(i.token, BASE_USDC_ADDRESS)))
5464
6084
  throw new OwneyError(
5465
6085
  "PERMIT2_APPROVAL_REQUIRED",
5466
6086
  "token deposits need a one-time Permit2 approval."
@@ -5638,7 +6258,7 @@ async function runAgentDepositBatch(chainId, legs, transfer) {
5638
6258
  }
5639
6259
 
5640
6260
  // src/lib/sponsored-calls-deposit.ts
5641
- var import_viem12 = require("viem");
6261
+ var import_viem14 = require("viem");
5642
6262
  var DEFAULT_POLL_INTERVAL_MS = 1500;
5643
6263
  var DEFAULT_MAX_POLLS = 30;
5644
6264
  async function paymasterSupported(provider, owner, chainId) {
@@ -5646,7 +6266,7 @@ async function paymasterSupported(provider, owner, chainId) {
5646
6266
  method: "wallet_getCapabilities",
5647
6267
  params: [owner]
5648
6268
  });
5649
- const forChain = caps?.[(0, import_viem12.toHex)(chainId)] ?? caps?.[String(chainId)];
6269
+ const forChain = caps?.[(0, import_viem14.toHex)(chainId)] ?? caps?.[String(chainId)];
5650
6270
  return Boolean(forChain?.paymasterService?.supported);
5651
6271
  }
5652
6272
  function makeSponsoredCallsCallback(deps) {
@@ -5683,8 +6303,8 @@ function makeSponsoredCallsCallback(deps) {
5683
6303
  const calls = transfers.map((transfer) => ({
5684
6304
  to: token,
5685
6305
  value: "0x0",
5686
- data: (0, import_viem12.encodeFunctionData)({
5687
- abi: import_viem12.erc20Abi,
6306
+ data: (0, import_viem14.encodeFunctionData)({
6307
+ abi: import_viem14.erc20Abi,
5688
6308
  functionName: "transfer",
5689
6309
  args: [transfer.to, BigInt(transfer.amount)]
5690
6310
  })
@@ -5722,7 +6342,7 @@ function makeSponsoredCallsCallback(deps) {
5722
6342
  {
5723
6343
  version: "2.0.0",
5724
6344
  from: deps.ownerAddress,
5725
- chainId: (0, import_viem12.toHex)(chainId),
6345
+ chainId: (0, import_viem14.toHex)(chainId),
5726
6346
  atomicRequired: transfers.length > 1,
5727
6347
  calls,
5728
6348
  capabilities: {
@@ -5816,9 +6436,9 @@ var SPONSORED_USDC_BY_CHAIN = {
5816
6436
  1: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
5817
6437
  };
5818
6438
  var VIEM_CHAIN2 = {
5819
- 8453: import_chains4.base,
5820
- 42161: import_chains4.arbitrum,
5821
- 1: import_chains4.mainnet
6439
+ 8453: import_chains5.base,
6440
+ 42161: import_chains5.arbitrum,
6441
+ 1: import_chains5.mainnet
5822
6442
  };
5823
6443
  var SPONSORED_WETH_BY_CHAIN = {
5824
6444
  8453: "0x4200000000000000000000000000000000000006",
@@ -5991,14 +6611,14 @@ var OwneySDK = class {
5991
6611
  // PublicClient/WalletClient param types — structurally identical at
5992
6612
  // runtime, but the two share a name TS treats as unrelated.
5993
6613
  getPublicClient: (cid) => this.getPaidRpcClient(cid),
5994
- getWalletChainClient: (cid) => (0, import_viem13.createPublicClient)({
6614
+ getWalletChainClient: (cid) => (0, import_viem15.createPublicClient)({
5995
6615
  chain: VIEM_CHAIN2[cid],
5996
- transport: (0, import_viem13.custom)(provider)
6616
+ transport: (0, import_viem15.custom)(provider)
5997
6617
  }),
5998
- getWalletClient: (cid) => (0, import_viem13.createWalletClient)({
6618
+ getWalletClient: (cid) => (0, import_viem15.createWalletClient)({
5999
6619
  account: owner,
6000
6620
  chain: VIEM_CHAIN2[cid],
6001
- transport: (0, import_viem13.custom)(provider)
6621
+ transport: (0, import_viem15.custom)(provider)
6002
6622
  })
6003
6623
  });
6004
6624
  if (!onApproved && !onSubmitted) this.cachedSponsoredCallback = callback;
@@ -6044,14 +6664,14 @@ var OwneySDK = class {
6044
6664
  // PublicClient/WalletClient param types — structurally identical at
6045
6665
  // runtime, but the two share a name TS treats as unrelated.
6046
6666
  getPublicClient: (cid) => this.getPaidRpcClient(cid),
6047
- getWalletChainClient: (cid) => (0, import_viem13.createPublicClient)({
6667
+ getWalletChainClient: (cid) => (0, import_viem15.createPublicClient)({
6048
6668
  chain: VIEM_CHAIN2[cid],
6049
- transport: (0, import_viem13.custom)(provider)
6669
+ transport: (0, import_viem15.custom)(provider)
6050
6670
  }),
6051
- getWalletClient: (cid) => (0, import_viem13.createWalletClient)({
6671
+ getWalletClient: (cid) => (0, import_viem15.createWalletClient)({
6052
6672
  account: owner,
6053
6673
  chain: VIEM_CHAIN2[cid],
6054
- transport: (0, import_viem13.custom)(provider)
6674
+ transport: (0, import_viem15.custom)(provider)
6055
6675
  })
6056
6676
  });
6057
6677
  if (!onApproved && !onSubmitted) this.cachedWethSponsoredCallback = callback;
@@ -6172,6 +6792,7 @@ var OwneySDK = class {
6172
6792
  }
6173
6793
  if (agentId === "yieldseeker") {
6174
6794
  return new YieldseekerAgent(this.apiKey, {
6795
+ routingApiBaseUrl: this.routingApiBaseUrl,
6175
6796
  auth: { origin: this.yieldseekerSiweOrigin },
6176
6797
  baseUrl: this.yieldseekerApiBaseUrl ?? getYieldseekerProxyBaseUrl(this.routingApiBaseUrl),
6177
6798
  rpcUrls: this.rpcUrls
@@ -6763,12 +7384,12 @@ var OwneySDK = class {
6763
7384
  throw new OwneyError("AGENT_API_ERROR", "Funding wallet does not match this account.");
6764
7385
  const token = SupportedAssets.find((t) => t.chainId === chainId && t.symbol === evidence.token);
6765
7386
  if (!token) throw new OwneyError("CHAIN_UNSUPPORTED", "Unsupported funding asset.");
6766
- const rpc = this.getPaidRpcClient(chainId);
6767
- const receipt = await rpc.getTransactionReceipt({ hash: evidence.txHash });
7387
+ const rpc2 = this.getPaidRpcClient(chainId);
7388
+ const receipt = await rpc2.getTransactionReceipt({ hash: evidence.txHash });
6768
7389
  assertCurrent();
6769
7390
  let verified = inspectFundingReceipt(receipt, { ...evidence, agentWallet }, token.address, direction);
6770
7391
  if (direction === "withdraw" && evidence.agentId === "yieldseeker" && verified.transfer === "unknown" && verified.confirmedAmount && BigInt(verified.confirmedAmount) > 0n) {
6771
- const transaction = await rpc.getTransaction({ hash: evidence.txHash });
7392
+ const transaction = await rpc2.getTransaction({ hash: evidence.txHash });
6772
7393
  assertCurrent();
6773
7394
  if (isFullYieldseekerWithdrawal(transaction, { ...evidence, agentWallet }, token.address))
6774
7395
  verified = inspectFundingReceipt(receipt, { ...evidence, agentWallet, intendedAmount: "MAX" }, token.address, direction);
@@ -6782,6 +7403,45 @@ var OwneySDK = class {
6782
7403
  }
6783
7404
  return verified;
6784
7405
  }
7406
+ /** Resolve a saved sponsored-withdrawal ID without opening a wallet prompt. */
7407
+ async resolveSponsoredWithdrawalEvidence(evidence) {
7408
+ const { state, chainId, assertCurrent } = this.captureReadScope(evidence.chainId);
7409
+ if (evidence.agentId !== "yieldseeker" || chainId !== 8453 || evidence.txHash || state.walletAddress.toLowerCase() !== evidence.walletAddress.toLowerCase()) return evidence;
7410
+ const agent = this.getAgent("yieldseeker");
7411
+ const wallet = await agent.getFundingWallet?.(state, chainId, evidence.token);
7412
+ if (!wallet || wallet.toLowerCase() !== evidence.agentWallet?.toLowerCase()) return evidence;
7413
+ let txHash;
7414
+ let executionFailed = false;
7415
+ if (evidence.userOpHash && /^0x[0-9a-fA-F]{64}$/.test(evidence.userOpHash)) {
7416
+ const response = await fetch(`${getRoutingApiBaseUrl(this.routingApiBaseUrl).replace(/\/$/, "")}/api/v1/sponsor/yieldseeker-withdraw/resolve`, {
7417
+ method: "POST",
7418
+ headers: { "content-type": "application/json", "x-owney-api-key": this.apiKey },
7419
+ body: JSON.stringify({
7420
+ owner: state.walletAddress,
7421
+ agentWallet: wallet,
7422
+ asset: SupportedAssets.find((t) => t.chainId === chainId && t.symbol === evidence.token)?.address,
7423
+ userOpHash: evidence.userOpHash
7424
+ })
7425
+ });
7426
+ if (!response.ok) throw new OwneyError("AGENT_API_ERROR", "Could not resolve sponsored withdrawal status.");
7427
+ const payload = await response.json();
7428
+ txHash = payload.data?.txHash ?? void 0;
7429
+ executionFailed = payload.data?.executionFailed === true;
7430
+ } else if (evidence.callsId) {
7431
+ const status = await state.provider.request({ method: "wallet_getCallsStatus", params: [evidence.callsId] });
7432
+ if (status?.id && status.id !== evidence.callsId || status?.chainId && Number(status.chainId) !== chainId) return evidence;
7433
+ executionFailed = status?.status === 400 || status?.status === 500;
7434
+ txHash = status?.receipts?.[0]?.transactionHash;
7435
+ }
7436
+ assertCurrent();
7437
+ if (executionFailed) return {
7438
+ ...evidence,
7439
+ ...txHash && /^0x[0-9a-fA-F]{64}$/.test(txHash) ? { txHash } : {},
7440
+ transfer: "failed",
7441
+ delivery: "failed"
7442
+ };
7443
+ return txHash && /^0x[0-9a-fA-F]{64}$/.test(txHash) ? { ...evidence, txHash } : evidence;
7444
+ }
6785
7445
  /** A display acknowledgement controls polling only; it never confirms a financial outcome. */
6786
7446
  endFundingBalanceRefresh(evidence, read2) {
6787
7447
  const { state, chainId } = this.captureReadScope(evidence.chainId);
@@ -6806,6 +7466,39 @@ var OwneySDK = class {
6806
7466
  return this.getAgent("zyfai").retryDepositRegistration(this.requireState(), verified);
6807
7467
  }
6808
7468
  // --- Fund operations ---
7469
+ /** On-chain version and ownership status for this owner's Yieldseeker agent. */
7470
+ async getYieldseekerWalletStatus(asset) {
7471
+ const state = this.requireState();
7472
+ const chainId = this.requireChainId();
7473
+ const agent = this.getAgent("yieldseeker");
7474
+ return agent.getWalletStatus(state, chainId, asset);
7475
+ }
7476
+ /** Deployment gate; an unavailable response keeps the current paid path. */
7477
+ async isYieldseekerWithdrawalSponsorshipAvailable() {
7478
+ return this.isYieldseekerSponsorshipAvailable("withdraw");
7479
+ }
7480
+ async isYieldseekerUpgradeSponsorshipAvailable() {
7481
+ return this.isYieldseekerSponsorshipAvailable("upgrade");
7482
+ }
7483
+ async isYieldseekerSponsorshipAvailable(action) {
7484
+ const baseUrl = getRoutingApiBaseUrl(this.routingApiBaseUrl).replace(/\/$/, "");
7485
+ try {
7486
+ const owner = this.requireState().walletAddress;
7487
+ const response = await fetch(`${baseUrl}/api/v1/sponsor/yieldseeker-withdraw/availability?owner=${encodeURIComponent(owner)}&action=${action}`);
7488
+ if (!response.ok) return false;
7489
+ const payload = await response.json();
7490
+ return payload.data?.enabled === true;
7491
+ } catch {
7492
+ return false;
7493
+ }
7494
+ }
7495
+ /** Explicit V1-to-V2 upgrade, confirmed on chain before returning. */
7496
+ async upgradeYieldseekerWallet(asset, gasMode = "paid") {
7497
+ const state = this.requireState();
7498
+ const chainId = this.requireChainId();
7499
+ const agent = this.getAgent("yieldseeker");
7500
+ return agent.upgradeWallet(state, chainId, asset, gasMode);
7501
+ }
6809
7502
  /**
6810
7503
  * Withdraw funds from a specific agent, or all agents that support the active chain+asset if agentId is omitted.
6811
7504
  * Validates that the asset is supported by the target agent(s) on the active chain.
@@ -6869,7 +7562,7 @@ var OwneySDK = class {
6869
7562
  };
6870
7563
  progress(evidence);
6871
7564
  try {
6872
- return await agent.withdraw(state, chainId, token, requested2, progress);
7565
+ return await (options.gasMode === void 0 ? agent.withdraw(state, chainId, token, requested2, progress) : agent.withdraw(state, chainId, token, requested2, progress, options.gasMode));
6873
7566
  } catch (error) {
6874
7567
  if (!evidence.txHash && (this.isUserRejectedWithdrawal(error) || /insufficient (balance|funds)/i.test(error instanceof Error ? error.message : "")))
6875
7568
  progress({ ...evidence, transfer: "failed", delivery: "failed" });
@@ -6907,6 +7600,7 @@ var OwneySDK = class {
6907
7600
  results2[agent.id] = await submit(agent);
6908
7601
  notifyAgentResult(agent.id, results2[agent.id]);
6909
7602
  } catch (err) {
7603
+ if (err instanceof OwneyError && err.code === "SPONSOR_REQUEST_FAILED" && err.details?.safeToFallback === true) throw err;
6910
7604
  if (this.isUserRejectedWithdrawal(err)) throw err;
6911
7605
  if (err instanceof OwneyError && err.code === "WITHDRAW_INSUFFICIENT_BALANCE" && err.details?.available === "0" && submissionEvidence.get(agent.id)?.transfer === "failed") continue;
6912
7606
  console.error(`withdraw failed for agent "${agent.id}":`, err);
@@ -7008,6 +7702,7 @@ var OwneySDK = class {
7008
7702
  results[p.agent.id] = await submit(p.agent, p.planned.toString());
7009
7703
  notifyAgentResult(p.agent.id, results[p.agent.id]);
7010
7704
  } catch (err) {
7705
+ if (err instanceof OwneyError && err.code === "SPONSOR_REQUEST_FAILED" && err.details?.safeToFallback === true) throw err;
7011
7706
  if (this.isUserRejectedWithdrawal(err)) throw err;
7012
7707
  console.error(`withdraw failed for agent "${p.agent.id}":`, err);
7013
7708
  agentErrors[p.agent.id] = err instanceof Error ? err.message : String(err);
@@ -7505,16 +8200,16 @@ var OwneySDK = class {
7505
8200
  );
7506
8201
  }
7507
8202
  const provider = this.requireConnectedProvider();
7508
- const walletChainClient = (0, import_viem13.createPublicClient)({
8203
+ const walletChainClient = (0, import_viem15.createPublicClient)({
7509
8204
  chain: VIEM_CHAIN2[chainId],
7510
- transport: (0, import_viem13.custom)(provider)
8205
+ transport: (0, import_viem15.custom)(provider)
7511
8206
  });
7512
8207
  const publicClient = this.getPaidRpcClient(chainId);
7513
8208
  const approvalAmount = permit2ApprovalAmount(requiredAmount);
7514
- const wallet = (0, import_viem13.createWalletClient)({
8209
+ const wallet = (0, import_viem15.createWalletClient)({
7515
8210
  account: state.walletAddress,
7516
8211
  chain: VIEM_CHAIN2[chainId],
7517
- transport: (0, import_viem13.custom)(provider)
8212
+ transport: (0, import_viem15.custom)(provider)
7518
8213
  });
7519
8214
  await ensureWalletOnChain(walletChainClient, wallet, chainId);
7520
8215
  const hash = await wallet.writeContract({
@@ -7676,7 +8371,7 @@ var OwneySDK = class {
7676
8371
  };
7677
8372
 
7678
8373
  // src/agents/zyfai/zyfai.siwx.ts
7679
- var import_viem14 = require("viem");
8374
+ var import_viem16 = require("viem");
7680
8375
  var import_siwe2 = require("siwe");
7681
8376
  var import_sdk2 = require("@zyfai/sdk");
7682
8377
 
@@ -7803,7 +8498,7 @@ function buildSIWXConfig(deps) {
7803
8498
  issuedAt,
7804
8499
  toString() {
7805
8500
  return new import_siwe2.SiweMessage({
7806
- address: (0, import_viem14.getAddress)(accountAddress),
8501
+ address: (0, import_viem16.getAddress)(accountAddress),
7807
8502
  chainId: numericChainId(chainId),
7808
8503
  domain,
7809
8504
  uri,