class Bluzelle::Swarm::Cosmos
Attributes
account_info[RW]
address[R]
chain_id[R]
endpoint[R]
mnemonic[R]
Public Class Methods
new(options = {})
click to toggle source
# File lib/bluzelle/swarm/cosmos.rb, line 17 def initialize(options = {}) @mnemonic = options[:mnemonic] @chain_id = options[:chain_id] @endpoint = options[:endpoint] @account_info = {} @private_key = get_ec_private_key(@mnemonic) @address = address_from_mnemonic account end
Public Instance Methods
query(endpoint)
click to toggle source
# File lib/bluzelle/swarm/cosmos.rb, line 29 def query(endpoint) Request.execute(method: 'get', url: "#{@endpoint}/#{endpoint}") end
send_transaction(method, endpoint, data, gas_info)
click to toggle source
# File lib/bluzelle/swarm/cosmos.rb, line 33 def send_transaction(method, endpoint, data, gas_info) txn = Transaction.new(method, endpoint, data) txn.set_gas(gas_info) # fetch skeleton skeleton = fetch_txn_skeleton(txn) # set gas skeleton = update_gas(txn, skeleton) # sort skeleton = sort_hash(skeleton) broadcast_transaction(Transaction.new('post', TX_COMMAND, skeleton)) end
Private Instance Methods
account()
click to toggle source
Account query
# File lib/bluzelle/swarm/cosmos.rb, line 50 def account url = "#{@endpoint}/auth/accounts/#{@address}" res = Request.execute(method: 'get', url: url) set_account_details(res.dig('result', 'value')) end
address_from_mnemonic()
click to toggle source
Check if address and mnemonic are valid
# File lib/bluzelle/swarm/cosmos.rb, line 115 def address_from_mnemonic pub_key = get_ec_public_key_from_priv(@private_key) get_address(pub_key) end
broadcast_transaction(txn)
click to toggle source
Broadcasts a transaction
@param [Bluzelle::Swarm::Transaction] txn
# File lib/bluzelle/swarm/cosmos.rb, line 60 def broadcast_transaction(txn) txn.data['memo'] = make_random_string txn.data['signatures'] = [{ 'account_number' => @account_info['account_number'].to_s, 'pub_key' => { 'type' => 'tendermint/PubKeySecp256k1', 'value' => to_base64( [compressed_pub_key(open_key(@private_key))].pack('H*') ) }, 'sequence' => @account_info['sequence'].to_s, 'signature' => sign_transaction(txn.data) }] url = "#{@endpoint}/#{txn.endpoint}" payload = { 'mode' => 'block', 'tx' => txn.data } res = Request.execute(method: txn.method, url: url, payload: payload) if res.dig('code').nil? update_sequence decode_json(hex_to_bin(res.dig('data'))) if res.key?('data') else handle_broadcast_error(res.dig('raw_log'), txn) end end
fetch_txn_skeleton(txn)
click to toggle source
Fetch transaction skeleton
# File lib/bluzelle/swarm/cosmos.rb, line 101 def fetch_txn_skeleton(txn) url = "#{@endpoint}/#{txn.endpoint}" data = Request.execute( method: txn.method, url: url, payload: txn.data, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } ) data['value'] end
handle_broadcast_error(raw_log, txn)
click to toggle source
Handle broadcast error
@param [String] raw_log @param [Bluzelle::Swarm::Transaction] txn
# File lib/bluzelle/swarm/cosmos.rb, line 152 def handle_broadcast_error(raw_log, txn) if raw_log.include?('signature verification failed') update_account_sequence(txn) else raise Error::ApiError, extract_error_message(raw_log) end end
retry_broadcast(txn)
click to toggle source
Retry broadcast after failure
@param [Bluzelle::Swarm::Transaction]
# File lib/bluzelle/swarm/cosmos.rb, line 140 def retry_broadcast(txn) txn.retries_left -= 1 sleep BROADCAST_RETRY_SECONDS broadcast_transaction(txn) end
set_account_details(data)
click to toggle source
Updates account details
@param [Hash] data
# File lib/bluzelle/swarm/cosmos.rb, line 123 def set_account_details(data) account_number = data.dig('account_number') sequence = data.dig('sequence') @account_info['account_number'] = account_number if @account_info['sequence'] != sequence @account_info['sequence'] = sequence return true end false end
sign_transaction(txn)
click to toggle source
Signs a transaction
@param txn
# File lib/bluzelle/swarm/cosmos.rb, line 168 def sign_transaction(txn) payload = { 'account_number' => @account_info['account_number'].to_s, 'chain_id' => @chain_id, 'fee' => txn['fee'], 'memo' => txn['memo'], 'msgs' => txn['msg'], 'sequence' => @account_info['sequence'].to_s } to_base64(ecdsa_sign(encode_json(payload), @private_key)) end
update_account_sequence(txn)
click to toggle source
Updates account sequence and retries broadcast
@param [Bluzelle::Swarm::Transaction] txn
# File lib/bluzelle/swarm/cosmos.rb, line 91 def update_account_sequence(txn) if txn.retries_left != 0 account retry_broadcast(txn) else raise Error::ApiError, 'Invalid chain id' end end
update_gas(txn, data)
click to toggle source
# File lib/bluzelle/swarm/cosmos.rb, line 181 def update_gas(txn, data) res = data.clone if res.dig('fee', 'gas').to_i > txn.max_gas && txn.max_gas != 0 res['fee']['gas'] = txn.max_gas.to_s end if !txn.max_fee.nil? res['fee']['amount'] = [{ 'denom': TOKEN_NAME, 'amount': txn.max_fee.to_s }] elsif !txn.gas_price.nil? res['fee']['amount'] = [{ 'denom': TOKEN_NAME, 'amount': (res['fee']['gas'] * txn.gas_price).to_s }] end res end
update_memo(txn)
click to toggle source
# File lib/bluzelle/swarm/cosmos.rb, line 203 def update_memo(txn) txn['memo'] = make_random_string txn end
update_sequence()
click to toggle source
Update account sequence
# File lib/bluzelle/swarm/cosmos.rb, line 161 def update_sequence @account_info['sequence'] = @account_info['sequence'].to_i + 1 end