open-core 0.3.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 +7 -0
- data/.gitignore +15 -0
- data/.travis.yml +15 -0
- data/.yardopts +8 -0
- data/CONTRIBUTING.md +48 -0
- data/Gemfile +15 -0
- data/Guardfile +5 -0
- data/LICENSE.txt +202 -0
- data/README.md +83 -0
- data/Rakefile +4 -0
- data/examples/create_account.rb +26 -0
- data/examples/low_level_transaction_post.rb +46 -0
- data/examples/mid_level_transaction_post.rb +33 -0
- data/examples/non_native_payment.rb +60 -0
- data/examples/offer.rb +75 -0
- data/examples/transaction_merge.rb +23 -0
- data/generated/stellar-base-generated.rb +134 -0
- data/generated/stellar/account_entry.rb +53 -0
- data/generated/stellar/account_entry/ext.rb +24 -0
- data/generated/stellar/account_flags.rb +27 -0
- data/generated/stellar/account_merge_result.rb +26 -0
- data/generated/stellar/account_merge_result_code.rb +30 -0
- data/generated/stellar/allow_trust_op.rb +38 -0
- data/generated/stellar/allow_trust_op/asset.rb +33 -0
- data/generated/stellar/allow_trust_result.rb +25 -0
- data/generated/stellar/allow_trust_result_code.rb +31 -0
- data/generated/stellar/asset.rb +47 -0
- data/generated/stellar/asset/alpha_num12.rb +22 -0
- data/generated/stellar/asset/alpha_num4.rb +22 -0
- data/generated/stellar/asset_type.rb +24 -0
- data/generated/stellar/bucket_entry.rb +28 -0
- data/generated/stellar/bucket_entry_type.rb +22 -0
- data/generated/stellar/change_trust_op.rb +22 -0
- data/generated/stellar/change_trust_result.rb +25 -0
- data/generated/stellar/change_trust_result_code.rb +30 -0
- data/generated/stellar/claim_offer_atom.rb +33 -0
- data/generated/stellar/create_account_op.rb +20 -0
- data/generated/stellar/create_account_result.rb +25 -0
- data/generated/stellar/create_account_result_code.rb +32 -0
- data/generated/stellar/create_passive_offer_op.rb +24 -0
- data/generated/stellar/crypto_key_type.rb +20 -0
- data/generated/stellar/decorated_signature.rb +20 -0
- data/generated/stellar/dont_have.rb +20 -0
- data/generated/stellar/envelope_type.rb +22 -0
- data/generated/stellar/error.rb +20 -0
- data/generated/stellar/hello.rb +26 -0
- data/generated/stellar/inflation_payout.rb +20 -0
- data/generated/stellar/inflation_result.rb +26 -0
- data/generated/stellar/inflation_result_code.rb +24 -0
- data/generated/stellar/ledger_entry.rb +44 -0
- data/generated/stellar/ledger_entry/data.rb +33 -0
- data/generated/stellar/ledger_entry/ext.rb +24 -0
- data/generated/stellar/ledger_entry_change.rb +31 -0
- data/generated/stellar/ledger_entry_change_type.rb +24 -0
- data/generated/stellar/ledger_entry_type.rb +24 -0
- data/generated/stellar/ledger_header.rb +65 -0
- data/generated/stellar/ledger_header/ext.rb +24 -0
- data/generated/stellar/ledger_header_history_entry.rb +33 -0
- data/generated/stellar/ledger_header_history_entry/ext.rb +24 -0
- data/generated/stellar/ledger_key.rb +50 -0
- data/generated/stellar/ledger_key/account.rb +20 -0
- data/generated/stellar/ledger_key/offer.rb +22 -0
- data/generated/stellar/ledger_key/trust_line.rb +22 -0
- data/generated/stellar/ledger_upgrade.rb +27 -0
- data/generated/stellar/ledger_upgrade_type.rb +22 -0
- data/generated/stellar/manage_offer_effect.rb +24 -0
- data/generated/stellar/manage_offer_op.rb +28 -0
- data/generated/stellar/manage_offer_result.rb +26 -0
- data/generated/stellar/manage_offer_result_code.rb +48 -0
- data/generated/stellar/manage_offer_success_result.rb +34 -0
- data/generated/stellar/manage_offer_success_result/offer.rb +30 -0
- data/generated/stellar/memo.rb +38 -0
- data/generated/stellar/memo_type.rb +28 -0
- data/generated/stellar/message_type.rb +45 -0
- data/generated/stellar/offer_entry.rb +49 -0
- data/generated/stellar/offer_entry/ext.rb +24 -0
- data/generated/stellar/offer_entry_flags.rb +21 -0
- data/generated/stellar/operation.rb +51 -0
- data/generated/stellar/operation/body.rb +60 -0
- data/generated/stellar/operation_meta.rb +18 -0
- data/generated/stellar/operation_result.rb +53 -0
- data/generated/stellar/operation_result/tr.rb +61 -0
- data/generated/stellar/operation_result_code.rb +25 -0
- data/generated/stellar/operation_type.rb +38 -0
- data/generated/stellar/path_payment_op.rb +32 -0
- data/generated/stellar/path_payment_result.rb +34 -0
- data/generated/stellar/path_payment_result/success.rb +22 -0
- data/generated/stellar/path_payment_result_code.rb +45 -0
- data/generated/stellar/payment_op.rb +22 -0
- data/generated/stellar/payment_result.rb +25 -0
- data/generated/stellar/payment_result_code.rb +39 -0
- data/generated/stellar/peer_address.rb +22 -0
- data/generated/stellar/price.rb +20 -0
- data/generated/stellar/public_key.rb +23 -0
- data/generated/stellar/scp_ballot.rb +20 -0
- data/generated/stellar/scp_envelope.rb +20 -0
- data/generated/stellar/scp_nomination.rb +22 -0
- data/generated/stellar/scp_quorum_set.rb +22 -0
- data/generated/stellar/scp_statement.rb +59 -0
- data/generated/stellar/scp_statement/pledges.rb +64 -0
- data/generated/stellar/scp_statement/pledges/confirm.rb +28 -0
- data/generated/stellar/scp_statement/pledges/externalize.rb +28 -0
- data/generated/stellar/scp_statement/pledges/prepare.rb +32 -0
- data/generated/stellar/scp_statement_type.rb +26 -0
- data/generated/stellar/set_options_op.rb +41 -0
- data/generated/stellar/set_options_result.rb +25 -0
- data/generated/stellar/set_options_result_code.rb +38 -0
- data/generated/stellar/signer.rb +20 -0
- data/generated/stellar/simple_payment_result.rb +22 -0
- data/generated/stellar/stellar_message.rb +66 -0
- data/generated/stellar/stellar_value.rb +40 -0
- data/generated/stellar/stellar_value/ext.rb +24 -0
- data/generated/stellar/threshold_indexes.rb +26 -0
- data/generated/stellar/time_bounds.rb +20 -0
- data/generated/stellar/transaction.rb +50 -0
- data/generated/stellar/transaction/ext.rb +24 -0
- data/generated/stellar/transaction_envelope.rb +20 -0
- data/generated/stellar/transaction_history_entry.rb +33 -0
- data/generated/stellar/transaction_history_entry/ext.rb +24 -0
- data/generated/stellar/transaction_history_result_entry.rb +33 -0
- data/generated/stellar/transaction_history_result_entry/ext.rb +24 -0
- data/generated/stellar/transaction_meta.rb +31 -0
- data/generated/stellar/transaction_meta/v0.rb +22 -0
- data/generated/stellar/transaction_result.rb +43 -0
- data/generated/stellar/transaction_result/ext.rb +24 -0
- data/generated/stellar/transaction_result/result.rb +30 -0
- data/generated/stellar/transaction_result_code.rb +45 -0
- data/generated/stellar/transaction_result_pair.rb +20 -0
- data/generated/stellar/transaction_result_set.rb +18 -0
- data/generated/stellar/transaction_set.rb +20 -0
- data/generated/stellar/trust_line_entry.rb +41 -0
- data/generated/stellar/trust_line_entry/ext.rb +24 -0
- data/generated/stellar/trust_line_flags.rb +21 -0
- data/lib/stellar-base.rb +32 -0
- data/lib/stellar/account_flags.rb +28 -0
- data/lib/stellar/asset.rb +69 -0
- data/lib/stellar/base.rb +1 -0
- data/lib/stellar/base/version.rb +5 -0
- data/lib/stellar/convert.rb +32 -0
- data/lib/stellar/key_pair.rb +112 -0
- data/lib/stellar/networks.rb +45 -0
- data/lib/stellar/operation.rb +304 -0
- data/lib/stellar/path_payment_result.rb +17 -0
- data/lib/stellar/price.rb +32 -0
- data/lib/stellar/thresholds.rb +39 -0
- data/lib/stellar/transaction.rb +170 -0
- data/lib/stellar/transaction_envelope.rb +32 -0
- data/lib/stellar/util/continued_fraction.rb +96 -0
- data/lib/stellar/util/strkey.rb +43 -0
- data/open-core.gemspec +37 -0
- data/spec/lib/stellar/account_flags_spec.rb +19 -0
- data/spec/lib/stellar/asset_spec.rb +45 -0
- data/spec/lib/stellar/convert_spec.rb +61 -0
- data/spec/lib/stellar/key_pair_spec.rb +238 -0
- data/spec/lib/stellar/networks_spec.rb +77 -0
- data/spec/lib/stellar/path_payment_result_spec.rb +95 -0
- data/spec/lib/stellar/price_spec.rb +34 -0
- data/spec/lib/stellar/thresholds_spec.rb +62 -0
- data/spec/lib/stellar/transaction_envelope_spec.rb +93 -0
- data/spec/lib/stellar/transaction_spec.rb +54 -0
- data/spec/lib/stellar/util/strkey_spec.rb +46 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/matchers/be_strkey.rb +9 -0
- data/spec/support/matchers/eq_bytes.rb +5 -0
- data/spec/support/matchers/have_length.rb +5 -0
- data/tasks/rspec.rake +6 -0
- data/tasks/travis.rake +1 -0
- data/tasks/xdr.rake +50 -0
- data/xdr/Stellar-SCP.x +87 -0
- data/xdr/Stellar-ledger-entries.x +222 -0
- data/xdr/Stellar-ledger.x +231 -0
- data/xdr/Stellar-overlay.x +87 -0
- data/xdr/Stellar-transaction.x +670 -0
- data/xdr/Stellar-types.x +34 -0
- metadata +444 -0
data/lib/stellar/base.rb
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
require "stellar-base"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
module Stellar
|
|
2
|
+
#
|
|
3
|
+
# Generic format conversion module
|
|
4
|
+
#
|
|
5
|
+
module Convert
|
|
6
|
+
require 'base64'
|
|
7
|
+
|
|
8
|
+
def to_hex(string)
|
|
9
|
+
string.unpack("H*").first
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def from_hex(hex_string)
|
|
13
|
+
[hex_string].pack("H*")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def to_base64(string)
|
|
17
|
+
Base64.strict_encode64(string)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def from_base64(base64_string)
|
|
21
|
+
Base64.strict_decode64(base64_string)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
## Converts a Stellar::PublicKey instance (or any typedef of it such as
|
|
25
|
+
# Stellar::AccountID) to an address
|
|
26
|
+
def pk_to_address(pk)
|
|
27
|
+
Stellar::Util::StrKey.check_encode(:account_id, pk.ed25519!)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
extend self
|
|
31
|
+
end
|
|
32
|
+
end
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
module Stellar
|
|
2
|
+
class KeyPair
|
|
3
|
+
def self.from_seed(seed)
|
|
4
|
+
seed_bytes = Util::StrKey.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::StrKey.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 self.from_network_passphrase(passphrase)
|
|
31
|
+
network_id = Digest::SHA256.digest(passphrase)
|
|
32
|
+
from_raw_seed network_id
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def self.master
|
|
36
|
+
from_raw_seed(Stellar.current_network_id)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def initialize(public_key, secret_key=nil)
|
|
40
|
+
@public_key = public_key
|
|
41
|
+
@secret_key = secret_key
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def account_id
|
|
45
|
+
Stellar::AccountID.new :key_type_ed25519, raw_public_key
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def public_key
|
|
49
|
+
Stellar::PublicKey.new :key_type_ed25519, raw_public_key
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def raw_public_key
|
|
53
|
+
@public_key.to_bytes
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def signature_hint
|
|
57
|
+
# take last 4 bytes
|
|
58
|
+
account_id.to_xdr.slice(-4, 4)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def raw_seed
|
|
62
|
+
@secret_key.to_bytes
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def rbnacl_signing_key
|
|
66
|
+
@secret_key
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def rbnacl_verify_key
|
|
70
|
+
@public_key
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def address
|
|
74
|
+
pk_bytes = raw_public_key
|
|
75
|
+
Util::StrKey.check_encode(:account_id, pk_bytes)
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def seed
|
|
79
|
+
raise "no private key" if @secret_key.nil?
|
|
80
|
+
#TODO: improve the error class above
|
|
81
|
+
seed_bytes = raw_seed
|
|
82
|
+
encoder = Util::StrKey.check_encode(:seed, seed_bytes)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def sign?
|
|
86
|
+
!@secret_key.nil?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def sign(message)
|
|
90
|
+
raise "no private key" if @secret_key.nil?
|
|
91
|
+
#TODO: improve the error class above
|
|
92
|
+
@secret_key.sign(message)
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def sign_decorated(message)
|
|
96
|
+
raw_signature = sign(message)
|
|
97
|
+
Stellar::DecoratedSignature.new({
|
|
98
|
+
hint: signature_hint,
|
|
99
|
+
signature: raw_signature
|
|
100
|
+
})
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
def verify(signature, message)
|
|
104
|
+
@public_key.verify(signature, message)
|
|
105
|
+
rescue RbNaCl::LengthError
|
|
106
|
+
false
|
|
107
|
+
rescue RbNaCl::BadSignatureError
|
|
108
|
+
false
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
end
|
|
112
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
module Stellar
|
|
2
|
+
# Provides a container for well-known network passphrases, such as the main network and SDF test network
|
|
3
|
+
module Networks
|
|
4
|
+
|
|
5
|
+
PUBLIC = "Public Global Stellar Network ; September 2015"
|
|
6
|
+
TESTNET = "Test SDF Network ; September 2015"
|
|
7
|
+
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# Configures the default stellar network passphrase for the current process. Unless otherwise
|
|
11
|
+
# specified in a method that needs the passphrase, this value will be used.
|
|
12
|
+
#
|
|
13
|
+
# NOTE: This method is not thread-safe. It's best to just call this at startup once and use the other
|
|
14
|
+
# methods of specifying a network if you need two threads in the same process to communicate with
|
|
15
|
+
# different networks
|
|
16
|
+
#
|
|
17
|
+
# @see Stellar.default_network
|
|
18
|
+
# @see Stellar.on_network
|
|
19
|
+
def self.default_network=(passphrase)
|
|
20
|
+
@default_network = passphrase
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
# Returns the passphrase for the currently-configured network, as set by Stellar.default_network
|
|
24
|
+
# or Stellar.on_network
|
|
25
|
+
def self.current_network
|
|
26
|
+
Thread.current["stellar_network_passphrase"] ||
|
|
27
|
+
@default_network ||
|
|
28
|
+
Stellar::Networks::PUBLIC
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Returns the id for the currently configured network, suitable for use in generating
|
|
32
|
+
# a signature base string or making the root account's keypair.
|
|
33
|
+
def self.current_network_id
|
|
34
|
+
Digest::SHA256.digest(self.current_network)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Executes the provided block in the context of the provided network.
|
|
38
|
+
def self.on_network(passphrase, &block)
|
|
39
|
+
old = Thread.current["stellar_network_passphrase"]
|
|
40
|
+
Thread.current["stellar_network_passphrase"] = passphrase
|
|
41
|
+
block.call
|
|
42
|
+
ensure
|
|
43
|
+
Thread.current["stellar_network_passphrase"] = old
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
require 'bigdecimal'
|
|
2
|
+
|
|
3
|
+
module Stellar
|
|
4
|
+
class Operation
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
#
|
|
8
|
+
# Construct a new Stellar::Operation from the provided
|
|
9
|
+
# source account and body
|
|
10
|
+
#
|
|
11
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
12
|
+
# @option attributes [Stellar::KeyPair] :source_account
|
|
13
|
+
# @option attributes [Stellar::Operation::Body] :body
|
|
14
|
+
#
|
|
15
|
+
# @return [Stellar::Operation] the built operation
|
|
16
|
+
def self.make(attributes={})
|
|
17
|
+
source_account = attributes[:source_account]
|
|
18
|
+
body = Stellar::Operation::Body.new(*attributes[:body])
|
|
19
|
+
|
|
20
|
+
op = Stellar::Operation.new(body:body)
|
|
21
|
+
|
|
22
|
+
if source_account
|
|
23
|
+
raise ArgumentError, "Bad :source_account" unless source_account.is_a?(Stellar::KeyPair)
|
|
24
|
+
op.source_account = source_account.account_id
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
return op
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
#
|
|
32
|
+
# Helper method to create a valid PaymentOp, wrapped
|
|
33
|
+
# in the necessary XDR structs to be included within a
|
|
34
|
+
# transactions `operations` array.
|
|
35
|
+
#
|
|
36
|
+
# @see Stellar::Asset
|
|
37
|
+
#
|
|
38
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
39
|
+
# @option attributes [Stellar::KeyPair] :destination the receiver of the payment
|
|
40
|
+
# @option attributes [Array] :amount the amount to pay
|
|
41
|
+
# @return [Stellar::Operation] the built operation, containing a
|
|
42
|
+
# Stellar::PaymentOp body
|
|
43
|
+
def self.payment(attributes={})
|
|
44
|
+
destination = attributes[:destination]
|
|
45
|
+
asset, amount = extract_amount(attributes[:amount])
|
|
46
|
+
|
|
47
|
+
raise ArgumentError unless destination.is_a?(KeyPair)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
op = PaymentOp.new
|
|
51
|
+
op.asset = asset
|
|
52
|
+
op.amount = amount
|
|
53
|
+
op.destination = destination.account_id
|
|
54
|
+
|
|
55
|
+
return make(attributes.merge({
|
|
56
|
+
body:[:payment, op]
|
|
57
|
+
}))
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
#
|
|
61
|
+
# Helper method to create a valid PathPaymentOp, wrapped
|
|
62
|
+
# in the necessary XDR structs to be included within a
|
|
63
|
+
# transactions `operations` array.
|
|
64
|
+
#
|
|
65
|
+
# @see Stellar::Asset
|
|
66
|
+
#
|
|
67
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
68
|
+
# @option attributes [Stellar::KeyPair] :destination the receiver of the payment
|
|
69
|
+
# @option attributes [Array] :amount the amount to pay
|
|
70
|
+
# @option attributes [Array] :with the source asset and maximum allowed source amount to pay with
|
|
71
|
+
# @option attributes [Array<Stellar::Asset>] :path the payment path to use
|
|
72
|
+
#
|
|
73
|
+
# @return [Stellar::Operation] the built operation, containing a
|
|
74
|
+
# Stellar::PaymentOp body
|
|
75
|
+
def self.path_payment(attributes={})
|
|
76
|
+
destination = attributes[:destination]
|
|
77
|
+
asset, amount = extract_amount(attributes[:amount])
|
|
78
|
+
send_asset, send_max = extract_amount(attributes[:with])
|
|
79
|
+
path = (attributes[:path] || []).map{|p| Stellar::Asset.send(*p)}
|
|
80
|
+
|
|
81
|
+
raise ArgumentError unless destination.is_a?(KeyPair)
|
|
82
|
+
|
|
83
|
+
op = PathPaymentOp.new
|
|
84
|
+
op.send_asset = send_asset
|
|
85
|
+
op.send_max = send_max
|
|
86
|
+
op.destination = destination.account_id
|
|
87
|
+
op.dest_asset = asset
|
|
88
|
+
op.dest_amount = amount
|
|
89
|
+
op.path = path
|
|
90
|
+
|
|
91
|
+
return make(attributes.merge({
|
|
92
|
+
body:[:path_payment, op]
|
|
93
|
+
}))
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def self.create_account(attributes={})
|
|
97
|
+
destination = attributes[:destination]
|
|
98
|
+
starting_balance = attributes[:starting_balance]
|
|
99
|
+
|
|
100
|
+
raise ArgumentError unless destination.is_a?(KeyPair)
|
|
101
|
+
|
|
102
|
+
op = CreateAccountOp.new()
|
|
103
|
+
op.destination = destination.account_id
|
|
104
|
+
op.starting_balance = starting_balance
|
|
105
|
+
|
|
106
|
+
return make(attributes.merge({
|
|
107
|
+
body:[:create_account, op]
|
|
108
|
+
}))
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
#
|
|
112
|
+
# Helper method to create a valid ChangeTrustOp, wrapped
|
|
113
|
+
# in the necessary XDR structs to be included within a
|
|
114
|
+
# transactions `operations` array.
|
|
115
|
+
#
|
|
116
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
117
|
+
# @option attributes [Stellar::Currrency] :line the asset to trust
|
|
118
|
+
# @option attributes [Fixnum] :limit the maximum amount to trust
|
|
119
|
+
#
|
|
120
|
+
# @return [Stellar::Operation] the built operation, containing a
|
|
121
|
+
# Stellar::ChangeTrustOp body
|
|
122
|
+
def self.change_trust(attributes={})
|
|
123
|
+
line = Asset.send(*attributes[:line])
|
|
124
|
+
limit = attributes[:limit]
|
|
125
|
+
|
|
126
|
+
raise ArgumentError, "Bad :limit #{limit}" unless limit.is_a?(Integer)
|
|
127
|
+
|
|
128
|
+
op = ChangeTrustOp.new(line: line, limit: limit)
|
|
129
|
+
|
|
130
|
+
return make(attributes.merge({
|
|
131
|
+
body:[:change_trust, op]
|
|
132
|
+
}))
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def self.manage_offer(attributes={})
|
|
136
|
+
buying = Asset.send(*attributes[:buying])
|
|
137
|
+
selling = Asset.send(*attributes[:selling])
|
|
138
|
+
amount = attributes[:amount]
|
|
139
|
+
offer_id = attributes[:offer_id] || 0
|
|
140
|
+
price = interpret_price(attributes[:price])
|
|
141
|
+
|
|
142
|
+
op = ManageOfferOp.new({
|
|
143
|
+
buying: buying,
|
|
144
|
+
selling: selling,
|
|
145
|
+
amount: amount,
|
|
146
|
+
price: price,
|
|
147
|
+
offer_id: offer_id
|
|
148
|
+
})
|
|
149
|
+
|
|
150
|
+
return make(attributes.merge({
|
|
151
|
+
body:[:manage_offer, op]
|
|
152
|
+
}))
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def self.create_passive_offer(attributes={})
|
|
156
|
+
buying = Asset.send(*attributes[:buying])
|
|
157
|
+
selling = Asset.send(*attributes[:selling])
|
|
158
|
+
amount = attributes[:amount]
|
|
159
|
+
price = interpret_price(attributes[:price])
|
|
160
|
+
|
|
161
|
+
op = CreatePassiveOfferOp.new({
|
|
162
|
+
buying: buying,
|
|
163
|
+
selling: selling,
|
|
164
|
+
amount: amount,
|
|
165
|
+
price: price,
|
|
166
|
+
})
|
|
167
|
+
|
|
168
|
+
return make(attributes.merge({
|
|
169
|
+
body:[:create_passive_offer, op]
|
|
170
|
+
}))
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
#
|
|
174
|
+
# Helper method to create a valid SetOptionsOp, wrapped
|
|
175
|
+
# in the necessary XDR structs to be included within a
|
|
176
|
+
# transactions `operations` array.
|
|
177
|
+
#
|
|
178
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
179
|
+
# @option attributes [Stellar::KeyPair] :inflation_dest
|
|
180
|
+
# @option attributes [Array<Stellar::AccountFlags>] :set flags to set
|
|
181
|
+
# @option attributes [Array<Stellar::AccountFlags>] :clear flags to clear
|
|
182
|
+
# @option attributes [String] :thresholds
|
|
183
|
+
# @option attributes [Stellar::Signer] :signer
|
|
184
|
+
#
|
|
185
|
+
# @return [Stellar::Operation] the built operation, containing a
|
|
186
|
+
# Stellar::SetOptionsOp body
|
|
187
|
+
def self.set_options(attributes={})
|
|
188
|
+
op = SetOptionsOp.new()
|
|
189
|
+
op.set_flags = Stellar::AccountFlags.make_mask attributes[:set]
|
|
190
|
+
op.clear_flags = Stellar::AccountFlags.make_mask attributes[:clear]
|
|
191
|
+
op.master_weight = attributes[:master_weight]
|
|
192
|
+
op.low_threshold = attributes[:low_threshold]
|
|
193
|
+
op.med_threshold = attributes[:med_threshold]
|
|
194
|
+
op.high_threshold = attributes[:high_threshold]
|
|
195
|
+
|
|
196
|
+
op.signer = attributes[:signer]
|
|
197
|
+
op.home_domain = attributes[:home_domain]
|
|
198
|
+
|
|
199
|
+
|
|
200
|
+
inflation_dest = attributes[:inflation_dest]
|
|
201
|
+
if inflation_dest
|
|
202
|
+
raise ArgumentError, "Bad :inflation_dest" unless inflation_dest.is_a?(Stellar::KeyPair)
|
|
203
|
+
op.inflation_dest = inflation_dest.account_id
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
|
|
207
|
+
return make(attributes.merge({
|
|
208
|
+
body:[:set_options, op]
|
|
209
|
+
}))
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
#
|
|
213
|
+
# Helper method to create a valid AllowTrustOp, wrapped
|
|
214
|
+
# in the necessary XDR structs to be included within a
|
|
215
|
+
# transactions `operations` array.
|
|
216
|
+
#
|
|
217
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
218
|
+
# @option attributes [Stellar::KeyPair] :trustor
|
|
219
|
+
# @option attributes [Stellar::Asset] :asset
|
|
220
|
+
#
|
|
221
|
+
# @return [Stellar::Operation] the built operation, containing a
|
|
222
|
+
# Stellar::AllowTrustOp body
|
|
223
|
+
def self.allow_trust(attributes={})
|
|
224
|
+
op = AllowTrustOp.new()
|
|
225
|
+
|
|
226
|
+
trustor = attributes[:trustor]
|
|
227
|
+
authorize = attributes[:authorize]
|
|
228
|
+
asset = Asset.send(*attributes[:asset])
|
|
229
|
+
|
|
230
|
+
raise ArgumentError, "Bad :trustor" unless trustor.is_a?(Stellar::KeyPair)
|
|
231
|
+
raise ArgumentError, "Bad :authorize" unless authorize == !!authorize # check boolean
|
|
232
|
+
raise ArgumentError, "Bad :asset" unless asset.type == Stellar::AssetType.asset_type_credit_alphanum4
|
|
233
|
+
|
|
234
|
+
atc = AllowTrustOp::Asset.new(:asset_type_credit_alphanum4, asset.code)
|
|
235
|
+
|
|
236
|
+
op.trustor = trustor.account_id
|
|
237
|
+
op.authorize = authorize
|
|
238
|
+
op.asset = atc
|
|
239
|
+
|
|
240
|
+
return make(attributes.merge({
|
|
241
|
+
body:[:allow_trust, op]
|
|
242
|
+
}))
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
#
|
|
246
|
+
# Helper method to create an account merge operation
|
|
247
|
+
#
|
|
248
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
249
|
+
# @option attributes [Stellar::KeyPair] :destination
|
|
250
|
+
#
|
|
251
|
+
# @return [Stellar::Operation] the built operation
|
|
252
|
+
def self.account_merge(attributes={})
|
|
253
|
+
destination = attributes[:destination]
|
|
254
|
+
|
|
255
|
+
raise ArgumentError, "Bad :destination" unless destination.is_a?(KeyPair)
|
|
256
|
+
|
|
257
|
+
# TODO: add source_account support
|
|
258
|
+
return make(attributes.merge({
|
|
259
|
+
body:[:account_merge, destination.account_id]
|
|
260
|
+
}))
|
|
261
|
+
end
|
|
262
|
+
|
|
263
|
+
#
|
|
264
|
+
# Helper method to create an inflation operation
|
|
265
|
+
#
|
|
266
|
+
# @param [Hash] attributes the attributes to create the operation with
|
|
267
|
+
# @option attributes [Integer] :sequence
|
|
268
|
+
#
|
|
269
|
+
# @return [Stellar::Operation] the built operation
|
|
270
|
+
def self.inflation(attributes={})
|
|
271
|
+
sequence = attributes[:sequence]
|
|
272
|
+
|
|
273
|
+
raise ArgumentError, "Bad :sequence #{sequence}" unless sequence.is_a?(Integer)
|
|
274
|
+
|
|
275
|
+
# TODO: add source_account support
|
|
276
|
+
return make(attributes.merge({
|
|
277
|
+
body:[:inflation]
|
|
278
|
+
}))
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
private
|
|
282
|
+
def self.extract_amount(a)
|
|
283
|
+
amount = a.last
|
|
284
|
+
asset = Stellar::Asset.send(*a[0...-1])
|
|
285
|
+
|
|
286
|
+
return asset, amount
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
def self.interpret_price(price)
|
|
291
|
+
case price
|
|
292
|
+
when String
|
|
293
|
+
bd = BigDecimal.new(price)
|
|
294
|
+
Price.from_f(bd)
|
|
295
|
+
when Numeric
|
|
296
|
+
Price.from_f(price)
|
|
297
|
+
when Stellar::Price
|
|
298
|
+
price
|
|
299
|
+
else
|
|
300
|
+
raise ArgumentError, "Invalid price type: #{price.class}. Must be String, Numeric, or Stellar::Price"
|
|
301
|
+
end
|
|
302
|
+
end
|
|
303
|
+
end
|
|
304
|
+
end
|