Getting and sending transactions with Celestia Node's Gateway API
In this tutorial, we will cover how to use the Celestia Node Gateway API to submit and retrieve messages from the Data Availability Layer by their namespace ID.
This tutorial assumes you are working in a Linux environment.
To view a video tutorial for setting up a Celestia Light Node, click here.
Hardware requirements
The following minimum hardware requirements are recommended for running a light node:
- Memory: 2 GB RAM
- CPU: Single Core
- Disk: 25 GB SSD Storage
- Bandwidth: 56 Kbps for Download/56 Kbps for Upload
Setting up dependencies
First, make sure to update and upgrade the OS:
- APT
- YUM
sudo apt update && sudo apt upgrade -y
sudo yum update
These are essential packages that are necessary to execute many tasks like downloading files, compiling, and monitoring the node:
- APT
- YUM
- Mac (Apple)
- Mac (Intel)
sudo apt install curl tar wget clang pkg-config libssl-dev jq build-essential git make ncdu -y
sudo yum install curl tar wget clang pkg-config libssl-dev jq build-essential git make ncdu -y
🍺 Installing Homebrew
Homebrew is a package manager for macOS and Linux and will allow you to install your dependencies.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Be sure to run the commands in the output that are similar to:
==> Next steps:
- Run these three commands in your terminal to add Homebrew to your PATH:
echo '# Set PATH, MANPATH, etc., for Homebrew.' >> /Users/joshstein/.zprofile
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/joshstein/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
🗄 Install wget and jq
Using Homebrew, in your terminal:
brew install wget && brew install jq
wget is an internet file retriever and jq is a lightweight command-line JSON processor.
🍺 Installing Homebrew
Homebrew is a package manager for macOS and Linux and will allow you to install your dependencies.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
Be sure to run the commands in the output that are similar to:
==> Next steps:
- Run these three commands in your terminal to add Homebrew to your PATH:
echo '# Set PATH, MANPATH, etc., for Homebrew.' >> /Users/joshstein/.zprofile
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> /Users/joshstein/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv)"
🗄 Install wget and jq
Using Homebrew, in your terminal:
brew install wget && brew install jq
wget is an internet file retriever and jq is a lightweight command-line JSON processor.
Install Golang
celestia-app
and celestia-node
are written in Golang
so we must install Golang to build and run them.
- Blockspace Race
- Mocha
- Arabica 🏗️
- Ubuntu (AMD)
- Ubuntu (ARM)
- Mac (Apple)
- Mac (Intel)
ver="1.20.2"
cd $HOME
wget "https://golang.org/dl/go$ver.linux-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.linux-amd64.tar.gz"
rm "go$ver.linux-amd64.tar.gz"
ver="1.20.2"
cd $HOME
wget "https://golang.org/dl/go$ver.linux-arm64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.linux-arm64.tar.gz"
rm "go$ver.linux-arm64.tar.gz"
ver="1.20.2"
cd $HOME
wget "https://golang.org/dl/go$ver.darwin-arm64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.darwin-arm64.tar.gz"
rm "go$ver.darwin-arm64.tar.gz"
ver="1.20.2"
cd $HOME
wget "https://golang.org/dl/go$ver.darwin-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.darwin-amd64.tar.gz"
rm "go$ver.darwin-amd64.tar.gz"
Now we need to add the /usr/local/go/bin
directory to $PATH
:
- bash
- zsh
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.bash_profile
source $HOME/.bash_profile
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.zshrc
source $HOME/.zshrc
To check if Go was installed correctly run:
go version
The output should be the version installed:
- Ubuntu (AMD)
- Ubuntu (ARM)
- Mac (Apple)
- Mac (Intel)
go version go1.20.2 linux/amd64
go version go1.20.2 linux/arm64
go version go1.20.2 darwin/arm64
go version go1.20.2 darwin/amd64
- Ubuntu (AMD)
- Ubuntu (ARM)
- Mac (Apple)
- Mac (Intel)
ver="1.19.1"
cd $HOME
wget "https://golang.org/dl/go$ver.linux-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.linux-amd64.tar.gz"
rm "go$ver.linux-amd64.tar.gz"
ver="1.19.1"
cd $HOME
wget "https://golang.org/dl/go$ver.linux-arm64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.linux-arm64.tar.gz"
rm "go$ver.linux-arm64.tar.gz"
ver="1.19.1"
cd $HOME
wget "https://golang.org/dl/go$ver.darwin-arm64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.darwin-arm64.tar.gz"
rm "go$ver.darwin-arm64.tar.gz"
ver="1.19.1"
cd $HOME
wget "https://golang.org/dl/go$ver.darwin-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.darwin-amd64.tar.gz"
rm "go$ver.darwin-amd64.tar.gz"
Now we need to add the /usr/local/go/bin
directory to $PATH
:
- bash
- zsh
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.bash_profile
source $HOME/.bash_profile
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.zshrc
source $HOME/.zshrc
To check if Go was installed correctly run:
go version
The output should be the version installed:
- Ubuntu (AMD)
- Ubuntu (ARM)
- Mac (Apple)
- Mac (Intel)
go version go1.19.1 linux/amd64
go version go1.19.1 linux/arm64
go version go1.19.1 darwin/arm64
go version go1.19.1 darwin/amd64
- Ubuntu (AMD)
- Ubuntu (ARM)
- Mac (Apple)
- Mac (Intel)
ver="1.20.2"
cd $HOME
wget "https://golang.org/dl/go$ver.linux-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.linux-amd64.tar.gz"
rm "go$ver.linux-amd64.tar.gz"
ver="1.20.2"
cd $HOME
wget "https://golang.org/dl/go$ver.linux-arm64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.linux-arm64.tar.gz"
rm "go$ver.linux-arm64.tar.gz"
ver="1.20.2"
cd $HOME
wget "https://golang.org/dl/go$ver.darwin-arm64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.darwin-arm64.tar.gz"
rm "go$ver.darwin-arm64.tar.gz"
ver="1.20.2"
cd $HOME
wget "https://golang.org/dl/go$ver.darwin-amd64.tar.gz"
sudo rm -rf /usr/local/go
sudo tar -C /usr/local -xzf "go$ver.darwin-amd64.tar.gz"
rm "go$ver.darwin-amd64.tar.gz"
Now we need to add the /usr/local/go/bin
directory to $PATH
:
- bash
- zsh
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.bash_profile
source $HOME/.bash_profile
echo "export PATH=$PATH:/usr/local/go/bin:$HOME/go/bin" >> $HOME/.zshrc
source $HOME/.zshrc
To check if Go was installed correctly run:
go version
The output should be the version installed:
- Ubuntu (AMD)
- Ubuntu (ARM)
- Mac (Apple)
- Mac (Intel)
go version go1.20.2 linux/amd64
go version go1.20.2 linux/arm64
go version go1.20.2 darwin/arm64
go version go1.20.2 darwin/amd64
Celestia node
Install Celestia Node
- Blockspace Race
- Mocha
- Arabica 🏗️
- Ubuntu (AMD)
- Ubuntu (ARM)
- Mac (Apple)
- Mac (Intel)
Installing celestia-node
for the Blockspace Race testnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.10.2
make build
make install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.10.2
Commit: 960b522ec4ed2fb2069a220e2cef2da609158f4d
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: amd64/linux
Golang version: go1.20.2
Installing celestia-node
for the Blockspace Race testnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.10.2
make build
make install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.10.2
Commit: 960b522ec4ed2fb2069a220e2cef2da609158f4d
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: arm64/linux
Golang version: go1.20.2
Installing celestia-node
for the Blockspace Race testnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.10.2
make build
make go-install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.10.2
Commit: 960b522ec4ed2fb2069a220e2cef2da609158f4d
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: arm64/darwin
Golang version: go1.20.2
Installing celestia-node
for the Blockspace Race testnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.10.2
make build
make go-install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.10.2
Commit: 960b522ec4ed2fb2069a220e2cef2da609158f4d
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: amd64/darwin
Golang version: go1.20.2
- Ubuntu (AMD)
- Ubuntu (ARM)
- Mac (Apple)
- Mac (Intel)
Installing celestia-node
for Mocha Testnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.6.4
make build
make install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.6.4
Commit: 747c9e593542dfb32a933c731a9cd74b1fab897f
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: amd64/linux
Golang version: go1.19.1
Installing celestia-node
for Mocha Testnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.6.4
make build
make install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.6.4
Commit: 747c9e593542dfb32a933c731a9cd74b1fab897f
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: arm64/linux
Golang version: go1.19.1
Installing celestia-node
for Mocha Testnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.6.4
make build
make go-install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.6.4
Commit: 747c9e593542dfb32a933c731a9cd74b1fab897f
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: arm64/darwin
Golang version: go1.19.1
Installing celestia-node
for Mocha Testnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.6.4
make build
make go-install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.6.4
Commit: 747c9e593542dfb32a933c731a9cd74b1fab897f
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: amd64/darwin
Golang version: go1.19.1
- Ubuntu (AMD)
- Ubuntu (ARM)
- Mac (Apple)
- Mac (Intel)
Installing celestia-node
for Arabica Devnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.11.0-rc1
make build
make install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.11.0-rc1
Commit: b62452af1e7dd1cc1b9a5ca1d96d1545154b4d04
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: amd64/linux
Golang version: go1.20.2
Installing celestia-node
for Arabica Devnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.11.0-rc1
make build
make install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.11.0-rc1
Commit: b62452af1e7dd1cc1b9a5ca1d96d1545154b4d04
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: arm64/linux
Golang version: go1.20.2
Installing celestia-node
for Arabica Devnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.11.0-rc1
make build
make go-install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.11.0-rc1
Commit: b62452af1e7dd1cc1b9a5ca1d96d1545154b4d04
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: arm64/darwin
Golang version: go1.20.2
Installing celestia-node
for Arabica Devnet means installing a specific version
to be compatible with the network.
Install the celestia-node
binary by running the following commands:
cd $HOME
rm -rf celestia-node
git clone https://github.com/celestiaorg/celestia-node.git
cd celestia-node/
git checkout tags/v0.11.0-rc1
make build
make go-install
make cel-key
Verify that the binary is working and check the version with the celestia
version
command:
$ celestia version
Semantic version: v0.11.0-rc1
Commit: b62452af1e7dd1cc1b9a5ca1d96d1545154b4d04
Build Date: Thu Dec 15 10:19:22 PM UTC 2022
System version: amd64/darwin
Golang version: go1.20.2
Instantiate a Celestia light node
Now, let's instantiate a Celestia Light node:
Note: RPC Endpoints are exposed in all
celestia-node
types such as Light, Bridge and Full Nodes.
- Blockspace Race
- Mocha
- Arabica 🏗️
celestia light init --p2p.network blockspacerace
celestia light init
celestia light init --p2p.network arabica
- Blockspace Race
- Mocha
- Arabica 🏗️
Connect to a public core endpoint
Let's now run the Celestia Light node with a GRPC connection to an example public core endpoint.
Note: You are also encouraged to find a community-run API endpoint and there are several in the Discord. This one is used for demonstration purposes. You can find a list of RPC endpoints here.
celestia light start --core.ip <ip-address> --gateway --gateway.addr <ip-address> --gateway.port <port> --p2p.network blockspacerace
The --core.ip
gRPC port defaults to 9090,
so if you do not specify it in the command
line, it will default to that port. You can
add the port after the IP address or use the
--core.grpc.port
flag to specify another
port if you prefer.
Please refer to the ports section for information on which ports are required to be open on your machine.
Connect to a public core endpoint
Let's now run the Celestia Light node with a GRPC connection to an example public core endpoint.
Note: You are also encouraged to find a community-run API endpoint and there are several in the Discord. This one is used for demonstration purposes. You can find a list of RPC endpoints here.
celestia light start --core.ip <ip-address> --gateway --gateway.addr <ip-address> --gateway.port <port> --p2p.network mocha
The --core.ip
gRPC port defaults to 9090,
so if you do not specify it in the command
line, it will default to that port. You can
add the port after the IP address or use the
--core.grpc.port
flag to specify another
port if you prefer.
Please refer to the ports section for information on which ports are required to be open on your machine.
Connect to a public core endpoint
Let's now run the Celestia Light node with a GRPC connection to an example public core endpoint.
Note: You are also encouraged to find a community-run API endpoint and there are several in the Discord. This one is used for demonstration purposes. You can find a list of RPC endpoints here.
celestia light start --core.ip <ip-address> --gateway --gateway.addr <ip-address> --gateway.port <port> --p2p.network arabica
The --core.ip
gRPC port defaults to 9090,
so if you do not specify it in the command
line, it will default to that port. You can
add the port after the IP address or use the
--core.grpc.port
flag to specify another
port if you prefer.
Please refer to the ports section for information on which ports are required to be open on your machine.
For example, your command along with an RPC endpoint might look like this:
- Blockspace Race
- Mocha
- Arabica 🏗️
celestia light start --core.ip <ip-address> --gateway --gateway.addr 127.0.0.1 --gateway.port 26659 --p2p.network blockspacerace
Please refer to the ports section for information on which ports are required to be open on your machine.
celestia light start --core.ip https://rpc-mocha.pops.one --gateway --gateway.addr 127.0.0.1 --gateway.port 26659 --p2p.network mocha
Please refer to the ports section for information on which ports are required to be open on your machine.
celestia light start --core.ip https://consensus-full-arabica-8.celestia-arabica.com/ --gateway --gateway.addr 127.0.0.1 --gateway.port 26659 --p2p.network arabica
Please refer to the ports section for information on which ports are required to be open on your machine.
Keys and wallets
You can create your key for your node by running the following command:
./cel-key add <key_name> --keyring-backend test --node.type light --p2p.network <network>
You can start your light node with the key created above by running the following command:
- Blockspace Race
- Mocha
- Arabica 🏗️
celestia light start --core.ip <ip-address> --keyring.accname <key_name> --gateway --gateway.addr <ip-address> --gateway.port <port> --p2p.network blockspacerace
Please refer to the ports section for information on which ports are required to be open on your machine.
celestia light start --core.ip <ip-address> --keyring.accname <key_name> --gateway --gateway.addr <ip-address> --gateway.port <port> --p2p.network mocha
Please refer to the ports section for information on which ports are required to be open on your machine.
celestia light start --core.ip <ip-address> --keyring.accname <key_name> --gateway --gateway.addr 127.0.0.1 --gateway.port 26659 --p2p.network arabica
Please refer to the ports section for information on which ports are required to be open on your machine.
Once you start the Light Node, a wallet key will be generated for you.
You will need to fund that address with Mocha Testnet or Arabica Devnet
tokens to pay for PayForData
transactions or PayForBlob transactions
, respectively.
You can find the address by running the following command in
the celestia-node
directory:
./cel-key list --node.type light --keyring-backend test --p2p.network <network>
If you would like to fund your wallet with testnet tokens, head over
to either the #mocha-faucet
or #arabica-faucet
channels on the
Celestia Discord.
You can request funds to your wallet address using the following command in Discord:
$request <Wallet-Address>
Where <Wallet-Address>
is the celestia1******
address generated
when you created the wallet.
With your wallet funded, you can move on to the next step.
Node API calls
Open up another terminal window in order to begin querying the API.
celestia-node
exposes its REST gateway on port 26659
by default.
This endpoint will soon be deprecated in favor of RPC equivalent. Learn more about the RPC here.
Balance
Now, let's query our node for the balance of its default account
(which is the account associated with the developer
key we generated earlier):
curl -X GET http://127.0.0.1:26659/balance
It will output the following:
{
"denom":"utia",
"amount":"999995000000000"
}
This shows you the balance in that wallet.
Get block header
Now, let's get the block header information.
Here we will get the header from Block 1:
curl -X GET http://127.0.0.1:26659/header/1
It will output something like this:
{
"header":{
"version":{
"block":11
},
"chain_id":"devnet-2",
"height":1,
"time":"2021-11-23T02:24:05.965728875Z",
"last_block_id":{
"hash":"",
"parts":{
"total":0,
"hash":""
}
},
"last_commit_hash":"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"data_hash":"7B578B351B1B0BBD70BB350019EBC964C44A140A37EF715B552A7F8F315ACD19",
"validators_hash":"7F4EA93A134DEDBDA6A1FDD30D05760DD98A2B5FBA95DB3EFFFE7FCE4B361855",
"next_validators_hash":"7F4EA93A134DEDBDA6A1FDD30D05760DD98A2B5FBA95DB3EFFFE7FCE4B361855",
"consensus_hash":"048091BC7DDC283F77BFBF91D73C44DA58C3DF8A9CBC867405D8B7F3DAADA22F",
"app_hash":"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"last_results_hash":"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"evidence_hash":"E3B0C44298FC1C149AFBF4C8996FB92427AE41E4649B934CA495991B7852B855",
"proposer_address":"04881EB0A0A4C1DB414C708249CEEC2FCF348F3E"
},
"commit":{
"height":1,
"round":1,
"block_id":{
"hash":"4632277C441CA6155C4374AC56048CF4CFE3CBB2476E07A548644435980D5E17",
"parts":{
"total":1,
"hash":"BE1B789969938DB061B7723BE45C8A7B4B27192339A8E0A4E216775B2CB58D97"
}
},
"signatures":[
{
"block_id_flag":2,
"validator_address":"03F1044A6DF782189C7061FF89146B3D33608F17",
"timestamp":"2021-11-23T11:53:56.123958759Z",
"signature":"q/XF7Nc2ThcQgWfqi6LYOUEqLcU+sgVPY1nB2CLWdjRo80WwI6xy6QaYx1B0lmcKAkWR0YMxbc7vJzKF70qwBA=="
},
{
"block_id_flag":2,
"validator_address":"04881EB0A0A4C1DB414C708249CEEC2FCF348F3E",
"timestamp":"2021-11-23T11:53:56.036027188Z",
"signature":"0bbxeviCvgLlyIF47JoY1CMN2e/MhHtFzhdgV0zCM+P3qeO/rkh+0TSxoRVUB1MDvMCoA8hyffCw3amxympMAA=="
},
{
"block_id_flag":2,
"validator_address":"31711F367349D1BD619BD0A39568A69614B8A048",
"timestamp":"2021-11-23T11:53:56.135943844Z",
"signature":"gT23rZ8+XcG5rQ9QS+uh+Wn5eAiJDVy8bh23Fb8hevnHsuO1er2892MXAohaLRF6TTWs/C6dItYph4B/k3b6DQ=="
},
{
"block_id_flag":2,
"validator_address":"5A253EC2A9AB20AFD48C7BED2AFCA53F5C80BCA6",
"timestamp":"2021-11-23T11:53:56.081698742Z",
"signature":"nMngIlJ7PPPtu0N20YwKhWt/H3/JrEKJC3rnS5KG/8J3IppTacuwjGDUqIuHpRlrD0MmWa1mlY+6+ulbytt2AA=="
},
{
"block_id_flag":2,
"validator_address":"79BEB39F4B396F9278DA03F1C97F9BE3B10B12D3",
"timestamp":"2021-11-23T11:53:56.037896319Z",
"signature":"wPAL/sK4YXSU7iRXl00GDLvi4IItVlkY2zRkxIUeV9VA3Tq8Tke6wGE0N6pXKmtMcKUMoyjm03RWHv4mrtj1BA=="
},
{
"block_id_flag":1,
"validator_address":"",
"timestamp":"0001-01-01T00:00:00Z",
"signature":null
},
{
"block_id_flag":1,
"validator_address":"",
"timestamp":"0001-01-01T00:00:00Z",
"signature":null
},
{
"block_id_flag":2,
"validator_address":"D345D62BBD18C301B843DF7C65F10E57AB17BD98",
"timestamp":"2021-11-23T11:53:56.123499237Z",
"signature":"puj5Epw3yPGjSsJk6aQI74S2prgL7+cuiEpCxXYzQxOi0kNIqh8UMZLYf+AVHDQNJXehSmrAK6+VsIt9NF0DDg=="
},
{
"block_id_flag":2,
"validator_address":"DEC2642E786A941511A401090D21621E7F08A36D",
"timestamp":"2021-11-23T11:53:56.123136439Z",
"signature":"J/lnFqARXj42Lfx5MGY0FO/wug+AyQRxTnQp1u1HyczvV+0hXXuk06Uosi61jQKgJG6JBJF2VidqA41/uKMEDw=="
}
]
},
"validator_set":{
"validators":[
{
"address":"03F1044A6DF782189C7061FF89146B3D33608F17",
"pub_key":"sMcFgSIzlD77eZYgV7H4akyxoHCPc2oIQW05qWEB6b4=",
"voting_power":5000,
"proposer_priority":-40000
},
{
"address":"04881EB0A0A4C1DB414C708249CEEC2FCF348F3E",
"pub_key":"WdqZ8hoyc1HxZCJfQrAGKm2fFJZFg7PngPNGkA1RWXc=",
"voting_power":5000,
"proposer_priority":5000
},
{
"address":"31711F367349D1BD619BD0A39568A69614B8A048",
"pub_key":"pvwSRksq3ekXIiYK7IzjQJ870BxLqEma8zRr9n9VnXI=",
"voting_power":5000,
"proposer_priority":5000
},
{
"address":"5A253EC2A9AB20AFD48C7BED2AFCA53F5C80BCA6",
"pub_key":"RnmnTlKoKxNoh2TpohBDP3cKlx4ATiPOCvQFk/6xpUU=",
"voting_power":5000,
"proposer_priority":5000
},
{
"address":"79BEB39F4B396F9278DA03F1C97F9BE3B10B12D3",
"pub_key":"oh/N+GOIennBOAa/gPNCso1mDlqaHQNn7Op/X8opbeY=",
"voting_power":5000,
"proposer_priority":5000
},
{
"address":"7F1105B7B219481810C49730AECB1A83036BCA3A",
"pub_key":"Ow/AHP/Q3guPGymUKpvhnwae+QoCOpGztpVnP179IG8=",
"voting_power":5000,
"proposer_priority":5000
},
{
"address":"87265CC17922E01497F40B701EC9F05373B83467",
"pub_key":"MNi0Z+uNF5X1Bxj988IDXVl0BKUcLs7LItoMnX6dbg4=",
"voting_power":5000,
"proposer_priority":5000
},
{
"address":"D345D62BBD18C301B843DF7C65F10E57AB17BD98",
"pub_key":"4g3hhdyU4IIgWW/4sR0nax8bsC/M/fDbt1N8s/QanF8=",
"voting_power":5000,
"proposer_priority":5000
},
{
"address":"DEC2642E786A941511A401090D21621E7F08A36D",
"pub_key":"b+Vv6Lcp0bhIjOQncr+OYBHixCvU5+k34y4RqyvpluE=",
"voting_power":5000,
"proposer_priority":5000
}
],
"proposer":{
"address":"03F1044A6DF782189C7061FF89146B3D33608F17",
"pub_key":"sMcFgSIzlD77eZYgV7H4akyxoHCPc2oIQW05qWEB6b4=",
"voting_power":5000,
"proposer_priority":-40000
}
},
"dah":{
"row_roots":[
"//////////7//////////uyLCVMJmAItYqbOqgHXm3OwHsq1xQiAX1kZV2Tgcobm",
"/////////////////////ykyWNfDJZfigziZC5BN5L00KKuoyDPduwynDywauskL"
],
"column_roots":[
"//////////7//////////uyLCVMJmAItYqbOqgHXm3OwHsq1xQiAX1kZV2Tgcobm",
"/////////////////////ykyWNfDJZfigziZC5BN5L00KKuoyDPduwynDywauskL"
]
}
}
- Blockspace Race
- Mocha
- Arabica 🏗️
Submit a PFB transaction
In this example, we will be submitting a PayForBlob
transaction to the node's /submit_pfb
endpoint.
Some things to consider:
- PFB is a
PayForBlob
Message. - The endpoint also takes in a
namespace_id
anddata
values. - Namespace ID should be 8 bytes.
- Data is in hex-encoded bytes of the raw message.
gas_limit
is the limit of gas to use for the transaction
We use the following namespace_id
of 0000010000000100
and
the data
value of f1f20ca8007e910a3bf8b2e61da0f26bca07ef78717a6ea54165f5
.
You can generate your own namespace_id
and data values using this
useful Golang Playground we created here.
When running a Celestia node, you will need to use the following flags when starting your node to submit a PFB:
- the
--core.ip string
flag, to allow you to submit transactions to your node - the
--gateway
,--gateway.addr string
, and--gateway.port string
, to open the gateway and allow anyone to use your IP as an endpoint to submit PFBs
We run the following:
curl -X POST -d '{"namespace_id": "0c204d39600fddd3",
"data": "f1f20ca8007e910a3bf8b2e61da0f26bca07ef78717a6ea54165f5",
"gas_limit": 80000, "fee": 2000}' http://localhost:26659/submit_pfb
We get the following output:
{
"height": 4249,
"txhash": "B31DEA16E1F3EE13895D4A70FE808801E8BCF8381AACD5071CB51E929F17AB65",
"codespace": "undefined",
"code": 111222,
"raw_log": "recovered: UnmarshalJSON cannot decode empty bytes\nstack:\ngoroutine 61 [running]:\nruntime/debug.Stack()\n\t/usr/local/go/src/runtime/debug/stack.go:24 +0x65\ngithub.com/cosmos/cosmos-sdk/baseapp.newDefaultRecoveryMiddleware.func1({0x1f63960, 0xc00653eef0})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/recovery.go:71 +0x27\ngithub.com/cosmos/cosmos-sdk/baseapp.newRecoveryMiddleware.func1({0x1f63960?, 0xc00653eef0?})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/recovery.go:39 +0x30\ngithub.com/cosmos/cosmos-sdk/baseapp.processRecovery({0x1f63960, 0xc00653eef0}, 0xc0091f4580?)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/recovery.go:28 +0x37\ngithub.com/cosmos/cosmos-sdk/baseapp.processRecovery({0x1f63960, 0xc00653eef0}, 0x2d32158?)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/recovery.go:33 +0x5e\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).runTx.func1()\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/baseapp.go:639 +0xf0\npanic({0x1f63960, 0xc00653eef0})\n\t/usr/local/go/src/runtime/panic.go:838 +0x207\ngithub.com/cosmos/cosmos-sdk/x/params/types.Subspace.Get({{0x2d31748, 0xc001099090}, 0xc0004ee198, {0x2d0e170, 0xc001099730}, {0x2d0e1c0, 0xc001099c10}, {0xc00168aba0, 0x4, 0x12}, ...}, ...)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/x/params/types/subspace.go:110 +0x307\ngithub.com/celestiaorg/celestia-app/x/blob/keeper.Keeper.GasPerBlobByte(...)\n\t/celestia-app/x/blob/keeper/params.go:36\ngithub.com/celestiaorg/celestia-app/x/blob/keeper.Keeper.PayForBlobs({{0x2d31748, 0xc001099090}, {0x2d0e170, 0xc001099ac0}, {0x2d0e170, 0x0}, {{0x2d31748, 0xc001099090}, 0xc0004ee198, {0x2d0e170, ...}, ...}}, ...)\n\t/celestia-app/x/blob/keeper/keeper.go:60 +0x3a8\ngithub.com/celestiaorg/celestia-app/x/blob.NewHandler.func1({{0x2d24c58, 0xc000138020}, {0x2d32158, 0xc00acc0680}, {{0xb, 0x0}, {0xc0067752e0, 0x9}, 0x1099, {0x5f89ec0, ...}, ...}, ...}, ...)\n\t/celestia-app/x/blob/handler.go:20 +0x195\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).runMsgs(_, {{0x2d24c58, 0xc000138020}, {0x2d32158, 0xc00acc0680}, {{0xb, 0x0}, {0xc0067752e0, 0x9}, 0x1099, ...}, ...}, ...)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/baseapp.go:800 +0x7a8\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).runTx(0xc000be6e00, 0x3, {0xc0026698c0, 0x143, 0x143})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/baseapp.go:725 +0xc45\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).DeliverTx(0xc000be6e00, {{0xc0026698c0?, 0x20?, 0xc00abfe9c0?}})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/abci.go:283 +0x17a\ngithub.com/tendermint/tendermint/abci/client.(*localClient).DeliverTxAsync(0xc000cf9320, {{0xc0026698c0?, 0x0?, 0xc000cf9320?}})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/abci/client/local_client.go:93 +0x105\ngithub.com/tendermint/tendermint/proxy.(*appConnConsensus).DeliverTxAsync(0xc00a464780?, {{0xc0026698c0?, 0x20?, 0xb?}})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/proxy/app_conn.go:88 +0x26\ngithub.com/tendermint/tendermint/state.execBlockOnProxyApp({0x2d25e10?, 0xc000d69f20}, {0x2d2ffe8, 0xc000dafdd0}, 0xc008a5ba00, {0x2d329b0, 0xc001194120}, 0x1098?)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/state/execution.go:390 +0x822\ngithub.com/tendermint/tendermint/state.(*BlockExecutor).ApplyBlock(_, {{{0xb, 0x0}, {0xc000c8b080, 0x7}}, {0xc000c8b087, 0x9}, 0x1, 0x1098, {{0xc00a536640, ...}, ...}, ...}, ...)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/state/execution.go:210 +0x171\ngithub.com/tendermint/tendermint/consensus.(*State).finalizeCommit(0xc0010dc700, 0x1099)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1668 +0xb2d\ngithub.com/tendermint/tendermint/consensus.(*State).tryFinalizeCommit(0xc0010dc700, 0x1099)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1576 +0x2ff\ngithub.com/tendermint/tendermint/consensus.(*State).enterCommit.func1()\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1511 +0x87\ngithub.com/tendermint/tendermint/consensus.(*State).enterCommit(0xc0010dc700, 0x1099, 0x0)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1549 +0xcb7\ngithub.com/tendermint/tendermint/consensus.(*State).addVote(0xc0010dc700, 0xc008e7b220, {0x0, 0x0})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:2171 +0xb7c\ngithub.com/tendermint/tendermint/consensus.(*State).tryAddVote(0xc0010dc700, 0xc008e7b220, {0x0?, 0x47b9a6?})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1963 +0x2c\ngithub.com/tendermint/tendermint/consensus.(*State).handleMsg(0xc0010dc700, {{0x2d06640?, 0xc0011f6c70?}, {0x0?, 0x0?}})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:853 +0x44b\ngithub.com/tendermint/tendermint/consensus.(*State).receiveRoutine(0xc0010dc700, 0x0)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:780 +0x512\ncreated by github.com/tendermint/tendermint/consensus.(*State).OnStart\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:379 +0x12d\n: panic",
"logs": null,
"gas_wanted": 80000,
"gas_used": 62131,
"events": [
{
"type": "coin_spent",
"attributes": [
{
"key": "c3BlbmRlcg==",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODU=",
"index": true
},
{
"key": "YW1vdW50",
"value": "MjAwMHV0aWE=",
"index": true
}
]
},
{
"type": "coin_received",
"attributes": [
{
"key": "cmVjZWl2ZXI=",
"value": "Y2VsZXN0aWExN3hwZnZha20yYW1nOTYyeWxzNmY4NHoza2VsbDhjNWxwbmpzM3M=",
"index": true
},
{
"key": "YW1vdW50",
"value": "MjAwMHV0aWE=",
"index": true
}
]
},
{
"type": "transfer",
"attributes": [
{
"key": "cmVjaXBpZW50",
"value": "Y2VsZXN0aWExN3hwZnZha20yYW1nOTYyeWxzNmY4NHoza2VsbDhjNWxwbmpzM3M=",
"index": true
},
{
"key": "c2VuZGVy",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODU=",
"index": true
},
{
"key": "YW1vdW50",
"value": "MjAwMHV0aWE=",
"index": true
}
]
},
{
"type": "message",
"attributes": [
{
"key": "c2VuZGVy",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODU=",
"index": true
}
]
},
{
"type": "tx",
"attributes": [
{
"key": "ZmVl",
"value": "MjAwMHV0aWE=",
"index": true
},
{
"key": "ZmVlX3BheWVy",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODU=",
"index": true
}
]
},
{
"type": "tx",
"attributes": [
{
"key": "YWNjX3NlcQ==",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODUvMQ==",
"index": true
}
]
},
{
"type": "tx",
"attributes": [
{
"key": "c2lnbmF0dXJl",
"value": "ZUdtRWhHNUFtYk1uUUE0MjFzdUM3RERqSE9seFBuNC81b3ZlZHB5YUI0RVpQL0RHc3NYTTEzTnUvZEVPTllBWEJ2dDFuSWpqM2JNOHZiMlEwQmhXdHc9PQ==",
"index": true
}
]
}
]
}
If you notice from the above output, it returns a height
of
4249
which we will use for the next command.
Note: To learn more about status response codes, please navigate to cosmos code explanation
Troubleshooting
If you encounter an error like:
"rpc error: code = NotFound desc = account celestia1krkle0n547u0znz3unnln8paft2dq4z3rznv86 not found"
It is possible that the account you are trying to submit a PayForBlob
from
doesn't have testnet tokens yet. Ensure the testnet faucet has funded your
account with tokens and then try again.
Get namespaced shares by block height
After submitting your PFB transaction, upon success, the node will return the block height for which the PFB transaction was included. You can then use that block height and the namespace ID with which you submitted your PFB transaction to get your message shares returned to you. In this example, the block height we got was 2452 which we will use for the following command. Read more about shares in the Celestia Specs.
curl -X GET \
http://localhost:26659/namespaced_shares/0c204d39600fddd3/height/4249
Will generate the following output:
{
"shares": [
"DCBNOWAP3dMBAAAAG/HyDKgAfpEKO/iy5h2g8mvKB+94cXpupUFl9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
],
"height": 4249
}
The output here is base64-encoded.
Submit a PFD transaction
In this example, we will be submitting a PayForData
transaction to the node's /submit_pfd
endpoint.
Some things to consider:
- PFD is a
PayForData
Message. - The endpoint also takes in a
namespace_id
anddata
values. - Namespace ID should be 8 bytes.
- Data is in hex-encoded bytes of the raw message.
gas_limit
is the limit of gas to use for the transaction
We use the following namespace_id
of 0000010000000100
and
the data
value of f1f20ca8007e910a3bf8b2e61da0f26bca07ef78717a6ea54165f5
.
You can generate your own namespace_id
and data values using this
useful Golang Playground we created here.
When running a Celestia node, you will need to use the following flags when starting your node to submit a PFD:
- the
--core.ip string
flag, to allow you to submit transactions to your node - the
--gateway
,--gateway.addr string
, and--gateway.port string
, to open the gateway and allow anyone to use your IP as an endpoint to submit PFDs
We run the following:
curl -X POST -d '{"namespace_id": "0c204d39600fddd3",
"data": "f1f20ca8007e910a3bf8b2e61da0f26bca07ef78717a6ea54165f5",
"gas_limit": 80000, "fee": 2000}' http://localhost:26659/submit_pfd
We get the following output:
{
"height":2452,
"txhash":"04A79AF9DA62FDB41ACD7D82EB0B9004AE4E4ED603B280A65816560B4F38A999",
"data":"12200A1E2F7061796D656E742E4D7367506179466F7244617461526573706F6E7365",
"raw_log":"[{\"msg_index\":0,\"events\":[{\"type\":\"message\",\"attributes\":[{\"key\":\"action\",\"value\":\"/payment.MsgPayForData\"}]},{\"type\":\"payfordata\",\"attributes\":[{\"key\":\"signer\",\"value\":\"celestia1vdjkcetnw35kzvtgxvmxwmnwwaaxuet4xp3hxut6dce8wctsdq6hjwfcxd5xvvmyddsh5mnvvaaq6776xw\"},{\"key\":\"size\",\"value\":\"27\"}]}]}]",
"logs":[
{
"msg_index":0,
"events":[
{
"type":"message",
"attributes":[
{
"key":"action",
"value":"/payment.MsgPayForData"
}
]
},
{
"type":"payfordata",
"attributes":[
{
"key":"signer",
"value":"celestia1vdjkcetnw35kzvtgxvmxwmnwwaaxuet4xp3hxut6dce8wctsdq6hjwfcxd5xvvmyddsh5mnvvaaq6776xw"
},
{
"key":"size",
"value":"27"
}
]
}
]
}
],
"events":[
{
"type":"coin_spent",
"attributes":[
{
"key":"spender",
"value":"celestia10jhckjxxymsufflglvypxscnmggetwh0gfasws",
"index":true
},
{
"key":"amount",
"value":"1utia",
"index":true
}
]
},
{
"type":"coin_received",
"attributes":[
{
"key":"receiver",
"value":"celestia17xpfvakm2amg962yls6f84z3kell8c5lpnjs3s",
"index":true
},
{
"key":"amount",
"value":"1utia",
"index":true
}
]
},
{
"type":"transfer",
"attributes":[
{
"key":"recipient",
"value":"celestia17xpfvakm2amg962yls6f84z3kell8c5lpnjs3s",
"index":true
},
{
"key":"sender",
"value":"celestia10jhckjxxymsufflglvypxscnmggetwh0gfasws",
"index":true
},
{
"key":"amount",
"value":"1utia",
"index":true
}
]
},
{
"type":"message",
"attributes":[
{
"key":"sender",
"value":"celestia10jhckjxxymsufflglvypxscnmggetwh0gfasws",
"index":true
}
]
},
{
"type":"tx",
"attributes":[
{
"key":"fee",
"value":"1utia",
"index":true
}
]
},
{
"type":"tx",
"attributes":[
{
"key":"acc_seq",
"value":"celestia10jhckjxxymsufflglvypxscnmggetwh0gfasws/267",
"index":true
}
]
},
{
"type":"tx",
"attributes":[
{
"key":"signature",
"value":"JMNihnKS/MtYJDprqEFGJuXh16tVADsDDxXaFFpvv2te57btl4LbiRzwRRiN2rvwkJ2zlAApu2ImT22MZBi5+A==",
"index":true
}
]
},
{
"type":"tx",
"attributes":[
{
"key":"fee",
"value":"",
"index":true
}
]
},
{
"type":"tx",
"attributes":[
{
"key":"acc_seq",
"value":"celestia13zx48t96zauht0kpcn0kcfykc9wn8fehzcp9wq/1024",
"index":true
}
]
},
{
"type":"tx",
"attributes":[
{
"key":"signature",
"value":"mIZIjbzN0/RQAlQN7TDWzqtey3vVBPe7IO3+IIDhJstIH8QU9vsHfl0Rql9qWMZQG4dM+77w9WmUcnCeS7edfw==",
"index":true
}
]
},
{
"type":"tx",
"attributes":[
{
"key":"fee",
"value":"",
"index":true
}
]
},
{
"type":"tx",
"attributes":[
{
"key":"acc_seq",
"value":"celestia1h36gnnwzneu0csqzn2waph5y983hf3dkaznlgz/0",
"index":true
}
]
},
{
"type":"tx",
"attributes":[
{
"key":"signature",
"value":"sfy+XyP7iWU+V9q3zEIOWxbGihvhzUKRLNVeXP+a+5oRefIA/Pyqfm13A5NU9I27hhfvpqo9vhXW1waRgcI9OA==",
"index":true
}
]
},
{
"type":"message",
"attributes":[
{
"key":"action",
"value":"/payment.MsgPayForData",
"index":true
}
]
},
{
"type":"payfordata",
"attributes":[
{
"key":"signer",
"value":"celestia1vdjkcetnw35kzvtgxvmxwmnwwaaxuet4xp3hxut6dce8wctsdq6hjwfcxd5xvvmyddsh5mnvvaaq6776xw",
"index":true
},
{
"key":"size",
"value":"27",
"index":true
}
]
}
]
}
If you notice from the above output, it returns a height
of
2452
which we will use for the next command.
Note: To learn more about status response codes, please navigate to cosmos code explanation
Troubleshooting
If you encounter an error like:
"rpc error: code = NotFound desc = account celestia1krkle0n547u0znz3unnln8paft2dq4z3rznv86 not found"
It is possible that the account you are trying to submit a PayForData
from
doesn't have testnet tokens yet. Ensure the testnet faucet has funded your
account with tokens and then try again.
Get namespaced shares by block height
After submitting your PFD transaction, upon success, the node will return the block height for which the PFD transaction was included. You can then use that block height and the namespace ID with which you submitted your PFD transaction to get your message shares returned to you. In this example, the block height we got was 2452 which we will use for the following command. Read more about shares in the Celestia Specs.
curl -X GET \
http://localhost:26659/namespaced_shares/0c204d39600fddd3/height/2452
Will generate the following output:
{
"shares":[
"DCBNOWAP3dMb8fIMqAB+kQo7+LLmHaDya8oH73hxem6lQWX1AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="
],
"height":2452
}
The output here is base64-encoded.
Submit a PFB transaction
In this example, we will be submitting a PayForBlob
transaction to the node's /submit_pfb
endpoint.
Some things to consider:
- PFB is a
PayForBlob
Message. - The endpoint also takes in a
namespace_id
anddata
values. - Namespace ID should be 8 bytes.
- Data is in hex-encoded bytes of the raw message.
gas_limit
is the limit of gas to use for the transaction
We use the following namespace_id
of 0000010000000100
and
the data
value of f1f20ca8007e910a3bf8b2e61da0f26bca07ef78717a6ea54165f5
.
You can generate your own namespace_id
and data values using this
useful Golang Playground we created here.
When running a Celestia node, you will need to use the following flags when starting your node to submit a PFB:
- the
--core.ip string
flag, to allow you to submit transactions to your node - the
--gateway
,--gateway.addr string
, and--gateway.port string
, to open the gateway and allow anyone to use your IP as an endpoint to submit PFBs
We run the following:
curl -X POST -d '{"namespace_id": "0c204d39600fddd3",
"data": "f1f20ca8007e910a3bf8b2e61da0f26bca07ef78717a6ea54165f5",
"gas_limit": 80000, "fee": 2000}' http://localhost:26659/submit_pfb
We get the following output:
{
"height": 4249,
"txhash": "B31DEA16E1F3EE13895D4A70FE808801E8BCF8381AACD5071CB51E929F17AB65",
"codespace": "undefined",
"code": 111222,
"raw_log": "recovered: UnmarshalJSON cannot decode empty bytes\nstack:\ngoroutine 61 [running]:\nruntime/debug.Stack()\n\t/usr/local/go/src/runtime/debug/stack.go:24 +0x65\ngithub.com/cosmos/cosmos-sdk/baseapp.newDefaultRecoveryMiddleware.func1({0x1f63960, 0xc00653eef0})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/recovery.go:71 +0x27\ngithub.com/cosmos/cosmos-sdk/baseapp.newRecoveryMiddleware.func1({0x1f63960?, 0xc00653eef0?})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/recovery.go:39 +0x30\ngithub.com/cosmos/cosmos-sdk/baseapp.processRecovery({0x1f63960, 0xc00653eef0}, 0xc0091f4580?)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/recovery.go:28 +0x37\ngithub.com/cosmos/cosmos-sdk/baseapp.processRecovery({0x1f63960, 0xc00653eef0}, 0x2d32158?)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/recovery.go:33 +0x5e\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).runTx.func1()\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/baseapp.go:639 +0xf0\npanic({0x1f63960, 0xc00653eef0})\n\t/usr/local/go/src/runtime/panic.go:838 +0x207\ngithub.com/cosmos/cosmos-sdk/x/params/types.Subspace.Get({{0x2d31748, 0xc001099090}, 0xc0004ee198, {0x2d0e170, 0xc001099730}, {0x2d0e1c0, 0xc001099c10}, {0xc00168aba0, 0x4, 0x12}, ...}, ...)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/x/params/types/subspace.go:110 +0x307\ngithub.com/celestiaorg/celestia-app/x/blob/keeper.Keeper.GasPerBlobByte(...)\n\t/celestia-app/x/blob/keeper/params.go:36\ngithub.com/celestiaorg/celestia-app/x/blob/keeper.Keeper.PayForBlobs({{0x2d31748, 0xc001099090}, {0x2d0e170, 0xc001099ac0}, {0x2d0e170, 0x0}, {{0x2d31748, 0xc001099090}, 0xc0004ee198, {0x2d0e170, ...}, ...}}, ...)\n\t/celestia-app/x/blob/keeper/keeper.go:60 +0x3a8\ngithub.com/celestiaorg/celestia-app/x/blob.NewHandler.func1({{0x2d24c58, 0xc000138020}, {0x2d32158, 0xc00acc0680}, {{0xb, 0x0}, {0xc0067752e0, 0x9}, 0x1099, {0x5f89ec0, ...}, ...}, ...}, ...)\n\t/celestia-app/x/blob/handler.go:20 +0x195\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).runMsgs(_, {{0x2d24c58, 0xc000138020}, {0x2d32158, 0xc00acc0680}, {{0xb, 0x0}, {0xc0067752e0, 0x9}, 0x1099, ...}, ...}, ...)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/baseapp.go:800 +0x7a8\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).runTx(0xc000be6e00, 0x3, {0xc0026698c0, 0x143, 0x143})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/baseapp.go:725 +0xc45\ngithub.com/cosmos/cosmos-sdk/baseapp.(*BaseApp).DeliverTx(0xc000be6e00, {{0xc0026698c0?, 0x20?, 0xc00abfe9c0?}})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/baseapp/abci.go:283 +0x17a\ngithub.com/tendermint/tendermint/abci/client.(*localClient).DeliverTxAsync(0xc000cf9320, {{0xc0026698c0?, 0x0?, 0xc000cf9320?}})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/abci/client/local_client.go:93 +0x105\ngithub.com/tendermint/tendermint/proxy.(*appConnConsensus).DeliverTxAsync(0xc00a464780?, {{0xc0026698c0?, 0x20?, 0xb?}})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/proxy/app_conn.go:88 +0x26\ngithub.com/tendermint/tendermint/state.execBlockOnProxyApp({0x2d25e10?, 0xc000d69f20}, {0x2d2ffe8, 0xc000dafdd0}, 0xc008a5ba00, {0x2d329b0, 0xc001194120}, 0x1098?)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/state/execution.go:390 +0x822\ngithub.com/tendermint/tendermint/state.(*BlockExecutor).ApplyBlock(_, {{{0xb, 0x0}, {0xc000c8b080, 0x7}}, {0xc000c8b087, 0x9}, 0x1, 0x1098, {{0xc00a536640, ...}, ...}, ...}, ...)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/state/execution.go:210 +0x171\ngithub.com/tendermint/tendermint/consensus.(*State).finalizeCommit(0xc0010dc700, 0x1099)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1668 +0xb2d\ngithub.com/tendermint/tendermint/consensus.(*State).tryFinalizeCommit(0xc0010dc700, 0x1099)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1576 +0x2ff\ngithub.com/tendermint/tendermint/consensus.(*State).enterCommit.func1()\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1511 +0x87\ngithub.com/tendermint/tendermint/consensus.(*State).enterCommit(0xc0010dc700, 0x1099, 0x0)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1549 +0xcb7\ngithub.com/tendermint/tendermint/consensus.(*State).addVote(0xc0010dc700, 0xc008e7b220, {0x0, 0x0})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:2171 +0xb7c\ngithub.com/tendermint/tendermint/consensus.(*State).tryAddVote(0xc0010dc700, 0xc008e7b220, {0x0?, 0x47b9a6?})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:1963 +0x2c\ngithub.com/tendermint/tendermint/consensus.(*State).handleMsg(0xc0010dc700, {{0x2d06640?, 0xc0011f6c70?}, {0x0?, 0x0?}})\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:853 +0x44b\ngithub.com/tendermint/tendermint/consensus.(*State).receiveRoutine(0xc0010dc700, 0x0)\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:780 +0x512\ncreated by github.com/tendermint/tendermint/consensus.(*State).OnStart\n\t/go/pkg/mod/github.com/celestiaorg/[email protected]/consensus/state.go:379 +0x12d\n: panic",
"logs": null,
"gas_wanted": 80000,
"gas_used": 62131,
"events": [
{
"type": "coin_spent",
"attributes": [
{
"key": "c3BlbmRlcg==",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODU=",
"index": true
},
{
"key": "YW1vdW50",
"value": "MjAwMHV0aWE=",
"index": true
}
]
},
{
"type": "coin_received",
"attributes": [
{
"key": "cmVjZWl2ZXI=",
"value": "Y2VsZXN0aWExN3hwZnZha20yYW1nOTYyeWxzNmY4NHoza2VsbDhjNWxwbmpzM3M=",
"index": true
},
{
"key": "YW1vdW50",
"value": "MjAwMHV0aWE=",
"index": true
}
]
},
{
"type": "transfer",
"attributes": [
{
"key": "cmVjaXBpZW50",
"value": "Y2VsZXN0aWExN3hwZnZha20yYW1nOTYyeWxzNmY4NHoza2VsbDhjNWxwbmpzM3M=",
"index": true
},
{
"key": "c2VuZGVy",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODU=",
"index": true
},
{
"key": "YW1vdW50",
"value": "MjAwMHV0aWE=",
"index": true
}
]
},
{
"type": "message",
"attributes": [
{
"key": "c2VuZGVy",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODU=",
"index": true
}
]
},
{
"type": "tx",
"attributes": [
{
"key": "ZmVl",
"value": "MjAwMHV0aWE=",
"index": true
},
{
"key": "ZmVlX3BheWVy",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODU=",
"index": true
}
]
},
{
"type": "tx",
"attributes": [
{
"key": "YWNjX3NlcQ==",
"value": "Y2VsZXN0aWExOG1lbHFkNmV0eXZ5aDZ3M3BkMDZkODRleXA5cHU1c2xuN2h5ODUvMQ==",
"index": true
}
]
},
{
"type": "tx",
"attributes": [
{
"key": "c2lnbmF0dXJl",
"value": "ZUdtRWhHNUFtYk1uUUE0MjFzdUM3RERqSE9seFBuNC81b3ZlZHB5YUI0RVpQL0RHc3NYTTEzTnUvZEVPTllBWEJ2dDFuSWpqM2JNOHZiMlEwQmhXdHc9PQ==",
"index": true
}
]
}
]
}
If you notice from the above output, it returns a height
of
4249
which we will use for the next command.
Note: To learn more about status response codes, please navigate to cosmos code explanation
Troubleshooting
If you encounter an error like:
"rpc error: code = NotFound desc = account celestia1krkle0n547u0znz3unnln8paft2dq4z3rznv86 not found"
It is possible that the account you are trying to submit a PayForBlob
from
doesn't have testnet tokens yet. Ensure the testnet faucet has funded your
account with tokens and then try again.
Get namespaced shares by block height
After submitting your PFB transaction, upon success, the node will return the block height for which the PFB transaction was included. You can then use that block height and the namespace ID with which you submitted your PFB transaction to get your message shares returned to you. In this example, the block height we got was 2452 which we will use for the following command. Read more about shares in the Celestia Specs.
curl -X GET \
http://localhost:26659/namespaced_shares/0c204d39600fddd3/height/4249
Will generate the following output:
{
"shares": [
"DCBNOWAP3dMBAAAAG/HyDKgAfpEKO/iy5h2g8mvKB+94cXpupUFl9QAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="
],
"height": 4249
}
The output here is base64-encoded.