Andromeda
Search
⌃K

Marketplace App

Deploying a marketplace App with modules using the Andromeda CLI.
If unfimailar with the steps of deploying an app, go back to the first example where we explain in detail all the different parts of deploying an App.
If any of the messages in this example do not work, you might want to cross reference the messages with the ADO specific section which always contains the latest ADO versions to make sure they are correct. Other than that the logic will remain the same.
The examples use uni-5 testnet. As of now, Juno has upgraded to uni-6. The steps of building the App remain the same.

Defining our App

For this App, we will be selling NFTs using the Marketplace ADO. We will also be showcasing two of our modules by adding rates and an address list to the marketplace. The steps that will be performed:
  • Mint NFTs
  • Setup the marketplace with modules attached
  • Send the NFTs to the markeplace to be sold
  • Check that all the results are as expected

Defining the Messages

The components/ADOs we would need:
Although not necessary, if you are unfamiliar with these ADOs, it is suggested to read through each of the them before deploying an app.
Let us first start by representing the instantiation message for each of our ADOs:
Keep in mind that the app takes these messages as base64 encoded.

cw721

{
"name":"Marketpalce NFTs",
"symbol":"MRK",
"minter":{
"identifier":"juno1zkpthqsz3ud97fm6p4kxcra8ae99jgzauugyem"
}
}
Make sure to set the minter as your own address.
As base64:
eyJuYW1lIjoiTWFya2V0cGFsY2UgTkZUcyIsInN5bWJvbCI6Ik1SSyIsIm1pbnRlciI6eyJpZGVudGlmaWVyIjoianVubzF6a3B0aHFzejN1ZDk3Zm02cDRreGNyYThhZTk5amd6YXV1Z3llbSJ9fQ==

Rates

We will add a 10% royalties to the NFTs that will be receive by another address.
We set is_additive to false to indicate that the rate is a royalty.
{
"rates":[
{
"rate":{
"percent":{
"percent":"0.1"
}
},
"is_additive":false,
"recipients":[{"addr":"juno13ad8pm66dfwjujfgwutrpazdcw8c33x9jj3lwk"}]
}
]
}
As base64:
eyJyYXRlcyI6W3sicmF0ZSI6eyJwZXJjZW50Ijp7InBlcmNlbnQiOiIwLjEifX0sImlzX2FkZGl0aXZlIjpmYWxzZSwicmVjaXBpZW50cyI6W3siYWRkciI6Imp1bm8xM2FkOHBtNjZkZndqdWpmZ3d1dHJwYXpkY3c4YzMzeDlqajNsd2sifV19XX0=

Address List

The address list can be used to either whitelist or blacklist addresses from interacting with the marketplace ADO. I will blacklist one address for this example:
{
"is_inclusive": false
}
As base64:
eyJpc19pbmNsdXNpdmUiOiBmYWxzZX0=

Marketplace

We will attach the two modules to the marketplace ADO.
{
"modules":[
{
"module_type":"address-list",
"address":{
"identifier":"whitelist"
},
"is_mutable": false
},
{
"module_type":"rates",
"address":{
"identifier":"royalties"
},
"is_mutable":false
}
]
}
As base64:
eyJtb2R1bGVzIjpbeyJtb2R1bGVfdHlwZSI6ImFkZHJlc3MtbGlzdCIsImFkZHJlc3MiOnsiaWRlbnRpZmllciI6IndoaXRlbGlzdCJ9LCJpc19tdXRhYmxlIjogZmFsc2V9LHsibW9kdWxlX3R5cGUiOiJyYXRlcyIsImFkZHJlc3MiOnsiaWRlbnRpZmllciI6InJveWFsdGllcyJ9LCJpc19tdXRhYmxlIjpmYWxzZX1dfQ==

App

