Skip to content

Align AccountLens ABI and deployment sources - #85

Merged
Seranged merged 6 commits into
mainfrom
fix/account-lens-runtime-sources
Jul 29, 2026
Merged

Seranged merged 6 commits into
mainfrom
fix/account-lens-runtime-sources

Conversation

@dglowinski

@dglowinski dglowinski commented Jul 29, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Resolve the AccountLens ABI at runtime for account reads, transaction simulation, and reward-stream reads so SDK decoding follows the deployed lens interface.
  • Add one Euler interfaces branch setting for both ABI documents and the default EulerChains deployment document.
  • Preserve healthy positions and rewards when individual lens queries fail, while exposing account-read diagnostics.

Changes

  • Validate ABI HTTP and JSON responses, coalesce concurrent fetches, and evict failed requests so later calls can retry.
  • Fall back to the bundled AccountLens ABI when runtime resolution fails or lacks functions required by a consumer.
  • Surface whole-vault query failures, omit failed vault rows, and keep simulation operational through ABI fallback.
  • Read rewards through getRewardAccountInfo and isolate per-position failures instead of failing the entire reward result.
  • Support eulerInterfacesBranch and EULER_SDK_EULER_INTERFACES_BRANCH; keep an explicit deploymentsUrl or EULER_SDK_DEPLOYMENTS_URL as the higher-priority deployment override.
  • Refresh the bundled AccountLens ABI and document the runtime configuration.

Test plan

  • Run the full SDK test suite: 492 tests passed.
  • Run SDK typecheck.
  • Build the SDK package.
  • Run SDK lint; only existing warnings outside this diff remain.
  • Verify the configured mainnet AccountLens with a live account and reward query.
  • Compare the deployed AccountLens runtime bytecode with the current periphery implementation.

Summary by CodeRabbit

  • New Features
    • Added configurable Euler Interfaces branch selection through SDK settings and environment variables.
    • Improved ABI loading with branch-aware URLs, request reuse, validation, and retry handling.
    • Added runtime ABI fallback so account, reward, and simulation reads can continue when remote ABI retrieval fails.
    • Enhanced account and reward data with query failure details and reward-account information.
    • Simulations now report snapshot read failures for improved diagnostics.
  • Documentation
    • Updated configuration guidance for Euler Interfaces branches and deployment URL precedence.
  • Bug Fixes
    • Preserved compatibility with legacy reward-account query overrides.

LeonardEulerXYZ and others added 4 commits July 28, 2026 11:23
Reject unsuccessful or malformed ABI responses while keeping failed fetches retryable.

Ignore whole-vault AccountLens query failures in account, rewards, and simulation results.
Resolving the AccountLens ABI through ABIService made every account read,
reward-stream read, and simulation depend on fetching the ABI document: a
404, rate limit, or blocked host rejected before any RPC call, even though
a usable bundled ABI ships with the package.

Add resolveAccountLensAbi, which degrades to the bundled ABI when the
document is unreachable or is missing the functions the SDK calls, and
report the fallback where a channel exists (a FALLBACK_USED data issue on
account reads, a warning log for rewards and simulation).

Also:
- keep the resolved ABI out of AccountLens query cache keys, so a ~33KB
  array is not serialized into every key (and into consumer query keys
  derived from the same helpers)
- key the ABI request cache by resolved URL rather than contract name, so
  it tracks whatever getABIURL keys on
- extract the duplicated SOURCE_UNAVAILABLE data issue in
  collectSettledVaultAccountInfos and document the two originalValue shapes
- document why a whole-vault queryFailure is dropped silently in
  decodeAccountSnapshot: the EVC batch item succeeded, so it cannot surface
  via failedBatchItems

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- configure ABI and deployment reads from one interfaces branch
- use the reward-specific AccountLens query and isolate failures
- refresh the bundled fallback ABI for current lens deployments
@coderabbitai

coderabbitai Bot commented Jul 29, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The SDK adds configurable Euler Interfaces branch selection, dynamic deployment URLs, runtime AccountLens ABI loading with fallback and caching, ABI-aware account/reward/simulation reads, structured lens-read failure reporting, and legacy reward-query compatibility.

Changes

AccountLens ABI integration

