Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
3be2e3e
update anvil state json to new kimap
barraguda Jun 10, 2024
f5f708b
kinostate: include multicall deployment
barraguda Jun 11, 2024
671854a
allow .os and .dev
barraguda Jun 11, 2024
31deec3
update kinostate json to match contract change
barraguda Jun 18, 2024
0364fb6
kinostate.json: update
barraguda Jun 28, 2024
28043ae
kit publish: init
barraguda Aug 1, 2024
b045672
publish: tweak whitespace
nick1udwig Aug 1, 2024
85cd32a
publish: execute() -> end of file
nick1udwig Aug 1, 2024
181b929
publish: move around imports
nick1udwig Aug 1, 2024
96c4843
publish: get compiling with new args
nick1udwig Aug 2, 2024
9dfc0fc
publish: handle update case
barraguda Aug 2, 2024
c1d55d1
publish: fix path & fix error print links
nick1udwig Aug 2, 2024
0db6ba8
publish: get it working
nick1udwig Aug 2, 2024
81dccbc
Merge branch 'kitpublish' into hf/publish-use-cast-for-private-keys
nick1udwig Aug 2, 2024
0a2e4af
Merge pull request #204 from kinode-dao/hf/publish-use-cast-for-priva…
nick1udwig Aug 2, 2024
8cd0970
update kinostate
barraguda Aug 3, 2024
29e2828
Merge branch 'bp/kinomap' into kitpublish
barraguda Aug 3, 2024
18c4b33
update contract addresses
barraguda Aug 3, 2024
678f48f
Merge branch 'master' into bp/kinomap
barraguda Aug 6, 2024
49c2726
update kinostate to new anvil 2.0 format
barraguda Aug 9, 2024
7cbc217
Merge branch 'master' into bp/kinomap
nick1udwig Aug 9, 2024
a32a66d
Merge branch 'bp/kinomap' into kitpublish
nick1udwig Aug 10, 2024
86c7de8
Merge pull request #208 from kinode-dao/bp/anvil-update
barraguda Aug 12, 2024
fdfb3c4
start: add version_hash to InstallRequest
barraguda Aug 12, 2024
6089204
start: app metadata in install rather than start command
barraguda Aug 12, 2024
58c819c
Merge branch 'bp/kinomap' into kitpublish
nick1udwig Aug 12, 2024
940c73c
publish: add real node options
nick1udwig Aug 13, 2024
fefce45
publish: get it working
nick1udwig Aug 13, 2024
0af3c06
publish: remove unused const
nick1udwig Aug 13, 2024
c716d5a
publish: change some fn names
nick1udwig Aug 13, 2024
1fa7b6e
fix some helptext formatting
nick1udwig Aug 13, 2024
3e9df44
publish: add a `--unpublish` flag
nick1udwig Aug 14, 2024
e3a698f
publish: add ledger & trezor support
nick1udwig Aug 14, 2024
98d4ed7
Merge pull request #211 from kinode-dao/bp/appstore-api
barraguda Aug 16, 2024
9c9786d
Merge branch 'bp/kinomap' into kitpublish
nick1udwig Aug 20, 2024
35490d9
clarify rpc is for optimism mainnet
nick1udwig Aug 20, 2024
e0af3fb
Merge pull request #203 from kinode-dao/kitpublish
nick1udwig Aug 20, 2024
836508b
Merge branch 'master' into bp/kinomap
nick1udwig Aug 20, 2024
91892b1
bump version
nick1udwig Aug 20, 2024
88d7615
zip and hash during build, not start-package
nick1udwig Aug 21, 2024
b3ce62e
new: fix rust no-ui templates scripts
nick1udwig Aug 21, 2024
0ff5fa5
Merge pull request #214 from kinode-dao/hf/zip-and-hash-during-build
nick1udwig Aug 21, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,149 changes: 1,080 additions & 69 deletions Cargo.lock

Large diffs are not rendered by default.

25 changes: 24 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,13 +1,34 @@
[package]
name = "kit"
version = "0.6.11"
version = "0.7.0"
edition = "2021"

[build-dependencies]
anyhow = "1.0"
git2 = "0.18"

