forked from Eclipse-Laboratories-Inc/eclipse-deposit
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[refactor] restructuring project to support mainnet beta and sepolia
- Loading branch information
Showing
11 changed files
with
1,349 additions
and
68 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"semi": true, | ||
"singleQuote": true, | ||
"trailingComma": "all" | ||
} | ||
|
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
# Deposit on Testnet | ||
# Eclipse Deposit CLI | ||
|
||
This script allows end users to deposit Ether from Sepolia to the Eclipse test network. | ||
This CLI tool allows end users to deposit Ether from Ethereum Mainnet or the Sepolia test network into the Eclipse rollup, which utilizes the Solana Virtual Machine (SVM). | ||
|
||
## Prerequisites | ||
|
||
|
@@ -14,8 +14,8 @@ An Ethereum wallet such as Phantom or Metamask is needed. | |
|
||
For Metamask: | ||
1. Choose the account you wish to use and copy its address. | ||
2. Visit the [Sepolia faucet](https://sepoliafaucet.com/) to airdrop tokens to yourself. | ||
3. To obtain your private key for later use, navigate to 'account details' in Metamask and select 'reveal private key'. | ||
2. Visit the [Sepolia faucet](https://sepoliafaucet.com/) to airdrop tokens to yourself, if using Sepolia. | ||
3. Navigate to 'account details' in MetaMask and select 'reveal private key'. Store this key in a secure file. | ||
|
||
### Solana CLI | ||
|
||
|
@@ -26,19 +26,53 @@ To generate a wallet for deposits: | |
2. To generate a wallet: | ||
- Execute `solana-keygen new --no-outfile` or `solana-keygen new --outfile my-wallet.json`. | ||
3. Copy the public key from the output, which should resemble `6g8wB6cJbodeYaEb5aD9QYqhdxiS8igfcHpz36oHY7p8`. | ||
## Installation | ||
|
||
1. Clone this repository: | ||
```bash | ||
git clone https://github.com/Eclipse-Laboratories-Inc/eclipse-deposit.git | ||
cd eclipse-deposit | ||
``` | ||
|
||
2. Install the necessary dependencies: | ||
```bash | ||
yarn install | ||
``` | ||
|
||
## Create a Deposit | ||
|
||
1. Obtain and set up the deposit.js script: | ||
- Clone this repository | ||
- Install script dependencies: | ||
- `yarn install` | ||
2. Execute the script: | ||
- `node deposit.js [Solana Address] 0x11b8db6bb77ad8cb9af09d0867bb6b92477dd68e [Amount in Gwei] [Ethereum Private Key] https://rpc.sepolia.org | ||
1. Run the CLI tool with the necessary options: | ||
```bash | ||
eclipse-deposit deposit -k <path_to_private_key> -d <solana_destination_address> -a <amount_in_ether> --mainnet|--sepolia [-r <rpc_url>] | ||
``` | ||
|
||
For example: | ||
|
||
**Mainnet Deposit:** | ||
```bash | ||
eclipse-deposit deposit -k /path/to/private-key.txt -d 6g8wB6cJbodeYaEb5aD9QYqhdxiS8igfcHpz36oHY7p8 -a 0.01 --mainnet | ||
``` | ||
|
||
**Sepolia Testnet Deposit:** | ||
```bash | ||
eclipse-deposit deposit -k /path/to/private-key.txt -d 6g8wB6cJbodeYaEb5aD9QYqhdxiS8igfcHpz36oHY7p8 -a 0.01 --sepolia | ||
``` | ||
|
||
**With Custom RPC URL:** | ||
```bash | ||
eclipse-deposit deposit -k /path/to/private-key.txt -d 6g8wB6cJbodeYaEb5aD9QYqhdxiS8igfcHpz36oHY7p8 -a 0.01 --mainnet -r https://custom-rpc-url | ||
``` | ||
|
||
- The `-k, --key-file` option specifies the path to the Ethereum private key file. | ||
- The `-d, --destination` option specifies the Solana destination address on the rollup (base58 encoded). | ||
- The `-a, --amount` option specifies the amount of Ether to deposit. | ||
- Use `--mainnet` or `--sepolia` to select the network. The tool will use different contract addresses depending on the network. | ||
- The `-r, --rpc-url` option is optional and allows overriding the default JSON RPC URL. | ||
|
||
## Security Note | ||
|
||
Keep your Ethereum private key secure. Do not share it publicly or expose it in untrusted environments. | ||
|
||
Details: | ||
- The `[Solana Address]` is the one you generated using the Solana CLI or Phantom. | ||
- The `[Ethereum Private Key]` is sourced from Metamask. | ||
- `[Amount in Gwei]` is the desired deposit amount, with a minimum of '1500000' gwei (0.0015 ETH). | ||
## Support | ||
|
||
Please reach out to [email protected] with additional questions | ||
For issues or questions, please contact [email protected]. |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
#!/usr/bin/env node | ||
|
||
const { Command } = require('commander'); | ||
const { runDeposit } = require('../src/lib'); | ||
const program = new Command(); | ||
|
||
program | ||
.name('eclipse-deposit') | ||
.description('CLI to deposit Ether into the Eclipse rollup') | ||
.version('2.0.0'); | ||
|
||
program | ||
.command('deposit') | ||
.description('Deposit Ether into the Eclipse rollup') | ||
.requiredOption('-k, --key-file <path>', 'Path to the Ethereum private key file') | ||
.requiredOption('-d, --destination <address>', 'Destination address on the rollup (base58 encoded)') | ||
.requiredOption('-a, --amount <ether>', 'Amount in Ether to deposit') | ||
.option('--mainnet', 'Use Ethereum Mainnet') | ||
.option('--sepolia', 'Use Sepolia test network') | ||
.option('-r, --rpc-url <url>', 'Optional: JSON RPC URL to override the default') | ||
.action((options) => { | ||
if (!options.mainnet && !options.sepolia) { | ||
console.error('Error: You must specify either --mainnet or --sepolia'); | ||
process.exit(1); | ||
} | ||
runDeposit(options); | ||
}); | ||
|
||
program.parse(process.argv); |
File renamed without changes.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
// eslint.config.js | ||
|
||
import { FlatCompat } from '@eslint/eslintrc'; | ||
import js from '@eslint/js'; | ||
import prettier from 'eslint-config-prettier'; | ||
import prettierPlugin from 'eslint-plugin-prettier'; | ||
import globals from 'globals'; | ||
|
||
const compat = new FlatCompat({ | ||
baseDirectory: import.meta.url, | ||
}); | ||
|
||
export default [ | ||
js.configs.recommended, | ||
prettier, | ||
{ | ||
files: ["**/*.js"], | ||
languageOptions: { | ||
ecmaVersion: 'latest', | ||
sourceType: 'module', | ||
globals: { | ||
...globals.node, | ||
...globals.es2021, | ||
}, | ||
}, | ||
plugins: { | ||
prettier: prettierPlugin, | ||
}, | ||
rules: { | ||
'prettier/prettier': 'error', | ||
}, | ||
}, | ||
]; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,14 +1,32 @@ | ||
{ | ||
"name": "ethereum-scripts", | ||
"version": "1.0.0", | ||
"description": "Utility and helper scripts for working on ethereum smart-contracts", | ||
"main": "index.js", | ||
"license": "None", | ||
"scripts": { | ||
"deposit": "node deposit.js" | ||
"name": "eclipse-deposit", | ||
"version": "2.0.0", | ||
"type": "module", | ||
"description": "A tool for depositing Ether into the Eclipse rollup, supporting both Sepolia and Ethereum Mainnet.", | ||
"main": "src/lib.js", | ||
"bin": { | ||
"eclipse-deposit": "bin/cli.js" | ||
}, | ||
"repository": "https://github.com/Eclipse-Laboratories-Inc/eclipse-deposit", | ||
"author": "Eclipse Labs Team", | ||
"license": "Apache-2.0", | ||
"private": false, | ||
"dependencies": { | ||
"bs58": "^5.0.0", | ||
"ethers": "^6.8.0" | ||
"@solana/web3.js": "^1.95.2", | ||
"bs58": "^6.0.0", | ||
"commander": "^12.1.0", | ||
"viem": "^2.18.4" | ||
}, | ||
"devDependencies": { | ||
"@eslint/eslintrc": "^3.1.0", | ||
"@eslint/js": "^9.8.0", | ||
"eslint": "^9.8.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-prettier": "^5.2.1", | ||
"prettier": "^3.3.3" | ||
}, | ||
"scripts": { | ||
"lint": "eslint 'src/**/*.js'", | ||
"format": "prettier --write 'src/**/*.js'" | ||
} | ||
} |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
const { readFileSync } = require('fs'); | ||
|
||
function getPrivateKeyFromFile(filePath) { | ||
try { | ||
return readFileSync(filePath, 'utf8').trim(); | ||
} catch (error) { | ||
throw new Error(`Failed to read private key from file: ${error.message}`); | ||
} | ||
} | ||
|
||
module.exports = { getPrivateKeyFromFile }; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
async function deposit(client, etherBridgeAddress, destination, amountWei) { | ||
try { | ||
// Define the ABI for the EtherBridge contract | ||
const abi = ['function deposit(bytes32,uint256) payable']; | ||
const contract = new client.Contract(etherBridgeAddress, abi); | ||
|
||
// Convert destination to bytes32 for compatibility | ||
const destinationBytes32 = `0x${Buffer.from(destination).toString('hex').padEnd(64, '0')}`; | ||
|
||
// Send the deposit transaction | ||
const tx = await contract.deposit(destinationBytes32, amountWei); | ||
console.log(`Transaction hash: ${tx.hash}`); | ||
} catch (error) { | ||
console.error(`Error during deposit: ${error.message}`); | ||
throw error; | ||
} | ||
} | ||
|
||
module.exports = deposit; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
const { createClient, parseEther } = require('viem'); | ||
const { getPrivateKeyFromFile } = require('./config'); | ||
const { validateSolanaAddress } = require('./validate'); | ||
const deposit = require('./deposit'); | ||
|
||
// Define network configurations | ||
const NETWORK_CONFIG = { | ||
mainnet: { | ||
etherBridgeAddress: '0xMainnetContractAddress', | ||
rpcUrl: 'todo', | ||
}, | ||
sepolia: { | ||
etherBridgeAddress: '0xSepoliaContractAddress', | ||
rpcUrl: 'https://rpc2.sepolia.org', | ||
}, | ||
}; | ||
|
||
async function runDeposit({ | ||
keyFile, | ||
destination, | ||
amount, | ||
mainnet, | ||
sepolia, | ||
rpcUrl, | ||
}) { | ||
try { | ||
// Determine the network and validate | ||
const network = mainnet ? 'mainnet' : sepolia ? 'sepolia' : null; | ||
if (!network) { | ||
throw new Error('Invalid network selection.'); | ||
} | ||
|
||
// Validate and decode destination address | ||
if (!validateSolanaAddress(destination)) { | ||
throw new Error('Invalid Solana address.'); | ||
} | ||
|
||
// Parse and validate the amount | ||
const amountWei = parseEther(amount); | ||
|
||
// Retrieve the private key from file | ||
const privateKey = getPrivateKeyFromFile(keyFile); | ||
|
||
// Get network-specific configuration | ||
const { etherBridgeAddress, rpcUrl: defaultRpcUrl } = | ||
NETWORK_CONFIG[network]; | ||
const effectiveRpcUrl = rpcUrl || defaultRpcUrl; | ||
|
||
// Set up the client | ||
const client = createClient({ | ||
transport: effectiveRpcUrl, | ||
wallet: { privateKey }, | ||
}); | ||
|
||
// Call the deposit function with the validated inputs | ||
await deposit(client, etherBridgeAddress, destination, amountWei); | ||
} catch (error) { | ||
console.error(`Error: ${error.message}`); | ||
process.exit(1); | ||
} | ||
} | ||
|
||
module.exports = { | ||
runDeposit, | ||
}; |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
const bs58 = require('bs58'); | ||
const { PublicKey } = require('@solana/web3.js'); | ||
|
||
// List of known Solana native program addresses | ||
const SOLANA_NATIVE_PROGRAMS = new Set([ | ||
'11111111111111111111111111111111', // System Program | ||
'TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA', // SPL Token Program | ||
'Stake11111111111111111111111111111111111111', // Stake Program | ||
// Add other known native programs as needed | ||
]); | ||
|
||
// Function to validate Solana address | ||
function validateSolanaAddress(address) { | ||
try { | ||
// Decode the base58 address | ||
const decoded = bs58.decode(address); | ||
|
||
// Check the length to ensure it's a valid Ed25519 public key | ||
if (decoded.length !== 32) { | ||
throw new Error('Invalid length for a Solana address.'); | ||
} | ||
|
||
// Convert the decoded address to a PublicKey object | ||
const publicKey = new PublicKey(decoded); | ||
|
||
// Check if the address is a known native program | ||
if (SOLANA_NATIVE_PROGRAMS.has(publicKey.toString())) { | ||
throw new Error('Address is a reserved Solana native program.'); | ||
} | ||
|
||
// Additional check using Solana Web3's PublicKey class for verification | ||
if (!PublicKey.isOnCurve(publicKey.toBuffer())) { | ||
throw new Error('Address is not a valid Ed25519 public key.'); | ||
} | ||
|
||
return true; | ||
} catch (error) { | ||
console.error(`Validation error: ${error.message}`); | ||
return false; | ||
} | ||
} | ||
|
||
module.exports = { validateSolanaAddress }; |
Oops, something went wrong.