tezos_client 0.3.9 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
 - data/.travis.yml +5 -4
 - data/Gemfile.lock +1 -1
 - data/lib/tezos_client.rb +19 -10
 - data/lib/tezos_client/exceptions.rb +92 -0
 - data/lib/tezos_client/liquidity_interface.rb +4 -2
 - data/lib/tezos_client/logger.rb +22 -0
 - data/lib/tezos_client/operation_mgr.rb +178 -0
 - data/lib/tezos_client/operations/activate_account_operation.rb +9 -27
 - data/lib/tezos_client/operations/operation.rb +33 -0
 - data/lib/tezos_client/operations/operation_array.rb +35 -0
 - data/lib/tezos_client/operations/origination_operation.rb +13 -44
 - data/lib/tezos_client/operations/reveal_operation.rb +3 -22
 - data/lib/tezos_client/operations/transaction_operation.rb +21 -24
 - data/lib/tezos_client/operations/transactions_operation.rb +24 -22
 - data/lib/tezos_client/rpc_interface.rb +2 -0
 - data/lib/tezos_client/rpc_interface/helper.rb +29 -85
 - data/lib/tezos_client/rpc_interface/operations.rb +44 -0
 - data/lib/tezos_client/rpc_interface/request_manager.rb +23 -5
 - data/lib/tezos_client/version.rb +1 -1
 - data/travis-scripts/install-liquidity.sh +2 -10
 - data/travis-scripts/install-opam.sh +11 -3
 - data/travis-scripts/prepare-ubuntu.sh +14 -0
 - metadata +8 -4
 - data/lib/tezos_client/operation.rb +0 -159
 - data/travis-scripts/prepare-trusty.sh +0 -16
 
    
        checksums.yaml
    CHANGED
    
    | 
         @@ -1,7 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
2 
     | 
    
         
             
            SHA256:
         
     | 
| 
       3 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       4 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 3 
     | 
    
         
            +
              metadata.gz: 725a3f4be32e4f23f291c0abb15ad9671bff432a3b00f4f149fbad9c8cadf007
         
     | 
| 
      
 4 
     | 
    
         
            +
              data.tar.gz: 21864905eeb5b701357551ee410c88f2e24832b31f53a1d811b0025f6410248d
         
     | 
| 
       5 
5 
     | 
    
         
             
            SHA512:
         
     | 
| 
       6 
     | 
    
         
            -
              metadata.gz:  
     | 
| 
       7 
     | 
    
         
            -
              data.tar.gz:  
     | 
| 
      
 6 
     | 
    
         
            +
              metadata.gz: 810cdd1ea762452c662bac91752c53b60756ad780989c58fa488fcb056d9907b4ac76e37907bbdb0fe7e40398badf686aa8f229033b5c53ec7a27bf07c389b9e
         
     | 
| 
      
 7 
     | 
    
         
            +
              data.tar.gz: 39b1a9bfefda07893cab407b5abdd9835603473098e6db4828847c9265358b11833e3ed160c91db6f50d0f6d52a659f38242d243a1cbc2ea112f0fccab71683e
         
     | 
    
        data/.travis.yml
    CHANGED
    
    | 
         @@ -1,8 +1,7 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            ---
         
     | 
| 
       2 
     | 
    
         
            -
            dist:  
     | 
| 
      
 2 
     | 
    
         
            +
            dist: xenial
         
     | 
| 
      
 3 
     | 
    
         
            +
            language: ruby
         
     | 
| 
       3 
4 
     | 
    
         
             
            sudo: required
         
     | 
| 
       4 
     | 
    
         
            -
            #language: ruby
         
     | 
| 
       5 
     | 
    
         
            -
            language: ocaml
         
     | 
| 
       6 
5 
     | 
    
         
             
            cache:
         
     | 
| 
       7 
6 
     | 
    
         
             
              bundler: true
         
     | 
| 
       8 
7 
     | 
    
         
             
              directories:
         
     | 
| 
         @@ -13,9 +12,11 @@ rvm: 
     | 
|
| 
       13 
12 
     | 
    
         
             
            env:
         
     | 
| 
       14 
13 
     | 
    
         
             
              - OPAMYES=1
         
     | 
| 
       15 
14 
     | 
    
         
             
            before_install:
         
     | 
| 
       16 
     | 
    
         
            -
              - sh travis-scripts/prepare- 
     | 
| 
      
 15 
     | 
    
         
            +
              - sh travis-scripts/prepare-ubuntu.sh
         
     | 
| 
       17 
