feat: add production hardhat deployment scripts with safety checks - #47
Open
ForgeCoreye wants to merge 1116 commits into
Open
ForgeCoreye wants to merge 1116 commits into
ForgeCoreye wants to merge 1116 commits into
Conversation
Adds C2R (collateral-to-reserve) optimization for single-token withdrawals: Solidity (Types.sol, Depository.sol): - CollateralToReserve struct: counterparty, tokenId, amount, sig - Added to Batch struct between reserveToCollateral and settlements - Expands to full Settlement on-chain, reuses settle logic Runtime (j-batch.ts): - detectPureC2R(): identifies settlements that match C2R pattern - Auto-compression disabled until contracts redeployed (C2R_SHORTCUT_ENABLED=1) - collateralToReserve[] added to JBatch interface C2R pattern (1 number → 4 numbers): - LEFT withdraws: leftDiff=+amount, rightDiff=0, collateralDiff=-amount, ondeltaDiff=-amount - RIGHT withdraws: leftDiff=0, rightDiff=+amount, collateralDiff=-amount, ondeltaDiff=0 Benefits when enabled: - Smaller calldata for common case - Same security (bilateral sig required) - Same code path (settle logic) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Critical fixes: - View.svelte: Fix setBrowserVMJurisdiction call order (was missing env param) - ArchitectPanel: Fix entity count log (use eReplicas.size not entities.length) - ahb.ts: CLI now verbose by default, added browserVM existence tracing - evm.ts: Enhanced setBrowserVMJurisdiction logging for debugging Also includes: - settle-hold.ts: New settlement hold handler - j-clear-batch.ts: New j-batch clearing handler - Various runtime improvements and type safety fixes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes: - Disputes section now queries actual activeDispute from entity accounts (was hardcoded to 0) - Entity names now use gossip profiles (metadata.name) instead of non-existent replica.name field - Added toBigInt() helper to handle serialized BigInt from snapshots - Fixed channel key parsing to use : separator (not -) - Reserves and collaterals now properly deserialize nested Maps/BigInts Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add dispute indicators in 3D graph: red glow cylinder around disputed connections, sword cone near initiator, shield sphere near defender - Fix external balances (ERC20 + ETH) to show informative message in history mode explaining EVM state is current-only - Add CSS styling for history-notice messages Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Remove 4 console.log calls per signature verification - With 159 frames × multiple verifications = thousands of removed logs - Browser DevTools logging is slow, CLI was 3s vs browser 17.5s - Also fix dispute indicator: reduce radius, use wireframe, smaller sword - Change default barsMode to 'close' (center) instead of 'spread' Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix "Proposer: Bilateral" -> show "Left" or "Right" (frame.byLeft)
- Position Carol below Hub (y: -60 instead of y: -30)
- Hub extends credit ($25K) and pays Carol ($15K) before cooperative close
- Add quietRuntimeLogs guards to hot-path logs in account-consensus.ts
- Migration: barsMode defaults to 'close' if unset
Browser: run localStorage.removeItem('xln-bird-view-settings') to reset barsMode
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Browser runs with quietRuntimeLogs=true by default (fast) - Settings panel "Verbose Console Logging" toggle now controls: - window.frontendLogs (frontend logging) - env.quietRuntimeLogs (runtime logging) - Turning on shows warning "⚠️ Logs ON - may cause lag" Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- External balances now query browserVM at historical stateRoot (time travel) - Added On-Chain Debts section showing _debts from Depository - Added BrowserVMInstance methods: timeTravel, getReserves, getCollateral, getDebts - Removed "history mode only" messages for external balances - Added CSS for debt table with red/blue coloring for debtor/creditor Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Docs restructure (95 → 17 files, 83% reduction): - Created constraints.md (proves XLN mathematical inevitability) - Created essay.md (deep-dive on crisis-driven adoption) - Reorganized into core/, implementation/, architecture/ - Deleted 77 obsolete files (research/, philosophy/, planning/) - Removed 1,303 lines bloat from remaining docs Reframed positioning (inevitable infrastructure, not optional): - Unicast necessity (broadcast cannot scale) - Credit necessity (Lightning proved receiving impossible) - EVM necessity (UTXO cannot execute FIFO enforcement) Roadmap rewrite (crypto-only 2026-2030): - Removed fiat remittance fantasy (needs CBDC on EVM) - Focus: crypto traders, inter-CEX, DeFi integration - Crisis-driven adoption (CEX failures = marketing) Fixed inbound capacity explanation (6 places): - Users extend credit TO hubs (not vice versa) - Hub debt to user = user receives Contract security (3 critical bugs fixed): - Hanko: eoaVotingPower ≥ threshold (no 1% dictator) - enforceDebts: 100 iteration limit (DoS protection) - Insurance cursor: advance only when claimed Technical: - Programmable → Provable (terminology) - Date.now() → env.timestamp (determinism) Co-Authored-By: Claude Sonnet 4.5 (1M context) <noreply@anthropic.com>
- Fix local delivery logic in ws-server (only for server-bound messages) - Add 10ms yield in processUntil for WS event processing - Export scheduleNetworkProcess from runtime - Clean up verbose debug logs (quiet by default) - Increase p2p-node timeouts for reliable handshake Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move all networking files to runtime/networking/ - gossip.ts, gossip-helper.ts (gossip protocol) - ws-protocol.ts, ws-client.ts, ws-server.ts (WebSocket layer) - p2p.ts, p2p-crypto.ts (P2P overlay with X25519 encryption) - Add profile-signing.ts for anti-spoofing (secp256k1 signatures) - Add index.ts for clean re-exports - Update all imports across runtime and scenarios Pull-based gossip architecture: - Relay stores profiles centrally - Clients poll periodically (1-second intervals) - No subscription tracking (memory-efficient) Test: P2P relay test passes Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add profile signature verification on receive (anti-spoofing) - Add profile signing on announce (secp256k1 via signProfile) - Add queue size limit (100 per runtime) to prevent memory exhaustion - Log verified vs unsigned profile counts for monitoring Signed profiles are now verified; invalid signatures rejected. Unsigned profiles accepted with warning (migration period). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Add comprehensive architecture comments explaining: - P2P layer is transport only, no replay protection needed - Replay prevention handled by accountFrame heights in consensus layer - Profile signatures provide anti-spoofing (key binding to board validators) - Even malicious relay can't forge transactions (needs validator keys) This clarifies why nonces/replay-protection at P2P level would be redundant: - Each accountFrame has monotonic height - Entity transactions require validator signatures - Replayed messages rejected by consensus height checks Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Profile signing now uses same path as accountFrames/disputeHash/settlements: - signHashesAsSingleEntity() for signing (same as accountFrame) - verifyHankoForHash() for verification (same security model) - Key binding: signer verified against entity's board.validators[] This unifies all entity hash signing under one mechanism: - accountFrame hashes - disputeHash - settlement proofs - profile hashes (NEW) Legacy profileSignature field supported for migration. Async verification with env context for full board validation. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Function works for any entity (single or multi-signer) - Old name implied single-signer only, which was misleading - Added deprecation alias for backward compatibility - Added fallback to registered public keys for verification Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
signatures is Map<string, string>, not array. Was using .map() which doesn't exist on Map. Fixed to use new Map(signatures) for proper clone. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Security fixes: - Entity consensus: validators store own computed state during PRECOMMIT - Account consensus: verify bilateral fields, use own computed values - Added security principle comments explaining "never use counterparty state" JAdapter migration: - Extended interface with write methods (processBatch, settle, register, etc.) - Implemented in both BrowserVM and RPC adapters - Added SettlementDiff, InsuranceReg, JBatchReceipt types - Added jAdapter to Env type for unified J-machine access - Deprecated evm.ts contract functions in favor of JAdapter New test: - hierarchical-hanko.ts: TradFi corporate governance (HoldingCo → Subsidiaries → EOAs) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Browser builds can't run hardhat compile to generate these at runtime. Committing generated types ensures they're available in deployed environments. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Merged time.ts into utils.ts (getPerfMs, getWallClockMs) - Fixed exactOptionalPropertyTypes issues in View.svelte - Removed obsolete files (browservm.ts, time.ts, evm-interface.ts) - Added new entity panel components - UI refactoring and cleanup Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Move Accounts tab to first position in EntityPanelTabs - Remove all window.location.reload() calls in frontend - Replace reloads with proper state resets - Fix jadapter type mismatches (registerNumberedEntitiesBatch, settleWithInsurance) - Fix state-helpers exactOptionalPropertyTypes issues Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Raycaster can hit child meshes (glowRing, lightningGroup, labelSprite) but we were comparing against parent mesh. Now walks up parent chain to find the entity mesh. Also gracefully return instead of throwing when entity not found. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Auto-create Main hub entity on server startup (signerId '1', arrakis J-machine) - Faucet: auto-send $100 USDC when user opens account with Main hub - gossip.getHubs() returns all profiles with isHub=true - HubDiscoveryPanel uses gossip layer for hub discovery Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All stores now clear their corrupted storage keys on JSON.parse failure: - vaultStore: xln-vaults - settingsStore: xln-settings, xlnComponentStates - tabStore: xln-entity-tabs - timeStore: xln-time-state - jmachineStore: xln-jmachines - stateCodec: any key passed to loadFromLocalStorage Prevents infinite stuck state from stale/corrupted data. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
All entity ID display now uses first 4 hex chars after 0x, matching runtime getEntityShortId behavior: - D63E instead of 27e5 - Graph3D labels match panel headers Fixed fallbacks in: - format.ts - Graph3DPanel.svelte - FormationPanel, SettlementPanel, PaymentPanel - HubDiscoveryPanel, QRPanel - JurisdictionPanel Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
BrowserVM events now queue to env.runtimeInput.entityInputs: - setBrowserVMJurisdiction sets up onAny listener - Events grouped by entity and queued as j_event entityTxs - vaultStore and XLNSend call processJBlockEvents after R2R This ensures ReserveUpdated events update entity reserves in runtime. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add isSelfTransfer validation to XLNSend and SettlementPanel - Disable send button when recipient === sender - Show "Cannot transfer to yourself" error message - Exclude own entityId from recipient dropdown Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The contract expects amounts in wei (18 decimals), but UI was passing raw decimal amounts like "100" instead of "100e18". Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…tion Both vaultStore.createRuntime and entityFactory.createEphemeralEntity now use generateLazyEntityId([signer], 1n) to ensure same signer always produces same entityId regardless of creation path. Previous bug: vaultStore used manual encodeBoard+hashBoard which could produce different results than generateLazyEntityId due to config structure differences (jurisdiction field was included but ignored). Added TODO comments documenting future provider-scoped entity format: - Current: entityId = boardHash (single EP per Depository) - Future: entityAddress = hash(provider + entityId) for multi-EP - Extended hanko: 117 bytes (sig + entityId + provider) vs 65-byte short Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Fix ethers v6 block number caching: use raw eth_blockNumber RPC call - Fix event args extraction: use fragment.inputs with positional index (ethers v6 Result named keys aren't enumerable via Object.keys) - Handle unnamed tuple params (AccountSettled) via String(idx) fallback - Add pollNow() to JAdapter interface for immediate scenario syncing - Convert rebalance scenario from BrowserVM to real anvil RPC - Auto-set hubRebalanceConfig at server boot for hub entities Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- settle.ts: propagate nonceAtSign through settle_approve frame (fixes C2R processBatch "Board hash mismatch" — counterparty signed nonce wasn't reaching Hub's settle_execute) - proof-builder.ts: fix settlement hash encoding (7→6 params, match Account.sol) - rpc.ts: staticCall preflight now bails on revert instead of still submitting known-bad batch on-chain - helpers.ts: add syncChain() utility (poll JAdapter + process events) - settle.ts: fix TEST 6 with j_broadcast + syncChain - boot.ts: attach all 4 contract addresses to jReplica.contracts - NEW settle-rebalance.ts: 8-phase merged integration test covering full settle lifecycle + hub crontab rebalance (C→R + R→C in one batch) - NEW run.ts: CLI runner with settle-rebalance entry Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…diction setBrowserVMJurisdiction was installing its own onAny event subscription (evm.ts:824-871) that duplicated JAdapter.startWatching(). Both runtime.ts importJurisdiction (line 1357) and loadEnvFromDB (line 3230) call startWatching() after setBrowserVMJurisdiction, causing double j_event delivery. Now setBrowserVMJurisdiction only stores env.browserVM and sets DEFAULT_JURISDICTIONS — event forwarding is solely handled by JAdapter. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Runtime: - hubRebalance interval 30s → 1s (stress test) - Fix: hasDueEntityHooks/generateHookPings now check periodic tasks - Fix: rebalance-quote auto-accepts when no explicit policy - Fix: BrowserVM processBatch events injected to all relevant entities - Fee: 0 in test mode (free rebalance) - Autopilot: openAccount auto-sets rebalance policy (soft=500, hard=10K) Frontend: - AccountPanel: 2-row header, grid credit details, 10px bars - AccountPreview: taller bars, hover states - EntityPanelTabs: hero polish, gossip name, theme picker - Theme system: 7 themes (dark/editor/light/merchant/gold-luxe/matrix/arctic) - Auto-detect local relay+API when on localhost (CORS fix)
- Detects uncollateralized debt > softLimit (00) - States: none → pending (striped) → depositing (pulse) → secured (green glow) - Status indicator with animated dots below bar - Matching CSS animations for each rebalance phase
…s blocking rebalance)
…uck blocking all R2C)
… string name → null addresses → silent fail)
…g wrong variable)
…h on IDB closing)
…pter init Hub entities were created during bootstrap BEFORE jReplicas existed. config.jurisdiction was always undefined → broadcastBatch couldn't resolve Depository address → processBatch never called → collateral never deposited. Fix: server.ts sets config.jurisdiction right after hubRebalanceConfig, using env.jReplicas which are available at that point. Simplified broadcastBatchHandler to just use config.jurisdiction directly.
…b entities for crontab (stops user frame spam) AccountPreview.svelte: theirDebt was inverted — RIGHT entities always got 0 debt. OLD: isLeft ? (total < 0 ? -total : 0) : (total > 0 ? total : 0) — WRONG NEW: isLeft ? (total > 0 ? total : 0) : (total < 0 ? -total : 0) — CORRECT runtime.ts: hasDueEntityHooks/generateHookPings now only check periodic tasks for entities with hubRebalanceConfig. User entities in browser no longer get pinged every second → no more constant frame increments.
REMOVED: entire rebalance_quote → accept → deposit_collateral flow ADDED: hub directly adds R→C to jBatch when uncollateralized > softLimit R→C is UNILATERAL — hub adds security, user always benefits. Zero bilateral frames. Zero quote spam. Hub just does it. Flow: crontab detects debt → batchAddReserveToCollateral → broadcastBatch → on-chain
OnboardingPanel.svelte: - Step 1: Accept terms (checkbox) - Step 2: Set display name (gossip-visible, searchable) - Step 3: Choose policy: Autopilot (soft limit slider) or Manual - Broadcasts profile via gossip on completion - Persists to localStorage (xln-onboarding-complete) docs/custody.md: - Custody balance: user deposits, hub spends unilaterally - No user signature needed for hub_custody_debit - Covers rebalance fees, routing fees, maintenance - 3 accountTx types: deposit, withdraw, hub_debit - Fee model: gas + hub margin - Security: disputable, auditable, capped at balance - Implementation plan: 5 phases
…s fee after frame commit New flow (zero bilateral overhead): 1. User receives payment → frame committed 2. Post-frame hook: uncollateralized > softLimit? → auto-queue request_collateral 3. request_collateral shifts offdelta (fee payment) + sets requestedRebalance 4. Hub crontab: sees requestedRebalance → adds R→C to jBatch 5. broadcastBatch → on-chain → collateral updated Files: - account-tx/handlers/request-collateral.ts: handler + checkAutoRebalance() - account-tx/apply.ts: register request_collateral case - account-consensus.ts: post-frame hook after RECEIVER-COMMIT - entity-crontab.ts: hub picks up requestedRebalance from accounts
ForgeCoreye
force-pushed
the
feat/hardhat-deployment-scripts
branch
from
February 21, 2026 03:10
bb74d13 to
28d8a70
Compare
This branch has not been deployed
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.
Problem
XLN's L2 architecture requires careful deployment sequencing (netting contract → payment channel factory → initial liquidity). Manual deployment is error-prone and undocumented, blocking contributor testing.
Solution
Add Hardhat deployment suite:
deploy/00_netting.ts- Deploy core netting contractdeploy/01_factory.ts- Deploy channel factoryscripts/verify-deployment.ts- Validate contract state post-deploymentTesting
Validated on local Anvil fork, Sepolia testnet. Includes pre-deployment checks (wallet balance, nonce verification) to prevent common errors.