Class: Stellar::TransactionBuilder

Inherits:
Object
  • Object
show all
Includes:
DSL
Defined in:
lib/stellar/transaction_builder.rb

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from DSL

Account, Asset, ClaimPredicate, Claimant, KeyPair, SignerKey

Constructor Details

#initialize(source_account:, sequence_number:, base_fee: 100, time_bounds: nil, memo: nil, enable_muxed_accounts: false, **_) ⇒ TransactionBuilder

Returns a new instance of TransactionBuilder.

Raises:

  • (ArgumentError)


28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/stellar/transaction_builder.rb', line 28

def initialize(
  source_account:,
  sequence_number:,
  base_fee: 100,
  time_bounds: nil,
  memo: nil,
  enable_muxed_accounts: false,
  **_ # ignore any additional parameters without errors
)
  raise ArgumentError, "Bad :sequence_number" unless sequence_number.is_a?(Integer) && sequence_number >= 0
  raise ArgumentError, "Bad :time_bounds" unless time_bounds.is_a?(Stellar::TimeBounds) || time_bounds.nil?
  raise ArgumentError, "Bad :base_fee" unless base_fee.is_a?(Integer) && base_fee >= 100

  @source_account = Account()
  @sequence_number = sequence_number
  @base_fee = base_fee
  @time_bounds = time_bounds
  @enable_muxed_accounts = enable_muxed_accounts

  set_timeout(0) if time_bounds.nil?

  @memo = make_memo(memo)
  @operations = []
end

Instance Attribute Details

#base_feeObject (readonly)

Returns the value of attribute base_fee.



5
6
7
# File 'lib/stellar/transaction_builder.rb', line 5

def base_fee
  @base_fee
end

#memoObject (readonly)

Returns the value of attribute memo.



5
6
7
# File 'lib/stellar/transaction_builder.rb', line 5

def memo
  @memo
end

#operationsObject (readonly)

Returns the value of attribute operations.



5
6
7
# File 'lib/stellar/transaction_builder.rb', line 5

def operations
  @operations
end

#sequence_numberObject (readonly)

Returns the value of attribute sequence_number.



5
6
7
# File 'lib/stellar/transaction_builder.rb', line 5

def sequence_number
  @sequence_number
end

#source_accountObject (readonly)

Returns the value of attribute source_account.



5
6
7
# File 'lib/stellar/transaction_builder.rb', line 5

def 
  @source_account
end

#time_boundsObject (readonly)

Returns the value of attribute time_bounds.



5
6
7
# File 'lib/stellar/transaction_builder.rb', line 5

def time_bounds
  @time_bounds
end

Class Method Details

.method_missing(method_name, *args, **kwargs) ⇒ Object

This enable user to call shortcut methods, like TransactionBuilder.payment(…), TransactionBuilder.manage_data(…) and etc. It reduces the boilerplate, when you just need to shoot a single operation in transaction



13
14
15
16
17
18
19
20
21
# File 'lib/stellar/transaction_builder.rb', line 13

def method_missing(method_name, *args, **kwargs)
  unless Stellar::Operation.respond_to?(method_name)
    return super
  end

  op = Stellar::Operation.send(method_name, **kwargs)

  new(**kwargs).add_operation(op).build
end

.respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


23
24
25
# File 'lib/stellar/transaction_builder.rb', line 23

def respond_to_missing?(method_name, include_private = false)
  Stellar::Operation.respond_to?(method_name) || super
end

Instance Method Details

#add_operation(operation) ⇒ Object

Raises:

  • (ArgumentError)


101
102
103
104
105
# File 'lib/stellar/transaction_builder.rb', line 101

def add_operation(operation)
  raise ArgumentError, "Bad operation" unless operation.is_a? Stellar::Operation
  @operations.push(operation)
  self
end

#buildObject



53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/stellar/transaction_builder.rb', line 53

def build
  if @time_bounds.nil?
    raise "TransactionBuilder.time_bounds must be set during initialization or by calling set_timeout"
  elsif !@time_bounds.min_time.is_a?(Integer) || !@time_bounds.max_time.is_a?(Integer)
    raise "TimeBounds.min_time and max_time must be Integers"
  elsif @time_bounds.max_time != 0 && @time_bounds.min_time > @time_bounds.max_time
    raise "Timebounds.max_time must be greater than min_time"
  end

  attrs = {
    source_account: ,
    fee: @base_fee * @operations.length,
    seq_num: @sequence_number,
    time_bounds: @time_bounds,
    memo: @memo,
    operations: @operations,
    ext: Stellar::Transaction::Ext.new(0)
  }

  @sequence_number += 1

  Stellar::Transaction.new(attrs)