16 
     | 
    
         
             
              - sh travis-scripts/install-opam.sh
         
     | 
| 
       18 
17 
     | 
    
         
             
              - sh travis-scripts/install-liquidity.sh
         
     | 
| 
       19 
18 
     | 
    
         
             
              - gem install bundler -v 1.16.3
         
     | 
| 
       20 
19 
     | 
    
         
             
            script:
         
     | 
| 
      
 20 
     | 
    
         
            +
              - eval `opam config env`
         
     | 
| 
      
 21 
     | 
    
         
            +
              - bundle install
         
     | 
| 
       21 
22 
     | 
    
         
             
              - bundle exec rake
         
     | 
    
        data/Gemfile.lock
    CHANGED
    
    
    
        data/lib/tezos_client.rb
    CHANGED
    
    | 
         @@ -3,6 +3,7 @@ 
     | 
|
| 
       3 
3 
     | 
    
         
             
            require "pp"
         
     | 
| 
       4 
4 
     | 
    
         
             
            require "active_support/core_ext/hash/indifferent_access"
         
     | 
| 
       5 
5 
     | 
    
         
             
            require "active_support/core_ext/string/inflections"
         
     | 
| 
      
 6 
     | 
    
         
            +
            require "active_support/core_ext/module/delegation"
         
     | 
| 
       6 
7 
     | 
    
         
             
            require "timeout"
         
     | 
| 
       7 
8 
     | 
    
         | 
| 
       8 
9 
     | 
    
         
             
            require "tezos_client/version"
         
     | 
| 
         @@ -11,13 +12,16 @@ require "tezos_client/currency_utils" 
     | 
|
| 
       11 
12 
     | 
    
         
             
            require "tezos_client/crypto"
         
     | 
| 
       12 
13 
     | 
    
         
             
            require "tezos_client/commands"
         
     | 
| 
       13 
14 
     | 
    
         
             
            require "tezos_client/logger"
         
     | 
| 
      
 15 
     | 
    
         
            +
            require "tezos_client/exceptions"
         
     | 
| 
       14 
16 
     | 
    
         
             
            require "tezos_client/encode_utils"
         
     | 
| 
       15 
     | 
    
         
            -
            require "tezos_client/ 
     | 
| 
      
 17 
     | 
    
         
            +
            require "tezos_client/operation_mgr"
         
     | 
| 
      
 18 
     | 
    
         
            +
            require "tezos_client/operations/operation"
         
     | 
| 
       16 
19 
     | 
    
         
             
            require "tezos_client/operations/origination_operation"
         
     | 
| 
       17 
20 
     | 
    
         
             
            require "tezos_client/operations/transaction_operation"
         
     | 
| 
       18 
21 
     | 
    
         
             
            require "tezos_client/operations/transactions_operation"
         
     | 
| 
       19 
22 
     | 
    
         
             
            require "tezos_client/operations/activate_account_operation"
         
     | 
| 
       20 
23 
     | 
    
         
             
            require "tezos_client/operations/reveal_operation"
         
     | 
| 
      
 24 
     | 
    
         
            +
            require "tezos_client/operations/operation_array"
         
     | 
| 
       21 
25 
     | 
    
         | 
| 
       22 
26 
     | 
    
         
             
            require "tezos_client/client_interface"
         
     | 
| 
       23 
27 
     | 
    
         
             
            require "tezos_client/rpc_interface"
         
     | 
| 
         @@ -72,17 +76,26 @@ class TezosClient 
     | 
|
| 
       72 
76 
     | 
    
         
             
              #
         
     | 
| 
       73 
77 
     | 
    
         
             
              # @return [Hash] result of the origination containing :operation_id, :operation_result and :originated_contract
         
     | 
| 
       74 
78 
     | 
    
         
             
              #
         
     | 
| 
       75 
     | 
    
         
            -
              def originate_contract(from:, amount:, secret_key:, **args)
         
     | 
| 
       76 
     | 
    
         
            -
                 
     | 
| 
       77 
     | 
    
         
            -
                  liquidity_interface: liquidity_interface,
         
     | 
| 
      
 79 
     | 
    
         
            +
              def originate_contract(from:, amount:, secret_key:, script: nil, init_params: nil, **args)
         
     | 
