@owney/sdk 0.7.27-beta.0 → 0.7.27-beta.1
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 +105 -49
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +105 -49
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -5689,7 +5689,7 @@ var YieldseekerAgent = class {
|
|
|
5689
5689
|
const initialFunds = funds;
|
|
5690
5690
|
const idle = initialFunds.idle;
|
|
5691
5691
|
const maxLiquidity = amount === void 0 ? funds : void 0;
|
|
5692
|
-
let positions = [...funds.positions, ...funds.indexedPositions.filter((position2) => !funds.
|
|
5692
|
+
let positions = [...funds.positions, ...funds.indexedPositions.filter((position2) => !funds.resolvedVaults.includes(position2.yieldOption.address.toLowerCase()))];
|
|
5693
5693
|
let positionsStatus = "empty";
|
|
5694
5694
|
const validatePositions = (values) => this.validateWithdrawalPositions(values, chainId, asset);
|
|
5695
5695
|
validatePositions(positions);
|
|
@@ -5703,17 +5703,17 @@ var YieldseekerAgent = class {
|
|
|
5703
5703
|
const verifiedPositions = [];
|
|
5704
5704
|
if (timeoutMs <= 0) return { verified: false, positions: verifiedPositions };
|
|
5705
5705
|
let active = true;
|
|
5706
|
-
const checks = this.
|
|
5706
|
+
const checks = this.readVaultShares(values.map((position2) => position2.yieldOption), agentWallet, blockNumber).catch(() => []);
|
|
5707
5707
|
const reads = values.map(async (position2, index) => {
|
|
5708
5708
|
const address = (0, import_viem13.getAddress)(position2.yieldOption.address);
|
|
5709
5709
|
try {
|
|
5710
|
-
const group = (await checks).slice(index *
|
|
5711
|
-
if (!active || group.length !==
|
|
5710
|
+
const group = (await checks).slice(index * 2, index * 2 + 2);
|
|
5711
|
+
if (!active || group.length !== 2 || group.some((value) => value.status !== "success")) return null;
|
|
5712
5712
|
this.assertSession(generation, chainId, asset);
|
|
5713
|
-
const [underlying, shares
|
|
5714
|
-
if (typeof underlying !== "string" || !(0, import_viem13.isAddress)(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n
|
|
5715
|
-
const verified = { ...position2, assetsRaw: shares.toString(), withdrawableAssetsRaw:
|
|
5716
|
-
if (shares > 0n
|
|
5713
|
+
const [underlying, shares] = group.map((value) => value.result);
|
|
5714
|
+
if (typeof underlying !== "string" || !(0, import_viem13.isAddress)(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n) return null;
|
|
5715
|
+
const verified = { ...position2, assetsRaw: shares.toString(), withdrawableAssetsRaw: "0" };
|
|
5716
|
+
if (shares > 0n) {
|
|
5717
5717
|
let positiveValue = false;
|
|
5718
5718
|
const valuations = await Promise.all(["convertToAssets", "previewRedeem"].map(async (functionName) => {
|
|
5719
5719
|
try {
|
|
@@ -5724,9 +5724,11 @@ var YieldseekerAgent = class {
|
|
|
5724
5724
|
args: [shares],
|
|
5725
5725
|
blockNumber
|
|
5726
5726
|
});
|
|
5727
|
-
if (typeof value !== "bigint" || value < 0n) return null;
|
|
5727
|
+
if (!active || typeof value !== "bigint" || value < 0n) return null;
|
|
5728
|
+
this.assertSession(generation, chainId, asset);
|
|
5728
5729
|
if (value > 0n && !positiveValue) {
|
|
5729
5730
|
positiveValue = true;
|
|
5731
|
+
verified.withdrawableAssetsRaw = value.toString();
|
|
5730
5732
|
verifiedPositions.push(verified);
|
|
5731
5733
|
}
|
|
5732
5734
|
return value;
|
|
@@ -5734,7 +5736,12 @@ var YieldseekerAgent = class {
|
|
|
5734
5736
|
return null;
|
|
5735
5737
|
}
|
|
5736
5738
|
}));
|
|
5737
|
-
if (positiveValue)
|
|
5739
|
+
if (positiveValue) {
|
|
5740
|
+
const redemptionValue = valuations[1];
|
|
5741
|
+
if (redemptionValue !== null && redemptionValue > 0n)
|
|
5742
|
+
verified.withdrawableAssetsRaw = redemptionValue.toString();
|
|
5743
|
+
return verified;
|
|
5744
|
+
}
|
|
5738
5745
|
if (blockNumber === void 0 || valuations.some((value) => value !== 0n)) return null;
|
|
5739
5746
|
zeroValuePositions.add(verified);
|
|
5740
5747
|
}
|
|
@@ -5897,8 +5904,10 @@ var YieldseekerAgent = class {
|
|
|
5897
5904
|
this.assertSession(generation, chainId, asset);
|
|
5898
5905
|
if (proof.verified) {
|
|
5899
5906
|
positions = [...proof.positions, ...(catalog ?? []).filter((position2) => !knownBeforeRefresh.has(position2.yieldOption.address.toLowerCase()))];
|
|
5900
|
-
} else if (catalog)
|
|
5901
|
-
|
|
5907
|
+
} else if (catalog) {
|
|
5908
|
+
const checked = new Set(proof.positions.map((position2) => position2.yieldOption.address.toLowerCase()));
|
|
5909
|
+
positions = [...proof.positions, ...catalog.filter((position2) => !checked.has(position2.yieldOption.address.toLowerCase()))];
|
|
5910
|
+
} else {
|
|
5902
5911
|
positionsStatus = "unavailable";
|
|
5903
5912
|
break;
|
|
5904
5913
|
}
|
|
@@ -6082,7 +6091,7 @@ var YieldseekerAgent = class {
|
|
|
6082
6091
|
}
|
|
6083
6092
|
}
|
|
6084
6093
|
}
|
|
6085
|
-
/**
|
|
6094
|
+
/** Fresh position amounts for withdrawal planning, net of reserved fees. */
|
|
6086
6095
|
async getWithdrawableBalance(state, chainId, asset, minimumAmount) {
|
|
6087
6096
|
this.assertChain(chainId);
|
|
6088
6097
|
this.assertAsset(asset);
|
|
@@ -6107,7 +6116,7 @@ var YieldseekerAgent = class {
|
|
|
6107
6116
|
);
|
|
6108
6117
|
return proof.available;
|
|
6109
6118
|
}
|
|
6110
|
-
async
|
|
6119
|
+
async readVaultShares(options, wallet, blockNumber) {
|
|
6111
6120
|
const owner = (0, import_viem13.getAddress)(wallet);
|
|
6112
6121
|
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));
|
|
6113
6122
|
const results = await Promise.all(batches.map((batch) => this.getReceiptClient().multicall({
|
|
@@ -6117,8 +6126,7 @@ var YieldseekerAgent = class {
|
|
|
6117
6126
|
const address = (0, import_viem13.getAddress)(option.address);
|
|
6118
6127
|
return [
|
|
6119
6128
|
{ address, abi: import_viem13.erc4626Abi, functionName: "asset" },
|
|
6120
|
-
{ address, abi: import_viem13.erc20Abi, functionName: "balanceOf", args: [owner] }
|
|
6121
|
-
{ address, abi: import_viem13.erc4626Abi, functionName: "maxWithdraw", args: [owner] }
|
|
6129
|
+
{ address, abi: import_viem13.erc20Abi, functionName: "balanceOf", args: [owner] }
|
|
6122
6130
|
];
|
|
6123
6131
|
})
|
|
6124
6132
|
})));
|
|
@@ -6188,7 +6196,7 @@ var YieldseekerAgent = class {
|
|
|
6188
6196
|
);
|
|
6189
6197
|
let active = true;
|
|
6190
6198
|
let knownProof;
|
|
6191
|
-
const hasUnverifiedIndexedFunds = (proof) => proof.indexedPositions.some((position2) => !proof.
|
|
6199
|
+
const hasUnverifiedIndexedFunds = (proof) => proof.indexedPositions.some((position2) => !proof.resolvedVaults.includes(position2.yieldOption.address.toLowerCase()) && BigInt(position2.withdrawableAssetsRaw) > 0n);
|
|
6192
6200
|
const assertReadCurrent = () => {
|
|
6193
6201
|
this.assertSession(generation, chainId, context.asset);
|
|
6194
6202
|
if (!active || this.portfolioVersion(contextKey) !== version) throw unavailable();
|
|
@@ -6206,7 +6214,6 @@ var YieldseekerAgent = class {
|
|
|
6206
6214
|
for (const position2 of indexedPositions) candidates.set(position2.yieldOption.address.toLowerCase(), position2.yieldOption);
|
|
6207
6215
|
const options = [...candidates.values()];
|
|
6208
6216
|
if (options.length > YIELDSEEKER_WITHDRAWAL_CANDIDATE_LIMIT) throw unavailable();
|
|
6209
|
-
const checksRead = this.readVaultLiquidity(options, wallet, blockNumber).then((value) => ({ value }), (error) => ({ error }));
|
|
6210
6217
|
const [idle, feeTracker] = await Promise.all([
|
|
6211
6218
|
client.readContract({
|
|
6212
6219
|
address: metadata.address,
|
|
@@ -6233,7 +6240,7 @@ var YieldseekerAgent = class {
|
|
|
6233
6240
|
});
|
|
6234
6241
|
if (typeof fees !== "bigint" || fees < 0n) throw unavailable();
|
|
6235
6242
|
const verified = [];
|
|
6236
|
-
const
|
|
6243
|
+
const resolvedVaults = [];
|
|
6237
6244
|
let deployed = 0n;
|
|
6238
6245
|
const proof = (complete) => ({
|
|
6239
6246
|
blockNumber,
|
|
@@ -6241,51 +6248,100 @@ var YieldseekerAgent = class {
|
|
|
6241
6248
|
fees,
|
|
6242
6249
|
available: idle + deployed > fees ? idle + deployed - fees : 0n,
|
|
6243
6250
|
positions: [...verified],
|
|
6244
|
-
|
|
6251
|
+
resolvedVaults: [...resolvedVaults],
|
|
6245
6252
|
indexedPositions,
|
|
6246
6253
|
complete
|
|
6247
6254
|
});
|
|
6248
6255
|
assertReadCurrent();
|
|
6249
6256
|
knownProof = proof(false);
|
|
6250
6257
|
if (requested !== void 0 && knownProof.available >= requested) return knownProof;
|
|
6251
|
-
const
|
|
6258
|
+
const indexed = new Map(indexedPositions.map((position2) => [position2.yieldOption.address.toLowerCase(), position2]));
|
|
6259
|
+
const indexedValue = indexedPositions.reduce((sum, position2) => sum + BigInt(position2.withdrawableAssetsRaw), 0n);
|
|
6260
|
+
const missingKnownPosition = previousPositions.some((position2) => !indexed.has(position2.yieldOption.address.toLowerCase()));
|
|
6261
|
+
const unvaluedPosition = indexedPositions.some((position2) => BigInt(position2.assetsRaw) > 0n && BigInt(position2.withdrawableAssetsRaw) === 0n);
|
|
6262
|
+
const indexedAvailable = idle + indexedValue > fees ? idle + indexedValue - fees : 0n;
|
|
6263
|
+
if (indexedValue > 0n && !missingKnownPosition && !unvaluedPosition && (requested === void 0 || indexedAvailable >= requested)) {
|
|
6264
|
+
const known = this.balanceVaults.get(contextKey) ?? /* @__PURE__ */ new Set();
|
|
6265
|
+
for (const position2 of indexedPositions) if (BigInt(position2.withdrawableAssetsRaw) > 0n)
|
|
6266
|
+
known.add(position2.yieldOption.address.toLowerCase());
|
|
6267
|
+
this.balanceVaults.set(contextKey, known);
|
|
6268
|
+
return {
|
|
6269
|
+
blockNumber,
|
|
6270
|
+
idle,
|
|
6271
|
+
fees,
|
|
6272
|
+
available: indexedAvailable,
|
|
6273
|
+
positions: indexedPositions,
|
|
6274
|
+
resolvedVaults: [...indexed.keys()],
|
|
6275
|
+
indexedPositions,
|
|
6276
|
+
complete: true
|
|
6277
|
+
};
|
|
6278
|
+
}
|
|
6279
|
+
const collect = async (options2, results) => {
|
|
6252
6280
|
assertReadCurrent();
|
|
6253
6281
|
const known = this.balanceVaults.get(contextKey) ?? /* @__PURE__ */ new Set();
|
|
6254
6282
|
this.balanceVaults.set(contextKey, known);
|
|
6255
|
-
|
|
6256
|
-
|
|
6257
|
-
|
|
6258
|
-
const
|
|
6259
|
-
if (
|
|
6260
|
-
|
|
6261
|
-
|
|
6262
|
-
valid2 = false;
|
|
6263
|
-
return;
|
|
6264
|
-
}
|
|
6265
|
-
const [underlying, shares, withdrawable] = group.map((value) => value.result);
|
|
6266
|
-
if (typeof underlying !== "string" || !(0, import_viem13.isAddress)(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n || typeof withdrawable !== "bigint" || withdrawable < 0n || shares === 0n && withdrawable > 0n) {
|
|
6267
|
-
valid2 = false;
|
|
6268
|
-
return;
|
|
6269
|
-
}
|
|
6270
|
-
verifiedVaults.push(option.address.toLowerCase());
|
|
6271
|
-
deployed += withdrawable;
|
|
6272
|
-
verified.push({
|
|
6283
|
+
const valid2 = await Promise.all(options2.map(async (option, index) => {
|
|
6284
|
+
const group = results.slice(index * 2, index * 2 + 2);
|
|
6285
|
+
if (group.length !== 2 || group.some((value2) => value2.status !== "success")) return false;
|
|
6286
|
+
const [underlying, shares] = group.map((value2) => value2.result);
|
|
6287
|
+
if (typeof underlying !== "string" || !(0, import_viem13.isAddress)(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n) return false;
|
|
6288
|
+
if (shares > 0n) known.add(option.address.toLowerCase());
|
|
6289
|
+
const position2 = {
|
|
6273
6290
|
yieldOption: option,
|
|
6274
6291
|
assetsRaw: shares.toString(),
|
|
6275
6292
|
assetsBase: "0",
|
|
6276
6293
|
assetsUsd: 0,
|
|
6277
|
-
withdrawableAssetsRaw:
|
|
6278
|
-
withdrawableAssetsBase:
|
|
6279
|
-
}
|
|
6280
|
-
|
|
6281
|
-
|
|
6294
|
+
withdrawableAssetsRaw: "0",
|
|
6295
|
+
withdrawableAssetsBase: "0"
|
|
6296
|
+
};
|
|
6297
|
+
resolvedVaults.push(option.address.toLowerCase());
|
|
6298
|
+
verified.push(position2);
|
|
6299
|
+
knownProof = proof(false);
|
|
6300
|
+
if (shares === 0n) return true;
|
|
6301
|
+
let preview;
|
|
6302
|
+
try {
|
|
6303
|
+
const value2 = await client.readContract({
|
|
6304
|
+
address: (0, import_viem13.getAddress)(option.address),
|
|
6305
|
+
abi: import_viem13.erc4626Abi,
|
|
6306
|
+
functionName: "previewRedeem",
|
|
6307
|
+
args: [shares],
|
|
6308
|
+
blockNumber
|
|
6309
|
+
});
|
|
6310
|
+
if (typeof value2 === "bigint" && value2 >= 0n) preview = value2;
|
|
6311
|
+
} catch {
|
|
6312
|
+
}
|
|
6313
|
+
assertReadCurrent();
|
|
6314
|
+
let value = preview;
|
|
6315
|
+
if (value === void 0 || value === 0n) {
|
|
6316
|
+
try {
|
|
6317
|
+
const converted = await client.readContract({
|
|
6318
|
+
address: (0, import_viem13.getAddress)(option.address),
|
|
6319
|
+
abi: import_viem13.erc4626Abi,
|
|
6320
|
+
functionName: "convertToAssets",
|
|
6321
|
+
args: [shares],
|
|
6322
|
+
blockNumber
|
|
6323
|
+
});
|
|
6324
|
+
if (typeof converted === "bigint" && converted >= 0n && (converted > 0n || preview === 0n)) value = converted;
|
|
6325
|
+
else value = void 0;
|
|
6326
|
+
} catch {
|
|
6327
|
+
value = void 0;
|
|
6328
|
+
}
|
|
6329
|
+
}
|
|
6330
|
+
assertReadCurrent();
|
|
6331
|
+
if (value === void 0) return false;
|
|
6332
|
+
position2.withdrawableAssetsRaw = value.toString();
|
|
6333
|
+
position2.withdrawableAssetsBase = value.toString();
|
|
6334
|
+
deployed += value;
|
|
6335
|
+
knownProof = proof(false);
|
|
6336
|
+
return true;
|
|
6337
|
+
}));
|
|
6338
|
+
return valid2.every(Boolean);
|
|
6282
6339
|
};
|
|
6283
|
-
const checks = await
|
|
6340
|
+
const checks = await this.readVaultShares(options, wallet, blockNumber);
|
|
6284
6341
|
assertReadCurrent();
|
|
6285
|
-
|
|
6286
|
-
const allKnownVerified = collect(options, checks.value);
|
|
6342
|
+
const allKnownVerified = await collect(options, checks);
|
|
6287
6343
|
knownProof = proof(false);
|
|
6288
|
-
|
|
6344
|
+
if (requested !== void 0 && knownProof.available >= requested) return knownProof;
|
|
6289
6345
|
const discrepancy = verified.some((position2) => {
|
|
6290
6346
|
const row = indexed.get(position2.yieldOption.address.toLowerCase());
|
|
6291
6347
|
return row ? BigInt(position2.withdrawableAssetsRaw) < BigInt(row.withdrawableAssetsRaw) : BigInt(position2.assetsRaw) > 0n;
|
|
@@ -6305,7 +6361,7 @@ var YieldseekerAgent = class {
|
|
|
6305
6361
|
}
|
|
6306
6362
|
const extra = [...eligible].filter(([address]) => !candidates.has(address)).map(([, option]) => option);
|
|
6307
6363
|
if (options.length + extra.length > YIELDSEEKER_WITHDRAWAL_CANDIDATE_LIMIT) throw unavailable();
|
|
6308
|
-
const allExtraVerified = collect(extra, await this.
|
|
6364
|
+
const allExtraVerified = await collect(extra, await this.readVaultShares(extra, wallet, blockNumber));
|
|
6309
6365
|
assertReadCurrent();
|
|
6310
6366
|
const result = proof(eligible.size > 0 && allKnownVerified && allExtraVerified);
|
|
6311
6367
|
if (result.available === 0n && !result.complete && !hasUnverifiedIndexedFunds(result)) throw unavailable();
|
package/dist/index.d.cts
CHANGED
|
@@ -1913,9 +1913,9 @@ declare class YieldseekerAgent implements IAgent {
|
|
|
1913
1913
|
deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback, onProgress?: FundingProgress, onBeforeSubmission?: (evidence: FundingEvidence) => void | Promise<void>): Promise<OwneyDepositResult>;
|
|
1914
1914
|
withdraw(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, amount?: string, onProgress?: FundingProgress, gasMode?: "auto" | "sponsored" | "paid", onBeforeSubmission?: FundingProgress): Promise<AgentWithdrawResult>;
|
|
1915
1915
|
private withdrawInternal;
|
|
1916
|
-
/**
|
|
1916
|
+
/** Fresh position amounts for withdrawal planning, net of reserved fees. */
|
|
1917
1917
|
getWithdrawableBalance(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, minimumAmount?: bigint): Promise<bigint>;
|
|
1918
|
-
private
|
|
1918
|
+
private readVaultShares;
|
|
1919
1919
|
private validateWithdrawalPositions;
|
|
1920
1920
|
private withdrawalVaultHints;
|
|
1921
1921
|
private readWithdrawalPositions;
|
package/dist/index.d.ts
CHANGED
|
@@ -1913,9 +1913,9 @@ declare class YieldseekerAgent implements IAgent {
|
|
|
1913
1913
|
deposit(state: ConnectionState, chainId: number, amount: string, asset: OwneySupportedTokens, depositCallback?: DepositCallback, onProgress?: FundingProgress, onBeforeSubmission?: (evidence: FundingEvidence) => void | Promise<void>): Promise<OwneyDepositResult>;
|
|
1914
1914
|
withdraw(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, amount?: string, onProgress?: FundingProgress, gasMode?: "auto" | "sponsored" | "paid", onBeforeSubmission?: FundingProgress): Promise<AgentWithdrawResult>;
|
|
1915
1915
|
private withdrawInternal;
|
|
1916
|
-
/**
|
|
1916
|
+
/** Fresh position amounts for withdrawal planning, net of reserved fees. */
|
|
1917
1917
|
getWithdrawableBalance(state: ConnectionState, chainId: number, asset: OwneySupportedTokens, minimumAmount?: bigint): Promise<bigint>;
|
|
1918
|
-
private
|
|
1918
|
+
private readVaultShares;
|
|
1919
1919
|
private validateWithdrawalPositions;
|
|
1920
1920
|
private withdrawalVaultHints;
|
|
1921
1921
|
private readWithdrawalPositions;
|
package/dist/index.js
CHANGED
|
@@ -5677,7 +5677,7 @@ var YieldseekerAgent = class {
|
|
|
5677
5677
|
const initialFunds = funds;
|
|
5678
5678
|
const idle = initialFunds.idle;
|
|
5679
5679
|
const maxLiquidity = amount === void 0 ? funds : void 0;
|
|
5680
|
-
let positions = [...funds.positions, ...funds.indexedPositions.filter((position2) => !funds.
|
|
5680
|
+
let positions = [...funds.positions, ...funds.indexedPositions.filter((position2) => !funds.resolvedVaults.includes(position2.yieldOption.address.toLowerCase()))];
|
|
5681
5681
|
let positionsStatus = "empty";
|
|
5682
5682
|
const validatePositions = (values) => this.validateWithdrawalPositions(values, chainId, asset);
|
|
5683
5683
|
validatePositions(positions);
|
|
@@ -5691,17 +5691,17 @@ var YieldseekerAgent = class {
|
|
|
5691
5691
|
const verifiedPositions = [];
|
|
5692
5692
|
if (timeoutMs <= 0) return { verified: false, positions: verifiedPositions };
|
|
5693
5693
|
let active = true;
|
|
5694
|
-
const checks = this.
|
|
5694
|
+
const checks = this.readVaultShares(values.map((position2) => position2.yieldOption), agentWallet, blockNumber).catch(() => []);
|
|
5695
5695
|
const reads = values.map(async (position2, index) => {
|
|
5696
5696
|
const address = getAddress5(position2.yieldOption.address);
|
|
5697
5697
|
try {
|
|
5698
|
-
const group = (await checks).slice(index *
|
|
5699
|
-
if (!active || group.length !==
|
|
5698
|
+
const group = (await checks).slice(index * 2, index * 2 + 2);
|
|
5699
|
+
if (!active || group.length !== 2 || group.some((value) => value.status !== "success")) return null;
|
|
5700
5700
|
this.assertSession(generation, chainId, asset);
|
|
5701
|
-
const [underlying, shares
|
|
5702
|
-
if (typeof underlying !== "string" || !isAddress4(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n
|
|
5703
|
-
const verified = { ...position2, assetsRaw: shares.toString(), withdrawableAssetsRaw:
|
|
5704
|
-
if (shares > 0n
|
|
5701
|
+
const [underlying, shares] = group.map((value) => value.result);
|
|
5702
|
+
if (typeof underlying !== "string" || !isAddress4(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n) return null;
|
|
5703
|
+
const verified = { ...position2, assetsRaw: shares.toString(), withdrawableAssetsRaw: "0" };
|
|
5704
|
+
if (shares > 0n) {
|
|
5705
5705
|
let positiveValue = false;
|
|
5706
5706
|
const valuations = await Promise.all(["convertToAssets", "previewRedeem"].map(async (functionName) => {
|
|
5707
5707
|
try {
|
|
@@ -5712,9 +5712,11 @@ var YieldseekerAgent = class {
|
|
|
5712
5712
|
args: [shares],
|
|
5713
5713
|
blockNumber
|
|
5714
5714
|
});
|
|
5715
|
-
if (typeof value !== "bigint" || value < 0n) return null;
|
|
5715
|
+
if (!active || typeof value !== "bigint" || value < 0n) return null;
|
|
5716
|
+
this.assertSession(generation, chainId, asset);
|
|
5716
5717
|
if (value > 0n && !positiveValue) {
|
|
5717
5718
|
positiveValue = true;
|
|
5719
|
+
verified.withdrawableAssetsRaw = value.toString();
|
|
5718
5720
|
verifiedPositions.push(verified);
|
|
5719
5721
|
}
|
|
5720
5722
|
return value;
|
|
@@ -5722,7 +5724,12 @@ var YieldseekerAgent = class {
|
|
|
5722
5724
|
return null;
|
|
5723
5725
|
}
|
|
5724
5726
|
}));
|
|
5725
|
-
if (positiveValue)
|
|
5727
|
+
if (positiveValue) {
|
|
5728
|
+
const redemptionValue = valuations[1];
|
|
5729
|
+
if (redemptionValue !== null && redemptionValue > 0n)
|
|
5730
|
+
verified.withdrawableAssetsRaw = redemptionValue.toString();
|
|
5731
|
+
return verified;
|
|
5732
|
+
}
|
|
5726
5733
|
if (blockNumber === void 0 || valuations.some((value) => value !== 0n)) return null;
|
|
5727
5734
|
zeroValuePositions.add(verified);
|
|
5728
5735
|
}
|
|
@@ -5885,8 +5892,10 @@ var YieldseekerAgent = class {
|
|
|
5885
5892
|
this.assertSession(generation, chainId, asset);
|
|
5886
5893
|
if (proof.verified) {
|
|
5887
5894
|
positions = [...proof.positions, ...(catalog ?? []).filter((position2) => !knownBeforeRefresh.has(position2.yieldOption.address.toLowerCase()))];
|
|
5888
|
-
} else if (catalog)
|
|
5889
|
-
|
|
5895
|
+
} else if (catalog) {
|
|
5896
|
+
const checked = new Set(proof.positions.map((position2) => position2.yieldOption.address.toLowerCase()));
|
|
5897
|
+
positions = [...proof.positions, ...catalog.filter((position2) => !checked.has(position2.yieldOption.address.toLowerCase()))];
|
|
5898
|
+
} else {
|
|
5890
5899
|
positionsStatus = "unavailable";
|
|
5891
5900
|
break;
|
|
5892
5901
|
}
|
|
@@ -6070,7 +6079,7 @@ var YieldseekerAgent = class {
|
|
|
6070
6079
|
}
|
|
6071
6080
|
}
|
|
6072
6081
|
}
|
|
6073
|
-
/**
|
|
6082
|
+
/** Fresh position amounts for withdrawal planning, net of reserved fees. */
|
|
6074
6083
|
async getWithdrawableBalance(state, chainId, asset, minimumAmount) {
|
|
6075
6084
|
this.assertChain(chainId);
|
|
6076
6085
|
this.assertAsset(asset);
|
|
@@ -6095,7 +6104,7 @@ var YieldseekerAgent = class {
|
|
|
6095
6104
|
);
|
|
6096
6105
|
return proof.available;
|
|
6097
6106
|
}
|
|
6098
|
-
async
|
|
6107
|
+
async readVaultShares(options, wallet, blockNumber) {
|
|
6099
6108
|
const owner = getAddress5(wallet);
|
|
6100
6109
|
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));
|
|
6101
6110
|
const results = await Promise.all(batches.map((batch) => this.getReceiptClient().multicall({
|
|
@@ -6105,8 +6114,7 @@ var YieldseekerAgent = class {
|
|
|
6105
6114
|
const address = getAddress5(option.address);
|
|
6106
6115
|
return [
|
|
6107
6116
|
{ address, abi: erc4626Abi2, functionName: "asset" },
|
|
6108
|
-
{ address, abi: erc20Abi5, functionName: "balanceOf", args: [owner] }
|
|
6109
|
-
{ address, abi: erc4626Abi2, functionName: "maxWithdraw", args: [owner] }
|
|
6117
|
+
{ address, abi: erc20Abi5, functionName: "balanceOf", args: [owner] }
|
|
6110
6118
|
];
|
|
6111
6119
|
})
|
|
6112
6120
|
})));
|
|
@@ -6176,7 +6184,7 @@ var YieldseekerAgent = class {
|
|
|
6176
6184
|
);
|
|
6177
6185
|
let active = true;
|
|
6178
6186
|
let knownProof;
|
|
6179
|
-
const hasUnverifiedIndexedFunds = (proof) => proof.indexedPositions.some((position2) => !proof.
|
|
6187
|
+
const hasUnverifiedIndexedFunds = (proof) => proof.indexedPositions.some((position2) => !proof.resolvedVaults.includes(position2.yieldOption.address.toLowerCase()) && BigInt(position2.withdrawableAssetsRaw) > 0n);
|
|
6180
6188
|
const assertReadCurrent = () => {
|
|
6181
6189
|
this.assertSession(generation, chainId, context.asset);
|
|
6182
6190
|
if (!active || this.portfolioVersion(contextKey) !== version) throw unavailable();
|
|
@@ -6194,7 +6202,6 @@ var YieldseekerAgent = class {
|
|
|
6194
6202
|
for (const position2 of indexedPositions) candidates.set(position2.yieldOption.address.toLowerCase(), position2.yieldOption);
|
|
6195
6203
|
const options = [...candidates.values()];
|
|
6196
6204
|
if (options.length > YIELDSEEKER_WITHDRAWAL_CANDIDATE_LIMIT) throw unavailable();
|
|
6197
|
-
const checksRead = this.readVaultLiquidity(options, wallet, blockNumber).then((value) => ({ value }), (error) => ({ error }));
|
|
6198
6205
|
const [idle, feeTracker] = await Promise.all([
|
|
6199
6206
|
client.readContract({
|
|
6200
6207
|
address: metadata.address,
|
|
@@ -6221,7 +6228,7 @@ var YieldseekerAgent = class {
|
|
|
6221
6228
|
});
|
|
6222
6229
|
if (typeof fees !== "bigint" || fees < 0n) throw unavailable();
|
|
6223
6230
|
const verified = [];
|
|
6224
|
-
const
|
|
6231
|
+
const resolvedVaults = [];
|
|
6225
6232
|
let deployed = 0n;
|
|
6226
6233
|
const proof = (complete) => ({
|
|
6227
6234
|
blockNumber,
|
|
@@ -6229,51 +6236,100 @@ var YieldseekerAgent = class {
|
|
|
6229
6236
|
fees,
|
|
6230
6237
|
available: idle + deployed > fees ? idle + deployed - fees : 0n,
|
|
6231
6238
|
positions: [...verified],
|
|
6232
|
-
|
|
6239
|
+
resolvedVaults: [...resolvedVaults],
|
|
6233
6240
|
indexedPositions,
|
|
6234
6241
|
complete
|
|
6235
6242
|
});
|
|
6236
6243
|
assertReadCurrent();
|
|
6237
6244
|
knownProof = proof(false);
|
|
6238
6245
|
if (requested !== void 0 && knownProof.available >= requested) return knownProof;
|
|
6239
|
-
const
|
|
6246
|
+
const indexed = new Map(indexedPositions.map((position2) => [position2.yieldOption.address.toLowerCase(), position2]));
|
|
6247
|
+
const indexedValue = indexedPositions.reduce((sum, position2) => sum + BigInt(position2.withdrawableAssetsRaw), 0n);
|
|
6248
|
+
const missingKnownPosition = previousPositions.some((position2) => !indexed.has(position2.yieldOption.address.toLowerCase()));
|
|
6249
|
+
const unvaluedPosition = indexedPositions.some((position2) => BigInt(position2.assetsRaw) > 0n && BigInt(position2.withdrawableAssetsRaw) === 0n);
|
|
6250
|
+
const indexedAvailable = idle + indexedValue > fees ? idle + indexedValue - fees : 0n;
|
|
6251
|
+
if (indexedValue > 0n && !missingKnownPosition && !unvaluedPosition && (requested === void 0 || indexedAvailable >= requested)) {
|
|
6252
|
+
const known = this.balanceVaults.get(contextKey) ?? /* @__PURE__ */ new Set();
|
|
6253
|
+
for (const position2 of indexedPositions) if (BigInt(position2.withdrawableAssetsRaw) > 0n)
|
|
6254
|
+
known.add(position2.yieldOption.address.toLowerCase());
|
|
6255
|
+
this.balanceVaults.set(contextKey, known);
|
|
6256
|
+
return {
|
|
6257
|
+
blockNumber,
|
|
6258
|
+
idle,
|
|
6259
|
+
fees,
|
|
6260
|
+
available: indexedAvailable,
|
|
6261
|
+
positions: indexedPositions,
|
|
6262
|
+
resolvedVaults: [...indexed.keys()],
|
|
6263
|
+
indexedPositions,
|
|
6264
|
+
complete: true
|
|
6265
|
+
};
|
|
6266
|
+
}
|
|
6267
|
+
const collect = async (options2, results) => {
|
|
6240
6268
|
assertReadCurrent();
|
|
6241
6269
|
const known = this.balanceVaults.get(contextKey) ?? /* @__PURE__ */ new Set();
|
|
6242
6270
|
this.balanceVaults.set(contextKey, known);
|
|
6243
|
-
|
|
6244
|
-
|
|
6245
|
-
|
|
6246
|
-
const
|
|
6247
|
-
if (
|
|
6248
|
-
|
|
6249
|
-
|
|
6250
|
-
valid2 = false;
|
|
6251
|
-
return;
|
|
6252
|
-
}
|
|
6253
|
-
const [underlying, shares, withdrawable] = group.map((value) => value.result);
|
|
6254
|
-
if (typeof underlying !== "string" || !isAddress4(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n || typeof withdrawable !== "bigint" || withdrawable < 0n || shares === 0n && withdrawable > 0n) {
|
|
6255
|
-
valid2 = false;
|
|
6256
|
-
return;
|
|
6257
|
-
}
|
|
6258
|
-
verifiedVaults.push(option.address.toLowerCase());
|
|
6259
|
-
deployed += withdrawable;
|
|
6260
|
-
verified.push({
|
|
6271
|
+
const valid2 = await Promise.all(options2.map(async (option, index) => {
|
|
6272
|
+
const group = results.slice(index * 2, index * 2 + 2);
|
|
6273
|
+
if (group.length !== 2 || group.some((value2) => value2.status !== "success")) return false;
|
|
6274
|
+
const [underlying, shares] = group.map((value2) => value2.result);
|
|
6275
|
+
if (typeof underlying !== "string" || !isAddress4(underlying) || underlying.toLowerCase() !== metadata.address.toLowerCase() || typeof shares !== "bigint" || shares < 0n) return false;
|
|
6276
|
+
if (shares > 0n) known.add(option.address.toLowerCase());
|
|
6277
|
+
const position2 = {
|
|
6261
6278
|
yieldOption: option,
|
|
6262
6279
|
assetsRaw: shares.toString(),
|
|
6263
6280
|
assetsBase: "0",
|
|
6264
6281
|
assetsUsd: 0,
|
|
6265
|
-
withdrawableAssetsRaw:
|
|
6266
|
-
withdrawableAssetsBase:
|
|
6267
|
-
}
|
|
6268
|
-
|
|
6269
|
-
|
|
6282
|
+
withdrawableAssetsRaw: "0",
|
|
6283
|
+
withdrawableAssetsBase: "0"
|
|
6284
|
+
};
|
|
6285
|
+
resolvedVaults.push(option.address.toLowerCase());
|
|
6286
|
+
verified.push(position2);
|
|
6287
|
+
knownProof = proof(false);
|
|
6288
|
+
if (shares === 0n) return true;
|
|
6289
|
+
let preview;
|
|
6290
|
+
try {
|
|
6291
|
+
const value2 = await client.readContract({
|
|
6292
|
+
address: getAddress5(option.address),
|
|
6293
|
+
abi: erc4626Abi2,
|
|
6294
|
+
functionName: "previewRedeem",
|
|
6295
|
+
args: [shares],
|
|
6296
|
+
blockNumber
|
|
6297
|
+
});
|
|
6298
|
+
if (typeof value2 === "bigint" && value2 >= 0n) preview = value2;
|
|
6299
|
+
} catch {
|
|
6300
|
+
}
|
|
6301
|
+
assertReadCurrent();
|
|
6302
|
+
let value = preview;
|
|
6303
|
+
if (value === void 0 || value === 0n) {
|
|
6304
|
+
try {
|
|
6305
|
+
const converted = await client.readContract({
|
|
6306
|
+
address: getAddress5(option.address),
|
|
6307
|
+
abi: erc4626Abi2,
|
|
6308
|
+
functionName: "convertToAssets",
|
|
6309
|
+
args: [shares],
|
|
6310
|
+
blockNumber
|
|
6311
|
+
});
|
|
6312
|
+
if (typeof converted === "bigint" && converted >= 0n && (converted > 0n || preview === 0n)) value = converted;
|
|
6313
|
+
else value = void 0;
|
|
6314
|
+
} catch {
|
|
6315
|
+
value = void 0;
|
|
6316
|
+
}
|
|
6317
|
+
}
|
|
6318
|
+
assertReadCurrent();
|
|
6319
|
+
if (value === void 0) return false;
|
|
6320
|
+
position2.withdrawableAssetsRaw = value.toString();
|
|
6321
|
+
position2.withdrawableAssetsBase = value.toString();
|
|
6322
|
+
deployed += value;
|
|
6323
|
+
knownProof = proof(false);
|
|
6324
|
+
return true;
|
|
6325
|
+
}));
|
|
6326
|
+
return valid2.every(Boolean);
|
|
6270
6327
|
};
|
|
6271
|
-
const checks = await
|
|
6328
|
+
const checks = await this.readVaultShares(options, wallet, blockNumber);
|
|
6272
6329
|
assertReadCurrent();
|
|
6273
|
-
|
|
6274
|
-
const allKnownVerified = collect(options, checks.value);
|
|
6330
|
+
const allKnownVerified = await collect(options, checks);
|
|
6275
6331
|
knownProof = proof(false);
|
|
6276
|
-
|
|
6332
|
+
if (requested !== void 0 && knownProof.available >= requested) return knownProof;
|
|
6277
6333
|
const discrepancy = verified.some((position2) => {
|
|
6278
6334
|
const row = indexed.get(position2.yieldOption.address.toLowerCase());
|
|
6279
6335
|
return row ? BigInt(position2.withdrawableAssetsRaw) < BigInt(row.withdrawableAssetsRaw) : BigInt(position2.assetsRaw) > 0n;
|
|
@@ -6293,7 +6349,7 @@ var YieldseekerAgent = class {
|
|
|
6293
6349
|
}
|
|
6294
6350
|
const extra = [...eligible].filter(([address]) => !candidates.has(address)).map(([, option]) => option);
|
|
6295
6351
|
if (options.length + extra.length > YIELDSEEKER_WITHDRAWAL_CANDIDATE_LIMIT) throw unavailable();
|
|
6296
|
-
const allExtraVerified = collect(extra, await this.
|
|
6352
|
+
const allExtraVerified = await collect(extra, await this.readVaultShares(extra, wallet, blockNumber));
|
|
6297
6353
|
assertReadCurrent();
|
|
6298
6354
|
const result = proof(eligible.size > 0 && allKnownVerified && allExtraVerified);
|
|
6299
6355
|
if (result.available === 0n && !result.complete && !hasUnverifiedIndexedFunds(result)) throw unavailable();
|