Skip to content

Commit

Permalink
Conversions, fix onramp, formating proposal markdown (#78)
Browse files Browse the repository at this point in the history
* GITBOOK-1: Address conversions. GET + Decode RPC/REST Block Transactions

* GITBOOK-2: address conversion python

* GITBOOK-3: CLI bech32 convert

* GITBOOK-4: use Wynd & kado instead of Junoswap

* GITBOOK-5: Formating proposal markdown
  • Loading branch information
Reecepbcups authored Mar 10, 2023
1 parent 2b28e5f commit 05ca2be
Show file tree
Hide file tree
Showing 7 changed files with 378 additions and 6 deletions.
5 changes: 4 additions & 1 deletion SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@
* [Query A Contract](developer-guides/cosmwasm-contracts/query-a-contract.md)
* [Send Tokens to a Contract](developer-guides/cosmwasm-contracts/send-tokens-to-a-contract.md)
* [Miscellaneous](developer-guides/miscellaneous/README.md)
* [Conversions](developer-guides/miscellaneous/conversions.md)
* [Multi Message Transaction](developer-guides/miscellaneous/multi-message-transaction.md)
* [Get & Decode Transactions](developer-guides/miscellaneous/get-and-decode-transactions.md)
* [Get Token Prices](developer-guides/miscellaneous/get-token-prices.md)
* [Get Account Transactions](developer-guides/miscellaneous/get-account-transactions.md)
* [IBC Transfer](developer-guides/miscellaneous/ibc-transfer.md)
Expand Down Expand Up @@ -162,7 +164,8 @@
## Governance

* [Before submitting a proposal](governance/before-submitting-a-proposal.md)
* [Submitting a Proposal (CLI)](governance/submitting-a-proposal-cli.md)
* [Submitting a Proposal (CLI)](governance/submitting-a-proposal-cli/README.md)
* [Formatting Proposal Markdown](governance/submitting-a-proposal-cli/formatting-proposal-markdown.md)

## Command-Line Interface (CLI) <a href="#cli" id="cli"></a>

Expand Down
139 changes: 139 additions & 0 deletions developer-guides/miscellaneous/conversions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
---
description: How to convert between different aspects of data for
---

# Conversions

## Denominations

In Cosmos, every denomination amount is formatted as an unsigned integer. With this, the chain does not have to deal with fractions. For an EVM chain this amount is typically `10**18` power, while Juno and other native Cosmos chains use the `10**6` power. This means if I want to send you 1 JUNO, I am actually sending 1,000,000 of the smaller token.\
\
You can figure out which power a token uses by its prefix character in the denomination. In the case of JUNO, the actual denomination is shown as `ujuno`. This u signals that it is using any amount times `10**6` to get the human readable amount.

{% hint style="info" %}
10JUNO = 10,000,000ujuno\
0.5 JUNO = 500,000ujuno\
0.00001 JUNO = 10ujuno\
\
This means the smallest amount anyone can send is 0.000001 JUNO
{% endhint %}

## Hex address to valcons (validator consensus)

Sometimes you may want to convert from a hex address found from one of Juno's endpoints to a more readable validators consensus address to get their signing blocks and link to other data. TO do so, here is a Typescript snippet

```typescript
// npm i @cosmjs/encoding
import {fromHex, toBech32} from '@cosmjs/encoding'

// where junovalcons is the wallet prefix for the chain + valcons
const prefix = "junovalcons"

let addr = toBech32(prefix, fromHex("1470B9237056641663CB4DFDEC86B064578B29BF"))
console.log(addr)

// This outputs junovalcons1z3ctjgms2ejpvc7tfh77ep4sv3tck2dl30r3mx
// which matches their page
// https://ping.pub/juno/staking/junovaloper196ax4vc0lwpxndu9dyhvca7jhxp70rmcqcnylw
```

With this, you can now make a mapping between a junovaloper and junovalcons address

## Public Key to Valcons (Validator Consensus)

{% hint style="info" %}
```
You can get the Public Key from the REST/LCD endpoint:
cosmos/staking/v1beta1/validators
https://api.juno.strange.love/cosmos/staking/v1beta1/validators
&
https://.../cosmos/staking/v1beta1/validators/junovalopera_address_here
```
{% endhint %}

```typescript
// npm i @cosmjs/encoding
import {fromBase64, toBech32} from '@cosmjs/encoding'
// npm i @cosmjs/crypto
import { sha256 } from '@cosmjs/crypto'

let prefix = "junovalcons"

// Chain Format:
// {
// "@type":"/cosmos.crypto.ed25519.PubKey",
// "key":"/O7BtNW0pafwfvomgR4ZnfldwPXiFfJs9mHg3gwfv5Q="
// }

// we just need the .key string from the object
let pubKey = "/O7BtNW0pafwfvomgR4ZnfldwPXiFfJs9mHg3gwfv5Q="
const addr = toBech32(prefix, sha256(fromBase64(pubKey)).slice(0, 20))

console.log(addr)
// junovalcons1z3ctjgms2ejpvc7tfh77ep4sv3tck2dl30r3mx
```

## Validator Operator (Valoper) to normal account

```typescript
// npm i @cosmjs/encoding
import {toBech32, fromBech32} from '@cosmjs/encoding'

let toPrefix = "juno"

let initial = "junovaloper196ax4vc0lwpxndu9dyhvca7jhxp70rmcqcnylw"
let converted = toBech32(toPrefix, fromBech32(initial).data)

console.log(converted)
// juno196ax4vc0lwpxndu9dyhvca7jhxp70rmcl99tyh
```

## JUNO Address to another chain

For an easy UI, you can use [https://bech32.scrtlabs.com/](https://bech32.scrtlabs.com/) for address conversions. If you need a more programmatic version

#### Typescript

```typescript
// Typescript
// npm i @cosmjs/encoding
import {toBech32, fromBech32} from '@cosmjs/encoding'

let toPrefix = "cosmos"

let initial = "juno196ax4vc0lwpxndu9dyhvca7jhxp70rmcl99tyh"
let converted = toBech32(toPrefix, fromBech32(initial).data)

console.log(converted)
// cosmos196ax4vc0lwpxndu9dyhvca7jhxp70rmcfhxsrt
```

#### Python

```python
# pip install bech32 - https://pypi.org/project/bech32/
import bech32

address = "juno196ax4vc0lwpxndu9dyhvca7jhxp70rmcl99tyh"

def address_convert(address=address, prefix="cosmos"):
_, data = bech32.bech32_decode(address)
return bech32.bech32_encode(prefix, data)

converted_addr = address_convert(address, "cosmos")
print(converted_addr)
# cosmos196ax4vc0lwpxndu9dyhvca7jhxp70rmcfhxsrt
```

#### Command Line

```sh
junod debug bech32-convert juno196ax4vc0lwpxndu9dyhvca7jhxp70rmcl99tyh --prefix cosmos
# cosmos196ax4vc0lwpxndu9dyhvca7jhxp70rmcfhxsrt
```

Here we take SG-1's JUNO address and convert it to a cosmoshub address since these are both 118 coin types. Other 118 coin types include Juno, Osmosis, Chihuahua, and others. You can only convert between the same cointype, so converting a JUNO to EVM address such as EVMOS or INJECTIVE will not function.\
\
Once converted, [you can see that SG-1 cosmos address](https://www.mintscan.io/cosmos/account/cosmos196ax4vc0lwpxndu9dyhvca7jhxp70rmcfhxsrt) also has funds just like their JUNO account by using a UI explorer like mintscan.

184 changes: 184 additions & 0 deletions developer-guides/miscellaneous/get-and-decode-transactions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
# Get & Decode Transactions

## Get Transactions

You can get a blocks transactions both via the RPC and REST API. You can find other public endpoints on the [https://cosmos.directory/juno/nodes](https://cosmos.directory/juno/nodes) website

### Get with RPC:&#x20;

URL: [https://rpc.juno.strange.love/block](https://rpc.juno.strange.love/block)\
Transaction Array: result.block.data.txs\[]

### Get with REST API:

URL: [https://api.juno.strange.love/cosmos/base/tendermint/v1beta1/blocks/latest](https://api.juno.strange.love/cosmos/base/tendermint/v1beta1/blocks/latest)\
Transaction Array: block.data.txs\[]

### Get with CLI:

```sh
# apt install jq | pacman -S jq
junod q block | jq .block.data.txs
```

## Decode: Command Line

You can decode transaction data using the `junod` command:

```sh
junod tx decode <base64-amino-byte-string> --output=json
```

For example

```sh
junod tx decode CoMECvwBCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QS0wEKK2p1bm8xaHRzOGdnMHdudXhxazl4ZXJ1a3djNHB4ZG1ncmdoZG5qdjhnZGcSP2p1bm8xZzVqOXZkNzZjcXQ3ZnNxMjJuZTdqcWZrejR2OXB0a3ZoNGprbnN2d2NocGo3NTNhdHdmczk0MmEyNRpOeyJzd2FwIjp7ImlucHV0X3Rva2VuIjoiVG9rZW4yIiwiaW5wdXRfYW1vdW50IjoiNDUyOTAwMDAwMCIsIm1pbl9vdXRwdXQiOiIwIn19KhMKBXVqdW5vEgo0NTI5MDAwMDAwCoECCiQvY29zbXdhc20ud2FzbS52MS5Nc2dFeGVjdXRlQ29udHJhY3QS2AEKK2p1bm8xaHRzOGdnMHdudXhxazl4ZXJ1a3djNHB4ZG1ncmdoZG5qdjhnZGcSP2p1bm8xZThuNmNoN21za3M0ODdlY3pueWVhZ216ZDVtbDJwcTl0Z2VkcXQydTYzdnJhMHEwcjltcXJqeTZ5cxpUeyJzd2FwIjp7ImlucHV0X3Rva2VuIjoiVG9rZW4xIiwiaW5wdXRfYW1vdW50IjoiNDUyOTAwMDAwMCIsIm1pbl9vdXRwdXQiOiI2MDAwMDAwIn19KhIKBXVqdW5vEgk5NjkwMDAwMDASZgpQCkYKHy9jb3Ntb3MuY3J5cHRvLnNlY3AyNTZrMS5QdWJLZXkSIwohA2IKqvhI5iJwjhzNfy90VKT/UKcn7hQtmJD2WtPxiIY5EgQKAggBGEsSEgoMCgV1anVubxIDNjAwEMOaDBpAh+kKHSm07sTOYe8K/m7GhSGgmciMjGPD7eTLtLHX2x1Rp5e0m+cHK2rFB9f9ZNRITrf0L7E/emsOKjdFkUFbnA== --output json
```

returns

```json
{
"body":{
"messages":[
{
"@type":"/cosmwasm.wasm.v1.MsgExecuteContract",
"sender":"juno1hts8gg0wnuxqk9xerukwc4pxdmgrghdnjv8gdg",
"contract":"juno1g5j9vd76cqt7fsq22ne7jqfkz4v9ptkvh4jknsvwchpj753atwfs942a25",
"msg":{
"swap":{
"input_token":"Token2",
"input_amount":"4529000000",
"min_output":"0"
}
},
"funds":[
{
"denom":"ujuno",
"amount":"4529000000"
}
]
},
{
"@type":"/cosmwasm.wasm.v1.MsgExecuteContract",
"sender":"juno1hts8gg0wnuxqk9xerukwc4pxdmgrghdnjv8gdg",
"contract":"juno1e8n6ch7msks487ecznyeagmzd5ml2pq9tgedqt2u63vra0q0r9mqrjy6ys",
"msg":{
"swap":{
"input_token":"Token1",
"input_amount":"4529000000",
"min_output":"6000000"
}
},
"funds":[
{
"denom":"ujuno",
"amount":"969000000"
}
]
}
],
"memo":"",
"timeout_height":"0",
"extension_options":[

],
"non_critical_extension_options":[

]
},
"auth_info":{
"signer_infos":[
{
"public_key":{
"@type":"/cosmos.crypto.secp256k1.PubKey",
"key":"A2IKqvhI5iJwjhzNfy90VKT/UKcn7hQtmJD2WtPxiIY5"
},
"mode_info":{
"single":{
"mode":"SIGN_MODE_DIRECT"
}
},
"sequence":"75"
}
],
"fee":{
"amount":[
{
"denom":"ujuno",
"amount":"600"
}
],
"gas_limit":"200003",
"payer":"",
"granter":""
}
},
"signatures":[
"h+kKHSm07sTOYe8K/m7GhSGgmciMjGPD7eTLtLHX2x1Rp5e0m+cHK2rFB9f9ZNRITrf0L7E/emsOKjdFkUFbnA=="
]
}
```

## Decode with Python (junod)

Using junod and python, we can save this JSON data for later using the following example.\
This excerpt was taken from the [juno-analysis repo](https://github.com/Reecepbcups/juno-analysis/blob/main/main.py)

```python
# python3 -m pip install httpx
import httpx, json, os

RPC_URL = "https://rpc.juno.strange.love:443"
height = 7_000_000

client = httpx.Client()
tx_data: dict[int, dict] = {}

def run_cmd(cmd) -> str:
return os.popen(cmd).read()


def get_block_transactions(height: int) -> list[str]:
block = client.get(f"{RPC_URL}/block?height={height}").json()
block_txs = block["result"]["block"]["data"]["txs"]
return block_txs


def main():
version = run_cmd("junod version")
if len(version) == 0:
print("Junod not installed. Please install junod and try again.")
exit(1)

txs = get_block_transactions(height=height)

for tx in txs:
txs_json = json.loads(run_cmd(f"junod tx decode {tx} --output json"))
tx_data[height] = txs_json.get("body", {}).get("messages", [])

# Do somethign with that tx data here
print(tx_data)

if __name__ == "__main__":
main()
```

## Decode with Python (protobuf)

If you have experience with protobuf, you can use cosmospy to decode transaction data and decode is from base64 strings

```python
# python -m pip install cosmospy-protobuf
import base64
import cosmospy_protobuf.cosmos.tx.v1beta1.tx_pb2 as tx_pb2

tx = "CpMBCpABChwvY29zbW9zLmJhbmsudjFiZXRhMS5Nc2dTZW5kEnAKLWNvc21vczEweGw5cXV1Z2N2amhsMGdsamplaG1oeHhhN3cwaDM5ZTJ2aGFndhItY29zbW9zMThsemp0NWpwcjdtd3U0dHlkbGNmZ2N1dHI2Z25ycGsweWo4ZnNjGhAKBXVhdG9tEgcxMDAwMDAwEmcKUApGCh8vY29zbW9zLmNyeXB0by5zZWNwMjU2azEuUHViS2V5EiMKIQM+g5XXnqLLelLxz8CTy+vG5aO7SohNKS78OtL9ysdcEhIECgIIARgCEhMKDQoFdWF0b20SBDIyNzUQ+MYFGkBbTDHP0mn8d2hxQnNUE/SeudBrXMgjyRO5Bv12D4iWgk4cPsczc6EaDQD3v7cqqD22HL8ZZXVMF3GKi1SNAGNT"
decode64 = base64.b64decode(tx)
tx = tx_pb2.Tx()
tx.ParseFromString(decode64)

print(tx)
# print(tx.body.messages)
```

2 changes: 1 addition & 1 deletion governance/before-submitting-a-proposal.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ Consider making appropriate changes to your proposal based on feedback from the

### Submit your proposal on-chain

Once you are confident about your proposal, you can submit on-chain for voting. You can find guidance on submitting your proposal [here](submitting-a-proposal-cli.md).
Once you are confident about your proposal, you can submit on-chain for voting. You can find guidance on submitting your proposal [here](submitting-a-proposal-cli/).

Please note that the fee to fully fund a governance deposit is 1,000 JUNO. These funds will be returned to the depositor following completion of the voting period. If there are sufficient `NO WITH VETO` votes, the depositors will lose their funds. The depositor will also lose their funds if quorum of 33.4% is not reached.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
---
cover: ../.gitbook/assets/Discord Invite (1) (6).png
cover: ../../.gitbook/assets/Discord Invite (1) (6).png
coverY: 261
---

Expand All @@ -13,7 +13,9 @@ You can query the current setting for that parameter with `junod query params su
junod query params subspace distribution communitytax
```

> NB: if you have not set it in config, you will need to add chain-id: `--chain-id uni`.
{% hint style="info" %}
if you have not set it in config, you will need to add chain-id: `--chain-id uni-6`
{% endhint %}

This will return:

Expand All @@ -39,7 +41,7 @@ value: '{"max_bytes":"22020096","max_gas":"80000000"}'

Let's take this BlockParams parameter as an example. Say we want to create a proposal that increases this value.

We can encode the parameter change in a JSON proposal like so:
We can encode the parameter change in a JSON proposal like so. You can [use the following script](formatting-proposal-markdown.md) to format the description in markdown.

```json
{
Expand Down
Loading

0 comments on commit 05ca2be

Please sign in to comment.