| 
      
 80 
     | 
    
         
            +
                origination_args = {
         
     | 
| 
       78 
81 
     | 
    
         
             
                  rpc_interface: rpc_interface,
         
     | 
| 
       79 
82 
     | 
    
         
             
                  from: from,
         
     | 
| 
       80 
83 
     | 
    
         
             
                  secret_key: secret_key,
         
     | 
| 
       81 
84 
     | 
    
         
             
                  amount: amount,
         
     | 
| 
       82 
85 
     | 
    
         
             
                  **args
         
     | 
| 
       83 
     | 
    
         
            -
                 
     | 
| 
      
 86 
     | 
    
         
            +
                }
         
     | 
| 
      
 87 
     | 
    
         
            +
             
     | 
| 
      
 88 
     | 
    
         
            +
                if script != nil
         
     | 
| 
      
 89 
     | 
    
         
            +
                  origination_args[:script] = liquidity_interface.origination_script(
         
     | 
| 
      
 90 
     | 
    
         
            +
                    from: from,
         
     | 
| 
      
 91 
     | 
    
         
            +
                    script: script,
         
     | 
| 
      
 92 
     | 
    
         
            +
                    init_params: init_params
         
     | 
| 
      
 93 
     | 
    
         
            +
                  )
         
     | 
| 
      
 94 
     | 
    
         
            +
                end
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                res = OriginationOperation.new(origination_args).test_and_broadcast
         
     | 
| 
       84 
