Skip to content
This repository was archived by the owner on Mar 21, 2023. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
366 changes: 362 additions & 4 deletions Cargo.lock

Large diffs are not rendered by default.

20 changes: 5 additions & 15 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,5 @@
[package]
name = "gutenberg"
version = "0.2.0"
edition = "2021"

[dependencies]
thiserror = "1.0"
strfmt = "0.2"
gumdrop = "0.8"

serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"

[dev-dependencies]
pretty_assertions = "1.3.0"
[workspace]
members = [
"crates/gutenberg",
"crates/byte_cli",
]
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ You can obtain a `gutenberg` executable by building it using [cargo](https://doc
```shell
cd gutenberg
cargo build --release
cargo run ./examples/suimarines.yaml
cargo run --bin gutenberg ./examples/suimarines.yaml
```

Alternatively, you can [download a pre-built executable](https://github.com/Origin-Byte/nft-protocol/tags) once these become available.
Expand Down
16 changes: 16 additions & 0 deletions crates/byte_cli/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "byte_cli"
version = "0.2.0"
edition = "2021"

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"
# thiserror = "1.0"
tokio = {version = "1.24", features = ["macros", "rt-multi-thread"]}
clap = {version = "4.0", features = ["derive"]}
anyhow = "1.0"
console = "0.15.4"

[dev-dependencies]
pretty_assertions = "1.3.0"
51 changes: 51 additions & 0 deletions crates/byte_cli/src/cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use clap::{Parser, Subcommand};

pub use crate::consts::DEFAULT_ASSETS_FOLDER;

#[derive(Parser)]
#[clap(author, version, about)]
pub struct Cli {
#[clap(subcommand)]
pub command: Commands,
}

#[derive(Subcommand)]
pub enum Commands {
/// Creates or adds confiiguration to JSON config file to be read by
/// Gutenberg for the purpose of building the Move module
InitCollectionConfig {},

/// Creates or adds configuration to JSON config file to be read the asset
/// deployer for the purpose of deploying assets, usually to an off-chain
/// storage service
InitUploadConfig {
/// Path to the directory with the assets
#[clap(default_value = DEFAULT_ASSETS_FOLDER)]
assets_dir: String,
},

/// Combines `InitCollectionConfig` and `InitUploadConfig in one single flow,
/// hence make the UX seamless for the majority of use cases
InitConfig {
/// Path to the directory with the assets
#[clap(default_value = DEFAULT_ASSETS_FOLDER)]
assets_dir: String,
},

/// Deploys assets to a storage service
DeployAssets {
/// Path to the directory with the assets
#[clap(default_value = DEFAULT_ASSETS_FOLDER)]
assets_dir: String,
},

/// Deploys NFT contract to Sui Blockchain
DeployContract {},

/// Mints NFTs by calling the deployed contract
MintNfts {
/// Path to the directory with the assets
#[clap(default_value = DEFAULT_ASSETS_FOLDER)]
assets_dir: String,
},
}
6 changes: 6 additions & 0 deletions crates/byte_cli/src/consts.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use console::Emoji;

/// Default path for assets folder.
pub const DEFAULT_ASSETS_FOLDER: &str = "assets";

pub const ROCKET_EMOJI: Emoji<'_, '_> = Emoji("🚀 ", "");
3 changes: 3 additions & 0 deletions crates/byte_cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
pub mod cli;
pub mod consts;
pub mod prelude;
40 changes: 40 additions & 0 deletions crates/byte_cli/src/main.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
pub mod cli;
pub mod consts;
pub mod prelude;

use crate::prelude::*;
use anyhow::Result;
use clap::Parser;
use console::style;

#[tokio::main]
async fn main() {
match run().await {
Ok(()) => {
println!(
"\n{}{}",
consts::ROCKET_EMOJI,
style("Process ran successfully.").green().bold().dim()
);
}
Err(err) => {
println!("\n{}", err,);
std::process::exit(1);
}
}
}

async fn run() -> Result<()> {
let cli = Cli::parse();

match cli.command {
Commands::InitCollectionConfig {} => {}
Commands::InitUploadConfig { assets_dir: _ } => {}
Commands::InitConfig { assets_dir: _ } => {}
Commands::DeployAssets { assets_dir: _ } => {}
Commands::DeployContract {} => {}
Commands::MintNfts { assets_dir: _ } => {}
}

Ok(())
}
2 changes: 2 additions & 0 deletions crates/byte_cli/src/prelude.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
pub use crate::cli::{Cli, Commands};
pub use crate::consts;
16 changes: 16 additions & 0 deletions crates/gutenberg/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[package]
name = "gutenberg"
version = "0.2.0"
edition = "2021"

[dependencies]
thiserror = "1.0"
strfmt = "0.2"
gumdrop = "0.8"

serde = { version = "1.0", features = ["derive"] }
serde_yaml = "0.9"
serde_json = "1.0"

[dev-dependencies]
pretty_assertions = "1.3.0"
31 changes: 31 additions & 0 deletions crates/gutenberg/examples/bytes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"NftType": "Classic",
"Collection": {
"name": "Bytes",
"description": "A unique NFT collection of Bytes on Sui",
"symbol": "SUIM",
"tags": ["Art", "ProfilePicture"],
"royalty_fee_bps": "100",
"url": "https://originbyte.io/"
},
"Listings": [
{
"receiver": "@0xcf9bcdb25929869053dd4a2c467539f8b792346f",
"markets": [
{
"FixedPrice": {
"token": "sui::sui::SUI",
"price": 500,
"is_whitelisted": false
}
},
{
"DutchAuction": {
"token": "sui::sui::SUI",
"reserve_price": 100,
"is_whitelisted": true
}
}]
}
]
}
23 changes: 23 additions & 0 deletions crates/gutenberg/examples/packages/Move.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
[package]
name = "Gutenberg"
version = "0.14.0"

[dependencies.Sui]
git = "https://github.com/MystenLabs/sui.git"
subdir = "crates/sui-framework"
# devnet-0.19.0
rev = "a8af20d94e951ecfb6d0cd47c23cf6393013d8a8"

[dependencies.Movemate]
git = "https://github.com/Origin-Byte/movemate.git"
subdir = "sui"
# devnet-0.19.0
rev = "115d56bd59cd9c0f59ac3a39b4c83872efa78608"

[dependencies.NftProtocol]
git = "https://github.com/Origin-Byte/nft-protocol"
# version 0.16.0
rev = "484ffaca16d561d8123c14138770fa99fe5591af"

[addresses]
gutenberg = "0x0"
123 changes: 123 additions & 0 deletions crates/gutenberg/examples/packages/sources/suimarines.move
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
module gutenberg::suimarines {
use std::string::{Self, String};

use sui::url;
use sui::balance;
use sui::transfer;
use sui::tx_context::{Self, TxContext};

use nft_protocol::nft;
use nft_protocol::tags;
use nft_protocol::royalty;
use nft_protocol::display;
use nft_protocol::creators;
use nft_protocol::inventory::{Self, Inventory};
use nft_protocol::royalties::{Self, TradePayment};
use nft_protocol::collection::{Self, Collection, MintCap};

/// One time witness is only instantiated in the init method
struct SUIMARINES has drop {}

/// Can be used for authorization of other actions post-creation. It is
/// vital that this struct is not freely given to any contract, because it
/// serves as an auth token.
struct Witness has drop {}

fun init(witness: SUIMARINES, ctx: &mut TxContext) {
let (mint_cap, collection) = collection::create<SUIMARINES>(
&witness,
ctx,
);

collection::add_domain(
&mut collection,
&mut mint_cap,
creators::from_address(tx_context::sender(ctx))
);

// Register custom domains
display::add_collection_display_domain(
&mut collection,
&mut mint_cap,
string::utf8(b"Suimarines"),
string::utf8(b"A unique NFT collection of Suimarines on Sui"),
);

display::add_collection_url_domain(
&mut collection,
&mut mint_cap,
sui::url::new_unsafe_from_bytes(b"https://originbyte.io/"),
);

display::add_collection_symbol_domain(
&mut collection,
&mut mint_cap,
string::utf8(b"SUIM")
);

let royalty = royalty::new(ctx);
royalty::add_proportional_royalty(
&mut royalty,
nft_protocol::royalty_strategy_bps::new(100),
);
royalty::add_royalty_domain(&mut collection, &mut mint_cap, royalty);

let tags = tags::empty(ctx);
tags::add_tag(&mut tags, tags::art());
tags::add_collection_tag_domain(&mut collection, &mut mint_cap, tags);

transfer::transfer(mint_cap, tx_context::sender(ctx));
transfer::share_object(collection);
}

/// Calculates and transfers royalties to the `RoyaltyDomain`
public entry fun collect_royalty<FT>(
payment: &mut TradePayment<SUIMARINES, FT>,
collection: &mut Collection<SUIMARINES>,
ctx: &mut TxContext,
) {
let b = royalties::balance_mut(Witness {}, payment);

let domain = royalty::royalty_domain(collection);
let royalty_owed =
royalty::calculate_proportional_royalty(domain, balance::value(b));

royalty::collect_royalty(collection, b, royalty_owed);
royalties::transfer_remaining_to_beneficiary(Witness {}, payment, ctx);
}

public entry fun mint_nft(
name: String,
description: String,
url: vector<u8>,
attribute_keys: vector<String>,
attribute_values: vector<String>,
_mint_cap: &MintCap<SUIMARINES>,
inventory: &mut Inventory,
ctx: &mut TxContext,
) {
let nft = nft::new<SUIMARINES>(tx_context::sender(ctx), ctx);

display::add_display_domain(
&mut nft,
name,
description,
ctx,
);

display::add_url_domain(
&mut nft,
url::new_unsafe_from_bytes(url),
ctx,
);

display::add_attributes_domain_from_vec(
&mut nft,
attribute_keys,
attribute_values,
ctx,
);

inventory::deposit_nft(inventory, nft);
}
}
Loading