stellar-sdk 0.6.0 → 0.23.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +15 -0
  3. data/{LICENSE.txt → LICENSE} +0 -0
  4. data/README.md +12 -12
  5. data/lib/stellar-sdk.rb +3 -4
  6. data/lib/stellar/account.rb +16 -18
  7. data/lib/stellar/amount.rb +9 -13
  8. data/lib/stellar/client.rb +204 -93
  9. data/lib/stellar/horizon/problem.rb +14 -16
  10. data/lib/stellar/sep10.rb +347 -0
  11. data/lib/stellar/transaction_page.rb +4 -6
  12. data/lib/stellar/version.rb +1 -1
  13. metadata +21 -217
  14. data/.gitignore +0 -16
  15. data/.travis.yml +0 -17
  16. data/.yardopts +0 -7
  17. data/CONTRIBUTING.md +0 -48
  18. data/Gemfile +0 -14
  19. data/Guardfile +0 -5
  20. data/Rakefile +0 -3
  21. data/examples/01_get_funded.rb +0 -37
  22. data/examples/02_payment.rb +0 -15
  23. data/examples/03_transaction_history.rb +0 -21
  24. data/examples/04_setting_trust.rb +0 -1
  25. data/examples/05_fiat_payment.rb +0 -13
  26. data/examples/06_fund_testnet_friendbot.rb +0 -15
  27. data/ruby-stellar-sdk.gemspec +0 -36
  28. data/spec/config.yml.sample +0 -12
  29. data/spec/fixtures/vcr_cassettes/Stellar_Account/_lookup/should_handle_404_request_when_performing_federation_lookup.yml +0 -133
  30. data/spec/fixtures/vcr_cassettes/Stellar_Account/_lookup/should_handle_domains_that_are_not_federation_servers.yml +0 -44
  31. data/spec/fixtures/vcr_cassettes/Stellar_Account/_lookup/should_peforms_federation_lookup.yml +0 -85
  32. data/spec/fixtures/vcr_cassettes/Stellar_Client/_account_info/returns_the_current_details_for_the_account.yml +0 -190
  33. data/spec/fixtures/vcr_cassettes/Stellar_Client/_account_merge/merges_source_account_into_destination.yml +0 -714
  34. data/spec/fixtures/vcr_cassettes/Stellar_Client/_change_trust/given_an_asset_described_as_an_array/creates_updates_or_deletes_a_trustline.yml +0 -1156
  35. data/spec/fixtures/vcr_cassettes/Stellar_Client/_create_account/creates_the_account.yml +0 -323
  36. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/alphanum12_asset/sends_a_alphanum12_asset_to_the_destination.yml +0 -747
  37. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/alphanum4_asset/sends_a_alphanum4_asset_to_the_destination.yml +0 -747
  38. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/memo/accepts_the_memo_attribute.yml +0 -716
  39. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/native_asset/sends_a_native_payment_to_the_account.yml +0 -562
  40. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/using_a_payment_channel/sends_a_payment_account_through_a_channel_account.yml +0 -694
  41. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/using_a_payment_channel/sends_a_payment_when_the_channel_is_the_same_as_from_.yml +0 -586
  42. data/spec/fixtures/vcr_cassettes/Stellar_Client/_transactions/account_transactions/accepts_a_cursor_to_return_less_data.yml +0 -94
  43. data/spec/fixtures/vcr_cassettes/Stellar_Client/_transactions/account_transactions/returns_a_list_of_transaction_for_an_account.yml +0 -94
  44. data/spec/fixtures/vcr_cassettes/Stellar_Client/_transactions/all_transactions/accepts_a_cursor_to_return_less_data.yml +0 -94
  45. data/spec/fixtures/vcr_cassettes/Stellar_Client/_transactions/all_transactions/returns_a_list_of_transactions.yml +0 -94
  46. data/spec/lib/stellar/account_spec.rb +0 -59
  47. data/spec/lib/stellar/amount_spec.rb +0 -70
  48. data/spec/lib/stellar/client_spec.rb +0 -392
  49. data/spec/spec_helper.rb +0 -14
  50. data/spec/support/config.rb +0 -3
  51. data/spec/support/vcr.rb +0 -10
  52. data/tasks/rspec.rake +0 -6
  53. data/tasks/travis.rake +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 4f4c58d5a53d9bfd6d7738fe6d70cabb61c0d6fe
