def unbonding_delegations( self, delegator: Optional[AccAddress] = None, validator: Optional[ValAddress] = None, ) -> Union[ApiResponse, List[UnbondingDelegation]]: if delegator is not None and validator is not None: delegator = validate_acc_address(delegator) validator = validate_val_address(validator) res = self._api_get( f"/staking/delegators/{delegator}/unbonding_delegations/{validator}" ) return project(res, [UnbondingDelegation.deserialize(res)]) elif delegator: delegator = validate_acc_address(delegator) res = self._api_get( f"/staking/delegators/{delegator}/unbonding_delegations" ) elif validator: validator = validate_val_address(validator) res = self._api_get( f"/staking/validators/{validator}/unbonding_delegations" ) else: raise TypeError("arguments delegator and validator cannot both be None") return project(res, [UnbondingDelegation.deserialize(delgn) for delgn in res])
def signing_info_by_address(self, address: str = None): if address: validate_val_consaddress(address) res = self._api_get("/slashing/signing_infos") infos = [to_signing_info(r) for r in res] by_address = JiguBox({info.address: info for info in infos}) return project(res, by_address[address] if address else by_address)
def exchange_rate(self, denom: str) -> Union[ApiResponse, Coin]: """Gets the exchange rate of LUNA against one denomination.""" res = self.exchange_rates() if denom not in res: raise DenomNotFound( f"denom '{denom}' not found, available denoms: {res.denoms}") return project(res, res[denom])
def votes_for(self, proposal_id: str) -> Union[ApiResponse, dict]: res = self._api_get(f"/gov/proposals/{proposal_id}/votes") vs = res or [] votes = JiguBox({}) for v in vs: votes[v["voter"]] = v["option"] return project(res, votes)
def node_info(self) -> Union[ApiResponse, JiguBox]: """Get information for the node. Returns: Node information with the following schema. """ res = self._api_get("/node_info", unwrap=False) return project(res, JiguBox(res))
def tally_for(self, proposal_id: str) -> Union[ApiResponse, Dict[str, Coin]]: res = self._api_get(f"/gov/proposals/{proposal_id}/tally") denoms = res or [] tally = JiguBox({}) for denom in denoms: tally[denom] = Coin(uLuna, int(res[denom])) return project(res, JiguBox(tally))
def validators( self, status: Optional[str] = None ) -> Union[ApiResponse, List[Validator]]: params = dict() if status is not None: params["status"] = status res = self._api_get("/staking/validators", params=params) return project(res, [Validator.deserialize(v) for v in res])
def syncing(self) -> Union[ApiResponse, bool]: """Get whether the node is currently syncing with updates on the blockchain. Returns: If node is syncing. """ res = self._api_get("/syncing", unwrap=False) return project(res, res["syncing"])
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 rewards( self, validator: Optional[ValAddress] = None ) -> Union[ApiResponse, Dict[ValAddress, Coins], Coins]: if validator: validator = validate_val_address(validator) res = self.terra.distribution.rewards_for(delegator=self.address) rewards = res["rewards"] return project(res, rewards[validator] if validator else rewards)
def supply(self, denom: Optional[str] = None): total_supply = self._supply.total() if denom is None: return total_supply if denom not in total_supply: raise DenomNotFound( f"denom '{denom}' was not found, avaialble denoms are: {total_supply.denoms}" ) return project(total_supply, total_supply[denom])
def params( self, key: Optional[str] = None) -> Union[ApiResponse, dict, Dec, bool]: res = self._api_get("/distribution/parameters") p = res p["community_tax"] = Dec(p["community_tax"]) p["base_proposer_reward"] = Dec(p["base_proposer_reward"]) p["bonus_proposer_reward"] = Dec(p["bonus_proposer_reward"]) return project(res, p[key] if key else JiguBox(p))
def tally_params(self, key: str = None) -> Union[ApiResponse, Dict[str, Dec]]: res = self._api_get(f"/gov/parameters/tallying") p = JiguBox(res, box_recast={ "quorum": Dec, "threshold": Dec, "veto": Dec }) return project(res, p[key] if key else p)
def pool( self, key: Optional[str] = None ) -> Union[ApiResponse, Coin, JiguBox[str, Coin]]: res = self._api_get("/staking/pool") pool = JiguBox( { "bonded": Coin(uLuna, res["bonded_tokens"]), "not_bonded": Coin(uLuna, res["not_bonded_tokens"]), } ) return project(res, pool[key] if key else pool)
def params(self, key: Optional[str] = None) -> Union[ApiResponse, Dec, dict]: res = self._api_get("/market/parameters") p = JiguBox(res) p["pool_recovery_period"] = int(p["pool_recovery_period"]) p["base_pool"] = Dec.deserialize(p["base_pool"]) p["min_spread"] = Dec.deserialize(p["min_spread"]) p["tobin_tax"] = Dec.deserialize(p["tobin_tax"]) ill = p["illiquid_tobin_tax_list"] p["illiquid_tobin_tax_list"] = JiguBox({}) for item in ill: p["illiquid_tobin_tax_list"][item["denom"]] = Dec(item["tax_rate"]) return project(res, p[key] if key else p)
def swap_rate(self, offer_coin: Coin, ask_denom: str) -> Union[ApiResponse, Coin]: if type(offer_coin.amount) != int: warnings.warn( f"Coin's amount will be converted to integer: {int(offer_coin.amount)} {offer_coin.denom}", SyntaxWarning, ) params = { "offer_coin": f"{int(offer_coin.amount)}{offer_coin.denom}", "ask_denom": ask_denom, } res = self._api_get(f"/market/swap", params=params) return project(res, Coin.deserialize(res))
def params(self, key: str = None): """Puts all the parameters together.""" deposit = self.deposit_params() voting = self.voting_params() tally = self.tally_params() p = JiguBox({ "deposit_params": deposit, "voting_params": voting, "tally_params": tally }) return project( # use response information of last entry, even if there is a delay tally, p[key] if key else p)
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 params(self, key: Optional[str] = None) -> Union[int, Dec, dict]: res = self._api_get("/slashing/parameters") p = JiguBox( res, box_recast={ "max_evidence_age": int, "signed_blocks_window": int, "min_signed_per_window": Dec, "downtime_jail_duration": int, "slash_fraction_double_sign": Dec, "slash_fraction_downtime": Dec, }, ) return project(res, p[key] if key else p)
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 block(self, height=None) -> Union[ApiResponse, dict]: """Get the raw block data at a height on the blockchain. Args: height (int, optional): block height Returns: - The block at the provided height. If no height was specified, get the latest block at the time of calling. """ if height: res = self._api_get(f"/blocks/{height}", unwrap=False) else: res = self._api_get("/blocks/latest", unwrap=False) return project(res, JiguBox(res))
def params( self, key: Optional[str] = None) -> Union[ApiResponse, Dec, int, dict]: res = self._api_get("/treasury/parameters") p = JiguBox( res, box_recast={ "seigniorage_burden_target": Dec, "mining_increment": Dec, "window_short": int, "window_long": int, "window_probation": int, }, ) p["tax_policy"] = PolicyConstraints.deserialize(p["tax_policy"]) p["reward_policy"] = PolicyConstraints.deserialize(p["reward_policy"]) return project(res, p[key] if key else p)
def acc_info_for( self, address: AccAddress ) -> Union[ApiResponse, account_info_type]: address = validate_acc_address(address) info = self._api_get(f"/auth/accounts/{address}") if info["type"] == "core/Account": res = Account.from_data(info) elif info["type"] == "core/LazyGradedVestingAccount": res = LazyGradedVestingAccount.from_data(info) else: raise ValueError("could not deserialize account in auth.acc_info") if res.address is None: warnings.warn( "Account was not found; perhaps wrong chain or account needs to first be sent funds.", AccountNotFoundWarning, ) return project(info, res)
def redelegations( self, delegator: Optional[AccAddress] = None, validator_src: Optional[ValAddress] = None, validator_dst: Optional[ValAddress] = None, ) -> Union[ApiResponse, List[Redelegation]]: params = {} if delegator: delegator = validate_acc_address(delegator) params["delegator"] = delegator if validator_src: validator_src = validate_val_address(validator_src) params["validator_from"] = validator_src if validator_dst: validator_dst = validate_val_address(validator_dst) params["validator_to"] = validator_dst res = self._api_get(f"/staking/redelegations", params=params) return project(res, [Redelegation.deserialize(rd) for rd in res])
def params( self, key: Optional[str] = None ) -> Union[ApiResponse, dict, int, Dec, List[str]]: res = self._api_get("/oracle/parameters") p = JiguBox( res, box_recast={ "vote_period": int, "vote_threshold": Dec, "reward_band": Dec, "reward_distribution_window": int, "slash_fraction": Dec, "slash_window": int, "min_valid_per_window": Dec, }, ) return project(res, p[key] if key else p)
def prevotes( self, validator: Optional[ValAddress] = None, denom: Optional[str] = None ) -> Union[ApiResponse, List[ExchangeRatePrevote]]: if validator is not None and denom is not None: validator = validate_val_address(validator) res = self._api_get(f"/oracle/denoms/{denom}/prevotes/{validator}") elif validator: validator = validate_val_address(validator) res = self._api_get(f"/oracle/voters/{validator}/prevotes") elif denom: res = self._api_get(f"/oracle/denoms/{denom}/prevotes") else: raise ValueError( "arguments validator and denom cannot both be None") return project( res, [ExchangeRatePrevote.deserialize(prevote) for prevote in res])
def validator_set(self, height=None) -> Union[ApiResponse, dict]: """Retrieves the current set of validators in the actively validating set. ## Arguments - **height** `int` *optional* block height ## Returns List of `dict` with the following keys: - **address** `ValConsAddress` validator's consensus address - **pub_key** `ValConsPubKey` validator's consensus public key - **proposer_priority** `int` - **voting_power** `int` """ if height: res = self._api_get(f"/validatorsets/{height}") else: res = self._api_get("/validatorsets/latest") vs = res["validators"] results = [] for v in vs: results.append( JiguBox({ "address": v["address"], "pub_key": v["pub_key"], "proposer_priority": int(v["proposer_priority"]), "voting_power": int(v["voting_power"]), })) return project(res, results)
def params(self, key: Optional[str] = None) -> Union[ApiResponse, JiguBox]: res = self._api_get("/staking/parameters") p = JiguBox(res, box_recast={"unbonding_time": int}) return project(res, p[key] if key else p)
def val_info_for(self, validator: ValAddress) -> Union[ApiResponse, Validator]: validator = validate_val_address(validator) res = self._api_get(f"/staking/validators/{validator}") return project(res, Validator.deserialize(res))