Layer / File(s) Summary
Branch configuration and ABI loading
packages/euler-v2-sdk/src/sdk/..., packages/euler-v2-sdk/src/services/abiService/..., packages/euler-v2-sdk/docs/config-through-env.md, packages/euler-v2-sdk/test/sdkConfig.test.ts
Adds eulerInterfacesBranch, branch-derived deployment URLs, validated ABI responses, URL-keyed promise caching, failure eviction, and SDK wiring.
Runtime AccountLens resolution and account reads
packages/euler-v2-sdk/src/services/accountService/adapters/accountOnchainAdapter/..., packages/euler-v2-sdk/test/accountLensAbiService.test.ts
Resolves runtime or bundled AccountLens ABIs, propagates them through reads and batch encoding, stabilizes query keys, and reports in-band or rejected vault reads.
Simulation ABI propagation and read failures
packages/euler-v2-sdk/src/services/executionService/..., packages/euler-v2-sdk/test/simulate.test.ts
Passes ABIService into simulation, decodes snapshots with the resolved ABI, and exposes reverted or in-band lens failures through snapshotReadFailures.
Reward account reads and legacy compatibility
packages/euler-v2-sdk/src/services/rewardsService/..., packages/euler-v2-sdk/test/rewardsService.test.ts
Uses reward-account reads for streams, isolates rejected reads, and preserves deprecated callback behavior through legacy result projection.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested reviewers: leonardeulerxyz

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 42.86% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the core change: aligning AccountLens ABI resolution and deployment source selection with configured branches.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/account-lens-runtime-sources

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@LeonardEulerXYZ

LeonardEulerXYZ commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Overview

This PR moves AccountLens account reads, layered transaction simulation, and reward-stream reads onto a runtime ABI sourced from the configured euler-interfaces branch. It also aligns default deployment resolution with that branch and isolates per-vault Lens failures.

Incremental re-review

Reviewed head: f797bca26c37c00af6440e8e64f352b2057075f5

Since the previous review:

  • snapshotReadFailures now exposes reverted and in-band EVC/vault reads by account, vault, cause, reason, and simulation layer. This resolves the silent-partial-snapshot finding while preserving the separate meaning of canExecute.
  • The deprecated public queryVaultAccountInfo property is restored, and setQueryVaultAccountInfo accepts/projectively adapts the legacy callback shape. The same strict downstream fixture now compiles.
  • Per Darek's direction, the previous bundled/default ABI finding is withdrawn as a code blocker here. euler-interfaces#225 updates the ABI and AccountLens deployments together.

Cross-repo composition

  • euler-interfaces#225 head 51e3b5a6ddf8474dd8d8747f18ff9636da75e71e was inspected directly.
  • Its AccountLens.json is structurally identical to this SDK's bundled ABI.
  • The new mainnet AccountLens 0x2C5C13e4600AAbf77c1FdaA7b63d2D654DdFf7C5 successfully answered getEVCAccountInfo, getVaultAccountInfo, and getRewardAccountInfo against a live vault fixture.
  • Its deployed-code and chains-manifest checks pass.

Rollout note: merge/publish this SDK and update consumers before or atomically with switching euler-interfaces/master in #225. Euler Lite development currently pins SDK 1.2.1; that version uses the old static AccountLens call shape while loading mutable master deployments. Lite also needs to consume snapshotReadFailures before treating layered simulation output as authoritative.

Verdict

Approved. The two remaining code findings are resolved, and finding 1 is withdrawn under the accepted euler-interfaces#225 sequencing.

Non-blocking follow-ups

CodeRabbit's branch-normalization note is valid but minor: programmatic config values containing whitespace are normalized by ABIService but not by the deployment URL helper. Arity-aware runtime ABI validation and the stronger per-layer test assertion are also reasonable hardening, not merge blockers for the verified #225 ABI.

Validation

  • pnpm --filter @eulerxyz/euler-v2-sdk test — 33 files / 497 tests passed
  • pnpm --filter @eulerxyz/euler-v2-sdk typecheck — passed
  • pnpm --filter @eulerxyz/euler-v2-sdk build — passed
  • pnpm --filter @eulerxyz/euler-v2-sdk lint — exited 0 with existing warnings outside this PR
  • strict downstream RewardsService compatibility fixture — passed
  • whole-diff malicious-code/supply-chain sweep — no dependency, lockfile, workflow, install-script, credential, or executable-package changes