The primitive address used here might be outdated in the future. Check our deployed contracts to get the latest registry.
{
"name": "Marketplace App",
"app": [
{
"name": "NFTs",
"ado_type": "cw721",
"instantiate_msg": "eyJuYW1lIjoiTWFya2V0cGFsY2UgTkZUcyIsInN5bWJvbCI6Ik1SSyIsIm1pbnRlciI6eyJpZGVudGlmaWVyIjoianVubzF6a3B0aHFzejN1ZDk3Zm02cDRreGNyYThhZTk5amd6YXV1Z3llbSJ9fQ=="
},
{
"name": "royalties",
"ado_type": "rates",
"instantiate_msg": "eyJyYXRlcyI6W3sicmF0ZSI6eyJwZXJjZW50Ijp7InBlcmNlbnQiOiIwLjEifX0sImlzX2FkZGl0aXZlIjpmYWxzZSwicmVjaXBpZW50cyI6W3siYWRkciI6Imp1bm8xM2FkOHBtNjZkZndqdWpmZ3d1dHJwYXpkY3c4YzMzeDlqajNsd2sifV19XX0="
},
{
"name": "whitelist",
"ado_type": "address-list",
"instantiate_msg": "eyJpc19pbmNsdXNpdmUiOiBmYWxzZX0="
},
{
"name": "marketplace",
"ado_type": "marketplace",
"instantiate_msg": "eyJtb2R1bGVzIjpbeyJtb2R1bGVfdHlwZSI6ImFkZHJlc3MtbGlzdCIsImFkZHJlc3MiOnsiaWRlbnRpZmllciI6IndoaXRlbGlzdCJ9LCJpc19tdXRhYmxlIjogZmFsc2V9LHsibW9kdWxlX3R5cGUiOiJyYXRlcyIsImFkZHJlc3MiOnsiaWRlbnRpZmllciI6InJveWFsdGllcyJ9LCJpc19tdXRhYmxlIjpmYWxzZX1dfQ=="
}
],
"primitive_contract": "juno133fdsnvcah870exzcyxknydswyh778jfhwxzlhhgjuagh4482zpqp856dz"
}
There are several components found here. A simple name for the app, the components of the app itself and a reference to the “registry”. Each component of the app provides two values: a name used for referencing for other components within the app, and the base64 encoded instantiation message.

Instantiating the App

If you do not have the CLI downloaded, go to the Introduction to Apps section to get the latest version.
First, let us open the CLI by running andr in our terminal. We then need to choose the chain we want to deploy on. Run "chain use" in the CLI and select the testnet that you want to deploy on. For this example I will be using the juno testnet uni-5.
If this is the first time using the CLI make sure to run "wallets add <wallet-name>"in order to create a wallet. Then go to that chain's faucet (usually located in their discord) and request tokens.
We have already uploaded the App ADO to the uni-5 testnet. The code I will use is 98. This code Id will most likely be outdated in the future. A simple way to check the latest code id for the App ADO is to query it from the ADODB using the the chain you want to use.
In the CLI, while connected to the chain of choice, run:
ado db getcodeid app
The code Id to use will be returned.
Now we can instantiate our App. We will be using our wasm command to instantiate our app:
wasm instantiate 98 '{"name": "Marketplace App","app": [{"name": "NFTs","ado_type": "cw721","instantiate_msg": "eyJuYW1lIjoiTWFya2V0cGFsY2UgTkZUcyIsInN5bWJvbCI6Ik1SSyIsIm1pbnRlciI6eyJpZGVudGlmaWVyIjoianVubzF6a3B0aHFzejN1ZDk3Zm02cDRreGNyYThhZTk5amd6YXV1Z3llbSJ9fQ=="},{"name": "royalties","ado_type": "rates","instantiate_msg": "eyJyYXRlcyI6W3sicmF0ZSI6eyJwZXJjZW50Ijp7InBlcmNlbnQiOiIwLjEifX0sImlzX2FkZGl0aXZlIjpmYWxzZSwicmVjaXBpZW50cyI6W3siYWRkciI6Imp1bm8xM2FkOHBtNjZkZndqdWpmZ3d1dHJwYXpkY3c4YzMzeDlqajNsd2sifV19XX0="},{"name": "whitelist","ado_type": "address-list","instantiate_msg": "eyJpc19pbmNsdXNpdmUiOiBmYWxzZX0="},{"name": "marketplace","ado_type": "marketplace","instantiate_msg": "eyJtb2R1bGVzIjpbeyJtb2R1bGVfdHlwZSI6ImFkZHJlc3MtbGlzdCIsImFkZHJlc3MiOnsiaWRlbnRpZmllciI6IndoaXRlbGlzdCJ9LCJpc19tdXRhYmxlIjogZmFsc2V9LHsibW9kdWxlX3R5cGUiOiJyYXRlcyIsImFkZHJlc3MiOnsiaWRlbnRpZmllciI6InJveWFsdGllcyJ9LCJpc19tdXRhYmxlIjpmYWxzZX1dfQ=="}],"primitive_contract": "juno133fdsnvcah870exzcyxknydswyh778jfhwxzlhhgjuagh4482zpqp856dz"}'
You will be using the contract addresses that were instantiated for you instead of the ones in this tutorial.

Interacting with the App

Andromeda contracts assign the original instantiator as contract owners. Due to how instantiation via a submessage operates in CosmWasm contracts, we must claim ownership of the components in order to execute messages that have authorization restrictions (owner restricted).
We could also use proxy messages to run our executes through the app.

