Fixed Price Sale
Technical Description
Creators to sell something have to:
- Create store - It's necessary because we have to filter Markets somehow 
- It will contain name, admin key, description 
 
- Initialise Selling resource. It can be either created one or our platform will create it. - Once user initialise selling resource we have an object with resource which we can sell
 
- Create a Market - Create object with info about items selling, all apart from max supply such as we defined it in Selling resource
 
Users to buy tokens have to:
- Go to store. 
- Choose token and click "Buy" - Under the hood next things will happen: - TradeHistory account will be created where we track how many tokens this user already bought 
- Debit and credit operations 
- New NFT created(create mint, mint token, create Metadata, create MasterEdition) 
 
 
- Token will be shown in their wallets 
Accounts
Store
| Field | Type | Description | 
|---|---|---|
| admin | Pubkey | Admin key who can create selling resources and markets in specific store | 
| name | String | |
| description | String | 
Selling resource
| Field | Type | Description | 
|---|---|---|
| store | Pubkey | |
| owner | Pubkey | Owner of resource. This account can receive back resource once sail is ended | 
| resource | Pubkey | Mint account Metadata attached to. We donât need store Metadata key because itâs PDA and we can calculate it knowing the mint key | 
| vault | Pubkey | Token account which holds MasterEdition | 
| vault_owner | Pubkey | PDA with seeds [âmt_vaultâ, resource.key(), store.key()] | 
| supply | u64 | Amount of tokens already sold | 
| max_supply | Option<u64> | Max amount of token can be sold | 
| state | Enum{Uninitialised, Created, InUse, Exhausted, Stoped,} | State of resource | 
Market
| Field | Type | Description | 
|---|---|---|
| store | Pubkey | |
| selling_resource | Pubkey | |
| treasury_mint | Pubkey | Mint account of tokens which market will accept as a payment | 
| treasury_holder | Pubkey | Token account buyers will send tokens to. Only market owner can withdraw assets | 
| treasury_owner | Pubkey | PDA[âholderâ, treasury_mint.key(), selling_resource.key()] | 
| owner | Pubkey | Market owner | 
| name | String | |
| description | String | |
| mutable | bool | |
| price | u64 | |
| pieces_in_one_wallet | Option<u64> | How many tokens we can sell to one wallet | 
| start_date | u64 | |
| end_date | Option<u64> | |
| state | Enum {Uninitialised, Created, Active, Ended,} | |
| funds_collected | u64 | 
TradeHistory
PDA [âhistoryâ, wallet.key(), market.key()]
| Field | Type | Description | 
|---|---|---|
| market | Pubkey | |
| wallet | Pubkey | |
| already_bought | u64 | How many tokens user already bought from specific Market | 
PrimaryMetadataCreators
PDA [âprimary_creatorsâ, metadata.key()]
| Field | Type | Description | 
|---|---|---|
| creators | Vec<mpl_token_metadata::state::Creator> | List of creators to receive primary sales royalties | 
Instructions
CreateStore
Creates new Store account.
| Parameter | Type | Description | 
|---|---|---|
| admin | Key, Signer, Writable | |
| store | Key, Signer, Writable | Uninitialized account | 
| name | String | |
| description | String | 
InitSellingResource
Initialize SellingResource account which will be used by Market.
| Parameter | Type | Description | 
|---|---|---|
| store | Key | |
| store_admin | Key, Signer, Writable | Holds resource_token and pays for selling_resource account creating | 
| selling_resource | Key, Signer, Writable | Uninitialized account | 
| selling_resource_owner | Key | Key which can withdraw MasterEdition once sale is ended | 
| resource_mint | Key | Mint account Metadata attached to | 
| master_edition | Key | PDA with seeds [âmetadataâ, tokenMetadataProgramID, resource_mint, âeditionâ] | 
| metadata | Key | Master editionâs metadata | 
| vault | Key, Writable | Token account to hold resource | 
| vault_owner | PDA [âmt_vaultâ, resource_mint.key(), store.key()] | Owner of vault token account | 
| resource_token | Key, Writable | Userâs token account which holds token from resource_mint | 
| max_supply | Option<u64> | Max amount of tokens to sell | 
CreateMarket
Initialize Market account. Set state to Created, it means that owner can change some data before it will be activated, off course if Market marked as mutable.
:::warning
If user want sell art for native SOL as treasury_mint should be set 11111111111111111111111111111111 also treasury_holder and treasury_owner should be the same accounts PDA. Itâs necessary for security reasons so only program will be able to spend that SOL.
:::
| Parameter | Type | Description | 
|---|---|---|
| market | Key, Signer, Writable | Uninitialized account | 
| store | Key | |
| selling_resource_owner | Key, Signer, Writable | |
| selling_resource | Key, Writable | |
| treasury_mint | Key | Mint of assets which we will take as a payment | 
| treasury_holder | Key | Token account | 
| treasury_owner | PDA [âholderâ, treasury_mint.key(), selling_resource.key()] | |
| name | String | |
| description | String | |
| mutable | bool | |
| price | u64 | |
| pieces_in_one_wallet | Option<u64> | |
| start_date | u64 | |
| end_date | Option<u64> | |
| gating_config | Option<GatingConfig{collection: Pubkey, expire_on_use: bool, gating_time: Option<u64>}> | Gating token. If this value set only users with NFT from pointed collection can buy new NFTs from market. | 
ChangeMarket
Available only if Market::mutable == true. Can change: name, description, mutable, price, pieces_in_one_wallet.
| Parameter | Type | Description | 
|---|---|---|
| market | Key, Writable | |
| market_owner | Key, Signer | |
| new_name | Option<String> | |
| new_description | Option<String> | |
| mutable | Option<bool> | |
| new_price | Option<u64> | |
| new_pieces_in_one_wallet | Option<u64> | 
Buy
User can call only if current date > Market::start_date.
:::warning
If user buy art for native SOL user_token_acc and user_wallet accounts should be the same.
:::
| Parameter | Type | Description | 
|---|---|---|
| market | Key, Writable | |
| selling_resource | Key, Writable | |
| user_token_acc | Key, Writable | Token account to pay for the member token. Mint of this token acc should be == treasury_mint | 
| user_wallet | Key, Signer, Writable | |
| trade_history | Key, Writable | Account to track how many NFTs user already bought | 
| treasury_holder | Key, Writable | |
| new_metadata_acc | Key, Writable | |
| new_edition_acc | Key, Writable | |
| master_edition_acc | Key, Writable | |
| new_mint | Key, Writable | |
| edition_marker | Key, Writable | PDA, seeds can be found in token-metadata program | 
| vault | Key | |
| vault_owner | PDA [âmt_vaultâ, resource.key(), store.key()] | |
| master_edition_metadata | Key | |
| Below accounts are optional and should be passed only if gating feature is enabled â | ||
| user_collection_token_account | Key, Writable | Userâs token account from collection | 
| token_account_mint | Key, Writable | Tokenâs mint account | 
| metadata_account | Key | Metadata account for the mint mentioned above | 
SuspendMarket
Suspend Market so nobody can buy items and market owner can change data. Instruction should be available only if Market::mutable == true because in other case there is no reason to suspend it.
| Parameter | Type | Description | 
|---|---|---|
| market | Key, Writable | |
| market_owner | Key, Signer | |
| clock | Key | 
ResumeMarket
Instruction to resume the market after it was suspended. Can be called only if market is in suspended state.
| Parameter | Type | Description | 
|---|---|---|
| market | Key, Writable | |
| market_owner | Key, Signer | |
| clock | Key | 
CloseMarket
This instruction can be called only if Market was created with unlimited duration.
| Parameter | Type | Description | 
|---|---|---|
| market | Key, Writable | |
| market_owner | Key, Signer | |
| clock | Key | 
Withdraw
Called by Market owner to withdraw collected treasury funds. Available only if Market::state == Ended.
| Parameter | Type | Description | 
|---|---|---|
| market | Key | |
| selling_resource | Key | |
| metadata | Key | |
| treasury_holder | Key, Writable | Market::treasury_holder. Token account which holds all the tokens received from users during selling | 
| treasury_mint | Key | |
| funder | Key | |
| payer | Key, Signer | |
| payout_ticket | Key, Writable | PDA[âpayout_ticketâ, market.key(), funder.key()] | 
| treasury_owner | Key | PDA[âholderâ, treasury_mint.key(), selling_resource.key()] | 
| destination | Key, Writable | Token account transfer tokens to | 
| Below account is optional and should be passed only during primary sale â | ||
| primary_metadata_creators_data | Key | List of creators who should receive royalties from primary sale | 
ClaimResource
Called by Resource owner. Available only if SellingResource::state == Exhausted of Market::state == Ended.
| Parameter | Type | Description | 
|---|---|---|
| market | Key | |
| treasury_holder | Key | |
| selling_resource | Key | |
| selling_resource_owner | Key, Signer | |
| source | Key, Writable | SellingResource::vault. Token account which holds master edition | 
| metadata | Key | Metadata for token which was sold | 
| vault_owner | Key | PDA with seeds [âmt_vaultâ, resource.key(), store.key()] | 
| secondary_metadata_creators | Key | |
| destination | Key, Writable | Token account transfer master edition to | 
SavePrimaryMetadataCreators
Called before market is created. This list of creators will be used in withdraw instruction to distribute royalties. Take a note that if you are going to sell NFTs from master edition with primary_sale_happen = true you don't need to call this instruction.
| Parameter | Type | Description | 
|---|---|---|
| admin | Key, Signer, Writable | Metadataâs update authority | 
| metadata | Key, Writable | |
| primary_metadata_creators | Key, Writable | PDA with seeds [âprimary_creatorsâ, metadata.key()] | 
| system_program | Key | |
| primary_metadata_creators | u8 | primary_metadata_creators key bump | 
| creators | Vec<mpl_token_metadata::state::Creator> | List of creators who will receive primary royalties |