They are all fairly straightforward, since everything is human-readable and all the functions and methods are returned by simply sending an "invalid" payload in a query.
The REST API method is simple:
/cosmwasm/wasm/v1/contract/${contractAddress}/smart/${payLoad_base64}
Here is a pretty basic script for exploring these queries, [or you can just use https://seiscan.app
]
[click to expand]
#!/bin/bash
# accepts 3 args: REST URL, contract address, payload [json string]
# remembers last-entered values for first 2 args
# payload "test" set as alias for '{"a":"b"}' to return valid query methods
# File to store the last used values
config_file="last_run.conf"
# Load previous values if the file exists
if [ -f "$config_file" ]; then
source $config_file
fi
# Function to get user input with default
function get_input() {
local input
local default_value=$2
read -p "$1 [$default_value]: " input
echo "${input:-$default_value}"
}
# Prompt for restAddress
restAddress=$(get_input "Enter the REST API address" "$restAddress")
# Prompt for contractAddress
contractAddress=$(get_input "Enter the contract address" "$contractAddress")
# Prompt for payload and check if input is 'test'
payLoad=$(get_input "Enter the payload (or 'test' for default)" "$payLoad")
if [ "$payLoad" == "test" ]; then
payLoad='{"a":"b"}'
fi
# Prompt for block height (optional)
blockHeight=$(get_input "Enter the block height (optional)" "") # Default is empty
# Encode payload to base64
payLoad_base64=$(echo "$payLoad" | base64 -w 0) # -w 0 to disable line wrapping
# Save the latest inputs, excluding blockHeight
echo "restAddress='$restAddress'" > $config_file
echo "contractAddress='$contractAddress'" >> $config_file
echo "payLoad='$payLoad'" >> $config_file
# Build the URL
url="${restAddress}/cosmwasm/wasm/v1/contract/${contractAddress}/smart/${payLoad_base64}"
# Add header if block height is provided
if [ -n "$blockHeight" ]; then
response=$(curl -s --write-out "\n%{http_code}" --url "$url" -H "x-cosmos-block-height: $blockHeight")
else
response=$(curl -s --write-out "\n%{http_code}" --url "$url")
fi
# Separate the status code from the response body
http_code=$(echo "$response" | tail -n1) # Last line of output is the HTTP status code
response_body=$(echo "$response" | head -n -1) # Remove the last line (status code)
# Check if the response is successful or expected (200 or 400)
if [ "$http_code" -eq 200 ] || [ "$http_code" -eq 400 ]; then
# Print pretty JSON
echo "$response_body" | jq .
else
echo "Error: HTTP status $http_code"
echo "$response_body"
fi
The script will save your most recently used selections in a temporary file so you don't have to enter them again for repeated queries.
Everything is in interactive promptss.
Give it a REST address, followed by the contract address, then a query method (or just test
to send the "invalid" payload and discover the available methods as reported by the contract itself)
Finally (optional) a block height. Leaving this one null
will just default to "latest" height.
Query the collection itself to see ownership
payload:
{
"ownership": {}
}
response:
{
"data": {
"owner": "sei1hjsqrfdg2hvwl3gacg4fkznurf36usrv7rkzkyh29wz3guuzeh0snslz7d",
"pending_owner": null,
"pending_expiry": null
}
}
Check into this contract
payload:
{"a":"b"}
response:
{
"code": 3,
"message": "Error parsing into type lighthouse::msg::QueryMsg: unknown variant `a`, expected one of `get_config`, `get_collection`, `balance_of`, `get_collections`, `get_minter_of`, `is_collection_renounced`: query wasm contract failed: invalid request",
"details": []
}
From this we can tell this is the "lighthouse" contract which is a marketplace or launchpad of some kind
Now we query this using one of the above methods
payload:
{
"get_collection": {
"collection": "sei1lsde7r5mgjaxw7gtae7tadmpprz05qg3rkpalrwxy3kuvesf0k5q5wqepf"
}
}
and just out of sheer luck, this one happens to contain the royalties info:
[click to expand]
{
"data": {
"admin": "sei19c7a9uccaw9y0q6jz90nk69e8jt3kdq4rtw8c0",
"cw721_address": "sei1lsde7r5mgjaxw7gtae7tadmpprz05qg3rkpalrwxy3kuvesf0k5q5wqepf",
"name": "SEITAN",
"symbol": "SEITAN",
"supply": 6666,
"token_uri": "https://arweave.net/7Ftj2FmIzzTtJBY55hSPxAr6zui5FAkuFFpz1HYPBu0",
"royalty_percent": 9,
"royalty_wallet": "sei1sqfnzezu55ectwwunt6nmjcelkyk0qru9wmhgh",
"next_token_id": 6666,
"mint_groups": [
{
"name": "team",
"merkle_root": [
3,
246,
111,
97,
101,
144,
222,
165,
174,
77,
12,
252,
47,
200,
167,
82,
197,
216,
174,
75,
169,
135,
148,
13,
105,
181,
89,
243,
133,
87,
105,
148
],
"max_tokens": 0,
"unit_price": "0",
"creators": [
{
"address": "sei1sqfnzezu55ectwwunt6nmjcelkyk0qru9wmhgh",
"share": 100
}
],
"start_time": 1674500400,
"end_time": 1737659700
},
{
"name": "OG",
"merkle_root": [
206,
195,
66,
6,
168,
143,
26,
222,
59,
185,
209,
39,
211,
206,
204,
58,
84,
27,
24,
236,
113,
12,
255,
51,
75,
220,
250,
157,
74,
77,
130,
148
],
"max_tokens": 2,
"unit_price": "0",
"creators": [
{
"address": "sei1sqfnzezu55ectwwunt6nmjcelkyk0qru9wmhgh",
"share": 100
}
],
"start_time": 1706037300,
"end_time": 1706038200
},
{
"name": "Whitelist",
"merkle_root": [
31,
1,
242,
183,
77,
216,
92,
133,
175,
79,
219,
180,
18,
161,
63,
173,
225,
213,
253,
179,
7,
179,
216,
143,
158,
161,
94,
144,
246,
180,
53,
71
],
"max_tokens": 1,
"unit_price": "0",
"creators": [
{
"address": "sei1sqfnzezu55ectwwunt6nmjcelkyk0qru9wmhgh",
"share": 100
}
],
"start_time": 1706038200,
"end_time": 1706040000
},
{
"name": "Public",
"merkle_root": null,
"max_tokens": 5,
"unit_price": "16660000",
"creators": [
{
"address": "sei1v9dlnmfhzfvk2wyj38f0e3w6557xhv7js7q736",
"share": 8
},
{
"address": "sei1sqfnzezu55ectwwunt6nmjcelkyk0qru9wmhgh",
"share": 92
}
],
"start_time": 1737662400,
"end_time": 0
}
],
"iterated_uri": false,
"start_order": null,
"frozen": false,
"hidden_metadata": false,
"placeholder_token_uri": null
}
}