counterparty_ruby 0.9.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.
@@ -0,0 +1,70 @@
1
+ require 'json'
2
+ require 'rest_client'
3
+ require 'open-uri'
4
+ require 'bitcoin'
5
+
6
+ require 'counterparty/raw_tx'
7
+ require 'counterparty/version'
8
+ require 'counterparty/resource'
9
+ require 'counterparty/resources'
10
+ require 'counterparty/connection'
11
+
12
+ # The main module, under which all classes in the library are defined.
13
+ module Counterparty
14
+ # One XCP, in units of Satoshi
15
+ ONE_XCP = 100_000_000
16
+
17
+ # One BTC, in units of Satoshi
18
+ ONE_BTC = 100_000_000
19
+
20
+ # This exception is typically raised by errors related to the params and/or
21
+ # request format
22
+ class JsonResponseError < StandardError; end
23
+
24
+ # This exception comes from an error relating to a proper request, but an
25
+ # inability to complete the request via the counterpartyd api
26
+ class ResponseError < StandardError
27
+ attr_reader :data_type
28
+ attr_reader :data_args
29
+ attr_reader :data_message
30
+ attr_reader :code
31
+ attr_reader :message_class
32
+
33
+ def initialize(json)
34
+ @message_class, @code = json['message'], json['code']
35
+
36
+ json['data'].each_pair do |(k,v)|
37
+ instance_variable_set '@data_%s' % k, v
38
+ end if json.has_key? 'data'
39
+
40
+ super
41
+ end
42
+
43
+ def message
44
+ '%s: %s' % [@message_class,@data_message]
45
+ end
46
+ end
47
+
48
+ class << self
49
+ # Sets/Gets the default connection object
50
+ attr_writer :connection
51
+
52
+ # Returns the current default connection object, or creates a new test-mode
53
+ # connection, if none has been defined
54
+ def connection
55
+ @connection || Connection.new
56
+ end
57
+
58
+ # Establishes the default connection for new objects as being the default
59
+ # counterparty production mode port/user/ip
60
+ def production!
61
+ @connection = Connection.new 4000
62
+ end
63
+
64
+ # Establishes the default connection for new objects as being the default
65
+ # counterparty test mode port/user/ip
66
+ def test!
67
+ @connection = Connection.new
68
+ end
69
+ end
70
+ end
data/spec/config.yml ADDED
@@ -0,0 +1,3 @@
1
+ source_address: msCXwsPVbv1Q1pc5AjXd5TdVwy3a1fSYB2
2
+ source_privkey: cP7ufwcbZujaa1qkKthLbVZUaP88RS5r9awyXerJE5rAEMTRVmzc
3
+ spend_destination: msj42CCGruhRsFrGATiUuh25dtxYtnpbTx
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Counterparty::Connection do
4
+ describe "#new" do
5
+ # It should default to the test network parameters
6
+ subject{Counterparty::Connection.new}
7
+
8
+ its(:host){ should eq('localhost') }
9
+ its(:port){ should eq(14000) }
10
+ its(:username){ should eq('rpc') }
11
+ its(:password){ should eq('1234') }
12
+ its(:api_url){ should eq('http://rpc:1234@localhost:14000/api/') }
13
+ end
14
+ end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ describe Counterparty::ResponseError do
4
+ include_context 'globals'
5
+
6
+ let(:bad_issuance) do
7
+ Counterparty::Issuance.new source: source_address,
8
+ asset: 'THISASSETNAMEISFARTOOLONGANDINVALID',
9
+ quantity: 1000, description: "my asset is uncool",
10
+ allow_unconfirmed_inputs: true
11
+ end
12
+
13
+ it "should fail on to_raw_tx" do
14
+ expect{ bad_issuance.to_raw_tx }.to raise_error Counterparty::ResponseError
15
+ end
16
+
17
+ it "should fail on save!" do
18
+ expect{ bad_issuance.save! }.to raise_error Counterparty::ResponseError
19
+ end
20
+
21
+ subject do
22
+ begin
23
+ bad_issuance.save!
24
+ rescue => error
25
+ error
26
+ end
27
+ end
28
+
29
+ its(:data_type) { should eq('AssetNameError') }
30
+ its(:data_args) { should eq(["long asset names must be numeric"]) }
31
+ its(:data_message) { should eq("long asset names must be numeric") }
32
+ its(:code) { should eq(-32000) }
33
+ its(:message) { should eq("Server error: long asset names must be numeric") }
34
+ end
35
+
36
+ describe Counterparty::JsonResponseError do
37
+ pending
38
+ end
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+
3
+ describe RawTx do
4
+ describe ".double_sha256" do
5
+ # http://bitcoin.stackexchange.com/questions/2177/how-to-calculate-a-hash-of-a-tx
6
+ genesis_block = '01000000010000000000000000000000000000000000000000000'+
7
+ '000000000000000000000FFFFFFFF4D04FFFF001D0104455468652054696D657320'+
8
+ '30332F4A616E2F32303039204368616E63656C6C6F72206F6E206272696E6B206F6'+
9
+ '6207365636F6E64206261696C6F757420666F722062616E6B73FFFFFFFF0100F205'+
10
+ '2A01000000434104678AFDB0FE5548271967F1A67130B7105CD6A828E03909A6796'+
11
+ '2E0EA1F61DEB649F6BC3F4CEF38C4F35504E51EC112DE5C384DF7BA0B8D578A4C70'+
12
+ '2B6BF11D5FAC00000000'
13
+ genesis_double_sha = '4A5E1E4BAAB89F3A32518A88C31BC87F618F76673E2CC77AB2127B7AFDEDA33B'
14
+
15
+ pending
16
+ end
17
+
18
+ describe ".nibbles_to_ui" do
19
+ it "should fail on byte arrays larger than 32 bits" do
20
+ expect{ RawTx.nibbles_to_ui([1,0,0,0,0]) }.to raise_error(ArgumentError)
21
+ end
22
+
23
+ # Remember that the least significant byte is first here:
24
+ it ("should convert 0x10 to 1") { expect(RawTx.nibbles_to_ui([1,0])).to eq(1) }
25
+ it ("should convert 0x01 to 16") { expect(RawTx.nibbles_to_ui([0,1])).to eq(16) }
26
+ it ("should convert 0xf to 15") { expect(RawTx.nibbles_to_ui([0xf])).to eq(15) }
27
+ it ("should convert 0x11 to 17") { expect(RawTx.nibbles_to_ui([1,1])).to eq(17) }
28
+ it ("should convert 0xf1 to 31") { expect(RawTx.nibbles_to_ui([0xf,1])).to eq(31) }
29
+ it ("should convert 0xff to 255") { expect(RawTx.nibbles_to_ui([0xf,0xf])).to eq(255) }
30
+ end
31
+
32
+ describe ".bytes_to_base64_s" do
33
+ it "should convert 0x14FB9C03D97E to FPucA91+" do
34
+ bytes = [0x14, 0xFB, 0x9C, 0x03, 0xD9, 0x7E]
35
+ expect(RawTx.bytes_to_base64_s bytes).to eq("FPucA9l+")
36
+ end
37
+
38
+ it "should convert 0x14FB9C03D9 to FPucA9k=" do
39
+ bytes = [0x14, 0xFB, 0x9C, 0x03, 0xD9]
40
+ expect(RawTx.bytes_to_base64_s bytes).to eq("FPucA9k=")
41
+ end
42
+
43
+ it "should convert 0x14FB9C03 to FPucAw==" do
44
+ bytes = [0x14, 0xFB, 0x9C, 0x03]
45
+ expect(RawTx.bytes_to_base64_s bytes).to eq("FPucAw==")
46
+ end
47
+ end
48
+
49
+ describe "#to_hash" do
50
+ # NOTE that these spec values were obtained via:
51
+ # bitcoind -testnet decoderawtransaction [subject]
52
+ subject{ RawTx.new(
53
+ "0100000001ec549bdf53cfb319201d672fc0933500e48505724010dad615a9344b99" +
54
+ "1721cc010000001976a9148025b288cb325d88bcd7ef5d1ab1f8827778d5ee88acff" +
55
+ "ffffff03781e0000000000006951210286cdf9ec8742c452bd13299771fe40130124" +
56
+ "038e2198ffc402204c48cc2d32da21033de0df1555e81783f42e00458d0b542ff293" +
57
+ "d9d04fbc7704650448ee07728a8a210286b1e4f15de57fd34bde19cf64ad9302e454" +
58
+ "c4c377677581a951579a124b86e753ae781e00000000000069512102a2cdf9ec8742" +
59
+ "c452bd2214fe01c9f33b0d0066ed0efb90aa715400038c1c621921034f89bc707587" +
60
+ "71a393416c21a12b651db3def9851bff574904762b86365caaea210286b1e4f15de5" +
61
+ "7fd34bde19cf64ad9302e454c4c377677581a951579a124b86e753aec0ba770d0000" +
62
+ "00001976a9148025b288cb325d88bcd7ef5d1ab1f8827778d5ee88ac00000000").to_hash }
63
+
64
+ its(['ver']){should eq(1)}
65
+ its(['lock_time']){should eq(0)}
66
+ its(['size']){should eq(338)}
67
+ its(['vin_sz']){should eq(1)}
68
+ its(['vout_sz']){should eq(3)}
69
+
70
+ its(['vin']) do
71
+ # If we're testing to base64, the hash would look like:
72
+ # RawTx.bytes_to_base64_s(out_hash.scan(/../).collect(&:hex))
73
+ should eq([
74
+ { "txid" => "cc2117994b34a915d6da1040720585e4003593c02f671d2019b3cf53df9b54ec",
75
+ "vout" => 1,
76
+ "scriptSig" => {
77
+ "hex" => "76a9148025b288cb325d88bcd7ef5d1ab1f8827778d5ee88ac",
78
+ "asm" => %w(OP_DUP OP_HASH160
79
+ 8025b288cb325d88bcd7ef5d1ab1f8827778d5ee OP_EQUALVERIFY
80
+ OP_CHECKSIG).join(' ')
81
+ }, "sequence" => 4294967295 }])
82
+ end
83
+
84
+ its(['vout']) do
85
+ should eq( [
86
+ { "value" => 0.00007800, "n" => 0,
87
+ "scriptPubKey" => {
88
+ "hex" => "51210286cdf9ec8742c452bd13299771fe40130124038e2198ffc40"+
89
+ "2204c48cc2d32da21033de0df1555e81783f42e00458d0b542ff293d9d04f"+
90
+ "bc7704650448ee07728a8a210286b1e4f15de57fd34bde19cf64ad9302e45"+
91
+ "4c4c377677581a951579a124b86e753ae",
92
+ "asm" => "1 0286cdf9ec8742c452bd13299771fe40130124038e2198ffc402204c48cc2d32da 033de0df1555e81783f42e00458d0b542ff293d9d04fbc7704650448ee07728a8a 0286b1e4f15de57fd34bde19cf64ad9302e454c4c377677581a951579a124b86e7 3 OP_CHECKMULTISIG" }
93
+ },
94
+ { "value" => 0.00007800, "n" => 1,
95
+ "scriptPubKey" => {
96
+ "hex" => "512102a2cdf9ec8742c452bd2214fe01c9f33b0d0066ed0efb90aa71"+
97
+ "5400038c1c621921034f89bc70758771a393416c21a12b651db3def9851bf"+
98
+ "f574904762b86365caaea210286b1e4f15de57fd34bde19cf64ad9302e454"+
99
+ "c4c377677581a951579a124b86e753ae",
100
+ "asm" => "1 02a2cdf9ec8742c452bd2214fe01c9f33b0d0066ed0efb90aa715400038c1c6219 034f89bc70758771a393416c21a12b651db3def9851bff574904762b86365caaea 0286b1e4f15de57fd34bde19cf64ad9302e454c4c377677581a951579a124b86e7 3 OP_CHECKMULTISIG" }
101
+ },
102
+ { "value" => 2.25950400, "n" => 2,
103
+ "scriptPubKey" => {
104
+ "hex" => "76a9148025b288cb325d88bcd7ef5d1ab1f8827778d5ee88ac",
105
+ "asm" => "OP_DUP OP_HASH160 8025b288cb325d88bcd7ef5d1ab1f8827778d5ee OP_EQUALVERIFY OP_CHECKSIG" } } ] )
106
+ end
107
+ end
108
+
109
+ describe("#to_hash coinbase") do
110
+
111
+ subject{ RawTx.new(
112
+ "01000000010000000000000000000000000000000000000000000000000000000000" +
113
+ "000000ffffffff53038349040d00456c69676975730052d8f72ffabe6d6dd991088d" +
114
+ "ecd13e658bbecc0b2b4c87306f637828917838c02a5d95d0e1bdff9b040000000000" +
115
+ "0000002f73733331312f00906b570400000000e4050000ffffffff01bf2087950000" +
116
+ "00001976a9145399c3093d31e4b0af4be1215d59b857b861ad5d88ac00000000").to_hash }
117
+
118
+ pending
119
+ end
120
+
121
+ end
122
+
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ # NOTE: Most of these examples are from:
4
+ # https://github.com/CounterpartyXCP/counterpartyd/blob/master/docs/API.rst#id8
5
+ # The tests have to run in the specified order, as we populate our test account
6
+ # before running test operations
7
+ describe Counterparty do
8
+ include_context 'globals'
9
+
10
+ before(:all) { Counterparty.test! }
11
+
12
+ # TODO: deprecate?
13
+ #it "Ensure test account has BTC" do
14
+ #expect(bitcoin.getreceivedbyaddress(source_address)).to be > 0
15
+ #end
16
+
17
+ describe "Ensure test account has XCP" do
18
+ subject do
19
+ Counterparty::Balance.find( filters:
20
+ { field: 'address', op: '==', value: source_address}
21
+ ).find{|b| b.asset == 'XCP' }
22
+ end
23
+
24
+ its(:quantity){ should be > Counterparty::ONE_XCP }
25
+ end
26
+
27
+ # Send 1 XCP (specified in satoshis) from one address to another (you must have
28
+ # the sending address in your bitcoind wallet and it will be broadcast as a
29
+ # multisig transaction
30
+ describe "#do_send" do
31
+ subject do
32
+ Counterparty::Send.new source: source_address, destination: destination_address,
33
+ asset: "XCP", quantity: Counterparty::ONE_XCP,
34
+ allow_unconfirmed_inputs: true
35
+ end
36
+
37
+ its(:to_raw_tx) { should_not be_empty }
38
+ its(:save!) { should_not be_empty }
39
+ end
40
+
41
+ describe "#do_issuance" do
42
+ subject do
43
+ Counterparty::Issuance.new source: source_address, asset: unique_asset_name,
44
+ quantity: 1000, description: "my asset is cool", divisible: true,
45
+ allow_unconfirmed_inputs: true
46
+ end
47
+
48
+ its(:to_raw_tx) { should_not be_empty }
49
+ its(:save!) { should_not be_empty }
50
+ end
51
+
52
+ describe "signed #create_broadcast" do
53
+ subject do
54
+ # We want the save(private_key) syntax here
55
+ Counterparty::Broadcast.new source: source_address, fee_fraction: 0.05,
56
+ text: "Price of gold, 12AM UTC March1. 1=inc 2=dec/const", value: 2.0,
57
+ timestamp: 1418926641,
58
+ allow_unconfirmed_inputs: true
59
+ end
60
+
61
+ its(:to_raw_tx) { should_not be_empty }
62
+
63
+ it "should persist using a provided key" do
64
+ # TODO: Make this work
65
+ expect(subject.save!(source_privkey)).to_not be_empty
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ # NOTE: Most of these examples are from:
4
+ # https://github.com/CounterpartyXCP/counterpartyd/blob/master/docs/API.rst#id8
5
+ describe Counterparty do
6
+ include_context 'globals'
7
+
8
+ before(:all) { Counterparty.production! }
9
+
10
+ # Get all burns between blocks 280537 and 280539 where greater than .2 BTC was
11
+ # burned, sorting by tx_hash (ascending order) With this (and the rest of the
12
+ # examples below) we use positional arguments, instead of keyword-based arguments
13
+ describe "#get_burns" do
14
+ burn_params = {
15
+ order_by: 'tx_hash',
16
+ order_dir: 'asc',
17
+ start_block: 280537,
18
+ end_block: 280539 }
19
+
20
+ subject{ Counterparty::Burn.find burn_params }
21
+
22
+ it("should equal get_burns") do
23
+ expect(subject).to eq(Counterparty.connection.get_burns(burn_params))
24
+ end
25
+
26
+ its('length'){ should eq(10) }
27
+ its('first') do
28
+ should eq(Counterparty::Burn.new(
29
+ tx_index: 1096,
30
+ source: '1ADpYypUcnbezuuYpCyRCY7G4KD6a9YXiF',
31
+ block_index: 280537,
32
+ earned: 129754545455,
33
+ status: "valid",
34
+ burned: 100000000,
35
+ tx_hash: '6e905ec73870d6c6cdc8f4e64767ec41f74c8f07a24cc7c54811134f5b6aa6a7'
36
+ ) )
37
+ end
38
+ end
39
+
40
+ # Fetch all balances for all assets for both of two addresses, using keyword-
41
+ # based arguments
42
+ describe "#get_balances" do
43
+ balance_params = { filters: {
44
+ field: 'address', op: '==', value: "14qqz8xpzzEtj6zLs3M1iASP7T4mj687yq" } }
45
+
46
+ subject{ Counterparty::Balance.find balance_params }
47
+
48
+ it("should equal get_balances") do
49
+ expect(subject).to eq(Counterparty.connection.get_balances(balance_params))
50
+ end
51
+
52
+ its('length'){ should eq(1) }
53
+ its('first') do
54
+ should eq(Counterparty::Balance.new(
55
+ quantity: 0,
56
+ asset: "XCP",
57
+ address: "14qqz8xpzzEtj6zLs3M1iASP7T4mj687yq" ) )
58
+ end
59
+ end
60
+
61
+ # Fetch all debits for > 2 XCP between blocks 280537 and 280539, sorting the
62
+ # results by quantity (descending order)
63
+ describe "#get_debits" do
64
+ debit_params = {
65
+ filters: [
66
+ {field: 'asset', op: '==', value: "XCP"},
67
+ {field: 'quantity', op: '>', value: 200000000}
68
+ ],
69
+ filterop: 'AND',
70
+ order_by: 'quantity',
71
+ order_dir: 'desc'}
72
+
73
+ subject{ Counterparty::Debit.find debit_params }
74
+
75
+ it("should equal get_debits") do
76
+ expect(subject).to eq(Counterparty.connection.get_debits(debit_params))
77
+ end
78
+
79
+ its('length'){ should eq(1000) }
80
+ its('first') do
81
+ should eq(Counterparty::Debit.new(
82
+ block_index: 318845,
83
+ asset: "XCP",
84
+ address: "1FxhdSid1TUfzfTyveMcsUhF3ePjRK6qqa",
85
+ action: "send",
86
+ event: "64c26f4dc12fbbdbead62962a9428d4a6b17a44c061d202ff525e2f513cd34e8",
87
+ quantity: 6184957374430
88
+ ) )
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,29 @@
1
+ $:<< File.join(File.dirname(__FILE__), '..','lib')
2
+
3
+ require 'yaml'
4
+ require 'rspec/its'
5
+ require 'counterparty_ruby'
6
+
7
+ shared_context 'globals' do
8
+ let(:config) do
9
+ YAML.load File.open([File.dirname(__FILE__),'config.yml'].join('/')).read
10
+ end
11
+
12
+ let(:source_address) { config['source_address'] }
13
+ let(:source_privkey) { config['source_privkey'] }
14
+ let(:destination_address) { config['spend_destination'] }
15
+
16
+ # Since asset names have to be unique, we try our best to create a unique
17
+ # one here. This asset is composed of the timestamp, plus the machine
18
+ # name we're running on. Be advised this might be a small privacy breach
19
+ # forsensitive operations.
20
+ # There might be some collisions here due to my not handling fixed-width
21
+ # integers greater than 26. I don't think I care about that right now
22
+ let!(:unique_asset_name) do
23
+ base26_time = Time.now.strftime('%y %m %d %H %M %S').split(' ').collect{|c| c.to_i.to_s(26)}
24
+ alpha_encode = base26_time.join.tr((('0'..'9').to_a+('a'..'q').to_a).join, ('A'..'Z').to_a.join)
25
+
26
+ [alpha_encode,`hostname`.upcase.tr('^A-Z','')].join[0...12]
27
+ end
28
+ end
29
+
metadata ADDED
@@ -0,0 +1,185 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: counterparty_ruby
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Chris DeRose
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2015-01-07 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rest_client
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: bitcoin-ruby
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: ffi
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec-its
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: rake
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: rdoc
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: This gem is designed to abstract communications with the counterpartyd
127
+ api server in an ActiveRecord-esque object model
128
+ email:
129
+ - chris@chrisderose.com
130
+ executables: []
131
+ extensions: []
132
+ extra_rdoc_files: []
133
+ files:
134
+ - .gitignore
135
+ - Gemfile
136
+ - Gemfile.lock
137
+ - README.md
138
+ - Rakefile
139
+ - counterparty_ruby.gemspec
140
+ - lib/counterparty/connection.rb
141
+ - lib/counterparty/raw_tx.rb
142
+ - lib/counterparty/resource.rb
143
+ - lib/counterparty/resources.rb
144
+ - lib/counterparty/version.rb
145
+ - lib/counterparty_ruby.rb
146
+ - spec/config.yml
147
+ - spec/connection_spec.rb
148
+ - spec/exceptions_spec.rb
149
+ - spec/rawtx_decode_spec.rb
150
+ - spec/resource_create_spec.rb
151
+ - spec/resource_read_spec.rb
152
+ - spec/spec_helper.rb
153
+ homepage: https://github.com/brighton36/counterparty_ruby
154
+ licenses:
155
+ - LGPL
156
+ post_install_message:
157
+ rdoc_options: []
158
+ require_paths:
159
+ - lib
160
+ required_ruby_version: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ! '>='
164
+ - !ruby/object:Gem::Version
165
+ version: '1.9'
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ none: false
168
+ requirements:
169
+ - - ! '>='
170
+ - !ruby/object:Gem::Version
171
+ version: '0'
172
+ requirements: []
173
+ rubyforge_project:
174
+ rubygems_version: 1.8.23
175
+ signing_key:
176
+ specification_version: 3
177
+ summary: An ActiveRecord-esque abstraction of the Counterparty API
178
+ test_files:
179
+ - spec/config.yml
180
+ - spec/connection_spec.rb
181
+ - spec/exceptions_spec.rb
182
+ - spec/rawtx_decode_spec.rb
183
+ - spec/resource_create_spec.rb
184
+ - spec/resource_read_spec.rb
185
+ - spec/spec_helper.rb