Custom chains
Creating a custom version of BDJuno is pretty straightforward. All you have to do is:
- Fork the BDJuno repository.
- Create a new branch for your project.
- Add or update the dependencies based on your needs.
- Add your application module managers.
- (Optional) Implement a custom messages parser.
Fork BDJuno
The first thing you need to do is forking our BDJuno repository.
This will allow you to create a new repository where you can work without any limits. It will also allow you to later update the base repo to make sure you have a constantly updated BDJuno codebase that does not fall behind ours.
Create a new branch
The next thing you want to do is create a new branch for your project. The best way to do this is by checking out one of
the cosmos/
branches and then create a new branch from there.
It is important that when you create your new branch you checkout the one that is most similar to the Cosmos SDK your project is based on.
We will see how to handle that later. For now, just check out the branch that is made for the Cosmos version most similar to the one you are based on.
To checkout the branch you desire, just run:
$ git checkout -t origin/<branch-name>
# E.g.
# git checkout origin/cosmos/stargate
Now that you have checked out the Cosmos branch, you can create your own branch:
$ git checkout -b chains/<project-name>
# E.g
# git checkout -b chains/my-project
This will create a new chains/
branch that you can start working on.
Add or update your dependencies
Now it's time to add the dependencies that your project needs. For these steps, we will take as example Desmos.
The first thing we want to do is add Desmos as a dependency:
$ go get -u github.com/desmos-labs/[email protected]
This will edit your go.mod
and go.sum
files including the Desmos dependency.
Then, we need to make sure that the project we want to use does not use some custom dependencies. To do this, we can
take a look at its go.mod
file and search for
any replace
directives.
In our case, Desmos uses some custom dependencies:
replace github.com/gogo/protobuf => github.com/regen-network/protobuf v1.3.3-alpha.regen.1
replace github.com/cosmos/cosmos-sdk => github.com/desmos-labs/cosmos-sdk v0.43.0-alpha1.0.20211102084520-683147efd235
replace google.golang.org/grpc => google.golang.org/grpc v1.33.2
replace github.com/tendermint/tendermint => github.com/forbole/tendermint v0.34.13-0.20210820072129-a2a4af55563d
What we need to do, is edit BDJuno's go.mod
file by adding the same replace
directives. This will make sure that
BDJuno uses the same Cosmos SDK fork and other dependencies and does not error due to incompatibility problems.
Add your application modules
Once you have added the dependency to your project, it is not time to use such dependency inside BDJuno.
This will be used to tell BDJuno which modules you support to make sure that it is able to properly deserialize all your messages. Failing in doing this will result in BDJuno returning an error each time a custom message is to be parsed from a transaction.
To tell BDJuno which modules you support, you need to change what the
cmd/bdjuno/main.go#getBasicManages
function returns by adding your project's ModuleBasics
. As an example, for Desmos we will change it to be
func getBasicManagers() []module.BasicManager {
return []module.BasicManager{
simapp.ModuleBasics,
desmosapp.ModuleBasics, // <--- We have added this line
}
}
Make sure that you set your ModuleBasics
to be the last one in the slice.
This will make sure that if you have any module that is named the same way as a Cosmos one (maybe because you use a custom implementation), the custom one will be used correctly.
If you set your modules first, the Cosmos ones will override them.
(Optional) Add your custom addresses parser
Inside BigDipper, when you visualize the details of an account you are able to see all the messages that it was involved in.
This is done by parsing each message to get the involved addresses.
By default, inside BDJuno we do this only with the Cosmos messages, and then we rely on the Msg#GetSigners
method.
Although this works great for most messages that involve a single user (the signer), your project might include some messages that involve more addresses. For example, you might have a message that allows to send funds from one user to the other. Or a message that allows one user to perform a kind of action towards another one.
If this is the case, it is important that you build a custom addresses parser inside BDJuno to make sure that each message is associated with the proper list of addresses, and that the associated accounts are refreshed correctly once the message is parsed (especially if it edits both account balances).
To do this, what you can do is create a new file inside the cmd/bdjuno
folder naming it after your project.
Inside that file, you need to create a function with the following signature:
// CustomAddressesParser represents a MessageAddressesParser for the my custom module
func CustomAddressesParser(cdc codec.Marshaler, cosmosMsg sdk.Msg) ([]string, error)
This method should return either a list of all the parsed addresses or messages.MessageNotSupported(cosmosMsg)
if the message is not supported.
If you want to take a look at a reference implementation you can refer to the Desmos one.
If you have multiple modules that should be parsed in different ways, we suggest you splitting them into different parsers and then combining those parsers together using the messages.JoinMessageParsers
method.
You can see how this is used for Desmos here.
Finally, once you have your custom addresses parser setup, you need to add it to the cmd/bdjuno/main.go#getAddressesParser
method. Here is the example for Desmos:
func getAddressesParser() messages.MessageAddressesParser {
return messages.JoinMessageParsers(
desmosMessageAddressesParser,
messages.CosmosMessageAddressesParser,
)
}
Make sure you set your parser to be the first one used. Otherwise, the CosmosMessageAddressesParser
will default to using the Msg#GetSigners
method and your parser will never be called, even though BDJuno will not return any error.