|
1 |
| -use near_sdk::serde::Serialize; |
2 |
| -use near_sdk::{env, log, near, AccountId, NearToken, Promise, PromiseError, PublicKey}; |
| 1 | +use near_sdk::{env, json_types::U128, log, near, require, AccountId, NearToken, Promise, PromiseError, PublicKey}; |
| 2 | +use near_contract_standards::fungible_token::metadata::FungibleTokenMetadata; |
3 | 3 |
|
4 |
| -use crate::{Contract, ContractExt, NEAR_PER_STORAGE, NO_DEPOSIT, TGAS}; |
| 4 | +use crate::{Contract, ContractExt, FT_CONTRACT, NEAR_PER_STORAGE, NO_DEPOSIT, TGAS}; |
5 | 5 |
|
6 |
| -#[derive(Serialize)] |
7 |
| -#[serde(crate = "near_sdk::serde")] |
8 |
| -struct DonationInitArgs { |
9 |
| - beneficiary: AccountId, |
| 6 | + |
| 7 | +#[near(serializers = [json])] |
| 8 | +pub struct TokenArgs { |
| 9 | + owner_id: AccountId, |
| 10 | + total_supply: U128, |
| 11 | + metadata: FungibleTokenMetadata, |
10 | 12 | }
|
11 | 13 |
|
12 | 14 | #[near]
|
13 | 15 | impl Contract {
|
| 16 | + |
| 17 | + fn get_required(&self, args: &TokenArgs) -> u128 { |
| 18 | + ((FT_WASM_CODE.len() + EXTRA_BYTES + args.try_to_vec().unwrap().len() * 2) as NearToken) |
| 19 | + * STORAGE_PRICE_PER_BYTE) |
| 20 | + .into() |
| 21 | + } |
| 22 | + |
14 | 23 | #[payable]
|
15 |
| - pub fn create_factory_subaccount_and_deploy( |
| 24 | + pub fn create_token( |
16 | 25 | &mut self,
|
17 |
| - name: String, |
18 |
| - beneficiary: AccountId, |
19 |
| - public_key: Option<PublicKey>, |
| 26 | + args: TokenArgs, |
20 | 27 | ) -> Promise {
|
| 28 | + args.metadata.assert_valid(); |
| 29 | + let token_id = args.metadata.symbol.to_ascii_lowercase(); |
| 30 | + |
| 31 | + require!(is_valid_token_id(&token_id), "Invalid Symbol"); |
| 32 | + |
21 | 33 | // Assert the sub-account is valid
|
22 |
| - let current_account = env::current_account_id().to_string(); |
23 |
| - let subaccount: AccountId = format!("{name}.{current_account}").parse().unwrap(); |
| 34 | + let token_account_id = format!("{}.{}", token_id, env::current_account_id()); |
24 | 35 | assert!(
|
25 |
| - env::is_valid_account_id(subaccount.as_bytes()), |
26 |
| - "Invalid subaccount" |
| 36 | + env::is_valid_account_id(token_account_id.as_bytes()), |
| 37 | + "Token Account ID is invalid" |
27 | 38 | );
|
28 | 39 |
|
29 | 40 | // Assert enough tokens are attached to create the account and deploy the contract
|
30 | 41 | let attached = env::attached_deposit();
|
| 42 | + let required = self.get_required(&args); |
31 | 43 |
|
32 |
| - let code = self.code.clone().unwrap(); |
33 |
| - let contract_bytes = code.len() as u128; |
34 |
| - let minimum_needed = NEAR_PER_STORAGE.saturating_mul(contract_bytes); |
35 | 44 | assert!(
|
36 |
| - attached >= minimum_needed, |
| 45 | + attached >= required, |
37 | 46 | "Attach at least {minimum_needed} yⓃ"
|
38 | 47 | );
|
39 | 48 |
|
40 |
| - let init_args = near_sdk::serde_json::to_vec(&DonationInitArgs { beneficiary }).unwrap(); |
| 49 | + let init_args = near_sdk::serde_json::to_vec(args).unwrap(); |
41 | 50 |
|
42 | 51 | let mut promise = Promise::new(subaccount.clone())
|
43 | 52 | .create_account()
|
44 | 53 | .transfer(attached)
|
45 |
| - .deploy_contract(code) |
| 54 | + .deploy_contract(FT_CONTRACT) |
46 | 55 | .function_call(
|
47 |
| - "init".to_owned(), |
| 56 | + "new".to_owned(), |
48 | 57 | init_args,
|
49 | 58 | NO_DEPOSIT,
|
50 |
| - TGAS.saturating_mul(5), |
| 59 | + TGAS.saturating_mul(50), |
51 | 60 | );
|
52 |
| - |
53 |
| - // Add full access key is the user passes one |
54 |
| - if let Some(pk) = public_key { |
55 |
| - promise = promise.add_full_access_key(pk); |
56 |
| - } |
57 |
| - |
58 |
| - // Add callback |
59 |
| - promise.then( |
60 |
| - Self::ext(env::current_account_id()).create_factory_subaccount_and_deploy_callback( |
61 |
| - subaccount, |
62 |
| - env::predecessor_account_id(), |
63 |
| - attached, |
64 |
| - ), |
65 |
| - ) |
66 | 61 | }
|
67 | 62 |
|
68 |
| - #[private] |
69 |
| - pub fn create_factory_subaccount_and_deploy_callback( |
70 |
| - &mut self, |
71 |
| - account: AccountId, |
72 |
| - user: AccountId, |
73 |
| - attached: NearToken, |
74 |
| - #[callback_result] create_deploy_result: Result<(), PromiseError>, |
75 |
| - ) -> bool { |
76 |
| - if let Ok(_result) = create_deploy_result { |
77 |
| - log!(format!("Correctly created and deployed to {account}")); |
78 |
| - return true; |
79 |
| - }; |
80 |
| - |
81 |
| - log!(format!( |
82 |
| - "Error creating {account}, returning {attached}yⓃ to {user}" |
83 |
| - )); |
84 |
| - Promise::new(user).transfer(attached); |
85 |
| - false |
86 |
| - } |
87 | 63 | }
|
0 commit comments