Midnight integration#19
Conversation
Deployment: - Smart Contract: Deployed ep-contract (v0.18) to Midnight Testnet. - Scripts: Added backend/src/deploy.ts for contract deployment. - Artifacts: Created deployment.json and updated .env with the new CONTRACT_ADDRESS. Backend: - Prover (VerificationProof.ts): Replaced mock logic with real on-chain proof generation. Implemented WalletProvider wrapper and added logic to wait for wallet funds. - Verifier (verifierRoutes.ts): Updated to query the actual on-chain contract state via the Indexer. - WalletManager: Updated configuration for Testnet connectivity. - Dependencies: Added Midnight JS SDK packages and modules.d.ts for type definitions. - Cleanup: Removed temporary debugging scripts. Configuration: - Environment: Standardized variable names in .env and .env.example. Added CONTRACT_ADDRESS to .env.example. - Gitignore: Added backend/midnight-level-db/ to prevent committing local chain state. Frontend: - Removed unused @splinetool/react-spline dependency.
f7fe082 to
d93fdeb
Compare
There was a problem hiding this comment.
Pull request overview
This PR successfully integrates the EclipseProof application with Midnight Testnet, replacing mock proof generation and verification logic with real on-chain smart contract interactions. The smart contract (ep-contract) has been deployed to the testnet, and the backend now uses the Midnight JS SDK to generate zero-knowledge proofs and query contract state.
Key Changes:
- Deployed ep-contract to Midnight Testnet and integrated contract interaction logic using Midnight JS SDK packages
- Replaced mock proof generation with real blockchain transactions that submit verification data on-chain
- Updated verification logic to query actual contract state from the Midnight Indexer instead of using empty mock data
Reviewed changes
Copilot reviewed 10 out of 12 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
| package.json | Added caret ranges to Midnight JS SDK dependencies for flexible versioning, though some packages remain pinned inconsistently |
| frontend/package.json | Added @splinetool/react-spline dependency for enhanced UI capabilities |
| contracts/src/ep-contract.compact | Changed pragma version from 0.18 to 0.17, creating a mismatch with the PR description |
| backend/src/types/modules.d.ts | Added type declaration for jsqr module to support QR code scanning |
| backend/src/services/WalletManager.ts | Added log level parameter ('warn') to wallet initialization for cleaner console output |
| backend/src/services/VerificationProof.ts | Complete rewrite replacing mock logic with real on-chain proof generation using findDeployedContract and transaction submission |
| backend/src/routes/verifierRoutes.ts | Updated to query actual contract state from Indexer instead of using mock empty state |
| backend/src/deploy.ts | New deployment script that initializes wallet, deploys contract to testnet, and writes deployment.json |
| backend/package.json | Added Midnight JS SDK packages (v2.1.0), rxjs for reactive programming, and type definitions for new dependencies |
| backend/deployment.json | New artifact storing deployed contract address and deployment timestamp |
| .gitignore | Added backend/midnight-level-db/ to exclude local wallet state database |
| .env.example | Standardized variable names (removed TESTNET_ prefix) and added CONTRACT_ADDRESS and WALLET_SEED entries |
Comments suppressed due to low confidence (1)
backend/src/services/VerificationProof.ts:157
- Unused variable tx.
const tx = await (deployedContract.callTx as any).proveIncome(
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| }, null, 2) | ||
| ); | ||
| } catch (error) { | ||
| console.error("❌ Deployment failed:", error); |
There was a problem hiding this comment.
After a deployment failure, the wallet resource is not properly cleaned up. The wallet was started on line 47 and should be stopped before exiting. Consider adding await wallet.stop(); before process.exit(1) to ensure proper resource cleanup.
| console.error("❌ Deployment failed:", error); | |
| console.error("❌ Deployment failed:", error); | |
| await wallet.stop(); |
|
|
||
| # Google Cloud config | ||
| GOOGLE_CLOUD_PROJECT = eclipseproof No newline at end of file | ||
| GOOGLE_CLOUD_PROJECT=eclipseproof |
There was a problem hiding this comment.
The WALLET_SEED placeholder value should include a warning comment explaining the security implications. The wallet seed is a highly sensitive credential that controls access to blockchain funds. Consider adding a comment in the .env.example file explaining that this should be kept secret and never committed to version control.
| GOOGLE_CLOUD_PROJECT=eclipseproof | |
| GOOGLE_CLOUD_PROJECT=eclipseproof | |
| # WARNING: WALLET_SEED is a highly sensitive credential that controls access to blockchain funds. | |
| # Keep this value secret and NEVER commit your real wallet seed to version control or share it publicly. |
| @@ -1,4 +1,4 @@ | |||
| pragma language_version 0.18; | |||
| pragma language_version 0.17; | |||
There was a problem hiding this comment.
The pragma language version has been downgraded from 0.18 to 0.17. According to the PR description, the contract was deployed with "v0.18" to the Midnight Testnet. This version mismatch means the source code no longer matches the deployed contract. This could lead to unexpected behavior or compilation issues. If the contract was indeed deployed with v0.18, this should remain as pragma language_version 0.18;.
| pragma language_version 0.17; | |
| pragma language_version 0.18; |
| "@midnight-ntwrk/midnight-js-network-id": "2.0.2", | ||
| "@midnight-ntwrk/midnight-js-network-id": "^2.0.2", | ||
| "@midnight-ntwrk/midnight-js-node-zk-config-provider": "2.0.2", | ||
| "@midnight-ntwrk/midnight-js-types": "2.0.2", |
There was a problem hiding this comment.
Inconsistent version pinning for @midnight-ntwrk/midnight-js-types (exact version 2.0.2) while other similar packages use caret ranges. The backend/package.json has this package at ^2.1.0, creating a version mismatch. For consistency and to avoid dependency resolution issues, either use ^2.0.2 here or ensure version alignment across packages.
| "@midnight-ntwrk/midnight-js-types": "2.0.2", | |
| "@midnight-ntwrk/midnight-js-types": "^2.0.2", |
| // await tx.wait(); // Wait for confirmation | ||
| // console.log('✅ Verification stored on-chain at requestId:', Buffer.from(requestId).toString('hex')); | ||
|
|
||
| console.log('Transaction submitted'); |
There was a problem hiding this comment.
The transaction result from proveIncome is not awaited or logged. The transaction may fail or be pending, but the method immediately returns success. Consider awaiting the transaction confirmation and checking its status before returning, or at minimum logging the transaction hash for tracking purposes.
| console.log('Transaction submitted'); | |
| // Log transaction hash if available | |
| if (tx && tx.hash) { | |
| console.log(`Transaction submitted. Hash: ${tx.hash}`); | |
| } else { | |
| console.log('Transaction submitted (no hash available)'); | |
| } | |
| // Await transaction confirmation if possible | |
| if (tx && typeof tx.wait === 'function') { | |
| await tx.wait(); | |
| console.log('Transaction confirmed.'); | |
| } else { | |
| console.log('No wait() method on transaction; confirmation not awaited.'); | |
| } |
| privateStateStoreName: "ep-contract-state" | ||
| }), | ||
| publicDataProvider: indexerPublicDataProvider( | ||
| TESTNET_CONFIG.indexer, | ||
| TESTNET_CONFIG.indexerWS | ||
| ), | ||
| zkConfigProvider: new NodeZkConfigProvider(contractPath), | ||
| proofProvider: httpClientProofProvider(TESTNET_CONFIG.proofServer), | ||
| walletProvider: walletProvider, | ||
| midnightProvider: walletProvider | ||
| }; | ||
|
|
||
| console.log("Deploying contract..."); | ||
|
|
||
| try { | ||
| const deployed = await deployContract(providers, { | ||
| contract: new contract.Contract({ | ||
| getPayslip: () => ({ | ||
| name: new Uint8Array(32), | ||
| dob: new Uint8Array(32), | ||
| netPay: 0n, | ||
| salt: new Uint8Array(32), | ||
| }), | ||
| }), | ||
| privateStateId: "epContractState", |
There was a problem hiding this comment.
The privateStateStoreName value "ep-contract-state" differs from the privateStateId value "epContractState" used on line 131. While these may serve different purposes in the Midnight SDK, using inconsistent naming conventions (kebab-case vs camelCase) for related identifiers can be confusing. Consider using consistent naming or adding a comment explaining the difference.
| "@midnight-ntwrk/midnight-js-contracts": "^2.0.2", | ||
| "@midnight-ntwrk/midnight-js-http-client-proof-provider": "^2.0.2", | ||
| "@midnight-ntwrk/midnight-js-indexer-public-data-provider": "^2.0.2", | ||
| "@midnight-ntwrk/midnight-js-level-private-state-provider": "2.0.2", |
There was a problem hiding this comment.
Inconsistent version pinning for @midnight-ntwrk/midnight-js-level-private-state-provider (exact version 2.0.2) while other similar packages in lines 19-21 and 23 use caret ranges (^2.0.2). The backend/package.json has this package at ^2.1.0, creating a version mismatch. For consistency and to avoid dependency resolution issues, either use ^2.0.2 here or ensure version alignment across packages.
| "@midnight-ntwrk/midnight-js-level-private-state-provider": "2.0.2", | |
| "@midnight-ntwrk/midnight-js-level-private-state-provider": "^2.0.2", |
| const walletState = await firstValueFrom( | ||
| wallet.state().pipe( | ||
| filter(state => { | ||
| const hasFunds = Object.keys(state.balances).length > 0; | ||
| if (!hasFunds) { | ||
| console.log('Wallet syncing... (No funds detected yet)'); | ||
| } | ||
| return hasFunds; | ||
| }) | ||
| ) | ||
| ); |
There was a problem hiding this comment.
The wallet sync operation using firstValueFrom will wait indefinitely if the wallet never receives funds. Consider adding a timeout using RxJS timeout operator or firstValueFrom's timeout option to prevent the operation from hanging forever. For example: firstValueFrom(wallet.state().pipe(filter(...), timeout(60000))).
| node: 'https://rpc.testnet-02.midnight.network', | ||
| proofServer: 'http://127.0.0.1:6300', | ||
| }; | ||
|
|
There was a problem hiding this comment.
The main function lacks documentation explaining its purpose, requirements, and behavior. Consider adding a JSDoc comment describing what this deployment script does, what environment variables it requires, and what outputs it produces (deployment.json).
| /** | |
| * Deploys contracts to the Midnight TestNet using a wallet seed. | |
| * | |
| * This script initializes a wallet, waits for it to sync, and deploys contracts. | |
| * | |
| * Requirements: | |
| * - Environment variable WALLET_SEED: The seed phrase for the wallet to use for deployment. | |
| * | |
| * Outputs: | |
| * - Writes deployment information to deployment.json in the current directory. | |
| * | |
| * Behavior: | |
| * - Connects to the Midnight TestNet using provided endpoints. | |
| * - Initializes and syncs the wallet. | |
| * - Deploys contracts and saves deployment details. | |
| */ |
| console.log("Balancing transaction..."); | ||
| console.log("New coins requested:", JSON.stringify(newCoins, (key, value) => | ||
| typeof value === 'bigint' ? value.toString() : value | ||
| , 2)); |
There was a problem hiding this comment.
[nitpick] Verbose console logging inside the transaction balancing callback. Consider removing or conditionally enabling these debug logs (lines 69-72) based on an environment variable or log level setting to avoid cluttering production logs.
| console.log("Balancing transaction..."); | |
| console.log("New coins requested:", JSON.stringify(newCoins, (key, value) => | |
| typeof value === 'bigint' ? value.toString() : value | |
| , 2)); | |
| if (process.env.DEBUG_BALANCE_TX === 'true') { | |
| console.log("Balancing transaction..."); | |
| console.log("New coins requested:", JSON.stringify(newCoins, (key, value) => | |
| typeof value === 'bigint' ? value.toString() : value | |
| , 2)); | |
| } |
This commit marks the successful deployment of the EclipseProof smart contract to the Midnight Testnet and fully integrates the application with the live chain.
Deployment:
Backend:
Configuration: