stellar-sdk 0.7.0 → 0.23.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +11 -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 +201 -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 +18 -217
  14. data/.github/CODEOWNERS +0 -2
  15. data/.gitignore +0 -16
  16. data/.travis.yml +0 -19
  17. data/.yardopts +0 -7
  18. data/CONTRIBUTING.md +0 -48
  19. data/Gemfile +0 -14
  20. data/Guardfile +0 -5
  21. data/Rakefile +0 -3
  22. data/examples/01_get_funded.rb +0 -37
  23. data/examples/02_payment.rb +0 -15
  24. data/examples/03_transaction_history.rb +0 -21
  25. data/examples/04_setting_trust.rb +0 -1
  26. data/examples/05_fiat_payment.rb +0 -13
  27. data/examples/06_fund_testnet_friendbot.rb +0 -15
  28. data/ruby-stellar-sdk.gemspec +0 -36
  29. data/spec/config.yml.sample +0 -12
  30. data/spec/fixtures/vcr_cassettes/Stellar_Account/_lookup/should_handle_404_request_when_performing_federation_lookup.yml +0 -133
  31. data/spec/fixtures/vcr_cassettes/Stellar_Account/_lookup/should_handle_domains_that_are_not_federation_servers.yml +0 -44
  32. data/spec/fixtures/vcr_cassettes/Stellar_Account/_lookup/should_peforms_federation_lookup.yml +0 -85
  33. data/spec/fixtures/vcr_cassettes/Stellar_Client/_account_info/returns_the_current_details_for_the_account.yml +0 -190
  34. data/spec/fixtures/vcr_cassettes/Stellar_Client/_account_merge/merges_source_account_into_destination.yml +0 -714
  35. 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
  36. data/spec/fixtures/vcr_cassettes/Stellar_Client/_create_account/creates_the_account.yml +0 -323
  37. data/spec/fixtures/vcr_cassettes/Stellar_Client/_friendbot/requests_for_XLM_from_a_friendbot.yml +0 -246
  38. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/alphanum12_asset/sends_a_alphanum12_asset_to_the_destination.yml +0 -747
  39. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/alphanum4_asset/sends_a_alphanum4_asset_to_the_destination.yml +0 -747
  40. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/memo/accepts_the_memo_attribute.yml +0 -716
  41. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/native_asset/sends_a_native_payment_to_the_account.yml +0 -562
  42. data/spec/fixtures/vcr_cassettes/Stellar_Client/_send_payment/using_a_payment_channel/sends_a_payment_account_through_a_channel_account.yml +0 -694
  43. 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
  44. data/spec/fixtures/vcr_cassettes/Stellar_Client/_transactions/account_transactions/accepts_a_cursor_to_return_less_data.yml +0 -94
  45. data/spec/fixtures/vcr_cassettes/Stellar_Client/_transactions/account_transactions/returns_a_list_of_transaction_for_an_account.yml +0 -94
  46. data/spec/fixtures/vcr_cassettes/Stellar_Client/_transactions/all_transactions/accepts_a_cursor_to_return_less_data.yml +0 -94
  47. data/spec/fixtures/vcr_cassettes/Stellar_Client/_transactions/all_transactions/returns_a_list_of_transactions.yml +0 -94
  48. data/spec/lib/stellar/account_spec.rb +0 -59
  49. data/spec/lib/stellar/amount_spec.rb +0 -70
  50. data/spec/lib/stellar/client_spec.rb +0 -413
  51. data/spec/spec_helper.rb +0 -14
  52. data/spec/support/config.rb +0 -3
  53. data/spec/support/vcr.rb +0 -10
  54. data/tasks/rspec.rake +0 -6
  55. data/tasks/travis.rake +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3390d577fe288a6397d9f1c2844729023abc68b3147584211794d1d0eed294b2
4
- data.tar.gz: 01ce41b3d2a9be6ea02196e14639a379955b584744435a622d7091840426358e
3
+ metadata.gz: 6ba0c7588160128f44661f6d2d76ae5222a480da069a632381996ea3e96673a4
4
+ data.tar.gz: 6125026b196da359d48636cbf6f4e11492f2b197745fa1c035d9957ca169c405
5
5
  SHA512:
6
- metadata.gz: c740fe9977ea1dd2ae41ce0f2c4001eec2142d3adafe2739a2ec7deed9ba60f31419ad1f63c8d63b91cbc565146f855f5041f4171e2e324bda8770f1eae7d12b
7
- data.tar.gz: 563d52017e9767190f0bd09d1fdf0dfe17903dfb55820b53ca24be6eabd2e4cc8d3896a6bf4148ee6f2fcdbec89fecba08ec7b012a5d2258bf6fd354bbac28d0
6
+ metadata.gz: 0d5a62b7b0e532bd2c6c7e29c0628911cc37e3aabc81bc9301918fe34c2ea932d81fca416f5d989852ab4900e2a17b4ba4780fdf500eb5520687165526a54523
7
+ data.tar.gz: 29f8a8feeba48b840406515e056640c2c13eab8b4b32b585af47c32c95e300987506f69f7c656d010588f34187bf6e3433e83d992194ff0d032b173361e7347b
@@ -4,6 +4,17 @@ 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
+
7
18
  ## [0.7.0] - 2019-04-26
8
19
  ### Added
9
20
  - Friendbot support
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,32 +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'
14
- FRIENDBOT_URL = 'https://friendbot.stellar.org'.freeze
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
15
23
 
16
- def self.default(options={})
24
+ def self.default(options = {})
17
25
  new options.merge(
18
26
  horizon: HORIZON_MAINNET_URL
19
27
  )
20
28
  end
21
29
 
22
- def self.default_testnet(options={})
30
+ def self.default_testnet(options = {})
23
31
  new options.merge(
24
- horizon: HORIZON_TESTNET_URL,
25
- friendbot: HORIZON_TESTNET_URL,
32
+ horizon: HORIZON_TESTNET_URL,
33
+ friendbot: HORIZON_TESTNET_URL
26
34
  )
27
35
  end
28
36
 
29
- def self.localhost(options={})
37
+ def self.localhost(options = {})
30
38
  new options.merge(
31
39
  horizon: HORIZON_LOCALHOST_URL
32
40
  )
@@ -34,10 +42,10 @@ module Stellar
34
42
 
35
43
  attr_reader :horizon
36
44
 
37
- Contract ({horizon: String}) => Any
45
+ # @option options [String] :horizon The Horizon server URL.
38
46
  def initialize(options)
39
47
  @options = options
40
- @horizon = Hyperclient.new(options[:horizon]) do |client|
48
+ @horizon = Hyperclient.new(options[:horizon]) { |client|
41
49
  client.faraday_block = lambda do |conn|
42
50
  conn.use Faraday::Response::RaiseError
43
51
  conn.use FaradayMiddleware::FollowRedirects
@@ -46,34 +54,39 @@ module Stellar
46
54
  conn.adapter :excon
47
55
  end
48
56
  client.headers = {
49
- '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
50
60
  }
51
- end
61
+ }
52
62
  end
53
63
 
54
- Contract Stellar::Account => Any
55
- def account_info(account)
56
- account_id = account.address
57
- @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
58
72
  end
59
73
 
60
- Contract ({
61
- account: Stellar::Account,
62
- destination: Stellar::Account
63
- }) => Any
64
- def account_merge(options={})
65
- account = options[:account]
74
+ # @option options [Stellar::Account] :account
75
+ # @option options [Stellar::Account] :destination
76
+ def account_merge(options = {})
77
+ account = options[:account]
66
78
  destination = options[:destination]
67
- sequence = options[:sequence] || (account_info(account).sequence.to_i + 1)
79
+ sequence = options[:sequence] || (account_info(account).sequence.to_i + 1)
68
80
 
69
- transaction = Stellar::Transaction.account_merge({
70
- account: account.keypair,
71
- destination: destination.keypair,
72
- sequence: sequence
73
- })
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
74
87
 
75
- envelope_base64 = transaction.to_envelope(account.keypair).to_xdr(:base64)
76
- @horizon.transactions._post(tx: envelope_base64)
88
+ envelope = transaction.to_envelope(account.keypair)
89
+ submit_transaction(tx_envelope: envelope)
77
90
  end
78
91
 
79
92
  def friendbot(account)
@@ -82,70 +95,65 @@ module Stellar
82
95
  Faraday.post(uri.to_s)
83
96
  end
84
97
 
85
- Contract ({
86
- account: Stellar::Account,
87
- funder: Stellar::Account,
88
- starting_balance: Integer
89
- }) => Any
90
- def create_account(options={})
91
- 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]
92
103
  sequence = options[:sequence] || (account_info(funder).sequence.to_i + 1)
93
104
  # In the future, the fee should be grabbed from the network's last transactions,
94
105
  # instead of using a hard-coded default value.
95
106
  fee = options[:fee] || DEFAULT_FEE
96
107
 
97
- payment = Stellar::Transaction.create_account({
98
- account: funder.keypair,
99
- destination: options[:account].keypair,
100
- sequence: sequence,
101
- starting_balance: options[:starting_balance],
102
- fee: fee,
103
- })
104
-
105
- envelope_base64 = payment.to_envelope(funder.keypair).to_xdr(:base64)
106
- @horizon.transactions._post(tx: envelope_base64)
107
- end
108
-
109
- Contract ({
110
- from: Stellar::Account,
111
- to: Stellar::Account,
112
- amount: Stellar::Amount
113
- }) => Any
114
- def send_payment(options={})
115
- 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]
116
128
  tx_source_account = options[:transaction_source] || from_account
117
129
  op_source_account = from_account if tx_source_account.present?
118
130
 
119
131
  sequence = options[:sequence] ||
120
132
  (account_info(tx_source_account).sequence.to_i + 1)
121
133
 
122
- payment_details = {
123
- destination: options[:to].keypair,
124
- sequence: sequence,
125
- amount: options[:amount].to_payment,
126
- memo: options[:memo],
127
- }
128
-
129
- payment_details[:account] = tx_source_account.keypair
130
- if op_source_account.present?
131
- payment_details[:source_account] = op_source_account.keypair
132
- end
133
-
134
- 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
135
144
 
136
145
  signers = [tx_source_account, op_source_account].uniq(&:address)
137
146
  to_envelope_args = signers.map(&:keypair)
138
147
 
139
- envelope_base64 = payment.to_envelope(*to_envelope_args).to_xdr(:base64)
140
- @horizon.transactions._post(tx: envelope_base64)
148
+ envelope = payment.to_envelope(*to_envelope_args)
149
+ submit_transaction(tx_envelope: envelope)
141
150
  end
142
151
 
143
- Contract ({
144
- account: Maybe[Stellar::Account],
145
- limit: Maybe[Pos],
146
- cursor: Maybe[String]
147
- }) => TransactionPage
148
- 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 = {})
149
157
  args = options.slice(:limit, :cursor)
150
158
 
151
159
  resource = if options[:account]
@@ -158,13 +166,11 @@ module Stellar
158
166
  TransactionPage.new(resource)
159
167
  end
160
168
 
161
- Contract(C::KeywordArgs[
162
- asset: [Symbol, String, Xor[Stellar::KeyPair, Stellar::Account]],
163
- source: Stellar::Account,
164
- sequence: Maybe[Integer],
165
- fee: Maybe[Integer],
166
- limit: Maybe[Integer],
167
- ] => 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
168
174
  def change_trust(
169
175
  asset:,
170
176
  source:,
@@ -177,15 +183,117 @@ module Stellar
177
183
  args = {
178
184
  account: source.keypair,
179
185
  sequence: sequence,
180
- line: asset,
186
+ line: asset
181
187
  }
182
- args[:limit] = limit if !limit.nil?
188
+ args[:limit] = limit unless limit.nil?
183
189
 
184
190
  tx = Stellar::Transaction.change_trust(args)
185
191
 
186
- envelope_base64 = tx.to_envelope(source.keypair).to_xdr(:base64)
187
- 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
188
283
  end
189
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
190
298
  end
191
299
  end