forked from 0xPolygonMiden/miden-client
-
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.
feat: set up client structure add command skeleton and table migrations lints and remove testing prints fmt] add log to crate testing feature so that PoW in seed grinding does not take long addressing reviews map_err fix deserialization remove further unwraps add test address further reviews use new functions address reviews prettier table replace tabled with no std alt add SQL relations align comments feat: add github ci workflow feat: introduce input notes db and list command prettier wrapping table
- Loading branch information
0 parents
commit 86b39cb
Showing
16 changed files
with
1,355 additions
and
0 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,69 @@ | ||
name: CI | ||
on: | ||
push: | ||
branches: | ||
- main | ||
pull_request: | ||
types: [opened, repoened, synchronize] | ||
|
||
jobs: | ||
test: | ||
name: Test Rust ${{matrix.toolchain}} on ${{matrix.os}} | ||
runs-on: ${{matrix.os}}-latest | ||
strategy: | ||
fail-fast: false | ||
matrix: | ||
toolchain: [stable, nightly] | ||
os: [ubuntu] | ||
steps: | ||
- uses: actions/checkout@main | ||
- name: Install rust | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
toolchain: ${{matrix.toolchain}} | ||
override: true | ||
- name: Test | ||
uses: actions-rs/cargo@v1 | ||
env: | ||
RUSTFLAGS: -C debug-assertions | ||
with: | ||
command: test | ||
args: --release | ||
|
||
clippy: | ||
name: Clippy | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@main | ||
- name: Install minimal stable with clippy | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
profile: minimal | ||
toolchain: nightly | ||
components: clippy | ||
override: true | ||
|
||
- name: Clippy | ||
uses: actions-rs/cargo@v1 | ||
with: | ||
command: clippy | ||
args: --all --all-targets -- -D clippy::all -D warnings | ||
|
||
rustfmt: | ||
name: rustfmt | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@main | ||
- name: Install minimal stable with rustfmt | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
profile: minimal | ||
toolchain: stable | ||
components: rustfmt | ||
override: true | ||
|
||
- name: rustfmt | ||
uses: actions-rs/cargo@v1 | ||
with: | ||
command: fmt | ||
args: --all -- --check |
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,14 @@ | ||
# Generated by Cargo | ||
# will have compiled files and executables | ||
debug/ | ||
target/ | ||
|
||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries | ||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html | ||
Cargo.lock | ||
|
||
# These are backup files generated by rustfmt | ||
**/*.rs.bk | ||
|
||
# MSVC Windows builds of rustc generate these, which store debugging information | ||
*.pdb |
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 @@ | ||
# See https://pre-commit.com for more information | ||
# See https://pre-commit.com/hooks.html for more hooks | ||
repos: | ||
- repo: https://github.com/pre-commit/pre-commit-hooks | ||
rev: v3.2.0 | ||
hooks: | ||
- id: trailing-whitespace | ||
- id: end-of-file-fixer | ||
- id: check-yaml | ||
- id: check-json | ||
- id: check-toml | ||
- id: pretty-format-json | ||
- id: check-added-large-files | ||
- id: check-case-conflict | ||
- id: check-executables-have-shebangs | ||
- id: check-merge-conflict | ||
- id: detect-private-key | ||
- repo: https://github.com/hackaugusto/pre-commit-cargo | ||
rev: v1.0.0 | ||
hooks: | ||
# Allows cargo fmt to modify the source code prior to the commit | ||
- id: cargo | ||
name: Cargo fmt | ||
args: ["+stable", "fmt", "--all"] | ||
stages: [commit] | ||
# Requires code to be properly formatted prior to pushing upstream | ||
- id: cargo | ||
name: Cargo fmt --check | ||
args: ["+stable", "fmt", "--all", "--check"] | ||
stages: [push, manual] | ||
- id: cargo | ||
name: Cargo check --all-targets | ||
args: ["+stable", "check", "--all-targets"] | ||
- id: cargo | ||
name: Cargo check --all-targets --no-default-features | ||
args: ["+stable", "check", "--all-targets", "--no-default-features"] | ||
- id: cargo | ||
name: Cargo check --all-targets --all-features | ||
args: ["+stable", "check", "--all-targets", "--all-features"] | ||
# Unlike fmt, clippy will not be automatically applied | ||
- id: cargo | ||
name: Cargo clippy | ||
args: ["+nightly", "clippy", "--workspace", "--", "--deny", "clippy::all", "--deny", "warnings"] |
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 @@ | ||
[package] | ||
name = "miden-client" | ||
version = "0.1.0" | ||
authors = ["miden contributors"] | ||
readme = "README.md" | ||
license = "MIT" | ||
repository = "https://github.com/0xPolygonMiden/miden-client" | ||
keywords = ["miden", "client"] | ||
edition = "2021" | ||
rust-version = "1.67" | ||
|
||
[features] | ||
default = ["std"] | ||
std = ["crypto/std", "objects/std"] | ||
testing = ["objects/testing", "mock"] | ||
|
||
[dependencies] | ||
clap = { version = "4.3" , features = ["derive"] } | ||
crypto = { package = "miden-crypto", git = "https://github.com/0xPolygonMiden/crypto", branch = "next", default-features = false } | ||
lazy_static = "1.4.0" | ||
objects = { package = "miden-objects", git = "https://github.com/0xPolygonMiden/miden-base", branch = "main", features = ["serde"] } | ||
miden_lib = { package = "miden-lib", git = "https://github.com/0xPolygonMiden/miden-base", branch = "main", default-features = false } | ||
mock = { package = "miden-mock", git = "https://github.com/0xPolygonMiden/miden-base", branch = "main", default-features = false, optional = true } | ||
rusqlite = { version = "0.29.0", features = ["bundled"] } | ||
rusqlite_migration = { version = "1.0" } | ||
rand = { version="0.8.5" } | ||
serde = {version="1.0", features = ["derive"]} | ||
serde_json = { version = "1.0", features = ["raw_value"] } | ||
comfy-table = "7.1.0" | ||
|
||
[dev-dependencies] | ||
uuid = { version = "1.6.1", features = ["serde", "v4"] } | ||
mock = { package = "miden-mock", git = "https://github.com/0xPolygonMiden/miden-base", branch = "main", default-features = false } |
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,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2023 Polygon Miden | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
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 @@ | ||
# miden-client |
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,183 @@ | ||
use clap::Parser; | ||
use comfy_table::{presets, Attribute, Cell, ContentArrangement, Table}; | ||
use crypto::{dsa::rpo_falcon512::KeyPair, Felt}; | ||
use miden_client::Client; | ||
use miden_lib::{faucets, AuthScheme}; | ||
use objects::{accounts::AccountType, assets::TokenSymbol}; | ||
use rand::Rng; | ||
|
||
// ACCOUNT COMMAND | ||
// ================================================================================================ | ||
|
||
#[derive(Debug, Clone, Parser)] | ||
#[clap(about = "View accounts and account details")] | ||
pub enum AccountCmd { | ||
/// List all accounts monitored by this client | ||
#[clap(short_flag = 'l')] | ||
List, | ||
|
||
/// View details of the account for the specified ID | ||
#[clap(short_flag = 'v')] | ||
View { | ||
#[clap()] | ||
id: Option<String>, | ||
}, | ||
|
||
/// Create new account and store it locally | ||
#[clap(short_flag = 'n')] | ||
New { | ||
#[clap(subcommand)] | ||
template: Option<AccountTemplate>, | ||
|
||
/// Executes a transaction that records the account on-chain | ||
#[clap(short, long, default_value_t = false)] | ||
deploy: bool, | ||
}, | ||
} | ||
|
||
#[derive(Debug, Parser, Clone)] | ||
#[clap()] | ||
pub enum AccountTemplate { | ||
/// Creates a basic account (Regular account with immutable code) | ||
BasicImmutable, | ||
/// Creates a basic account (Regular account with mutable code) | ||
BasicMutable, | ||
/// Creates a faucet for fungible tokens | ||
FungibleFaucet { | ||
#[clap(short, long)] | ||
token_symbol: String, | ||
#[clap(short, long)] | ||
decimals: u8, | ||
#[clap(short, long)] | ||
max_supply: u64, | ||
}, | ||
/// Creates a faucet for non-fungible tokens | ||
NonFungibleFaucet, | ||
} | ||
|
||
impl AccountCmd { | ||
pub fn execute(&self, client: Client) -> Result<(), String> { | ||
match self { | ||
AccountCmd::List => { | ||
list_accounts(client)?; | ||
} | ||
AccountCmd::New { template, deploy } => { | ||
new_account(client, template, *deploy)?; | ||
} | ||
AccountCmd::View { id: _ } => todo!(), | ||
} | ||
Ok(()) | ||
} | ||
} | ||
|
||
// LIST ACCOUNTS | ||
// ================================================================================================ | ||
|
||
fn list_accounts(client: Client) -> Result<(), String> { | ||
println!("{}", "-".repeat(240)); | ||
println!( | ||
"{0: <18} | {1: <66} | {2: <66} | {3: <66} | {4: <15}", | ||
"account id", "code root", "vault root", "storage root", "nonce", | ||
); | ||
println!("{}", "-".repeat(240)); | ||
|
||
let accounts = client.get_accounts().map_err(|err| err.to_string())?; | ||
|
||
let mut table = Table::new(); | ||
table | ||
.load_preset(presets::UTF8_FULL) | ||
.set_content_arrangement(ContentArrangement::Dynamic) | ||
.set_header(vec![ | ||
Cell::new("account id").add_attribute(Attribute::Bold), | ||
Cell::new("code root").add_attribute(Attribute::Bold), | ||
Cell::new("vault root").add_attribute(Attribute::Bold), | ||
Cell::new("storage root").add_attribute(Attribute::Bold), | ||
Cell::new("nonce").add_attribute(Attribute::Bold), | ||
]); | ||
|
||
accounts.iter().for_each(|acc| { | ||
table.add_row(vec![ | ||
acc.id().to_string(), | ||
acc.code_root().to_string(), | ||
acc.vault_root().to_string(), | ||
acc.storage_root().to_string(), | ||
acc.nonce().to_string(), | ||
]); | ||
}); | ||
|
||
println!("{table}"); | ||
Ok(()) | ||
} | ||
|
||
// ACCOUNT NEW | ||
// ================================================================================================ | ||
|
||
fn new_account( | ||
client: Client, | ||
template: &Option<AccountTemplate>, | ||
deploy: bool, | ||
) -> Result<(), String> { | ||
if deploy { | ||
todo!("Recording the account on chain is not supported yet"); | ||
} | ||
|
||
let key_pair: KeyPair = | ||
KeyPair::new().map_err(|err| format!("Error generating KeyPair: {}", err))?; | ||
let auth_scheme: AuthScheme = AuthScheme::RpoFalcon512 { | ||
pub_key: key_pair.public_key(), | ||
}; | ||
|
||
let mut rng = rand::thread_rng(); | ||
// we need to use an initial seed to create the wallet account | ||
let init_seed: [u8; 32] = rng.gen(); | ||
|
||
// TODO: as the client takes form, make errors more structured | ||
let (account, _) = match template { | ||
None => todo!("Generic account creation is not supported yet"), | ||
Some(AccountTemplate::BasicImmutable) => miden_lib::wallets::create_basic_wallet( | ||
init_seed, | ||
auth_scheme, | ||
AccountType::RegularAccountImmutableCode, | ||
), | ||
Some(AccountTemplate::FungibleFaucet { | ||
token_symbol, | ||
decimals, | ||
max_supply, | ||
}) => { | ||
let max_supply = max_supply.to_le_bytes(); | ||
faucets::create_basic_fungible_faucet( | ||
init_seed, | ||
TokenSymbol::new(token_symbol) | ||
.expect("Hardcoded test token symbol creation should not panic"), | ||
*decimals, | ||
Felt::try_from(max_supply.as_slice()) | ||
.map_err(|_| "Maximum supply must fit into a field element")?, | ||
auth_scheme, | ||
) | ||
} | ||
Some(AccountTemplate::BasicMutable) => miden_lib::wallets::create_basic_wallet( | ||
init_seed, | ||
auth_scheme, | ||
AccountType::RegularAccountUpdatableCode, | ||
), | ||
_ => todo!("Template not supported yet"), | ||
} | ||
.map_err(|err| err.to_string())?; | ||
|
||
// TODO: Make these inserts atomic through a single transaction | ||
client | ||
.store() | ||
.insert_account_code(account.code()) | ||
.and_then(|_| client.store().insert_account_storage(account.storage())) | ||
.and_then(|_| client.store().insert_account_vault(account.vault())) | ||
.and_then(|_| client.store().insert_account(&account)) | ||
.map(|_| { | ||
println!( | ||
"Succesfully created and stored Account ID: {}", | ||
account.id() | ||
) | ||
}) | ||
.map_err(|x| x.to_string())?; | ||
|
||
Ok(()) | ||
} |
Oops, something went wrong.