feat: Payments 8/8, Reconciliation, observability, and testnet demo tooling - #153
Open
Diggardson270 wants to merge 1 commit into
Open
feat: Payments 8/8, Reconciliation, observability, and testnet demo tooling#153Diggardson270 wants to merge 1 commit into
Diggardson270 wants to merge 1 commit into
Conversation
|
@Diggardson270 is attempting to deploy a commit to the wumibals' projects Team on Vercel. A member of the Team first needs to authorize it. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR adds the reconciliation, observability, and demo tooling issue #145 asks for, built on top of #138–#144. It does not include an actual live testnet deployment — that requires a funded Stellar identity and network access I don't have in this environment, and running it is inherently something only whoever holds those credentials should do. Instead, this PR ships everything needed to deploy and verify the stack yourself in one pass.
Issues
Closes #145
What's included
Contract event emission (
contracts/vault_flex|vault_l3|vault_l6|vault_l12|harvester/src/lib.rs)deposit,withdraw, andearly_exitnow emit structured events from all four tier vaults (topics:(kind, user, asset), data: the amount/payout that moved the vault's balance).harvestnow emits(harvested, bounty, remainder)from Harvester, including the zero-yield path, so reconciliation can tell "harvest ran and found nothing" apart from "harvest never ran."vault_flex'swithdraw/early_exitwere refactored (shareddo_withdrawhelper) so each emits its own distinct event instead ofearly_exitsilently firing awithdrawevent.getEventsagainst these topics is the indexing layer.scripts/— deployment, reconciliation, and demo tooling (new)deploy-testnet.sh: builds and deploys the full stack (GuardianMultisig, StrategyVault, Harvester, all four tier vaults, VaultRouter, Governance), initializes them in dependency order, and writes real contract ids intodeployments/testnet.json. Always deploys fresh rather than trying to detect/reuse stale ids — the correct behavior after a testnet reset, and the only behavior that's safe to assume.src/reconcile.ts+src/reconcile.core.ts: cross-checks event-derived per-asset balances against each tier vault'stotal_balance(), flags any(tier, asset)whose computed balance goes negative (catches a shortfall in one asset that a surplus in another would otherwise mask), validates Harvester's bounty/remainder split against every harvest event (mirroring the invariant already unit-tested in isolation atcontracts/harvester/src/lib.rs:160-179, now checked against live chain state), and flags disagreement betweenVaultRouter.position()and a tier vault's ownbalance()read directly. Exits non-zero on any mismatch — safe to wire into CI/cron.src/reconcile.core.tsis pure (no network I/O) and has its own test suite (src/reconcile.test.ts, 15 tests) covering: a clean run, an injected negative-balance mismatch, an injected harvest-split mismatch, the documented zero-yield harvest path (expected, not flagged), a paused window with zero new deposit events (expected, not flagged — by construction, not a special case), and SDK-vs-chain disagreement.src/operational-report.ts: TVL vs. cap per tier and last-harvest-ledger vs. expected-cooldown-elapsed, answering "is the system healthy right now?" without reading contract storage by hand.src/e2e-demo.ts: drives the real@yieldladder/sdk(issues Payments 2/8: Implement real Soroban transaction pipeline in the TypeScript SDK #139/Payments 4/8: Real transaction status tracking and confirmation lifecycle #141) through deposit into 2 tiers → status-tracked confirmation → (prints the harvest-trigger command) → withdraw/early-exit → final balance check, exactly the flow the acceptance criteria describe. It signs with aKeypairinstead of a browser Freighter extension (Freighter can't be automated headlessly from Node) — sameSignerinterface aWalletAdaptersatisfies, so it's exercising the identical SDK call path the app makes through a connected wallet..env.example,README.md: full reproducible walkthrough, required env vars, and documented limitations (event-lookback window bounded by RPC retention; GuardianMultisig id isn't indeployments/testnet.json's existing schema).SDK (
sdks/typescript/src/index.ts)positionForTier(address, tier)— a minimal addition alongside the existingposition()(which collapses all four tiers into "the first with a non-zero principal"). Needed once a single account holds positions in more than one tier at once, which the e2e demo and reconciliation both require. All 38 existing SDK tests still pass unchanged.README.md
scripts/README.md.