@LeonardEulerXYZ LeonardEulerXYZ left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed exact head ce02fbe5b085dccdeadfd6f9c36121ec7ea44741. Requesting changes for the default fallback-ABI incompatibility, silent partial simulation snapshots, and the deprecated setter's source-compatibility regression. Full validation: 492/492 tests passed; typecheck and build passed; lint exited 0 with existing warnings outside this diff. See inline comments for the concrete invariants and minimal fixes.

dglowinski and others added 2 commits July 29, 2026 16:44
A failed AccountLens read dropped a position from a simulated snapshot with
no way for callers to notice. `rawBatchResults` covers only the batch's
action positions, so a reverted lens read never reaches `failedBatchItems`,
and a whole-vault failure is reported in-band with the batch item itself
succeeding. Either way `canExecute` could stay true while
`simulatedAccounts` silently omitted a collateral or debt position, which a
preflight consumer cannot distinguish from a complete healthy post-state.

Record both failure modes and surface them on `SimulateBatchResult` as
`snapshotReadFailures`, attributed per layer, sub-account and vault, with
the lens `queryFailureReason` or the reverted read's return data. Positions
still degrade to absent rather than throwing, matching the surrounding
per-vault tolerance; `canExecute` still tracks whether the batch executes,
and now documents the dependency on this field.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Renaming the reward reader to `queryRewardAccountInfo` removed a public
property and changed the deprecated setter's callback contract, so existing
TypeScript consumers failed to compile: direct access to
`queryVaultAccountInfo` with TS2551, and an old-style
`setQueryVaultAccountInfo` callback with TS2322 once `AccountRewardInfo`
required `balanceTracker` and `balance`.

Restore `queryVaultAccountInfo` with its original contract, deprecated and
unused internally, and widen the deprecated setter to accept the legacy
return shape, projecting it onto `AccountRewardInfo` so only the fields
`fetchRewardStreams` actually reads are required. The setter keeps
retargeting the live reader, as it always did — pointing it at the unused
legacy property would silently discard an override.

Note the rename itself was a fix: `getVaultAccountInfo` carries no
`enabledRewardsInfo`, so the previous reader made `fetchRewardStreams`
return an empty list unconditionally.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (2)
packages/euler-v2-sdk/test/simulate.test.ts (1)

1386-1391: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

This per-layer assertion is vacuous.

inBand.length > 0 is already asserted at Line 1365, so the set size is always ≥ 1. Assert the actual expectation — every layer that read the vault reported it — e.g. compare against result.simulatedAccounts.length.

