feat(tranch4): Solidity/EAS/Bridge Infrastructure #68
Merged
wasabi opened 3 days ago

Tranch 4: Solidity / EAS / Bridge Infrastructure

Implements the foundational on-chain infrastructure for Kokonut Intelligence: smart contracts, EAS attestation pipeline, and cross-chain bridge support.

Work Items (7/7 Complete)

Work 1-2: EAS Data-Stream Anchoring + Ethereum Config

  • signer_service.py — Polls pending attestation_request queue, submits via EAS
  • reconciliation.py — Backfills missing UIDs, detects orphans, verifies onchain
  • anchor.py — Rewritten with pending_anchor intermediate state; is_anchored only set after signer confirms onchain
  • Migration 345 — Signing attempt tracking on attestation_request
  • Ethereum mainnet EAS addresses added to attestation config

Work 3: KokonutCreditToken (ERC-1155 UUPS)

  • KokonutCreditToken.sol — ERC-1155 with issue/retire/batchIssue, role-based access, non-transferable credits
  • 12 Forge tests, deployment script, PostgreSQL-chain sync service

Work 4: KGP Deployment on Gnosis

  • kgp_deploy.py — record_deployment, get_deployment, list_deployments, verify_deployment
  • Migration 346 — kgp_protocol_deployment table

Work 5: Marketplace Fee Settlement

  • marketplace.py — Wired collect_fee() into execute_buy_order with buyer/seller fee split
  • fees.py — Over-distribution guard
  • Migration 347 — Fee columns on credit_buy_order

Work 6: Selective-Disclosure / Merkle Proofs

  • KokonutSelectiveDisclosure.sol — On-chain Merkle root verifier for selective field disclosure
  • 6 Forge tests, Python Merkle tree construction and proof verification
  • Migration 348 — disclosure_proof table

Work 7: Oracle Price Attestation on Ethereum

  • KokonutPriceOracle.sol — On-chain price feed with EAS attestation linkage, confidence thresholds, max age, history buffer
  • 7 Forge tests, PostgreSQL-to-Oracle sync service

Testing

  • Forge: 62/62 tests pass (49 existing + 13 new across 3 contracts)
  • Python: All modified files compile cleanly

Migrations

  • 345: attestation_request signing columns + data_stream_post.content_hash
  • 346: kgp_protocol_deployment table
  • 347: credit_buy_order fee columns
  • 348: disclosure_proof table

Architecture Notes

  • Ethereum is hub chain — Oracle + Credit tokens live here. L2s leverage native bridges.
  • Celo OP Stack — EAS v1.3.0 deployed at 0x72E1d8ccf5299fb36fEfD8CC4394B8ef7e98Af92
  • kokonut-data-post schema activated in seed 014

Closes KKN-215