4
- data.tar.gz: f580c29fc169d126e7546589f03d675c5aaee307
2
+ SHA256:
3
+ metadata.gz: 0d8a8fa97989972efbe53dd536b329596c7f0eaa9769aff84ceb86f3f70c0f69
4
+ data.tar.gz: 4d8e9eae54618c12ba827b62e8243a28cbe1c1dfe3b60e14b2e26394266a560b
5
5
  SHA512:
6
- metadata.gz: e38b8a8b03360f65fe9e739806cb0b2fbddc563026c61a512e75c1f5808cf5c5e20b0a195e60bbc50d2bfff1c72a255717f74de05d65f586063d42ce2756a6f6
7
- data.tar.gz: 85afab30aa425ee7fb29a5d2b919fb7f2fc556369186665f7d513704dac4881aa8fbe6362bcce9bd5ace283c0c2046873a6d4a2cd9c9b16993b58d4828540100
6
+ metadata.gz: 4952c1aea1709d96d2933e9aeae95afd094c7708a95c450c385ab39cfa7ac96c725a78d9579c424d6cddc7ffad95260c2e75b2535504ee4e0031c41721b7235e
7
+ data.tar.gz: 8d3e8c2f10c959c4c52c3e26a61f61f7580bc3a93797b4ac8a976c0951133a79b60bbc6b07e9eabd5383cac2d11b62e67066163c9eda0ecaa580417a7056d6c3
@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
4
4
  The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
