A custom Cosmos SDK blockchain that supports multi-signature wallets.
While multsig transfer of coins utilizes the built in multisig feautres of cosmos, this blockchain expands that to create an infrastructure to have a nice UI around multisig transactions.
The complete workflow of a multisig transaction as follows...
- Create a multisig wallet, specifying the name, minimum number of signatures for a transaction to take place, and the pub keys associated with the wallet.
- Transfer funds to this wallet
- Create a transaction request to send funds from the multisig wallet to another address
- Multiple owners of the multisig wallet sign the transaction.
- Once enough signatures have been made, send the funds.
- Update the transaction request with the
txhash
of the transfer of funds.
The cli tool has a series of queries and transaction that you can use. In theory, you could iteract with this blockchain fully using the cli, but REST was the intended purpose.
This command is used to create a multisig wallet. Pubkeys should be comma separated (no spaces).
msgicli tx multisig create-wallet [name] [min-signatures-required] [pub-keys], [addresses] [flags]
Get wallet info by wallet address
msgicli query multisig get-wallet [address] [flags]
Search for a list of wallets by public key
msgicli query multisig query-wallets [pub_key] [flags]
This command creates a transaction request to move funds out of a multisig wallet.
msgicli tx multisig create-transaction [from] [to] [coins] [signers] [flags]
Retrieve transaction request information by uuid
msgicli query multisig get-transaction [uuid] [flags]
Get a list of transaction requests by wallet address.
msgicli query multisig query-transactions [wallet_address] [flags]
This command adds a signature to a transaction request.
TODO: remove need to supply pubkey_base64
. This info is available via the
account info (/auth/accounts/<address>
).
msgicli tx multisig save-transaction-signature [uuid] [pubkey] [pubkey_base64] [signature] [signers] [flags]
Once the transaction is completed and funds sent, save the txhash
in the
transaction request to mark it as completed.
msgicli tx multisig complete-transaction [uuid] [transaction_id] [signers] [flags]
There are corresponding API endpoints for each of the CLI commands above.
Create a wallet
{
"name": "demo 1",
"base_req": {"chain_id":"msigchain", "from": "msigXXXXXX"},
"min_sig_tx": 2,
"pub_keys": [...],
"signers": [...]
}
Get a wallet
List wallets that contain specified public key
Create a transaction request
{
"base_req": {"chain_id":"msigchain", "from": "msigXXXXXX"},
"from": "msigXXXX",
"to": "msigXXXX",
"amount": 3,
"denom": "msigtoken",
"signers": [...]
}
Get a transaction request by uuid
List transaction by wallet address
Add signature for a transaction request
{
"base_req": {"chain_id":"msigchain", "from": "msigXXXXXX"},
"uuid": "02206ab8-ef05-4ecc-8e81-4430405e929a",
"signature": "1KRP93NJ85SxygGucoS7MqV39INDG/TYZzRP9NVzS4k/J7zn5kus1r3SoIXkyHgYEZmnaIyr26liL7uez45Uiw",
"pub_key": "msigp1addwnpepq0wx75hs3jpepjlvvee4r8gmuuxnmjzk6k5jkjps7n9rr3y4v0quqqy456c",
"pub_key_base64": "A/HRtDdV5mtPOMFhDDRRqb0s60q8rVJ+3AqSWd3PkOWx",
"signers": [...]
}
With given signatures, generate a multi-signature. "Signatures" must be a list of tx signatures for pub keys of the wallet. Order is important here, and must align with the pub key order of the wallet. "Slots" is a string of zeros and ones representing which pubkeys of the wallet are included in the list of signatures, and which are not. Zeros are not include, ones are included. The resulting json response will include the multisig signature.
{
"Signatures": [...],
"Slots": "011",
}
Complete a transaction supplying the txhash
of the transfer of funds.
{
"base_req": {"chain_id":"msigchain", "from": "msigXXXXXX"},
"uuid": "02206ab8-ef05-4ecc-8e81-4430405e929a",
"TxID": "939HDJ300...",
"signers": [...],
}
Broadcast a message (same as to /txs
in the cosmos SDK).
MultiSigWallet
is a type to store multisignature wallet information. This
type includes...
Name
- the custom name of the wallet. This makes it easier for users to identify each wallet and its purpose.MinSigTx
- the minimum number of regular user signatures required before a transaction can be sent.Address
- The receiving address to send coins into this wallet.PubKeys
- A list of public keys associated with this wallet that has the ability to sign transactions. Order of public keys is important.
** Notes ** Wallets cannot be deleted, nor can they be overwritten or change once created.
Transaction
is a type to store a transaction request information to move
funds out of a multisig wallet.
UUID
- a unique identifier (follow uuid standards)From
- an multisig wallet address to send the funds fromTo
- a wallet address to send the funds toCoins
- an array of coins to be sent from the multisig wallet. Currently only one coins (one denom) can be sent at this time.Signatures
- the signed signatures of this transaction from the public keys associated with the multisig walletTxID
- the transaction hash from the blockchain referencing this transaction on the blockchain. This is written as a last step to signify the transaction is complete.CreatedAt
- The block height when this transaction request was first created. This helps the UI sort the transaction list, but also acts a means to cleanup old transaction requests from history (ie deleting transaction requests after X blocks have passed).
Ensure you have a recent version of go (ie `1.121) and enabled go modules
export GO111MODULE=on
And have GOBIN
in your PATH
export GOBIN=$GOPATH/bin
Install via this make
command.
make install
Once you've installed msigcli
and msigd
, check that they are there.
msigcli help
msigd help
Next configure your chain.
# Initialize configuration files and genesis file
# moniker is the name of your node
msigd init <moniker> --chain-id msigchain
# Copy the Address output here and save it for later use
# [optional] add "--ledger" at the end to use a Ledger Nano S
msigcli keys add jack
# Copy the Address output here and save it for later use
msigcli keys add alice
# Add both accounts, with coins to the genesis file
msigd add-genesis-account $(msigcli keys show jack -a) 1000msig,100000000stake
msigd add-genesis-account $(msigcli keys show alice -a) 1000msig,100000000stake
# Configure your CLI to eliminate need for chain-id flag
msigcli config chain-id msigchain
msigcli config output json
msigcli config indent true
msigcli config trust-node true
msigd gentx --name jack
There are three services you may want to start.
This runs the backend
msigd start
Starts an HTTP service to service requests to the backend.
msigcli rest-server
For making requests in a browser to the API backend, you'll need to start a
proxy in front of the API service to give proper CORS headers.
For development purposes, a service is provided in /scripts/cors
cd scripts/cors
npm start