Commits were merged into target branch
  • feat(tranch4): EAS data-stream anchoring pipeline + Ethereum EAS config
    Work 1: EAS Data-Stream Post Anchoring
    - signer_service.py: processes pending attestation_request queue, submits
      onchain via EASClient, updates data_stream_post.attestation_uid on confirm
    - reconciliation.py: backfills missing UIDs from confirmed requests, detects
      orphaned anchored posts, verifies onchain attestation existence
    - anchor.py: rewritten to use pending_anchor intermediate state (no longer
      sets is_anchored=TRUE before onchain confirmation); adds anchor_batch,
      content hash dedup, idempotent request creation
    - CLI: add anchor-batch, reconcile, status, process commands
    - migration 345: signing_attempts, last_signing_at, error_message on
      attestation_request; content_hash on data_stream_post
    - seed 014: activate kokonut-data-post schema (active=TRUE)
    
    Work 2: Ethereum Mainnet EAS Configuration
    - attestation/config.py: add ethereum mainnet EAS addresses (EAS v0.26)
    - ingestion/config.py: add ethereum to EAS_CHAIN_CONFIG
    
    Closes KKN-215 Work 1 and Work 2
    3 days ago
    feat(tranch4): KokonutCreditToken ERC-1155 on Ethereum + chain sync
    Work 3: KokonutCreditToken (ERC-1155) on Ethereum
    - contracts/src/KokonutCreditToken.sol: ERC-1155 UUPS credit token
      following KGP pattern (non-transferable, role-based access)
      - issue/retire/batchIssue with evidence hash tracking
      - totalIssued/totalRetired/isRetired per token
      - availableBalance view for remaining tradable credits
    - contracts/test/KokonutCreditToken.t.sol: 12 tests covering
      initialize, issue, retire, batch issue, non-transferability,
      pause, zero address/amount validation, balance tracking
    - contracts/script/DeployKokonutCreditToken.s.sol: deployment
      script for Ethereum mainnet
    - services/credit_class/chain_sync.py: PostgreSQL <-> onchain
      reconciliation (sync_credits_to_chain, verify_chain_balance,
      reconcile_all)
    
    Forge: 49/49 tests pass (12 new + 37 existing)
    
    Closes KKN-215 Work 3
    3 days ago
    feat(tranch4): KGP deployment orchestration for Gnosis
    Work 4: KGP Deployment on Gnosis
    - services/guilds/kgp_deploy.py: deployment orchestration service
      with record_deployment, get_deployment, list_deployments,
      verify_deployment functions
    - schemas/postgres/346_kgp_deployment.sql: migration for
      kgp_protocol_deployment table tracking deployed contracts per chain
    
    Closes KKN-215 Work 4
    3 days ago
    feat(tranch4): wire marketplace fee settlement into buy order execution
    Work 5: Marketplace Fee Settlement
    - marketplace.py: collect_fee() now called inside execute_buy_order(),
      computing buyer_fee and seller_fee from ecocredit_params and persisting
      them in the buy order result
    - fees.py: added over-distribution guard in distribute_fee() that checks
      SUM(distributed.amount) <= total_fee before allowing further distribution
    - schemas/postgres/347_marketplace_fee_settlement.sql: adds buyer_fee and
      seller_fee columns to credit_buy_order
    
    Closes KKN-215 Work 5
    3 days ago
    feat(tranch4): selective-disclosure Merkle evidence proofs
    Work 6: Selective-Disclosure / Merkle Evidence Proofs
    - contracts/src/KokonutSelectiveDisclosure.sol: on-chain Merkle root
      verifier for selective field disclosure (setRoot, verifyProof)
    - contracts/test/KokonutSelectiveDisclosure.t.sol: 6 tests covering
      root setting, proof verification, access control, pause
    - services/attestation/selective_disclosure.py: Python Merkle tree
      construction, proof generation, verification, and attestation
      preparation (build_disclosure_tree, generate_proof, verify_proof,
      prepare_disclosure_attestation)
    - schemas/postgres/348_selective_disclosure.sql: disclosure_proof
      table for tracking roots per attestation
    
    Forge: 55/55 tests pass (6 new + 49 existing)
    
    Closes KKN-215 Work 6
    3 days ago
    feat(tranch4): Oracle price attestation on Ethereum
    Work 7: Oracle Price Attestation on Ethereum
    - contracts/src/KokonutPriceOracle.sol: on-chain price feed with
      EAS attestation linkage (updatePrice, getPrice, getPriceHistory,
      confidence thresholds, max age, history buffer)
    - contracts/test/KokonutPriceOracle.t.sol: 7 tests covering price
      updates, zero price revert, confidence threshold, history tracking,
      feed existence, pause
    - services/ingestion/oracle_price_sync.py: sync service for
      PostgreSQL price observations to onchain Oracle (dry run)
    
    Forge: 62/62 tests pass (7 new + 55 existing)
    
    Closes KKN-215 Work 7
    3 days ago
  • fix(tests): correct CRISP transparency key and roadmap review param
    - test_score_transparency: use governance_body key (not decision_method)
      to match _score_transparency implementation
    - test_technology_roadmap_lifecycle: pass reviewed_by to review_roadmap
      to satisfy human-oversight requirement
    3 days ago
  • fix(migration): renumber 345_eas_data_stream_anchor to 349
    After merging Tranch 3 (PR #67) into main, 345_threat_signal_dedup.sql
    claimed version 345. Renumber to 349 to resolve duplicate.
    3 days ago
  • fix: apply migrations one-at-a-time to eliminate SIGPIPE (exit 141) in CI
    The monolithic _apply_files() batched all pending migrations into a single
    psql session via subprocess.run(input=<2 MB>). When piped through
    docker compose exec -T, a statement failure inside a BEGIN/COMMIT block
    (e.g. 061_impact_value_chain.sql) with ON_ERROR_STOP=1 caused psql to
    exit early, triggering BrokenPipeError → SIGPIPE (141) — the root cause
    of recurring CI failures on builds 7, 8, and 11.
    
    Rewrite _apply_files() to apply each migration in its own _psql() call:
    - First checks if already applied (SELECT → \gset)
    - If not, runs the migration SQL + tracking INSERT in one session
    - Successfully applied migrations are committed before the next starts
    - A failure in one migration does not kill the pipe for subsequent ones
    - On re-run, already-applied migrations are skipped via ON CONFLICT
    
    Also replace cat|psql pipe patterns in seed.sh and seed-pilot.sh with
    input redirection (< file) to eliminate the same SIGPIPE vector in
    curated seed application.
    
    Remove dead code: ADVISORY_LOCK_KEY constant, _migration_is_applied_sql().
    3 days ago
  • fix: write SQL to temp file with shell redirection instead of stdin pipe
    The per-migration approach (one _psql() call per migration) resolved the
    monolithic SIGPIPE but not migration-specific SIGPIPE at 061. The root
    cause is subprocess.run(input=...) piping SQL through Python's stdin to
    docker compose exec -T database psql — when psql exits early (e.g. an
    error inside BEGIN/COMMIT with ON_ERROR_STOP=1), the Python-level pipe
    breaks and triggers SIGPIPE (exit 141).
    
    Replace stdin piping with temp file + shell input redirection:
      docker compose exec ... psql < /tmp/mig.sql
    
    This matches the fix already applied to seed.sh and seed-pilot.sh:
    shell-level file redirection avoids the Python subprocess stdin pipe
    that was the SIGPIPE vector. Temp files are created per-call and
    cleaned up in a finally block.
    3 days ago
  • fix(migration): remove duplicated docker compose exec in _psql and quote variable args
    The temp-file rewrite of _psql() duplicated the 'docker compose exec
    -T database' prefix: psql_args already contained it, then shell_cmd
    added it again. This caused 'exec: docker: not found' inside the
    database container (which has no docker binary). Also shell-quote
    psql_args via shlex.quote() to prevent injection via -v variables.
    3 days ago
  • ci: increase bootstrap error output from head -60 to head -200
    The Clean PostgreSQL bootstrap failure was hiding the actual SQL error
    because head -60 truncated the output right after the schema name
    listing. Increase to head -200 so the full error message is visible
    in CI logs.
    3 days ago
  • ci: show tail -80 of bootstrap error output instead of head -200
    The migration CLI prints all 341 schema names BEFORE applying them,
    so head -200 only shows schema names and never reaches the actual
    error message. Switch to tail -80 which captures the last 80 lines
    including the actual SQL error and failing migration.
    3 days ago
  • fix: migration 346 - add chain column to kgp_protocol_deployment
    Migration 317 created the table with chain_id (INTEGER), but the
    Python code (kgp_deploy.py) uses chain (VARCHAR). 346's CREATE TABLE
    was a no-op (IF NOT EXISTS), then the index on chain failed with
    'column does not exist'. Replace with ALTER TABLE ADD COLUMN IF NOT
    EXISTS + index creation.
    3 days ago
  • fix(migration): remove broken -F flag from _psql and split on default | separator
    psql's -F flag does not interpret escape sequences. The change from
    subprocess.run(list) to sh -c '...' with shlex.quote() in 4ab3191
    turned the tab byte into a literal \t string, breaking _get_applied()
    parsing when schema_migration has rows. Bootstrap passes because the
    fresh DB table is empty on first parse. Removes -F entirely (default |)
    and splits on | instead of tab.
    3 days ago
    fix: resolve 3 remaining CI test failures
    - test_anchor_post: add _fake_conn_sequential helper, fix mock to return
      None for existing attestation query and account for _store_content_hash
      UPDATE call (5 mock responses needed)
    - test_execute_buy_order: add total_price to buy_order mock, add 2 missing
      mock responses for fees.get_fee_params inside collect_fee (12 total)
    - test_technology_roadmap: change reviewed_by from 'test-user' to valid
      UUID (review_roadmap casts to ::uuid)
    3 days ago
  • wasabi merged 3 days ago
1/1
Submitter wasabi
Target main
Source feat/tranch4-solidity-eas-bridge
Jobs
Merge Strategy
Create Merge Commit
Watchers (1)
Reference
pull request KI-68
Please wait...
Connection lost or session expired, reload to recover
Page is in error, reload to recover