@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.js
CHANGED
|
@@ -1543,6 +1543,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1543
1543
|
earningsRefreshes = /* @__PURE__ */ new Map();
|
|
1544
1544
|
earningsSnapshot = null;
|
|
1545
1545
|
earningsGeneration = 0;
|
|
1546
|
+
balanceSnapshots = /* @__PURE__ */ new WeakMap();
|
|
1546
1547
|
constructor(apiKey, rpcUrls, referralSource) {
|
|
1547
1548
|
this.rpcUrls = resolveRpcUrls(rpcUrls);
|
|
1548
1549
|
this.sdk = new ZyfaiSDK({
|
|
@@ -1746,7 +1747,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
1746
1747
|
* chain/account switch fires the provider's `accountsChanged` →
|
|
1747
1748
|
* `disconnectAccount` (nulls walletClient + authenticatedUserId) while our
|
|
1748
1749
|
* own `connectAuth` guard still believes this chain is connected and
|
|
1749
|
-
* early-returns. Without this, authenticated calls (
|
|
1750
|
+
* early-returns. Without this, authenticated calls (sendDeposit,
|
|
1750
1751
|
* withdrawFunds) fail with "No account connected".
|
|
1751
1752
|
*/
|
|
1752
1753
|
async ensureConnected(state, chainId) {
|
|
@@ -2368,7 +2369,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2368
2369
|
return { txHash, smartWallet, amount, evidence: evidence2 };
|
|
2369
2370
|
}
|
|
2370
2371
|
await this.ensureWalletDeployed(this.getAddress(), validChainId);
|
|
2371
|
-
const raw2 = await this.sdk.
|
|
2372
|
+
const raw2 = await this.sdk.sendDeposit(
|
|
2372
2373
|
this.getAddress(),
|
|
2373
2374
|
validChainId,
|
|
2374
2375
|
amount,
|
|
@@ -2384,7 +2385,7 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2384
2385
|
intendedAmount: amount,
|
|
2385
2386
|
txHash: raw2.txHash,
|
|
2386
2387
|
transfer: "unknown",
|
|
2387
|
-
registration: "unknown",
|
|
2388
|
+
registration: raw2.registration ? "confirmed" : "unknown",
|
|
2388
2389
|
delivery: "not-applicable"
|
|
2389
2390
|
};
|
|
2390
2391
|
notifyFunding(onProgress, evidence);
|
|
@@ -2692,10 +2693,37 @@ var ZyfaiAgent = class _ZyfaiAgent {
|
|
|
2692
2693
|
}
|
|
2693
2694
|
async getBalances(state, chainId) {
|
|
2694
2695
|
const requestedAt = Date.now();
|
|
2696
|
+
const generation = this.earningsGeneration;
|
|
2695
2697
|
const { smartWallet, chainId: validChainId } = await this.resolveSmartWallet(state, chainId);
|
|
2696
2698
|
const raw2 = await this.sdk.getPortfolio(this.getAddress());
|
|
2697
2699
|
const balance = mapBalances(raw2, validChainId, smartWallet);
|
|
2698
|
-
|
|
2700
|
+
const reads = balance.readMetadata?.map((read2) => ({ ...read2, requestedAt })) ?? [];
|
|
2701
|
+
for (const asset of SupportedAssets.filter((item) => item.chainId === chainId)) {
|
|
2702
|
+
if (!reads.some((read2) => read2.chainId === chainId && read2.asset === asset.symbol) && hasEmptyWithdrawalSnapshot(raw2, chainId, asset.symbol)) {
|
|
2703
|
+
reads.push({ chainId, asset: asset.symbol, requestedAt, fetchedAt: Date.now(), positionsStatus: "available" });
|
|
2704
|
+
}
|
|
2705
|
+
}
|
|
2706
|
+
const result = { ...balance, readMetadata: reads };
|
|
2707
|
+
for (const read2 of reads) this.balanceSnapshots.set(read2, { raw: raw2, generation, owner: state.walletAddress.toLowerCase() });
|
|
2708
|
+
return result;
|
|
2709
|
+
}
|
|
2710
|
+
async verifyWithdrawalBalance(state, evidence, balance) {
|
|
2711
|
+
const read2 = balance.readMetadata?.find((item) => item.chainId === evidence.chainId && item.asset === evidence.token);
|
|
2712
|
+
const snapshot = read2 && this.balanceSnapshots.get(read2);
|
|
2713
|
+
const asset = SupportedAssets.find((item) => item.chainId === evidence.chainId && item.symbol === evidence.token);
|
|
2714
|
+
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;
|
|
2715
|
+
const client = this.getPublicClient(evidence.chainId);
|
|
2716
|
+
const blockNumber = await client.getBlockNumber({ cacheTime: 0 });
|
|
2717
|
+
if (blockNumber < BigInt(evidence.blockNumber)) return void 0;
|
|
2718
|
+
const idle = await client.readContract({
|
|
2719
|
+
address: asset.address,
|
|
2720
|
+
abi: erc20Abi2,
|
|
2721
|
+
functionName: "balanceOf",
|
|
2722
|
+
args: [balance.smartWallet],
|
|
2723
|
+
blockNumber
|
|
2724
|
+
});
|
|
2725
|
+
if (idle !== 0n || snapshot.generation !== this.earningsGeneration || this.connectedAddress?.toLowerCase() !== snapshot.owner || this.connectedChainId !== evidence.chainId) return void 0;
|
|
2726
|
+
return { ...read2, withdrawalCheck: { txHash: evidence.txHash, blockNumber: blockNumber.toString() } };
|
|
2699
2727
|
}
|
|
2700
2728
|
earningsKey(state, chainId, smartWallet) {
|
|
2701
2729
|
return JSON.stringify([
|
|
@@ -2901,10 +2929,11 @@ import {
|
|
|
2901
2929
|
decodeEventLog as decodeEventLog2,
|
|
2902
2930
|
encodeEventTopics,
|
|
2903
2931
|
encodeFunctionData,
|
|
2904
|
-
erc20Abi as
|
|
2905
|
-
erc4626Abi,
|
|
2906
|
-
getAddress as
|
|
2907
|
-
isAddress as isAddress3
|
|
2932
|
+
erc20Abi as erc20Abi4,
|
|
2933
|
+
erc4626Abi as erc4626Abi2,
|
|
2934
|
+
getAddress as getAddress5,
|
|
2935
|
+
isAddress as isAddress3,
|
|
2936
|
+
parseUnits
|
|
2908
2937
|
} from "viem";
|
|
2909
2938
|
import { base as base4 } from "viem/chains";
|
|
2910
2939
|
|
|
@@ -3694,6 +3723,7 @@ function mapYieldseekerBalances(contexts) {
|
|
|
3694
3723
|
chainId: context.agent.chainId,
|
|
3695
3724
|
asset: context.asset,
|
|
3696
3725
|
fetchedAt: context.fetchedAt,
|
|
3726
|
+
requestedAt: context.requestedAt,
|
|
3697
3727
|
readVersion: context.readVersion,
|
|
3698
3728
|
providerUpdatedAt: context.snapshot.updatedDate,
|
|
3699
3729
|
snapshotId: String(context.snapshot.agentWalletSnapshotId),
|
|
@@ -4071,9 +4101,55 @@ function mapYieldseekerAgentApy(options, days) {
|
|
|
4071
4101
|
};
|
|
4072
4102
|
}
|
|
4073
4103
|
|
|
4104
|
+
// src/lib/remaining-vault-balance.ts
|
|
4105
|
+
import { erc20Abi as erc20Abi3, erc4626Abi, getAddress as getAddress2 } from "viem";
|
|
4106
|
+
async function remainingVaultBalance(client, wallet, asset, vaults, blockNumber) {
|
|
4107
|
+
const addresses = [...new Set(vaults.map((value) => value.toLowerCase()))];
|
|
4108
|
+
if (addresses.length > 64) return void 0;
|
|
4109
|
+
const batches = [];
|
|
4110
|
+
for (let index = 0; index < addresses.length; index += 10) batches.push(addresses.slice(index, index + 10));
|
|
4111
|
+
const values = await Promise.all(batches.map(async (batch) => {
|
|
4112
|
+
const balances = await client.multicall({
|
|
4113
|
+
blockNumber,
|
|
4114
|
+
allowFailure: true,
|
|
4115
|
+
contracts: batch.map((address) => ({
|
|
4116
|
+
address: getAddress2(address),
|
|
4117
|
+
abi: erc20Abi3,
|
|
4118
|
+
functionName: "balanceOf",
|
|
4119
|
+
args: [wallet]
|
|
4120
|
+
}))
|
|
4121
|
+
});
|
|
4122
|
+
if (balances.length !== batch.length) return void 0;
|
|
4123
|
+
const funded = [];
|
|
4124
|
+
for (let index = 0; index < batch.length; index++) {
|
|
4125
|
+
const result = balances[index];
|
|
4126
|
+
if (result?.status !== "success" || typeof result.result !== "bigint" || result.result < 0n) return void 0;
|
|
4127
|
+
if (result.result > 0n) funded.push({ address: getAddress2(batch[index]), shares: result.result });
|
|
4128
|
+
}
|
|
4129
|
+
if (!funded.length) return 0n;
|
|
4130
|
+
const valuations = await client.multicall({
|
|
4131
|
+
blockNumber,
|
|
4132
|
+
allowFailure: true,
|
|
4133
|
+
contracts: funded.flatMap(({ address, shares }) => [
|
|
4134
|
+
{ address, abi: erc4626Abi, functionName: "asset" },
|
|
4135
|
+
{ address, abi: erc4626Abi, functionName: "convertToAssets", args: [shares] }
|
|
4136
|
+
])
|
|
4137
|
+
});
|
|
4138
|
+
if (valuations.length !== funded.length * 2) return void 0;
|
|
4139
|
+
let total = 0n;
|
|
4140
|
+
for (let index = 0; index < funded.length; index++) {
|
|
4141
|
+
const underlying = valuations[index * 2], value = valuations[index * 2 + 1];
|
|
4142
|
+
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;
|
|
4143
|
+
total += value.result;
|
|
4144
|
+
}
|
|
4145
|
+
return total;
|
|
4146
|
+
}));
|
|
4147
|
+
return values.some((value) => value === void 0) ? void 0 : values.reduce((sum, value) => sum + value, 0n);
|
|
4148
|
+
}
|
|
4149
|
+
|
|
4074
4150
|
// src/agents/yieldseeker/yieldseeker.wallet-version.ts
|
|
4075
4151
|
import {
|
|
4076
|
-
getAddress as
|
|
4152
|
+
getAddress as getAddress3,
|
|
4077
4153
|
isAddressEqual,
|
|
4078
4154
|
parseAbi as parseAbi3
|
|
4079
4155
|
} from "viem";
|
|
@@ -4097,9 +4173,9 @@ function yieldseekerOwnerPath(code) {
|
|
|
4097
4173
|
return !code || code === "0x" || /^0xef0100[0-9a-f]{40}$/i.test(code) ? "eoa" : "smart";
|
|
4098
4174
|
}
|
|
4099
4175
|
async function readYieldseekerWalletStatus(client, wallet, owner, asset, blockNumber) {
|
|
4100
|
-
const agentWallet =
|
|
4101
|
-
const expectedOwner =
|
|
4102
|
-
const expectedAsset =
|
|
4176
|
+
const agentWallet = getAddress3(wallet);
|
|
4177
|
+
const expectedOwner = getAddress3(owner);
|
|
4178
|
+
const expectedAsset = getAddress3(asset);
|
|
4103
4179
|
const [code, ownerCode, slot, actualOwner, index, actualAsset, actualFactory, latest] = await Promise.all([
|
|
4104
4180
|
client.getBytecode({ address: agentWallet, blockNumber }),
|
|
4105
4181
|
client.getBytecode({ address: expectedOwner, blockNumber }),
|
|
@@ -4113,7 +4189,7 @@ async function readYieldseekerWalletStatus(client, wallet, owner, asset, blockNu
|
|
|
4113
4189
|
if (!code || code === "0x" || !slot || /^0x0+$/.test(slot)) {
|
|
4114
4190
|
throw new Error("Yieldseeker wallet is not a deployed ERC1967 proxy");
|
|
4115
4191
|
}
|
|
4116
|
-
const implementation =
|
|
4192
|
+
const implementation = getAddress3(`0x${slot.slice(-40)}`);
|
|
4117
4193
|
const mapped = await client.readContract({
|
|
4118
4194
|
address: YIELDSEEKER_FACTORY,
|
|
4119
4195
|
abi: factoryAbi,
|
|
@@ -4140,7 +4216,7 @@ var YIELDSEEKER_UPGRADE_ABI = walletAbi;
|
|
|
4140
4216
|
import {
|
|
4141
4217
|
createWalletClient as createWalletClient2,
|
|
4142
4218
|
custom as custom2,
|
|
4143
|
-
getAddress as
|
|
4219
|
+
getAddress as getAddress4,
|
|
4144
4220
|
toHex
|
|
4145
4221
|
} from "viem";
|
|
4146
4222
|
import { getUserOperationHash as getUserOperationHash2 } from "viem/account-abstraction";
|
|
@@ -4649,7 +4725,7 @@ async function submitSmart(input) {
|
|
|
4649
4725
|
);
|
|
4650
4726
|
}
|
|
4651
4727
|
async function submitYieldseekerSponsoredWithdrawal(input) {
|
|
4652
|
-
const owner =
|
|
4728
|
+
const owner = getAddress4(input.state.walletAddress);
|
|
4653
4729
|
const { intent, rpcUrl } = await requestIntent({
|
|
4654
4730
|
apiKey: input.apiKey,
|
|
4655
4731
|
routingApiBaseUrl: input.routingApiBaseUrl,
|
|
@@ -4667,7 +4743,7 @@ async function submitYieldseekerSponsoredWithdrawal(input) {
|
|
|
4667
4743
|
return intent.ownerPath === "eoa" ? submitEoa(args) : submitSmart(args);
|
|
4668
4744
|
}
|
|
4669
4745
|
async function submitYieldseekerSponsoredUpgrade(input) {
|
|
4670
|
-
const owner =
|
|
4746
|
+
const owner = getAddress4(input.state.walletAddress);
|
|
4671
4747
|
const { intent, rpcUrl } = await requestIntent({
|
|
4672
4748
|
apiKey: input.apiKey,
|
|
4673
4749
|
routingApiBaseUrl: input.routingApiBaseUrl,
|
|
@@ -4784,6 +4860,8 @@ var YieldseekerAgent = class {
|
|
|
4784
4860
|
transactionExecutor;
|
|
4785
4861
|
unwindReceiptWaiter;
|
|
4786
4862
|
agentContexts = /* @__PURE__ */ new Map();
|
|
4863
|
+
balanceContexts = /* @__PURE__ */ new WeakMap();
|
|
4864
|
+
balanceVaults = /* @__PURE__ */ new Map();
|
|
4787
4865
|
users = /* @__PURE__ */ new Map();
|
|
4788
4866
|
pendingAgents = /* @__PURE__ */ new Map();
|
|
4789
4867
|
pendingWalletContexts = /* @__PURE__ */ new Map();
|
|
@@ -4829,8 +4907,8 @@ var YieldseekerAgent = class {
|
|
|
4829
4907
|
if (useCachedV2 && cached && Date.now() - cached.at < 15 * 6e4) return { ...cached.status };
|
|
4830
4908
|
const status = await readYieldseekerWalletStatus(
|
|
4831
4909
|
this.getReceiptClient(),
|
|
4832
|
-
|
|
4833
|
-
|
|
4910
|
+
getAddress5(context.wallet.walletAddress),
|
|
4911
|
+
getAddress5(state.walletAddress),
|
|
4834
4912
|
YIELDSEEKER_ASSET_METADATA[asset].address
|
|
4835
4913
|
);
|
|
4836
4914
|
this.rememberWalletStatus(key2, status);
|
|
@@ -5026,7 +5104,7 @@ var YieldseekerAgent = class {
|
|
|
5026
5104
|
}
|
|
5027
5105
|
} else {
|
|
5028
5106
|
txHash = await this.submitTransaction(state, chainId, {
|
|
5029
|
-
from:
|
|
5107
|
+
from: getAddress5(state.walletAddress),
|
|
5030
5108
|
to: before.agentWallet,
|
|
5031
5109
|
data,
|
|
5032
5110
|
value: "0",
|
|
@@ -5049,6 +5127,7 @@ var YieldseekerAgent = class {
|
|
|
5049
5127
|
}
|
|
5050
5128
|
this.users.clear();
|
|
5051
5129
|
this.agentContexts.clear();
|
|
5130
|
+
this.balanceVaults.clear();
|
|
5052
5131
|
this.pendingAgents.clear();
|
|
5053
5132
|
this.pendingWalletContexts.clear();
|
|
5054
5133
|
this.readCache.clear();
|
|
@@ -5112,12 +5191,12 @@ var YieldseekerAgent = class {
|
|
|
5112
5191
|
} else {
|
|
5113
5192
|
try {
|
|
5114
5193
|
txHash = await this.submitTransaction(state, chainId, {
|
|
5115
|
-
from:
|
|
5194
|
+
from: getAddress5(state.walletAddress),
|
|
5116
5195
|
to: YIELDSEEKER_ASSET_METADATA[asset].address,
|
|
5117
5196
|
data: encodeFunctionData({
|
|
5118
|
-
abi:
|
|
5197
|
+
abi: erc20Abi4,
|
|
5119
5198
|
functionName: "transfer",
|
|
5120
|
-
args: [
|
|
5199
|
+
args: [getAddress5(context.wallet.walletAddress), BigInt(amount)]
|
|
5121
5200
|
}),
|
|
5122
5201
|
value: "0",
|
|
5123
5202
|
chainId
|
|
@@ -5251,7 +5330,7 @@ var YieldseekerAgent = class {
|
|
|
5251
5330
|
);
|
|
5252
5331
|
const positionsRead = this.readWithdrawalPositions(state, chainId, context);
|
|
5253
5332
|
const metadata = YIELDSEEKER_ASSET_METADATA[asset];
|
|
5254
|
-
const agentWallet =
|
|
5333
|
+
const agentWallet = getAddress5(context.wallet.walletAddress);
|
|
5255
5334
|
const readOwnerFunds = async (blockNumber) => {
|
|
5256
5335
|
const feeTracker = await withPaidRpcDiagnostics(() => this.getReceiptClient().readContract({
|
|
5257
5336
|
address: agentWallet,
|
|
@@ -5265,13 +5344,13 @@ var YieldseekerAgent = class {
|
|
|
5265
5344
|
const [idle2, fees] = await Promise.all([
|
|
5266
5345
|
withPaidRpcDiagnostics(() => this.getReceiptClient().readContract({
|
|
5267
5346
|
address: metadata.address,
|
|
5268
|
-
abi:
|
|
5347
|
+
abi: erc20Abi4,
|
|
5269
5348
|
functionName: "balanceOf",
|
|
5270
5349
|
args: [agentWallet],
|
|
5271
5350
|
blockNumber
|
|
5272
5351
|
}), chainId, "eth_call", this.id),
|
|
5273
5352
|
withPaidRpcDiagnostics(() => this.getReceiptClient().readContract({
|
|
5274
|
-
address:
|
|
5353
|
+
address: getAddress5(feeTracker),
|
|
5275
5354
|
abi: YIELDSEEKER_FEE_TRACKER_ABI,
|
|
5276
5355
|
functionName: "getFeesOwed",
|
|
5277
5356
|
args: [agentWallet],
|
|
@@ -5313,7 +5392,7 @@ var YieldseekerAgent = class {
|
|
|
5313
5392
|
let active = true;
|
|
5314
5393
|
const checks = this.readVaultLiquidity(values.map((position2) => position2.yieldOption), agentWallet, blockNumber).catch(() => []);
|
|
5315
5394
|
const reads = values.map(async (position2, index) => {
|
|
5316
|
-
const address =
|
|
5395
|
+
const address = getAddress5(position2.yieldOption.address);
|
|
5317
5396
|
try {
|
|
5318
5397
|
const group = (await checks).slice(index * 3, index * 3 + 3);
|
|
5319
5398
|
if (!active || group.length !== 3 || group.some((value) => value.status !== "success")) return null;
|
|
@@ -5327,7 +5406,7 @@ var YieldseekerAgent = class {
|
|
|
5327
5406
|
try {
|
|
5328
5407
|
const value = await this.getReceiptClient().readContract({
|
|
5329
5408
|
address,
|
|
5330
|
-
abi:
|
|
5409
|
+
abi: erc4626Abi2,
|
|
5331
5410
|
functionName,
|
|
5332
5411
|
args: [shares],
|
|
5333
5412
|
blockNumber
|
|
@@ -5540,7 +5619,7 @@ var YieldseekerAgent = class {
|
|
|
5540
5619
|
delta: maxSettlementBasis.delta - payout,
|
|
5541
5620
|
expectedNetDeposits: maxSettlementBasis.expectedNetDeposits - payout
|
|
5542
5621
|
} : this.snapshotMovement(state, chainId, context, -payout);
|
|
5543
|
-
const account =
|
|
5622
|
+
const account = getAddress5(state.walletAddress);
|
|
5544
5623
|
let receipt;
|
|
5545
5624
|
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" };
|
|
5546
5625
|
const data = amount === void 0 ? encodeFunctionData({
|
|
@@ -5563,7 +5642,7 @@ var YieldseekerAgent = class {
|
|
|
5563
5642
|
refreshYieldseekerSignature: (rejected) => this.auth.refreshToken(state, chainId, rejected),
|
|
5564
5643
|
userId: context.user.userId,
|
|
5565
5644
|
agentId: context.agent.agentId,
|
|
5566
|
-
agentWallet:
|
|
5645
|
+
agentWallet: getAddress5(context.wallet.walletAddress),
|
|
5567
5646
|
asset: metadata.address,
|
|
5568
5647
|
callData: data,
|
|
5569
5648
|
onPending: (pending) => notifyFunding(onProgress, { ...base6, ...pending }),
|
|
@@ -5578,7 +5657,7 @@ var YieldseekerAgent = class {
|
|
|
5578
5657
|
onOwnerTransferAttempted?.();
|
|
5579
5658
|
txHash = await this.submitTransaction(state, chainId, {
|
|
5580
5659
|
from: account,
|
|
5581
|
-
to:
|
|
5660
|
+
to: getAddress5(context.wallet.walletAddress),
|
|
5582
5661
|
data,
|
|
5583
5662
|
value: "0",
|
|
5584
5663
|
chainId
|
|
@@ -5686,17 +5765,17 @@ var YieldseekerAgent = class {
|
|
|
5686
5765
|
return proof.available;
|
|
5687
5766
|
}
|
|
5688
5767
|
async readVaultLiquidity(options, wallet, blockNumber) {
|
|
5689
|
-
const owner =
|
|
5768
|
+
const owner = getAddress5(wallet);
|
|
5690
5769
|
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));
|
|
5691
5770
|
const results = await Promise.all(batches.map((batch) => this.getReceiptClient().multicall({
|
|
5692
5771
|
blockNumber,
|
|
5693
5772
|
allowFailure: true,
|
|
5694
5773
|
contracts: batch.flatMap((option) => {
|
|
5695
|
-
const address =
|
|
5774
|
+
const address = getAddress5(option.address);
|
|
5696
5775
|
return [
|
|
5697
|
-
{ address, abi:
|
|
5698
|
-
{ address, abi:
|
|
5699
|
-
{ address, abi:
|
|
5776
|
+
{ address, abi: erc4626Abi2, functionName: "asset" },
|
|
5777
|
+
{ address, abi: erc20Abi4, functionName: "balanceOf", args: [owner] },
|
|
5778
|
+
{ address, abi: erc4626Abi2, functionName: "maxWithdraw", args: [owner] }
|
|
5700
5779
|
];
|
|
5701
5780
|
})
|
|
5702
5781
|
})));
|
|
@@ -5772,7 +5851,7 @@ var YieldseekerAgent = class {
|
|
|
5772
5851
|
const read2 = async () => {
|
|
5773
5852
|
const client = this.getReceiptClient();
|
|
5774
5853
|
const blockNumber = await client.getBlockNumber({ cacheTime: 0 });
|
|
5775
|
-
const wallet =
|
|
5854
|
+
const wallet = getAddress5(context.wallet.walletAddress);
|
|
5776
5855
|
assertReadCurrent();
|
|
5777
5856
|
if (typeof blockNumber !== "bigint") throw unavailable();
|
|
5778
5857
|
const indexedPositions = this.validateWithdrawalPositions(positions ?? [], chainId, context.asset);
|
|
@@ -5786,7 +5865,7 @@ var YieldseekerAgent = class {
|
|
|
5786
5865
|
this.readVaultLiquidity(options, wallet, blockNumber),
|
|
5787
5866
|
client.readContract({
|
|
5788
5867
|
address: metadata.address,
|
|
5789
|
-
abi:
|
|
5868
|
+
abi: erc20Abi4,
|
|
5790
5869
|
functionName: "balanceOf",
|
|
5791
5870
|
args: [wallet],
|
|
5792
5871
|
blockNumber
|
|
@@ -5801,7 +5880,7 @@ var YieldseekerAgent = class {
|
|
|
5801
5880
|
if (typeof idle !== "bigint" || idle < 0n || !isAddress3(feeTracker) || /^0x0{40}$/i.test(feeTracker)) throw unavailable();
|
|
5802
5881
|
assertReadCurrent();
|
|
5803
5882
|
const fees = await client.readContract({
|
|
5804
|
-
address:
|
|
5883
|
+
address: getAddress5(feeTracker),
|
|
5805
5884
|
abi: YIELDSEEKER_FEE_TRACKER_ABI,
|
|
5806
5885
|
functionName: "getFeesOwed",
|
|
5807
5886
|
args: [wallet],
|
|
@@ -5812,9 +5891,15 @@ var YieldseekerAgent = class {
|
|
|
5812
5891
|
const verifiedVaults = [];
|
|
5813
5892
|
let deployed = 0n;
|
|
5814
5893
|
const collect = (options2, results) => {
|
|
5894
|
+
assertReadCurrent();
|
|
5895
|
+
const known = this.balanceVaults.get(contextKey) ?? /* @__PURE__ */ new Set();
|
|
5896
|
+
this.balanceVaults.set(contextKey, known);
|
|
5815
5897
|
let valid2 = true;
|
|
5816
5898
|
options2.forEach((option, index) => {
|
|
5817
5899
|
const group = results.slice(index * 3, index * 3 + 3);
|
|
5900
|
+
const shareProbe = group[1];
|
|
5901
|
+
if (shareProbe?.status === "success" && typeof shareProbe.result === "bigint" && shareProbe.result > 0n)
|
|
5902
|
+
known.add(option.address.toLowerCase());
|
|
5818
5903
|
if (group.length !== 3 || group.some((value) => value.status !== "success")) {
|
|
5819
5904
|
valid2 = false;
|
|
5820
5905
|
return;
|
|
@@ -5893,7 +5978,59 @@ var YieldseekerAgent = class {
|
|
|
5893
5978
|
async getBalances(state, chainId, asset) {
|
|
5894
5979
|
this.assertChain(chainId);
|
|
5895
5980
|
if (asset !== void 0) this.assertAsset(asset);
|
|
5896
|
-
|
|
5981
|
+
const contexts = await this.loadPortfolio(state, chainId, { asset, allowMissingPositions: true });
|
|
5982
|
+
const balance = mapYieldseekerBalances(contexts);
|
|
5983
|
+
for (const context of contexts) {
|
|
5984
|
+
const read2 = balance.readMetadata.find((item) => item.asset === context.asset);
|
|
5985
|
+
this.balanceContexts.set(read2, { context, generation: this.readGeneration });
|
|
5986
|
+
const key2 = this.contextKey(state, chainId, context.asset);
|
|
5987
|
+
const known = this.balanceVaults.get(key2) ?? /* @__PURE__ */ new Set();
|
|
5988
|
+
for (const position2 of context.positions) known.add(position2.yieldOption.address.toLowerCase());
|
|
5989
|
+
this.balanceVaults.set(key2, known);
|
|
5990
|
+
}
|
|
5991
|
+
return balance;
|
|
5992
|
+
}
|
|
5993
|
+
async verifyWithdrawalBalance(state, evidence, balance) {
|
|
5994
|
+
this.assertAsset(evidence.token);
|
|
5995
|
+
this.assertChain(evidence.chainId);
|
|
5996
|
+
const read2 = balance.readMetadata?.find((item) => item.chainId === evidence.chainId && item.asset === evidence.token);
|
|
5997
|
+
const cached = read2 && this.balanceContexts.get(read2);
|
|
5998
|
+
const context = cached?.generation === this.readGeneration ? cached.context : void 0;
|
|
5999
|
+
if (!context || context.positionsUnavailable || !read2 || !evidence.blockNumber || !evidence.txHash || context.wallet.walletAddress.toLowerCase() !== evidence.agentWallet?.toLowerCase()) return void 0;
|
|
6000
|
+
const key2 = this.contextKey(state, evidence.chainId, evidence.token);
|
|
6001
|
+
const generation = this.readGeneration, version = this.portfolioVersion(key2);
|
|
6002
|
+
if (read2.readVersion !== version) return void 0;
|
|
6003
|
+
const wallet = getAddress5(context.wallet.walletAddress);
|
|
6004
|
+
const asset = YIELDSEEKER_ASSET_METADATA[evidence.token];
|
|
6005
|
+
const client = this.getReceiptClient();
|
|
6006
|
+
const blockNumber = await client.getBlockNumber({ cacheTime: 0 });
|
|
6007
|
+
if (blockNumber < BigInt(evidence.blockNumber)) return void 0;
|
|
6008
|
+
const vaults = [...this.balanceVaults.get(key2) ?? []];
|
|
6009
|
+
const [invested, idle, tracker] = await Promise.all([
|
|
6010
|
+
remainingVaultBalance(client, wallet, asset.address, vaults, blockNumber),
|
|
6011
|
+
client.readContract({ address: asset.address, abi: erc20Abi4, functionName: "balanceOf", args: [wallet], blockNumber }),
|
|
6012
|
+
client.readContract({ address: wallet, abi: YIELDSEEKER_AGENT_WALLET_ABI, functionName: "feeTracker", blockNumber })
|
|
6013
|
+
]);
|
|
6014
|
+
if (invested === void 0 || typeof idle !== "bigint" || idle < 0n || !isAddress3(tracker) || /^0x0{40}$/i.test(tracker)) return void 0;
|
|
6015
|
+
const fees = await client.readContract({
|
|
6016
|
+
address: tracker,
|
|
6017
|
+
abi: YIELDSEEKER_FEE_TRACKER_ABI,
|
|
6018
|
+
functionName: "getFeesOwed",
|
|
6019
|
+
args: [wallet],
|
|
6020
|
+
blockNumber
|
|
6021
|
+
});
|
|
6022
|
+
this.assertSession(generation, evidence.chainId, evidence.token);
|
|
6023
|
+
if (version !== this.portfolioVersion(key2) || typeof fees !== "bigint" || fees < 0n) return void 0;
|
|
6024
|
+
const total = idle + invested > fees ? idle + invested - fees : 0n;
|
|
6025
|
+
const displayed = balance.assetBalances?.find((item) => item.chainId === evidence.chainId && item.asset === evidence.token);
|
|
6026
|
+
if (!displayed || !evidence.confirmedAmount || !/^\d+$/.test(evidence.confirmedAmount)) return void 0;
|
|
6027
|
+
const amount = parseUnits(displayed.amount, asset.decimals);
|
|
6028
|
+
if (amount < 0n) return void 0;
|
|
6029
|
+
const displayUnit = evidence.token === "USDC" ? 5000n : 500000000000n;
|
|
6030
|
+
const movementUnit = BigInt(evidence.confirmedAmount) / 1000n;
|
|
6031
|
+
const tolerance = movementUnit < displayUnit ? movementUnit : displayUnit;
|
|
6032
|
+
if ((total > amount ? total - amount : amount - total) > tolerance) return void 0;
|
|
6033
|
+
return { ...read2, withdrawalCheck: { txHash: evidence.txHash, blockNumber: blockNumber.toString() } };
|
|
5897
6034
|
}
|
|
5898
6035
|
invalidateFundingRead(state, chainId, asset, refreshUntil = Date.now() + YIELDSEEKER_SETTLEMENT_WINDOW_MS) {
|
|
5899
6036
|
this.assertAsset(asset);
|
|
@@ -5933,9 +6070,9 @@ var YieldseekerAgent = class {
|
|
|
5933
6070
|
if (!context) return void 0;
|
|
5934
6071
|
const idle = await withPaidRpcDiagnostics(() => this.getReceiptClient().readContract({
|
|
5935
6072
|
address: YIELDSEEKER_ASSET_METADATA[asset].address,
|
|
5936
|
-
abi:
|
|
6073
|
+
abi: erc20Abi4,
|
|
5937
6074
|
functionName: "balanceOf",
|
|
5938
|
-
args: [
|
|
6075
|
+
args: [getAddress5(context.wallet.walletAddress)]
|
|
5939
6076
|
}), chainId, "eth_call", this.id);
|
|
5940
6077
|
this.assertSession(generation, chainId, asset);
|
|
5941
6078
|
if (typeof idle !== "bigint" || idle < 0n) throw this.invalidResponse("wallet deposit balance");
|
|
@@ -6047,11 +6184,13 @@ var YieldseekerAgent = class {
|
|
|
6047
6184
|
const pending = this.pendingReads.get(key2);
|
|
6048
6185
|
if (pending) return pending;
|
|
6049
6186
|
const generation = this.readGeneration;
|
|
6187
|
+
const requestedAt = Date.now();
|
|
6050
6188
|
const request = Promise.resolve().then(read2).then((value) => {
|
|
6051
6189
|
if (this.readGeneration === generation && this.pendingReads.get(key2) === request) {
|
|
6052
6190
|
this.readCache.set(key2, {
|
|
6053
6191
|
expiresAt: Date.now() + ttlMs,
|
|
6054
6192
|
fetchedAt: Date.now(),
|
|
6193
|
+
requestedAt,
|
|
6055
6194
|
value
|
|
6056
6195
|
});
|
|
6057
6196
|
}
|
|
@@ -6128,7 +6267,7 @@ var YieldseekerAgent = class {
|
|
|
6128
6267
|
this.users.set(key2, persisted);
|
|
6129
6268
|
return persisted;
|
|
6130
6269
|
}
|
|
6131
|
-
const walletAddress =
|
|
6270
|
+
const walletAddress = getAddress5(state.walletAddress);
|
|
6132
6271
|
const generation = this.readGeneration;
|
|
6133
6272
|
let user = null;
|
|
6134
6273
|
try {
|
|
@@ -6420,6 +6559,7 @@ var YieldseekerAgent = class {
|
|
|
6420
6559
|
...context,
|
|
6421
6560
|
snapshot: snapshot.agentSnapshot,
|
|
6422
6561
|
fetchedAt: this.readCache.get(`snapshot:${contextKey}`)?.fetchedAt,
|
|
6562
|
+
requestedAt: this.readCache.get(`snapshot:${contextKey}`)?.requestedAt,
|
|
6423
6563
|
readVersion: version,
|
|
6424
6564
|
positionsUnavailable,
|
|
6425
6565
|
...portfolioParts
|
|
@@ -6619,7 +6759,7 @@ var YieldseekerAgent = class {
|
|
|
6619
6759
|
return hash2;
|
|
6620
6760
|
}
|
|
6621
6761
|
this.assertTransaction(transaction, state, chainId);
|
|
6622
|
-
const account =
|
|
6762
|
+
const account = getAddress5(state.walletAddress);
|
|
6623
6763
|
const walletClient = createWalletClient3({
|
|
6624
6764
|
account,
|
|
6625
6765
|
chain: base4,
|
|
@@ -6637,7 +6777,7 @@ var YieldseekerAgent = class {
|
|
|
6637
6777
|
const hash = await walletClient.sendTransaction({
|
|
6638
6778
|
account,
|
|
6639
6779
|
chain: base4,
|
|
6640
|
-
to:
|
|
6780
|
+
to: getAddress5(transaction.to),
|
|
6641
6781
|
data: transaction.data,
|
|
6642
6782
|
value: BigInt(transaction.value)
|
|
6643
6783
|
});
|
|
@@ -6741,7 +6881,7 @@ var YieldseekerAgent = class {
|
|
|
6741
6881
|
return receipt;
|
|
6742
6882
|
}
|
|
6743
6883
|
assertTransaction(transaction, state, chainId) {
|
|
6744
|
-
if (!transaction || typeof transaction.from !== "string" || !isAddress3(transaction.from) || typeof transaction.to !== "string" || !isAddress3(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 ||
|
|
6884
|
+
if (!transaction || typeof transaction.from !== "string" || !isAddress3(transaction.from) || typeof transaction.to !== "string" || !isAddress3(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 || getAddress5(transaction.from) !== getAddress5(state.walletAddress)) {
|
|
6745
6885
|
throw this.invalidResponse("transaction");
|
|
6746
6886
|
}
|
|
6747
6887
|
}
|
|
@@ -6900,7 +7040,7 @@ async function withFailureReporting(apiKey, agentType, fn, baseUrl) {
|
|
|
6900
7040
|
}
|
|
6901
7041
|
|
|
6902
7042
|
// src/lib/helpers/withdraw-helper.ts
|
|
6903
|
-
import { parseUnits } from "viem";
|
|
7043
|
+
import { parseUnits as parseUnits2 } from "viem";
|
|
6904
7044
|
function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decimals) {
|
|
6905
7045
|
const target = asset.toUpperCase();
|
|
6906
7046
|
return agents.map((agent) => {
|
|
@@ -6908,7 +7048,7 @@ function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decima
|
|
|
6908
7048
|
const tokenBalance = agentBalance?.tokens.find(
|
|
6909
7049
|
(t) => t.chainId === chainId && t.asset.toUpperCase() === target
|
|
6910
7050
|
);
|
|
6911
|
-
let balance = tokenBalance ?
|
|
7051
|
+
let balance = tokenBalance ? parseUnits2(tokenBalance.amount, decimals) : 0n;
|
|
6912
7052
|
if (agent.balanceComposition === "tokens-plus-positions") {
|
|
6913
7053
|
const chainNameById = {
|
|
6914
7054
|
1: "ETHEREUM",
|
|
@@ -6920,14 +7060,14 @@ function projectAgentBalancesForAsset(agents, aggregated, chainId, asset, decima
|
|
|
6920
7060
|
const positionChain = position2.chain.trim().toUpperCase();
|
|
6921
7061
|
const matchesChain = positionChain === String(chainId) || targetChain !== void 0 && positionChain === targetChain;
|
|
6922
7062
|
if (!matchesChain || position2.asset.toUpperCase() !== target) continue;
|
|
6923
|
-
balance += position2.withdrawableAmountRaw !== void 0 ? BigInt(position2.withdrawableAmountRaw) :
|
|
7063
|
+
balance += position2.withdrawableAmountRaw !== void 0 ? BigInt(position2.withdrawableAmountRaw) : parseUnits2(position2.amount, decimals);
|
|
6924
7064
|
}
|
|
6925
7065
|
}
|
|
6926
7066
|
const assetTotal = agentBalance?.assetBalances?.find(
|
|
6927
7067
|
(t) => t.chainId === chainId && t.asset.toUpperCase() === target
|
|
6928
7068
|
);
|
|
6929
7069
|
if (assetTotal) {
|
|
6930
|
-
const total =
|
|
7070
|
+
const total = parseUnits2(assetTotal.amount, decimals);
|
|
6931
7071
|
if (total < balance) balance = total > 0n ? total : 0n;
|
|
6932
7072
|
}
|
|
6933
7073
|
return { agent, balance };
|
|
@@ -7087,7 +7227,7 @@ function aggregateApyByChainAndAsset(agentApys, agentBalances) {
|
|
|
7087
7227
|
|
|
7088
7228
|
// src/client.ts
|
|
7089
7229
|
import {
|
|
7090
|
-
parseUnits as
|
|
7230
|
+
parseUnits as parseUnits3,
|
|
7091
7231
|
createPublicClient as createPublicClient4,
|
|
7092
7232
|
createWalletClient as createWalletClient4,
|
|
7093
7233
|
custom as custom4
|
|
@@ -7247,7 +7387,40 @@ async function execute(i, key2, plan) {
|
|
|
7247
7387
|
const send = async (initial) => {
|
|
7248
7388
|
let body = initial;
|
|
7249
7389
|
save(key2, body);
|
|
7390
|
+
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);
|
|
7250
7391
|
try {
|
|
7392
|
+
const post = () => postSponsorBatchTransfer({ apiKey: i.apiKey, baseUrl: i.baseUrl, body });
|
|
7393
|
+
const pendingError = (phase, txHash) => new OwneyError(
|
|
7394
|
+
"DEPOSIT_IN_PROGRESS",
|
|
7395
|
+
phase === "approval" ? "Deposit approval is awaiting confirmation. Retry the same amount to continue it." : "Deposit is awaiting confirmation. Its transaction is still being checked.",
|
|
7396
|
+
{ sponsorPending: true, phase, txHash, safeToFallback: false }
|
|
7397
|
+
);
|
|
7398
|
+
const assertReceipt = (receipt, phase) => {
|
|
7399
|
+
if (receipt.status !== "success") throw new OwneyError(
|
|
7400
|
+
"SPONSOR_REQUEST_FAILED",
|
|
7401
|
+
`Sponsored ${phase} transaction reverted. Please retry.`,
|
|
7402
|
+
{ notSubmitted: true, safeToFallback: false }
|
|
7403
|
+
);
|
|
7404
|
+
};
|
|
7405
|
+
const waitForConfirmation = async (phase, hash2) => {
|
|
7406
|
+
let receipt;
|
|
7407
|
+
try {
|
|
7408
|
+
receipt = await i.pub.waitForTransactionReceipt({ hash: hash2, confirmations: 1, timeout: 9e4, checkReplacement: false });
|
|
7409
|
+
} catch {
|
|
7410
|
+
receipt = await i.pub.getTransactionReceipt({ hash: hash2 }).catch(() => void 0);
|
|
7411
|
+
}
|
|
7412
|
+
if (!receipt) throw pendingError(phase, hash2);
|
|
7413
|
+
assertReceipt(receipt, phase);
|
|
7414
|
+
};
|
|
7415
|
+
const postSigned = async (phase, hash2) => {
|
|
7416
|
+
try {
|
|
7417
|
+
return await post();
|
|
7418
|
+
} catch (error) {
|
|
7419
|
+
if (rejectedPreparation(error) || error instanceof OwneyError && error.details?.notSubmitted === true) throw error;
|
|
7420
|
+
await waitForConfirmation(phase, hash2);
|
|
7421
|
+
return void 0;
|
|
7422
|
+
}
|
|
7423
|
+
};
|
|
7251
7424
|
if (body.erc2612Permit && !body.serializedPermitTransaction) {
|
|
7252
7425
|
const preparedPermit = await postSponsorBatchTransfer({
|
|
7253
7426
|
apiKey: i.apiKey,
|
|
@@ -7265,11 +7438,17 @@ async function execute(i, key2, plan) {
|
|
|
7265
7438
|
save(key2, body);
|
|
7266
7439
|
}
|
|
7267
7440
|
if (!body.serializedTransaction) {
|
|
7268
|
-
const
|
|
7269
|
-
|
|
7270
|
-
|
|
7271
|
-
|
|
7272
|
-
|
|
7441
|
+
const permitHash = body.serializedPermitTransaction ? keccak256(body.serializedPermitTransaction) : void 0;
|
|
7442
|
+
let prepared = permitHash ? await postSigned("approval", permitHash) : await post();
|
|
7443
|
+
if (prepared?.status === "pending") {
|
|
7444
|
+
if (!permitHash || prepared.phase !== "approval" || prepared.txHash !== permitHash)
|
|
7445
|
+
throw new Error("Sponsorship approval does not match the pending transaction.");
|
|
7446
|
+
await waitForConfirmation("approval", permitHash);
|
|
7447
|
+
prepared = void 0;
|
|
7448
|
+
}
|
|
7449
|
+
if (!prepared) prepared = await post();
|
|
7450
|
+
if (prepared.status === "pending" && permitHash && prepared.phase === "approval" && prepared.txHash === permitHash)
|
|
7451
|
+
throw pendingError("approval", permitHash);
|
|
7273
7452
|
if (!prepared.serializedTransaction || keccak256(prepared.serializedTransaction) !== prepared.txHash)
|
|
7274
7453
|
throw new Error(
|
|
7275
7454
|
"Sponsorship API did not return a valid prepared transaction."
|
|
@@ -7284,19 +7463,30 @@ async function execute(i, key2, plan) {
|
|
|
7284
7463
|
i.onSubmitted?.(keccak256(body.serializedTransaction));
|
|
7285
7464
|
} catch {
|
|
7286
7465
|
}
|
|
7287
|
-
const
|
|
7288
|
-
|
|
7289
|
-
|
|
7290
|
-
|
|
7291
|
-
|
|
7292
|
-
|
|
7293
|
-
|
|
7294
|
-
|
|
7295
|
-
|
|
7466
|
+
const hash = keccak256(body.serializedTransaction);
|
|
7467
|
+
const existing = await i.pub.getTransactionReceipt({ hash }).catch(() => void 0);
|
|
7468
|
+
if (existing) {
|
|
7469
|
+
assertReceipt(existing, "deposit");
|
|
7470
|
+
void post().catch(() => void 0);
|
|
7471
|
+
clear(key2);
|
|
7472
|
+
return hash;
|
|
7473
|
+
}
|
|
7474
|
+
let result = await postSigned("deposit", hash);
|
|
7475
|
+
if (result?.status === "pending" && result.phase === "approval" && body.serializedPermitTransaction && result.txHash === keccak256(body.serializedPermitTransaction)) {
|
|
7476
|
+
await waitForConfirmation("approval", result.txHash);
|
|
7477
|
+
result = await postSigned("deposit", hash);
|
|
7478
|
+
if (result?.status === "pending" && result.phase === "approval" && result.txHash === keccak256(body.serializedPermitTransaction)) throw pendingError("approval", result.txHash);
|
|
7479
|
+
}
|
|
7480
|
+
if (result) {
|
|
7481
|
+
if (result.txHash !== hash || result.status === "pending" && result.phase !== "deposit")
|
|
7482
|
+
throw new Error("Sponsorship receipt does not match the pending transaction.");
|
|
7483
|
+
if (result.status === "pending") await waitForConfirmation("deposit", hash);
|
|
7484
|
+
}
|
|
7485
|
+
if (!result || result.status === "pending") void post().catch(() => void 0);
|
|
7296
7486
|
clear(key2);
|
|
7297
|
-
return
|
|
7487
|
+
return hash;
|
|
7298
7488
|
} catch (error) {
|
|
7299
|
-
if (!body.serializedTransaction || error instanceof OwneyError && error.details?.notSubmitted === true)
|
|
7489
|
+
if (!body.serializedTransaction && !body.serializedPermitTransaction || rejectedPreparation(error) || error instanceof OwneyError && error.details?.notSubmitted === true)
|
|
7300
7490
|
clear(key2);
|
|
7301
7491
|
throw error;
|
|
7302
7492
|
}
|
|
@@ -7502,7 +7692,7 @@ async function runAgentDepositBatch(chainId, legs, transfer) {
|
|
|
7502
7692
|
}
|
|
7503
7693
|
|
|
7504
7694
|
// src/lib/sponsored-calls-deposit.ts
|
|
7505
|
-
import { encodeFunctionData as encodeFunctionData2, erc20Abi as
|
|
7695
|
+
import { encodeFunctionData as encodeFunctionData2, erc20Abi as erc20Abi5, toHex as toHex2 } from "viem";
|
|
7506
7696
|
var DEFAULT_POLL_INTERVAL_MS = 1500;
|
|
7507
7697
|
var DEFAULT_MAX_POLLS = 30;
|
|
7508
7698
|
async function paymasterSupported(provider, owner, chainId) {
|
|
@@ -7548,7 +7738,7 @@ function makeSponsoredCallsCallback(deps) {
|
|
|
7548
7738
|
to: token,
|
|
7549
7739
|
value: "0x0",
|
|
7550
7740
|
data: encodeFunctionData2({
|
|
7551
|
-
abi:
|
|
7741
|
+
abi: erc20Abi5,
|
|
7552
7742
|
functionName: "transfer",
|
|
7553
7743
|
args: [transfer.to, BigInt(transfer.amount)]
|
|
7554
7744
|
})
|
|
@@ -7749,6 +7939,7 @@ var OwneySDK = class {
|
|
|
7749
7939
|
cachedSponsoredCallsCallbacks = /* @__PURE__ */ new Map();
|
|
7750
7940
|
agentReads = new AgentReads();
|
|
7751
7941
|
recoveredFundingReads = /* @__PURE__ */ new Set();
|
|
7942
|
+
fundingBalanceChecks = /* @__PURE__ */ new WeakMap();
|
|
7752
7943
|
activationChecks = /* @__PURE__ */ new Map();
|
|
7753
7944
|
readAgent(agent, method, fetch2, params = null) {
|
|
7754
7945
|
const key2 = JSON.stringify([
|
|
@@ -7794,6 +7985,7 @@ var OwneySDK = class {
|
|
|
7794
7985
|
}
|
|
7795
7986
|
this.agentReads.clearInFlight();
|
|
7796
7987
|
this.activationChecks.clear();
|
|
7988
|
+
this.fundingBalanceChecks = /* @__PURE__ */ new WeakMap();
|
|
7797
7989
|
this.state = { provider, walletAddress, chainId: null };
|
|
7798
7990
|
this.cachedSponsoredCallback = null;
|
|
7799
7991
|
this.cachedWethSponsoredCallback = null;
|
|
@@ -7805,6 +7997,7 @@ var OwneySDK = class {
|
|
|
7805
7997
|
*/
|
|
7806
7998
|
async disconnect() {
|
|
7807
7999
|
this.state = null;
|
|
8000
|
+
this.fundingBalanceChecks = /* @__PURE__ */ new WeakMap();
|
|
7808
8001
|
for (const agent of this.agents.values()) {
|
|
7809
8002
|
await agent.disconnect();
|
|
7810
8003
|
}
|
|
@@ -8705,9 +8898,8 @@ var OwneySDK = class {
|
|
|
8705
8898
|
verified = inspectFundingReceipt(receipt, { ...evidence, agentWallet, intendedAmount: "MAX" }, token.address, direction);
|
|
8706
8899
|
}
|
|
8707
8900
|
const key2 = `${state.walletAddress.toLowerCase()}:${chainId}:${evidence.agentId}:${evidence.token}:${evidence.txHash}`;
|
|
8708
|
-
if ((verified.transfer === "confirmed" || verified.transfer === "failed" && verified.confirmedAmount === "0") && !this.recoveredFundingReads.has(key2)) {
|
|
8709
|
-
|
|
8710
|
-
agent.invalidateFundingRead?.(state, chainId, evidence.token, options.balanceRefreshUntil);
|
|
8901
|
+
if (options.refreshBalance !== false && (verified.transfer === "confirmed" || verified.transfer === "failed" && verified.confirmedAmount === "0") && !this.recoveredFundingReads.has(key2)) {
|
|
8902
|
+
agent.invalidateFundingRead?.(state, chainId, evidence.token, options.balanceRefreshUntil);
|
|
8711
8903
|
this.recoveredFundingReads.add(key2);
|
|
8712
8904
|
if (this.recoveredFundingReads.size > 256) this.recoveredFundingReads.delete(this.recoveredFundingReads.values().next().value);
|
|
8713
8905
|
}
|
|
@@ -8815,6 +9007,44 @@ var OwneySDK = class {
|
|
|
8815
9007
|
assertCurrent();
|
|
8816
9008
|
return true;
|
|
8817
9009
|
}
|
|
9010
|
+
/** Optional post-payout display proof; receipt verification and the provider
|
|
9011
|
+
* adapter must agree before attaching it to this exact balance object. */
|
|
9012
|
+
async verifyWithdrawalBalance(evidence, balance) {
|
|
9013
|
+
const { state, chainId, assertCurrent } = this.captureReadScope(evidence.chainId);
|
|
9014
|
+
const agent = this.getAgent(evidence.agentId);
|
|
9015
|
+
if (!agent.verifyWithdrawalBalance || !evidence.txHash || state.walletAddress.toLowerCase() !== evidence.walletAddress.toLowerCase()) return balance;
|
|
9016
|
+
const key2 = `${state.walletAddress.toLowerCase()}:${chainId}:${evidence.agentId}:${evidence.token}:${evidence.txHash}:${evidence.intendedAmount}`;
|
|
9017
|
+
const checks = this.fundingBalanceChecks.get(balance) ?? /* @__PURE__ */ new Map();
|
|
9018
|
+
this.fundingBalanceChecks.set(balance, checks);
|
|
9019
|
+
const previous = checks.get(key2);
|
|
9020
|
+
if (previous) {
|
|
9021
|
+
const result2 = await previous;
|
|
9022
|
+
assertCurrent();
|
|
9023
|
+
return result2;
|
|
9024
|
+
}
|
|
9025
|
+
let timer;
|
|
9026
|
+
const read2 = async () => {
|
|
9027
|
+
const verified = await this.inspectFunding(evidence, "withdraw", { refreshBalance: false });
|
|
9028
|
+
assertCurrent();
|
|
9029
|
+
if (verified.transfer !== "confirmed" || verified.delivery !== "confirmed" || !verified.blockNumber) return balance;
|
|
9030
|
+
const metadata = await agent.verifyWithdrawalBalance(state, verified, balance);
|
|
9031
|
+
assertCurrent();
|
|
9032
|
+
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;
|
|
9033
|
+
return { ...balance, readMetadata: [
|
|
9034
|
+
...(balance.readMetadata ?? []).filter((item) => !(item.chainId === chainId && item.asset.toUpperCase() === evidence.token)),
|
|
9035
|
+
metadata
|
|
9036
|
+
] };
|
|
9037
|
+
};
|
|
9038
|
+
const pending = Promise.race([read2(), new Promise((resolve) => {
|
|
9039
|
+
timer = setTimeout(() => resolve(balance), 2e3);
|
|
9040
|
+
})]).catch(() => balance).finally(() => {
|
|
9041
|
+
if (timer) clearTimeout(timer);
|
|
9042
|
+
});
|
|
9043
|
+
checks.set(key2, pending);
|
|
9044
|
+
const result = await pending;
|
|
9045
|
+
assertCurrent();
|
|
9046
|
+
return result;
|
|
9047
|
+
}
|
|
8818
9048
|
/** A display acknowledgement controls polling only; it never confirms a financial outcome. */
|
|
8819
9049
|
endFundingBalanceRefresh(evidence, read2) {
|
|
8820
9050
|
const { state, chainId } = this.captureReadScope(evidence.chainId);
|
|
@@ -9083,7 +9313,7 @@ var OwneySDK = class {
|
|
|
9083
9313
|
if (this.isUserRejectedWithdrawal(originalFailure)) throw originalFailure;
|
|
9084
9314
|
if (entry.balance !== 0n && entry.agent.id !== "yieldseeker") {
|
|
9085
9315
|
const total = aggregated.agentBalances[entry.agent.id]?.assetBalances?.find((value) => value.chainId === chainId && value.asset.toUpperCase() === token);
|
|
9086
|
-
if (!total ||
|
|
9316
|
+
if (!total || parseUnits3(total.amount, assetInfo.decimals) <= entry.balance) return;
|
|
9087
9317
|
}
|
|
9088
9318
|
try {
|
|
9089
9319
|
const otherAvailable = indexedAvailable - entry.balance;
|
|
@@ -9858,7 +10088,7 @@ var OwneySDK = class {
|
|
|
9858
10088
|
};
|
|
9859
10089
|
|
|
9860
10090
|
// src/agents/zyfai/zyfai.siwx.ts
|
|
9861
|
-
import { getAddress as
|
|
10091
|
+
import { getAddress as getAddress6 } from "viem";
|
|
9862
10092
|
import { SiweMessage as SiweMessage2 } from "siwe";
|
|
9863
10093
|
import { ZyfaiSDK as ZyfaiSDK2 } from "@zyfai/sdk";
|
|
9864
10094
|
|
|
@@ -9985,7 +10215,7 @@ function buildSIWXConfig(deps) {
|
|
|
9985
10215
|
issuedAt,
|
|
9986
10216
|
toString() {
|
|
9987
10217
|
return new SiweMessage2({
|
|
9988
|
-
address:
|
|
10218
|
+
address: getAddress6(accountAddress),
|
|
9989
10219
|
chainId: numericChainId(chainId),
|
|
9990
10220
|
domain,
|
|
9991
10221
|
uri,
|