stellar-base 0.21.0 → 0.22.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -2
- data/Gemfile +0 -6
- data/README.md +1 -1
- data/generated/stellar-base-generated.rb +15 -0
- data/generated/stellar/ledger_close_meta.rb +23 -0
- data/generated/stellar/ledger_close_meta_v0.rb +35 -0
- data/generated/stellar/message_type.rb +6 -1
- data/generated/stellar/peer_stats.rb +48 -0
- data/generated/stellar/signed_survey_request_message.rb +20 -0
- data/generated/stellar/signed_survey_response_message.rb +20 -0
- data/generated/stellar/stellar_message.rb +22 -12
- data/generated/stellar/survey_message_command_type.rb +20 -0
- data/generated/stellar/survey_request_message.rb +26 -0
- data/generated/stellar/survey_response_body.rb +23 -0
- data/generated/stellar/survey_response_message.rb +26 -0
- data/generated/stellar/topology_response_body.rb +25 -0
- data/generated/stellar/transaction_meta.rb +4 -0
- data/generated/stellar/transaction_meta_v2.rb +24 -0
- data/generated/stellar/transaction_result_meta.rb +22 -0
- data/generated/stellar/upgrade_entry_meta.rb +20 -0
- data/lib/stellar-base.rb +1 -0
- data/lib/stellar/base/version.rb +1 -1
- data/lib/stellar/operation.rb +55 -26
- data/lib/stellar/transaction.rb +11 -0
- data/lib/stellar/transaction_builder.rb +106 -0
- data/ruby-stellar-base.gemspec +1 -1
- data/spec/lib/stellar/operation_spec.rb +7 -9
- data/spec/lib/stellar/transaction_builder_spec.rb +263 -0
- data/xdr/Stellar-ledger.x +54 -0
- data/xdr/Stellar-overlay.x +84 -1
- metadata +20 -5
@@ -11,6 +11,8 @@ require 'xdr'
|
|
11
11
|
# OperationMeta operations<>;
|
12
12
|
# case 1:
|
13
13
|
# TransactionMetaV1 v1;
|
14
|
+
# case 2:
|
15
|
+
# TransactionMetaV2 v2;
|
14
16
|
# };
|
15
17
|
#
|
16
18
|
# ===========================================================================
|
@@ -20,8 +22,10 @@ module Stellar
|
|
20
22
|
|
21
23
|
switch 0, :operations
|
22
24
|
switch 1, :v1
|
25
|
+
switch 2, :v2
|
23
26
|
|
24
27
|
attribute :operations, XDR::VarArray[OperationMeta]
|
25
28
|
attribute :v1, TransactionMetaV1
|
29
|
+
attribute :v2, TransactionMetaV2
|
26
30
|
end
|
27
31
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# This code was automatically generated using xdrgen
|
2
|
+
# DO NOT EDIT or your changes may be overwritten
|
3
|
+
|
4
|
+
require 'xdr'
|
5
|
+
|
6
|
+
# === xdr source ============================================================
|
7
|
+
#
|
8
|
+
# struct TransactionMetaV2
|
9
|
+
# {
|
10
|
+
# LedgerEntryChanges txChangesBefore; // tx level changes before operations
|
11
|
+
# // are applied if any
|
12
|
+
# OperationMeta operations<>; // meta for each operation
|
13
|
+
# LedgerEntryChanges txChangesAfter; // tx level changes after operations are
|
14
|
+
# // applied if any
|
15
|
+
# };
|
16
|
+
#
|
17
|
+
# ===========================================================================
|
18
|
+
module Stellar
|
19
|
+
class TransactionMetaV2 < XDR::Struct
|
20
|
+
attribute :tx_changes_before, LedgerEntryChanges
|
21
|
+
attribute :operations, XDR::VarArray[OperationMeta]
|
22
|
+
attribute :tx_changes_after, LedgerEntryChanges
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# This code was automatically generated using xdrgen
|
2
|
+
# DO NOT EDIT or your changes may be overwritten
|
3
|
+
|
4
|
+
require 'xdr'
|
5
|
+
|
6
|
+
# === xdr source ============================================================
|
7
|
+
#
|
8
|
+
# struct TransactionResultMeta
|
9
|
+
# {
|
10
|
+
# TransactionResultPair result;
|
11
|
+
# LedgerEntryChanges feeProcessing;
|
12
|
+
# TransactionMeta txApplyProcessing;
|
13
|
+
# };
|
14
|
+
#
|
15
|
+
# ===========================================================================
|
16
|
+
module Stellar
|
17
|
+
class TransactionResultMeta < XDR::Struct
|
18
|
+
attribute :result, TransactionResultPair
|
19
|
+
attribute :fee_processing, LedgerEntryChanges
|
20
|
+
attribute :tx_apply_processing, TransactionMeta
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# This code was automatically generated using xdrgen
|
2
|
+
# DO NOT EDIT or your changes may be overwritten
|
3
|
+
|
4
|
+
require 'xdr'
|
5
|
+
|
6
|
+
# === xdr source ============================================================
|
7
|
+
#
|
8
|
+
# struct UpgradeEntryMeta
|
9
|
+
# {
|
10
|
+
# LedgerUpgrade upgrade;
|
11
|
+
# LedgerEntryChanges changes;
|
12
|
+
# };
|
13
|
+
#
|
14
|
+
# ===========================================================================
|
15
|
+
module Stellar
|
16
|
+
class UpgradeEntryMeta < XDR::Struct
|
17
|
+
attribute :upgrade, LedgerUpgrade
|
18
|
+
attribute :changes, LedgerEntryChanges
|
19
|
+
end
|
20
|
+
end
|
data/lib/stellar-base.rb
CHANGED
@@ -25,6 +25,7 @@ require_relative './stellar/price'
|
|
25
25
|
require_relative './stellar/signer_key'
|
26
26
|
require_relative './stellar/thresholds'
|
27
27
|
require_relative './stellar/transaction'
|
28
|
+
require_relative './stellar/transaction_builder'
|
28
29
|
require_relative './stellar/transaction_envelope'
|
29
30
|
require_relative './stellar/util/strkey'
|
30
31
|
require_relative './stellar/util/continued_fraction'
|
data/lib/stellar/base/version.rb
CHANGED
data/lib/stellar/operation.rb
CHANGED
@@ -43,7 +43,7 @@ module Stellar
|
|
43
43
|
# Stellar::PaymentOp body
|
44
44
|
def self.payment(attributes={})
|
45
45
|
destination = attributes[:destination]
|
46
|
-
asset, amount =
|
46
|
+
asset, amount = get_asset_amount(attributes[:amount])
|
47
47
|
|
48
48
|
raise ArgumentError unless destination.is_a?(KeyPair)
|
49
49
|
|
@@ -96,9 +96,11 @@ module Stellar
|
|
96
96
|
#
|
97
97
|
def self.path_payment_strict_receive(attributes={})
|
98
98
|
destination = attributes[:destination]
|
99
|
-
asset, amount =
|
100
|
-
send_asset, send_max =
|
101
|
-
path = (attributes[:path] || []).map{
|
99
|
+
asset, amount = get_asset_amount(attributes[:amount])
|
100
|
+
send_asset, send_max = get_asset_amount(attributes[:with])
|
101
|
+
path = (attributes[:path] || []).map{
|
102
|
+
|p| p.is_a?(Array) ? Stellar::Asset.send(*p) : p
|
103
|
+
}
|
102
104
|
|
103
105
|
raise ArgumentError unless destination.is_a?(KeyPair)
|
104
106
|
|
@@ -132,9 +134,11 @@ module Stellar
|
|
132
134
|
#
|
133
135
|
def self.path_payment_strict_send(attributes={})
|
134
136
|
destination = attributes[:destination]
|
135
|
-
asset, dest_min =
|
136
|
-
send_asset, send_amount =
|
137
|
-
path = (attributes[:path] || []).map{
|
137
|
+
asset, dest_min = get_asset_amount(attributes[:amount])
|
138
|
+
send_asset, send_amount = get_asset_amount(attributes[:with])
|
139
|
+
path = (attributes[:path] || []).map{
|
140
|
+
|p| p.is_a?(Array) ? Stellar::Asset.send(*p) : p
|
141
|
+
}
|
138
142
|
|
139
143
|
raise ArgumentError unless destination.is_a?(KeyPair)
|
140
144
|
|
@@ -199,11 +203,17 @@ module Stellar
|
|
199
203
|
end
|
200
204
|
|
201
205
|
def self.manage_sell_offer(attributes={})
|
202
|
-
buying
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
206
|
+
buying = attributes[:buying]
|
207
|
+
if buying.is_a?(Array)
|
208
|
+
buying = Asset.send(*buying)
|
209
|
+
end
|
210
|
+
selling = attributes[:selling]
|
211
|
+
if selling.is_a?(Array)
|
212
|
+
selling = Asset.send(*selling)
|
213
|
+
end
|
214
|
+
amount = interpret_amount(attributes[:amount])
|
215
|
+
offer_id = attributes[:offer_id] || 0
|
216
|
+
price = interpret_price(attributes[:price])
|
207
217
|
|
208
218
|
op = ManageSellOfferOp.new({
|
209
219
|
buying: buying,
|
@@ -219,11 +229,17 @@ module Stellar
|
|
219
229
|
end
|
220
230
|
|
221
231
|
def self.manage_buy_offer(attributes={})
|
222
|
-
buying
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
232
|
+
buying = attributes[:buying]
|
233
|
+
if buying.is_a?(Array)
|
234
|
+
buying = Asset.send(*buying)
|
235
|
+
end
|
236
|
+
selling = attributes[:selling]
|
237
|
+
if selling.is_a?(Array)
|
238
|
+
selling = Asset.send(*selling)
|
239
|
+
end
|
240
|
+
amount = interpret_amount(attributes[:amount])
|
241
|
+
offer_id = attributes[:offer_id] || 0
|
242
|
+
price = interpret_price(attributes[:price])
|
227
243
|
|
228
244
|
op = ManageBuyOfferOp.new({
|
229
245
|
buying: buying,
|
@@ -239,10 +255,16 @@ module Stellar
|
|
239
255
|
end
|
240
256
|
|
241
257
|
def self.create_passive_sell_offer(attributes={})
|
242
|
-
buying
|
243
|
-
|
244
|
-
|
245
|
-
|
258
|
+
buying = attributes[:buying]
|
259
|
+
if buying.is_a?(Array)
|
260
|
+
buying = Asset.send(*buying)
|
261
|
+
end
|
262
|
+
selling = attributes[:selling]
|
263
|
+
if selling.is_a?(Array)
|
264
|
+
selling = Asset.send(*selling)
|
265
|
+
end
|
266
|
+
amount = interpret_amount(attributes[:amount])
|
267
|
+
price = interpret_price(attributes[:price])
|
246
268
|
|
247
269
|
op = CreatePassiveSellOfferOp.new({
|
248
270
|
buying: buying,
|
@@ -309,9 +331,12 @@ module Stellar
|
|
309
331
|
def self.allow_trust(attributes={})
|
310
332
|
op = AllowTrustOp.new()
|
311
333
|
|
312
|
-
trustor
|
334
|
+
trustor = attributes[:trustor]
|
313
335
|
authorize = attributes[:authorize]
|
314
|
-
asset
|
336
|
+
asset = attributes[:asset]
|
337
|
+
if asset.is_a?(Array)
|
338
|
+
asset = Asset.send(*asset)
|
339
|
+
end
|
315
340
|
|
316
341
|
raise ArgumentError, "Bad :trustor" unless trustor.is_a?(Stellar::KeyPair)
|
317
342
|
raise ArgumentError, "Bad :authorize" unless authorize == !!authorize # check boolean
|
@@ -407,9 +432,13 @@ module Stellar
|
|
407
432
|
end
|
408
433
|
|
409
434
|
private
|
410
|
-
def self.
|
411
|
-
amount
|
412
|
-
|
435
|
+
def self.get_asset_amount(values)
|
436
|
+
amount = interpret_amount(values.last)
|
437
|
+
if values[0].is_a?(Stellar::Asset)
|
438
|
+
asset = values.first
|
439
|
+
else
|
440
|
+
asset = Stellar::Asset.send(*values[0...-1])
|
441
|
+
end
|
413
442
|
|
414
443
|
return asset, amount
|
415
444
|
end
|
data/lib/stellar/transaction.rb
CHANGED
@@ -91,6 +91,14 @@ module Stellar
|
|
91
91
|
make :bump_sequence, attributes
|
92
92
|
end
|
93
93
|
|
94
|
+
#
|
95
|
+
# DEPRECATED
|
96
|
+
#
|
97
|
+
# All methods calling make() have been deprecated in favor of Stellar::TransactionBuilder.
|
98
|
+
# These functions only create single-operation transactions and essentially duplicate the
|
99
|
+
# methods provided by Stellar::Operation. Stellar::TransactionBuilder enables the construction
|
100
|
+
# of multi-operation transactions and mirrors the functionality provided by the Python and
|
101
|
+
# JavaScript SDKs.
|
94
102
|
#
|
95
103
|
# Helper method to create a transaction with a single
|
96
104
|
# operation of the provided type. See class methods
|
@@ -104,6 +112,9 @@ module Stellar
|
|
104
112
|
#
|
105
113
|
# @return [Stellar::Transaction] the resulting transaction
|
106
114
|
def self.make(operation_type, attributes={})
|
115
|
+
Stellar::Deprecation.warn(
|
116
|
+
"Transaction.#{operation_type.to_s} is deprecated. Use Stellar::TransactionBuilder instead."
|
117
|
+
)
|
107
118
|
for_account(attributes).tap do |result|
|
108
119
|
result.operations << Operation.send(operation_type, attributes)
|
109
120
|
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
module Stellar
|
2
|
+
class TransactionBuilder
|
3
|
+
|
4
|
+
attr_reader :source_account, :sequence_number, :base_fee, :time_bounds, :time_bounds, :memo, :operations
|
5
|
+
|
6
|
+
def initialize(
|
7
|
+
source_account:,
|
8
|
+
sequence_number:,
|
9
|
+
base_fee: 100,
|
10
|
+
time_bounds: nil,
|
11
|
+
memo: nil
|
12
|
+
)
|
13
|
+
raise ArgumentError, "Bad :source_account" unless source_account.is_a?(Stellar::KeyPair)
|
14
|
+
raise ArgumentError, "Bad :sequence_number" unless sequence_number.is_a?(Integer) && sequence_number >= 0
|
15
|
+
raise ArgumentError, "Bad :time_bounds" unless time_bounds.is_a?(Stellar::TimeBounds) || time_bounds.nil?
|
16
|
+
raise ArgumentError, "Bad :base_fee" unless base_fee.is_a?(Integer) && base_fee >= 100
|
17
|
+
|
18
|
+
@source_account = source_account
|
19
|
+
@sequence_number = sequence_number
|
20
|
+
@base_fee = base_fee
|
21
|
+
@time_bounds = time_bounds
|
22
|
+
@memo = self.make_memo(memo)
|
23
|
+
@operations = Array.new
|
24
|
+
end
|
25
|
+
|
26
|
+
def build
|
27
|
+
if @time_bounds.nil?
|
28
|
+
raise "TransactionBuilder.time_bounds must be set during initialization or by calling set_timeout"
|
29
|
+
elsif !@time_bounds.min_time.is_a?(Integer) || !@time_bounds.max_time.is_a?(Integer)
|
30
|
+
raise "TimeBounds.min_time and max_time must be Integers"
|
31
|
+
elsif @time_bounds.max_time != 0 && @time_bounds.min_time > @time_bounds.max_time
|
32
|
+
raise "Timebounds.max_time must be greater than min_time"
|
33
|
+
end
|
34
|
+
tx = Stellar::Transaction.new(
|
35
|
+
source_account: @source_account.account_id,
|
36
|
+
fee: @base_fee * @operations.length,
|
37
|
+
seq_num: @sequence_number,
|
38
|
+
time_bounds: @time_bounds,
|
39
|
+
memo: @memo,
|
40
|
+
operations: @operations,
|
41
|
+
ext: Stellar::Transaction::Ext.new(0)
|
42
|
+
)
|
43
|
+
@sequence_number += 1
|
44
|
+
tx
|
45
|
+
end
|
46
|
+
|
47
|
+
def add_operation(operation)
|
48
|
+
raise ArgumentError, "Bad operation" unless operation.is_a? Stellar::Operation
|
49
|
+
@operations.push(operation)
|
50
|
+
self
|
51
|
+
end
|
52
|
+
|
53
|
+
def clear_operations()
|
54
|
+
@operations.clear
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
def set_sequence_number(seq_num)
|
59
|
+
raise ArgumentError, "Bad sequence number" unless seq_num.is_a?(Integer) && seq_num >= 0
|
60
|
+
@sequence_number = seq_num
|
61
|
+
self
|
62
|
+
end
|
63
|
+
|
64
|
+
def set_timeout(timeout)
|
65
|
+
if !timeout.is_a?(Integer) || timeout < 0
|
66
|
+
raise ArgumentError, "Timeout must be a non-negative integer"
|
67
|
+
end
|
68
|
+
|
69
|
+
if @time_bounds.nil?
|
70
|
+
@time_bounds = Stellar::TimeBounds.new(min_time: 0, max_time: nil)
|
71
|
+
end
|
72
|
+
|
73
|
+
if timeout == 0
|
74
|
+
@time_bounds.max_time = timeout
|
75
|
+
else
|
76
|
+
@time_bounds.max_time = Time.now.to_i + timeout
|
77
|
+
end
|
78
|
+
|
79
|
+
self
|
80
|
+
end
|
81
|
+
|
82
|
+
def set_memo(memo)
|
83
|
+
@memo = make_memo(memo)
|
84
|
+
self
|
85
|
+
end
|
86
|
+
|
87
|
+
def make_memo(memo)
|
88
|
+
case memo
|
89
|
+
when Stellar::Memo ;
|
90
|
+
memo
|
91
|
+
when nil ;
|
92
|
+
Memo.new(:memo_none)
|
93
|
+
when Integer ;
|
94
|
+
Memo.new(:memo_id, memo)
|
95
|
+
when String ;
|
96
|
+
Memo.new(:memo_text, memo)
|
97
|
+
when Array ;
|
98
|
+
t, val = *memo
|
99
|
+
Memo.new(:"memo_#{t}", val)
|
100
|
+
else
|
101
|
+
raise ArgumentError, "Bad :memo"
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
data/ruby-stellar-base.gemspec
CHANGED
@@ -7,7 +7,7 @@ Gem::Specification.new do |spec|
|
|
7
7
|
spec.authors = ["Scott Fleckenstein"]
|
8
8
|
spec.email = ["scott@stellar.org"]
|
9
9
|
spec.summary = %q{Stellar client library: XDR}
|
10
|
-
spec.homepage = "https://github.com/
|
10
|
+
spec.homepage = "https://github.com/stellar/ruby-stellar-base"
|
11
11
|
spec.license = "Apache 2.0"
|
12
12
|
|
13
13
|
spec.files = `git ls-files -z`.split("\x0")
|
@@ -1,15 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Stellar::Operation, ".payment" do
|
4
|
-
|
5
|
-
|
6
4
|
it "correctly translates the provided amount to the native representation" do
|
7
5
|
op = Stellar::Operation.payment(destination: Stellar::KeyPair.random, amount: [:native, 20])
|
8
6
|
expect(op.body.value.amount).to eql(20_0000000)
|
9
7
|
op = Stellar::Operation.payment(destination: Stellar::KeyPair.random, amount: [:native, "20"])
|
10
8
|
expect(op.body.value.amount).to eql(20_0000000)
|
11
9
|
end
|
12
|
-
|
13
10
|
end
|
14
11
|
|
15
12
|
def pk_to_address(pk)
|
@@ -22,13 +19,14 @@ describe "path payment operations" do
|
|
22
19
|
let(:send_asset){ Stellar::Asset.alphanum4("USD", send_asset_issuer) }
|
23
20
|
let(:dest_asset_issuer){ Stellar::KeyPair.master }
|
24
21
|
let(:dest_asset){ Stellar::Asset.alphanum4("EUR", dest_asset_issuer) }
|
25
|
-
let(:amount){ [
|
26
|
-
let(:with){ [
|
22
|
+
let(:amount){ [Stellar::Asset.alphanum4(dest_asset.code, dest_asset_issuer), 9.2] }
|
23
|
+
let(:with){ [Stellar::Asset.alphanum4(send_asset.code, send_asset_issuer), 10] }
|
27
24
|
|
28
25
|
describe Stellar::Operation, ".path_payment" do
|
29
26
|
it "works" do
|
30
27
|
destination = Stellar::KeyPair.random
|
31
|
-
|
28
|
+
# test both forms of arrays
|
29
|
+
amount = [Stellar::Asset.alphanum4("USD", Stellar::KeyPair.master), 10]
|
32
30
|
with = [:alphanum4, "EUR", Stellar::KeyPair.master, 9.2]
|
33
31
|
|
34
32
|
op = Stellar::Operation.path_payment(
|
@@ -98,7 +96,7 @@ describe Stellar::Operation, ".change_trust" do
|
|
98
96
|
let(:asset) { Stellar::Asset.alphanum4("USD", issuer) }
|
99
97
|
|
100
98
|
it "creates a ChangeTrustOp" do
|
101
|
-
op = Stellar::Operation.change_trust(line:
|
99
|
+
op = Stellar::Operation.change_trust(line: Stellar::Asset.alphanum4("USD", issuer))
|
102
100
|
expect(op.body.value).to be_an_instance_of(Stellar::ChangeTrustOp)
|
103
101
|
expect(op.body.value.line).to eq(Stellar::Asset.alphanum4("USD", issuer))
|
104
102
|
expect(op.body.value.limit).to eq(9223372036854775807)
|
@@ -119,7 +117,7 @@ describe Stellar::Operation, ".change_trust" do
|
|
119
117
|
end
|
120
118
|
|
121
119
|
it "creates a ChangeTrustOp with limit" do
|
122
|
-
op = Stellar::Operation.change_trust(line:
|
120
|
+
op = Stellar::Operation.change_trust(line: Stellar::Asset.alphanum4("USD", issuer), limit: 1234.75)
|
123
121
|
expect(op.body.value).to be_an_instance_of(Stellar::ChangeTrustOp)
|
124
122
|
expect(op.body.value.line).to eq(Stellar::Asset.alphanum4("USD", issuer))
|
125
123
|
expect(op.body.value.limit).to eq(12347500000)
|
@@ -127,7 +125,7 @@ describe Stellar::Operation, ".change_trust" do
|
|
127
125
|
|
128
126
|
it "throws ArgumentError for incorrect limit argument" do
|
129
127
|
expect {
|
130
|
-
Stellar::Operation.change_trust(line:
|
128
|
+
Stellar::Operation.change_trust(line: Stellar::Asset.alphanum4("USD", issuer), limit: true)
|
131
129
|
}.to raise_error(ArgumentError)
|
132
130
|
end
|
133
131
|
end
|
@@ -0,0 +1,263 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Stellar::TransactionBuilder do
|
4
|
+
let(:key_pair){ Stellar::KeyPair.random }
|
5
|
+
builder = nil
|
6
|
+
before(:each) do
|
7
|
+
builder = Stellar::TransactionBuilder.new(
|
8
|
+
source_account: key_pair,
|
9
|
+
sequence_number: 1
|
10
|
+
)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".initialize" do
|
14
|
+
it "bad source_account" do
|
15
|
+
expect {
|
16
|
+
Stellar::TransactionBuilder.new(
|
17
|
+
source_account: key_pair.account_id,
|
18
|
+
sequence_number: 1
|
19
|
+
)
|
20
|
+
}.to raise_error(
|
21
|
+
ArgumentError, "Bad :source_account"
|
22
|
+
)
|
23
|
+
end
|
24
|
+
it "bad sequence_number" do
|
25
|
+
expect {
|
26
|
+
Stellar::TransactionBuilder.new(
|
27
|
+
source_account: key_pair,
|
28
|
+
sequence_number: -1
|
29
|
+
)
|
30
|
+
}.to raise_error(
|
31
|
+
ArgumentError, "Bad :sequence_number"
|
32
|
+
)
|
33
|
+
end
|
34
|
+
it "bad timeout" do
|
35
|
+
expect {
|
36
|
+
Stellar::TransactionBuilder.new(
|
37
|
+
source_account: key_pair,
|
38
|
+
sequence_number: 1,
|
39
|
+
time_bounds: 600
|
40
|
+
)
|
41
|
+
}.to raise_error(
|
42
|
+
ArgumentError, "Bad :time_bounds"
|
43
|
+
)
|
44
|
+
end
|
45
|
+
it "bad base_fee" do
|
46
|
+
expect {
|
47
|
+
Stellar::TransactionBuilder.new(
|
48
|
+
source_account: key_pair,
|
49
|
+
sequence_number: 1,
|
50
|
+
base_fee: 0
|
51
|
+
)
|
52
|
+
}.to raise_error(
|
53
|
+
ArgumentError, "Bad :base_fee"
|
54
|
+
)
|
55
|
+
end
|
56
|
+
it "bad memo" do
|
57
|
+
expect {
|
58
|
+
Stellar::TransactionBuilder.new(
|
59
|
+
source_account: key_pair,
|
60
|
+
sequence_number: 1,
|
61
|
+
memo: {"data" => "Testing bad memo"}
|
62
|
+
)
|
63
|
+
}.to raise_error(
|
64
|
+
ArgumentError, "Bad :memo"
|
65
|
+
)
|
66
|
+
end
|
67
|
+
it "success" do
|
68
|
+
builder = Stellar::TransactionBuilder.new(
|
69
|
+
source_account: key_pair,
|
70
|
+
sequence_number: 1,
|
71
|
+
time_bounds: Stellar::TimeBounds.new(min_time: 0, max_time: 600),
|
72
|
+
base_fee: 200,
|
73
|
+
memo: "My test memo"
|
74
|
+
)
|
75
|
+
expect(builder.memo).to eql(Stellar::Memo.new(:memo_text, "My test memo"))
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe ".add_operation" do
|
80
|
+
it "bad operation" do
|
81
|
+
expect {
|
82
|
+
builder.add_operation(
|
83
|
+
[:bump_sequence, 1]
|
84
|
+
)
|
85
|
+
}.to raise_error(
|
86
|
+
ArgumentError, "Bad operation"
|
87
|
+
)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "returns self" do
|
91
|
+
expect(builder.add_operation(
|
92
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
93
|
+
)).to be_an_instance_of(Stellar::TransactionBuilder)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe ".clear_operations" do
|
98
|
+
it "can clear operations" do
|
99
|
+
builder = builder.add_operation(
|
100
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
101
|
+
).clear_operations
|
102
|
+
expect(builder.operations).to eql([])
|
103
|
+
end
|
104
|
+
|
105
|
+
it "returns self" do
|
106
|
+
expect(builder.add_operation(
|
107
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
108
|
+
).clear_operations).to be_an_instance_of(Stellar::TransactionBuilder)
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe ".set_sequence_number" do
|
113
|
+
it "allows sequence number to be updated" do
|
114
|
+
builder.set_sequence_number(5)
|
115
|
+
expect(builder.sequence_number).to eql(5)
|
116
|
+
end
|
117
|
+
|
118
|
+
it "returns self" do
|
119
|
+
expect(builder.set_sequence_number(3)).to be_an_instance_of(Stellar::TransactionBuilder)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "raises an error for bad sequence number" do
|
123
|
+
expect {
|
124
|
+
builder.set_sequence_number(nil)
|
125
|
+
}.to raise_error(
|
126
|
+
ArgumentError, "Bad sequence number"
|
127
|
+
)
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
describe ".set_timeout" do
|
132
|
+
it "raises an error for non-integers" do
|
133
|
+
expect {
|
134
|
+
builder.set_timeout(nil)
|
135
|
+
}.to raise_error(
|
136
|
+
ArgumentError, "Timeout must be a non-negative integer"
|
137
|
+
)
|
138
|
+
end
|
139
|
+
|
140
|
+
it "raises an error for negative timeouts" do
|
141
|
+
expect {
|
142
|
+
builder.set_timeout(-1)
|
143
|
+
}.to raise_error(
|
144
|
+
ArgumentError, "Timeout must be a non-negative integer"
|
145
|
+
)
|
146
|
+
end
|
147
|
+
|
148
|
+
it "returns self" do
|
149
|
+
expect(builder.set_timeout(10)).to be_an_instance_of(Stellar::TransactionBuilder)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
describe ".set_memo" do
|
154
|
+
it "raises an error for bad memos" do
|
155
|
+
expect {
|
156
|
+
builder.set_memo({"data" => "Testing bad memo"})
|
157
|
+
}.to raise_error(
|
158
|
+
ArgumentError, "Bad :memo"
|
159
|
+
)
|
160
|
+
end
|
161
|
+
|
162
|
+
it "works and returns self" do
|
163
|
+
expect(builder.set_memo("Hello").memo).to eql(Stellar::Memo.new(:memo_text, "Hello"))
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
describe ".build" do
|
168
|
+
it "raises error for time_bounds not set" do
|
169
|
+
expect {
|
170
|
+
tx = builder.add_operation(
|
171
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
172
|
+
).build()
|
173
|
+
}.to raise_error(
|
174
|
+
RuntimeError,
|
175
|
+
"TransactionBuilder.time_bounds must be set during initialization or by calling set_timeout"
|
176
|
+
)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "raises an error for non-integer timebounds" do
|
180
|
+
builder = Stellar::TransactionBuilder.new(
|
181
|
+
source_account: key_pair,
|
182
|
+
sequence_number: 1,
|
183
|
+
time_bounds: Stellar::TimeBounds.new(min_time: "not", max_time: "integers")
|
184
|
+
)
|
185
|
+
expect {
|
186
|
+
tx = builder.add_operation(
|
187
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
188
|
+
).build()
|
189
|
+
}.to raise_error(
|
190
|
+
RuntimeError, "TimeBounds.min_time and max_time must be Integers"
|
191
|
+
)
|
192
|
+
end
|
193
|
+
|
194
|
+
it "raises an error for bad TimeBounds range" do
|
195
|
+
builder = Stellar::TransactionBuilder.new(
|
196
|
+
source_account: key_pair,
|
197
|
+
sequence_number: 1,
|
198
|
+
time_bounds: Stellar::TimeBounds.new(min_time: Time.now.to_i + 10, max_time: Time.now.to_i)
|
199
|
+
)
|
200
|
+
expect {
|
201
|
+
tx = builder.add_operation(
|
202
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
203
|
+
).build()
|
204
|
+
}.to raise_error(
|
205
|
+
RuntimeError, "Timebounds.max_time must be greater than min_time"
|
206
|
+
)
|
207
|
+
end
|
208
|
+
|
209
|
+
it "allows max_time to be zero" do
|
210
|
+
tx = builder.add_operation(
|
211
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
212
|
+
).set_timeout(0).build()
|
213
|
+
expect(builder.time_bounds.max_time).to eql(0)
|
214
|
+
end
|
215
|
+
|
216
|
+
it "updates sequence number by 1 per build" do
|
217
|
+
builder.add_operation(
|
218
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
219
|
+
).set_timeout(0).build()
|
220
|
+
expect(builder.sequence_number).to eql(2)
|
221
|
+
end
|
222
|
+
|
223
|
+
it "creates transaction successfully" do
|
224
|
+
bump_op = Stellar::Operation.bump_sequence({"bump_to": 1})
|
225
|
+
builder.add_operation(
|
226
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
227
|
+
).set_timeout(600).build()
|
228
|
+
expect(builder.operations).to eql([bump_op])
|
229
|
+
end
|
230
|
+
|
231
|
+
it "allows for multiple transactions to be created" do
|
232
|
+
first_max_time = Time.now.to_i + 1000
|
233
|
+
bump_op = Stellar::Operation.bump_sequence({"bump_to": 1})
|
234
|
+
builder = Stellar::TransactionBuilder.new(
|
235
|
+
source_account: key_pair,
|
236
|
+
sequence_number: 1,
|
237
|
+
time_bounds: Stellar::TimeBounds.new(min_time: 0, max_time: first_max_time)
|
238
|
+
)
|
239
|
+
tx1 = builder.add_operation(
|
240
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
241
|
+
).build()
|
242
|
+
expect(tx1.seq_num).to eql(1)
|
243
|
+
expect(tx1.operations).to eql([
|
244
|
+
Stellar::Operation.bump_sequence({"bump_to": 1})
|
245
|
+
])
|
246
|
+
expect(tx1.time_bounds.max_time).to eql(first_max_time)
|
247
|
+
|
248
|
+
tx2 = builder.clear_operations.add_operation(
|
249
|
+
Stellar::Operation.bump_sequence({"bump_to": 2})
|
250
|
+
).set_timeout(0).build()
|
251
|
+
expect(tx2.seq_num).to eql(2)
|
252
|
+
expect(tx2.operations).to eql([
|
253
|
+
Stellar::Operation.bump_sequence({"bump_to": 2})
|
254
|
+
])
|
255
|
+
expect(tx2.time_bounds.max_time).to eql(0)
|
256
|
+
|
257
|
+
expect(builder.sequence_number).to eql(3)
|
258
|
+
expect(builder.operations).to eql([
|
259
|
+
Stellar::Operation.bump_sequence({"bump_to": 2})
|
260
|
+
])
|
261
|
+
end
|
262
|
+
end
|
263
|
+
end
|