stellar-base 0.0.1

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.
Files changed (122) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.travis.yml +15 -0
  4. data/.yardopts +8 -0
  5. data/Gemfile +15 -0
  6. data/Guardfile +5 -0
  7. data/LICENSE.txt +202 -0
  8. data/README.md +79 -0
  9. data/Rakefile +6 -0
  10. data/examples/low_level_transaction_post.rb +53 -0
  11. data/examples/mid_level_transaction_post.rb +34 -0
  12. data/examples/non_native_payment.rb +60 -0
  13. data/generated/stellar/account_entry.rb +37 -0
  14. data/generated/stellar/account_flags.rb +20 -0
  15. data/generated/stellar/account_merge_result.rb +25 -0
  16. data/generated/stellar/account_merge_result_code.rb +30 -0
  17. data/generated/stellar/allow_trust_op/currency.rb +28 -0
  18. data/generated/stellar/allow_trust_op.rb +35 -0
  19. data/generated/stellar/allow_trust_result.rb +25 -0
  20. data/generated/stellar/allow_trust_result_code.rb +28 -0
  21. data/generated/stellar/bucket_entry.rb +28 -0
  22. data/generated/stellar/bucket_entry_type.rb +22 -0
  23. data/generated/stellar/change_trust_op.rb +22 -0
  24. data/generated/stellar/change_trust_result.rb +25 -0
  25. data/generated/stellar/change_trust_result_code.rb +28 -0
  26. data/generated/stellar/claim_offer_atom.rb +29 -0
  27. data/generated/stellar/create_offer_effect.rb +24 -0
  28. data/generated/stellar/create_offer_op.rb +28 -0
  29. data/generated/stellar/create_offer_result.rb +26 -0
  30. data/generated/stellar/create_offer_result_code.rb +45 -0
  31. data/generated/stellar/create_offer_success_result/offer.rb +30 -0
  32. data/generated/stellar/create_offer_success_result.rb +34 -0
  33. data/generated/stellar/currency.rb +29 -0
  34. data/generated/stellar/currency_type.rb +22 -0
  35. data/generated/stellar/decorated_signature.rb +20 -0
  36. data/generated/stellar/dont_have.rb +20 -0
  37. data/generated/stellar/error.rb +20 -0
  38. data/generated/stellar/hello.rb +24 -0
  39. data/generated/stellar/inflation_payout.rb +20 -0
  40. data/generated/stellar/inflation_result.rb +26 -0
  41. data/generated/stellar/inflation_result_code.rb +24 -0
  42. data/generated/stellar/iso_currency_issuer.rb +20 -0
  43. data/generated/stellar/ledger_entry.rb +33 -0
  44. data/generated/stellar/ledger_entry_type.rb +24 -0
  45. data/generated/stellar/ledger_header.rb +45 -0
  46. data/generated/stellar/ledger_header_history_entry.rb +20 -0
  47. data/generated/stellar/ledger_key/account.rb +20 -0
  48. data/generated/stellar/ledger_key/offer.rb +22 -0
  49. data/generated/stellar/ledger_key/trust_line.rb +22 -0
  50. data/generated/stellar/ledger_key.rb +50 -0
  51. data/generated/stellar/message_type.rb +45 -0
  52. data/generated/stellar/offer_entry.rb +34 -0
  53. data/generated/stellar/operation/body.rb +49 -0
  54. data/generated/stellar/operation.rb +45 -0
  55. data/generated/stellar/operation_result/tr.rb +49 -0
  56. data/generated/stellar/operation_result.rb +47 -0
  57. data/generated/stellar/operation_result_code.rb +25 -0
  58. data/generated/stellar/operation_type.rb +32 -0
  59. data/generated/stellar/payment_op.rb +35 -0
  60. data/generated/stellar/payment_result.rb +29 -0
  61. data/generated/stellar/payment_result_code.rb +41 -0
  62. data/generated/stellar/payment_success_multi_result.rb +20 -0
  63. data/generated/stellar/peer_address.rb +22 -0
  64. data/generated/stellar/price.rb +20 -0
  65. data/generated/stellar/scp_ballot.rb +20 -0
  66. data/generated/stellar/scp_envelope.rb +22 -0
  67. data/generated/stellar/scp_quorum_set.rb +20 -0
  68. data/generated/stellar/scp_statement/pledges/prepare.rb +24 -0
  69. data/generated/stellar/scp_statement/pledges.rb +40 -0
  70. data/generated/stellar/scp_statement.rb +42 -0
  71. data/generated/stellar/scp_statement_type.rb +26 -0
  72. data/generated/stellar/set_options_op.rb +31 -0
  73. data/generated/stellar/set_options_result.rb +25 -0
  74. data/generated/stellar/set_options_result_code.rb +28 -0
  75. data/generated/stellar/signer.rb +20 -0
  76. data/generated/stellar/simple_payment_result.rb +22 -0
  77. data/generated/stellar/stellar_ballot.rb +22 -0
  78. data/generated/stellar/stellar_ballot_value.rb +22 -0
  79. data/generated/stellar/stellar_message.rb +66 -0
  80. data/generated/stellar/transaction.rb +37 -0
  81. data/generated/stellar/transaction_envelope.rb +20 -0
  82. data/generated/stellar/transaction_history_entry.rb +20 -0
  83. data/generated/stellar/transaction_history_result_entry.rb +20 -0
  84. data/generated/stellar/transaction_meta.rb +18 -0
  85. data/generated/stellar/transaction_result/result.rb +30 -0
  86. data/generated/stellar/transaction_result.rb +33 -0
  87. data/generated/stellar/transaction_result_code.rb +46 -0
  88. data/generated/stellar/transaction_result_pair.rb +20 -0
  89. data/generated/stellar/transaction_result_set.rb +18 -0
  90. data/generated/stellar/transaction_set.rb +20 -0
  91. data/generated/stellar/trust_line_entry.rb +28 -0
  92. data/generated/stellar-base-generated.rb +160 -0
  93. data/lib/stellar/base/version.rb +5 -0
  94. data/lib/stellar/base.rb +1 -0
  95. data/lib/stellar/change_trust_op.rb +10 -0
  96. data/lib/stellar/currency.rb +28 -0
  97. data/lib/stellar/key_pair.rb +94 -0
  98. data/lib/stellar/payment_op.rb +38 -0
  99. data/lib/stellar/transaction.rb +72 -0
  100. data/lib/stellar/transaction_envelope.rb +32 -0
  101. data/lib/stellar/util/base58.rb +127 -0
  102. data/lib/stellar-base.rb +23 -0
  103. data/ruby-stellar-base.gemspec +34 -0
  104. data/spec/lib/stellar/key_pair_spec.rb +199 -0
  105. data/spec/lib/stellar/transaction_envelope_spec.rb +93 -0
  106. data/spec/lib/stellar/transaction_spec.rb +43 -0
  107. data/spec/lib/stellar/util/base58_spec.rb +74 -0
  108. data/spec/spec_helper.rb +16 -0
  109. data/spec/support/matchers/be_base58_check.rb +9 -0
  110. data/spec/support/matchers/eq_bytes.rb +5 -0
  111. data/spec/support/matchers/have_length.rb +5 -0
  112. data/tasks/rspec.rake +6 -0
  113. data/tasks/travis.rake +9 -0
  114. data/tasks/xdr.rake +48 -0
  115. data/xdr/SCPXDR.x +61 -0
  116. data/xdr/Stellar-ledger-entries.x +105 -0
  117. data/xdr/Stellar-ledger.x +117 -0
  118. data/xdr/Stellar-overlay.x +100 -0
  119. data/xdr/Stellar-transaction.x +497 -0
  120. data/xdr/Stellar-types.x +53 -0
  121. data/xdr/StellarXDR.x +11 -0
  122. metadata +342 -0
