NEAR Fungible Token ICO Exchange I (Rust)

Fungible Token ICo Exchange

Contract A - EXCHANGE contract

/**
 * Cross contract call method:
 * 1) It checks whether the Seller/Exchange contract (A) is authorized in FT ICO contract (B) or not
 * 2) It checks whether the Buyer account has enough storage balance in FT ICO contract (B) to be able to buy FT or not
 * 3) It calls transfer_tokens method in FT ICO contract (B), which transfers FTs to the Buyer account and sends calculated reward/fee back to the Seller/Exchange (A)
 *
 */
pub fn transfer_tokens(&self, ico_account_id: AccountId, buyer_account_id:AccountId, near_price: u128, tokens: u128, msg: String) -> Promise

/**
 * Callback method for transfer_tokens cross contract call.
 *
 * If all 3 promise results are successful, the Seller/Exchange contract(A) sends money for transfered tokens to the FT ICO contract (B)
 * This method returns a reward/fee, which is transfered back from FT ICO contract (B) to the Seller/Exchange contract (A) as a profit.
 */
pub fn buy_tokens(&mut self, ico_account_id: AccountId, amount: u128) -> u128

/**
 * Helper method - money (NEAR) transfer to another account
 */
pub fn transfer_money(&mut self, account_id: AccountId, amount: u64)

Contract B - Fungible Token ICO contract

/**
 * Initialization of the Fungible Token contract with [FT metadata (NEP-148)](https://nomicon.io/Standards/FungibleToken/Metadata.html#reference-level-explanation){:target="_blank"}
 */
pub fn new(owner_id: ValidAccountId, total_supply: u128, metadata: FungibleTokenMetadata) -> Self

/**
 * Create new FT ICO offer with predefined supply and price in NEAR
 */
pub fn new_offer(&mut self, near_price: u128, supply: u128)

/**
 * Remove FT ICO offer
 */
pub fn remove_offer(&mut self, near_price: u128)

/**
 * View single FT ICO offer
 */
pub fn get_offer(&self, near_price: u128) -> Option<u128>

/**
 * Get all FT ICO offers - paginated
 */
pub fn get_all_offers(&self, from_index: u64, limit: u64) -> Vec<(u128, u128)>

/**
 * Add new authorized Seller/Exchange with predefined fee/reward (percentage from every FT sale)
 */
pub fn new_seller(&mut self, account_id: String, fee: f64)

/**
 * Remove/Unauthorize Seller/Exchange
 */
pub fn remove_seller(&mut self, account_id: String)

/**
 * Get authorized Seller/Exchange and it's fee/reward
 */
pub fn get_seller(&self, account_id: String) -> Option<f64>

/**
 * Get all authorized Sellers/Exchanges - paginated
 */
pub fn get_all_sellers(&self, from_index: u64, limit: u64) -> Vec<(String, f64)>

/**
 * Helper method to check whether the ICO tokens buyer has a storage
 */
pub fn has_storage(&self, account_id: ValidAccountId) -> bool

/**
 * Main method for transfering FT ICO tokens to a buyer and paying fee/reward to a Seller/Exchange
 */
pub fn transfer_tokens(&mut self, exchange_account: String, buyer_account_id: ValidAccountId, near_price: u128, tokens: u128, msg: String) -> u128

/**
 * Helper method - money (NEAR) transfer to another account
 */
pub fn transfer_money(&mut self, account_id: AccountId, amount: u64)

Demo usage

Build and Dev deploy contracts

sh

./build.sh

Contract A:

cd contract-a-exchange


near dev-deploy --wasmFile res/contract_a_exchange.wasm


source neardev/dev-account.env


export EXCHANGE=$CONTRACT_NAME

The Seller/Exchange contract dev-account should be the same as $CONTRACT_NAME

echo $EXCHANGE $CONTRACT_NAME

Contract B:

cd ../contract-b-ft-ico


near dev-deploy --wasmFile res/fungible_token.wasm


source neardev/dev-account.env


export ICO=$CONTRACT_NAME

The FT ICO contract dev-account should be the same as $CONTRACT_NAME

echo $ICO $CONTRACT_NAME

Initialize the FT ICO contract (B)

near call $ICO new '{"owner_id": "'$ICO'", "total_supply": 1000, "metadata": { "spec": "ft-1.0.0", "name": "NCD Token", "symbol": "NCDT", "decimals": 0 }}' --accountId $ICO

Get the fungible token metadata

near view $ICO ft_metadata

Create some demo ICO offers

near call $ICO new_offer '{"near_price":10, "supply":100}' --accountId $ICO

near call $ICO new_offer '{"near_price":20, "supply":200}' --accountId $ICO

near call $ICO new_offer '{"near_price":30, "supply":300}' --accountId $ICO

near call $ICO new_offer '{"near_price":40, "supply":0}' --accountId $ICO

Get all available offers

near view $ICO get_all_offers '{"from_index":0, "limit":20}' --accountId $ICO

Add new authorized Seller/Exchange

near call $ICO new_seller '{"account_id":"'$EXCHANGE'", "fee":10.0}' --accountId $ICO

Get all authorized Sellers/Exchanges

near view $ICO get_all_sellers '{"from_index":0, "limit":20}'

Sell FT ICO offer via EXCHANGE contract to a 3rd party buyer

Add storage deposit for a user

near call $ICO storage_deposit '{"account_id": "<buyer_test_acount>"}' --accountId <buyer_test_acount> --deposit 0.00125

Transfer FT tokens (minimum deposit from buyer account is needed, so the Exchange gets paid).

near call $EXCHANGE transfer_tokens '{"ico_account_id": "'$ICO'", "buyer_account_id": "<buyer_test_acount>", "near_price": 20, "tokens": 1, "msg":"Test transfer"}' --accountId <buyer_test_acount> --gas 300000000000000 --deposit <near_price * tokens>

Get FT Balance of buyer_test_account - The response should be 1

near view $ICO ft_balance_of '{"account_id":"<buyer_test_acount>"}'

Get FT offer - The response should be 199

near view $ICO get_offer '{"near_price":20}'

Credits and links

Part 2: VUE Frontend + PHP Laravel Gateway

NEAR Protocol

<°}))>{ AGNICO.io | Happy BLOCKCHAIN Apps