stellar-base 0.24.0 → 0.28.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/CHANGELOG.md +79 -56
- data/README.md +7 -7
- data/generated/stellar-base-generated.rb +15 -0
- data/generated/stellar/account_flags.rb +9 -4
- data/generated/stellar/account_merge_result.rb +1 -1
- data/generated/stellar/allow_trust_op.rb +3 -18
- data/generated/stellar/asset_code.rb +30 -0
- data/generated/stellar/begin_sponsoring_future_reserves_result.rb +2 -1
- data/generated/stellar/claimable_balance_entry.rb +2 -0
- data/generated/stellar/claimable_balance_entry/ext.rb +4 -0
- data/generated/stellar/claimable_balance_entry_extension_v1.rb +30 -0
- data/generated/stellar/claimable_balance_entry_extension_v1/ext.rb +24 -0
- data/generated/stellar/claimable_balance_flags.rb +22 -0
- data/generated/stellar/clawback_claimable_balance_op.rb +18 -0
- data/generated/stellar/clawback_claimable_balance_result.rb +26 -0
- data/generated/stellar/clawback_claimable_balance_result_code.rb +29 -0
- data/generated/stellar/clawback_op.rb +22 -0
- data/generated/stellar/clawback_result.rb +25 -0
- data/generated/stellar/clawback_result_code.rb +31 -0
- data/generated/stellar/create_passive_sell_offer_op.rb +1 -1
- data/generated/stellar/end_sponsoring_future_reserves_result.rb +2 -1
- data/generated/stellar/operation.rb +6 -0
- data/generated/stellar/operation/body.rb +12 -0
- data/generated/stellar/operation_id.rb +1 -1
- data/generated/stellar/operation_id/id.rb +2 -2
- data/generated/stellar/operation_result.rb +6 -0
- data/generated/stellar/operation_result/tr.rb +12 -0
- data/generated/stellar/operation_type.rb +7 -1
- data/generated/stellar/payment_result_code.rb +1 -1
- data/generated/stellar/revoke_sponsorship_op.rb +1 -2
- data/generated/stellar/set_options_result_code.rb +14 -11
- data/generated/stellar/set_trust_line_flags_op.rb +25 -0
- data/generated/stellar/set_trust_line_flags_result.rb +25 -0
- data/generated/stellar/set_trust_line_flags_result_code.rb +31 -0
- data/generated/stellar/transaction_result_code.rb +1 -1
- data/generated/stellar/trust_line_flags.rb +5 -1
- data/lib/stellar-base.rb +6 -2
- data/lib/stellar/account.rb +59 -0
- data/lib/stellar/asset.rb +10 -0
- data/lib/stellar/compat.rb +6 -7
- data/lib/stellar/concerns/transaction.rb +5 -4
- data/lib/stellar/dsl.rb +32 -5
- data/lib/stellar/ext/xdr.rb +8 -7
- data/lib/stellar/key_pair.rb +22 -23
- data/lib/stellar/ledger_key.rb +4 -2
- data/lib/stellar/muxed_account.rb +16 -0
- data/lib/stellar/operation.rb +89 -19
- data/lib/stellar/transaction.rb +1 -1
- data/lib/stellar/transaction_builder.rb +20 -7
- data/lib/stellar/transaction_envelope.rb +6 -16
- data/lib/stellar/transaction_v0.rb +2 -10
- data/lib/stellar/trust_line_flags.rb +53 -0
- data/lib/stellar/util/strkey.rb +15 -7
- data/lib/stellar/version.rb +3 -0
- metadata +34 -16
- data/generated/stellar/allow_trust_op/asset.rb +0 -33
- data/lib/stellar/base/version.rb +0 -5
data/lib/stellar/ext/xdr.rb
CHANGED
@@ -39,11 +39,12 @@ XDR::DSL::Union.redefine_method(:switch) do |switch, arm = nil|
|
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
42
|
-
# XDR::Union
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
42
|
+
# XDR::Union delegates missing methods to the underlying value
|
43
|
+
XDR::Union.define_method(:method_missing) do |name, *args|
|
44
|
+
return super(name, *args) unless value&.respond_to?(name)
|
45
|
+
value&.public_send(name, *args)
|
46
|
+
end
|
47
|
+
|
48
|
+
XDR::Union.define_method(:respond_to_missing?) do |*args|
|
49
|
+
value&.respond_to?(*args)
|
49
50
|
end
|
data/lib/stellar/key_pair.rb
CHANGED
@@ -6,6 +6,11 @@ module Stellar
|
|
6
6
|
from_raw_seed seed_bytes
|
7
7
|
end
|
8
8
|
|
9
|
+
def from_address(address)
|
10
|
+
pk_bytes = Util::StrKey.check_decode(:account_id, address)
|
11
|
+
from_public_key(pk_bytes)
|
12
|
+
end
|
13
|
+
|
9
14
|
def from_raw_seed(seed_bytes)
|
10
15
|
secret_key = RbNaCl::SigningKey.new(seed_bytes)
|
11
16
|
public_key = secret_key.verify_key
|
@@ -17,11 +22,6 @@ module Stellar
|
|
17
22
|
new(public_key)
|
18
23
|
end
|
19
24
|
|
20
|
-
def from_address(address)
|
21
|
-
pk_bytes = Util::StrKey.check_decode(:account_id, address)
|
22
|
-
from_public_key(pk_bytes)
|
23
|
-
end
|
24
|
-
|
25
25
|
def random
|
26
26
|
secret_key = RbNaCl::SigningKey.generate
|
27
27
|
public_key = secret_key.verify_key
|
@@ -40,11 +40,21 @@ module Stellar
|
|
40
40
|
|
41
41
|
extend FactoryMethods
|
42
42
|
|
43
|
+
# @param [RbNaCl::VerifyKey] public_key
|
44
|
+
# @param [RbNaCl::SigningKey, nil] secret_key
|
43
45
|
def initialize(public_key, secret_key = nil)
|
44
46
|
@public_key = public_key
|
45
47
|
@secret_key = secret_key
|
46
48
|
end
|
47
49
|
|
50
|
+
def address
|
51
|
+
Util::StrKey.check_encode(:account_id, raw_public_key)
|
52
|
+
end
|
53
|
+
|
54
|
+
def seed
|
55
|
+
Util::StrKey.check_encode(:seed, raw_seed)
|
56
|
+
end
|
57
|
+
|
48
58
|
def account_id
|
49
59
|
Stellar::AccountID.new :public_key_type_ed25519, raw_public_key
|
50
60
|
end
|
@@ -61,16 +71,17 @@ module Stellar
|
|
61
71
|
Stellar::SignerKey.new :signer_key_type_ed25519, raw_public_key
|
62
72
|
end
|
63
73
|
|
64
|
-
def raw_public_key
|
65
|
-
@public_key.to_bytes
|
66
|
-
end
|
67
|
-
|
68
74
|
def signature_hint
|
69
75
|
# take last 4 bytes
|
70
76
|
account_id.to_xdr.slice(-4, 4)
|
71
77
|
end
|
72
78
|
|
79
|
+
def raw_public_key
|
80
|
+
@public_key.to_bytes
|
81
|
+
end
|
82
|
+
|
73
83
|
def raw_seed
|
84
|
+
raise "no private key" if @secret_key.nil?
|
74
85
|
@secret_key.to_bytes
|
75
86
|
end
|
76
87
|
|
@@ -82,25 +93,13 @@ module Stellar
|
|
82
93
|
@public_key
|
83
94
|
end
|
84
95
|
|
85
|
-
def address
|
86
|
-
pk_bytes = raw_public_key
|
87
|
-
Util::StrKey.check_encode(:account_id, pk_bytes)
|
88
|
-
end
|
89
|
-
|
90
|
-
def seed
|
91
|
-
raise "no private key" if @secret_key.nil?
|
92
|
-
# TODO: improve the error class above
|
93
|
-
seed_bytes = raw_seed
|
94
|
-
Util::StrKey.check_encode(:seed, seed_bytes)
|
95
|
-
end
|
96
|
-
|
97
96
|
def sign?
|
98
97
|
!@secret_key.nil?
|
99
98
|
end
|
100
99
|
|
101
100
|
def sign(message)
|
102
|
-
raise "no private key"
|
103
|
-
|
101
|
+
raise NotImplementedError, "no private key, signing is not available" unless sign?
|
102
|
+
|
104
103
|
@secret_key.sign(message)
|
105
104
|
end
|
106
105
|
|
data/lib/stellar/ledger_key.rb
CHANGED
@@ -4,6 +4,8 @@ require "stellar/dsl"
|
|
4
4
|
module Stellar
|
5
5
|
class LedgerKey
|
6
6
|
class << self
|
7
|
+
include Stellar::DSL
|
8
|
+
|
7
9
|
def switch_for_arm(name)
|
8
10
|
(@switch_by_arm ||= switches.invert).fetch(name)
|
9
11
|
end
|
@@ -12,7 +14,7 @@ module Stellar
|
|
12
14
|
field, value = options.first
|
13
15
|
case field
|
14
16
|
when nil
|
15
|
-
account(account_id:
|
17
|
+
account(account_id: KeyPair(account_id).account_id)
|
16
18
|
when :balance_id
|
17
19
|
claimable_balance(balance_id: ClaimableBalanceID.v0(Stellar::Convert.from_hex(value.to_s)))
|
18
20
|
when :offer_id
|
@@ -20,7 +22,7 @@ module Stellar
|
|
20
22
|
when :data_name
|
21
23
|
data(account_id: account_id, data_name: value.to_s)
|
22
24
|
when :asset
|
23
|
-
trust_line(account_id: account_id, asset:
|
25
|
+
trust_line(account_id: account_id, asset: Asset(value))
|
24
26
|
else
|
25
27
|
raise ArgumentError, "unknown option #{field} (not in :asset, :offer_id, :data_name, :balance_id)"
|
26
28
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Stellar
|
2
|
+
class MuxedAccount
|
3
|
+
def to_keypair
|
4
|
+
case arm
|
5
|
+
when :ed25519 then KeyPair.from_public_key(value)
|
6
|
+
when :med25519 then KeyPair.from_public_key(value.ed25519)
|
7
|
+
else
|
8
|
+
raise "impossible"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def address
|
13
|
+
to_keypair.address
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/stellar/operation.rb
CHANGED
@@ -3,8 +3,14 @@ require "bigdecimal"
|
|
3
3
|
module Stellar
|
4
4
|
class Operation
|
5
5
|
MAX_INT64 = 2**63 - 1
|
6
|
+
TRUST_LINE_FLAGS_MAPPING = {
|
7
|
+
full: Stellar::TrustLineFlags.authorized_flag,
|
8
|
+
maintain_liabilities: Stellar::TrustLineFlags.authorized_to_maintain_liabilities_flag,
|
9
|
+
clawback_enabled: Stellar::TrustLineFlags.trustline_clawback_enabled_flag
|
10
|
+
}.freeze
|
6
11
|
|
7
12
|
class << self
|
13
|
+
include Stellar::DSL
|
8
14
|
#
|
9
15
|
# Construct a new Stellar::Operation from the provided
|
10
16
|
# source account and body
|
@@ -16,16 +22,17 @@ module Stellar
|
|
16
22
|
# @return [Stellar::Operation] the built operation
|
17
23
|
def make(attributes = {})
|
18
24
|
source_account = attributes[:source_account]
|
19
|
-
body = Stellar::Operation::Body.new(*attributes[:body])
|
20
|
-
|
21
|
-
op = Stellar::Operation.new(body: body)
|
22
25
|
|
23
|
-
if source_account
|
24
|
-
raise ArgumentError, "Bad :source_account"
|
25
|
-
op.source_account = source_account.muxed_account
|
26
|
+
if source_account && !source_account.is_a?(Stellar::KeyPair)
|
27
|
+
raise ArgumentError, "Bad :source_account"
|
26
28
|
end
|
27
29
|
|
28
|
-
|
30
|
+
body = Stellar::Operation::Body.new(*attributes[:body])
|
31
|
+
|
32
|
+
Stellar::Operation.new(
|
33
|
+
body: body,
|
34
|
+
source_account: source_account&.muxed_account
|
35
|
+
)
|
29
36
|
end
|
30
37
|
|
31
38
|
#
|
@@ -233,7 +240,7 @@ module Stellar
|
|
233
240
|
|
234
241
|
def begin_sponsoring_future_reserves(sponsored:, **attributes)
|
235
242
|
op = BeginSponsoringFutureReservesOp.new(
|
236
|
-
sponsored_id:
|
243
|
+
sponsored_id: KeyPair(sponsored).account_id
|
237
244
|
)
|
238
245
|
|
239
246
|
make(attributes.merge(body: [:begin_sponsoring_future_reserves, op]))
|
@@ -247,10 +254,10 @@ module Stellar
|
|
247
254
|
def revoke_sponsorship(sponsored:, **attributes)
|
248
255
|
key_fields = attributes.slice(:offer_id, :data_name, :balance_id, :asset, :signer)
|
249
256
|
raise ArgumentError, "conflicting attributes: #{key_fields.keys.join(", ")}" if key_fields.size > 1
|
250
|
-
account_id =
|
257
|
+
account_id = KeyPair(sponsored).account_id
|
251
258
|
key, value = key_fields.first
|
252
259
|
op = if key == :signer
|
253
|
-
RevokeSponsorshipOp.signer(account_id: account_id, signer_key:
|
260
|
+
RevokeSponsorshipOp.signer(account_id: account_id, signer_key: SignerKey(value))
|
254
261
|
else
|
255
262
|
RevokeSponsorshipOp.ledger_key(LedgerKey.from(account_id: account_id, **key_fields))
|
256
263
|
end
|
@@ -299,7 +306,7 @@ module Stellar
|
|
299
306
|
op = ManageBuyOfferOp.new({
|
300
307
|
buying: buying,
|
301
308
|
selling: selling,
|
302
|
-
|
309
|
+
buy_amount: amount,
|
303
310
|
price: price,
|
304
311
|
offer_id: offer_id
|
305
312
|
})
|
@@ -370,11 +377,31 @@ module Stellar
|
|
370
377
|
}))
|
371
378
|
end
|
372
379
|
|
380
|
+
# @param asset [Stellar::Asset]
|
381
|
+
# @param trustor [Stellar::KeyPair]
|
382
|
+
# @param flags [{String, Symbol, Stellar::TrustLineFlags => true, false}] flags to to set or clear
|
383
|
+
# @param source_account [Stellar::KeyPair] source account (default is `nil`, which will use the source account of transaction)
|
384
|
+
def set_trust_line_flags(asset:, trustor:, flags: {}, source_account: nil)
|
385
|
+
op = Stellar::SetTrustLineFlagsOp.new
|
386
|
+
op.trustor = KeyPair(trustor).account_id
|
387
|
+
op.asset = Asset(asset)
|
388
|
+
op.attributes = Stellar::TrustLineFlags.set_clear_masks(flags)
|
389
|
+
|
390
|
+
make(
|
391
|
+
source_account: source_account,
|
392
|
+
body: [:set_trust_line_flags, op]
|
393
|
+
)
|
394
|
+
end
|
395
|
+
|
396
|
+
# DEPRECATED in favor of `set_trustline_flags`
|
373
397
|
#
|
374
398
|
# Helper method to create a valid AllowTrustOp, wrapped
|
375
399
|
# in the necessary XDR structs to be included within a
|
376
400
|
# transactions `operations` array.
|
377
401
|
#
|
402
|
+
# @deprecated Use `set_trustline_flags` operation
|
403
|
+
# See {https://github.com/stellar/stellar-protocol/blob/master/core/cap-0035.md#allow-trust-operation-1 CAP-35 description}
|
404
|
+
# for more details
|
378
405
|
# @param [Hash] attributes the attributes to create the operation with
|
379
406
|
# @option attributes [Stellar::KeyPair] :trustor
|
380
407
|
# @option attributes [Stellar::Asset] :asset
|
@@ -386,7 +413,8 @@ module Stellar
|
|
386
413
|
op = AllowTrustOp.new
|
387
414
|
|
388
415
|
trustor = attributes[:trustor]
|
389
|
-
|
416
|
+
# we handle booleans here for the backward compatibility
|
417
|
+
authorize = attributes[:authorize].yield_self { |value| value == true ? :full : value }
|
390
418
|
asset = attributes[:asset]
|
391
419
|
if asset.is_a?(Array)
|
392
420
|
asset = Asset.send(*asset)
|
@@ -394,20 +422,21 @@ module Stellar
|
|
394
422
|
|
395
423
|
raise ArgumentError, "Bad :trustor" unless trustor.is_a?(Stellar::KeyPair)
|
396
424
|
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
425
|
+
allowed_flags = TRUST_LINE_FLAGS_MAPPING.slice(:full, :maintain_liabilities)
|
426
|
+
|
427
|
+
# we handle booleans here for the backward compatibility
|
428
|
+
op.authorize = if allowed_flags.key?(authorize)
|
429
|
+
allowed_flags[authorize].value
|
430
|
+
elsif [:none, false].include?(authorize)
|
431
|
+
0
|
401
432
|
else
|
402
433
|
raise ArgumentError, "Bad :authorize, supported values: :full, :maintain_liabilities, :none"
|
403
434
|
end
|
404
435
|
|
405
436
|
raise ArgumentError, "Bad :asset" unless asset.type == Stellar::AssetType.asset_type_credit_alphanum4
|
406
437
|
|
407
|
-
atc = AllowTrustOp::Asset.new(:asset_type_credit_alphanum4, asset.code)
|
408
|
-
|
409
438
|
op.trustor = trustor.account_id
|
410
|
-
op.asset =
|
439
|
+
op.asset = AssetCode.new(:asset_type_credit_alphanum4, asset.code)
|
411
440
|
|
412
441
|
make(attributes.merge({
|
413
442
|
body: [:allow_trust, op]
|
@@ -492,6 +521,47 @@ module Stellar
|
|
492
521
|
}))
|
493
522
|
end
|
494
523
|
|
524
|
+
def clawback(source_account:, from:, amount:)
|
525
|
+
asset, amount = get_asset_amount(amount)
|
526
|
+
|
527
|
+
if amount == 0
|
528
|
+
raise ArgumentError, "Amount can not be zero"
|
529
|
+
end
|
530
|
+
|
531
|
+
if amount < 0
|
532
|
+
raise ArgumentError, "Negative amount is not allowed"
|
533
|
+
end
|
534
|
+
|
535
|
+
op = ClawbackOp.new(
|
536
|
+
amount: amount,
|
537
|
+
from: from.muxed_account,
|
538
|
+
asset: asset
|
539
|
+
)
|
540
|
+
|
541
|
+
make({
|
542
|
+
source_account: source_account,
|
543
|
+
body: [:clawback, op]
|
544
|
+
})
|
545
|
+
end
|
546
|
+
|
547
|
+
# Helper method to create clawback claimable balance operation
|
548
|
+
#
|
549
|
+
# @param [Stellar::KeyPair] source_account the attributes to create the operation with
|
550
|
+
# @param [String] balance_id `ClaimableBalanceID`, serialized in hex
|
551
|
+
#
|
552
|
+
# @return [Stellar::Operation] the built operation
|
553
|
+
def clawback_claimable_balance(source_account:, balance_id:)
|
554
|
+
balance_id = Stellar::ClaimableBalanceID.from_xdr(balance_id, :hex)
|
555
|
+
op = ClawbackClaimableBalanceOp.new(balance_id: balance_id)
|
556
|
+
|
557
|
+
make(
|
558
|
+
source_account: source_account,
|
559
|
+
body: [:clawback_claimable_balance, op]
|
560
|
+
)
|
561
|
+
rescue XDR::ReadError
|
562
|
+
raise ArgumentError, "Claimable balance id '#{balance_id}' is invalid"
|
563
|
+
end
|
564
|
+
|
495
565
|
private
|
496
566
|
|
497
567
|
def get_asset_amount(values)
|
data/lib/stellar/transaction.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
module Stellar
|
2
2
|
class TransactionBuilder
|
3
|
+
include Stellar::DSL
|
4
|
+
|
3
5
|
attr_reader :source_account, :sequence_number, :base_fee, :time_bounds, :memo, :operations
|
4
6
|
|
5
7
|
class << self
|
@@ -29,21 +31,20 @@ module Stellar
|
|
29
31
|
base_fee: 100,
|
30
32
|
time_bounds: nil,
|
31
33
|
memo: nil,
|
34
|
+
enable_muxed_accounts: false,
|
32
35
|
**_ # ignore any additional parameters without errors
|
33
36
|
)
|
34
|
-
raise ArgumentError, "Bad :source_account" unless source_account.is_a?(Stellar::KeyPair)
|
35
37
|
raise ArgumentError, "Bad :sequence_number" unless sequence_number.is_a?(Integer) && sequence_number >= 0
|
36
38
|
raise ArgumentError, "Bad :time_bounds" unless time_bounds.is_a?(Stellar::TimeBounds) || time_bounds.nil?
|
37
39
|
raise ArgumentError, "Bad :base_fee" unless base_fee.is_a?(Integer) && base_fee >= 100
|
38
40
|
|
39
|
-
@source_account = source_account
|
41
|
+
@source_account = Account(source_account)
|
40
42
|
@sequence_number = sequence_number
|
41
43
|
@base_fee = base_fee
|
42
44
|
@time_bounds = time_bounds
|
45
|
+
@enable_muxed_accounts = enable_muxed_accounts
|
43
46
|
|
44
|
-
if time_bounds.nil?
|
45
|
-
set_timeout(0)
|
46
|
-
end
|
47
|
+
set_timeout(0) if time_bounds.nil?
|
47
48
|
|
48
49
|
@memo = make_memo(memo)
|
49
50
|
@operations = []
|
@@ -59,7 +60,7 @@ module Stellar
|
|
59
60
|
end
|
60
61
|
|
61
62
|
attrs = {
|
62
|
-
source_account:
|
63
|
+
source_account: source_muxed_account,
|
63
64
|
fee: @base_fee * @operations.length,
|
64
65
|
seq_num: @sequence_number,
|
65
66
|
time_bounds: @time_bounds,
|
@@ -90,7 +91,7 @@ module Stellar
|
|
90
91
|
end
|
91
92
|
|
92
93
|
Stellar::FeeBumpTransaction.new(
|
93
|
-
fee_source:
|
94
|
+
fee_source: source_muxed_account,
|
94
95
|
fee: @base_fee * (inner_ops.length + 1),
|
95
96
|
inner_tx: Stellar::FeeBumpTransaction::InnerTx.new(:envelope_type_tx, inner_txe.v1!),
|
96
97
|
ext: Stellar::FeeBumpTransaction::Ext.new(0)
|
@@ -162,5 +163,17 @@ module Stellar
|
|
162
163
|
raise ArgumentError, "Bad :memo"
|
163
164
|
end
|
164
165
|
end
|
166
|
+
|
167
|
+
def source_muxed_account
|
168
|
+
if with_muxed_accounts?
|
169
|
+
@source_account.muxed_account
|
170
|
+
else
|
171
|
+
@source_account.base_account
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
def with_muxed_accounts?
|
176
|
+
@enable_muxed_accounts
|
177
|
+
end
|
165
178
|
end
|
166
179
|
end
|
@@ -1,13 +1,7 @@
|
|
1
1
|
module Stellar
|
2
2
|
class TransactionEnvelope
|
3
|
-
|
4
|
-
|
5
|
-
value&.public_send(method, *args) || super
|
6
|
-
end
|
7
|
-
|
8
|
-
def respond_to_missing?(method, include_private = false)
|
9
|
-
%w[tx signatures].include?(method) || super
|
10
|
-
end
|
3
|
+
delegate :tx, :signatures, to: :value
|
4
|
+
delegate :hash, to: :tx
|
11
5
|
|
12
6
|
# Checks to ensure that every signature for the envelope is
|
13
7
|
# a valid signature of one of the provided `key_pairs`
|
@@ -19,23 +13,19 @@ module Stellar
|
|
19
13
|
#
|
20
14
|
# @return [Boolean] true if all signatures are from the provided key_pairs and validly sign the tx's hash
|
21
15
|
def signed_correctly?(*key_pairs)
|
22
|
-
hash = tx.hash
|
23
16
|
return false if signatures.empty?
|
24
17
|
|
25
|
-
|
18
|
+
tx_hash = tx.hash
|
19
|
+
keys_by_hint = key_pairs.index_by(&:signature_hint)
|
26
20
|
|
27
21
|
signatures.all? do |sig|
|
28
|
-
key_pair =
|
22
|
+
key_pair = keys_by_hint[sig.hint]
|
29
23
|
break false if key_pair.nil?
|
30
24
|
|
31
|
-
key_pair.verify(sig.signature,
|
25
|
+
key_pair.verify(sig.signature, tx_hash)
|
32
26
|
end
|
33
27
|
end
|
34
28
|
|
35
|
-
def hash
|
36
|
-
Digest::SHA256.digest(to_xdr)
|
37
|
-
end
|
38
|
-
|
39
29
|
def merge(other)
|
40
30
|
merged_tx = tx.merge(other.tx)
|
41
31
|
merged_tx.signatures = [signatures, other.signatures]
|