Example #1
0
 def test_add_coins(self, t):
     """Coins can be added, which merges the collections of Coins and groups together
     the sum amount for Coins of a similar denom."""
     A = t([Coin("uluna", 2000)])
     B = t([Coin("ukrw", 1000)])
     C = t([Coin("uluna", 1000), Coin("ukrw", 250), Coin("uusd", 2000)])
     assert A + B == Coins([Coin("uluna", 2000), Coin("ukrw", 1000)])
     assert A + B + C == Coins(
         [Coin("uluna", 3000), Coin("ukrw", 1250), Coin("uusd", 2000)]
     )
Example #2
0
 def test_equality(self):
     """sdk.Coins object should be able to compare with coins and list."""
     A = Coins([Coin("A", 1000), Coin("B", 500)])
     B = Coins([Coin("B", 500), Coin("A", 1000)])
     assert A == B  # order of original input should not matter
     assert A == [Coin("A", 1000), Coin("B", 500)]
     assert [Coin("A", 1000), Coin("B", 500)] == A
     assert A == [Coin("B", 500), Coin("A", 1000)]
     assert [Coin("B", 500), Coin("A", 1000)] == A
     assert not (A == [500, 1000])
     assert not ([500, 1000] == A)
Example #3
0
    def test_constructor_copy(self):
        """sdk.Coins object should copy another sdk.Coins object when passed into constructor,
        rather than maintaining original references."""
        A = Coin("A", 1000)
        C1 = Coins([A])
        C2 = Coins(C1)

        assert C1 == C2
        assert list(C1) == list(C2)
        assert C1 is not C2
        assert C1.coins[0] is not A  # should be a new coin
        assert C2.coins[0] is not C1.coins[0]  # should be a new coin
Example #4
0
 def val_rewards_for(
     self,
     validator: ValAddress,
     key: Optional[str] = None
 ) -> Union[ApiResponse, Coins, Dict[str, Coins]]:
     validator = validate_val_address(validator)
     res = self._api_get(f"/distribution/validators/{validator}")
     rewards = JiguBox({
         "self_bond":
         Coins.deserialize(res["self_bond_rewards"]),
         "commission":
         Coins.deserialize(res["val_commission"]),
     })
     return project(res, rewards[key] if key else rewards)
Example #5
0
 def rewards_for(self, delegator: AccAddress) -> Union[ApiResponse, dict]:
     """Get an account's delegation rewards."""
     delegator = validate_acc_address(delegator)
     res = self._api_get(f"/distribution/delegators/{delegator}/rewards")
     rewards = res["rewards"] or []
     total = Coins.from_data(res["total"])
     result = JiguBox({
         "rewards": {
             r["validator_address"]: Coins.deserialize(r["reward"])
             for r in rewards
         },
         "total": total,
     })
     return project(res, result)
Example #6
0
    def test_broadcast_txcodespacerror(self, wallet, fee, mnemonics):
        """Tests that a that it captures the correct txcodespace error."""
        fail_swap = MsgSwap(
            trader=wallet.address, offer_coin=Coin("uluna", 1), ask_denom="bebo"
        )
        fail_vote = MsgExchangeRateVote(
            exchange_rate="603.899000000000000000",
            salt="0dff",
            denom="umnt",
            feeder=wallet.address,
            validator="terravaloper1vqnhgc6d0jyggtytzqrnsc40r4zez6tx99382w",
        )
        send = MsgSend(
            from_address=wallet.address,
            to_address=mnemonics[1]["address"],
            amount=Coins(uluna=1),
        )

        tx1 = wallet.create_and_sign_tx(send, send, fail_swap, send, fail_vote, fee=fee)
        with pytest.raises(TxCodespaceError) as excinfo:
            wallet.broadcast(tx1)
        err = excinfo.value
        assert err.codespace == "market"

        tx2 = wallet.create_and_sign_tx(
            send, fail_vote, send, send, fail_swap, fail_swap, fee=fee
        )
        with pytest.raises(TxCodespaceError) as excinfo:
            wallet.broadcast(tx2)
        err = excinfo.value
        assert err.codespace == "oracle"
Example #7
0
 def from_data(cls, data: dict) -> MsgDeposit:
     data = data["value"]
     return cls(
         proposal_id=int(data["proposal_id"]),
         depositor=data["depositor"],
         amount=Coins.from_data(data["amount"]),
     )
Example #8
0
 def from_data(cls, data: dict) -> MsgSend:
     data = data["value"]
     amount = Coins.from_data(data["amount"])
     return cls(
         from_address=data["from_address"],
         to_address=data["to_address"],
         amount=amount,
     )
Example #9
0
 def from_data(cls, data: dict) -> CommunityPoolSpendProposal:
     data = data["value"]
     return cls(
         title=data["title"],
         description=data["description"],
         recipient=data["recipient"],
         amount=Coins.from_data(data["amount"]),
     )
Example #10
0
 def from_data(cls, data: dict) -> MsgSubmitProposal:
     data = data["value"]
     p_type = PROPOSAL_TYPES[data["content"]["type"]]
     content = p_type.from_data(data["content"])
     return cls(
         content=content,
         initial_deposit=Coins.from_data(data["initial_deposit"]),
         proposer=data["proposer"],
     )
Example #11
0
 def deposit_params(
         self,
         key: str = None
 ) -> Union[ApiResponse, Dict[str, Union[int, Coins]]]:
     res = self._api_get(f"/gov/parameters/deposit")
     p = JiguBox(res)
     p["min_deposit"] = Coins.deserialize(p["min_deposit"])
     p["max_deposit_period"] = int(p["max_deposit_period"])
     return project(res, p[key] if key else p)
Example #12
0
 def deposits_for(self,
                  proposal_id: int) -> Union[ApiResponse, Dict[str, Coins]]:
     """Get the proposal's deposits."""
     res = self._api_get(f"/gov/proposals/{proposal_id}/deposits")
     ds = res or []
     deposits = JiguBox({})
     for d in ds:
         deposits[d["depositor"]] = Coins.deserialize(d["amount"])
     return project(res, deposits)
Example #13
0
    def test_getitem(self):
        """sdk.Coins object should act like a dict, and indexable by denom as key."""

        X = Coins([Coin("A", 1000), Coin("B", 2000), Coin("C", 3000)])
        assert all(isinstance(X[i], Coin) for i in ["A", "B", "C"])
        assert X["A"] == Coin("A", 1000)
        assert X["B"] == Coin("B", 2000)
        assert X["C"] == Coin("C", 3000)
        with pytest.raises(KeyError):
            X["D"]
Example #14
0
    def test_contains_denom(self):
        """The `in` operator in Python should allow a user to query whether a Coin of a specified denom
        exists in the sdk.Coins object."""

        haystack = Coins(
            [Coin("A", 1000), Coin("B", 500), Coin("needle", 250), Coin("C", 125)]
        )
        assert "needle" in haystack
        assert "B" in haystack
        assert "D" not in haystack
Example #15
0
 def from_data(cls, data: dict) -> Proposal:
     final_tally_result = data["final_tally_result"]
     for key in final_tally_result:
         final_tally_result[key] = Coin(uLuna, int(final_tally_result[key]))
     p_type = PROPOSAL_TYPES[data["content"]["type"]]
     content = p_type.from_data(data["content"])
     return cls(
         content=content,
         id=int(data["id"]),
         proposal_status=ProposalStatus(data["proposal_status"]),
         final_tally_result=JiguBox(final_tally_result),
         submit_time=Timestamp.from_data(data["submit_time"]),
         deposit_end_time=Timestamp.from_data(data["deposit_end_time"]),
         total_deposit=Coins.from_data(data["total_deposit"]),
         voting_start_time=Timestamp.from_data(data["voting_start_time"]),
         voting_end_time=Timestamp.from_data(data["voting_end_time"]),
     )
Example #16
0
    def __init__(
        self,
        chain_id: str,
        lcd_url: str,
        ws_url: str = None,
        gas_prices: Coins = None,
        gas_adjustment: Union[float, str] = "1.4",  # sensible defaults
    ):
        gas_prices = gas_prices or Coins(uluna="0.015")  # sensible defaults

        self.gas_prices = gas_prices
        self.gas_adjustment = gas_adjustment

        # LCD APIs
        self.lcd = LcdClient(self, lcd_url)

        # LCD module APIs
        self._auth = AuthApi(self)
        self._bank = BankApi(self)
        self._supply = SupplyApi(self)
        self._distribution = DistributionApi(self)
        self._staking = StakingApi(self)
        self._slashing = SlashingApi(self)
        self._oracle = OracleApi(self)
        self._market = MarketApi(self)
        self._treasury = TreasuryApi(self)
        self._gov = GovApi(self)

        # LCD lower-level APIs
        self._tendermint = TendermintApi(self)
        self._tx = TxApi(self)

        # LCD query APIs
        self._blocks = jigu.client.object_query.BlocksQuery(self)

        # if no chain_id, trust the node's chain_id
        if chain_id is None:
            # TODO: add warning if not same!
            self.chain_id = self.node_info()["node_info"]["network"]
        else:
            self.chain_id = chain_id

        # WebSocket APIs
        self.ws = WebSocketClient(self, ws_url)
Example #17
0
def test_multisend(master_key2):
    """This test highlights how Jigu is flexible to accomodate many input styles."""

    multisend = MsgMultiSend(
        inputs=[
            Input(
                address=master_key2.acc_address,
                coins=[
                    Coin("uluna", 1_000_000),
                    Coin(denom="usdr", amount="1000000")
                ],
            )
        ],
        outputs=[
            Output("terra12dazwl3yq6nwrce052ah3fudkarglsgvacyvl9",
                   [Coin("uluna", 500000)]),
            {
                "address": "terra1ptdx6akgk7wwemlk5j73artt5t6j8am08ql3qv",
                "coins":
                Coins() + Coin("uluna", 500000) + Coin("usdr", 1000000),
            },
        ],
    )

    unsigned = StdSignMsg(
        account_number=47,
        sequence=0,
        chain_id="columbus-3-testnet",
        msgs=[multisend],
        fee=StdFee.make(100_000, uluna=1500, usdr=1000),
        memo="1234",
    )

    tx = master_key2.sign_tx(unsigned)

    assert (
        tx.signatures[0].signature ==
        "YA/ToXLxuuAOQlpm5trbIUu2zv5NfBmeHz2jmXgNrt8jP+odukerfri3DUXAJuhETAMHVVV78t7Q4xC0j+CVkA=="
    )
Example #18
0
 def test_make_proposal(self, wallet, fee):
     e = MsgSubmitProposal(
         content=ParameterChangeProposal(
             "testing params",
             "yay!",
             changes={
                 "distribution": {
                     "community_tax": Dec(0),
                     "base_proposer_reward": Dec(32),
                     "bonus_proposer_reward": Dec(22),
                     "withdraw_addr_enabled": True,
                 },
                 "staking": {
                     "unbonding_time": 33,
                     "max_validators": 9999,
                     "max_entries": 2323,
                     "bond_denom": "uluna",
                 },
                 "slashing": {
                     "max_evidence_age": 234234,
                     "signed_blocks_window": 1,
                     "min_signed_per_window": Dec(1),
                     "downtime_jail_duration": 1,
                     "SlashFractionDoubleSign": Dec(100),
                     "slash_fraction_downtime": Dec(213.123),
                 },
                 "treasury": {
                     "tax_policy": PolicyConstraints(
                         rate_min=Dec(0),
                         rate_max=Dec(100),
                         cap=Coin("unused", 0),
                         change_max=Dec(3),
                     ),
                     "reward_policy": PolicyConstraints(
                         rate_min=Dec(0),
                         rate_max=Dec(1023423340),
                         cap=Coin("unused", 0),
                         change_max=Dec(3),
                     ),
                     "seigniorage_burden_target": Dec("2342.234234"),
                     "mining_increment": Dec(23423423423.234234234234982),
                     "window_short": 50,
                     "window_long": 2,
                     "window_probation": 30,
                 },
                 "oracle": {
                     "vote_period": 345345,
                     "vote_threshold": Dec("2342.234333"),
                     "reward_band": Dec("234343"),
                     "reward_distribution_window": 345345,
                     "whitelist": ["abc", "bdc", "ttt"],
                     "slash_fraction": Dec(23423.232343),
                     "slash_window": 343311,
                     "min_valid_per_window": Dec(2342.234234),
                 },
                 "market": {
                     "pool_recovery_period": 234234234,
                     "base_pool": Dec(232323232),
                     "min_spread": Dec(343434),
                     "illiquid_tobin_tax_list": [{"denom": "item", "msg": "sdfsdf"}],
                 },
                 "gov": {
                     "deposit_params": {
                         "min_deposit": Coins(uluna=2, ukrw=5),
                         "max_deposit_period": 30434,
                     },
                     "voting_params": {"voting_period": 434243234},
                     "tallyparams": {
                         "quorum": Dec(234234.2334),
                         "threshold": Dec(23423.2323),
                         "veto": Dec(1232.234),
                     },
                 },
             },
         ),
         initial_deposit=Coins(uluna=10000000),
         proposer=wallet.address,
     )
     print(wallet.address)
     print(wallet.account_number, wallet.sequence)
     tx = wallet.create_and_sign_tx(e, fee=fee)
     res = wallet.broadcast(tx)
Example #19
0
 def from_data(cls, data: dict) -> MultiSendIO:
     return cls(address=data["address"],
                coins=Coins.from_data(data["coins"]))
Example #20
0
 def test_converts_to_sorted_list(self):
     """sdk.Coins object should convert to sorted List[Coin] by alphabetic denom."""
     A = Coins([Coin("Z", 500), Coin("A", 1000)])
     B = [Coin("A", 1000), Coin("Z", 500)]
     assert list(A) == B
Example #21
0
 def community_pool(
         self,
         denom: Optional[str] = None) -> Union[ApiResponse, Coin, Coins]:
     res = self._api_get("/distribution/community_pool")
     cp = Coins.deserialize(res)
     return project(res, cp[denom] if denom else cp)
Example #22
0
 def tax_proceeds(self,
                  denom: Optional[str] = None) -> Union[ApiResponse, Coins]:
     res = self._api_get("/treasury/tax_proceeds")
     tax_proceeds = Coins.deserialize(res)
     return project(res, tax_proceeds[denom] if denom else tax_proceeds)
Example #23
0
 def exchange_rates(self) -> Union[ApiResponse, Coins]:
     """Gets all exchange rates."""
     res = self._api_get("/oracle/denoms/exchange_rates")
     return project(res, Coins.from_data(res))
Example #24
0
 def __init__(self, address: AccAddress, coins: Coins):
     address = validate_acc_address(address)
     self.address = address
     self.coins = Coins(coins)
Example #25
0
 def balance_for(self, address: AccAddress) -> Union[ApiResponse, Coins]:
     """Get's the balance of an account by its address."""
     address = validate_acc_address(address)
     res = self._api_get(f"/bank/balances/{address}")
     return project(res, Coins.deserialize(res))
Example #26
0
 def __post_init__(self):
     self.depositor = validate_acc_address(self.depositor)
     self.amount = Coins(self.amount)
Example #27
0
 def __post_init__(self):
     self.proposer = validate_acc_address(self.proposer)
     self.initial_deposit = Coins(self.initial_deposit)
Example #28
0
 def __post_init__(self):
     self.from_address = validate_acc_address(self.from_address)
     self.to_address = validate_acc_address(self.to_address)
     self.amount = Coins(self.amount)