Skip to content

Commit 0c1cd29

Browse files
committed
init commit
1 parent 47a07b8 commit 0c1cd29

File tree

13 files changed

+357
-0
lines changed

13 files changed

+357
-0
lines changed

.DS_Store

6 KB
Binary file not shown.

.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
RPC_URL=https://mainnet.infura.io/v3/your_project_id
2+
PRIVATE_KEY=your_private_key_here

.github/workflows/ci.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
name: CI
3+
4+
on:
5+
push:
6+
branches: [main]
7+
pull_request:
8+
branches: [main]
9+
10+
jobs:
11+
build:
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v2
15+
- name: Install Rust
16+
uses: actions-rs/toolchain@v1
17+
with:
18+
toolchain: stable
19+
profile: minimal
20+
override: true
21+
- name: Run fmt
22+
run: cargo fmt --all -- --check
23+
- name: Run tests
24+
run: cargo test

README.md

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
2+
# eth-rust-sdk
3+
4+
A modular, async-ready Rust SDK for interacting with Ethereum smart contracts using [ethers-rs](https://github.com/gakonst/ethers-rs).
5+
Includes support for:
6+
- **ERC-721 (NFTs)**
7+
- **DAOs**
8+
- **Staking contracts**
9+
- **ERC-20 tokens**
10+
- **Vault contracts**
11+
12+
---
13+
14+
## Features
15+
16+
- Modular design: each contract type is a separate module
17+
- Uses `ethers-rs` for provider, signer, and contract bindings
18+
- Works with any Ethereum-compatible chain (Mainnet, Goerli, Polygon, etc.)
19+
- Includes usage examples and `.env` configuration
20+
21+
---
22+
23+
## Setup
24+
25+
1. Clone this repo and enter the directory:
26+
```bash
27+
git clone https://github.com/bitcodr/eth-rust-sdk.git
28+
cd eth-rust-sdk
29+
```
30+
31+
2. Copy the `.env.example` to `.env` and add your Infura/Alchemy RPC + private key:
32+
```env
33+
RPC_URL=https://mainnet.infura.io/v3/your_project_id
34+
PRIVATE_KEY=your_private_key_here
35+
```
36+
37+
3. Build the project:
38+
```bash
39+
cargo build
40+
```
41+
42+
---
43+
44+
## Examples
45+
46+
Each module includes a sample usage file inside `/examples`.
47+
48+
Run them like this:
49+
50+
```bash
51+
cargo run --example fetch_nft_metadata
52+
cargo run --example dao_info
53+
cargo run --example staking_balance
54+
```
55+
56+
---
57+
58+
## Modules
59+
60+
- `nft`: Query token URI, owner, and transfer
61+
- `dao`: Read proposals and vote
62+
- `staking`: Stake/unstake and read earnings
63+
- `erc20`: Token transfers, approvals, balances
64+
- `vault`: Deposit, withdraw, and check balances
65+
66+
---
67+
68+
## Development
69+
70+
- Format code:
71+
```bash
72+
cargo fmt
73+
```
74+
75+
- Run unit tests:
76+
```bash
77+
cargo test
78+
```
79+
80+
---
81+
82+
## License
83+
84+
MIT © [bitcodr](https://github.com/bitcodr)

examples/dao_info.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
use ethers::prelude::*;
3+
use std::sync::Arc;
4+
use dotenv::dotenv;
5+
use std::env;
6+
use eth_rust_sdk::dao::DaoClient;
7+
8+
#[tokio::main]
9+
async fn main() -> anyhow::Result<()> {
10+
dotenv().ok();
11+
let rpc_url = env::var("RPC_URL")?;
12+
let private_key = env::var("PRIVATE_KEY")?;
13+
let provider = Provider::<Http>::try_from(rpc_url)?.interval(std::time::Duration::from_millis(10));
14+
let wallet: LocalWallet = private_key.parse()?;
15+
let client = Arc::new(SignerMiddleware::new(provider, wallet.with_chain_id(1u64)));
16+
17+
let dao_address: Address = "0xYourDaoContractAddressHere".parse()?;
18+
let dao = DaoClient::new(dao_address, client);
19+
20+
let (id, description, votes) = dao.get_proposal(U256::from(0)).await?;
21+
println!("Proposal {}: {} ({} votes)", id, description, votes);
22+
23+
Ok(())
24+
}

examples/fetch_nft_metadata.rs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
use ethers::prelude::*;
3+
use std::sync::Arc;
4+
use dotenv::dotenv;
5+
use std::env;
6+
use eth_rust_sdk::nft::NftClient;
7+
8+
#[tokio::main]
9+
async fn main() -> anyhow::Result<()> {
10+
dotenv().ok();
11+
let rpc_url = env::var("RPC_URL")?;
12+
let private_key = env::var("PRIVATE_KEY")?;
13+
let provider = Provider::<Http>::try_from(rpc_url)?.interval(std::time::Duration::from_millis(10));
14+
let wallet: LocalWallet = private_key.parse()?;
15+
let client = Arc::new(SignerMiddleware::new(provider, wallet.with_chain_id(1u64)));
16+
17+
let nft_address: Address = "0xYourNftContractAddressHere".parse()?;
18+
let nft = NftClient::new(nft_address, client.clone());
19+
20+
let token_id = U256::from(1);
21+
println!("Owner: {}", nft.owner_of(token_id).await?);
22+
println!("Token URI: {}", nft.token_uri(token_id).await?);
23+
Ok(())
24+
}

examples/staking_balance.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
use ethers::prelude::*;
3+
use std::sync::Arc;
4+
use dotenv::dotenv;
5+
use std::env;
6+
use eth_rust_sdk::staking::StakingClient;
7+
8+
#[tokio::main]
9+
async fn main() -> anyhow::Result<()> {
10+
dotenv().ok();
11+
let rpc_url = env::var("RPC_URL")?;
12+
let private_key = env::var("PRIVATE_KEY")?;
13+
let provider = Provider::<Http>::try_from(rpc_url)?.interval(std::time::Duration::from_millis(10));
14+
let wallet: LocalWallet = private_key.parse()?;
15+
let client = Arc::new(SignerMiddleware::new(provider, wallet.with_chain_id(1u64)));
16+
17+
let staking_address: Address = "0xYourStakingContractAddressHere".parse()?;
18+
let staking = StakingClient::new(staking_address, client.clone());
19+
20+
let address = client.address();
21+
println!("Staked Balance: {}", staking.balance_of(address).await?);
22+
println!("Earned: {}", staking.earned(address).await?);
23+
24+
Ok(())
25+
}

src/dao/mod.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
use ethers::prelude::*;
3+
use std::sync::Arc;
4+
5+
abigen!(
6+
DAO,
7+
r#"[function proposals(uint256) view returns (uint256 id, string description, uint256 votes)
8+
function vote(uint256 proposalId, bool support)]"#
9+
);
10+
11+
pub struct DaoClient<M> {
12+
contract: DAO<M>,
13+
}
14+
15+
impl<M: Middleware> DaoClient<M> {
16+
pub fn new(address: Address, client: Arc<M>) -> Self {
17+
let contract = DAO::new(address, client);
18+
Self { contract }
19+
}
20+
21+
pub async fn get_proposal(&self, proposal_id: U256) -> Result<(U256, String, U256), ContractError<M>> {
22+
self.contract.proposals(proposal_id).call().await
23+
}
24+
25+
pub async fn vote(&self, proposal_id: U256, support: bool) -> Result<TxHash, ContractError<M>> {
26+
let tx = self.contract.vote(proposal_id, support);
27+
let pending_tx = tx.send().await?;
28+
Ok(*pending_tx)
29+
}
30+
}

src/erc20/mod.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
2+
use ethers::prelude::*;
3+
use std::sync::Arc;
4+
5+
abigen!(
6+
ERC20,
7+
r#"[function balanceOf(address account) view returns (uint256)
8+
function transfer(address recipient, uint256 amount) returns (bool)
9+
function approve(address spender, uint256 amount) returns (bool)]"#
10+
);
11+
12+
pub struct Erc20Client<M> {
13+
contract: ERC20<M>,
14+
}
15+
16+
impl<M: Middleware> Erc20Client<M> {
17+
pub fn new(address: Address, client: Arc<M>) -> Self {
18+
let contract = ERC20::new(address, client);
19+
Self { contract }
20+
}
21+
22+
pub async fn balance_of(&self, account: Address) -> Result<U256, ContractError<M>> {
23+
self.contract.balance_of(account).call().await
24+
}
25+
26+
pub async fn transfer(&self, to: Address, amount: U256) -> Result<TxHash, ContractError<M>> {
27+
let tx = self.contract.transfer(to, amount);
28+
let pending_tx = tx.send().await?;
29+
Ok(*pending_tx)
30+
}
31+
32+
pub async fn approve(&self, spender: Address, amount: U256) -> Result<TxHash, ContractError<M>> {
33+
let tx = self.contract.approve(spender, amount);
34+
let pending_tx = tx.send().await?;
35+
Ok(*pending_tx)
36+
}
37+
}

src/lib.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
pub mod nft;
2+
pub mod dao;
3+
pub mod staking;
4+
pub mod erc20;
5+
pub mod vault;

0 commit comments

Comments
 (0)