This contract provides functionality to increase the value and utility of NFTs. NFT Benefits Vault allows multiple users to own a private vault for Fungible Assets accessed via the corresponding NFT.
Make sure Rust is installed
Make sure near-cli
is installed
To build run:
./build.sh
Compiled binary will be put in the dist
directory:
./dist/nft_benefits_vault.wasm
To test just run:
./test.sh
To do it manualy, build and place the contract WASM file to the dist
dir. Then:
cargo test [OPTIONS] [TESTNAME] [-- [args]...]
To turn on logger start with env variable RUST_LOG
:
RUST_LOG='nft_benefits_vault=debug' cargo test
Build and deploy this contract to the dev account:
./build.sh
near dev-deploy --wasmFile dist/nft_benefits_vault.wasm
near-cli
will create new dev account and deploy wasm code to it.
The next command will initialize contract using new
method:
near call $CONTRACT_ID new '' --accountId $CONTRACT_ID
To top up balance in vault you need to make ft_transfer_call
with specific msg:
near call $TOKEN_ID ft_transfer_call \
'{"receiver_id": "<receiver-contract>", "amount": "<amount>", "msg": "{\"nft_id\":\"awesome_test_pic_666\",\"nft_contract_id\":\"dev-20221207113253-32677407921596\",\"kind\":\"TopUp\"}"}' \
--accountId $ACCOUNT_ID
--deposit 1
To withdraw FTs from the Vault NFT owner should make a call:
near call $CONTRACT_ID withdraw \
'{"nft_contract_id": "<nft-contract>", "nft_id": "<token-id>", "fungible_token": "<ft-contract-id>"}' \
--accountId $ACCOUNT_ID
--deposit 1
You should create an account on NEAR. For convenience you can save account Id for the contract to the env variable. In the below command, replace MY_ACCOUNT_NAME with the contract account name.
export ID=MY_CONTRACT_ID`
Check env variable with:
echo $ID
Deploy:
near deploy --wasmFile dist/nft_benefits_vault.wasm --accountId $ID
Initialize:
near call $CONTRACT_ID new '' --accountId $CONTRACT_ID
Congrats! NFT Benefits Vault is ready to use.
pub fn withdraw_all(&mut self, nft_contract_id: AccountId, nft_id: TokenId) -> Promise {..}
Public call to withdraw all FTs of every type from the Vault. The contract will check caller ownership of the NFT specified by the NFT contract Id and NFT Id. Then it will try to find the corresponding vault with access via provided contract/id pair.
nft_contract_id
- account id of the NFT contract.
nft_id
- string with unique token Id.
Exactly 1 yoctoNEAR must be attached.
@TODO
pub fn withdraw(
&mut self,
nft_contract_id: AccountId,
nft_id: TokenId,
fungible_token: AccountId,
) {..}
Public call to withdraw all tokens of a single type of FT from the Vault.
The contract will check ownership of the NFT spectified by the arguments.
Than it will try to find the vault with access via provided contract/id pair.
And it makes ft_transfer
with all available tokens on the provided fungible_token
.
nft_contract_id
- account id of the NFT contract.
nft_id
- string with unique token Id.
fungible_token
- contract account id of the FT caller wants to withdraw.
Exactly 1 yoctoNEAR must be attached.
@TODO
pub fn withdraw_amount(
&mut self,
nft_contract_id: AccountId,
nft_id: TokenId,
fungible_token: AccountId,
amount: U128,
) {..}
Public call to withdraw specified amount
of tokens of a single type of FT from the Vault.
The contract will check ownership of the NFT spectified by the arguments.
Than it will try to find the vault with access via provided contract/id pair.
And it makes ft_transfer
with specified amount of tokens on the provided fungible_token
.
nft_contract_id
- account id of the NFT contract.
nft_id
- string with unique token Id.
fungible_token
- contract account id of the FT caller wants to withdraw.
amount
- amount of FTs to be withdrawn, must be provided as string, eg: "1000000000"
.
Exactly 1 yoctoNEAR must be attached.
@TODO
pub fn add_replenishment_callback(
&mut self,
nft_contract_id: AccountId,
nft_id: TokenId,
callback: String,
args: String,
) {..}
This method is used to add replenishers for the Vault.
When NFT owner calls withdraw methods the Contract will transfer available tokens from its own balance and will request available benefits from registered replenishers.
This method MUST be called and signed by replenisher himself because future replenishment requests will be made to the signer account.
The Vault will make call callback
with args
on the env::predecessor_account_id()
.
nft_contract_id
- account id of the NFT contract.
nft_id
- string with unique token Id.
callback
- function name of the external contract.
args
- serialized in json arguments will be passed to the callback
.
Exactly 1 yoctoNEAR must be attached.
@TODO
Complete list of tokens in the Vault.
pub struct BalanceView {
/// Unique identifier of the NFT.
pub nft_id: NftId,
/// List of FTs.
pub tokens: Vec<Token>,
}
Unique identifier of the NFT to be used as the Key to the Vault.
Only [TokenId
] is insufficient because there can be multiple NFT contracts containing the same [TokenId
].
pub struct NftId {
contract_id: AccountId,
token_id: TokenId,
}
Info about FT.
pub struct Token {
/// Account id of the FT contract.
pub contract_id: AccountId,
/// Amount of this tokens in the Vault.
pub amount: u128,
}
Info about vault.
pub struct VaultView {
/// Key NFT with access to the Vault.
pub nft_id: NftId,
/// The number of FT types in the Vault.
pub assets_count: u64,
}
pub fn balance_of(&self, nft_contract_id: AccountId, nft_id: TokenId) -> Option<BalanceView> {..}
Function to view balances of all assets in the vault.
nft_contract_id
- account id of the NFT contract.
nft_id
- string with unique token Id.
pub fn vault_assets_count(
&self,
nft_contract_id: AccountId,
nft_id: TokenId,
) -> Option<VaultView> {..}
Function to view the amount of assets in the Vault.
nft_contract_id
- account id of the NFT contract.
nft_id
- string with unique token Id.
pub fn replenishers(
&self,
nft_contract_id: AccountId,
nft_id: TokenId,
) -> Option<Vec<Replenisher>> {..}
Function to view the replenishers of the vault.
nft_contract_id
- account id of the NFT contract.
nft_id
- string with unique token Id.