@owney/sdk 0.7.25-beta.16 → 0.7.25-beta.17
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 -139
- package/dist/index.d.cts +16 -0
- package/dist/index.d.ts +16 -0
- package/dist/index.js +304 -74
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1574,6 +1574,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1574
1574
|
earningsRefreshes = /* @__PURE__ */ new Map();
|
|
1575
1575
|
earningsSnapshot = null;
|
|
1576
1576
|
earningsGeneration = 0;
|
|
1577
|
+
balanceSnapshots = /* @__PURE__ */ new WeakMap();
|
|
1577
1578
|
constructor(apiKey, rpcUrls, referralSource) {
|
|
1578
1579
|
this.rpcUrls = resolveRpcUrls(rpcUrls);
|
|
1579
1580
|
this.sdk = new import_sdk.ZyfaiSDK({
|
|
@@ -1777,7 +1778,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1777
1778
|
* chain/account switch fires the provider's `accountsChanged` →
|
|
1778
1779
|
* `disconnectAccount` (nulls walletClient + authenticatedUserId) while our
|
|
1779
1780
|
* own `connectAuth` guard still believes this chain is connected and
|
|
1780
|
-
* early-returns. Without this, authenticated calls (
|
|
1781
|
+
* early-returns. Without this, authenticated calls (sendDeposit,
|
|
1781
1782
|
* withdrawFunds) fail with "No account connected".
|
|
1782
1783
|
*/
|
|
1783
1784
|
async ensureConnected(state, chainId) {
|
|
@@ -2399,7 +2400,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2399
2400
|
return { txHash, smartWallet, amount, evidence: evidence2 };
|
|
2400
2401
|
}
|
|
2401
2402
|
await this.ensureWalletDeployed(this.getAddress(), validChainId);
|
|
2402
|
-
const raw2 = await this.sdk.
|
|
2403
|
+
const raw2 = await this.sdk.sendDeposit(
|
|
2403
2404
|
this.getAddress(),
|
|
2404
2405
|
validChainId,
|
|
2405
2406
|
amount,
|
|
@@ -2415,7 +2416,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2415
2416
|
intendedAmount: amount,
|
|
2416
2417
|
txHash: raw2.txHash,
|
|
2417
2418
|
transfer: "unknown",
|
|
2418
|
-
registration: "unknown",
|
|
2419
|
+
registration: raw2.registration ? "confirmed" : "unknown",
|
|
2419
2420
|
delivery: "not-applicable"
|
|
2420
2421
|
};
|
|
2421
2422
|
notifyFunding(onProgress, evidence);
|
|
@@ -2723,10 +2724,37 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2723
2724
|
}
|
|
2724
2725
|
async getBalances(state, chainId) {
|
|
2725
2726
|
const requestedAt = Date.now();
|
|
2727
|
+
const generation = this.earningsGeneration;
|
|
2726
2728
|
const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
|
|
2727
2729
|
const raw2 = await this.sdk.getPortfolio(this.getAddress());
|
|
2728
2730
|
const balance = mapBalances(raw2, validChainId, smartWallet);
|
|
2729
|
-
|
|
2731
|
+
const reads = balance.readMetadata?.map((read2) => ({ ...read2, requestedAt })) ?? [];
|
|
2732
|
+
for (const asset of SupportedAssets.filter((item) => item.chainId === chainId)) {
|
|
2733
|
+
if (!reads.some((read2) => read2.chainId === chainId && read2.asset === asset.symbol) && hasEmptyWithdrawalSnapshot(raw2, chainId, asset.symbol)) {
|
|
2734
|
+
reads.push({ chainId, asset: asset.symbol, requestedAt, fetchedAt: Date.now(), positionsStatus: "available" });
|
|
2735
|
+
}
|
|
2736
|
+
}
|
|
2737
|
+
const result = { ...balance, readMetadata: reads };
|
|
2738
|
+
for (const read2 of reads) this.balanceSnapshots.set(read2, { raw: raw2, generation, owner: state.walletAddress.toLowerCase() });
|
|
2739
|
+
return result;
|
|
2740
|
+
}
|
|
2741
|
+
async verifyWithdrawalBalance(state, evidence, balance) {
|
|
2742
|
+
const read2 = balance.readMetadata?.find((item) => item.chainId === evidence.chainId && item.asset === evidence.token);
|
|
2743
|
+
const snapshot = read2 && this.balanceSnapshots.get(read2);
|
|
2744
|
+
const asset = SupportedAssets.find((item) => item.chainId === evidence.chainId && item.symbol === evidence.token);
|
|
2745
|
+
if (!snapshot || snapshot.generation !== this.earningsGeneration || snapshot.owner !== state.walletAddress.toLowerCase() || !read2 || !asset || !evidence.txHash || !evidence.blockNumber || !balance.smartWallet || balance.smartWallet.toLowerCase() !== evidence.agentWallet?.toLowerCase() || !hasEmptyWithdrawalSnapshot(snapshot.raw, evidence.chainId, evidence.token)) return void 0;
|
|
2746
|
+
const client = this.getPublicClient(evidence.chainId);
|
|
2747
|
+
const blockNumber = await client.getBlockNumber({ cacheTime: 0 });
|
|
2748
|
+
if (blockNumber < BigInt(evidence.blockNumber)) return void 0;
|
|
2749
|
+
const idle = await client.readContract({
|
|
2750
|
+
address: asset.address,
|
|
2751
|
+
abi: import_viem4.erc20Abi,
|
|
2752
|
+
functionName: "balanceOf",
|
|
2753
|
+
args: [balance.smartWallet],
|
|
2754
|
+
blockNumber
|
|
2755
|
+
});
|
|
2756
|
+
if (idle !== 0n || snapshot.generation !== this.earningsGeneration || this.connectedAddress?.toLowerCase() !== snapshot.owner || this.connectedChainId !== evidence.chainId) return void 0;
|
|
2757
|
+
return { ...read2, withdrawalCheck: { txHash: evidence.txHash, blockNumber: blockNumber.toString() } };
|
|
2730
2758
|
}
|
|
2731
2759
|
earningsKey(state, chainId, smartWallet) {
|
|
2732
2760
|
return JSON.stringify([
|
|
@@ -2925,7 +2953,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2925
2953
|
};
|
|
2926
2954
|
|
|
2927
2955
|
// src/agents/yieldseeker/yieldseeker.agent.ts
|
|
2928
|
-
var
|
|
2956
|
+
var import_viem12 = require("viem");
|
|
2929
2957
|
var import_chains4 = require("viem/chains");
|
|
2930
2958
|
|
|
2931
2959
|
// src/lib/chain-guard.ts
|
|
@@ -3709,6 +3737,7 @@ function mapYieldseekerBalances(contexts) {
|
|
|
3709
3737
|
chainId: context.agent.chainId,
|
|
3710
3738
|
asset: context.asset,
|
|
3711
3739
|
fetchedAt: context.fetchedAt,
|
|
3740
|
+
requestedAt: context.requestedAt,
|
|
3712
3741
|
readVersion: context.readVersion,
|
|
3713
3742
|
providerUpdatedAt: context.snapshot.updatedDate,
|
|
3714
3743
|
snapshotId: String(context.snapshot.agentWalletSnapshotId),
|
|
@@ -4086,13 +4115,59 @@ function mapYieldseekerAgentApy(options, days) {
|
|
|
4086
4115
|
};
|
|
4087
4116
|
}
|
|
4088
4117
|
|
|
4089
|
-
// src/
|
|
4118
|
+
// src/lib/remaining-vault-balance.ts
|
|
4090
4119
|
var import_viem9 = require("viem");
|
|
4120
|
+
async function remainingVaultBalance(client, wallet, asset, vaults, blockNumber) {
|
|
4121
|
+
const addresses = [...new Set(vaults.map((value) => value.toLowerCase()))];
|
|
4122
|
+
if (addresses.length > 64) return void 0;
|
|
4123
|
+
const batches = [];
|
|
4124
|
+
for (let index = 0; index < addresses.length; index += 10) batches.push(addresses.slice(index, index + 10));
|
|
4125
|
+
const values = await Promise.all(batches.map(async (batch) => {
|
|
4126
|
+
const balances = await client.multicall({
|
|
4127
|
+
blockNumber,
|
|
4128
|
+
allowFailure: true,
|
|
4129
|
+
contracts: batch.map((address) => ({
|
|
4130
|
+
address: (0, import_viem9.getAddress)(address),
|
|
4131
|
+
abi: import_viem9.erc20Abi,
|
|
4132
|
+
functionName: "balanceOf",
|
|
4133
|
+
args: [wallet]
|
|
4134
|
+
}))
|
|
4135
|
+
});
|
|
4136
|
+
if (balances.length !== batch.length) return void 0;
|
|
4137
|
+
const funded = [];
|
|
4138
|
+
for (let index = 0; index < batch.length; index++) {
|
|
4139
|
+
const result = balances[index];
|
|
4140
|
+
if (result?.status !== "success" || typeof result.result !== "bigint" || result.result < 0n) return void 0;
|
|
4141
|
+
if (result.result > 0n) funded.push({ address: (0, import_viem9.getAddress)(batch[index]), shares: result.result });
|
|
4142
|
+
}
|
|
4143
|
+
if (!funded.length) return 0n;
|
|
4144
|
+
const valuations = await client.multicall({
|
|
4145
|
+
blockNumber,
|
|
4146
|
+
allowFailure: true,
|
|
4147
|
+
contracts: funded.flatMap(({ address, shares }) => [
|
|
4148
|
+
{ address, abi: import_viem9.erc4626Abi, functionName: "asset" },
|
|
4149
|
+
{ address, abi: import_viem9.erc4626Abi, functionName: "convertToAssets", args: [shares] }
|
|
4150
|
+
])
|
|
4151
|
+
});
|
|
4152
|
+
if (valuations.length !== funded.length * 2) return void 0;
|
|
4153
|
+
let total = 0n;
|
|
4154
|
+
for (let index = 0; index < funded.length; index++) {
|
|
4155
|
+
const underlying = valuations[index * 2], value = valuations[index * 2 + 1];
|
|
4156
|
+
if (underlying?.status !== "success" || typeof underlying.result !== "string" || underlying.result.toLowerCase() !== asset.toLowerCase() || value?.status !== "success" || typeof value.result !== "bigint" || value.result < 0n) return void 0;
|
|
4157
|
+
total += value.result;
|
|
4158
|
+
}
|
|
4159
|
+
return total;
|
|
4160
|
+
}));
|
|
4161
|
+
return values.some((value) => value === void 0) ? void 0 : values.reduce((sum, value) => sum + value, 0n);
|
|
4162
|
+
}
|
|
4163
|
+
|
|
4164
|
+
// src/agents/yieldseeker/yieldseeker.wallet-version.ts
|
|
4165
|
+
var import_viem10 = require("viem");
|
|
4091
4166
|
var YIELDSEEKER_FACTORY = "0x9c7410a0faCAC60850C46eE5b58B518daec95130";
|
|
4092
4167
|
var YIELDSEEKER_V1_IMPLEMENTATION = "0x32403455357589523435dB18b414057D7cE05051";
|
|
4093
4168
|
var YIELDSEEKER_V2_IMPLEMENTATION = "0x613Db9c924ADB7A7A90c11b02Cce20c913E3Fe50";
|
|
4094
4169
|
var ERC1967_IMPLEMENTATION_SLOT = "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc";
|
|
4095
|
-
var walletAbi = (0,
|
|
4170
|
+
var walletAbi = (0, import_viem10.parseAbi)([
|
|
4096
4171
|
"function owner() view returns (address)",
|
|
4097
4172
|
"function ownerAgentIndex() view returns (uint256)",
|
|
4098
4173
|
"function baseAsset() view returns (address)",
|
|
@@ -4100,7 +4175,7 @@ var walletAbi = (0, import_viem9.parseAbi)([
|
|
|
4100
4175
|
"function upgradeToLatest()",
|
|
4101
4176
|
"event Upgraded(address indexed implementation)"
|
|
4102
4177
|
]);
|
|
4103
|
-
var factoryAbi = (0,
|
|
4178
|
+
var factoryAbi = (0, import_viem10.parseAbi)([
|
|
4104
4179
|
"function userWallets(address owner, uint256 index) view returns (address)",
|
|
4105
4180
|
"function agentWalletImplementation() view returns (address)"
|
|
4106
4181
|
]);
|
|
@@ -4108,9 +4183,9 @@ function yieldseekerOwnerPath(code) {
|
|
|
4108
4183
|
return !code || code === "0x" || /^0xef0100[0-9a-f]{40}$/i.test(code) ? "eoa" : "smart";
|
|
4109
4184
|
}
|
|
4110
4185
|
async function readYieldseekerWalletStatus(client, wallet, owner, asset, blockNumber) {
|
|
4111
|
-
const agentWallet = (0,
|
|
4112
|
-
const expectedOwner = (0,
|
|
4113
|
-
const expectedAsset = (0,
|
|
4186
|
+
const agentWallet = (0, import_viem10.getAddress)(wallet);
|
|
4187
|
+
const expectedOwner = (0, import_viem10.getAddress)(owner);
|
|
4188
|
+
const expectedAsset = (0, import_viem10.getAddress)(asset);
|
|
4114
4189
|
const [code, ownerCode, slot, actualOwner, index, actualAsset, actualFactory, latest] = await Promise.all([
|
|
4115
4190
|
client.getBytecode({ address: agentWallet, blockNumber }),
|
|
4116
4191
|
client.getBytecode({ address: expectedOwner, blockNumber }),
|
|
@@ -4124,7 +4199,7 @@ async function readYieldseekerWalletStatus(client, wallet, owner, asset, blockNu
|
|
|
4124
4199
|
if (!code || code === "0x" || !slot || /^0x0+$/.test(slot)) {
|
|
4125
4200
|
throw new Error("Yieldseeker wallet is not a deployed ERC1967 proxy");
|
|
4126
4201
|
}
|
|
4127
|
-
const implementation = (0,
|
|
4202
|
+
const implementation = (0, import_viem10.getAddress)(`0x${slot.slice(-40)}`);
|
|
4128
4203
|
const mapped = await client.readContract({
|
|
4129
4204
|
address: YIELDSEEKER_FACTORY,
|
|
4130
4205
|
abi: factoryAbi,
|
|
@@ -4132,8 +4207,8 @@ async function readYieldseekerWalletStatus(client, wallet, owner, asset, blockNu
|
|
|
4132
4207
|
args: [expectedOwner, index],
|
|
4133
4208
|
blockNumber
|
|
4134
4209
|
});
|
|
4135
|
-
const verified = (0,
|
|
4136
|
-
const version = !verified ? "unknown" : (0,
|
|
4210
|
+
const verified = (0, import_viem10.isAddressEqual)(actualOwner, expectedOwner) && (0, import_viem10.isAddressEqual)(actualAsset, expectedAsset) && (0, import_viem10.isAddressEqual)(actualFactory, YIELDSEEKER_FACTORY) && (0, import_viem10.isAddressEqual)(mapped, agentWallet);
|
|
4211
|
+
const version = !verified ? "unknown" : (0, import_viem10.isAddressEqual)(implementation, YIELDSEEKER_V2_IMPLEMENTATION) ? "v2" : (0, import_viem10.isAddressEqual)(implementation, YIELDSEEKER_V1_IMPLEMENTATION) ? "v1" : "unknown";
|
|
4137
4212
|
return {
|
|
4138
4213
|
agentWallet,
|
|
4139
4214
|
owner: actualOwner,
|
|
@@ -4142,13 +4217,13 @@ async function readYieldseekerWalletStatus(client, wallet, owner, asset, blockNu
|
|
|
4142
4217
|
implementation,
|
|
4143
4218
|
version,
|
|
4144
4219
|
verified,
|
|
4145
|
-
upgradeAvailable: version === "v1" && (0,
|
|
4220
|
+
upgradeAvailable: version === "v1" && (0, import_viem10.isAddressEqual)(latest, YIELDSEEKER_V2_IMPLEMENTATION)
|
|
4146
4221
|
};
|
|
4147
4222
|
}
|
|
4148
4223
|
var YIELDSEEKER_UPGRADE_ABI = walletAbi;
|
|
4149
4224
|
|
|
4150
4225
|
// src/agents/yieldseeker/yieldseeker.sponsored-withdraw.ts
|
|
4151
|
-
var
|
|
4226
|
+
var import_viem11 = require("viem");
|
|
4152
4227
|
var import_account_abstraction2 = require("viem/account-abstraction");
|
|
4153
4228
|
var import_accounts = require("viem/accounts");
|
|
4154
4229
|
var import_chains3 = require("viem/chains");
|
|
@@ -4227,7 +4302,7 @@ function rpcDiagnostics(data) {
|
|
|
4227
4302
|
details.revertName = data.revertName;
|
|
4228
4303
|
if (typeof data?.aaCode === "string" && /^AA[0-9]{2}$/.test(data.aaCode)) details.aaCode = data.aaCode;
|
|
4229
4304
|
if (typeof data?.panicCode === "string" && /^0x[0-9a-fA-F]{1,2}$/.test(data.panicCode)) {
|
|
4230
|
-
const panicCode = (0,
|
|
4305
|
+
const panicCode = (0, import_viem11.toHex)(BigInt(data.panicCode));
|
|
4231
4306
|
if (["0x0", "0x1", "0x11", "0x12", "0x21", "0x22", "0x31", "0x32", "0x41", "0x51"].includes(panicCode))
|
|
4232
4307
|
details.panicCode = panicCode;
|
|
4233
4308
|
}
|
|
@@ -4447,14 +4522,14 @@ async function submitEoa(input) {
|
|
|
4447
4522
|
throw sponsorError("Base did not return EIP-1559 gas fees.", true);
|
|
4448
4523
|
let operation = {
|
|
4449
4524
|
sender: input.agentWallet,
|
|
4450
|
-
nonce: (0,
|
|
4525
|
+
nonce: (0, import_viem11.toHex)(nonce),
|
|
4451
4526
|
initCode: "0x",
|
|
4452
4527
|
callData: input.callData,
|
|
4453
|
-
callGasLimit: (0,
|
|
4454
|
-
verificationGasLimit: (0,
|
|
4455
|
-
preVerificationGas: (0,
|
|
4456
|
-
maxFeePerGas: (0,
|
|
4457
|
-
maxPriorityFeePerGas: (0,
|
|
4528
|
+
callGasLimit: (0, import_viem11.toHex)(3e5),
|
|
4529
|
+
verificationGasLimit: (0, import_viem11.toHex)(3e5),
|
|
4530
|
+
preVerificationGas: (0, import_viem11.toHex)(6e4),
|
|
4531
|
+
maxFeePerGas: (0, import_viem11.toHex)(fees.maxFeePerGas * USER_OP_FEE_HEADROOM),
|
|
4532
|
+
maxPriorityFeePerGas: (0, import_viem11.toHex)(fees.maxPriorityFeePerGas),
|
|
4458
4533
|
paymasterAndData: "0x",
|
|
4459
4534
|
signature: "0x"
|
|
4460
4535
|
};
|
|
@@ -4462,7 +4537,7 @@ async function submitEoa(input) {
|
|
|
4462
4537
|
const stub = await rpc(
|
|
4463
4538
|
input.rpcUrl,
|
|
4464
4539
|
"pm_getPaymasterStubData",
|
|
4465
|
-
[operation, ENTRY_POINT_V06, (0,
|
|
4540
|
+
[operation, ENTRY_POINT_V06, (0, import_viem11.toHex)(8453), {}],
|
|
4466
4541
|
"prepare"
|
|
4467
4542
|
);
|
|
4468
4543
|
if (!stub.paymasterAndData?.startsWith("0x"))
|
|
@@ -4477,7 +4552,7 @@ async function submitEoa(input) {
|
|
|
4477
4552
|
const final = await rpc(
|
|
4478
4553
|
input.rpcUrl,
|
|
4479
4554
|
"pm_getPaymasterData",
|
|
4480
|
-
[operation, ENTRY_POINT_V06, (0,
|
|
4555
|
+
[operation, ENTRY_POINT_V06, (0, import_viem11.toHex)(8453), {}],
|
|
4481
4556
|
"prepare"
|
|
4482
4557
|
);
|
|
4483
4558
|
if (!final.paymasterAndData?.startsWith("0x"))
|
|
@@ -4486,10 +4561,10 @@ async function submitEoa(input) {
|
|
|
4486
4561
|
}
|
|
4487
4562
|
const userOpHash = operationHash(operation);
|
|
4488
4563
|
await assertOwnerSession(input.state, input.owner);
|
|
4489
|
-
const wallet = (0,
|
|
4564
|
+
const wallet = (0, import_viem11.createWalletClient)({
|
|
4490
4565
|
account: input.owner,
|
|
4491
4566
|
chain: import_chains3.base,
|
|
4492
|
-
transport: (0,
|
|
4567
|
+
transport: (0, import_viem11.custom)(input.state.provider)
|
|
4493
4568
|
});
|
|
4494
4569
|
const signature = await wallet.signMessage({ message: { raw: userOpHash } });
|
|
4495
4570
|
operation = { ...operation, signature };
|
|
@@ -4566,12 +4641,12 @@ async function submitSmart(input) {
|
|
|
4566
4641
|
} catch {
|
|
4567
4642
|
throw sponsorError("This account cannot check paymaster support on Base.", true);
|
|
4568
4643
|
}
|
|
4569
|
-
const supportsPaymaster = capabilities?.[(0,
|
|
4644
|
+
const supportsPaymaster = capabilities?.[(0, import_viem11.toHex)(8453)]?.paymasterService?.supported ?? capabilities?.["8453"]?.paymasterService?.supported ?? capabilities?.["0x0"]?.paymasterService?.supported;
|
|
4570
4645
|
if (supportsPaymaster !== true)
|
|
4571
4646
|
throw sponsorError("This account cannot use a paymaster on Base.", true);
|
|
4572
4647
|
await assertOwnerSession(input.state, input.owner);
|
|
4573
4648
|
let sent;
|
|
4574
|
-
const requestedId = (0,
|
|
4649
|
+
const requestedId = (0, import_viem11.toHex)(globalThis.crypto.getRandomValues(new Uint8Array(32)));
|
|
4575
4650
|
savePending(input.onPending, { callsId: requestedId }, true);
|
|
4576
4651
|
await checkpoint(input.onBeforeSubmission, { callsId: requestedId });
|
|
4577
4652
|
try {
|
|
@@ -4580,7 +4655,7 @@ async function submitSmart(input) {
|
|
|
4580
4655
|
params: [{
|
|
4581
4656
|
version: "2.0.0",
|
|
4582
4657
|
from: input.owner,
|
|
4583
|
-
chainId: (0,
|
|
4658
|
+
chainId: (0, import_viem11.toHex)(8453),
|
|
4584
4659
|
id: requestedId,
|
|
4585
4660
|
atomicRequired: false,
|
|
4586
4661
|
calls: [{ to: input.agentWallet, value: "0x0", data: input.callData }],
|
|
@@ -4655,7 +4730,7 @@ async function submitSmart(input) {
|
|
|
4655
4730
|
);
|
|
4656
4731
|
}
|
|
4657
4732
|
async function submitYieldseekerSponsoredWithdrawal(input) {
|
|
4658
|
-
const owner = (0,
|
|
4733
|
+
const owner = (0, import_viem11.getAddress)(input.state.walletAddress);
|
|
4659
4734
|
const { intent, rpcUrl } = await requestIntent({
|
|
4660
4735
|
apiKey: input.apiKey,
|
|
4661
4736
|
routingApiBaseUrl: input.routingApiBaseUrl,
|
|
@@ -4673,7 +4748,7 @@ async function submitYieldseekerSponsoredWithdrawal(input) {
|
|
|
4673
4748
|
return intent.ownerPath === "eoa" ? submitEoa(args) : submitSmart(args);
|
|
4674
4749
|
}
|
|
4675
4750
|
async function submitYieldseekerSponsoredUpgrade(input) {
|
|
4676
|
-
const owner = (0,
|
|
4751
|
+
const owner = (0, import_viem11.getAddress)(input.state.walletAddress);
|
|
4677
4752
|
const { intent, rpcUrl } = await requestIntent({
|
|
4678
4753
|
apiKey: input.apiKey,
|
|
4679
4754
|
routingApiBaseUrl: input.routingApiBaseUrl,
|
|
@@ -4790,6 +4865,8 @@ var YieldseekerAgent = class {
|
|
|
4790
4865
|
transactionExecutor;
|
|
4791
4866
|
unwindReceiptWaiter;
|
|
4792
4867
|
agentContexts = /* @__PURE__ */ new Map();
|
|
4868
|
+
balanceContexts = /* @__PURE__ */ new WeakMap();
|
|
4869
|
+
balanceVaults = /* @__PURE__ */ new Map();
|
|
4793
4870
|
users = /* @__PURE__ */ new Map();
|
|
4794
4871
|
pendingAgents = /* @__PURE__ */ new Map();
|
|
4795
4872
|
pendingWalletContexts = /* @__PURE__ */ new Map();
|
|
@@ -4835,8 +4912,8 @@ var YieldseekerAgent = class {
|
|
|
4835
4912
|
if (useCachedV2 && cached && Date.now() - cached.at < 15 * 6e4) return { ...cached.status };
|
|
4836
4913
|
const status = await readYieldseekerWalletStatus(
|
|
4837
4914
|
this.getReceiptClient(),
|
|
4838
|
-
(0,
|
|
4839
|
-
(0,
|
|
4915
|
+
(0, import_viem12.getAddress)(context.wallet.walletAddress),
|
|
4916
|
+
(0, import_viem12.getAddress)(state.walletAddress),
|
|
4840
4917
|
YIELDSEEKER_ASSET_METADATA[asset].address
|
|
4841
4918
|
);
|
|
4842
4919
|
this.rememberWalletStatus(key2, status);
|
|
@@ -4866,12 +4943,12 @@ var YieldseekerAgent = class {
|
|
|
4866
4943
|
const pendingKey2 = `owney.yieldseeker.upgrade:${before.owner.toLowerCase()}:${before.agentWallet.toLowerCase()}`;
|
|
4867
4944
|
const confirmUpgrade = async (hash, receipt2) => {
|
|
4868
4945
|
this.withdrawalVersionCache.delete(versionKey);
|
|
4869
|
-
const upgradeTopic = (0,
|
|
4946
|
+
const upgradeTopic = (0, import_viem12.encodeEventTopics)({ abi: YIELDSEEKER_UPGRADE_ABI, eventName: "Upgraded" })[0];
|
|
4870
4947
|
const lastUpgrade = receipt2?.logs.filter((log) => log.address.toLowerCase() === before.agentWallet.toLowerCase() && log.topics[0] === upgradeTopic).at(-1);
|
|
4871
4948
|
const expectedUpgrade = (() => {
|
|
4872
4949
|
if (!lastUpgrade || lastUpgrade.removed) return false;
|
|
4873
4950
|
try {
|
|
4874
|
-
const event = (0,
|
|
4951
|
+
const event = (0, import_viem12.decodeEventLog)({ abi: YIELDSEEKER_UPGRADE_ABI, eventName: "Upgraded", data: lastUpgrade.data, topics: lastUpgrade.topics });
|
|
4875
4952
|
return event.args.implementation.toLowerCase() === YIELDSEEKER_V2_IMPLEMENTATION.toLowerCase();
|
|
4876
4953
|
} catch {
|
|
4877
4954
|
return false;
|
|
@@ -4989,7 +5066,7 @@ var YieldseekerAgent = class {
|
|
|
4989
5066
|
{ version: before.version },
|
|
4990
5067
|
this.id
|
|
4991
5068
|
);
|
|
4992
|
-
const data = (0,
|
|
5069
|
+
const data = (0, import_viem12.encodeFunctionData)({ abi: YIELDSEEKER_UPGRADE_ABI, functionName: "upgradeToLatest" });
|
|
4993
5070
|
let txHash;
|
|
4994
5071
|
let receipt;
|
|
4995
5072
|
if (gasMode === "sponsored") {
|
|
@@ -5032,7 +5109,7 @@ var YieldseekerAgent = class {
|
|
|
5032
5109
|
}
|
|
5033
5110
|
} else {
|
|
5034
5111
|
txHash = await this.submitTransaction(state, chainId, {
|
|
5035
|
-
from: (0,
|
|
5112
|
+
from: (0, import_viem12.getAddress)(state.walletAddress),
|
|
5036
5113
|
to: before.agentWallet,
|
|
5037
5114
|
data,
|
|
5038
5115
|
value: "0",
|
|
@@ -5055,6 +5132,7 @@ var YieldseekerAgent = class {
|
|
|
5055
5132
|
}
|
|
5056
5133
|
this.users.clear();
|
|
5057
5134
|
this.agentContexts.clear();
|
|
5135
|
+
this.balanceVaults.clear();
|
|
5058
5136
|
this.pendingAgents.clear();
|
|
5059
5137
|
this.pendingWalletContexts.clear();
|
|
5060
5138
|
this.readCache.clear();
|
|
@@ -5118,12 +5196,12 @@ var YieldseekerAgent = class {
|
|
|
5118
5196
|
} else {
|
|
5119
5197
|
try {
|
|
5120
5198
|
txHash = await this.submitTransaction(state, chainId, {
|
|
5121
|
-
from: (0,
|
|
5199
|
+
from: (0, import_viem12.getAddress)(state.walletAddress),
|
|
5122
5200
|
to: YIELDSEEKER_ASSET_METADATA[asset].address,
|
|
5123
|
-
data: (0,
|
|
5124
|
-
abi:
|
|
5201
|
+
data: (0, import_viem12.encodeFunctionData)({
|
|
5202
|
+
abi: import_viem12.erc20Abi,
|
|
5125
5203
|
functionName: "transfer",
|
|
5126
|
-
args: [(0,
|
|
5204
|
+
args: [(0, import_viem12.getAddress)(context.wallet.walletAddress), BigInt(amount)]
|
|
5127
5205
|
}),
|
|
5128
5206
|
value: "0",
|
|
5129
5207
|
chainId
|
|
@@ -5257,7 +5335,7 @@ var YieldseekerAgent = class {
|
|
|
5257
5335
|
);
|
|
5258
5336
|
const positionsRead = this.readWithdrawalPositions(state, chainId, context);
|
|
5259
5337
|
const metadata = YIELDSEEKER_ASSET_METADATA[asset];
|
|
5260
|
-
const agentWallet = (0,
|
|
5338
|
+
const agentWallet = (0, import_viem12.getAddress)(context.wallet.walletAddress);
|
|
5261
5339
|
const readOwnerFunds = async (blockNumber) => {
|
|
5262
5340
|
const feeTracker = await withPaidRpcDiagnostics(() => this.getReceiptClient().readContract({
|
|
5263
5341
|
address: agentWallet,
|
|
@@ -5266,18 +5344,18 @@ var YieldseekerAgent = class {
|
|
|
5266
5344
|
blockNumber
|
|
5267
5345
|
}), chainId, "eth_call", this.id);
|
|
5268
5346
|
this.assertSession(generation, chainId, asset);
|
|
5269
|
-
if (!(0,
|
|
5347
|
+
if (!(0, import_viem12.isAddress)(feeTracker) || /^0x0{40}$/i.test(feeTracker))
|
|
5270
5348
|
throw this.invalidResponse("wallet fee tracker");
|
|
5271
5349
|
const [idle2, fees] = await Promise.all([
|
|
5272
5350
|
withPaidRpcDiagnostics(() => this.getReceiptClient().readContract({
|
|
5273
5351
|
address: metadata.address,
|
|
5274
|
-
abi:
|
|
5352
|
+
abi: import_viem12.erc20Abi,
|
|
5275
5353
|
functionName: "balanceOf",
|
|
5276
5354
|
args: [agentWallet],
|
|
5277
5355
|
blockNumber
|
|
5278
5356
|
}), chainId, "eth_call", this.id),
|
|
5279
5357
|
withPaidRpcDiagnostics(() => this.getReceiptClient().readContract({
|
|
5280
|
-
address: (0,
|
|
5358
|
+
address: (0, import_viem12.getAddress)(feeTracker),
|
|
5281
5359
|
abi: YIELDSEEKER_FEE_TRACKER_ABI,
|
|
5282
5360
|
functionName: "getFeesOwed",
|
|
5283
5361
|
args: [agentWallet],
|
|
@@ -5319,13 +5397,13 @@ var YieldseekerAgent = class {
|
|
|
5319
5397
|
let active = true;
|
|
5320
5398
|
const checks = this.readVaultLiquidity(values.map((position2) => position2.yieldOption), agentWallet, blockNumber).catch(() => []);
|
|
5321
5399
|
const reads = values.map(async (position2, index) => {
|
|
5322
|
-
const address = (0,
|
|
5400
|
+
const address = (0, import_viem12.getAddress)(position2.yieldOption.address);
|
|
5323
5401
|
try {
|
|
5324
5402
|
const group = (await checks).slice(index * 3, index * 3 + 3);
|
|
5325
5403
|
if (!active || group.length !== 3 || group.some((value) => value.status !== "success")) return null;
|
|
5326
5404
|
this.assertSession(generation, chainId, asset);
|
|
5327
5405
|
const [underlying, shares, withdrawable] = group.map((value) => value.result);
|
|
5328
|
-
if (typeof underlying !== "string" || !(0,
|
|
5406
|
+
if (typeof underlying !== "string" || !(0, import_viem12.isAddress)(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n || typeof withdrawable !== "bigint" || withdrawable < 0n) return null;
|
|
5329
5407
|
const verified = { ...position2, assetsRaw: shares.toString(), withdrawableAssetsRaw: withdrawable.toString() };
|
|
5330
5408
|
if (shares > 0n && withdrawable === 0n) {
|
|
5331
5409
|
let positiveValue = false;
|
|
@@ -5333,7 +5411,7 @@ var YieldseekerAgent = class {
|
|
|
5333
5411
|
try {
|
|
5334
5412
|
const value = await this.getReceiptClient().readContract({
|
|
5335
5413
|
address,
|
|
5336
|
-
abi:
|
|
5414
|
+
abi: import_viem12.erc4626Abi,
|
|
5337
5415
|
functionName,
|
|
5338
5416
|
args: [shares],
|
|
5339
5417
|
blockNumber
|
|
@@ -5546,14 +5624,14 @@ var YieldseekerAgent = class {
|
|
|
5546
5624
|
delta: maxSettlementBasis.delta - payout,
|
|
5547
5625
|
expectedNetDeposits: maxSettlementBasis.expectedNetDeposits - payout
|
|
5548
5626
|
} : this.snapshotMovement(state, chainId, context, -payout);
|
|
5549
|
-
const account = (0,
|
|
5627
|
+
const account = (0, import_viem12.getAddress)(state.walletAddress);
|
|
5550
5628
|
let receipt;
|
|
5551
5629
|
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" };
|
|
5552
|
-
const data = amount === void 0 ? (0,
|
|
5630
|
+
const data = amount === void 0 ? (0, import_viem12.encodeFunctionData)({
|
|
5553
5631
|
abi: YIELDSEEKER_AGENT_WALLET_ABI,
|
|
5554
5632
|
functionName: "withdrawAllAssetToUser",
|
|
5555
5633
|
args: [account, metadata.address]
|
|
5556
|
-
}) : (0,
|
|
5634
|
+
}) : (0, import_viem12.encodeFunctionData)({
|
|
5557
5635
|
abi: YIELDSEEKER_AGENT_WALLET_ABI,
|
|
5558
5636
|
functionName: "withdrawAssetToUser",
|
|
5559
5637
|
args: [account, metadata.address, payout]
|
|
@@ -5569,7 +5647,7 @@ var YieldseekerAgent = class {
|
|
|
5569
5647
|
refreshYieldseekerSignature: (rejected) => this.auth.refreshToken(state, chainId, rejected),
|
|
5570
5648
|
userId: context.user.userId,
|
|
5571
5649
|
agentId: context.agent.agentId,
|
|
5572
|
-
agentWallet: (0,
|
|
5650
|
+
agentWallet: (0, import_viem12.getAddress)(context.wallet.walletAddress),
|
|
5573
5651
|
asset: metadata.address,
|
|
5574
5652
|
callData: data,
|
|
5575
5653
|
onPending: (pending) => notifyFunding(onProgress, { ...base6, ...pending }),
|
|
@@ -5584,7 +5662,7 @@ var YieldseekerAgent = class {
|
|
|
5584
5662
|
onOwnerTransferAttempted?.();
|
|
5585
5663
|
txHash = await this.submitTransaction(state, chainId, {
|
|
5586
5664
|
from: account,
|
|
5587
|
-
to: (0,
|
|
5665
|
+
to: (0, import_viem12.getAddress)(context.wallet.walletAddress),
|
|
5588
5666
|
data,
|
|
5589
5667
|
value: "0",
|
|
5590
5668
|
chainId
|
|
@@ -5692,17 +5770,17 @@ var YieldseekerAgent = class {
|
|
|
5692
5770
|
return proof.available;
|
|
5693
5771
|
}
|
|
5694
5772
|
async readVaultLiquidity(options, wallet, blockNumber) {
|
|
5695
|
-
const owner = (0,
|
|
5773
|
+
const owner = (0, import_viem12.getAddress)(wallet);
|
|
5696
5774
|
const batches = Array.from({ length: Math.ceil(options.length / YIELDSEEKER_VAULTS_PER_RPC_BATCH) }, (_, index) => options.slice(index * YIELDSEEKER_VAULTS_PER_RPC_BATCH, (index + 1) * YIELDSEEKER_VAULTS_PER_RPC_BATCH));
|
|
5697
5775
|
const results = await Promise.all(batches.map((batch) => this.getReceiptClient().multicall({
|
|
5698
5776
|
blockNumber,
|
|
5699
5777
|
allowFailure: true,
|
|
5700
5778
|
contracts: batch.flatMap((option) => {
|
|
5701
|
-
const address = (0,
|
|
5779
|
+
const address = (0, import_viem12.getAddress)(option.address);
|
|
5702
5780
|
return [
|
|
5703
|
-
{ address, abi:
|
|
5704
|
-
{ address, abi:
|
|
5705
|
-
{ address, abi:
|
|
5781
|
+
{ address, abi: import_viem12.erc4626Abi, functionName: "asset" },
|
|
5782
|
+
{ address, abi: import_viem12.erc20Abi, functionName: "balanceOf", args: [owner] },
|
|
5783
|
+
{ address, abi: import_viem12.erc4626Abi, functionName: "maxWithdraw", args: [owner] }
|
|
5706
5784
|
];
|
|
5707
5785
|
})
|
|
5708
5786
|
})));
|
|
@@ -5713,7 +5791,7 @@ var YieldseekerAgent = class {
|
|
|
5713
5791
|
const seen = /* @__PURE__ */ new Set();
|
|
5714
5792
|
for (const value of values) {
|
|
5715
5793
|
const option = value?.yieldOption;
|
|
5716
|
-
if (!option || typeof option.address !== "string" || !(0,
|
|
5794
|
+
if (!option || typeof option.address !== "string" || !(0, import_viem12.isAddress)(option.address) || seen.has(option.address.toLowerCase()) || option.chainId !== void 0 && option.chainId !== chainId || option.assetAddress !== void 0 && (typeof option.assetAddress !== "string" || option.assetAddress.toLowerCase() !== underlying) || typeof value.assetsRaw !== "string" || !/^\d+$/.test(value.assetsRaw) || typeof value.withdrawableAssetsRaw !== "string" || !/^\d+$/.test(value.withdrawableAssetsRaw))
|
|
5717
5795
|
throw this.invalidResponse("yield positions");
|
|
5718
5796
|
seen.add(option.address.toLowerCase());
|
|
5719
5797
|
}
|
|
@@ -5726,7 +5804,7 @@ var YieldseekerAgent = class {
|
|
|
5726
5804
|
const historic = this.readCache.get(`historic:${key2}`)?.value?.position;
|
|
5727
5805
|
const receivedAssets = new Set((historic?.movements ?? []).filter((movement) => movement.chainId === chainId && movement.agentWalletId === context.wallet.agentWalletId && movement.toAddress?.toLowerCase() === context.wallet.walletAddress.toLowerCase()).filter((movement) => typeof movement.assetAddress === "string").map((movement) => movement.assetAddress.toLowerCase()));
|
|
5728
5806
|
for (const option of this.yieldOptions.get(context.asset)?.value ?? []) {
|
|
5729
|
-
if (option.chainId !== chainId || typeof option.assetAddress !== "string" || option.assetAddress.toLowerCase() !== YIELDSEEKER_ASSET_METADATA[context.asset].address.toLowerCase() || !(0,
|
|
5807
|
+
if (option.chainId !== chainId || typeof option.assetAddress !== "string" || option.assetAddress.toLowerCase() !== YIELDSEEKER_ASSET_METADATA[context.asset].address.toLowerCase() || !(0, import_viem12.isAddress)(option.address) || !receivedAssets.has(option.address.toLowerCase()) || hints.has(option.address.toLowerCase())) continue;
|
|
5730
5808
|
hints.set(option.address.toLowerCase(), {
|
|
5731
5809
|
yieldOption: option,
|
|
5732
5810
|
assetsRaw: "0",
|
|
@@ -5778,7 +5856,7 @@ var YieldseekerAgent = class {
|
|
|
5778
5856
|
const read2 = async () => {
|
|
5779
5857
|
const client = this.getReceiptClient();
|
|
5780
5858
|
const blockNumber = await client.getBlockNumber({ cacheTime: 0 });
|
|
5781
|
-
const wallet = (0,
|
|
5859
|
+
const wallet = (0, import_viem12.getAddress)(context.wallet.walletAddress);
|
|
5782
5860
|
assertReadCurrent();
|
|
5783
5861
|
if (typeof blockNumber !== "bigint") throw unavailable();
|
|
5784
5862
|
const indexedPositions = this.validateWithdrawalPositions(positions ?? [], chainId, context.asset);
|
|
@@ -5792,7 +5870,7 @@ var YieldseekerAgent = class {
|
|
|
5792
5870
|
this.readVaultLiquidity(options, wallet, blockNumber),
|
|
5793
5871
|
client.readContract({
|
|
5794
5872
|
address: metadata.address,
|
|
5795
|
-
abi:
|
|
5873
|
+
abi: import_viem12.erc20Abi,
|
|
5796
5874
|
functionName: "balanceOf",
|
|
5797
5875
|
args: [wallet],
|
|
5798
5876
|
blockNumber
|
|
@@ -5804,10 +5882,10 @@ var YieldseekerAgent = class {
|
|
|
5804
5882
|
blockNumber
|
|
5805
5883
|
})
|
|
5806
5884
|
]);
|
|
5807
|
-
if (typeof idle !== "bigint" || idle < 0n || !(0,
|
|
5885
|
+
if (typeof idle !== "bigint" || idle < 0n || !(0, import_viem12.isAddress)(feeTracker) || /^0x0{40}$/i.test(feeTracker)) throw unavailable();
|
|
5808
5886
|
assertReadCurrent();
|
|
5809
5887
|
const fees = await client.readContract({
|
|
5810
|
-
address: (0,
|
|
5888
|
+
address: (0, import_viem12.getAddress)(feeTracker),
|
|
5811
5889
|
abi: YIELDSEEKER_FEE_TRACKER_ABI,
|
|
5812
5890
|
functionName: "getFeesOwed",
|
|
5813
5891
|
args: [wallet],
|
|
@@ -5818,15 +5896,21 @@ var YieldseekerAgent = class {
|
|
|
5818
5896
|
const verifiedVaults = [];
|
|
5819
5897
|
let deployed = 0n;
|
|
5820
5898
|
const collect = (options2, results) => {
|
|
5899
|
+
assertReadCurrent();
|
|
5900
|
+
const known = this.balanceVaults.get(contextKey) ?? /* @__PURE__ */ new Set();
|
|
5901
|
+
this.balanceVaults.set(contextKey, known);
|
|
5821
5902
|
let valid2 = true;
|
|
5822
5903
|
options2.forEach((option, index) => {
|
|
5823
5904
|
const group = results.slice(index * 3, index * 3 + 3);
|
|
5905
|
+
const shareProbe = group[1];
|
|
5906
|
+
if (shareProbe?.status === "success" && typeof shareProbe.result === "bigint" && shareProbe.result > 0n)
|
|
5907
|
+
known.add(option.address.toLowerCase());
|
|
5824
5908
|
if (group.length !== 3 || group.some((value) => value.status !== "success")) {
|
|
5825
5909
|
valid2 = false;
|
|
5826
5910
|
return;
|
|
5827
5911
|
}
|
|
5828
5912
|
const [underlying, shares, withdrawable] = group.map((value) => value.result);
|
|
5829
|
-
if (typeof underlying !== "string" || !(0,
|
|
5913
|
+
if (typeof underlying !== "string" || !(0, import_viem12.isAddress)(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n || typeof withdrawable !== "bigint" || withdrawable < 0n || shares === 0n && withdrawable > 0n) {
|
|
5830
5914
|
valid2 = false;
|
|
5831
5915
|
return;
|
|
5832
5916
|
}
|
|
@@ -5870,7 +5954,7 @@ var YieldseekerAgent = class {
|
|
|
5870
5954
|
assertReadCurrent();
|
|
5871
5955
|
const eligible = /* @__PURE__ */ new Map();
|
|
5872
5956
|
for (const option of catalog ?? []) {
|
|
5873
|
-
if (option?.chainId === chainId && typeof option.assetAddress === "string" && option.assetAddress.toLowerCase() === metadata.address.toLowerCase() && (0,
|
|
5957
|
+
if (option?.chainId === chainId && typeof option.assetAddress === "string" && option.assetAddress.toLowerCase() === metadata.address.toLowerCase() && (0, import_viem12.isAddress)(option.address))
|
|
5874
5958
|
eligible.set(option.address.toLowerCase(), option);
|
|
5875
5959
|
}
|
|
5876
5960
|
const extra = [...eligible].filter(([address]) => !candidates.has(address)).map(([, option]) => option);
|
|
@@ -5899,7 +5983,59 @@ var YieldseekerAgent = class {
|
|
|
5899
5983
|
async getBalances(state, chainId, asset) {
|
|
5900
5984
|
this.assertChain(chainId);
|
|
5901
5985
|
if (asset !== void 0) this.assertAsset(asset);
|
|
5902
|
-
|
|
5986
|
+
const contexts = await this.loadPortfolio(state, chainId, { asset, allowMissingPositions: true });
|
|
5987
|
+
const balance = mapYieldseekerBalances(contexts);
|
|
5988
|
+
for (const context of contexts) {
|
|
5989
|
+
const read2 = balance.readMetadata.find((item) => item.asset === context.asset);
|
|
5990
|
+
this.balanceContexts.set(read2, { context, generation: this.readGeneration });
|
|
5991
|
+
const key2 = this.contextKey(state, chainId, context.asset);
|
|
5992
|
+
const known = this.balanceVaults.get(key2) ?? /* @__PURE__ */ new Set();
|
|
5993
|
+
for (const position2 of context.positions) known.add(position2.yieldOption.address.toLowerCase());
|
|
5994
|
+
this.balanceVaults.set(key2, known);
|
|
5995
|
+
}
|
|
5996
|
+
return balance;
|
|
5997
|
+
}
|
|
5998
|
+
async verifyWithdrawalBalance(state, evidence, balance) {
|
|
5999
|
+
this.assertAsset(evidence.token);
|
|
6000
|
+
this.assertChain(evidence.chainId);
|
|
6001
|
+
const read2 = balance.readMetadata?.find((item) => item.chainId === evidence.chainId && item.asset === evidence.token);
|
|
6002
|
+
const cached = read2 && this.balanceContexts.get(read2);
|
|
6003
|
+
const context = cached?.generation === this.readGeneration ? cached.context : void 0;
|
|
6004
|
+
if (!context || context.positionsUnavailable || !read2 || !evidence.blockNumber || !evidence.txHash || context.wallet.walletAddress.toLowerCase() !== evidence.agentWallet?.toLowerCase()) return void 0;
|
|
6005
|
+
const key2 = this.contextKey(state, evidence.chainId, evidence.token);
|
|
6006
|
+
const generation = this.readGeneration, version = this.portfolioVersion(key2);
|
|
6007
|
+
if (read2.readVersion !== version) return void 0;
|
|
6008
|
+
const wallet = (0, import_viem12.getAddress)(context.wallet.walletAddress);
|
|
6009
|
+
const asset = YIELDSEEKER_ASSET_METADATA[evidence.token];
|
|
6010
|
+
const client = this.getReceiptClient();
|
|
6011
|
+
const blockNumber = await client.getBlockNumber({ cacheTime: 0 });
|
|
6012
|
+
if (blockNumber < BigInt(evidence.blockNumber)) return void 0;
|
|
6013
|
+
const vaults = [...this.balanceVaults.get(key2) ?? []];
|
|
6014
|
+
const [invested, idle, tracker] = await Promise.all([
|
|
6015
|
+
remainingVaultBalance(client, wallet, asset.address, vaults, blockNumber),
|
|
6016
|
+
client.readContract({ address: asset.address, abi: import_viem12.erc20Abi, functionName: "balanceOf", args: [wallet], blockNumber }),
|
|
6017
|
+
client.readContract({ address: wallet, abi: YIELDSEEKER_AGENT_WALLET_ABI, functionName: "feeTracker", blockNumber })
|
|
6018
|
+
]);
|
|
6019
|
+
if (invested === void 0 || typeof idle !== "bigint" || idle < 0n || !(0, import_viem12.isAddress)(tracker) || /^0x0{40}$/i.test(tracker)) return void 0;
|
|
6020
|
+
const fees = await client.readContract({
|
|
6021
|
+
address: tracker,
|
|
6022
|
+
abi: YIELDSEEKER_FEE_TRACKER_ABI,
|
|
6023
|
+
functionName: "getFeesOwed",
|
|
6024
|
+
args: [wallet],
|
|
6025
|
+
blockNumber
|
|
6026
|
+
});
|
|
6027
|
+
this.assertSession(generation, evidence.chainId, evidence.token);
|
|
6028
|
+
if (version !== this.portfolioVersion(key2) || typeof fees !== "bigint" || fees < 0n) return void 0;
|
|
6029
|
+
const total = idle + invested > fees ? idle + invested - fees : 0n;
|
|
6030
|
+
const displayed = balance.assetBalances?.find((item) => item.chainId === evidence.chainId && item.asset === evidence.token);
|
|
6031
|
+
if (!displayed || !evidence.confirmedAmount || !/^\d+$/.test(evidence.confirmedAmount)) return void 0;
|
|
6032
|
+
const amount = (0, import_viem12.parseUnits)(displayed.amount, asset.decimals);
|
|
6033
|
+
if (amount < 0n) return void 0;
|
|
6034
|
+
const displayUnit = evidence.token === "USDC" ? 5000n : 500000000000n;
|
|
6035
|
+
const movementUnit = BigInt(evidence.confirmedAmount) / 1000n;
|
|
6036
|
+
const tolerance = movementUnit < displayUnit ? movementUnit : displayUnit;
|
|
6037
|
+
if ((total > amount ? total - amount : amount - total) > tolerance) return void 0;
|
|
6038
|
+
return { ...read2, withdrawalCheck: { txHash: evidence.txHash, blockNumber: blockNumber.toString() } };
|
|
5903
6039
|
}
|
|
5904
6040
|
invalidateFundingRead(state, chainId, asset, refreshUntil = Date.now() + YIELDSEEKER_SETTLEMENT_WINDOW_MS) {
|
|
5905
6041
|
this.assertAsset(asset);
|
|
@@ -5939,9 +6075,9 @@ var YieldseekerAgent = class {
|
|
|
5939
6075
|
if (!context) return void 0;
|
|
5940
6076
|
const idle = await withPaidRpcDiagnostics(() => this.getReceiptClient().readContract({
|
|
5941
6077
|
address: YIELDSEEKER_ASSET_METADATA[asset].address,
|
|
5942
|
-
abi:
|
|
6078
|
+
abi: import_viem12.erc20Abi,
|
|
5943
6079
|
functionName: "balanceOf",
|
|
5944
|
-
args: [(0,
|
|
6080
|
+
args: [(0, import_viem12.getAddress)(context.wallet.walletAddress)]
|
|
5945
6081
|
}), chainId, "eth_call", this.id);
|
|
5946
6082
|
this.assertSession(generation, chainId, asset);
|
|
5947
6083
|
if (typeof idle !== "bigint" || idle < 0n) throw this.invalidResponse("wallet deposit balance");
|
|
@@ -5977,7 +6113,7 @@ var YieldseekerAgent = class {
|
|
|
5977
6113
|
);
|
|
5978
6114
|
const vaultAddresses = new Set(
|
|
5979
6115
|
catalog.flat().filter(
|
|
5980
|
-
(yieldOption) => yieldOption.chainId === chainId && (0,
|
|
6116
|
+
(yieldOption) => yieldOption.chainId === chainId && (0, import_viem12.isAddress)(yieldOption.address)
|
|
5981
6117
|
).map((yieldOption) => yieldOption.address.toLowerCase())
|
|
5982
6118
|
);
|
|
5983
6119
|
return mapYieldseekerHistory(contexts, {
|
|
@@ -6053,11 +6189,13 @@ var YieldseekerAgent = class {
|
|
|
6053
6189
|
const pending = this.pendingReads.get(key2);
|
|
6054
6190
|
if (pending) return pending;
|
|
6055
6191
|
const generation = this.readGeneration;
|
|
6192
|
+
const requestedAt = Date.now();
|
|
6056
6193
|
const request = Promise.resolve().then(read2).then((value) => {
|
|
6057
6194
|
if (this.readGeneration === generation && this.pendingReads.get(key2) === request) {
|
|
6058
6195
|
this.readCache.set(key2, {
|
|
6059
6196
|
expiresAt: Date.now() + ttlMs,
|
|
6060
6197
|
fetchedAt: Date.now(),
|
|
6198
|
+
requestedAt,
|
|
6061
6199
|
value
|
|
6062
6200
|
});
|
|
6063
6201
|
}
|
|
@@ -6104,7 +6242,7 @@ var YieldseekerAgent = class {
|
|
|
6104
6242
|
`/users/${user.userId}/agents/${agent.agentId}/wallet`
|
|
6105
6243
|
).then((walletResponse) => {
|
|
6106
6244
|
this.assertSession(generation, chainId, asset);
|
|
6107
|
-
if (!walletResponse?.agentWallet || !(0,
|
|
6245
|
+
if (!walletResponse?.agentWallet || !(0, import_viem12.isAddress)(walletResponse.agentWallet.walletAddress)) {
|
|
6108
6246
|
throw this.invalidResponse("agent wallet");
|
|
6109
6247
|
}
|
|
6110
6248
|
const context = {
|
|
@@ -6134,7 +6272,7 @@ var YieldseekerAgent = class {
|
|
|
6134
6272
|
this.users.set(key2, persisted);
|
|
6135
6273
|
return persisted;
|
|
6136
6274
|
}
|
|
6137
|
-
const walletAddress = (0,
|
|
6275
|
+
const walletAddress = (0, import_viem12.getAddress)(state.walletAddress);
|
|
6138
6276
|
const generation = this.readGeneration;
|
|
6139
6277
|
let user = null;
|
|
6140
6278
|
try {
|
|
@@ -6426,6 +6564,7 @@ var YieldseekerAgent = class {
|
|
|
6426
6564
|
...context,
|
|
6427
6565
|
snapshot: snapshot.agentSnapshot,
|
|
6428
6566
|
fetchedAt: this.readCache.get(`snapshot:${contextKey}`)?.fetchedAt,
|
|
6567
|
+
requestedAt: this.readCache.get(`snapshot:${contextKey}`)?.requestedAt,
|
|
6429
6568
|
readVersion: version,
|
|
6430
6569
|
positionsUnavailable,
|
|
6431
6570
|
...portfolioParts
|
|
@@ -6517,7 +6656,7 @@ var YieldseekerAgent = class {
|
|
|
6517
6656
|
this.agentPath(context, "deploy"),
|
|
6518
6657
|
{ method: "POST", body: {} }
|
|
6519
6658
|
);
|
|
6520
|
-
if (!deployed?.agentWallet || !(0,
|
|
6659
|
+
if (!deployed?.agentWallet || !(0, import_viem12.isAddress)(deployed.agentWallet.walletAddress) || deployed.agentWallet.walletAddress.toLowerCase() !== walletAddress) {
|
|
6521
6660
|
throw this.invalidResponse("agent deployment", {
|
|
6522
6661
|
reason: "Deploy did not return the expected Agent Wallet."
|
|
6523
6662
|
});
|
|
@@ -6625,15 +6764,15 @@ var YieldseekerAgent = class {
|
|
|
6625
6764
|
return hash2;
|
|
6626
6765
|
}
|
|
6627
6766
|
this.assertTransaction(transaction, state, chainId);
|
|
6628
|
-
const account = (0,
|
|
6629
|
-
const walletClient = (0,
|
|
6767
|
+
const account = (0, import_viem12.getAddress)(state.walletAddress);
|
|
6768
|
+
const walletClient = (0, import_viem12.createWalletClient)({
|
|
6630
6769
|
account,
|
|
6631
6770
|
chain: import_chains4.base,
|
|
6632
|
-
transport: (0,
|
|
6771
|
+
transport: (0, import_viem12.custom)(state.provider)
|
|
6633
6772
|
});
|
|
6634
|
-
const walletChainClient = (0,
|
|
6773
|
+
const walletChainClient = (0, import_viem12.createPublicClient)({
|
|
6635
6774
|
chain: import_chains4.base,
|
|
6636
|
-
transport: (0,
|
|
6775
|
+
transport: (0, import_viem12.custom)(state.provider)
|
|
6637
6776
|
});
|
|
6638
6777
|
await ensureWalletOnChain(
|
|
6639
6778
|
walletChainClient,
|
|
@@ -6643,7 +6782,7 @@ var YieldseekerAgent = class {
|
|
|
6643
6782
|
const hash = await walletClient.sendTransaction({
|
|
6644
6783
|
account,
|
|
6645
6784
|
chain: import_chains4.base,
|
|
6646
|
-
to: (0,
|
|
6785
|
+
to: (0, import_viem12.getAddress)(transaction.to),
|
|
6647
6786
|
data: transaction.data,
|
|
6648
6787
|
value: BigInt(transaction.value)
|
|
6649
6788
|
});
|
|
@@ -6747,12 +6886,12 @@ var YieldseekerAgent = class {
|
|
|
6747
6886
|
return receipt;
|
|
6748
6887
|
}
|
|
6749
6888
|
assertTransaction(transaction, state, chainId) {
|
|
6750
|
-
if (!transaction || typeof transaction.from !== "string" || !(0,
|
|
6889
|
+
if (!transaction || typeof transaction.from !== "string" || !(0, import_viem12.isAddress)(transaction.from) || typeof transaction.to !== "string" || !(0, import_viem12.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_viem12.getAddress)(transaction.from) !== (0, import_viem12.getAddress)(state.walletAddress)) {
|
|
6751
6890
|
throw this.invalidResponse("transaction");
|
|
6752
6891
|
}
|
|
6753
6892
|
}
|
|
6754
6893
|
assertAgent(agent) {
|
|
6755
|
-
if (typeof agent.agentId !== "string" || typeof agent.assetAddress !== "string" || !(0,
|
|
6894
|
+
if (typeof agent.agentId !== "string" || typeof agent.assetAddress !== "string" || !(0, import_viem12.isAddress)(agent.assetAddress) || agent.chainId !== 8453) {
|
|
6756
6895
|
throw this.invalidResponse("agent");
|
|
6757
6896
|
}
|
|
6758
6897
|
}
|
|
@@ -6906,7 +7045,7 @@ async function withFailureReporting(apiKey, agentType, fn, baseUrl) {
|
|
|
6906
7045
|
}
|
|
6907
7046
|
|
|
6908
7047
|
// src/lib/helpers/withdraw-helper.ts
|
|
6909
|
-
var
|
|
7048
|
+
var import_viem13 = require("viem");
|
|
6910
7049
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
6911
7050
|
const target = asset.toUpperCase();
|
|
6912
7051
|
return agents.map((agent) => {
|
|
@@ -6914,7 +7053,7 @@ function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decima
|
|
|
6914
7053
|
const tokenBalance = agentBalance?.tokens.find(
|
|
6915
7054
|
(t) => t.chainId === chainId && t.asset.toUpperCase() === target
|
|
6916
7055
|
);
|
|
6917
|
-
let balance = tokenBalance ? (0,
|
|
7056
|
+
let balance = tokenBalance ? (0, import_viem13.parseUnits)(tokenBalance.amount, decimals) : 0n;
|
|
6918
7057
|
if (agent.balanceComposition === "tokens-plus-positions") {
|
|
6919
7058
|
const chainNameById = {
|
|
6920
7059
|
1: "ETHEREUM",
|
|
@@ -6926,14 +7065,14 @@ function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decima
|
|
|
6926
7065
|
const positionChain = position2.chain.trim().toUpperCase();
|
|
6927
7066
|
const matchesChain = positionChain === String(chainId) || targetChain !== void 0 && positionChain === targetChain;
|
|
6928
7067
|
if (!matchesChain || position2.asset.toUpperCase() !== target) continue;
|
|
6929
|
-
balance += position2.withdrawableAmountRaw !== void 0 ? BigInt(position2.withdrawableAmountRaw) : (0,
|
|
7068
|
+
balance += position2.withdrawableAmountRaw !== void 0 ? BigInt(position2.withdrawableAmountRaw) : (0, import_viem13.parseUnits)(position2.amount, decimals);
|
|
6930
7069
|
}
|
|
6931
7070
|
}
|
|
6932
7071
|
const assetTotal = agentBalance?.assetBalances?.find(
|
|
6933
7072
|
(t) => t.chainId === chainId && t.asset.toUpperCase() === target
|
|
6934
7073
|
);
|
|
6935
7074
|
if (assetTotal) {
|
|
6936
|
-
const total = (0,
|
|
7075
|
+
const total = (0, import_viem13.parseUnits)(assetTotal.amount, decimals);
|
|
6937
7076
|
if (total < balance) balance = total > 0n ? total : 0n;
|
|
6938
7077
|
}
|
|
6939
7078
|
return { agent, balance };
|
|
@@ -7092,14 +7231,14 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
7092
7231
|
}
|
|
7093
7232
|
|
|
7094
7233
|
// src/client.ts
|
|
7095
|
-
var
|
|
7234
|
+
var import_viem17 = require("viem");
|
|
7096
7235
|
var import_chains5 = require("viem/chains");
|
|
7097
7236
|
|
|
7098
7237
|
// src/lib/sponsored-token-batch.ts
|
|
7099
|
-
var
|
|
7238
|
+
var import_viem15 = require("viem");
|
|
7100
7239
|
|
|
7101
7240
|
// src/lib/permit2-batch.ts
|
|
7102
|
-
var
|
|
7241
|
+
var import_viem14 = require("viem");
|
|
7103
7242
|
var BATCH_PERMIT2_ADDRESS = "0x000000000022D473030F116dDEE9F6B43aC78BA3";
|
|
7104
7243
|
var BASE_USDC_ADDRESS = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913";
|
|
7105
7244
|
var ERC2612_PERMIT_TYPES = {
|
|
@@ -7111,7 +7250,7 @@ var ERC2612_PERMIT_TYPES = {
|
|
|
7111
7250
|
{ name: "deadline", type: "uint256" }
|
|
7112
7251
|
]
|
|
7113
7252
|
};
|
|
7114
|
-
var ERC2612_READ_ABI = (0,
|
|
7253
|
+
var ERC2612_READ_ABI = (0, import_viem14.parseAbi)([
|
|
7115
7254
|
"function name() view returns (string)",
|
|
7116
7255
|
"function version() view returns (string)",
|
|
7117
7256
|
"function nonces(address owner) view returns (uint256)"
|
|
@@ -7149,7 +7288,7 @@ var PERMIT_BATCH_TYPES = {
|
|
|
7149
7288
|
{ name: "amount", type: "uint256" }
|
|
7150
7289
|
]
|
|
7151
7290
|
};
|
|
7152
|
-
var PERMIT2_BATCH_ABI = (0,
|
|
7291
|
+
var PERMIT2_BATCH_ABI = (0, import_viem14.parseAbi)([
|
|
7153
7292
|
"struct TokenPermissions { address token; uint256 amount; }",
|
|
7154
7293
|
"struct PermitBatchTransferFrom { TokenPermissions[] permitted; uint256 nonce; uint256 deadline; }",
|
|
7155
7294
|
"struct SignatureTransferDetails { address to; uint256 requestedAmount; }",
|
|
@@ -7192,14 +7331,14 @@ var planOf = (transfers) => JSON.stringify(
|
|
|
7192
7331
|
amount: BigInt(t.amount).toString()
|
|
7193
7332
|
}))
|
|
7194
7333
|
);
|
|
7195
|
-
var pendingKey = (i) => `owney.token-batch.v1:${(0,
|
|
7334
|
+
var pendingKey = (i) => `owney.token-batch.v1:${(0, import_viem15.keccak256)((0, import_viem15.toBytes)(i.apiKey))}:${i.baseUrl ?? "default"}:${i.chainId}:${i.owner.toLowerCase()}:${i.token.toLowerCase()}`;
|
|
7196
7335
|
function pendingTokenBatch(i) {
|
|
7197
7336
|
try {
|
|
7198
7337
|
const saved = read(pendingKey(i));
|
|
7199
7338
|
if (!saved) return;
|
|
7200
7339
|
const body = JSON.parse(saved);
|
|
7201
|
-
if (!body.serializedTransaction || body.chainId !== i.chainId || !(0,
|
|
7202
|
-
return { txHash: (0,
|
|
7340
|
+
if (!body.serializedTransaction || body.chainId !== i.chainId || !(0, import_viem15.isAddressEqual)(body.from, i.owner) || !(0, import_viem15.isAddressEqual)(body.token, i.token) || !body.transfers?.length) return;
|
|
7341
|
+
return { txHash: (0, import_viem15.keccak256)(body.serializedTransaction), transfers: body.transfers.map(({ to, amount }) => ({ to, amount })) };
|
|
7203
7342
|
} catch {
|
|
7204
7343
|
return;
|
|
7205
7344
|
}
|
|
@@ -7244,14 +7383,47 @@ async function execute(i, key2, plan) {
|
|
|
7244
7383
|
const send = async (initial) => {
|
|
7245
7384
|
let body = initial;
|
|
7246
7385
|
save(key2, body);
|
|
7386
|
+
const rejectedPreparation = (error) => !body.serializedTransaction && error instanceof OwneyError && typeof error.details?.statusCode === "number" && error.details.statusCode >= 400 && error.details.statusCode < 500 && ![408, 429].includes(error.details.statusCode);
|
|
7247
7387
|
try {
|
|
7388
|
+
const post = () => postSponsorBatchTransfer({ apiKey: i.apiKey, baseUrl: i.baseUrl, body });
|
|
7389
|
+
const pendingError = (phase, txHash) => new OwneyError(
|
|
7390
|
+
"DEPOSIT_IN_PROGRESS",
|
|
7391
|
+
phase === "approval" ? "Deposit approval is awaiting confirmation. Retry the same amount to continue it." : "Deposit is awaiting confirmation. Its transaction is still being checked.",
|
|
7392
|
+
{ sponsorPending: true, phase, txHash, safeToFallback: false }
|
|
7393
|
+
);
|
|
7394
|
+
const assertReceipt = (receipt, phase) => {
|
|
7395
|
+
if (receipt.status !== "success") throw new OwneyError(
|
|
7396
|
+
"SPONSOR_REQUEST_FAILED",
|
|
7397
|
+
`Sponsored ${phase} transaction reverted. Please retry.`,
|
|
7398
|
+
{ notSubmitted: true, safeToFallback: false }
|
|
7399
|
+
);
|
|
7400
|
+
};
|
|
7401
|
+
const waitForConfirmation = async (phase, hash2) => {
|
|
7402
|
+
let receipt;
|
|
7403
|
+
try {
|
|
7404
|
+
receipt = await i.pub.waitForTransactionReceipt({ hash: hash2, confirmations: 1, timeout: 9e4, checkReplacement: false });
|
|
7405
|
+
} catch {
|
|
7406
|
+
receipt = await i.pub.getTransactionReceipt({ hash: hash2 }).catch(() => void 0);
|
|
7407
|
+
}
|
|
7408
|
+
if (!receipt) throw pendingError(phase, hash2);
|
|
7409
|
+
assertReceipt(receipt, phase);
|
|
7410
|
+
};
|
|
7411
|
+
const postSigned = async (phase, hash2) => {
|
|
7412
|
+
try {
|
|
7413
|
+
return await post();
|
|
7414
|
+
} catch (error) {
|
|
7415
|
+
if (rejectedPreparation(error) || error instanceof OwneyError && error.details?.notSubmitted === true) throw error;
|
|
7416
|
+
await waitForConfirmation(phase, hash2);
|
|
7417
|
+
return void 0;
|
|
7418
|
+
}
|
|
7419
|
+
};
|
|
7248
7420
|
if (body.erc2612Permit && !body.serializedPermitTransaction) {
|
|
7249
7421
|
const preparedPermit = await postSponsorBatchTransfer({
|
|
7250
7422
|
apiKey: i.apiKey,
|
|
7251
7423
|
baseUrl: i.baseUrl,
|
|
7252
7424
|
body
|
|
7253
7425
|
});
|
|
7254
|
-
if (!preparedPermit.serializedPermitTransaction || !preparedPermit.permitTxHash || (0,
|
|
7426
|
+
if (!preparedPermit.serializedPermitTransaction || !preparedPermit.permitTxHash || (0, import_viem15.keccak256)(preparedPermit.serializedPermitTransaction) !== preparedPermit.permitTxHash)
|
|
7255
7427
|
throw new Error(
|
|
7256
7428
|
"Sponsorship API did not return a valid prepared permit transaction."
|
|
7257
7429
|
);
|
|
@@ -7262,12 +7434,18 @@ async function execute(i, key2, plan) {
|
|
|
7262
7434
|
save(key2, body);
|
|
7263
7435
|
}
|
|
7264
7436
|
if (!body.serializedTransaction) {
|
|
7265
|
-
const
|
|
7266
|
-
|
|
7267
|
-
|
|
7268
|
-
|
|
7269
|
-
|
|
7270
|
-
|
|
7437
|
+
const permitHash = body.serializedPermitTransaction ? (0, import_viem15.keccak256)(body.serializedPermitTransaction) : void 0;
|
|
7438
|
+
let prepared = permitHash ? await postSigned("approval", permitHash) : await post();
|
|
7439
|
+
if (prepared?.status === "pending") {
|
|
7440
|
+
if (!permitHash || prepared.phase !== "approval" || prepared.txHash !== permitHash)
|
|
7441
|
+
throw new Error("Sponsorship approval does not match the pending transaction.");
|
|
7442
|
+
await waitForConfirmation("approval", permitHash);
|
|
7443
|
+
prepared = void 0;
|
|
7444
|
+
}
|
|
7445
|
+
if (!prepared) prepared = await post();
|
|
7446
|
+
if (prepared.status === "pending" && permitHash && prepared.phase === "approval" && prepared.txHash === permitHash)
|
|
7447
|
+
throw pendingError("approval", permitHash);
|
|
7448
|
+
if (!prepared.serializedTransaction || (0, import_viem15.keccak256)(prepared.serializedTransaction) !== prepared.txHash)
|
|
7271
7449
|
throw new Error(
|
|
7272
7450
|
"Sponsorship API did not return a valid prepared transaction."
|
|
7273
7451
|
);
|
|
@@ -7278,22 +7456,33 @@ async function execute(i, key2, plan) {
|
|
|
7278
7456
|
save(key2, body);
|
|
7279
7457
|
}
|
|
7280
7458
|
try {
|
|
7281
|
-
i.onSubmitted?.((0,
|
|
7459
|
+
i.onSubmitted?.((0, import_viem15.keccak256)(body.serializedTransaction));
|
|
7282
7460
|
} catch {
|
|
7283
7461
|
}
|
|
7284
|
-
const
|
|
7285
|
-
|
|
7286
|
-
|
|
7287
|
-
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7462
|
+
const hash = (0, import_viem15.keccak256)(body.serializedTransaction);
|
|
7463
|
+
const existing = await i.pub.getTransactionReceipt({ hash }).catch(() => void 0);
|
|
7464
|
+
if (existing) {
|
|
7465
|
+
assertReceipt(existing, "deposit");
|
|
7466
|
+
void post().catch(() => void 0);
|
|
7467
|
+
clear(key2);
|
|
7468
|
+
return hash;
|
|
7469
|
+
}
|
|
7470
|
+
let result = await postSigned("deposit", hash);
|
|
7471
|
+
if (result?.status === "pending" && result.phase === "approval" && body.serializedPermitTransaction && result.txHash === (0, import_viem15.keccak256)(body.serializedPermitTransaction)) {
|
|
7472
|
+
await waitForConfirmation("approval", result.txHash);
|
|
7473
|
+
result = await postSigned("deposit", hash);
|
|
7474
|
+
if (result?.status === "pending" && result.phase === "approval" && result.txHash === (0, import_viem15.keccak256)(body.serializedPermitTransaction)) throw pendingError("approval", result.txHash);
|
|
7475
|
+
}
|
|
7476
|
+
if (result) {
|
|
7477
|
+
if (result.txHash !== hash || result.status === "pending" && result.phase !== "deposit")
|
|
7478
|
+
throw new Error("Sponsorship receipt does not match the pending transaction.");
|
|
7479
|
+
if (result.status === "pending") await waitForConfirmation("deposit", hash);
|
|
7480
|
+
}
|
|
7481
|
+
if (!result || result.status === "pending") void post().catch(() => void 0);
|
|
7293
7482
|
clear(key2);
|
|
7294
|
-
return
|
|
7483
|
+
return hash;
|
|
7295
7484
|
} catch (error) {
|
|
7296
|
-
if (!body.serializedTransaction || error instanceof OwneyError && error.details?.notSubmitted === true)
|
|
7485
|
+
if (!body.serializedTransaction && !body.serializedPermitTransaction || rejectedPreparation(error) || error instanceof OwneyError && error.details?.notSubmitted === true)
|
|
7297
7486
|
clear(key2);
|
|
7298
7487
|
throw error;
|
|
7299
7488
|
}
|
|
@@ -7303,7 +7492,7 @@ async function execute(i, key2, plan) {
|
|
|
7303
7492
|
throw new OwneyError("DEPOSIT_IN_PROGRESS", "The saved deposit changed. Check its status before depositing again.");
|
|
7304
7493
|
if (saved) {
|
|
7305
7494
|
const previous = JSON.parse(saved);
|
|
7306
|
-
if (previous.chainId !== i.chainId || !(0,
|
|
7495
|
+
if (previous.chainId !== i.chainId || !(0, import_viem15.isAddressEqual)(previous.from, i.owner) || !(0, import_viem15.isAddressEqual)(previous.token, i.token) || planOf(previous.transfers) !== plan)
|
|
7307
7496
|
throw new Error(
|
|
7308
7497
|
"Retry the previous token deposit and agent split first to reconcile its status."
|
|
7309
7498
|
);
|
|
@@ -7320,7 +7509,7 @@ async function execute(i, key2, plan) {
|
|
|
7320
7509
|
"DEPOSIT_INSUFFICIENT_BALANCE",
|
|
7321
7510
|
"Insufficient token balance for this deposit."
|
|
7322
7511
|
);
|
|
7323
|
-
if (allowance < total && (i.chainId !== 8453 || !(0,
|
|
7512
|
+
if (allowance < total && (i.chainId !== 8453 || !(0, import_viem15.isAddressEqual)(i.token, BASE_USDC_ADDRESS)))
|
|
7324
7513
|
throw new OwneyError(
|
|
7325
7514
|
"PERMIT2_APPROVAL_REQUIRED",
|
|
7326
7515
|
"token deposits need a one-time Permit2 approval."
|
|
@@ -7499,7 +7688,7 @@ async function runAgentDepositBatch(chainId, legs, transfer) {
|
|
|
7499
7688
|
}
|
|
7500
7689
|
|
|
7501
7690
|
// src/lib/sponsored-calls-deposit.ts
|
|
7502
|
-
var
|
|
7691
|
+
var import_viem16 = require("viem");
|
|
7503
7692
|
var DEFAULT_POLL_INTERVAL_MS = 1500;
|
|
7504
7693
|
var DEFAULT_MAX_POLLS = 30;
|
|
7505
7694
|
async function paymasterSupported(provider, owner, chainId) {
|
|
@@ -7507,7 +7696,7 @@ async function paymasterSupported(provider, owner, chainId) {
|
|
|
7507
7696
|
method: "wallet_getCapabilities",
|
|
7508
7697
|
params: [owner]
|
|
7509
7698
|
});
|
|
7510
|
-
const forChain = caps?.[(0,
|
|
7699
|
+
const forChain = caps?.[(0, import_viem16.toHex)(chainId)] ?? caps?.[String(chainId)];
|
|
7511
7700
|
return Boolean(forChain?.paymasterService?.supported);
|
|
7512
7701
|
}
|
|
7513
7702
|
function makeSponsoredCallsCallback(deps) {
|
|
@@ -7544,8 +7733,8 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
7544
7733
|
const calls = transfers.map((transfer) => ({
|
|
7545
7734
|
to: token,
|
|
7546
7735
|
value: "0x0",
|
|
7547
|
-
data: (0,
|
|
7548
|
-
abi:
|
|
7736
|
+
data: (0, import_viem16.encodeFunctionData)({
|
|
7737
|
+
abi: import_viem16.erc20Abi,
|
|
7549
7738
|
functionName: "transfer",
|
|
7550
7739
|
args: [transfer.to, BigInt(transfer.amount)]
|
|
7551
7740
|
})
|
|
@@ -7577,7 +7766,7 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
7577
7766
|
url.searchParams.append("owneyIntent", intent);
|
|
7578
7767
|
paymasterUrl = url.toString();
|
|
7579
7768
|
}
|
|
7580
|
-
const requestedId = (0,
|
|
7769
|
+
const requestedId = (0, import_viem16.toHex)(globalThis.crypto.getRandomValues(new Uint8Array(32)));
|
|
7581
7770
|
const progress = (id, transfer) => {
|
|
7582
7771
|
try {
|
|
7583
7772
|
deps.onCallsProgress?.(id, transfers, transfer);
|
|
@@ -7594,7 +7783,7 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
7594
7783
|
version: "2.0.0",
|
|
7595
7784
|
id: requestedId,
|
|
7596
7785
|
from: deps.ownerAddress,
|
|
7597
|
-
chainId: (0,
|
|
7786
|
+
chainId: (0, import_viem16.toHex)(chainId),
|
|
7598
7787
|
atomicRequired: transfers.length > 1,
|
|
7599
7788
|
calls,
|
|
7600
7789
|
capabilities: {
|
|
@@ -7746,6 +7935,7 @@ var OwneySDK = class {
|
|
|
7746
7935
|
cachedSponsoredCallsCallbacks = /* @__PURE__ */ new Map();
|
|
7747
7936
|
agentReads = new AgentReads();
|
|
7748
7937
|
recoveredFundingReads = /* @__PURE__ */ new Set();
|
|
7938
|
+
fundingBalanceChecks = /* @__PURE__ */ new WeakMap();
|
|
7749
7939
|
activationChecks = /* @__PURE__ */ new Map();
|
|
7750
7940
|
readAgent(agent, method, fetch2, params = null) {
|
|
7751
7941
|
const key2 = JSON.stringify([
|
|
@@ -7791,6 +7981,7 @@ var OwneySDK = class {
|
|
|
7791
7981
|
}
|
|
7792
7982
|
this.agentReads.clearInFlight();
|
|
7793
7983
|
this.activationChecks.clear();
|
|
7984
|
+
this.fundingBalanceChecks = /* @__PURE__ */ new WeakMap();
|
|
7794
7985
|
this.state = { provider, walletAddress, chainId: null };
|
|
7795
7986
|
this.cachedSponsoredCallback = null;
|
|
7796
7987
|
this.cachedWethSponsoredCallback = null;
|
|
@@ -7802,6 +7993,7 @@ var OwneySDK = class {
|
|
|
7802
7993
|
*/
|
|
7803
7994
|
async disconnect() {
|
|
7804
7995
|
this.state = null;
|
|
7996
|
+
this.fundingBalanceChecks = /* @__PURE__ */ new WeakMap();
|
|
7805
7997
|
for (const agent of this.agents.values()) {
|
|
7806
7998
|
await agent.disconnect();
|
|
7807
7999
|
}
|
|
@@ -7876,14 +8068,14 @@ var OwneySDK = class {
|
|
|
7876
8068
|
// PublicClient/WalletClient param types — structurally identical at
|
|
7877
8069
|
// runtime, but the two share a name TS treats as unrelated.
|
|
7878
8070
|
getPublicClient: (cid) => this.getPaidRpcClient(cid),
|
|
7879
|
-
getWalletChainClient: (cid) => (0,
|
|
8071
|
+
getWalletChainClient: (cid) => (0, import_viem17.createPublicClient)({
|
|
7880
8072
|
chain: VIEM_CHAIN2[cid],
|
|
7881
|
-
transport: (0,
|
|
8073
|
+
transport: (0, import_viem17.custom)(provider)
|
|
7882
8074
|
}),
|
|
7883
|
-
getWalletClient: (cid) => (0,
|
|
8075
|
+
getWalletClient: (cid) => (0, import_viem17.createWalletClient)({
|
|
7884
8076
|
account: owner,
|
|
7885
8077
|
chain: VIEM_CHAIN2[cid],
|
|
7886
|
-
transport: (0,
|
|
8078
|
+
transport: (0, import_viem17.custom)(provider)
|
|
7887
8079
|
})
|
|
7888
8080
|
});
|
|
7889
8081
|
if (!onApproved && !onSubmitted && !resumeTxHash) this.cachedSponsoredCallback = callback;
|
|
@@ -7931,14 +8123,14 @@ var OwneySDK = class {
|
|
|
7931
8123
|
// PublicClient/WalletClient param types — structurally identical at
|
|
7932
8124
|
// runtime, but the two share a name TS treats as unrelated.
|
|
7933
8125
|
getPublicClient: (cid) => this.getPaidRpcClient(cid),
|
|
7934
|
-
getWalletChainClient: (cid) => (0,
|
|
8126
|
+
getWalletChainClient: (cid) => (0, import_viem17.createPublicClient)({
|
|
7935
8127
|
chain: VIEM_CHAIN2[cid],
|
|
7936
|
-
transport: (0,
|
|
8128
|
+
transport: (0, import_viem17.custom)(provider)
|
|
7937
8129
|
}),
|
|
7938
|
-
getWalletClient: (cid) => (0,
|
|
8130
|
+
getWalletClient: (cid) => (0, import_viem17.createWalletClient)({
|
|
7939
8131
|
account: owner,
|
|
7940
8132
|
chain: VIEM_CHAIN2[cid],
|
|
7941
|
-
transport: (0,
|
|
8133
|
+
transport: (0, import_viem17.custom)(provider)
|
|
7942
8134
|
})
|
|
7943
8135
|
});
|
|
7944
8136
|
if (!onApproved && !onSubmitted && !resumeTxHash) this.cachedWethSponsoredCallback = callback;
|
|
@@ -8702,9 +8894,8 @@ var OwneySDK = class {
|
|
|
8702
8894
|
verified = inspectFundingReceipt(receipt, { ...evidence, agentWallet, intendedAmount: "MAX" }, token.address, direction);
|
|
8703
8895
|
}
|
|
8704
8896
|
const key2 = `${state.walletAddress.toLowerCase()}:${chainId}:${evidence.agentId}:${evidence.token}:${evidence.txHash}`;
|
|
8705
|
-
if ((verified.transfer === "confirmed" || verified.transfer === "failed" && verified.confirmedAmount === "0") && !this.recoveredFundingReads.has(key2)) {
|
|
8706
|
-
|
|
8707
|
-
agent.invalidateFundingRead?.(state, chainId, evidence.token, options.balanceRefreshUntil);
|
|
8897
|
+
if (options.refreshBalance !== false && (verified.transfer === "confirmed" || verified.transfer === "failed" && verified.confirmedAmount === "0") && !this.recoveredFundingReads.has(key2)) {
|
|
8898
|
+
agent.invalidateFundingRead?.(state, chainId, evidence.token, options.balanceRefreshUntil);
|
|
8708
8899
|
this.recoveredFundingReads.add(key2);
|
|
8709
8900
|
if (this.recoveredFundingReads.size > 256) this.recoveredFundingReads.delete(this.recoveredFundingReads.values().next().value);
|
|
8710
8901
|
}
|
|
@@ -8812,6 +9003,44 @@ var OwneySDK = class {
|
|
|
8812
9003
|
assertCurrent();
|
|
8813
9004
|
return true;
|
|
8814
9005
|
}
|
|
9006
|
+
/** Optional post-payout display proof; receipt verification and the provider
|
|
9007
|
+
* adapter must agree before attaching it to this exact balance object. */
|
|
9008
|
+
async verifyWithdrawalBalance(evidence, balance) {
|
|
9009
|
+
const { state, chainId, assertCurrent } = this.captureReadScope(evidence.chainId);
|
|
9010
|
+
const agent = this.getAgent(evidence.agentId);
|
|
9011
|
+
if (!agent.verifyWithdrawalBalance || !evidence.txHash || state.walletAddress.toLowerCase() !== evidence.walletAddress.toLowerCase()) return balance;
|
|
9012
|
+
const key2 = `${state.walletAddress.toLowerCase()}:${chainId}:${evidence.agentId}:${evidence.token}:${evidence.txHash}:${evidence.intendedAmount}`;
|
|
9013
|
+
const checks = this.fundingBalanceChecks.get(balance) ?? /* @__PURE__ */ new Map();
|
|
9014
|
+
this.fundingBalanceChecks.set(balance, checks);
|
|
9015
|
+
const previous = checks.get(key2);
|
|
9016
|
+
if (previous) {
|
|
9017
|
+
const result2 = await previous;
|
|
9018
|
+
assertCurrent();
|
|
9019
|
+
return result2;
|
|
9020
|
+
}
|
|
9021
|
+
let timer;
|
|
9022
|
+
const read2 = async () => {
|
|
9023
|
+
const verified = await this.inspectFunding(evidence, "withdraw", { refreshBalance: false });
|
|
9024
|
+
assertCurrent();
|
|
9025
|
+
if (verified.transfer !== "confirmed" || verified.delivery !== "confirmed" || !verified.blockNumber) return balance;
|
|
9026
|
+
const metadata = await agent.verifyWithdrawalBalance(state, verified, balance);
|
|
9027
|
+
assertCurrent();
|
|
9028
|
+
if (!metadata || metadata.chainId !== chainId || metadata.asset.toUpperCase() !== evidence.token || !metadata.withdrawalCheck || metadata.withdrawalCheck.txHash.toLowerCase() !== verified.txHash?.toLowerCase() || BigInt(metadata.withdrawalCheck.blockNumber) < BigInt(verified.blockNumber)) return balance;
|
|
9029
|
+
return { ...balance, readMetadata: [
|
|
9030
|
+
...(balance.readMetadata ?? []).filter((item) => !(item.chainId === chainId && item.asset.toUpperCase() === evidence.token)),
|
|
9031
|
+
metadata
|
|
9032
|
+
] };
|
|
9033
|
+
};
|
|
9034
|
+
const pending = Promise.race([read2(), new Promise((resolve) => {
|
|
9035
|
+
timer = setTimeout(() => resolve(balance), 2e3);
|
|
9036
|
+
})]).catch(() => balance).finally(() => {
|
|
9037
|
+
if (timer) clearTimeout(timer);
|
|
9038
|
+
});
|
|
9039
|
+
checks.set(key2, pending);
|
|
9040
|
+
const result = await pending;
|
|
9041
|
+
assertCurrent();
|
|
9042
|
+
return result;
|
|
9043
|
+
}
|
|
8815
9044
|
/** A display acknowledgement controls polling only; it never confirms a financial outcome. */
|
|
8816
9045
|
endFundingBalanceRefresh(evidence, read2) {
|
|
8817
9046
|
const { state, chainId } = this.captureReadScope(evidence.chainId);
|
|
@@ -9080,7 +9309,7 @@ var OwneySDK = class {
|
|
|
9080
9309
|
if (this.isUserRejectedWithdrawal(originalFailure)) throw originalFailure;
|
|
9081
9310
|
if (entry.balance !== 0n && entry.agent.id !== "yieldseeker") {
|
|
9082
9311
|
const total = aggregated.agentBalances[entry.agent.id]?.assetBalances?.find((value) => value.chainId === chainId && value.asset.toUpperCase() === token);
|
|
9083
|
-
if (!total || (0,
|
|
9312
|
+
if (!total || (0, import_viem17.parseUnits)(total.amount, assetInfo.decimals) <= entry.balance) return;
|
|
9084
9313
|
}
|
|
9085
9314
|
try {
|
|
9086
9315
|
const otherAvailable = indexedAvailable - entry.balance;
|
|
@@ -9684,16 +9913,16 @@ var OwneySDK = class {
|
|
|
9684
9913
|
);
|
|
9685
9914
|
}
|
|
9686
9915
|
const provider = this.requireConnectedProvider();
|
|
9687
|
-
const walletChainClient = (0,
|
|
9916
|
+
const walletChainClient = (0, import_viem17.createPublicClient)({
|
|
9688
9917
|
chain: VIEM_CHAIN2[chainId],
|
|
9689
|
-
transport: (0,
|
|
9918
|
+
transport: (0, import_viem17.custom)(provider)
|
|
9690
9919
|
});
|
|
9691
9920
|
const publicClient = this.getPaidRpcClient(chainId);
|
|
9692
9921
|
const approvalAmount = permit2ApprovalAmount(requiredAmount);
|
|
9693
|
-
const wallet = (0,
|
|
9922
|
+
const wallet = (0, import_viem17.createWalletClient)({
|
|
9694
9923
|
account: state.walletAddress,
|
|
9695
9924
|
chain: VIEM_CHAIN2[chainId],
|
|
9696
|
-
transport: (0,
|
|
9925
|
+
transport: (0, import_viem17.custom)(provider)
|
|
9697
9926
|
});
|
|
9698
9927
|
await ensureWalletOnChain(walletChainClient, wallet, chainId);
|
|
9699
9928
|
const hash = await wallet.writeContract({
|
|
@@ -9855,7 +10084,7 @@ var OwneySDK = class {
|
|
|
9855
10084
|
};
|
|
9856
10085
|
|
|
9857
10086
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
9858
|
-
var
|
|
10087
|
+
var import_viem18 = require("viem");
|
|
9859
10088
|
var import_siwe2 = require("siwe");
|
|
9860
10089
|
var import_sdk2 = require("@zyfai/sdk");
|
|
9861
10090
|
|
|
@@ -9982,7 +10211,7 @@ function buildSIWXConfig(deps) {
|
|
|
9982
10211
|
issuedAt,
|
|
9983
10212
|
toString() {
|
|
9984
10213
|
return new import_siwe2.SiweMessage({
|
|
9985
|
-
address: (0,
|
|
10214
|
+
address: (0, import_viem18.getAddress)(accountAddress),
|
|
9986
10215
|
chainId: numericChainId(chainId),
|
|
9987
10216
|
domain,
|
|
9988
10217
|
uri,
|