end

#build_fee_bump(inner_txe:) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/stellar/transaction_builder.rb', line 77

def build_fee_bump(inner_txe:)
  if inner_txe.switch == Stellar::EnvelopeType.envelope_type_tx_v0
    inner_txe = Stellar::TransactionEnvelope.v1(tx: inner_txe.tx.to_v1, signatures: inner_txe.signatures)
  elsif inner_txe.switch != Stellar::EnvelopeType.envelope_type_tx
    raise ArgumentError, "Invalid inner transaction type #{inner_txe.switch}"
  end

  inner_tx = inner_txe.tx
  inner_ops = inner_tx.operations
  inner_base_fee_rate = inner_tx.fee.fdiv(inner_ops.length)

  # The fee rate for fee bump is at least the fee rate of the inner transaction
  if @base_fee < inner_base_fee_rate
    raise "Insufficient base_fee, it should be at least #{inner_base_fee_rate} stroops."
  end

  Stellar::FeeBumpTransaction.new(
    fee_source: ,
    fee: @base_fee * (inner_ops.length + 1),
    inner_tx: Stellar::FeeBumpTransaction::InnerTx.new(:envelope_type_tx, inner_txe.v1!),
    ext: Stellar::FeeBumpTransaction::Ext.new(0)
  )
end

#clear_operationsObject



107
108
109
110
# File 'lib/stellar/transaction_builder.rb', line 107

def clear_operations
  @operations.clear
  self
end

#make_memo(memo) ⇒ Object



149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
# File 'lib/stellar/transaction_builder.rb', line 149

def make_memo(memo)
  case memo
  when Stellar::Memo
    memo
  when nil
    Memo.new(:memo_none)
  when Integer
    Memo.new(:memo_id, memo)
  when String
    Memo.new(:memo_text, memo)
  when Array
    t, val = *memo
    Memo.new(:"memo_#{t}", val)
  else
    raise ArgumentError, "Bad :memo"
  end
end

#set_base_fee(base_fee) ⇒ Object

Raises:

  • (ArgumentError)


143
144
145
146
147
# File 'lib/stellar/transaction_builder.rb', line 143

def set_base_fee(base_fee)
  raise ArgumentError, "Bad base fee" unless base_fee.is_a?(Integer) && base_fee >= 100
  @base_fee = base_fee
  self
end

#set_memo(memo) ⇒ Object



138
139
140
141
# File 'lib/stellar/transaction_builder.rb', line 138

def set_memo(memo)
  @memo = make_memo(memo)
  self
end

#set_sequence_number(seq_num) ⇒ Object

Raises:

  • (ArgumentError)


118
119
120
121
122
# File 'lib/stellar/transaction_builder.rb', line 118

def set_sequence_number(seq_num)
  raise ArgumentError, "Bad sequence number" unless seq_num.is_a?(Integer) && seq_num >= 0
  @sequence_number = seq_num
  self
end

#set_source_account(account_kp) ⇒ Object

Raises:

  • (ArgumentError)


112
113
114
115
116
# File 'lib/stellar/transaction_builder.rb', line 112

def ()
  raise ArgumentError, "Bad source account" unless .is_a?(Stellar::KeyPair)
  @source_account = 
  self
end

#set_timeout(timeout) ⇒ Object



124
125
126
127
128
129
130
131
132
133
134
135
136
# File 'lib/stellar/transaction_builder.rb', line 124

def set_timeout(timeout)
  if !timeout.is_a?(Integer) || timeout < 0
    raise ArgumentError, "Timeout must be a non-negative integer"
  end

  if @time_bounds.nil?
    @time_bounds = Stellar::TimeBounds.new(min_time: 0, max_time: nil)
  end

  @time_bounds.max_time = timeout == 0 ? timeout : Time.now.to_i + timeout

  self
end

#source_muxed_accountObject



167
168
169
170
171
172
173
# File 'lib/stellar/transaction_builder.rb', line 167

def 
  if with_muxed_accounts?
    @source_account.
  else
    @source_account.
  end
end

#with_muxed_accounts?Boolean

Returns:

  • (Boolean)


175
176
177
# File 'lib/stellar/transaction_builder.rb', line 175

def with_muxed_accounts?
  @enable_muxed_accounts
end