Claim Components

{
"claim_ownership":{}
}
wasm execute juno1lmahxmszth6nzy9jd0l8t77ddk74awk94zrmj6e7z5ayeqzxjgnqsl4x89 '{"claim_ownership":{}}'

Add Address to the address-list

We have instantiated the address list but have yet to add an address to blacklist. Let us do it before interacting with the marketplace.
{
"add_address":{
"address": "juno13ad8pm66dfwjujfgwutrpazdcw8c33x9jj3lwk"
}
}
wasm execute juno1f2yzuc6agmkk8y0m3t05evsx475rf3tfk2xmqy8zs0xfzmvpy7kqggksl0 '{"add_address": {"address": "juno13ad8pm66dfwjujfgwutrpazdcw8c33x9jj3lwk"}}'

Mint NFTs

Now we need to mint an NFT to send to the marketplace.
{
"mint": {
"token_id": "1",
"owner": "juno1zkpthqsz3ud97fm6p4kxcra8ae99jgzauugyem",
"extension": {
"name": "Some token",
"publisher": "juno1zkpthqsz3ud97fm6p4kxcra8ae99jgzauugyem",
"description": "A token to place in auction",
"attributes": [],
"image":"https://pic.onlinewebfonts.com/svg/img_522399.png"
}
}
}
wasm execute juno1vknej637gavm2xdaffsfge4kvfsmcjf7ae7y9l8p3tdqk30uld5qdq9a8f '{"mint": {"token_id": "1","owner": "juno1zkpthqsz3ud97fm6p4kxcra8ae99jgzauugyem","extension": {"name": "Marketplace Token","publisher": "juno1zkpthqsz3ud97fm6p4kxcra8ae99jgzauugyem","description": "A token to sell in marketplace","attributes": [],"image":"https://pic.onlinewebfonts.com/svg/img_522399.png"}}}'
Mint NFT

Send NFT to Marketplace to be Sold

In order to start a sale on the NFT, we need to send it to the marketplace ADO.
{
"send_nft": {
"contract": "juno175hu3dxvdy40snmpwhlkzaklp5m60qj4gmghhrhs7st5pjw7ca4s2x6kz6",
"token_id": "1",
"msg": "eyJzdGFydF9zYWxlIjp7InByaWNlIjogIjEwMDAwIiwiY29pbl9kZW5vbSI6InVqdW5veCJ9fQ=="
}
}
The attached message is a start_sale message to start the auction when the NFT is sent.
{
"start_sale":{
"price": "10000",
"coin_denom":"ujunox"
}
}
wasm execute juno1vknej637gavm2xdaffsfge4kvfsmcjf7ae7y9l8p3tdqk30uld5qdq9a8f '{"send_nft": {"contract": "juno175hu3dxvdy40snmpwhlkzaklp5m60qj4gmghhrhs7st5pjw7ca4s2x6kz6","token_id": "1","msg": "eyJzdGFydF9zYWxlIjp7InByaWNlIjogIjEwMDAwIiwiY29pbl9kZW5vbSI6InVqdW5veCJ9fQ=="}}'

Buy the NFT

Now let us buy the NFT. First, I will try to buy it using the blacklisted address to make sure that our address-list module is working as intended. On the CLI:
test is my wallet name for the blacklisted address.
wallets use test
{
"buy":{
"token_id":"1",
"token_address":"juno1vknej637gavm2xdaffsfge4kvfsmcjf7ae7y9l8p3tdqk30uld5qdq9a8f"
}
}
Make sure to attach funds to the message.
wasm execute juno175hu3dxvdy40snmpwhlkzaklp5m60qj4gmghhrhs7st5pjw7ca4s2x6kz6 '{"buy":{"token_id":"1","token_address":"juno1vknej637gavm2xdaffsfge4kvfsmcjf7ae7y9l8p3tdqk30uld5qdq9a8f"}}' --funds 10000ujunox
Using the blacklisted address we get the following error:
Query failed with (18): failed to execute message; message index: 0: Generic error: Querier contract error: codespace: wasm, code: 9: execute wasm contract failed: invalid request
Use the --help flag for help
Now I will switch to another wallet and try buying the NFT again:
wallets use test2
You can see in the explorer that the funds were divided between two addresses. 90% of the funds went to the seller whereas the other 10% went to our royalty address.

Conclusion

We have seen in this example how we can sell NFTs using our marketplace ADO and how to use the Andromeda modules to extend the ADOs by adding an address list and royalties to the marketplace. This is just one of many use cases that are possible using our ADOs and modules.