@@ -0,0 +1,33 @@
1
+ # Automatically generated on 2015-04-07T10:52:07-07:00
2
+ # DO NOT EDIT or your changes may be overwritten
3
+
4
+ require 'xdr'
5
+
6
+ # === xdr source ============================================================
7
+ #
8
+ # struct TransactionResult
9
+ # {
10
+ # int64 feeCharged; // actual fee charged for the transaction
11
+ #
12
+ # union switch (TransactionResultCode code)
13
+ # {
14
+ # case txSUCCESS:
15
+ # case txFAILED:
16
+ # OperationResult results<>;
17
+ # default:
18
+ # void;
19
+ # }
20
+ # result;
21
+ # };
22
+ #
23
+ # ===========================================================================
24
+ module Stellar
25
+ class TransactionResult < XDR::Struct
26
+ include XDR::Namespace
27
+
28
+ autoload :Result
29
+
30
+ attribute :fee_charged, Int64
31
+ attribute :result, Result
32
+ end
33
+ end
@@ -0,0 +1,46 @@
1
+ # Automatically generated on 2015-04-07T10:52:07-07:00
2
+ # DO NOT EDIT or your changes may be overwritten
3
+
4
+ require 'xdr'
5
+
6
+ # === xdr source ============================================================
7
+ #
8
+ # enum TransactionResultCode
9
+ # {
10
+ # txSUCCESS = 0, // all operations succeeded
11
+ #
12
+ # txDUPLICATE = 1, // transaction was already submited
13
+ #
14
+ # txFAILED = 2, // one of the operations failed (but none were applied)
15
+ #
16
+ # txBAD_LEDGER = 3, // ledger is not in range [minLeder; maxLedger]
17
+ # txMISSING_OPERATION = 4, // no operation was specified
18
+ # txBAD_SEQ = 5, // sequence number does not match source account
19
+ #
20
+ # txBAD_AUTH = 6, // not enough signatures to perform transaction
21
+ # txINSUFFICIENT_BALANCE = 7, // fee would bring account below reserve
22
+ # txNO_ACCOUNT = 8, // source account not found
23
+ # txINSUFFICIENT_FEE = 9, // max fee is too small
24
+ # txBAD_AUTH_EXTRA = 10, // too many signatures on transaction
25
+ # txINTERNAL_ERROR = 0xFFFFFFFF // an unknown error occured
26
+ # };
27
+ #
28
+ # ===========================================================================
29
+ module Stellar
30
+ class TransactionResultCode < XDR::Enum
31
+ member :tx_success, 0
32
+ member :tx_duplicate, 1
33
+ member :tx_failed, 2
34
+ member :tx_bad_ledger, 3
35
+ member :tx_missing_operation, 4
36
+ member :tx_bad_seq, 5
37
+ member :tx_bad_auth, 6
38
+ member :tx_insufficient_balance, 7
39
+ member :tx_no_account, 8
40
+ member :tx_insufficient_fee, 9
41
+ member :tx_bad_auth_extra, 10
42
+ member :tx_internal_error, 4294967295
43
+
44
+ seal
45
+ end
46
+ end
@@ -0,0 +1,20 @@
1
+ # Automatically generated on 2015-04-07T10:52:07-07:00
2
+ # DO NOT EDIT or your changes may be overwritten
3
+
4
+ require 'xdr'
5
+
6
+ # === xdr source ============================================================
7
+ #
8
+ # struct TransactionResultPair
9
+ # {
10
+ # Hash transactionHash;
11
+ # TransactionResult result; // result for the transaction
12
+ # };
13
+ #
14
+ # ===========================================================================
15
+ module Stellar
16
+ class TransactionResultPair < XDR::Struct
17
+ attribute :transaction_hash, Hash
18
+ attribute :result, TransactionResult
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ # Automatically generated on 2015-04-07T10:52:07-07:00
2
+ # DO NOT EDIT or your changes may be overwritten
3
+
4
+ require 'xdr'
5
+
6
+ # === xdr source ============================================================
7
+ #
8
+ # struct TransactionResultSet
9
+ # {
10
+ # TransactionResultPair results<5000>;
11
+ # };
12
+ #
13
+ # ===========================================================================
14
+ module Stellar
15
+ class TransactionResultSet < XDR::Struct
16
+ attribute :results, XDR::VarArray[TransactionResultPair, 5000]
17
+ end
18
+ end
@@ -0,0 +1,20 @@
1
+ # Automatically generated on 2015-04-07T10:52:07-07:00
2
+ # DO NOT EDIT or your changes may be overwritten
3
+
4
+ require 'xdr'
5
+
6
+ # === xdr source ============================================================
7
+ #
8
+ # struct TransactionSet
9
+ # {
10
+ # Hash previousLedgerHash;
11
+ # TransactionEnvelope txs<5000>;
12
+ # };
13
+ #
14
+ # ===========================================================================
15
+ module Stellar
16
+ class TransactionSet < XDR::Struct
17
+ attribute :previous_ledger_hash, Hash
18
+ attribute :txs, XDR::VarArray[TransactionEnvelope, 5000]
19
+ end
20
+ end
@@ -0,0 +1,28 @@
1
+ # Automatically generated on 2015-04-07T10:52:07-07:00
2
+ # DO NOT EDIT or your changes may be overwritten
3
+
4
+ require 'xdr'
5
+
6
+ # === xdr source ============================================================
7
+ #
8
+ # struct TrustLineEntry
9
+ # {
10
+ # AccountID accountID; // account this trustline belongs to
11
+ # Currency currency; // currency (with issuer)
12
+ # int64 balance; // how much of this currency the user has.
13
+ # // Currency defines the unit for this;
14
+ #
15
+ # int64 limit; // balance cannot be above this
16
+ # bool authorized; // issuer has authorized account to hold its credit
17
+ # };
18
+ #
19
+ # ===========================================================================
20
+ module Stellar
21
+ class TrustLineEntry < XDR::Struct
22
+ attribute :account_id, AccountID
23
+ attribute :currency, Currency
24
+ attribute :balance, Int64
25
+ attribute :limit, Int64
26
+ attribute :authorized, XDR::Bool
27
+ end
28
+ end
@@ -0,0 +1,160 @@
1
+ # Automatically generated on 2015-04-07T11:38:37-07:00
2
+ # DO NOT EDIT or your changes may be overwritten
3
+
4
+ require 'xdr'
5
+
6
+ module Stellar
7
+ include XDR::Namespace
8
+
9
+ Signature = XDR::Opaque[64]
10
+ Hash = XDR::Opaque[32]
11
+ Uint256 = XDR::Opaque[32]
12
+ Uint32 = XDR::UnsignedInt
13
+ Uint64 = XDR::UnsignedHyper
14
+ Value = XDR::VarOpaque[]
15
+ Evidence = XDR::VarOpaque[]
16
+
17
+ autoload :SCPBallot
18
+
19
+ autoload :SCPStatementType
20
+
21
+ autoload :SCPStatement
22
+ autoload :SCPEnvelope
23
+ autoload :SCPQuorumSet
24
+ end
25
+ module Stellar
26
+ include XDR::Namespace
27
+
28
+ autoload :LedgerEntryType
29
+
30
+ autoload :Signer
31
+
32
+ autoload :AccountFlags
33
+
34
+ autoload :AccountEntry
35
+ autoload :TrustLineEntry
36
+ autoload :OfferEntry
37
+
38
+ autoload :LedgerEntry
39
+ end
40
+ module Stellar
41
+ include XDR::Namespace
42
+
43
+ autoload :LedgerHeader
44
+
45
+ autoload :LedgerKey
46
+
47
+ autoload :BucketEntryType
48
+
49
+ autoload :BucketEntry
50
+
51
+ autoload :TransactionSet
52
+ autoload :TransactionResultPair
53
+ autoload :TransactionResultSet
54
+ autoload :TransactionMeta
55
+ autoload :TransactionHistoryEntry
56
+ autoload :TransactionHistoryResultEntry
57
+ autoload :LedgerHeaderHistoryEntry
58
+ end
59
+ module Stellar
60
+ include XDR::Namespace
61
+
62
+ autoload :StellarBallotValue
63
+ autoload :StellarBallot
64
+ autoload :Error
65
+ autoload :Hello
66
+ autoload :PeerAddress
67
+
68
+ autoload :MessageType
69
+
70
+ autoload :DontHave
71
+
72
+ autoload :StellarMessage
73
+ end
74
+ module Stellar
75
+ include XDR::Namespace
76
+
77
+ autoload :DecoratedSignature
78
+
79
+ autoload :OperationType
80
+
81
+ autoload :PaymentOp
82
+ autoload :CreateOfferOp
83
+ autoload :SetOptionsOp
84
+ autoload :ChangeTrustOp
85
+ autoload :AllowTrustOp
86
+ autoload :Operation
87
+ autoload :Transaction
88
+ autoload :TransactionEnvelope
89
+ autoload :ClaimOfferAtom
90
+
91
+ autoload :PaymentResultCode
92
+
93
+ autoload :SimplePaymentResult
94
+ autoload :PaymentSuccessMultiResult
95
+
96
+ autoload :PaymentResult
97
+
98
+ autoload :CreateOfferResultCode
99
+ autoload :CreateOfferEffect
100
+
101
+ autoload :CreateOfferSuccessResult
102
+
103
+ autoload :CreateOfferResult
104
+
105
+ autoload :SetOptionsResultCode
106
+
107
+ autoload :SetOptionsResult
108
+
109
+ autoload :ChangeTrustResultCode
110
+
111
+ autoload :ChangeTrustResult
112
+
113
+ autoload :AllowTrustResultCode
114
+
115
+ autoload :AllowTrustResult
116
+
117
+ autoload :AccountMergeResultCode
118
+
119
+ autoload :AccountMergeResult
120
+
121
+ autoload :InflationResultCode
122
+
123
+ autoload :InflationPayout
124
+
125
+ autoload :InflationResult
126
+
127
+ autoload :OperationResultCode
128
+
129
+ autoload :OperationResult
130
+
131
+ autoload :TransactionResultCode
132
+
133
+ autoload :TransactionResult
134
+ end
135
+ module Stellar
136
+ include XDR::Namespace
137
+
138
+ Uint512 = XDR::Opaque[64]
139
+ Uint256 = XDR::Opaque[32]
140
+ Uint64 = XDR::UnsignedHyper
141
+ Int64 = XDR::Hyper
142
+ Uint32 = XDR::UnsignedInt
143
+ Int32 = XDR::Int
144
+ AccountID = XDR::Opaque[32]
145
+ Signature = XDR::Opaque[64]
146
+ Hash = XDR::Opaque[32]
147
+ Thresholds = XDR::Opaque[4]
148
+ SequenceNumber = Uint64
149
+
150
+ autoload :CurrencyType
151
+
152
+ autoload :ISOCurrencyIssuer
153
+
154
+ autoload :Currency
155
+
156
+ autoload :Price
157
+ end
158
+ module Stellar
159
+ include XDR::Namespace
160
+ end
@@ -0,0 +1,5 @@
1
+ module Stellar
2
+ module Base
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1 @@
1
+ require "stellar-base"
@@ -0,0 +1,10 @@
1
+ module Stellar
2
+ ChangeTrustOp.class_eval do
3
+
4
+ def to_operation(source_account=nil)
5
+ body = Operation::Body.new(:change_trust, self)
6
+ Operation.new(source_account: source_account, body:body)
7
+ end
8
+
9
+ end
10
+ end
@@ -0,0 +1,28 @@
1
+ module Stellar
2
+ Currency.class_eval do
3
+ def self.native
4
+ new(:native)
5
+ end
6
+
7
+ def self.iso4217(code, issuer)
8
+ raise ArgumentError, "Bad :issuer" unless issuer.is_a?(KeyPair)
9
+ ici = ISOCurrencyIssuer.new({currency_code:code, issuer:issuer.public_key})
10
+ new(:iso4217, ici)
11
+ end
12
+
13
+ def to_s
14
+ if switch == CurrencyType.native
15
+ "native"
16
+ else
17
+ encoder = Stellar::Util::Base58.stellar
18
+ issuer_address = encoder.check_encode(:account_id,iso_ci.issuer)
19
+ "#{iso_ci.currency_code}/#{issuer_address}"
20
+ end
21
+ end
22
+
23
+ def inspect
24
+ label = switch.to_s
25
+ "#<Stellar::Currency #{to_s}>"
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,94 @@
1
+ module Stellar
2
+ class KeyPair
3
+ def self.from_seed(seed)
4
+ seed_bytes = Util::Base58.stellar.check_decode(:seed, seed)
5
+ from_raw_seed seed_bytes
6
+ end
7
+
8
+ def self.from_raw_seed(seed_bytes)
9
+ secret_key = RbNaCl::SigningKey.new(seed_bytes)
10
+ public_key = secret_key.verify_key
11
+ new(public_key, secret_key)
12
+ end
13
+
14
+ def self.from_public_key(pk_bytes)
15
+ public_key = RbNaCl::VerifyKey.new(pk_bytes)
16
+ new(public_key)
17
+ end
18
+
19
+ def self.from_address(address)
20
+ pk_bytes = Util::Base58.stellar.check_decode(:account_id, address)
21
+ from_public_key(pk_bytes)
22
+ end
23
+
24
+ def self.random
25
+ secret_key = RbNaCl::SigningKey.generate
26
+ public_key = secret_key.verify_key
27
+ new(public_key, secret_key)
28
+ end
29
+
30
+ def initialize(public_key, secret_key=nil)
31
+ @public_key = public_key
32
+ @secret_key = secret_key
33
+ end
34
+
35
+ def public_key
36
+ @public_key.to_bytes
37
+ end
38
+
39
+ def public_key_hint
40
+ public_key.slice(0, 4)
41
+ end
42
+
43
+ def raw_seed
44
+ @secret_key.to_bytes
45
+ end
46
+
47
+ def rbnacl_signing_key
48
+ @secret_key
49
+ end
50
+
51
+ def rbnacl_verify_key
52
+ @public_key
53
+ end
54
+
55
+ def address
56
+ pk_bytes = public_key
57
+ Util::Base58.stellar.check_encode(:account_id, pk_bytes)
58
+ end
59
+
60
+ def seed
61
+ raise "no private key" if @secret_key.nil?
62
+ #TODO: improve the error class above
63
+ seed_bytes = raw_seed
64
+ encoder = Util::Base58.stellar.check_encode(:seed, seed_bytes)
65
+ end
66
+
67
+ def sign?
68
+ !@secret_key.nil?
69
+ end
70
+
71
+ def sign(message)
72
+ raise "no private key" if @secret_key.nil?
73
+ #TODO: improve the error class above
74
+ @secret_key.sign(message)
75
+ end
76
+
77
+ def sign_decorated(message)
78
+ raw_signature = sign(message)
79
+ Stellar::DecoratedSignature.new({
80
+ hint: public_key_hint,
81
+ signature: raw_signature
82
+ })
83
+ end
84
+
85
+ def verify(signature, message)
86
+ @public_key.verify(signature, message)
87
+ rescue RbNaCl::LengthError
88
+ false
89
+ rescue RbNaCl::BadSignatureError
90
+ false
91
+ end
92
+
93
+ end
94
+ end
@@ -0,0 +1,38 @@
1
+ module Stellar
2
+ PaymentOp.class_eval do
3
+
4
+ def self.native(amount)
5
+ currency = Stellar::Currency.new(:native)
6
+ with_currency(currency).tap do |result|
7
+ result.amount = amount
8
+ result.send_max = amount
9
+ end
10
+ end
11
+
12
+ def self.iso4217(code, issuer, amount)
13
+ currency = Stellar::Currency.iso4217(code, issuer)
14
+ with_currency(currency).tap do |result|
15
+ result.amount = amount
16
+ result.send_max = amount
17
+ end
18
+ end
19
+
20
+ def self.with_currency(currency)
21
+ new.tap do |result|
22
+ result.currency = currency
23
+ result.path = []
24
+ end
25
+ end
26
+
27
+ def apply_defaults
28
+ self.source_memo ||= ""
29
+ self.memo ||= ""
30
+ end
31
+
32
+ def to_operation(source_account=nil)
33
+ body = Operation::Body.new(:payment, self)
34
+ Operation.new(source_account: source_account, body:body)
35
+ end
36
+
37
+ end
38
+ end
@@ -0,0 +1,72 @@
1
+ module Stellar
2
+ Transaction.class_eval do
3
+
4
+ def self.payment(attributes={})
5
+ destination = attributes[:destination]
6
+ amount = attributes[:amount]
7
+
8
+ raise ArgumentError unless destination.is_a?(KeyPair)
9
+
10
+ for_account(attributes).tap do |result|
11
+ payment = PaymentOp.send(*amount)
12
+ payment.destination = destination.public_key
13
+ payment.apply_defaults
14
+
15
+ result.operations = [payment.to_operation]
16
+ end
17
+ end
18
+
19
+ def self.change_trust(attributes={})
20
+ line = Currency.send(*attributes[:line])
21
+ limit = attributes[:limit]
22
+
23
+ raise ArgumentError, "Bad :limit #{limit}" unless limit.is_a?(Integer)
24
+
25
+ for_account(attributes).tap do |result|
26
+ details = ChangeTrustOp.new(line: line, limit: limit)
27
+ result.operations = [details.to_operation]
28
+ end
29
+ end
30
+
31
+ def self.for_account(attributes={})
32
+ account = attributes[:account]
33
+ sequence = attributes[:sequence]
34
+
35
+ raise ArgumentError, "Bad :account" unless account.is_a?(KeyPair) && account.sign?
36
+ raise ArgumentError, "Bad :sequence #{sequence}" unless sequence.is_a?(Integer)
37
+
38
+ new.tap do |result|
39
+ result.seq_num = sequence
40
+ result.source_account = account.public_key
41
+ result.apply_defaults
42
+ end
43
+ end
44
+
45
+ def sign(key_pair)
46
+ key_pair.sign(hash)
47
+ end
48
+
49
+ def sign_decorated(key_pair)
50
+ key_pair.sign_decorated(hash)
51
+ end
52
+
53
+ def hash
54
+ Digest::SHA256.digest(to_xdr)
55
+ end
56
+
57
+ def to_envelope(*key_pairs)
58
+ signatures = key_pairs.map(&method(:sign_decorated))
59
+
60
+ TransactionEnvelope.new({
61
+ :signatures => signatures,
62
+ :tx => self
63
+ })
64
+ end
65
+
66
+ def apply_defaults
67
+ self.max_fee ||= 10
68
+ self.min_ledger ||= 0
69
+ self.max_ledger ||= 2**32 - 1
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,32 @@
1
+ module Stellar
2
+ TransactionEnvelope.class_eval do
3
+
4
+ #
5
+ # Checks to ensure that every signature for the envelope is
6
+ # a valid signature of one of the provided `key_pairs`
7
+ #
8
+ # NOTE: this does not do any authorization checks, which requires access to
9
+ # the current ledger state.
10
+ #
11
+ # @param *key_pairs [Array<Stellar::KeyPair>] The key pairs to check the envelopes signatures against
12
+ #
13
+ # @return [Boolean] true if all signatures are from the provided key_pairs and validly sign the tx's hash
14
+ def signed_correctly?(*key_pairs)
15
+ hash = tx.hash
16
+ return false if signatures.empty?
17
+
18
+ key_index = key_pairs.index_by(&:public_key_hint)
19
+
20
+ signatures.all? do |sig|
21
+ key_pair = key_index[sig.hint]
22
+ break false if key_pair.nil?
23
+
24
+ key_pair.verify(sig.signature, hash)
25
+ end
26
+ end
27
+
28
+ def hash
29
+ Digest::SHA256.digest(to_xdr)
30
+ end
31
+ end
32
+ end