Skip to content

feat: Payments 8/8, Reconciliation, observability, and testnet demo tooling - #153

Open
Diggardson270 wants to merge 1 commit into
LadderMine:mainfrom
Diggardson270:main
Open

feat: Payments 8/8, Reconciliation, observability, and testnet demo tooling#153
Diggardson270 wants to merge 1 commit into
LadderMine:mainfrom
Diggardson270:main

Conversation

@Diggardson270

Copy link
Copy Markdown
Contributor

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, and early_exit now emit structured events from all four tier vaults (topics: (kind, user, asset), data: the amount/payout that moved the vault's balance).
  • harvest now 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's withdraw/early_exit were refactored (shared do_withdraw helper) so each emits its own distinct event instead of early_exit silently firing a withdraw event.
  • This is the foundation the reconciliation job reads from — there's no separate indexer in this PR; getEvents against 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 into deployments/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's total_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 at contracts/harvester/src/lib.rs:160-179, now checked against live chain state), and flags disagreement between VaultRouter.position() and a tier vault's own balance() read directly. Exits non-zero on any mismatch — safe to wire into CI/cron.
  • src/reconcile.core.ts is 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 a Keypair instead of a browser Freighter extension (Freighter can't be automated headlessly from Node) — same Signer interface a WalletAdapter satisfies, 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 in deployments/testnet.json's existing schema).

SDK (sdks/typescript/src/index.ts)

  • Added positionForTier(address, tier) — a minimal addition alongside the existing position() (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

  • New "Testnet deployment, reconciliation & demo" section pointing at scripts/README.md.

@vercel

vercel Bot commented Aug 24, 2026

Copy link
Copy Markdown

@Diggardson270 is attempting to deploy a commit to the wumibals' projects Team on Vercel.

A member of the Team first needs to authorize it.

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.

Payments 8/8: Reconciliation, observability, and a demonstrable end-to-end testnet payment flow

1 participant