-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from near-examples/add-factory
Add factory to deploy auctions
- Loading branch information
Showing
9 changed files
with
397 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,14 @@ | ||
name: Tests Factory | ||
on: push | ||
jobs: | ||
workflows: | ||
strategy: | ||
matrix: | ||
platform: [ubuntu-latest, macos-latest] | ||
runs-on: ${{ matrix.platform }} | ||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: Install and test modules | ||
run: | | ||
cd ./factory | ||
cargo test |
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 = "contract" | ||
description = "Factory Contract Example" | ||
version = "0.1.0" | ||
edition = "2021" | ||
# TODO: Fill out the repository field to help NEAR ecosystem tools to discover your project. | ||
# NEP-0330 is automatically implemented for all contracts built with https://github.com/near/cargo-near. | ||
# Link to the repository will be available via `contract_source_metadata` view-function. | ||
#repository = "https://github.com/xxx/xxx" | ||
|
||
[lib] | ||
crate-type = ["cdylib", "rlib"] | ||
|
||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | ||
[dependencies] | ||
near-sdk = { version = "5.5.0", features = ["unstable"] } | ||
|
||
[dev-dependencies] | ||
near-sdk = { version = "5.5.0", features = ["unit-testing"] } | ||
near-workspaces = { version = "0.14.0", features = ["unstable"] } | ||
tokio = { version = "1.12.0", features = ["full"] } | ||
serde_json = "1" | ||
chrono = "0.4.38" | ||
|
||
[profile.release] | ||
codegen-units = 1 | ||
# Tell `rustc` to optimize for small code size. | ||
opt-level = "z" | ||
lto = true | ||
debug = false | ||
panic = "abort" | ||
# Opt into extra safety checks on arithmetic operations https://stackoverflow.com/a/64136471/249801 | ||
overflow-checks = true |
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,4 @@ | ||
[toolchain] | ||
channel = "stable" | ||
components = ["rustfmt"] | ||
targets = ["wasm32-unknown-unknown"] |
Binary file not shown.
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,107 @@ | ||
use near_sdk::json_types::{U128, U64}; | ||
use near_sdk::serde::Serialize; | ||
use near_sdk::{env, log, near, AccountId, NearToken, Promise, PromiseError}; | ||
|
||
use crate::{Contract, ContractExt, NEAR_PER_STORAGE, NO_DEPOSIT, TGAS}; | ||
|
||
pub type TokenId = String; | ||
|
||
#[derive(Serialize)] | ||
#[serde(crate = "near_sdk::serde")] | ||
struct AuctionInitArgs { | ||
end_time: U64, | ||
auctioneer: AccountId, | ||
ft_contract: AccountId, | ||
nft_contract: AccountId, | ||
token_id: TokenId, | ||
starting_price: U128, | ||
} | ||
|
||
#[near] | ||
impl Contract { | ||
#[payable] | ||
pub fn deploy_new_auction( | ||
&mut self, | ||
name: String, | ||
end_time: U64, | ||
auctioneer: AccountId, | ||
ft_contract: AccountId, | ||
nft_contract: AccountId, | ||
token_id: TokenId, | ||
starting_price: U128, | ||
) -> Promise { | ||
// Assert the sub-account is valid | ||
let current_account = env::current_account_id().to_string(); | ||
let subaccount: AccountId = format!("{name}.{current_account}").parse().unwrap(); | ||
assert!( | ||
env::is_valid_account_id(subaccount.as_bytes()), | ||
"Invalid subaccount" | ||
); | ||
|
||
// Assert enough tokens are attached to create the account and deploy the contract | ||
let attached = env::attached_deposit(); | ||
|
||
let code = self.code.clone().unwrap(); | ||
let contract_bytes = code.len() as u128; | ||
let contract_storage_cost = NEAR_PER_STORAGE.saturating_mul(contract_bytes); | ||
let minimum_needed = contract_storage_cost.saturating_add(NearToken::from_millinear(100)); | ||
assert!( | ||
attached >= minimum_needed, | ||
"Attach at least {minimum_needed} yⓃ" | ||
); | ||
|
||
let args = &AuctionInitArgs { | ||
end_time, | ||
auctioneer, | ||
ft_contract, | ||
nft_contract, | ||
token_id, | ||
starting_price, | ||
}; | ||
|
||
let init_args = near_sdk::serde_json::to_vec(args).unwrap(); | ||
|
||
let promise = Promise::new(subaccount.clone()) | ||
.create_account() | ||
.transfer(attached) | ||
.deploy_contract(code) | ||
.function_call( | ||
"init".to_owned(), | ||
init_args, | ||
NO_DEPOSIT, | ||
TGAS.saturating_mul(5), | ||
); | ||
|
||
// Add callback | ||
promise.then( | ||
Self::ext(env::current_account_id()).deploy_new_auction_callback( | ||
subaccount, | ||
env::predecessor_account_id(), | ||
attached, | ||
), | ||
) | ||
} | ||
|
||
#[private] | ||
pub fn deploy_new_auction_callback( | ||
&mut self, | ||
account: AccountId, | ||
user: AccountId, | ||
attached: NearToken, | ||
#[callback_result] create_deploy_result: Result<(), PromiseError>, | ||
) -> bool { | ||
if let Ok(_result) = create_deploy_result { | ||
log!("Correctly created and deployed to {}", account); | ||
return true; | ||
}; | ||
|
||
log!( | ||
"Error creating {}, returning {}yⓃ to {}", | ||
account, | ||
attached, | ||
user | ||
); | ||
Promise::new(user).transfer(attached); | ||
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,31 @@ | ||
// Find all our documentation at https://docs.near.org | ||
use near_sdk::store::LazyOption; | ||
use near_sdk::{near, Gas, NearToken}; | ||
|
||
mod deploy; | ||
mod manager; | ||
|
||
const NEAR_PER_STORAGE: NearToken = NearToken::from_yoctonear(10u128.pow(19)); // 10e19yⓃ | ||
const AUCTION_CONTRACT: &[u8] = include_bytes!("./auction-contract/auction.wasm"); | ||
const TGAS: Gas = Gas::from_tgas(1); | ||
const NO_DEPOSIT: NearToken = NearToken::from_near(0); // 0yⓃ | ||
|
||
// Define the contract structure | ||
#[near(contract_state)] | ||
pub struct Contract { | ||
// Since a contract is something big to store, we use LazyOptions | ||
// this way it is not deserialized on each method call | ||
code: LazyOption<Vec<u8>>, | ||
// Please note that it is much more efficient to **not** store this | ||
// code in the state, and directly use `AUCTION_CONTRACT` | ||
// However, this does not enable to update the stored code. | ||
} | ||
|
||
// Define the default, which automatically initializes the contract | ||
impl Default for Contract { | ||
fn default() -> Self { | ||
Self { | ||
code: LazyOption::new("code".as_bytes(), Some(AUCTION_CONTRACT.to_vec())), | ||
} | ||
} | ||
} |
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,19 @@ | ||
use near_sdk::{env, near}; | ||
|
||
use crate::{Contract, ContractExt}; | ||
|
||
#[near] | ||
impl Contract { | ||
#[private] | ||
pub fn update_auction_contract(&mut self) { | ||
// This method receives the code to be stored in the contract directly | ||
// from the contract's input. In this way, it avoids the overhead of | ||
// deserializing parameters, which would consume a huge amount of GAS | ||
self.code.set(env::input()); | ||
} | ||
|
||
pub fn get_code(&self) -> &Vec<u8> { | ||
// If a contract wants to update themselves, they can ask for the code needed | ||
self.code.get().as_ref().unwrap() | ||
} | ||
} |
Binary file not shown.
Oops, something went wrong.