Class: IcAgent::Agent
- Inherits:
-
Object
- Object
- IcAgent::Agent
- Defined in:
- lib/ic_agent/agent.rb
Instance Attribute Summary collapse
-
#client ⇒ Object
Returns the value of attribute client.
-
#identity ⇒ Object
Returns the value of attribute identity.
-
#ingress_expiry ⇒ Object
Returns the value of attribute ingress_expiry.
-
#nonce_factory ⇒ Object
Returns the value of attribute nonce_factory.
-
#root_key ⇒ Object
Returns the value of attribute root_key.
Instance Method Summary collapse
- #call_endpoint(canister_id, request_id, data) ⇒ Object
- #get_expiry_date ⇒ Object
- #get_principal ⇒ Object
-
#initialize(identity, client, nonce_factory = nil, ingress_expiry = 300, root_key = IcAgent::IC_ROOT_KEY) ⇒ Agent
constructor
A new instance of Agent.
- #poll(canister_id, req_id, delay = 1, timeout = IcAgent::DEFAULT_POLL_TIMEOUT_SECS) ⇒ Object
- #query_endpoint(canister_id, data) ⇒ Object
- #query_raw(canister_id, method_name, arg, return_type = nil, effective_canister_id = nil) ⇒ Object
- #read_state_endpoint(canister_id, data) ⇒ Object
- #read_state_raw(canister_id, paths) ⇒ Object
- #request_status_raw(canister_id, req_id) ⇒ Object
- #update_raw(canister_id, method_name, arg, return_type = nil, effective_canister_id = nil, **kwargs) ⇒ Object
Constructor Details
#initialize(identity, client, nonce_factory = nil, ingress_expiry = 300, root_key = IcAgent::IC_ROOT_KEY) ⇒ Agent
Returns a new instance of Agent.
29 30 31 32 33 34 35 |
# File 'lib/ic_agent/agent.rb', line 29 def initialize(identity, client, nonce_factory = nil, ingress_expiry = 300, root_key = IcAgent::IC_ROOT_KEY) @identity = identity @client = client @ingress_expiry = ingress_expiry @root_key = root_key @nonce_factory = nonce_factory end |
Instance Attribute Details
#client ⇒ Object
Returns the value of attribute client.
27 28 29 |
# File 'lib/ic_agent/agent.rb', line 27 def client @client end |
#identity ⇒ Object
Returns the value of attribute identity.
27 28 29 |
# File 'lib/ic_agent/agent.rb', line 27 def identity @identity end |
#ingress_expiry ⇒ Object
Returns the value of attribute ingress_expiry.
27 28 29 |
# File 'lib/ic_agent/agent.rb', line 27 def ingress_expiry @ingress_expiry end |
#nonce_factory ⇒ Object
Returns the value of attribute nonce_factory.
27 28 29 |
# File 'lib/ic_agent/agent.rb', line 27 def nonce_factory @nonce_factory end |
#root_key ⇒ Object
Returns the value of attribute root_key.
27 28 29 |
# File 'lib/ic_agent/agent.rb', line 27 def root_key @root_key end |
Instance Method Details
#call_endpoint(canister_id, request_id, data) ⇒ Object
57 58 59 60 |
# File 'lib/ic_agent/agent.rb', line 57 def call_endpoint(canister_id, request_id, data) @client.call(canister_id, request_id, data) request_id end |
#get_expiry_date ⇒ Object
41 42 43 |
# File 'lib/ic_agent/agent.rb', line 41 def get_expiry_date ((Time.now.to_i + @ingress_expiry) * 10**9).to_i end |
#get_principal ⇒ Object
37 38 39 |
# File 'lib/ic_agent/agent.rb', line 37 def get_principal @identity.sender end |
#poll(canister_id, req_id, delay = 1, timeout = IcAgent::DEFAULT_POLL_TIMEOUT_SECS) ⇒ Object
153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 |
# File 'lib/ic_agent/agent.rb', line 153 def poll(canister_id, req_id, delay = 1, timeout = IcAgent::DEFAULT_POLL_TIMEOUT_SECS) status = nil cert = nil (timeout / delay).to_i.times do status, cert = request_status_raw(canister_id, req_id) break if %w[replied done rejected].include?(status) sleep(delay) end if status == 'replied' path = ['request_status', req_id, 'reply'] res = IcAgent::Certificate.lookup(path, cert) [status, res] elsif status == 'rejected' path = ['request_status', req_id, 'reject_message'] msg = IcAgent::Certificate.lookup(path, cert) [status, msg] else [status, _] end end |
#query_endpoint(canister_id, data) ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/ic_agent/agent.rb', line 45 def query_endpoint(canister_id, data) ret = @client.query(canister_id, data) decode_ret = nil begin decode_ret = CBOR.decode(ret) rescue CBOR::MalformedFormatError decode_ret = ret # print logger end decode_ret end |
#query_raw(canister_id, method_name, arg, return_type = nil, effective_canister_id = nil) ⇒ Object
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
# File 'lib/ic_agent/agent.rb', line 67 def query_raw(canister_id, method_name, arg, return_type = nil, effective_canister_id = nil) req_canister_id = canister_id.is_a?(String) ? Principal.from_str(canister_id).bytes : canister_id.bytes req = { 'request_type' => 'query', 'sender' => @identity.sender.bytes, 'canister_id' => req_canister_id, 'method_name' => method_name, 'arg' => arg.hex2str, 'ingress_expiry' => get_expiry_date } _, data = Request.sign_request(req, @identity) query_canister_id = effective_canister_id.nil? ? canister_id : effective_canister_id result = query_endpoint(query_canister_id, data) raise Exception, "Malformed result: #{result}" unless result.is_a?(CBOR::Tagged) && result.value.key?('status') if result.value['status'] == 'replied' arg = result.value['reply']['arg'] if arg[0..3] == 'DIDL' IcAgent::Candid.decode(arg.to_hex, return_type) else arg end elsif result.value['status'] == 'rejected' raise Exception, "Canister reject the call: #{result['reject_message']}" end end |
#read_state_endpoint(canister_id, data) ⇒ Object
62 63 64 65 |
# File 'lib/ic_agent/agent.rb', line 62 def read_state_endpoint(canister_id, data) result = @client.read_state(canister_id, data) result end |
#read_state_raw(canister_id, paths) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
# File 'lib/ic_agent/agent.rb', line 123 def read_state_raw(canister_id, paths) req = { 'request_type' => 'read_state', 'sender' => @identity.sender.bytes, 'paths' => paths, 'ingress_expiry' => get_expiry_date } _, data = Request.sign_request(req, @identity) ret = read_state_endpoint(canister_id, data) if ret == 'Invalid path requested.' raise ValueError, 'Invalid path requested!' elsif ret == 'Could not parse body as read request: invalid type: byte array, expected a sequence' raise ValueError, 'Could not parse body as read request: invalid type: byte array, expected a sequence' end begin d = CBOR.decode(ret) rescue StandardError raise ValueError, "Unable to decode cbor value: #{ret}" end CBOR.decode(d.value['certificate']) end |
#request_status_raw(canister_id, req_id) ⇒ Object
146 147 148 149 150 151 |
# File 'lib/ic_agent/agent.rb', line 146 def request_status_raw(canister_id, req_id) paths = [['request_status', req_id]] cert = read_state_raw(canister_id, paths) status = IcAgent::Certificate.lookup(['request_status', req_id, 'status'], cert) [status, cert] end |
#update_raw(canister_id, method_name, arg, return_type = nil, effective_canister_id = nil, **kwargs) ⇒ Object
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/ic_agent/agent.rb', line 95 def update_raw(canister_id, method_name, arg, return_type = nil, effective_canister_id = nil, **kwargs) req_canister_id = canister_id.is_a?(String) ? Principal.from_str(canister_id).bytes : canister_id.bytes req = { 'request_type' => 'call', 'sender' => @identity.sender.bytes, 'canister_id' => req_canister_id, 'method_name' => method_name, 'arg' => arg.hex2str, 'ingress_expiry' => get_expiry_date } req_id, data = Request.sign_request(req, @identity) eid = effective_canister_id.nil? ? canister_id : effective_canister_id _ = call_endpoint(eid, req_id, data) status, result = poll(eid, req_id, **kwargs) if status == 'rejected' raise Exception, "Rejected: #{result.to_s}" elsif status == 'replied' if result[0..3] == 'DIDL' IcAgent::Candid.decode(result.to_hex, return_type) else # Some canisters don't use DIDL (e.g. they might encode using json instead) result end else raise Exception, "Timeout to poll result, current status: #{status.to_s}" end end |