97 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
                res.merge(originated_contract: res[: 
     | 
| 
      
 98 
     | 
    
         
            +
                res.merge(originated_contract: res[:operations_result][0][:originated_contracts][0])
         
     | 
| 
       86 
99 
     | 
    
         
             
              end
         
     | 
| 
       87 
100 
     | 
    
         | 
| 
       88 
101 
     | 
    
         
             
              # Transfer funds to an account
         
     | 
| 
         @@ -97,7 +110,6 @@ class TezosClient 
     | 
|
| 
       97 
110 
     | 
    
         
             
              #
         
     | 
| 
       98 
111 
     | 
    
         
             
              def transfer(from:, amount:, to:, secret_key:, **args)
         
     | 
| 
       99 
112 
     | 
    
         
             
                TransactionOperation.new(
         
     | 
| 
       100 
     | 
    
         
            -
                  liquidity_interface: liquidity_interface,
         
     | 
| 
       101 
113 
     | 
    
         
             
                  rpc_interface: rpc_interface,
         
     | 
| 
       102 
114 
     | 
    
         
             
                  from: from,
         
     | 
| 
       103 
115 
     | 
    
         
             
                  to: to,
         
     | 
| 
         @@ -109,7 +121,6 @@ class TezosClient 
     | 
|
| 
       109 
121 
     | 
    
         | 
| 
       110 
122 
     | 
    
         
             
              def activate_account(pkh:, secret:, **args)
         
     | 
| 
       111 
123 
     | 
    
         
             
                ActivateAccountOperation.new(
         
     | 
| 
       112 
     | 
    
         
            -
                  liquidity_interface: liquidity_interface,
         
     | 
| 
       113 
124 
     | 
    
         
             
                  rpc_interface: rpc_interface,
         
     | 
| 
       114 
125 
     | 
    
         
             
                  pkh: pkh,
         
     | 
| 
       115 
126 
     | 
    
         
             
                  secret: secret,
         
     | 
| 
         @@ -119,7 +130,6 @@ class TezosClient 
     | 
|
| 
       119 
130 
     | 
    
         | 
| 
       120 
131 
     | 
    
         
             
              def transfer_to_many(from:, amounts:, secret_key:, **args)
         
     | 
| 
       121 
132 
     | 
    
         
             
                TransactionsOperation.new(
         
     | 
| 
       122 
     | 
    
         
            -
                  liquidity_interface: liquidity_interface,
         
     | 
| 
       123 
133 
     | 
    
         
             
                  rpc_interface: rpc_interface,
         
     | 
| 
       124 
134 
     | 
    
         
             
                  from: from,
         
     | 
| 
       125 
135 
     | 
    
         
             
                  amounts: amounts,
         
     | 
| 
         @@ -129,7 +139,6 @@ class TezosClient 
     | 
|
| 
       129 
139 
     | 
    
         
             
              end
         
     | 
| 
       130 
140 
     | 
    
         | 
| 
       131 
141 
     | 
    
         
             
              def reveal_pubkey(secret_key:, **args)
         
     | 
| 
       132 
     | 
    
         
            -
             
     | 
| 
       133 
142 
     | 
    
         
             
                public_key = secret_key_to_public_key(secret_key)
         
     | 
| 
       134 
143 
     | 
    
         
             
                from = public_key_to_address(public_key)
         
     | 
| 
       135 
144 
     | 
    
         | 
| 
         @@ -0,0 +1,92 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            # frozen_string_literal: true
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class TezosClient
         
     | 
| 
      
 4 
     | 
    
         
            +
              class RpcRequestFailure < Exception
         
     | 
| 
      
 5 
     | 
    
         
            +
                include Logger
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                attr_reader :status_code
         
     | 
| 
      
 8 
     | 
    
         
            +
                attr_reader :error
         
     | 
| 
      
 9 
     | 
    
         
            +
                attr_reader :formatted_response
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize(error:, url:, status_code:)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @status_code = status_code
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @error = error
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @formatted_response = formatted_response
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                  if @message.nil?
         
     | 
| 
      
 17 
     | 
    
         
            +
                    @message = "#{url} failed with status #{status_code}:\n #{tezos_contents_log(formatted_response)}"
         
     | 
| 
      
 18 
     | 
    
         
            +
                  end
         
     | 
| 
      
 19 
     | 
    
         
            +
             
     | 
| 
      
 20 
     | 
    
         
            +
                  super @message
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
              class InvalidActivation < RpcRequestFailure
         
     | 
| 
      
 25 
     | 
    
         
            +
                attr_reader :pkh
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def initialize(error:, **_args)
         
     | 
| 
      
 28 
     | 
    
         
            +
                  @pkh = error[:pkh]
         
     | 
| 
      
 29 
     | 
    
         
            +
                  @message = "Invalid activation (pkh: #{pkh})"
         
     | 
| 
      
 30 
     | 
    
         
            +
                  super
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
              class OperationFailure < Exception
         
     | 
| 
      
 35 
     | 
    
         
            +
                include Logger
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                attr_reader :metadata
         
     | 
| 
      
 38 
     | 
    
         
            +
                attr_reader :errors
         
     | 
| 
      
 39 
     | 
    
         
            +
                attr_reader :status
         
     | 
| 
      
 40 
     | 
    
         
            +
                attr_reader :message
         
     | 
| 
      
 41 
     | 
    
         
            +
             
     | 
| 
      
 42 
     | 
    
         
            +
                def initialize(metadata:, errors:, status:)
         
     | 
| 
      
 43 
     | 
    
         
            +
                  @metadata = metadata
         
     | 
| 
      
 44 
     | 
    
         
            +
                  @errors = errors
         
     | 
| 
      
 45 
     | 
    
         
            +
                  @status = status
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
                  error = errors[0]
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                  if @message.nil?
         
     | 
| 
      
 50 
     | 
    
         
            +
                    @message = "failure #{status}: #{tezos_contents_log(error).pretty_inspect}"
         
     | 
| 
      
 51 
     | 
    
         
            +
                  end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                  super(message)
         
     | 
| 
      
 54 
     | 
    
         
            +
                end
         
     | 
| 
      
 55 
     | 
    
         
            +
              end
         
     | 
| 
      
 56 
     | 
    
         
            +
             
     | 
| 
      
 57 
     | 
    
         
            +
              class TezBalanceTooLow < OperationFailure
         
     | 
| 
      
 58 
     | 
    
         
            +
                attr_reader :contract
         
     | 
| 
      
 59 
     | 
    
         
            +
                attr_reader :balance
         
     | 
| 
      
 60 
     | 
    
         
            +
                attr_reader :amount
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                def initialize(metadata:, errors:, status:)
         
     | 
| 
      
 63 
     | 
    
         
            +
                  error = errors[0]
         
     | 
| 
      
 64 
     | 
    
         
            +
                  @contract = error[:contract]
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @balance = error[:balance]
         
     | 
| 
      
 66 
     | 
    
         
            +
                  @amount = error[:amount]
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                  @message = "Tezos balance too low for address #{contract} (balance: #{balance}, amount #{amount})"
         
     | 
| 
      
 69 
     | 
    
         
            +
             
     | 
| 
      
 70 
     | 
    
         
            +
                  super
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
              end
         
     | 
| 
      
 73 
     | 
    
         
            +
             
     | 
| 
      
 74 
     | 
    
         
            +
              class ScriptRuntimeError < OperationFailure
         
     | 
| 
      
 75 
     | 
    
         
            +
                attr_reader :location
         
     | 
| 
      
 76 
     | 
    
         
            +
                attr_reader :with
         
     | 
| 
      
 77 
     | 
    
         
            +
                attr_reader :contract
         
     | 
| 
      
 78 
     | 
    
         
            +
             
     | 
| 
      
 79 
     | 
    
         
            +
                def initialize(metadata:, errors:, status:)
         
     | 
| 
      
 80 
     | 
    
         
            +
                  error = errors[0]
         
     | 
| 
      
 81 
     | 
    
         
            +
                  rejection_error = errors.detect { |error| error[:id] == "proto.003-PsddFKi3.scriptRejectedRuntimeError" }
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  @location = rejection_error[:location]
         
     | 
| 
      
 84 
     | 
    
         
            +
                  @contract =  error[:contractHandle]
         
     | 
| 
      
 85 
     | 
    
         
            +
                  @with = rejection_error[:with]
         
     | 
| 
      
 86 
     | 
    
         
            +
                  @message = "Script runtime Error when executing #{contract}: #{with} (location: #{location})"
         
     | 
| 
      
 87 
     | 
    
         
            +
                  super
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
              end
         
     | 
| 
      
 90 
     | 
    
         
            +
             
     | 
| 
      
 91 
     | 
    
         
            +
             
     | 
| 
      
 92 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -57,8 +57,10 @@ class TezosClient 
     | 
|
| 
       57 
57 
     | 
    
         | 
| 
       58 
58 
     | 
    
         
             
                def json_scripts(args)
         
     | 
| 
       59 
59 
     | 
    
         
             
                  with_file_copy(args[:script]) do |script_copy_path|
         
     | 
| 
       60 
     | 
    
         
            -
                     
     | 
| 
       61 
     | 
    
         
            -
             
     | 
| 
      
 60 
     | 
    
         
            +
                    script_basename = script_copy_path.sub(/.liq$/, "")
         
     | 
| 
      
 61 
     | 
    
         
            +
             
     | 
| 
      
 62 
     | 
    
         
            +
                    json_init_script_path = "#{script_basename}.initializer.tz.json"
         
     | 
| 
      
 63 
     | 
    
         
            +
                    json_contract_script_path = "#{script_basename}.tz.json"
         
     | 
| 
       62 
64 
     | 
    
         | 
| 
       63 
65 
     | 
    
         
             
                    call_liquidity "--json #{script_copy_path}"
         
     | 
| 
       64 
66 
     | 
    
         | 
    
        data/lib/tezos_client/logger.rb
    CHANGED
    
    | 
         @@ -12,6 +12,28 @@ class TezosClient 
     | 
|
| 
       12 
12 
     | 
    
         
             
                  self.class.logger << out + "\n"
         
     | 
| 
       13 
13 
     | 
    
         
             
                end
         
     | 
| 
       14 
14 
     | 
    
         | 
| 
      
 15 
     | 
    
         
            +
                FILTERED_KEYS = [:code, :contractCode]
         
     | 
| 
      
 16 
     | 
    
         
            +
                def tezos_contents_log_filter(content)
         
     | 
| 
      
 17 
     | 
    
         
            +
                  if content.is_a? Array
         
     | 
| 
      
 18 
     | 
    
         
            +
                    content.map { |el| tezos_contents_log_filter(el) }
         
     | 
| 
      
 19 
     | 
    
         
            +
                  elsif content.is_a? Hash
         
     | 
| 
      
 20 
     | 
    
         
            +
                    content.reduce({}) do |h, (k, v)|
         
     | 
| 
      
 21 
     | 
    
         
            +
                      value = if FILTERED_KEYS.include? k.to_sym
         
     | 
| 
      
 22 
     | 
    
         
            +
                        "#{v.to_s[0..30]}..."
         
     | 
| 
      
 23 
     | 
    
         
            +
                      else
         
     | 
| 
      
 24 
     | 
    
         
            +
                        tezos_contents_log_filter(v)
         
     | 
| 
      
 25 
     | 
    
         
            +
                      end
         
     | 
| 
      
 26 
     | 
    
         
            +
                      h.merge(k => value)
         
     | 
| 
      
 27 
     | 
    
         
            +
                    end
         
     | 
| 
      
 28 
     | 
    
         
            +
                  else
         
     | 
| 
      
 29 
     | 
    
         
            +
                    content
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def tezos_contents_log(content)
         
     | 
| 
      
 34 
     | 
    
         
            +
                  tezos_contents_log_filter(content).pretty_inspect
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
       15 
37 
     | 
    
         
             
                class_methods do
         
     | 
| 
       16 
38 
     | 
    
         
             
                  # Setup the log for TezosClient calls.
         
     | 
| 
       17 
39 
     | 
    
         
             
                  # Value should be a logger but can can be stdout, stderr, or a filename.
         
     | 
| 
         @@ -0,0 +1,178 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
             
     | 
| 
      
 2 
     | 
    
         
            +
            class TezosClient
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
              class OperationMgr
         
     | 
| 
      
 5 
     | 
    
         
            +
                include Crypto
         
     | 
| 
      
 6 
     | 
    
         
            +
                using CurrencyUtils
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                attr_accessor :rpc_interface,
         
     | 
| 
      
 9 
     | 
    
         
            +
                              :rpc_operation_args
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def initialize(rpc_interface:, rpc_operation_args:, **args)
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @rpc_interface = rpc_interface
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @secret_key = args.fetch(:secret_key)
         
     | 
| 
      
 14 
     | 
    
         
            +
                  @multiple_operations = rpc_operation_args.is_a?(Array)
         
     | 
| 
      
 15 
     | 
    
         
            +
                  @rpc_operation_args = @multiple_operations ? rpc_operation_args : [rpc_operation_args]
         
     | 
| 
      
 16 
     | 
    
         
            +
                  @signed_operation_args_h = nil
         
     | 
| 
      
 17 
     | 
    
         
            +
                  @branch = args[:branch]
         
     | 
| 
      
 18 
     | 
    
         
            +
                  @protocol = args[:protocol]
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def multiple_operations?
         
     | 
| 
      
 22 
     | 
    
         
            +
                  @multiple_operations
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def single_operation?
         
     | 
| 
      
 26 
     | 
    
         
            +
                  !multiple_operations?
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def branch
         
     | 
| 
      
 30 
     | 
    
         
            +
                  @branch ||= rpc_interface.head_hash
         
     | 
| 
      
 31 
     | 
    
         
            +
                end
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def protocol
         
     | 
| 
      
 34 
     | 
    
         
            +
                  @protocol ||= rpc_interface.protocol
         
     | 
| 
      
 35 
     | 
    
         
            +
                end
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
                def simulate_and_update_limits
         
     | 
| 
      
 38 
     | 
    
         
            +
                  run_result = run
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  run_result[:operations_result].zip(rpc_operation_args) do |operation_result, rpc_operation_args|
         
     | 
| 
      
 41 
     | 
    
         
            +
                    if rpc_operation_args.key?(:gas_limit)
         
     | 
| 
      
 42 
     | 
    
         
            +
                      rpc_operation_args[:gas_limit] = (operation_result[:consumed_gas].to_i + 0.001.to_satoshi).to_s
         
     | 
| 
      
 43 
     | 
    
         
            +
                    end
         
     | 
| 
      
 44 
     | 
    
         
            +
                  end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                  run_result
         
     | 
| 
      
 47 
     | 
    
         
            +
                end
         
     | 
| 
      
 48 
     | 
    
         
            +
             
     | 
| 
      
 49 
     | 
    
         
            +
                def to_hex
         
     | 
| 
      
 50 
     | 
    
         
            +
                  rpc_interface.forge_operations(operations: rpc_operation_args, branch: branch)
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def sign
         
     | 
| 
      
 54 
     | 
    
         
            +
                  sign_operation(
         
     | 
| 
      
 55 
     | 
    
         
            +
                    secret_key: @secret_key,
         
     | 
| 
      
 56 
     | 
    
         
            +
                    operation_hex: to_hex
         
     | 
| 
      
 57 
     | 
    
         
            +
                  ) do |base_58_signature, signed_hex, _op_id|
         
     | 
| 
      
 58 
     | 
    
         
            +
                    @signed_operation_args_h = rpc_operation_args.hash
         
     | 
| 
      
 59 
     | 
    
         
            +
                    @base_58_signature = base_58_signature
         
     | 
| 
      
 60 
     | 
    
         
            +
                    @signed_hex = signed_hex
         
     | 
| 
      
 61 
     | 
    
         
            +
                  end
         
     | 
| 
      
 62 
     | 
    
         
            +
                end
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
      
 64 
     | 
    
         
            +
                def signed?
         
     | 
| 
      
 65 
     | 
    
         
            +
                  @signed_operation_args_h == rpc_operation_args.hash
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
                def base_58_signature
         
     | 
| 
      
 69 
     | 
    
         
            +
                  sign unless signed?
         
     | 
| 
      
 70 
     | 
    
         
            +
                  @base_58_signature
         
     | 
| 
      
 71 
     | 
    
         
            +
                end
         
     | 
| 
      
 72 
     | 
    
         
            +
             
     | 
| 
      
 73 
     | 
    
         
            +
                def signed_hex
         
     | 
| 
      
 74 
     | 
    
         
            +
                  sign unless signed?
         
     | 
| 
      
 75 
     | 
    
         
            +
                  @signed_hex
         
     | 
| 
      
 76 
     | 
    
         
            +
                end
         
     | 
| 
      
 77 
     | 
    
         
            +
             
     | 
| 
      
 78 
     | 
    
         
            +
                def test_and_broadcast
         
     | 
| 
      
 79 
     | 
    
         
            +
                  # simulate operations and adjust gas limits
         
     | 
| 
      
 80 
     | 
    
         
            +
                  simulate_and_update_limits
         
     | 
| 
      
 81 
     | 
    
         
            +
                  operations_result = preapply
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  op_id = broadcast
         
     | 
| 
      
 84 
     | 
    
         
            +
                  {
         
     | 
| 
      
 85 
     | 
    
         
            +
                    operation_id: op_id,
         
     | 
| 
      
 86 
     | 
    
         
            +
                    operations_result: operations_result,
         
     | 
| 
      
 87 
     | 
    
         
            +
                  }
         
     | 
| 
      
 88 
     | 
    
         
            +
                end
         
     | 
| 
      
 89 
     | 
    
         
            +
             
     | 
| 
      
 90 
     | 
    
         
            +
                def run
         
     | 
| 
      
 91 
     | 
    
         
            +
                  rpc_responses = rpc_interface.run_operations(
         
     | 
| 
      
 92 
     | 
    
         
            +
                    operations: rpc_operation_args,
         
     | 
| 
      
 93 
     | 
    
         
            +
                    signature: base_58_signature,
         
     | 
| 
      
 94 
     | 
    
         
            +
                    branch: branch)
         
     | 
| 
      
 95 
     | 
    
         
            +
             
     | 
| 
      
 96 
     | 
    
         
            +
                  consumed_storage = 0
         
     | 
| 
      
 97 
     | 
    
         
            +
                  consumed_gas = 0
         
     | 
| 
      
 98 
     | 
    
         
            +
             
     | 
| 
      
 99 
     | 
    
         
            +
                  operations_result = rpc_responses.map do |rpc_response|
         
     | 
| 
      
 100 
     | 
    
         
            +
                    metadata = rpc_response[:metadata]
         
     | 
| 
      
 101 
     | 
    
         
            +
                    ensure_applied!(metadata)
         
     | 
| 
      
 102 
     | 
    
         
            +
                    consumed_storage += compute_consumed_storage(metadata)
         
     | 
| 
      
 103 
     | 
    
         
            +
                    consumed_gas += compute_consumed_gas(metadata)
         
     | 
| 
      
 104 
     | 
    
         
            +
                    metadata[:operation_result]
         
     | 
| 
      
 105 
     | 
    
         
            +
                  end
         
     | 
| 
      
 106 
     | 
    
         
            +
             
     | 
| 
      
 107 
     | 
    
         
            +
                  {
         
     | 
| 
      
 108 
     | 
    
         
            +
                    status: :applied,
         
     | 
| 
      
 109 
     | 
    
         
            +
                    consumed_gas: consumed_gas,
         
     | 
| 
      
 110 
     | 
    
         
            +
                    consumed_storage: consumed_storage,
         
     | 
| 
      
 111 
     | 
    
         
            +
                    operations_result: operations_result
         
     | 
| 
      
 112 
     | 
    
         
            +
                  }
         
     | 
| 
      
 113 
     | 
    
         
            +
                end
         
     | 
| 
      
 114 
     | 
    
         
            +
             
     | 
| 
      
 115 
     | 
    
         
            +
                def compute_consumed_gas(metadata)
         
     | 
| 
      
 116 
     | 
    
         
            +
                  consumed_gas = (metadata.dig(:operation_result, :consumed_gas) || "0").to_i.from_satoshi
         
     | 
| 
      
 117 
     | 
    
         
            +
             
     | 
| 
      
 118 
     | 
    
         
            +
                  if metadata.key?(:internal_operation_results)
         
     | 
| 
      
 119 
     | 
    
         
            +
                    metadata[:internal_operation_results].each do |internal_operation_result|
         
     | 
| 
      
 120 
     | 
    
         
            +
                      consumed_gas += (internal_operation_result[:result][:consumed_gas] || "0").to_i.from_satoshi
         
     | 
| 
      
 121 
     | 
    
         
            +
                    end
         
     | 
| 
      
 122 
     | 
    
         
            +
                  end
         
     | 
| 
      
 123 
     | 
    
         
            +
                  consumed_gas
         
     | 
| 
      
 124 
     | 
    
         
            +
                end
         
     | 
| 
      
 125 
     | 
    
         
            +
             
     | 
| 
      
 126 
     | 
    
         
            +
                def compute_consumed_storage(metadata)
         
     | 
| 
      
 127 
     | 
    
         
            +
                  (metadata.dig(:operation_result, :paid_storage_size_diff) || "0").to_i.from_satoshi
         
     | 
| 
      
 128 
     | 
    
         
            +
                end
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
             
     | 
| 
      
 131 
     | 
    
         
            +
                def preapply
         
     | 
| 
      
 132 
     | 
    
         
            +
                  rpc_responses = rpc_interface.preapply_operations(
         
     | 
| 
      
 133 
     | 
    
         
            +
                    operations: rpc_operation_args,
         
     | 
| 
      
 134 
     | 
    
         
            +
                    signature: base_58_signature,
         
     | 
| 
      
 135 
     | 
    
         
            +
                    protocol: protocol,
         
     | 
| 
      
 136 
     | 
    
         
            +
                    branch: branch)
         
     | 
| 
      
 137 
     | 
    
         
            +
             
     | 
| 
      
 138 
     | 
    
         
            +
                  rpc_responses.map do |rpc_response|
         
     | 
| 
      
 139 
     | 
    
         
            +
                    ensure_applied!(rpc_response[:metadata])
         
     | 
| 
      
 140 
     | 
    
         
            +
                  end
         
     | 
| 
      
 141 
     | 
    
         
            +
                end
         
     | 
| 
      
 142 
     | 
    
         
            +
             
     | 
| 
      
 143 
     | 
    
         
            +
                def broadcast
         
     | 
| 
      
 144 
     | 
    
         
            +
                  rpc_interface.broadcast_operation(signed_hex)
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                private
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                def ensure_applied!(metadata)
         
     | 
| 
      
 150 
     | 
    
         
            +
                  operation_result = metadata[:operation_result]
         
     | 
| 
      
 151 
     | 
    
         
            +
             
     | 
| 
      
 152 
     | 
    
         
            +
                  unless operation_result.nil?
         
     | 
| 
      
 153 
     | 
    
         
            +
                    status = operation_result[:status]
         
     | 
| 
      
 154 
     | 
    
         
            +
                    if status != "applied"
         
     | 
| 
      
 155 
     | 
    
         
            +
                      failed!(status, operation_result[:errors], metadata)
         
     | 
| 
      
 156 
     | 
    
         
            +
                    end
         
     | 
| 
      
 157 
     | 
    
         
            +
                  end
         
     | 
| 
      
 158 
     | 
    
         
            +
             
     | 
| 
      
 159 
     | 
    
         
            +
                  operation_result
         
     | 
| 
      
 160 
     | 
    
         
            +
                end
         
     | 
| 
      
 161 
     | 
    
         
            +
             
     | 
| 
      
 162 
     | 
    
         
            +
                def exception_klass(errors)
         
     | 
| 
      
 163 
     | 
    
         
            +
                  error = errors[0]
         
     | 
| 
      
 164 
     | 
    
         
            +
                  case error[:id]
         
     | 
| 
      
 165 
     | 
    
         
            +
                  when "proto.003-PsddFKi3.contract.balance_too_low"
         
     | 
| 
      
 166 
     | 
    
         
            +
                    TezBalanceTooLow
         
     | 
| 
      
 167 
     | 
    
         
            +
                  when "proto.003-PsddFKi3.scriptRuntimeError"
         
     | 
| 
      
 168 
     | 
    
         
            +
                    ScriptRuntimeError
         
     | 
| 
      
 169 
     | 
    
         
            +
                  else
         
     | 
| 
      
 170 
     | 
    
         
            +
                    OperationFailure
         
     | 
| 
      
 171 
     | 
    
         
            +
                  end
         
     | 
| 
      
 172 
     | 
    
         
            +
                end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                def failed!(status, errors, metadata)
         
     | 
| 
      
 175 
     | 
    
         
            +
                  raise exception_klass(errors).new(metadata: metadata, errors: errors, status: status)
         
     | 
| 
      
 176 
     | 
    
         
            +
                end
         
     | 
| 
      
 177 
     | 
    
         
            +
              end
         
     | 
| 
      
 178 
     | 
    
         
            +
            end
         
     |