💚 Suggested strengthening
-	assert.ok(
-		new Set(inBand.map((failure) => failure.layerIndex)).size >= 1,
-		"expected per-layer attribution",
-	);
+	assert.equal(
+		new Set(inBand.map((failure) => failure.layerIndex)).size,
+		result.simulatedAccounts.length,
+		"expected every layer to report the failure",
+	);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/euler-v2-sdk/test/simulate.test.ts` around lines 1386 - 1391,
Strengthen the per-layer assertion in the simulate test by comparing the number
of distinct failure.layerIndex values in inBand with
result.simulatedAccounts.length. Replace the vacuous “size >= 1” check while
preserving the existing per-layer attribution message.
packages/euler-v2-sdk/src/services/accountService/adapters/accountOnchainAdapter/resolveAccountLensAbi.ts (1)

23-30: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

Validation only checks function names, not arity.

A runtime ABI whose getVaultAccountInfo takes different inputs passes this check and then fails at encode/decode time with no fallback. Consider also asserting the expected input count for each required function so a genuinely incompatible document falls back to the bundle instead.

♻️ Suggested tightening
-const DEFAULT_REQUIRED_FUNCTIONS = [
-	"getEVCAccountInfo",
-	"getVaultAccountInfo",
-] as const;
+const DEFAULT_REQUIRED_FUNCTIONS = [
+	"getEVCAccountInfo",
+	"getVaultAccountInfo",
+] as const;
+const EXPECTED_INPUT_COUNT = 2;
 	requiredFunctions.filter(
 		(name) =>
-			!abi.some((item) => item.type === "function" && item.name === name),
+			!abi.some(
+				(item) =>
+					item.type === "function" &&
+					item.name === name &&
+					item.inputs.length === EXPECTED_INPUT_COUNT,
+			),
 	);
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@packages/euler-v2-sdk/src/services/accountService/adapters/accountOnchainAdapter/resolveAccountLensAbi.ts`
around lines 23 - 30, Update missingFunctions to validate each required
function’s expected input arity, not only its name, so incompatible ABI entries
are treated as missing and trigger the existing bundled-ABI fallback. Use the
required-function definitions or related symbols in resolveAccountLensAbi to
obtain the expected counts, while preserving the current name-based validation
for all other functions.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@packages/euler-v2-sdk/src/sdk/defaultConfig.ts`:
- Around line 110-113: Update getEulerInterfacesDeploymentsUrl to normalize its
branch input before interpolation: trim whitespace and fall back to the
established master default when the result is empty, matching ABIService
behavior and keeping ABI/deployments branch selection aligned.

---

Nitpick comments:
In
`@packages/euler-v2-sdk/src/services/accountService/adapters/accountOnchainAdapter/resolveAccountLensAbi.ts`:
- Around line 23-30: Update missingFunctions to validate each required
function’s expected input arity, not only its name, so incompatible ABI entries
are treated as missing and trigger the existing bundled-ABI fallback. Use the
required-function definitions or related symbols in resolveAccountLensAbi to
obtain the expected counts, while preserving the current name-based validation
for all other functions.

In `@packages/euler-v2-sdk/test/simulate.test.ts`:
- Around line 1386-1391: Strengthen the per-layer assertion in the simulate test
by comparing the number of distinct failure.layerIndex values in inBand with
result.simulatedAccounts.length. Replace the vacuous “size >= 1” check while
preserving the existing per-layer attribution message.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: euler-xyz/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 388459df-11c0-4869-8809-8651e08e2935

📥 Commits

Reviewing files that changed from the base of the PR and between 93daf32 and f797bca.

📒 Files selected for processing (19)
  • packages/euler-v2-sdk/docs/config-through-env.md
  • packages/euler-v2-sdk/src/sdk/buildSDK.ts
  • packages/euler-v2-sdk/src/sdk/config.ts
  • packages/euler-v2-sdk/src/sdk/defaultConfig.ts
  • packages/euler-v2-sdk/src/services/abiService/abiService.ts
  • packages/euler-v2-sdk/src/services/abiService/index.ts
  • packages/euler-v2-sdk/src/services/accountService/adapters/accountOnchainAdapter/abis/accountLensAbi.ts
  • packages/euler-v2-sdk/src/services/accountService/adapters/accountOnchainAdapter/accountLensTypes.ts
  • packages/euler-v2-sdk/src/services/accountService/adapters/accountOnchainAdapter/accountOnchainAdapter.ts
  • packages/euler-v2-sdk/src/services/accountService/adapters/accountOnchainAdapter/resolveAccountLensAbi.ts
  • packages/euler-v2-sdk/src/services/executionService/executionService.ts
  • packages/euler-v2-sdk/src/services/executionService/index.ts
  • packages/euler-v2-sdk/src/services/executionService/simulate.ts
  • packages/euler-v2-sdk/src/services/rewardsService/index.ts
  • packages/euler-v2-sdk/src/services/rewardsService/rewardsService.ts
  • packages/euler-v2-sdk/test/accountLensAbiService.test.ts
  • packages/euler-v2-sdk/test/rewardsService.test.ts
  • packages/euler-v2-sdk/test/sdkConfig.test.ts
  • packages/euler-v2-sdk/test/simulate.test.ts

Comment thread packages/euler-v2-sdk/src/sdk/defaultConfig.ts

@LeonardEulerXYZ LeonardEulerXYZ left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-reviewed exact head f797bca26c37c00af6440e8e64f352b2057075f5. The incomplete-snapshot diagnostic and RewardsService source-compatibility findings are resolved. Per Darek's direction, I am withdrawing the prior bundled/default ABI finding as a code blocker here: euler-interfaces#225 carries the matching ABI and AccountLens redeployments, its verification checks pass, and the new mainnet Lens answered all three target reads in a live fixture. Validation: 33 files / 497 tests passed; typecheck and build passed; lint exited 0 with existing out-of-diff warnings; strict downstream compatibility fixture passed. Approved with a release-order note: publish this SDK and update consumers before or atomically with switching euler-interfaces/master; Euler Lite development still pins SDK 1.2.1 and must also handle snapshotReadFailures. CodeRabbit's branch-normalization and ABI-arity notes remain reasonable non-blocking hardening.

@Seranged
Seranged self-requested a review July 29, 2026 15:44
@Seranged
Seranged merged commit a647480 into main Jul 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants