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)] )
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)
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
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)
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)
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"
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"]), )
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, )
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"]), )
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"], )
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)
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)
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"]
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
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"]), )
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)
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==" )
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)
def from_data(cls, data: dict) -> MultiSendIO: return cls(address=data["address"], coins=Coins.from_data(data["coins"]))
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
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)
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)
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))
def __init__(self, address: AccAddress, coins: Coins): address = validate_acc_address(address) self.address = address self.coins = Coins(coins)
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))
def __post_init__(self): self.depositor = validate_acc_address(self.depositor) self.amount = Coins(self.amount)
def __post_init__(self): self.proposer = validate_acc_address(self.proposer) self.initial_deposit = Coins(self.initial_deposit)
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)