mirror of
https://github.com/uqbar-dao/nectar.git
synced 2024-11-25 07:07:06 +03:00
Merge branch 'develop' into dr/terminal-special-chars
This commit is contained in:
commit
9ad0428886
7
Cargo.lock
generated
7
Cargo.lock
generated
@ -984,6 +984,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"kinode_process_lib 0.9.0 (git+https://github.com/kinode-dao/process_lib?tag=v0.9.0)",
|
||||
"process_macros",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -1581,6 +1582,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"kinode_process_lib 0.9.0 (git+https://github.com/kinode-dao/process_lib?tag=v0.9.0)",
|
||||
"process_macros",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -2346,6 +2348,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kinode_process_lib 0.9.0 (git+https://github.com/kinode-dao/process_lib?tag=v0.9.0)",
|
||||
"process_macros",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wit-bindgen",
|
||||
@ -2357,6 +2360,7 @@ version = "0.5.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kinode_process_lib 0.9.1",
|
||||
"process_macros",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -2622,6 +2626,7 @@ dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
"kinode_process_lib 0.9.1",
|
||||
"process_macros",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@ -3343,6 +3348,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kinode_process_lib 0.9.0 (git+https://github.com/kinode-dao/process_lib?tag=v0.9.0)",
|
||||
"process_macros",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wit-bindgen",
|
||||
@ -6480,6 +6486,7 @@ version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"kinode_process_lib 0.9.0 (git+https://github.com/kinode-dao/process_lib?tag=v0.9.0)",
|
||||
"process_macros",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"wit-bindgen",
|
||||
|
16
kinode/packages/app_store/Cargo.toml
Normal file
16
kinode/packages/app_store/Cargo.toml
Normal file
@ -0,0 +1,16 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"app_store",
|
||||
"chain",
|
||||
"download",
|
||||
"downloads",
|
||||
"ft_worker",
|
||||
"install",
|
||||
"uninstall",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
lto = true
|
@ -1,6 +1,6 @@
|
||||
interface downloads {
|
||||
//
|
||||
// download API as presented by download:app_store:sys-v0
|
||||
// download API as presented by download:app_store:sys-v1
|
||||
//
|
||||
|
||||
use standard.{package-id};
|
||||
@ -25,8 +25,8 @@ interface downloads {
|
||||
|
||||
variant download-responses {
|
||||
success,
|
||||
error(download-error),
|
||||
get-files(list<entry>),
|
||||
err(download-error),
|
||||
get-files(list<entry>),
|
||||
}
|
||||
|
||||
record local-download-request {
|
||||
@ -55,12 +55,13 @@ interface downloads {
|
||||
http-client-error,
|
||||
blob-not-found,
|
||||
vfs-error,
|
||||
handling-error(string),
|
||||
}
|
||||
|
||||
record download-complete-request {
|
||||
package-id: package-id,
|
||||
version-hash: string,
|
||||
error: option<download-error>,
|
||||
err: option<download-error>,
|
||||
}
|
||||
|
||||
record hash-mismatch {
|
||||
@ -96,7 +97,7 @@ interface downloads {
|
||||
version-hash: string,
|
||||
}
|
||||
|
||||
// part of new-package-request local-only flow.
|
||||
// part of new-package-request local-only flow.
|
||||
record add-download-request {
|
||||
package-id: package-id,
|
||||
version-hash: string,
|
||||
@ -118,7 +119,7 @@ interface downloads {
|
||||
|
||||
interface chain {
|
||||
//
|
||||
// on-chain API as presented by chain:app_store:sys-v0
|
||||
// on-chain API as presented by chain:app_store:sys-v1
|
||||
//
|
||||
|
||||
use standard.{package-id};
|
||||
@ -137,13 +138,13 @@ interface chain {
|
||||
get-our-apps(list<onchain-app>),
|
||||
auto-update-started,
|
||||
auto-update-stopped,
|
||||
error(chain-error),
|
||||
err(chain-error),
|
||||
}
|
||||
|
||||
variant chain-error {
|
||||
no-package,
|
||||
}
|
||||
|
||||
|
||||
record onchain-app {
|
||||
package-id: package-id,
|
||||
tba: string,
|
||||
@ -177,7 +178,7 @@ interface chain {
|
||||
|
||||
interface main {
|
||||
//
|
||||
// app store API as presented by main:app_store:sys-v0
|
||||
// app store API as presented by main:app_store:sys-v1
|
||||
//
|
||||
|
||||
use standard.{package-id};
|
||||
@ -192,6 +193,7 @@ interface main {
|
||||
local(local-response),
|
||||
chain-error(chain-error),
|
||||
download-error(download-error),
|
||||
handling-error(string),
|
||||
}
|
||||
|
||||
variant local-request {
|
||||
@ -215,7 +217,7 @@ interface main {
|
||||
package-id: package-id,
|
||||
mirror: bool,
|
||||
}
|
||||
|
||||
|
||||
record install-package-request {
|
||||
package-id: package-id,
|
||||
metadata: option<onchain-metadata>, // if None == local sideload package.
|
||||
@ -250,9 +252,9 @@ interface main {
|
||||
}
|
||||
}
|
||||
|
||||
world app-store-sys-v0 {
|
||||
world app-store-sys-v1 {
|
||||
import main;
|
||||
import downloads;
|
||||
import chain;
|
||||
include process-v0;
|
||||
}
|
||||
}
|
@ -12,6 +12,7 @@ alloy-sol-types = "0.7.6"
|
||||
anyhow = "1.0"
|
||||
bincode = "1.3.3"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", tag = "v0.9.0" }
|
||||
process_macros = { git = "https://github.com/kinode-dao/process_macros", rev = "626e501" }
|
||||
rand = "0.8"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
@ -318,9 +318,7 @@ fn serve_paths(
|
||||
DownloadResponses::GetFiles(files) => {
|
||||
Ok((StatusCode::OK, None, serde_json::to_vec(&files)?))
|
||||
}
|
||||
DownloadResponses::Error(e) => {
|
||||
Err(anyhow::anyhow!("Error from downloads: {:?}", e))
|
||||
}
|
||||
DownloadResponses::Err(e) => Err(anyhow::anyhow!("Error from downloads: {:?}", e)),
|
||||
_ => Err(anyhow::anyhow!(
|
||||
"Invalid response from downloads: {:?}",
|
||||
msg
|
||||
@ -348,9 +346,7 @@ fn serve_paths(
|
||||
DownloadResponses::GetFiles(files) => {
|
||||
Ok((StatusCode::OK, None, serde_json::to_vec(&files)?))
|
||||
}
|
||||
DownloadResponses::Error(e) => {
|
||||
Err(anyhow::anyhow!("Error from downloads: {:?}", e))
|
||||
}
|
||||
DownloadResponses::Err(e) => Err(anyhow::anyhow!("Error from downloads: {:?}", e)),
|
||||
_ => Err(anyhow::anyhow!(
|
||||
"Invalid response from downloads: {:?}",
|
||||
msg
|
||||
@ -509,7 +505,7 @@ fn serve_paths(
|
||||
let msg = serde_json::from_slice::<DownloadResponses>(resp.body())?;
|
||||
match msg {
|
||||
DownloadResponses::Success => Ok((StatusCode::OK, None, vec![])),
|
||||
DownloadResponses::Error(e) => {
|
||||
DownloadResponses::Err(e) => {
|
||||
Err(anyhow::anyhow!("Error starting mirroring: {:?}", e))
|
||||
}
|
||||
_ => Err(anyhow::anyhow!(
|
||||
@ -529,7 +525,7 @@ fn serve_paths(
|
||||
let msg = serde_json::from_slice::<DownloadResponses>(resp.body())?;
|
||||
match msg {
|
||||
DownloadResponses::Success => Ok((StatusCode::OK, None, vec![])),
|
||||
DownloadResponses::Error(e) => {
|
||||
DownloadResponses::Err(e) => {
|
||||
Err(anyhow::anyhow!("Error stopping mirroring: {:?}", e))
|
||||
}
|
||||
_ => Err(anyhow::anyhow!(
|
||||
@ -574,7 +570,7 @@ fn serve_paths(
|
||||
let msg = serde_json::from_slice::<DownloadResponses>(resp.body())?;
|
||||
match msg {
|
||||
DownloadResponses::Success => Ok((StatusCode::OK, None, vec![])),
|
||||
DownloadResponses::Error(e) => Err(anyhow::anyhow!("Error removing file: {:?}", e)),
|
||||
DownloadResponses::Err(e) => Err(anyhow::anyhow!("Error removing file: {:?}", e)),
|
||||
_ => Err(anyhow::anyhow!(
|
||||
"Invalid response from downloads: {:?}",
|
||||
msg
|
||||
@ -610,7 +606,7 @@ fn serve_paths(
|
||||
match msg {
|
||||
ChainResponses::AutoUpdateStarted
|
||||
| ChainResponses::AutoUpdateStopped
|
||||
| ChainResponses::Error(_) => Ok((StatusCode::OK, None, serde_json::to_vec(&msg)?)),
|
||||
| ChainResponses::Err(_) => Ok((StatusCode::OK, None, serde_json::to_vec(&msg)?)),
|
||||
_ => Ok((
|
||||
StatusCode::INTERNAL_SERVER_ERROR,
|
||||
None,
|
||||
|
@ -21,7 +21,8 @@ use crate::kinode::process::downloads::{
|
||||
};
|
||||
use crate::kinode::process::main::{
|
||||
ApisResponse, GetApiResponse, InstallPackageRequest, InstallResponse, LocalRequest,
|
||||
LocalResponse, NewPackageRequest, NewPackageResponse, UninstallResponse,
|
||||
LocalResponse, NewPackageRequest, NewPackageResponse, Response as AppStoreResponse,
|
||||
UninstallResponse,
|
||||
};
|
||||
use kinode_process_lib::{
|
||||
await_message, call_init, get_blob, http, print_to_terminal, println, vfs, Address,
|
||||
@ -33,8 +34,8 @@ use state::State;
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
generate_unused_types: true,
|
||||
world: "app-store-sys-v0",
|
||||
additional_derives: [serde::Deserialize, serde::Serialize],
|
||||
world: "app-store-sys-v1",
|
||||
additional_derives: [serde::Deserialize, serde::Serialize, process_macros::SerdeJsonInto],
|
||||
});
|
||||
|
||||
mod http_api;
|
||||
@ -45,7 +46,7 @@ const VFS_TIMEOUT: u64 = 10;
|
||||
|
||||
// internal types
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, process_macros::SerdeJsonInto)]
|
||||
#[serde(untagged)] // untagged as a meta-type for all incoming requests
|
||||
pub enum Req {
|
||||
LocalRequest(LocalRequest),
|
||||
@ -54,7 +55,7 @@ pub enum Req {
|
||||
Http(http::server::HttpServerRequest),
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, process_macros::SerdeJsonInto)]
|
||||
#[serde(untagged)] // untagged as a meta-type for all incoming responses
|
||||
pub enum Resp {
|
||||
LocalResponse(LocalResponse),
|
||||
@ -73,12 +74,16 @@ fn init(our: Address) {
|
||||
loop {
|
||||
match await_message() {
|
||||
Err(send_error) => {
|
||||
// for now, these are timer callbacks to already finished ft_workers.
|
||||
print_to_terminal(1, &format!("got network error: {send_error}"));
|
||||
print_to_terminal(1, &format!("main: got network error: {send_error}"));
|
||||
}
|
||||
Ok(message) => {
|
||||
if let Err(e) = handle_message(&our, &mut state, &mut http_server, &message) {
|
||||
println!("error handling message: {:?}", e);
|
||||
let error_message = format!("error handling message: {e:?}");
|
||||
print_to_terminal(1, &error_message);
|
||||
Response::new()
|
||||
.body(AppStoreResponse::HandlingError(error_message))
|
||||
.send()
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -96,13 +101,13 @@ fn handle_message(
|
||||
message: &Message,
|
||||
) -> anyhow::Result<()> {
|
||||
if message.is_request() {
|
||||
match serde_json::from_slice::<Req>(message.body())? {
|
||||
match message.body().try_into()? {
|
||||
Req::LocalRequest(local_request) => {
|
||||
if !message.is_local(our) {
|
||||
return Err(anyhow::anyhow!("request from non-local node"));
|
||||
}
|
||||
let (body, blob) = handle_local_request(our, state, local_request);
|
||||
let response = Response::new().body(serde_json::to_vec(&body)?);
|
||||
let response = Response::new().body(&body);
|
||||
if let Some(blob) = blob {
|
||||
response.blob(blob).send()?;
|
||||
} else {
|
||||
@ -130,7 +135,7 @@ fn handle_message(
|
||||
http::server::WsMessageType::Text,
|
||||
LazyLoadBlob {
|
||||
mime: Some("application/json".to_string()),
|
||||
bytes: serde_json::json!({
|
||||
bytes: serde_json::to_vec(&serde_json::json!({
|
||||
"kind": "progress",
|
||||
"data": {
|
||||
"package_id": progress.package_id,
|
||||
@ -138,10 +143,8 @@ fn handle_message(
|
||||
"downloaded": progress.downloaded,
|
||||
"total": progress.total,
|
||||
}
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
}))
|
||||
.unwrap(),
|
||||
},
|
||||
);
|
||||
}
|
||||
@ -155,17 +158,15 @@ fn handle_message(
|
||||
http::server::WsMessageType::Text,
|
||||
LazyLoadBlob {
|
||||
mime: Some("application/json".to_string()),
|
||||
bytes: serde_json::json!({
|
||||
bytes: serde_json::to_vec(&serde_json::json!({
|
||||
"kind": "complete",
|
||||
"data": {
|
||||
"package_id": req.package_id,
|
||||
"version_hash": req.version_hash,
|
||||
"error": req.error,
|
||||
"error": req.err,
|
||||
}
|
||||
})
|
||||
.to_string()
|
||||
.as_bytes()
|
||||
.to_vec(),
|
||||
}))
|
||||
.unwrap(),
|
||||
},
|
||||
);
|
||||
|
||||
@ -206,7 +207,7 @@ fn handle_message(
|
||||
}
|
||||
}
|
||||
} else {
|
||||
match serde_json::from_slice::<Resp>(message.body())? {
|
||||
match message.body().try_into()? {
|
||||
Resp::LocalResponse(_) => {
|
||||
// don't need to handle these at the moment
|
||||
}
|
||||
|
@ -114,7 +114,7 @@ pub fn new_package(
|
||||
|
||||
let download_resp = serde_json::from_slice::<DownloadResponses>(&resp.body())?;
|
||||
|
||||
if let DownloadResponses::Error(e) = download_resp {
|
||||
if let DownloadResponses::Err(e) = download_resp {
|
||||
return Err(anyhow::anyhow!("failed to add download: {:?}", e));
|
||||
}
|
||||
Ok(())
|
||||
|
@ -12,6 +12,7 @@ alloy-sol-types = "0.7.6"
|
||||
anyhow = "1.0"
|
||||
bincode = "1.3.3"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", tag = "v0.9.0" }
|
||||
process_macros = { git = "https://github.com/kinode-dao/process_macros", rev = "626e501" }
|
||||
rand = "0.8"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
@ -23,8 +23,8 @@ use std::{
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
generate_unused_types: true,
|
||||
world: "app-store-sys-v0",
|
||||
additional_derives: [serde::Deserialize, serde::Serialize],
|
||||
world: "app-store-sys-v1",
|
||||
additional_derives: [serde::Deserialize, serde::Serialize, process_macros::SerdeJsonInto],
|
||||
});
|
||||
|
||||
#[cfg(not(feature = "simulation-mode"))]
|
||||
@ -67,7 +67,7 @@ pub struct PackageListing {
|
||||
pub auto_update: bool,
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, process_macros::SerdeJsonInto)]
|
||||
#[serde(untagged)] // untagged as a meta-type for all incoming requests
|
||||
pub enum Req {
|
||||
Eth(eth::EthSubResult),
|
||||
@ -90,11 +90,11 @@ fn init(our: Address) {
|
||||
loop {
|
||||
match await_message() {
|
||||
Err(send_error) => {
|
||||
print_to_terminal(1, &format!("got network error: {send_error}"));
|
||||
print_to_terminal(1, &format!("chain: got network error: {send_error}"));
|
||||
}
|
||||
Ok(message) => {
|
||||
if let Err(e) = handle_message(&our, &mut state, &message) {
|
||||
print_to_terminal(1, &format!("error handling message: {:?}", e));
|
||||
print_to_terminal(1, &format!("chain: error handling message: {:?}", e));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,8 +114,7 @@ fn handle_message(our: &Address, state: &mut State, message: &Message) -> anyhow
|
||||
return Ok(());
|
||||
}
|
||||
} else {
|
||||
let req: Req = serde_json::from_slice(message.body())?;
|
||||
match req {
|
||||
match message.body().try_into()? {
|
||||
Req::Eth(eth_result) => {
|
||||
if !message.is_local(our) || message.source().process != "eth:distro:sys" {
|
||||
return Err(anyhow::anyhow!(
|
||||
@ -162,9 +161,7 @@ fn handle_local_request(state: &mut State, req: ChainRequests) -> anyhow::Result
|
||||
auto_update: app.auto_update,
|
||||
});
|
||||
let response = ChainResponses::GetApp(onchain_app);
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&response)?)
|
||||
.send()?;
|
||||
Response::new().body(&response).send()?;
|
||||
}
|
||||
ChainRequests::GetApps => {
|
||||
let apps: Vec<OnchainApp> = state
|
||||
@ -174,9 +171,7 @@ fn handle_local_request(state: &mut State, req: ChainRequests) -> anyhow::Result
|
||||
.collect();
|
||||
|
||||
let response = ChainResponses::GetApps(apps);
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&response)?)
|
||||
.send()?;
|
||||
Response::new().body(&response).send()?;
|
||||
}
|
||||
ChainRequests::GetOurApps => {
|
||||
let apps: Vec<OnchainApp> = state
|
||||
@ -191,36 +186,26 @@ fn handle_local_request(state: &mut State, req: ChainRequests) -> anyhow::Result
|
||||
.collect();
|
||||
|
||||
let response = ChainResponses::GetOurApps(apps);
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&response)?)
|
||||
.send()?;
|
||||
Response::new().body(&response).send()?;
|
||||
}
|
||||
ChainRequests::StartAutoUpdate(package_id) => {
|
||||
if let Some(listing) = state.listings.get_mut(&package_id.to_process_lib()) {
|
||||
listing.auto_update = true;
|
||||
let response = ChainResponses::AutoUpdateStarted;
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&response)?)
|
||||
.send()?;
|
||||
Response::new().body(&response).send()?;
|
||||
} else {
|
||||
let error_response = ChainResponses::Error(ChainError::NoPackage);
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&error_response)?)
|
||||
.send()?;
|
||||
let error_response = ChainResponses::Err(ChainError::NoPackage);
|
||||
Response::new().body(&error_response).send()?;
|
||||
}
|
||||
}
|
||||
ChainRequests::StopAutoUpdate(package_id) => {
|
||||
if let Some(listing) = state.listings.get_mut(&package_id.to_process_lib()) {
|
||||
listing.auto_update = false;
|
||||
let response = ChainResponses::AutoUpdateStopped;
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&response)?)
|
||||
.send()?;
|
||||
Response::new().body(&response).send()?;
|
||||
} else {
|
||||
let error_response = ChainResponses::Error(ChainError::NoPackage);
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&error_response)?)
|
||||
.send()?;
|
||||
let error_response = ChainResponses::Err(ChainError::NoPackage);
|
||||
Response::new().body(&error_response).send()?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -324,7 +309,7 @@ fn handle_eth_log(our: &Address, state: &mut State, log: eth::Log) -> anyhow::Re
|
||||
metadata: metadata.into(),
|
||||
});
|
||||
Request::to(("our", "downloads", "app_store", "sys"))
|
||||
.body(serde_json::to_vec(&request)?)
|
||||
.body(&request)
|
||||
.send()?;
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ simulation-mode = []
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", tag = "v0.9.0" }
|
||||
process_macros = { git = "https://github.com/kinode-dao/process_macros", rev = "626e501" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
wit-bindgen = "0.24.0"
|
||||
|
@ -1,5 +1,4 @@
|
||||
use crate::kinode::process::downloads::DownloadRequests;
|
||||
use kinode::process::downloads::LocalDownloadRequest;
|
||||
use crate::kinode::process::downloads::{DownloadRequests, LocalDownloadRequest};
|
||||
use kinode_process_lib::{
|
||||
await_next_message_body, call_init, println, Address, PackageId, Request,
|
||||
};
|
||||
@ -7,8 +6,8 @@ use kinode_process_lib::{
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
generate_unused_types: true,
|
||||
world: "app-store-sys-v0",
|
||||
additional_derives: [PartialEq, serde::Deserialize, serde::Serialize],
|
||||
world: "app-store-sys-v1",
|
||||
additional_derives: [PartialEq, serde::Deserialize, serde::Serialize, process_macros::SerdeJsonInto],
|
||||
});
|
||||
|
||||
call_init!(init);
|
||||
@ -38,17 +37,14 @@ fn init(our: Address) {
|
||||
let version_hash: String = arg3.to_string();
|
||||
|
||||
let Ok(_) = Request::to((our.node(), ("downloads", "app_store", "sys")))
|
||||
.body(
|
||||
serde_json::to_vec(&DownloadRequests::LocalDownload(LocalDownloadRequest {
|
||||
package_id: crate::kinode::process::main::PackageId {
|
||||
package_name: package_id.package_name.clone(),
|
||||
publisher_node: package_id.publisher_node.clone(),
|
||||
},
|
||||
download_from: download_from.clone(),
|
||||
desired_version_hash: version_hash.clone(),
|
||||
}))
|
||||
.expect("Failed to serialize LocalDownloadRequest"),
|
||||
)
|
||||
.body(DownloadRequests::LocalDownload(LocalDownloadRequest {
|
||||
package_id: crate::kinode::process::main::PackageId {
|
||||
package_name: package_id.package_name.clone(),
|
||||
publisher_node: package_id.publisher_node.clone(),
|
||||
},
|
||||
download_from: download_from.clone(),
|
||||
desired_version_hash: version_hash.clone(),
|
||||
}))
|
||||
.send()
|
||||
else {
|
||||
println!("download: failed to send request to downloads:app_store!");
|
||||
|
@ -9,6 +9,7 @@ simulation-mode = []
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "1c495ad" }
|
||||
process_macros = { git = "https://github.com/kinode-dao/process_macros", rev = "626e501" }
|
||||
rand = "0.8"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
@ -23,8 +23,8 @@ use sha2::{Digest, Sha256};
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
generate_unused_types: true,
|
||||
world: "app-store-sys-v0",
|
||||
additional_derives: [serde::Deserialize, serde::Serialize],
|
||||
world: "app-store-sys-v1",
|
||||
additional_derives: [serde::Deserialize, serde::Serialize, process_macros::SerdeJsonInto],
|
||||
});
|
||||
|
||||
mod ft_worker_lib;
|
||||
@ -32,7 +32,7 @@ mod ft_worker_lib;
|
||||
pub const VFS_TIMEOUT: u64 = 5; // 5s
|
||||
pub const APP_SHARE_TIMEOUT: u64 = 120; // 120s
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
#[derive(Debug, Serialize, Deserialize, process_macros::SerdeJsonInto)]
|
||||
#[serde(untagged)] // untagged as a meta-type for all incoming responses
|
||||
pub enum Resp {
|
||||
Download(DownloadResponses),
|
||||
@ -83,7 +83,7 @@ fn init(our: Address) {
|
||||
loop {
|
||||
match await_message() {
|
||||
Err(send_error) => {
|
||||
print_to_terminal(1, &format!("got network error: {send_error}"));
|
||||
print_to_terminal(1, &format!("downloads: got network error: {send_error}"));
|
||||
}
|
||||
Ok(message) => {
|
||||
if let Err(e) = handle_message(
|
||||
@ -94,7 +94,14 @@ fn init(our: Address) {
|
||||
&mut tmp,
|
||||
&mut auto_updates,
|
||||
) {
|
||||
print_to_terminal(1, &format!("error handling message: {:?}", e));
|
||||
let error_message = format!("error handling message: {e:?}");
|
||||
print_to_terminal(1, &error_message);
|
||||
Response::new()
|
||||
.body(DownloadResponses::Err(DownloadError::HandlingError(
|
||||
error_message,
|
||||
)))
|
||||
.send()
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -114,7 +121,7 @@ fn handle_message(
|
||||
auto_updates: &mut HashSet<(PackageId, String)>,
|
||||
) -> anyhow::Result<()> {
|
||||
if message.is_request() {
|
||||
match serde_json::from_slice::<DownloadRequests>(message.body())? {
|
||||
match message.body().try_into()? {
|
||||
DownloadRequests::LocalDownload(download_request) => {
|
||||
// we want to download a package.
|
||||
if !message.is_local(our) {
|
||||
@ -158,13 +165,11 @@ fn handle_message(
|
||||
)?;
|
||||
|
||||
Request::to((&download_from, "downloads", "app_store", "sys"))
|
||||
.body(serde_json::to_vec(&DownloadRequests::RemoteDownload(
|
||||
RemoteDownloadRequest {
|
||||
package_id,
|
||||
desired_version_hash,
|
||||
worker_address: our_worker.to_string(),
|
||||
},
|
||||
))?)
|
||||
.body(DownloadRequests::RemoteDownload(RemoteDownloadRequest {
|
||||
package_id,
|
||||
desired_version_hash,
|
||||
worker_address: our_worker.to_string(),
|
||||
}))
|
||||
.send()?;
|
||||
}
|
||||
DownloadRequests::RemoteDownload(download_request) => {
|
||||
@ -187,11 +192,11 @@ fn handle_message(
|
||||
&target_worker,
|
||||
)?;
|
||||
}
|
||||
DownloadRequests::Progress(progress) => {
|
||||
DownloadRequests::Progress(ref progress) => {
|
||||
// forward progress to main:app_store:sys,
|
||||
// pushed to UI via websockets
|
||||
let _ = Request::to(("our", "main", "app_store", "sys"))
|
||||
.body(serde_json::to_vec(&progress)?)
|
||||
.body(progress)
|
||||
.send();
|
||||
}
|
||||
DownloadRequests::DownloadComplete(req) => {
|
||||
@ -253,7 +258,7 @@ fn handle_message(
|
||||
|
||||
let resp = DownloadResponses::GetFiles(files);
|
||||
|
||||
Response::new().body(serde_json::to_string(&resp)?).send()?;
|
||||
Response::new().body(&resp).send()?;
|
||||
}
|
||||
DownloadRequests::RemoveFile(remove_req) => {
|
||||
if !message.is_local(our) {
|
||||
@ -273,9 +278,7 @@ fn handle_message(
|
||||
let manifest_path = format!("{}/{}.json", package_dir, version_hash);
|
||||
let _ = vfs::remove_file(&manifest_path, None);
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&Resp::Download(
|
||||
DownloadResponses::Success,
|
||||
))?)
|
||||
.body(Resp::Download(DownloadResponses::Success))
|
||||
.send()?;
|
||||
}
|
||||
DownloadRequests::AddDownload(add_req) => {
|
||||
@ -310,9 +313,7 @@ fn handle_message(
|
||||
}
|
||||
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&Resp::Download(
|
||||
DownloadResponses::Success,
|
||||
))?)
|
||||
.body(Resp::Download(DownloadResponses::Success))
|
||||
.send()?;
|
||||
}
|
||||
DownloadRequests::StartMirroring(package_id) => {
|
||||
@ -320,9 +321,7 @@ fn handle_message(
|
||||
state.mirroring.insert(package_id);
|
||||
set_state(&serde_json::to_vec(&state)?);
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&Resp::Download(
|
||||
DownloadResponses::Success,
|
||||
))?)
|
||||
.body(Resp::Download(DownloadResponses::Success))
|
||||
.send()?;
|
||||
}
|
||||
DownloadRequests::StopMirroring(package_id) => {
|
||||
@ -330,9 +329,7 @@ fn handle_message(
|
||||
state.mirroring.remove(&package_id);
|
||||
set_state(&serde_json::to_vec(&state)?);
|
||||
Response::new()
|
||||
.body(serde_json::to_vec(&Resp::Download(
|
||||
DownloadResponses::Success,
|
||||
))?)
|
||||
.body(Resp::Download(DownloadResponses::Success))
|
||||
.send()?;
|
||||
}
|
||||
DownloadRequests::AutoUpdate(auto_update_request) => {
|
||||
@ -369,9 +366,7 @@ fn handle_message(
|
||||
|
||||
// kick off local download to ourselves.
|
||||
Request::to(("our", "downloads", "app_store", "sys"))
|
||||
.body(serde_json::to_vec(&DownloadRequests::LocalDownload(
|
||||
download_request,
|
||||
))?)
|
||||
.body(DownloadRequests::LocalDownload(download_request))
|
||||
.send()?;
|
||||
|
||||
auto_updates.insert((process_lib_package_id, version_hash));
|
||||
@ -379,7 +374,7 @@ fn handle_message(
|
||||
_ => {}
|
||||
}
|
||||
} else {
|
||||
match serde_json::from_slice::<Resp>(message.body())? {
|
||||
match message.body().try_into()? {
|
||||
Resp::Download(download_response) => {
|
||||
// these are handled in line.
|
||||
print_to_terminal(
|
||||
@ -403,13 +398,13 @@ fn handle_message(
|
||||
&format!("error handling http_client response: {:?}", e),
|
||||
);
|
||||
Request::to(("our", "main", "app_store", "sys"))
|
||||
.body(serde_json::to_vec(&DownloadRequests::DownloadComplete(
|
||||
.body(DownloadRequests::DownloadComplete(
|
||||
DownloadCompleteRequest {
|
||||
package_id: download_request.package_id.clone(),
|
||||
version_hash: download_request.desired_version_hash.clone(),
|
||||
error: Some(e),
|
||||
err: Some(e),
|
||||
},
|
||||
))?)
|
||||
))
|
||||
.send()?;
|
||||
}
|
||||
}
|
||||
@ -462,14 +457,11 @@ fn handle_receive_http_download(
|
||||
extract_and_write_manifest(&bytes, &manifest_path).map_err(|_| DownloadError::VfsError)?;
|
||||
|
||||
Request::to(("our", "main", "app_store", "sys"))
|
||||
.body(
|
||||
serde_json::to_vec(&DownloadCompleteRequest {
|
||||
package_id: download_request.package_id.clone(),
|
||||
version_hash,
|
||||
error: None,
|
||||
})
|
||||
.unwrap(),
|
||||
)
|
||||
.body(DownloadCompleteRequest {
|
||||
package_id: download_request.package_id.clone(),
|
||||
version_hash,
|
||||
err: None,
|
||||
})
|
||||
.send()
|
||||
.unwrap();
|
||||
|
||||
|
@ -10,6 +10,7 @@ simulation-mode = []
|
||||
anyhow = "1.0"
|
||||
bincode = "1.3.3"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", rev = "1c495ad" }
|
||||
process_macros = { git = "https://github.com/kinode-dao/process_macros", rev = "626e501" }
|
||||
rand = "0.8"
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
|
@ -16,8 +16,8 @@ pub mod ft_worker_lib;
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
generate_unused_types: true,
|
||||
world: "app-store-sys-v0",
|
||||
additional_derives: [serde::Deserialize, serde::Serialize],
|
||||
world: "app-store-sys-v1",
|
||||
additional_derives: [serde::Deserialize, serde::Serialize, process_macros::SerdeJsonInto],
|
||||
});
|
||||
|
||||
const CHUNK_SIZE: u64 = 262144; // 256KB
|
||||
@ -42,10 +42,10 @@ fn init(our: Address) {
|
||||
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
let req: DownloadRequests =
|
||||
serde_json::from_slice(&body).expect("ft_worker: got unparseable init message");
|
||||
|
||||
match req {
|
||||
match body
|
||||
.try_into()
|
||||
.expect("ft_worker: got unparseable init message")
|
||||
{
|
||||
DownloadRequests::LocalDownload(local_request) => {
|
||||
let LocalDownloadRequest {
|
||||
package_id,
|
||||
@ -107,10 +107,10 @@ fn handle_sender(worker: &str, package_id: &PackageId, version_hash: &str) -> an
|
||||
let num_chunks = (size as f64 / CHUNK_SIZE as f64).ceil() as u64;
|
||||
|
||||
Request::new()
|
||||
.body(serde_json::to_vec(&DownloadRequests::Size(SizeUpdate {
|
||||
.body(DownloadRequests::Size(SizeUpdate {
|
||||
package_id: package_id.clone().into(),
|
||||
size,
|
||||
}))?)
|
||||
}))
|
||||
.target(target_worker.clone())
|
||||
.send()?;
|
||||
file.seek(SeekFrom::Start(0))?;
|
||||
@ -154,13 +154,11 @@ fn handle_receiver(
|
||||
if *message.source() == timer_address {
|
||||
return Ok(());
|
||||
}
|
||||
let Message::Request { body, .. } = message else {
|
||||
if !message.is_request() {
|
||||
return Err(anyhow::anyhow!("ft_worker: got bad message"));
|
||||
};
|
||||
}
|
||||
|
||||
let req: DownloadRequests = serde_json::from_slice(&body)?;
|
||||
|
||||
match req {
|
||||
match message.body().try_into()? {
|
||||
DownloadRequests::Chunk(chunk) => {
|
||||
handle_chunk(&mut file, &chunk, parent_process, &mut size, &mut hasher)?;
|
||||
if let Some(s) = size {
|
||||
@ -180,15 +178,13 @@ fn handle_receiver(
|
||||
let req = DownloadCompleteRequest {
|
||||
package_id: package_id.clone().into(),
|
||||
version_hash: version_hash.to_string(),
|
||||
error: Some(DownloadError::HashMismatch(HashMismatch {
|
||||
err: Some(DownloadError::HashMismatch(HashMismatch {
|
||||
desired: version_hash.to_string(),
|
||||
actual: recieved_hash,
|
||||
})),
|
||||
};
|
||||
Request::new()
|
||||
.body(serde_json::to_vec(&DownloadRequests::DownloadComplete(
|
||||
req,
|
||||
))?)
|
||||
.body(DownloadRequests::DownloadComplete(req))
|
||||
.target(parent_process.clone())
|
||||
.send()?;
|
||||
}
|
||||
@ -200,13 +196,13 @@ fn handle_receiver(
|
||||
extract_and_write_manifest(&contents, &manifest_filename)?;
|
||||
|
||||
Request::new()
|
||||
.body(serde_json::to_vec(&DownloadRequests::DownloadComplete(
|
||||
.body(DownloadRequests::DownloadComplete(
|
||||
DownloadCompleteRequest {
|
||||
package_id: package_id.clone().into(),
|
||||
version_hash: version_hash.to_string(),
|
||||
error: None,
|
||||
err: None,
|
||||
},
|
||||
))?)
|
||||
))
|
||||
.target(parent_process.clone())
|
||||
.send()?;
|
||||
return Ok(());
|
||||
@ -238,14 +234,12 @@ fn send_chunk(
|
||||
file.read_at(&mut buffer)?;
|
||||
|
||||
Request::new()
|
||||
.body(serde_json::to_vec(&DownloadRequests::Chunk(
|
||||
ChunkRequest {
|
||||
package_id: package_id.clone().into(),
|
||||
version_hash: version_hash.to_string(),
|
||||
offset,
|
||||
length,
|
||||
},
|
||||
))?)
|
||||
.body(DownloadRequests::Chunk(ChunkRequest {
|
||||
package_id: package_id.clone().into(),
|
||||
version_hash: version_hash.to_string(),
|
||||
offset,
|
||||
length,
|
||||
}))
|
||||
.target(target.clone())
|
||||
.blob_bytes(buffer)
|
||||
.send()?;
|
||||
@ -272,14 +266,12 @@ fn handle_chunk(
|
||||
// let progress = ((chunk.offset + chunk.length) as f64 / *total_size as f64 * 100.0) as u64;
|
||||
|
||||
Request::new()
|
||||
.body(serde_json::to_vec(&DownloadRequests::Progress(
|
||||
ProgressUpdate {
|
||||
package_id: chunk.package_id.clone(),
|
||||
downloaded: chunk.offset + chunk.length,
|
||||
total: *total_size,
|
||||
version_hash: chunk.version_hash.clone(),
|
||||
},
|
||||
))?)
|
||||
.body(DownloadRequests::Progress(ProgressUpdate {
|
||||
package_id: chunk.package_id.clone(),
|
||||
downloaded: chunk.offset + chunk.length,
|
||||
total: *total_size,
|
||||
version_hash: chunk.version_hash.clone(),
|
||||
}))
|
||||
.target(parent.clone())
|
||||
.send()?;
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ simulation-mode = []
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", tag = "v0.9.0" }
|
||||
process_macros = { git = "https://github.com/kinode-dao/process_macros", rev = "626e501" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
wit-bindgen = "0.24.0"
|
||||
|
@ -8,8 +8,8 @@ use kinode_process_lib::{
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
generate_unused_types: true,
|
||||
world: "app-store-sys-v0",
|
||||
additional_derives: [PartialEq, serde::Deserialize, serde::Serialize],
|
||||
world: "app-store-sys-v1",
|
||||
additional_derives: [PartialEq, serde::Deserialize, serde::Serialize, process_macros::SerdeJsonInto],
|
||||
});
|
||||
|
||||
call_init!(init);
|
||||
@ -40,24 +40,21 @@ fn init(our: Address) {
|
||||
|
||||
let Ok(Ok(Message::Response { body, .. })) =
|
||||
Request::to((our.node(), ("main", "app_store", "sys")))
|
||||
.body(
|
||||
serde_json::to_vec(&LocalRequest::Install(InstallPackageRequest {
|
||||
package_id: crate::kinode::process::main::PackageId {
|
||||
package_name: package_id.package_name.clone(),
|
||||
publisher_node: package_id.publisher_node.clone(),
|
||||
},
|
||||
version_hash,
|
||||
metadata: None,
|
||||
}))
|
||||
.unwrap(),
|
||||
)
|
||||
.body(LocalRequest::Install(InstallPackageRequest {
|
||||
package_id: crate::kinode::process::main::PackageId {
|
||||
package_name: package_id.package_name.clone(),
|
||||
publisher_node: package_id.publisher_node.clone(),
|
||||
},
|
||||
version_hash,
|
||||
metadata: None,
|
||||
}))
|
||||
.send_and_await_response(5)
|
||||
else {
|
||||
println!("install: failed to get a response from app_store..!");
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(response) = serde_json::from_slice::<LocalResponse>(&body) else {
|
||||
let Ok(response) = body.try_into() else {
|
||||
println!("install: failed to parse response from app_store..!");
|
||||
return;
|
||||
};
|
||||
|
@ -9,6 +9,7 @@ simulation-mode = []
|
||||
[dependencies]
|
||||
anyhow = "1.0"
|
||||
kinode_process_lib = { git = "https://github.com/kinode-dao/process_lib", tag = "v0.9.0" }
|
||||
process_macros = { git = "https://github.com/kinode-dao/process_macros", rev = "626e501" }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
wit-bindgen = "0.24.0"
|
||||
|
@ -6,8 +6,8 @@ use kinode_process_lib::{
|
||||
wit_bindgen::generate!({
|
||||
path: "target/wit",
|
||||
generate_unused_types: true,
|
||||
world: "app-store-sys-v0",
|
||||
additional_derives: [PartialEq, serde::Deserialize, serde::Serialize],
|
||||
world: "app-store-sys-v1",
|
||||
additional_derives: [PartialEq, serde::Deserialize, serde::Serialize, process_macros::SerdeJsonInto],
|
||||
});
|
||||
|
||||
call_init!(init);
|
||||
@ -33,22 +33,19 @@ fn init(our: Address) {
|
||||
|
||||
let Ok(Ok(Message::Response { body, .. })) =
|
||||
Request::to((our.node(), ("main", "app_store", "sys")))
|
||||
.body(
|
||||
serde_json::to_vec(&LocalRequest::Uninstall(
|
||||
crate::kinode::process::main::PackageId {
|
||||
package_name: package_id.package_name.clone(),
|
||||
publisher_node: package_id.publisher_node.clone(),
|
||||
},
|
||||
))
|
||||
.unwrap(),
|
||||
)
|
||||
.body(LocalRequest::Uninstall(
|
||||
crate::kinode::process::main::PackageId {
|
||||
package_name: package_id.package_name.clone(),
|
||||
publisher_node: package_id.publisher_node.clone(),
|
||||
},
|
||||
))
|
||||
.send_and_await_response(5)
|
||||
else {
|
||||
println!("uninstall: failed to get a response from app_store..!");
|
||||
return;
|
||||
};
|
||||
|
||||
let Ok(response) = serde_json::from_slice::<LocalResponse>(&body) else {
|
||||
let Ok(response) = body.try_into() else {
|
||||
println!("uninstall: failed to parse response from app_store..!");
|
||||
return;
|
||||
};
|
||||
|
10
kinode/packages/chess/Cargo.toml
Normal file
10
kinode/packages/chess/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"chess",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
lto = true
|
10
kinode/packages/homepage/Cargo.toml
Normal file
10
kinode/packages/homepage/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"homepage",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
lto = true
|
11
kinode/packages/kino_updates/Cargo.toml
Normal file
11
kinode/packages/kino_updates/Cargo.toml
Normal file
@ -0,0 +1,11 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"blog",
|
||||
"globe",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
lto = true
|
12
kinode/packages/kns_indexer/Cargo.toml
Normal file
12
kinode/packages/kns_indexer/Cargo.toml
Normal file
@ -0,0 +1,12 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"get_block",
|
||||
"kns_indexer",
|
||||
"state",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
lto = true
|
10
kinode/packages/settings/Cargo.toml
Normal file
10
kinode/packages/settings/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"settings",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
lto = true
|
22
kinode/packages/terminal/Cargo.toml
Normal file
22
kinode/packages/terminal/Cargo.toml
Normal file
@ -0,0 +1,22 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"alias",
|
||||
"cat",
|
||||
"echo",
|
||||
"help",
|
||||
"hi",
|
||||
"kfetch",
|
||||
"kill",
|
||||
"m",
|
||||
"net_diagnostics",
|
||||
"peer",
|
||||
"peers",
|
||||
"terminal",
|
||||
"top",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
lto = true
|
10
kinode/packages/tester/Cargo.toml
Normal file
10
kinode/packages/tester/Cargo.toml
Normal file
@ -0,0 +1,10 @@
|
||||
[workspace]
|
||||
resolver = "2"
|
||||
members = [
|
||||
"tester",
|
||||
]
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
opt-level = "s"
|
||||
lto = true
|
@ -1544,6 +1544,7 @@ pub struct Erc721Metadata {
|
||||
/// - `screenshots`: An optional field containing a list of URLs to screenshots of the package.
|
||||
/// - `wit_version`: An optional field containing the version of the WIT standard that the package adheres to.
|
||||
/// - `dependencies`: An optional field containing a list of `PackageId`s: API dependencies.
|
||||
/// - `api_includes`: An optional field containing a list of `PathBuf`s: additional files to include in the `api.zip`.
|
||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
||||
pub struct Erc721Properties {
|
||||
pub package_name: String,
|
||||
@ -1555,6 +1556,7 @@ pub struct Erc721Properties {
|
||||
pub screenshots: Option<Vec<String>>,
|
||||
pub wit_version: Option<u32>,
|
||||
pub dependencies: Option<Vec<String>>,
|
||||
pub api_includes: Option<Vec<std::path::PathBuf>>,
|
||||
}
|
||||
|
||||
/// the type that gets deserialized from each entry in the array in `manifest.json`
|
||||
|
Loading…
Reference in New Issue
Block a user