forked from Turbin3/valid8
-
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.
- Loading branch information
0 parents
commit 5928968
Showing
27 changed files
with
1,937 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,56 @@ | ||
name: Release | ||
|
||
permissions: | ||
contents: write | ||
|
||
# tag example: v0.0.1, v0.0.2 | ||
on: | ||
push: | ||
tags: | ||
- v[0-9]+.* | ||
|
||
jobs: | ||
create-release: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: taiki-e/create-gh-release-action@v1 | ||
with: | ||
# (optional) Path to changelog. | ||
# changelog: CHANGELOG.md | ||
# (required) GitHub token for creating GitHub Releases. | ||
token: ${{ secrets.GHTOKEN }} | ||
|
||
upload-assets: | ||
needs: create-release | ||
strategy: | ||
matrix: | ||
include: | ||
- target: x86_64-unknown-linux-gnu | ||
os: ubuntu-latest | ||
- target: x86_64-apple-darwin | ||
os: macos-latest | ||
runs-on: ${{ matrix.os }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- uses: taiki-e/upload-rust-binary-action@v1 | ||
with: | ||
# (required) Comma-separated list of binary names (non-extension portion of filename) to build and upload. | ||
# Note that glob pattern is not supported yet. | ||
bin: valid8 | ||
# (optional) Target triple, default is host triple. | ||
# This is optional but it is recommended that this always be set to | ||
# clarify which target you are building for if macOS is included in | ||
# the matrix because GitHub Actions changed the default architecture | ||
# of macos-latest since macos-14. | ||
target: ${{ matrix.target }} | ||
# (optional) On which platform to distribute the `.tar.gz` file. | ||
# [default value: unix] | ||
# [possible values: all, unix, windows, none] | ||
tar: unix | ||
# (optional) On which platform to distribute the `.zip` file. | ||
# [default value: windows] | ||
# [possible values: all, unix, windows, none] | ||
zip: none | ||
# (required) GitHub token for uploading assets to GitHub Releases. | ||
token: ${{ secrets.GHTOKEN }} |
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 @@ | ||
.DS_Store | ||
target | ||
.env | ||
.valid8 | ||
Cargo.lock | ||
test-ledger |
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 = "valid8" | ||
version = "0.0.3" | ||
edition = "2021" | ||
authors = ["Dean 利迪恩", "bergabman"] | ||
|
||
[dependencies] | ||
anyhow = "1.0.81" | ||
base64 = "0.22.0" | ||
bs58 = "0.5.1" | ||
clap = { version = "4.4.8", features = ["derive", "cargo"] } | ||
dialoguer = "0.11.0" | ||
rayon = "1.8.0" | ||
borsh = "1.3.1" | ||
solana-sdk = "=1.18.1" | ||
solana-client = "=1.18.1" | ||
solana-ledger = "=1.18.1" | ||
solana-runtime = "=1.18.1" | ||
solana-account-decoder = "=1.18.1" | ||
spl-token = "4.0.0" | ||
serde_json = "1.0.114" | ||
serde = { version = "1.0.197", features = ["derive"] } | ||
anchor-lang = { version = "0.29.0", features = ["idl-build"]} | ||
flate2 = "1.0.28" | ||
bincode = "1.3.3" | ||
tempfile = "3.10.1" | ||
convert_case = "0.6" | ||
|
||
[profile.release] | ||
strip = true | ||
lto = true | ||
codegen-units = 1 | ||
|
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,108 @@ | ||
valid8: Manage your Solana ledger locally | ||
|
||
valid8 is a cli tool that simplifies managing Solana test ledgers for development and testing purposes. It allows you to clone accounts from the Solana blockchain and store them in a local ledger compatible with the solana-test-validator. | ||
|
||
# Installation | ||
|
||
(Assuming you have Rust and Cargo installed) | ||
|
||
Clone the repository: | ||
|
||
`git clone https://github.com/.../valid8.git` | ||
|
||
|
||
Navigate to the project directory: | ||
`cd valid8` | ||
|
||
Build valid8: | ||
`cargo build --release` | ||
|
||
This will create a binary named valid8 in the target/release directory. You can copy the binary to a location in your PATH for easier access. | ||
|
||
# Usage | ||
|
||
Basic Usage: | ||
|
||
valid8 [command] | ||
|
||
## Available Commands: | ||
|
||
(no argument): Opens an interactive menu for managing accounts and programs. | ||
run : Opens the same interactive menu as no arguments | ||
ledger (arg: overwrite): Generates a local ledger compatible with solana-test-validator. | ||
Overwrite directory if already exists with the `-y` option. | ||
compose: Compose multiple valid8 config files into one. | ||
|
||
## Interactive Menu: | ||
|
||
In the interactive menu you can choose from the following options: | ||
|
||
Clone Account: Clone an account from the Solana blockchain. | ||
Clone Program: Clone a program from the Solana blockchain. | ||
Edit Accounts: Manage accounts in your local ledger. | ||
Edit Programs: Manage programs in your local ledger. | ||
Compose configs: Compose multiple valid8 config files into one. | ||
Generate Ledger: Generates a local ledger compatible with solana-test-validator. | ||
Exit: Exit the interactive menu. | ||
|
||
Clone Account: | ||
|
||
Select "Clone Account" from the menu. | ||
Choose a network (mainnet or devnet) or select "Custom Network" to specify a custom RPC endpoint. | ||
If you choose "Custom Network," provide the RPC endpoint URL when prompted. | ||
Enter the public key of the account you want to clone. | ||
valid8 will clone the account and store it locally. | ||
|
||
Edit Account: | ||
|
||
Select "Edit Account" from the menu. | ||
Enter the public key of the account you want to edit when prompted. | ||
Change the owner, or the amount of lamports in the account. | ||
valid8 will edit the account and store it locally with the changed value. | ||
|
||
Clone Program: | ||
|
||
Select "Clone Program" from the menu. | ||
Choose a network (mainnet or devnet) or select "Custom Network" to specify a custom RPC endpoint. | ||
If you choose "Custom Network," provide the RPC endpoint URL when prompted. | ||
Enter the public key of the program you want to clone, the program data account will automatically cloned. | ||
|
||
|
||
Edit Program: | ||
|
||
Select "Edit Program" from the menu. | ||
Enter the public key of the program you want to edit when prompted. | ||
Change the owner, the amount of lamports, or the upgrade authority of the program, or select Unpack PDA to edit a program related pda account | ||
valid8 will edit the program and store it locally with the changed value(s). | ||
|
||
Ledger Command: | ||
|
||
`valid8 ledger` | ||
|
||
Generates a local ledger compatible with solana-test-validator. | ||
You can use this ledger with solana-test-validator to create a test environment and ledger with your cloned accounts and programs pre-loaded. | ||
(use `-y` to automatically overwrite test-ledger if already exists) | ||
|
||
Compose Command: | ||
|
||
`valid8 compose` | ||
|
||
Composes multiple valid8 configs together, for an even bigger dev environment. | ||
To add an extra valid8 config and compose it with your own, just add a filename to the `compose: ` field in your `valid8.json` file. | ||
|
||
# Example: | ||
|
||
## Open the interactive menu | ||
`valid8` | ||
|
||
1. Select "Clone Account" | ||
2. Choose "devnet" network | ||
3. Enter the public key of the account to clone | ||
|
||
## Generate a local ledger | ||
`valid8 ledger -y` | ||
|
||
## Start solana-test-validator | ||
`solana-test-validator` | ||
|
||
This will create a local ledger and run it with the cloned accounts available for testing. |
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,26 @@ | ||
use anyhow::{anyhow, Result}; | ||
use dialoguer::Input; | ||
use solana_sdk::pubkey::Pubkey; | ||
use std::str::FromStr; | ||
|
||
use crate::{ common::network, context::Valid8Context }; | ||
|
||
pub fn clone(ctx: &mut Valid8Context) -> Result<()> { | ||
let network = network::get(ctx)?; | ||
|
||
let mut address: Option<Pubkey> = None; | ||
while address.is_none() { | ||
let address_string: String = Input::new() | ||
.with_prompt("Account address") | ||
.interact_text()?; | ||
|
||
match Pubkey::from_str(&address_string) { | ||
Ok(p) => address = Some(p), | ||
Err(_) => println!("Invalid address: {}. Please enter a valid base58-encoeded Solana address.", &address_string) | ||
} | ||
} | ||
|
||
let pubkey = address.ok_or(anyhow!("Public key not defined"))?; | ||
|
||
ctx.add_account(&network, &pubkey) | ||
} |
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,66 @@ | ||
use anyhow::{anyhow, Result}; | ||
use dialoguer::{Input, Select}; | ||
use solana_sdk::pubkey::Pubkey; | ||
use std::str::FromStr; | ||
|
||
use crate::context::{EditField, Valid8Context}; | ||
|
||
pub fn edit(ctx: &mut Valid8Context) -> Result<()> { | ||
|
||
let mut address: Option<Pubkey> = None; | ||
while address.is_none() { | ||
let address_string: String = Input::new() | ||
.with_prompt("Account address to edit") | ||
.interact_text()?; | ||
|
||
match Pubkey::from_str(&address_string) { | ||
Ok(p) => address = Some(p), | ||
Err(_) => println!("Invalid address: {}. Please enter a valid base58-encoeded Solana address.", &address_string) | ||
} | ||
} | ||
|
||
let pubkey = address.ok_or(anyhow!("Public key not defined"))?; | ||
if ctx.has_account(&pubkey) { | ||
let account = ctx.accounts | ||
.iter() | ||
.find(|acc| acc.pubkey == pubkey) | ||
.ok_or(anyhow!("No account found in context"))?; | ||
// let account = ctx.accounts.get(position).ok_or(anyhow!("No account at that position"))?; | ||
|
||
let fields: Vec<String> = vec![ | ||
format!("Owner: {}", account.owner.to_string()), | ||
format!("Lamports: {}", account.lamports.to_string()), | ||
format!("Unpack TokenAccount"), | ||
format!("Unpack PDA"), | ||
]; | ||
|
||
let selection = Select::new() | ||
.with_prompt("Select a field to edit") | ||
.items(&fields) | ||
.interact()?; | ||
|
||
match selection { | ||
0 => { | ||
let new_owner: Pubkey = Input::new().with_prompt("New owner pubkey").interact_text()?; | ||
ctx.edit_account(&pubkey, EditField::Owner(new_owner))?; | ||
}, | ||
1 => { | ||
let new_lamports: u64 = Input::new().with_prompt("New lamports").interact_text()?; | ||
ctx.edit_account(&pubkey, EditField::Lamports(new_lamports))?; | ||
}, | ||
2 => { | ||
ctx.edit_account(&pubkey, EditField::UnpackTokenAccount)?; | ||
}, | ||
3 => { | ||
todo!(); | ||
// ctx.edit_account(&pubkey, EditField::UnpackPDA(new_lamports))?; | ||
}, | ||
_ => {} | ||
} | ||
|
||
} else { | ||
return Err(anyhow!("Account not found in context")); | ||
} | ||
|
||
Ok(()) | ||
} |
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,5 @@ | ||
pub mod clone; | ||
pub use clone::*; | ||
|
||
pub mod edit; | ||
pub use edit::*; |
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,9 @@ | ||
use anyhow::Result; | ||
use crate::context::Valid8Context; | ||
|
||
pub fn compose(ctx: Valid8Context) -> Result<()> { | ||
let (compose_count, account_count, program_count) = ctx.try_compose()?; | ||
|
||
println!("✅ Valid8 configs composed! {} accounts and {} programs added from {} config(s)", account_count, program_count, compose_count); | ||
Ok(()) | ||
} |
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,30 @@ | ||
use anyhow::Result; | ||
use dialoguer::Select; | ||
|
||
use crate::{program, account, context::Valid8Context}; | ||
|
||
pub fn edit(ctx: &mut Valid8Context) -> Result<()> { | ||
let items = vec![ | ||
"Clone program", | ||
"Clone account", | ||
"Edit Program", | ||
"Edit Account" | ||
]; | ||
|
||
let selection = Select::new() | ||
.with_prompt("Select an option, or press Esc to exit.") | ||
.items(&items) | ||
.interact_opt()?; | ||
|
||
if let Some(n) = selection { | ||
match n { | ||
0 => program::clone(ctx)?, | ||
1 => account::clone(ctx)?, | ||
2 => program::edit(ctx)?, | ||
3 => account::edit(ctx)?, | ||
_ => {} | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
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,34 @@ | ||
use std::{fs, path::Path}; | ||
use anyhow::{anyhow, Result}; | ||
use dialoguer::Input; | ||
|
||
use crate::context::Valid8Context; | ||
|
||
pub fn ledger(ctx: Valid8Context, overwrite: &Option<String>) -> Result<()> { | ||
|
||
let ledger_path = Path::new("test-ledger"); | ||
|
||
let mut user_choice = false; | ||
if ledger_path.exists() { | ||
if let Some(overwrite) = overwrite { | ||
if overwrite.to_ascii_lowercase() == *"-y" { | ||
user_choice = true; | ||
} | ||
} else { | ||
let overwrite_choice: String = Input::new().with_prompt("Ledger path already exists, do you want to overwrite?(y/n)").interact_text()?; | ||
|
||
match overwrite_choice.to_ascii_lowercase().as_ref() { | ||
"y" => user_choice = true, | ||
"n" => return Err(anyhow!("No new ledger created")), | ||
_ => return Err(anyhow!("Incorrect option")), | ||
} | ||
} | ||
} | ||
|
||
if user_choice { | ||
println!("Overwiting test-ledger directory"); | ||
fs::remove_dir_all(ledger_path)?; | ||
} | ||
ctx.create_ledger()?; | ||
Ok(()) | ||
} |
Oops, something went wrong.