[dependencies]
alloy = { version = "0.1.3", features = [
"consensus",
"contract",
"json-rpc",
"network",
"provider-ws",
"providers",
"pubsub",
"rpc",
"rpc-client",
"rpc-client-ws",
"rpc-types",
"rpc-types-eth",
"signers",
"signer-keystore",
"signer-ledger",
"signer-local",
"signer-trezor",
] }
alloy-sol-macro = "0.7.6"
alloy-sol-types = "0.7.6"
base64 = "0.21"
clap = { version = "4.4", features = ["cargo", "string"] }
color-eyre = { version = "0.6", features = ["capture-spantrace"] }
Expand All @@ -18,6 +39,8 @@ kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib.git", re
nix = { version = "0.27", features = ["process", "signal", "term"] }
regex = "1"
reqwest = { version = "0.12", features = ["json"] }
# rmp-serde = "1.1.2"
rpassword = "7"
semver = "1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Expand Down
7 changes: 1 addition & 6 deletions src/boot_fake_node/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,12 +448,7 @@ pub async fn execute(
let send_to_cleanup_for_cleanup = send_to_cleanup.clone();
let _cleanup_context = CleanupContext::new(send_to_cleanup_for_cleanup);

// TODO: change this to be less restrictive; currently leads to weirdness
// like an input of `fake.os` -> `fake.os.dev`.
// The reason we need it for now is that non-`.dev` nodes are not currently
// addressable.
// Once they are addressable, change this to, perhaps, `!name.contains(".")
if !fake_node_name.ends_with(".dev") {
if !fake_node_name.contains(".") {
fake_node_name.push_str(".dev");
}

Expand Down
87 changes: 83 additions & 4 deletions src/build/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::{HashMap, HashSet};
use std::io::{Read, Write};
use std::path::{Path, PathBuf};
use std::process::Command;
use std::time::SystemTime;
Expand All @@ -12,15 +13,17 @@ use color_eyre::{
};
use fs_err as fs;
use serde::{Deserialize, Serialize};
use sha2::{Digest, Sha256};
use tracing::{debug, info, instrument, warn};
use walkdir::WalkDir;
use zip::write::FileOptions;

use kinode_process_lib::{PackageId, kernel_types::Erc721Metadata};

use crate::setup::{
check_js_deps, check_py_deps, check_rust_deps, get_deps, get_newest_valid_node_version,
get_python_version, REQUIRED_PY_PACKAGE,
};
use crate::start_package::zip_directory;
use crate::view_api;
use crate::KIT_CACHE;

Expand All @@ -46,6 +49,75 @@ struct CargoPackage {
name: String,
}

pub fn make_pkg_publisher(metadata: &Erc721Metadata) -> String {
let package_name = metadata.properties.package_name.as_str();
let publisher = metadata.properties.publisher.as_str();
let pkg_publisher = format!("{}:{}", package_name, publisher);
pkg_publisher
}

pub fn make_zip_filename(package_dir: &Path, pkg_publisher: &str) -> PathBuf {
let zip_filename = package_dir.join("target").join(pkg_publisher).with_extension("zip");
zip_filename
}

#[instrument(level = "trace", skip_all)]
pub fn hash_zip_pkg(zip_path: &Path) -> Result<String> {
let mut file = fs::File::open(&zip_path)?;
let mut hasher = Sha256::new();
let mut buffer = Vec::new();
file.read_to_end(&mut buffer)?;
hasher.update(&buffer);
let hash_result = hasher.finalize();
Ok(format!("{hash_result:x}"))
}

#[instrument(level = "trace", skip_all)]
pub fn zip_pkg(package_dir: &Path, pkg_publisher: &str) -> Result<(PathBuf, String)> {
let pkg_dir = package_dir.join("pkg");
let target_dir = package_dir.join("target");
fs::create_dir_all(&target_dir)?;
let zip_filename = make_zip_filename(package_dir, pkg_publisher);
zip_directory(&pkg_dir, &zip_filename.to_str().unwrap())?;

let hash = hash_zip_pkg(&zip_filename)?;
Ok((zip_filename, hash))
}

#[instrument(level = "trace", skip_all)]
fn zip_directory(directory: &Path, zip_filename: &str) -> Result<()> {
let file = fs::File::create(zip_filename)?;
let walkdir = WalkDir::new(directory);
let it = walkdir.into_iter();

let mut zip = zip::ZipWriter::new(file);

let options = FileOptions::default()
.compression_method(zip::CompressionMethod::Deflated)
.unix_permissions(0o755)
.last_modified_time(zip::DateTime::from_date_and_time(1980, 1, 1, 0, 0, 0).unwrap());

for entry in it {
let entry = entry?;
let path = entry.path();
let name = path.strip_prefix(Path::new(directory))?;

if path.is_file() {
zip.start_file(name.to_string_lossy(), options)?;
let mut f = fs::File::open(path)?;
let mut buffer = Vec::new();
f.read_to_end(&mut buffer)?;
zip.write_all(&*buffer)?;
} else if name.as_os_str().len() != 0 {
// Only if it is not the root directory
zip.add_directory(name.to_string_lossy(), options)?;
}
}

zip.finish()?;
Ok(())
}

#[instrument(level = "trace", skip_all)]
pub fn has_feature(cargo_toml_path: &str, feature: &str) -> Result<bool> {
let cargo_toml_content = fs::read_to_string(cargo_toml_path)?;
Expand Down Expand Up @@ -1200,7 +1272,7 @@ pub async fn execute(
verbose,
ignore_deps,
)
.await
.await?;
}
} else {
if no_ui {
Expand All @@ -1225,7 +1297,7 @@ pub async fn execute(
let valid_node = get_newest_valid_node_version(None, None)?;

if ui_only {
compile_and_copy_ui(package_dir, valid_node, verbose).await
compile_and_copy_ui(package_dir, valid_node, verbose).await?;
} else {
compile_package_and_ui(
package_dir,
Expand All @@ -1241,7 +1313,14 @@ pub async fn execute(
verbose,
ignore_deps,
)
.await
.await?;
}
}

let metadata = read_metadata(package_dir)?;
let pkg_publisher = make_pkg_publisher(&metadata);
let (_zip_filename, hash_string) = zip_pkg(package_dir, &pkg_publisher)?;
info!("package zip hash: {hash_string}");

Ok(())
}
2 changes: 1 addition & 1 deletion src/chain/kinostate.json

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ pub mod connect;
pub mod dev_ui;
pub mod inject_message;
pub mod new;
pub mod publish;
pub mod remove_package;
pub mod reset_cache;
pub mod run_tests;
Expand Down
133 changes: 126 additions & 7 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use tracing_subscriber::{

use kit::{
boot_fake_node, boot_real_node, build, build_start_package, chain, connect, dev_ui,
inject_message, new, remove_package, reset_cache, run_tests, setup, start_package, update,
view_api, KIT_LOG_PATH_DEFAULT,
inject_message, new, publish, remove_package, reset_cache, run_tests, setup, start_package,
update, view_api, KIT_LOG_PATH_DEFAULT,
};

const MAX_REMOTE_VALUES: usize = 3;
Expand All @@ -36,6 +36,11 @@ struct Commit {
sha: String,
}

fn parse_u128_with_underscores(s: &str) -> Result<u128, &'static str> {
let clean_string = s.replace('_', "");
clean_string.parse::<u128>().map_err(|_| "Invalid number format")
}

async fn get_latest_commit_sha_from_branch(
owner: &str,
repo: &str,
Expand Down Expand Up @@ -330,6 +335,39 @@ async fn execute(
*ui,
)
}
Some(("publish", matches)) => {
let package_dir = PathBuf::from(matches.get_one::<String>("DIR").unwrap());
let metadata_uri = matches.get_one::<String>("URI").unwrap();
let keystore_path = matches
.get_one::<String>("PATH")
.and_then(|kp| Some(PathBuf::from(kp)));
let ledger = matches.get_one::<bool>("LEDGER").unwrap();
let trezor = matches.get_one::<bool>("TREZOR").unwrap();
let rpc_uri = matches.get_one::<String>("RPC_URI").unwrap();
let real = matches.get_one::<bool>("REAL").unwrap();
let unpublish = matches.get_one::<bool>("UNPUBLISH").unwrap();
let gas_limit = matches.get_one::<u128>("GAS_LIMIT").unwrap();
let max_priority_fee = matches
.get_one::<u128>("MAX_PRIORITY_FEE_PER_GAS")
.and_then(|mpf| Some(mpf.clone()));
let max_fee_per_gas = matches
.get_one::<u128>("MAX_FEE_PER_GAS")
.and_then(|mfpg| Some(mfpg.clone()));

publish::execute(
&package_dir,
metadata_uri,
keystore_path,
ledger,
trezor,
rpc_uri,
real,
unpublish,
*gas_limit,
max_priority_fee,
max_fee_per_gas,
).await
}
Some(("remove-package", matches)) => {
let package_name = matches
.get_one::<String>("PACKAGE")
Expand Down Expand Up @@ -483,7 +521,7 @@ async fn make_app(current_dir: &std::ffi::OsString) -> Result<Command> {
.arg(Arg::new("RPC_ENDPOINT")
.action(ArgAction::Set)
.long("rpc")
.help("Ethereum RPC endpoint (wss://)")
.help("Ethereum Optimism mainnet RPC endpoint (wss://)")
.required(false)
)
.arg(Arg::new("PERSIST")
Expand Down Expand Up @@ -560,7 +598,7 @@ async fn make_app(current_dir: &std::ffi::OsString) -> Result<Command> {
.arg(Arg::new("RPC_ENDPOINT")
.action(ArgAction::Set)
.long("rpc")
.help("Ethereum RPC endpoint (wss://)")
.help("Ethereum Optimism mainnet RPC endpoint (wss://)")
.required(false)
)
//.arg(Arg::new("PASSWORD") // TODO: with develop 0.8.0
Expand Down Expand Up @@ -777,7 +815,7 @@ async fn make_app(current_dir: &std::ffi::OsString) -> Result<Command> {
.action(ArgAction::SetTrue)
.short('d')
.long("disconnect")
.help("If set, disconnect an existing tunnel (default: connect a new tunnel)")
.help("If set, disconnect an existing tunnel [default: connect a new tunnel]")
.required(false)
)
.arg(Arg::new("HOST")
Expand Down Expand Up @@ -850,7 +888,7 @@ async fn make_app(current_dir: &std::ffi::OsString) -> Result<Command> {
.action(ArgAction::Set)
.short('n')
.long("node")
.help("Node ID (default: our)")
.help("Node ID [default: our]")
.required(false)
)
.arg(Arg::new("PATH")
Expand Down Expand Up @@ -911,6 +949,87 @@ async fn make_app(current_dir: &std::ffi::OsString) -> Result<Command> {
.required(false)
)
)
.subcommand(Command::new("publish")
.about("Publish or update a package")
.visible_alias("p")
.arg(Arg::new("DIR")
.action(ArgAction::Set)
.help("The package directory to publish")
.default_value(current_dir)
)
.arg(Arg::new("PATH")
.action(ArgAction::Set)
.short('k')
.long("keystore-path")
.help("Path to private key keystore (choose 1 of `k`, `l`, `t`)") // TODO: add link to docs?
.required(false)
)
.arg(Arg::new("LEDGER")
.action(ArgAction::SetTrue)
.short('l')
.long("ledger")
.help("Use Ledger private key (choose 1 of `k`, `l`, `t`)")
.required(false)
)
.arg(Arg::new("TREZOR")
.action(ArgAction::SetTrue)
.short('t')
.long("trezor")
.help("Use Trezor private key (choose 1 of `k`, `l`, `t`)")
.required(false)
)
.arg(Arg::new("URI")
.action(ArgAction::Set)
.short('u')
.long("metadata-uri")
.help("URI where metadata lives")
.required(true)
)
.arg(Arg::new("RPC_URI")
.action(ArgAction::Set)
.short('r')
.long("rpc")
.help("Ethereum Optimism mainnet RPC endpoint (wss://)")
.required(true)
)
.arg(Arg::new("REAL")
.action(ArgAction::SetTrue)
.short('e')
.long("real")
.help("If set, deploy to real network [default: fake node]")
.required(false)
)
.arg(Arg::new("UNPUBLISH")
.action(ArgAction::SetTrue)
.long("unpublish")
.help("If set, unpublish existing published package [default: publish a package]")
)
.arg(Arg::new("GAS_LIMIT")
.action(ArgAction::Set)
.short('g')
.long("gas-limit")
.help("The ETH transaction gas limit")
.default_value("1_000_000")
.value_parser(clap::builder::ValueParser::new(parse_u128_with_underscores))
.required(false)
)
.arg(Arg::new("MAX_PRIORITY_FEE_PER_GAS")
.action(ArgAction::Set)
.short('p')
.long("priority-fee")
.help("The ETH transaction max priority fee per gas [default: estimated from network conditions]")
.value_parser(clap::builder::ValueParser::new(parse_u128_with_underscores))
.required(false)
)
.arg(Arg::new("MAX_FEE_PER_GAS")
.action(ArgAction::Set)
.short('f')
.long("fee-per-gas")
.help("The ETH transaction max fee per gas [default: estimated from network conditions]")
.value_parser(clap::builder::ValueParser::new(parse_u128_with_underscores))
.required(false)
)
)
.subcommand(Command::new("remove-package")
.about("Remove a running package from a node")
.visible_alias("r")
Expand Down Expand Up @@ -1000,7 +1119,7 @@ async fn make_app(current_dir: &std::ffi::OsString) -> Result<Command> {
.visible_alias("v")
.arg(Arg::new("PACKAGE_ID")
.action(ArgAction::Set)
.help("Get API of this package (default: list all APIs)")
.help("Get API of this package [default: list all APIs]")
.required(false)
)
.arg(Arg::new("NODE_PORT")
Expand Down
Loading