5
  and this project adheres to [Semantic Versioning](http://semver.org/).
6
6
 
7
+ ## [0.9.0](https://github.com/stellar/ruby-stellar-sdk/compare/v0.9.0...v0.8.0)
8
+ ### Added
9
+ - Stellar Protocol 13 support
10
+ - Fee-Bump transactions ([CAP-0015](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0015.md))
11
+ - Multiplexed accounts ([CAP-0027](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0027.md))
12
+ - Fine-Grained control on trustline authorization ([CAP-0018](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0018.md))
13
+ ## [0.8.0](https://github.com/stellar/ruby-stellar-sdk/compare/v0.7.0...v0.8.0)
14
+ ### Added
15
+ - SEP-10 Multisig Support [#69](https://github.com/stellar/ruby-stellar-sdk/pull/69)
16
+ - `X-Client-Name` and `X-Client-Version` headers
17
+
18
+ ## [0.7.0] - 2019-04-26
19
+ ### Added
20
+ - Friendbot support
21
+
7
22
  ## [0.6.0] - 2018-11-27
8
23
  ### Added
9
24
  - Allow setting of memo in `Stellar::Client#send_payment`
File without changes
data/README.md CHANGED
@@ -1,27 +1,24 @@
1
1
  # Ruby Stellar
2
2
 
3
- [![Build Status](https://travis-ci.org/stellar/ruby-stellar-sdk.svg)](https://travis-ci.org/stellar/ruby-stellar-sdk)
4
- [![Code Climate](https://codeclimate.com/github/stellar/ruby-stellar-sdk/badges/gpa.svg)](https://codeclimate.com/github/stellar/ruby-stellar-sdk)
5
-
6
- *STATUS: this library is very early and incomplete. The examples provided do not work, yet*
3
+ [![Build Status](https://travis-ci.org/bloom-solutions/ruby-stellar-sdk.svg)](https://travis-ci.org/bloom-solutions/ruby-stellar-sdk)
4
+ [![Code Climate](https://codeclimate.com/github/bloom-solutions/ruby-stellar-sdk/badges/gpa.svg)](https://codeclimate.com/github/bloom-solutions/ruby-stellar-sdk)
7
5
 
8
6
  This library helps you to integrate your application into the [Stellar network](http://stellar.org).
9
7
 
10
8
  ## Installation
11
9
 
12
- Add this line to your application's Gemfile:
10
+ Add this lines to your application's Gemfile:
13
11
 
14
12
  ```ruby
15
13
  gem 'stellar-sdk'
14
+ gem 'xdr', git: 'https://github.com/stellar/ruby-xdr.git', tag: 'v3.0.1'
16
15
  ```
17
16
 
18
17
  And then execute:
19
18
 
20
19
  $ bundle
21
-
22
- Or install it yourself as:
23
-
24
- $ gem install stellar-sdk
20
+
21
+ **Note** we need to add such explicit `xdr` dependency, because version 3.0.1 is not on RubyGems yet. When it's published, you can remove this line
25
22
 
26
23
  Also requires libsodium. Installable via `brew install libsodium` on OS X.
27
24
 
@@ -45,7 +42,7 @@ client.send_payment({
45
42
  })
46
43
  ```
47
44
 
48
- Be sure to set the network when submitting to the public network (more information in [stellar-base](https://www.github.com/stellar/ruby-stellar-base)):
45
+ Be sure to set the network when submitting to the public network (more information in [stellar-base](https://www.github.com/bloom-solutions/ruby-stellar-base)):
49
46
 
50
47
  ```ruby
51
48
  Stellar.default_network = Stellar::Networks::PUBLIC
@@ -53,14 +50,17 @@ Stellar.default_network = Stellar::Networks::PUBLIC
53
50
 
54
51
  ## Development
55
52
 
53
+ - Install and activate [rvm](https://rvm.io/rvm/install)
54
+ - Ensure your `bundler` version is up-to-date: `gem install bundler`
55
+ - Run `bundle install`
56
56
  - Copy `spec/config.yml.sample` to `spec/config.yml`
57
57
  - Replace anything in `spec/config.yml` especially if you will re-record specs
58
- - `rspec spec`
58
+ - `bundle exec rspec spec`
59
59
 
60
60
  ## Contributing
61
61
 
62
62
  1. Sign the [Contributor License Agreement](https://docs.google.com/forms/d/1g7EF6PERciwn7zfmfke5Sir2n10yddGGSXyZsq98tVY/viewform?usp=send_form)
63
- 2. Fork it ( https://github.com/stellar/ruby-stellar-lib/fork )
63
+ 2. Fork it ( https://github.com/bloom-solutions/ruby-stellar-lib/fork )
64
64
  2. Create your feature branch (`git checkout -b my-new-feature`)
65
65
  3. Commit your changes (`git commit -am 'Add some feature'`)
66
66
  4. Push to the branch (`git push origin my-new-feature`)
@@ -1,12 +1,11 @@
1
- require 'stellar-base'
2
- require 'contracts'
1
+ require "stellar-base"
2
+ require_relative "./stellar/version"
3
3
 
4
4
  module Stellar
5
-
6
5
  autoload :Account
7
- autoload :AccountInfo
8
6
  autoload :Amount
9
7
  autoload :Client
8
+ autoload :SEP10
10
9
 
11
10
  module Horizon
12
11
  extend ActiveSupport::Autoload
@@ -1,12 +1,10 @@
1
- require 'toml-rb'
2
- require 'uri'
3
- require 'faraday'
4
- require 'json'
1
+ require "toml-rb"
2
+ require "uri"
3
+ require "faraday"
4
+ require "json"
5
5
 
6
6
  module Stellar
7
7
  class Account
8
- include Contracts
9
-
10
8
  delegate :address, to: :keypair
11
9
 
12
10
  def self.random
@@ -25,7 +23,7 @@ module Stellar
25
23
  end
26
24
 
27
25
  def self.lookup(federated_name)
28
- _, domain = federated_name.split('*')
26
+ _, domain = federated_name.split("*")
29
27
  if domain.nil?
30
28
  raise InvalidFederationAddress.new
31
29
  end
@@ -33,25 +31,25 @@ module Stellar
33
31
  domain_req = Faraday.new("https://#{domain}/.well-known/stellar.toml").get
34
32
 
35
33
  unless domain_req.status == 200
36
- raise InvalidStellarDomain.new('Domain does not contain stellar.toml file')
34
+ raise InvalidStellarDomain.new("Domain does not contain stellar.toml file")
37
35
  end
38
-
36
+
39
37
  fed_server_url = TomlRB.parse(domain_req.body)["FEDERATION_SERVER"]
40
38
  if fed_server_url.nil?
41
- raise InvalidStellarTOML.new('Invalid Stellar TOML file')
39
+ raise InvalidStellarTOML.new("Invalid Stellar TOML file")
42
40
  end
43
41
 
44
- unless fed_server_url =~ URI::regexp
45
- raise InvalidFederationURL.new('Invalid Federation Server URL')
42
+ unless fed_server_url&.match?(URI::DEFAULT_PARSER.make_regexp)
43
+ raise InvalidFederationURL.new("Invalid Federation Server URL")
46
44
  end
47
45
 
48
- lookup_req = Faraday.new(fed_server_url).get do |req|
46
+ lookup_req = Faraday.new(fed_server_url).get { |req|
49
47
  req.params[:q] = federated_name
50
- req.params[:type] = 'name'
51
- end
48
+ req.params[:type] = "name"
49
+ }
52
50
 
53
51
  unless lookup_req.status == 200
54
- raise AccountNotFound.new('Account not found')
52
+ raise AccountNotFound.new("Account not found")
55
53
  end
56
54
 
57
55
  JSON.parse(lookup_req.body)["account_id"]
@@ -64,7 +62,7 @@ module Stellar
64
62
 
65
63
  attr_reader :keypair
66
64
 
67
- Contract Stellar::KeyPair => Any
65
+ # @param [Stellar::KeyPair] keypair
68
66
  def initialize(keypair)
69
67
  @keypair = keypair
70
68
  end
@@ -84,4 +82,4 @@ module Stellar
84
82
 
85
83
  class InvalidFederationURL < StandardError
86
84
  end
87
- end
85
+ end
@@ -1,25 +1,21 @@
1
1
  module Stellar
2
2
  class Amount
3
- include Contracts
4
-
5
3
  attr_reader :amount
6
4
  attr_reader :asset
7
5
 
8
- Contract Pos, Asset => Any
9
- def initialize(amount, asset=Stellar::Asset.native())
6
+ # @param [Fixnum] amount
7
+ # @param [Stellar::Asset] asset
8
+ def initialize(amount, asset = Stellar::Asset.native)
10
9
  # TODO: how are we going to handle decimal considerations?
11
-
10
+
12
11
  @amount = amount
13
- @asset = asset
12
+ @asset = asset
14
13
  end
15
14
 
16
-
17
- Contract None => Or[
18
- [Or[:alphanum4, :alphanum12], String, KeyPair, Pos],
19
- [:native, Pos],
20
- ]
15
+ # @return [Array(Symbol, Fixnum)] in case of a native asset
16
+ # @return [Array(Symbol, String, Stellar::KeyPair, Fixnum)] in case of alphanum asset
21
17
  def to_payment
22
- case asset.type
18
+ case asset.type
23
19
  when AssetType.asset_type_native
24
20
  [:native, amount]
25
21
  when AssetType.asset_type_credit_alphanum4
@@ -34,7 +30,7 @@ module Stellar
34
30
  end
35
31
 
36
32
  def inspect
37
- "#<Stellar::Amount #{asset}(#{amount})>"
33
+ "#<Stellar::Amount #{asset}(#{amount})>"
38
34
  end
39
35
  end
40
36
  end
@@ -1,31 +1,40 @@
1
- require 'hyperclient'
1
+ require "hyperclient"
2
2
  require "active_support/core_ext/object/blank"
3
+ require "securerandom"
3
4
 
4
5
  module Stellar
5
- class Client
6
- include Contracts
7
- C = Contracts
6
+ class AccountRequiresMemoError < StandardError
7
+ attr_reader :account_id, :operation_index
8
+
9
+ def initialize(message, account_id, operation_index)
10
+ super(message)
11
+ @account_id = account_id
12
+ @operation_index = operation_index
13
+ end
14
+ end
8
15
 
16
+ class Client
9
17
  DEFAULT_FEE = 100
10
18
 
11
- HORIZON_LOCALHOST_URL = 'http://127.0.0.1:8000'
12
- HORIZON_MAINNET_URL = 'https://horizon.stellar.org'
13
- HORIZON_TESTNET_URL = 'https://horizon-testnet.stellar.org'
19
+ HORIZON_LOCALHOST_URL = "http://127.0.0.1:8000"
20
+ HORIZON_MAINNET_URL = "https://horizon.stellar.org"
21
+ HORIZON_TESTNET_URL = "https://horizon-testnet.stellar.org"
22
+ FRIENDBOT_URL = "https://friendbot.stellar.org".freeze
14
23
 
15
- def self.default(options={})
24
+ def self.default(options = {})
16
25
  new options.merge(
17
26
  horizon: HORIZON_MAINNET_URL
18
27
  )
19
28
  end
20
29
 
21
- def self.default_testnet(options={})
30
+ def self.default_testnet(options = {})
22
31
  new options.merge(
23
- horizon: HORIZON_TESTNET_URL,
24
- friendbot: HORIZON_TESTNET_URL,
32
+ horizon: HORIZON_TESTNET_URL,
33
+ friendbot: HORIZON_TESTNET_URL
25
34
  )
26
35
  end
27
36
 
28
- def self.localhost(options={})
37
+ def self.localhost(options = {})
29
38
  new options.merge(
30
39
  horizon: HORIZON_LOCALHOST_URL
31
40
  )
@@ -33,10 +42,10 @@ module Stellar
33
42
 
34
43
  attr_reader :horizon
35
44
 
36
- Contract ({horizon: String}) => Any
45
+ # @option options [String] :horizon The Horizon server URL.
37
46
  def initialize(options)
38
47
  @options = options
39
- @horizon = Hyperclient.new(options[:horizon]) do |client|
48
+ @horizon = Hyperclient.new(options[:horizon]) { |client|
40
49
  client.faraday_block = lambda do |conn|
41
50
  conn.use Faraday::Response::RaiseError
42
51
  conn.use FaradayMiddleware::FollowRedirects
@@ -45,104 +54,106 @@ module Stellar
45
54
  conn.adapter :excon
46
55
  end
47
56
  client.headers = {
48
- 'Accept' => 'application/hal+json,application/problem+json,application/json'
57
+ "Accept" => "application/hal+json,application/problem+json,application/json",
58
+ "X-Client-Name" => "ruby-stellar-sdk",
59
+ "X-Client-Version" => VERSION
49
60
  }
50
- end
61
+ }
51
62
  end
52
63
 
53
- Contract Stellar::Account => Any
54
- def account_info(account)
55
- account_id = account.address
56
- @horizon.account(account_id:account_id)._get
64
+ # @param [Stellar::Account|String] account_or_address
65
+ def account_info(account_or_address)
66
+ account_id = if account_or_address.is_a?(Stellar::Account)
67
+ account_or_address.address
68
+ else
69
+ account_or_address
70
+ end
71
+ @horizon.account(account_id: account_id)._get
57
72
  end
58
73
 
59
- Contract ({
60
- account: Stellar::Account,
61
- destination: Stellar::Account
62
- }) => Any
63
- def account_merge(options={})
64
- account = options[:account]
74
+ # @option options [Stellar::Account] :account
75
+ # @option options [Stellar::Account] :destination
76
+ def account_merge(options = {})
77
+ account = options[:account]
65
78
  destination = options[:destination]
66
- sequence = options[:sequence] || (account_info(account).sequence.to_i + 1)
79
+ sequence = options[:sequence] || (account_info(account).sequence.to_i + 1)
67
80
 
68
- transaction = Stellar::Transaction.account_merge({
69
- account: account.keypair,
70
- destination: destination.keypair,
71
- sequence: sequence
72
- })
81
+ transaction = Stellar::TransactionBuilder.new(
82
+ source_account: destination.keypair,
83
+ sequence_number: sequence
84
+ ).add_operation(
85
+ Stellar::Operation.account_merge(destination: destination.keypair)
86
+ ).set_timeout(0).build
73
87
 
74
- envelope_base64 = transaction.to_envelope(account.keypair).to_xdr(:base64)
75
- @horizon.transactions._post(tx: envelope_base64)
88
+ envelope = transaction.to_envelope(account.keypair)
89
+ submit_transaction(tx_envelope: envelope)
76
90
  end
77
91
 
78
92
  def friendbot(account)
79
- raise NotImplementedError
93
+ uri = URI.parse(FRIENDBOT_URL)
94
+ uri.query = "addr=#{account.address}"
95
+ Faraday.post(uri.to_s)
80
96
  end
81
97
 
82
- Contract ({
83
- account: Stellar::Account,
84
- funder: Stellar::Account,
85
- starting_balance: Integer
86
- }) => Any
87
- def create_account(options={})
88
- funder = options[:funder]
98
+ # @option options [Stellar::Account] :account
99
+ # @option options [Stellar::Account] :funder
100
+ # @option options [Integer] :starting_balance
101
+ def create_account(options = {})
102
+ funder = options[:funder]
89
103
  sequence = options[:sequence] || (account_info(funder).sequence.to_i + 1)
90
104
  # In the future, the fee should be grabbed from the network's last transactions,
91
105
  # instead of using a hard-coded default value.
92
106
  fee = options[:fee] || DEFAULT_FEE
93
107
 
94
- payment = Stellar::Transaction.create_account({
95
- account: funder.keypair,
96
- destination: options[:account].keypair,
97
- sequence: sequence,
98
- starting_balance: options[:starting_balance],
99
- fee: fee,
100
- })
101
-
102
- envelope_base64 = payment.to_envelope(funder.keypair).to_xdr(:base64)
103
- @horizon.transactions._post(tx: envelope_base64)
104
- end
105
-
106
- Contract ({
107
- from: Stellar::Account,
108
- to: Stellar::Account,
109
- amount: Stellar::Amount
110
- }) => Any
111
- def send_payment(options={})
112
- from_account = options[:from]
108
+ payment = Stellar::TransactionBuilder.new(
109
+ source_account: funder.keypair,
110
+ sequence_number: sequence,
111
+ base_fee: fee
112
+ ).add_operation(
113
+ Stellar::Operation.create_account({
114
+ destination: options[:account].keypair,
115
+ starting_balance: options[:starting_balance]
116
+ })
117
+ ).set_timeout(0).build
118
+
119
+ envelope = payment.to_envelope(funder.keypair)
120
+ submit_transaction(tx_envelope: envelope)
121
+ end
122
+
123
+ # @option options [Stellar::Account] :from The source account
124
+ # @option options [Stellar::Account] :to The destination account
125
+ # @option options [Stellar::Amount] :amount The amount to send
126
+ def send_payment(options = {})
127
+ from_account = options[:from]
113
128
  tx_source_account = options[:transaction_source] || from_account
114
129
  op_source_account = from_account if tx_source_account.present?
115
130
 
116
131
  sequence = options[:sequence] ||
117
132
  (account_info(tx_source_account).sequence.to_i + 1)
118
133
 
119
- payment_details = {
120
- destination: options[:to].keypair,
121
- sequence: sequence,
122
- amount: options[:amount].to_payment,
123
- memo: options[:memo],
124
- }
125
-
126
- payment_details[:account] = tx_source_account.keypair
127
- if op_source_account.present?
128
- payment_details[:source_account] = op_source_account.keypair
129
- end
130
-
131
- payment = Stellar::Transaction.payment(payment_details)
134
+ payment = Stellar::TransactionBuilder.new(
135
+ source_account: tx_source_account.keypair,
136
+ sequence_number: sequence
137
+ ).add_operation(
138
+ Stellar::Operation.payment(
139
+ source_account: op_source_account.keypair,
140
+ destination: options[:to].keypair,
141
+ amount: options[:amount].to_payment
142
+ )
143
+ ).set_memo(options[:memo]).set_timeout(0).build
132
144
 
133
145
  signers = [tx_source_account, op_source_account].uniq(&:address)
134
146
  to_envelope_args = signers.map(&:keypair)
135
147
 
136
- envelope_base64 = payment.to_envelope(*to_envelope_args).to_xdr(:base64)
137
- @horizon.transactions._post(tx: envelope_base64)
148
+ envelope = payment.to_envelope(*to_envelope_args)
149
+ submit_transaction(tx_envelope: envelope)
138
150
  end
139
151
 
140
- Contract ({
141
- account: Maybe[Stellar::Account],
142
- limit: Maybe[Pos],
143
- cursor: Maybe[String]
144
- }) => TransactionPage
145
- def transactions(options={})
152
+ # @option options [Stellar::Account] :account
153
+ # @option options [Integer] :limit
154
+ # @option options [Integer] :cursor
155
+ # @return [Stellar::TransactionPage]
156
+ def transactions(options = {})
146
157
  args = options.slice(:limit, :cursor)
147
158
 
148
159
  resource = if options[:account]
@@ -155,13 +166,11 @@ module Stellar
155
166
  TransactionPage.new(resource)
156
167
  end
157
168
 
158
- Contract(C::KeywordArgs[
159
- asset: [Symbol, String, Xor[Stellar::KeyPair, Stellar::Account]],
160
- source: Stellar::Account,
161
- sequence: Maybe[Integer],
162
- fee: Maybe[Integer],
163
- limit: Maybe[Integer],
164
- ] => Any)
169
+ # @param [Array(Symbol,String,Stellar::KeyPair|Stellar::Account)] asset
170
+ # @param [Stellar::Account] source
171
+ # @param [Integer] sequence
172
+ # @param [Integer] fee
173
+ # @param [Integer] limit
165
174
  def change_trust(
166
175
  asset:,
167
176
  source:,
@@ -174,15 +183,117 @@ module Stellar
174
183
  args = {
175
184
  account: source.keypair,
176
185
  sequence: sequence,
177
- line: asset,
186
+ line: asset
178
187
  }
179
- args[:limit] = limit if !limit.nil?
188
+ args[:limit] = limit unless limit.nil?
180
189
 
181
190
  tx = Stellar::Transaction.change_trust(args)
182
191
 
183
- envelope_base64 = tx.to_envelope(source.keypair).to_xdr(:base64)
184
- horizon.transactions._post(tx: envelope_base64)
192
+ envelope = tx.to_envelope(source.keypair)
193
+ submit_transaction(tx_envelope: envelope)
194
+ end
195
+
196
+ # @param [Stellar::TransactionEnvelope] tx_envelope
197
+ # @option options [Boolean] :skip_memo_required_check (false)
198
+ def submit_transaction(tx_envelope:, options: {skip_memo_required_check: false})
199
+ unless options[:skip_memo_required_check]
200
+ check_memo_required(tx_envelope)
201
+ end
202
+ @horizon.transactions._post(tx: tx_envelope.to_xdr(:base64))
203
+ end
204
+
205
+ # Required by SEP-0029
206
+ # @param [Stellar::TransactionEnvelope] tx_envelope
207
+ def check_memo_required(tx_envelope)
208
+ tx = tx_envelope.tx
209
+
210
+ if tx.is_a?(Stellar::FeeBumpTransaction)
211
+ tx = tx.inner_tx.v1!.tx
212
+ end
213
+
214
+ # Check transactions where the .memo field is nil or of type MemoType.memo_none
215
+ if !tx.memo.nil? && tx.memo.type != Stellar::MemoType.memo_none
216
+ return
217
+ end
218
+
219
+ destinations = Set.new
220
+ ot = Stellar::OperationType
221
+
222
+ tx.operations.each_with_index do |op, idx|
223
+ destination = case op.body.type
224
+ when ot.payment, ot.path_payment_strict_receive, ot.path_payment_strict_send
225
+ op.body.value.destination
226
+ when ot.account_merge
227
+ # There is no AccountMergeOp, op.body is an Operation object
228
+ # and op.body.value is a PublicKey (or AccountID) object.
229
+ op.body.value
230
+ else
231
+ next
232
+ end
233
+
234
+ if destinations.include?(destination) || destination.switch == Stellar::CryptoKeyType.key_type_muxed_ed25519
235
+ next
236
+ end
237
+
238
+ destinations.add(destination)
239
+ kp = Stellar::KeyPair.from_public_key(destination.value)
240
+
241
+ begin
242
+ info = account_info(kp.address)
243
+ rescue Faraday::ResourceNotFound
244
+ # Don't raise an error if its a 404, but throw one otherwise
245
+ next
246
+ end
247
+ if info.data["config.memo_required"] == "MQ=="
248
+ # MQ== is the base64 encoded string for the string "1"
249
+ raise AccountRequiresMemoError.new("account requires memo", destination, idx)
250
+ end
251
+ end
252
+ end
253
+
254
+ # DEPRECATED: this function has been moved Stellar::SEP10.build_challenge_tx and
255
+ # will be removed in the next major version release.
256
+ #
257
+ # A wrapper function for Stellar::SEP10::build_challenge_tx.
258
+ #
259
+ # @param server [Stellar::KeyPair] Keypair for server's signing account.
260
+ # @param client [Stellar::KeyPair] Keypair for the account whishing to authenticate with the server.
261
+ # @param anchor_name [String] Anchor's name to be used in the manage_data key.
262
+ # @param timeout [Integer] Challenge duration (default to 5 minutes).
263
+ #
264
+ # @return [String] A base64 encoded string of the raw TransactionEnvelope xdr struct for the transaction.
265
+ def build_challenge_tx(server:, client:, anchor_name:, timeout: 300)
266
+ Stellar::SEP10.build_challenge_tx(
267
+ server: server, client: client, anchor_name: anchor_name, timeout: timeout
268
+ )
269
+ end
270
+
271
+ # DEPRECATED: this function has been moved to Stellar::SEP10::read_challenge_tx and
272
+ # will be removed in the next major version release.
273
+ #
274
+ # A wrapper function for Stellar::SEP10.verify_challenge_transaction
275
+ #
276
+ # @param challenge [String] SEP0010 transaction challenge in base64.
277
+ # @param server [Stellar::KeyPair] Stellar::KeyPair for server where the challenge was generated.
278
+ #
279
+ # @return [Boolean]
280
+ def verify_challenge_tx(challenge:, server:)
281
+ Stellar::SEP10.verify_challenge_tx(challenge_xdr: challenge, server: server)
282
+ true
185
283
  end
186
284
 
285
+ # DEPRECATED: this function has been moved to Stellar::SEP10::verify_tx_signed_by and
286
+ # will be removed in the next major version release.
287
+ #
288
+ # @param transaction_envelope [Stellar::TransactionEnvelope]
289
+ # @param keypair [Stellar::KeyPair]
290
+ #
291
+ # @return [Boolean]
292
+ #
293
+ def verify_tx_signed_by(transaction_envelope:, keypair:)
294
+ Stellar::SEP10.verify_tx_signed_by(
295
+ tx_envelope: transaction_envelope, keypair: keypair
296
+ )
297
+ end
187
298
  end
188
299
  end