stellar-sdk 0.26.0 → 0.30.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 +34 -9
- data/README.md +2 -2
- data/lib/stellar/federation.rb +51 -0
- data/lib/stellar/sep10.rb +37 -7
- data/lib/stellar-sdk.rb +7 -12
- metadata +32 -41
- data/lib/stellar/account.rb +0 -89
- data/lib/stellar/amount.rb +0 -36
- data/lib/stellar/client.rb +0 -298
- data/lib/stellar/horizon/problem.rb +0 -45
- data/lib/stellar/sdk/version.rb +0 -5
- data/lib/stellar/transaction_page.rb +0 -25
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5dc8d8d67076947afebdb2065fa08387d878e4250b5604ddfb4eb32b7056507a
|
4
|
+
data.tar.gz: 71b168f5ce4f97e76839d712eec86241a6839b0f93d7cd45544692703b28af22
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cf1ebdc0471f3884cfe207bcfc2f1131b6efbb9e35b7b4cce75044fea3b0c2245f7219af4b04bc868b79396d01303209fdc8ce041102b124ab92e64cb30e2dcc
|
7
|
+
data.tar.gz: 773d3492c23d37de50cafff1c6847aa0041136d235013e5d3526b44dc7a5e81ba18a77698eebcff3bb31f040bd958d903a803e2b9033205607cc47776c44e004
|
data/CHANGELOG.md
CHANGED
@@ -1,12 +1,37 @@
|
|
1
1
|
# Change Log
|
2
|
+
|
2
3
|
All notable changes to this project will be documented in this file.
|
3
4
|
|
4
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/)
|
5
6
|
and this project adheres to [Semantic Versioning](http://semver.org/).
|
6
7
|
|
7
|
-
## [
|
8
|
+
## [0.30.0](https://www.github.com/astroband/ruby-stellar-sdk/compare/v0.29.0...v0.30.0) (2021-10-14)
|
9
|
+
|
10
|
+
### Added
|
11
|
+
* `stellar-sdk` now depends on `stellar-horizon`
|
12
|
+
### Changed
|
13
|
+
* `Stellar::Amount` class moved to `stellar-base` gem
|
14
|
+
* `Stellar::Horizon::Problem` class moved to `stellar-horizon` gem
|
15
|
+
* `Stellar::TransactionPage` is now `Stellar::Horizon::TransactionPage` in `stellar-horizon` gem
|
16
|
+
* `toml-rb` gem is replaced with `tomlrb` gem to work around [segfaults in Ruby 3.0](https://github.com/mjackson/citrus/issues/60)
|
17
|
+
|
18
|
+
## [0.29.0](https://www.github.com/astroband/ruby-stellar-sdk/compare/v0.28.0...v0.29.0) (2021-09-07)
|
19
|
+
|
20
|
+
### Added
|
21
|
+
* support for client domain in SEP-10
|
22
|
+
### Deprecated
|
23
|
+
* `Stellar::Client` class is marked as deprecated in favour of new `stellar-horizon` gem
|
24
|
+
|
25
|
+
## [0.28.0](https://www.github.com/astroband/ruby-stellar-sdk/compare/v0.27.0...v0.28.0) (2021-07-17)
|
26
|
+
|
27
|
+
### Changed
|
28
|
+
* `Stellar::Account` class is now part of `stellar-base` gem
|
29
|
+
* `Stellar::Account.lookup` is deprecated, use `Stellar::Federation.lookup` instead
|
30
|
+
|
31
|
+
## [0.27.0](https://github.com/astroband/ruby-stellar-sdk/compare/v0.26.0...v0.27.0) (2021-05-08)
|
32
|
+
- No changes
|
8
33
|
|
9
|
-
## [0.26.0](https://github.com/
|
34
|
+
## [0.26.0](https://github.com/astroband/ruby-stellar-sdk/compare/v0.25.0...v0.26.0) - 2021-02-05
|
10
35
|
### Changed
|
11
36
|
- `Stellar::SEP10` is updated to comply with SEP10 v3.0.0 and v3.1.0
|
12
37
|
- `read_challenge_tx`` now verifies `domain` in challenge auth operation, as per SEP10 v3.0.0
|
@@ -14,7 +39,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
14
39
|
- `build_challenge_tx` will encode the extra auth domain operation into the challenge tx
|
15
40
|
- `read_challenge_tx` will verify that the challenge includes the correct auth domain operation
|
16
41
|
|
17
|
-
## [0.25.0](https://github.com/
|
42
|
+
## [0.25.0](https://github.com/astroband/ruby-stellar-sdk/compare/v0.24.0...v0.25.0) - 2020-10-30
|
18
43
|
### Changed
|
19
44
|
- `Stellar::SEP10` is updated to comply with SEP10 v2.1.0
|
20
45
|
- `build_challenge_tx` now accepts `domain` instead of `anchor_name`, using the
|
@@ -24,25 +49,25 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
|
|
24
49
|
### Removed:
|
25
50
|
- Deprecated `Stellar::SEP10.verify_challenge_tx` method is removed
|
26
51
|
|
27
|
-
## [0.24.0](https://github.com/
|
52
|
+
## [0.24.0](https://github.com/astroband/ruby-stellar-sdk/compare/v0.23.1...v0.24.0) - 2020-10-20
|
28
53
|
- Protocol 14 support
|
29
54
|
|
30
|
-
## [0.23.1](https://github.com/
|
55
|
+
## [0.23.1](https://github.com/astroband/ruby-stellar-sdk/compare/v0.23.0...v0.23.1) - 2020-06-18
|
31
56
|
- Fix SEP10, considering muxed accounts
|
32
57
|
|
33
|
-
## [0.23.0](https://github.com/
|
58
|
+
## [0.23.0](https://github.com/astroband/ruby-stellar-sdk/compare/v0.9.0-rc.1...v0.23.0)
|
34
59
|
- No changes. We bumped this version to sync `stellar-sdk` and `stellar-base` versions
|
35
60
|
|
36
|
-
## [0.9.0](https://github.com/
|
61
|
+
## [0.9.0](https://github.com/astroband/ruby-stellar-sdk/compare/v0.8.0...v0.9.0-rc.1)
|
37
62
|
### Added
|
38
63
|
- Stellar Protocol 13 support
|
39
64
|
- Fee-Bump transactions ([CAP-0015](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0015.md))
|
40
65
|
- Multiplexed accounts ([CAP-0027](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0027.md))
|
41
66
|
- Fine-Grained control on trustline authorization ([CAP-0018](https://github.com/stellar/stellar-protocol/blob/master/core/cap-0018.md))
|
42
67
|
|
43
|
-
## [0.8.0](https://github.com/
|
68
|
+
## [0.8.0](https://github.com/astroband/ruby-stellar-sdk/compare/v0.7.0...v0.8.0)
|
44
69
|
### Added
|
45
|
-
- SEP-10 Multisig Support [#69](https://github.com/
|
70
|
+
- SEP-10 Multisig Support [#69](https://github.com/astroband/ruby-stellar-sdk/pull/69)
|
46
71
|
- `X-Client-Name` and `X-Client-Version` headers
|
47
72
|
|
48
73
|
## [0.7.0] - 2019-04-26
|
data/README.md
CHANGED
@@ -39,7 +39,7 @@ client.send_payment({
|
|
39
39
|
})
|
40
40
|
```
|
41
41
|
|
42
|
-
Be sure to set the network when submitting to the public network (more information in [stellar-base](https://www.github.com/
|
42
|
+
Be sure to set the network when submitting to the public network (more information in [stellar-base](https://www.github.com/astroband/ruby-stellar-base)):
|
43
43
|
|
44
44
|
```ruby
|
45
45
|
Stellar.default_network = Stellar::Networks::PUBLIC
|
@@ -57,7 +57,7 @@ Stellar.default_network = Stellar::Networks::PUBLIC
|
|
57
57
|
## Contributing
|
58
58
|
|
59
59
|
1. Sign the [Contributor License Agreement](https://docs.google.com/forms/d/1g7EF6PERciwn7zfmfke5Sir2n10yddGGSXyZsq98tVY/viewform?usp=send_form)
|
60
|
-
2. Fork it ( https://github.com/
|
60
|
+
2. Fork it ( https://github.com/astroband/ruby-stellar-sdk/fork )
|
61
61
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
62
62
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
63
63
|
4. Push to the branch (`git push origin my-new-feature`)
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require "tomlrb"
|
2
|
+
require "uri"
|
3
|
+
require "faraday"
|
4
|
+
require "json"
|
5
|
+
|
6
|
+
module Stellar
|
7
|
+
class Federation
|
8
|
+
def self.lookup(federated_name)
|
9
|
+
_, domain = federated_name.split("*")
|
10
|
+
if domain.nil?
|
11
|
+
raise InvalidFederationAddress.new
|
12
|
+
end
|
13
|
+
|
14
|
+
domain_req = Faraday.new("https://#{domain}/.well-known/stellar.toml").get
|
15
|
+
|
16
|
+
unless domain_req.status == 200
|
17
|
+
raise InvalidStellarDomain, "Domain does not contain stellar.toml file"
|
18
|
+
end
|
19
|
+
|
20
|
+
fed_server_url = Tomlrb.parse(domain_req.body)["FEDERATION_SERVER"]
|
21
|
+
if fed_server_url.nil?
|
22
|
+
raise InvalidStellarTOML, "Invalid Stellar TOML file"
|
23
|
+
end
|
24
|
+
|
25
|
+
unless fed_server_url&.match?(URI::DEFAULT_PARSER.make_regexp)
|
26
|
+
raise InvalidFederationURL, "Invalid Federation Server URL"
|
27
|
+
end
|
28
|
+
|
29
|
+
lookup_req = Faraday.new(fed_server_url).get { |req|
|
30
|
+
req.params[:q] = federated_name
|
31
|
+
req.params[:type] = "name"
|
32
|
+
}
|
33
|
+
|
34
|
+
unless lookup_req.status == 200
|
35
|
+
raise AccountNotFound, "Account not found"
|
36
|
+
end
|
37
|
+
|
38
|
+
JSON.parse(lookup_req.body)["account_id"]
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class AccountNotFound < StandardError; end
|
43
|
+
|
44
|
+
class InvalidStellarTOML < StandardError; end
|
45
|
+
|
46
|
+
class InvalidFederationAddress < StandardError; end
|
47
|
+
|
48
|
+
class InvalidStellarDomain < StandardError; end
|
49
|
+
|
50
|
+
class InvalidFederationURL < StandardError; end
|
51
|
+
end
|
data/lib/stellar/sep10.rb
CHANGED
@@ -64,6 +64,20 @@ module Stellar
|
|
64
64
|
)
|
65
65
|
end
|
66
66
|
|
67
|
+
if options[:client_domain].present?
|
68
|
+
if options[:client_domain_account].blank?
|
69
|
+
raise "`client_domain_account` is required, if `client_domain` is provided"
|
70
|
+
end
|
71
|
+
|
72
|
+
tb.add_operation(
|
73
|
+
Stellar::Operation.manage_data(
|
74
|
+
name: "client_domain",
|
75
|
+
value: options[:client_domain],
|
76
|
+
source_account: options[:client_domain_account]
|
77
|
+
)
|
78
|
+
)
|
79
|
+
end
|
80
|
+
|
67
81
|
tb.build.to_envelope(server).to_xdr(:base64)
|
68
82
|
end
|
69
83
|
|
@@ -125,16 +139,14 @@ module Stellar
|
|
125
139
|
|
126
140
|
rest_ops.each do |op|
|
127
141
|
body = op.body
|
142
|
+
op_params = body.value
|
128
143
|
|
129
144
|
if body.arm != :manage_data_op
|
130
145
|
raise InvalidSep10ChallengeError, "The transaction has operations that are not of type 'manageData'"
|
131
|
-
elsif op.source_account != server.muxed_account
|
146
|
+
elsif op.source_account != server.muxed_account && op_params.data_name != "client_domain"
|
132
147
|
raise InvalidSep10ChallengeError, "The transaction has operations that are unrecognized"
|
133
|
-
|
134
|
-
|
135
|
-
if op_params.data_name == "web_auth_domain" && options.key?(:auth_domain) && op_params.data_value != options[:auth_domain]
|
136
|
-
raise InvalidSep10ChallengeError, "The transaction has 'manageData' operation with 'web_auth_domain' key and invalid value"
|
137
|
-
end
|
148
|
+
elsif op_params.data_name == "web_auth_domain" && options.key?(:auth_domain) && op_params.data_value != options[:auth_domain]
|
149
|
+
raise InvalidSep10ChallengeError, "The transaction has 'manageData' operation with 'web_auth_domain' key and invalid value"
|
138
150
|
end
|
139
151
|
end
|
140
152
|
|
@@ -210,6 +222,9 @@ module Stellar
|
|
210
222
|
client_signers = signers.select { |s| s =~ /G[A-Z0-9]{55}/ && s != server.address }.to_set
|
211
223
|
raise InvalidSep10ChallengeError, "at least one regular signer must be provided" if client_signers.empty?
|
212
224
|
|
225
|
+
client_domain_account_address = extract_client_domain_account(te.tx)
|
226
|
+
client_signers.add(client_domain_account_address) if client_domain_account_address.present?
|
227
|
+
|
213
228
|
# verify all signatures in one pass
|
214
229
|
client_signers.add(server.address)
|
215
230
|
signers_found = verify_tx_signatures(tx_envelope: te, signers: client_signers)
|
@@ -229,6 +244,10 @@ module Stellar
|
|
229
244
|
raise InvalidSep10ChallengeError, "Transaction has unrecognized signatures."
|
230
245
|
end
|
231
246
|
|
247
|
+
if client_domain_account_address.present? && !signers_found.include?(client_domain_account_address)
|
248
|
+
raise InvalidSep10ChallengeError, "Transaction not signed by client domain account."
|
249
|
+
end
|
250
|
+
|
232
251
|
signers_found
|
233
252
|
end
|
234
253
|
|
@@ -249,7 +268,7 @@ module Stellar
|
|
249
268
|
to_keypair = Stellar::DSL.method(:KeyPair)
|
250
269
|
keys_by_hint = signers.map(&to_keypair).index_by(&:signature_hint)
|
251
270
|
|
252
|
-
|
271
|
+
signatures.each_with_object(Set.new) do |sig, result|
|
253
272
|
key = keys_by_hint.delete(sig.hint)
|
254
273
|
result.add(key.address) if key&.verify(sig.signature, tx_hash)
|
255
274
|
end
|
@@ -272,5 +291,16 @@ module Stellar
|
|
272
291
|
keypair.verify(sig.signature, tx_hash)
|
273
292
|
end
|
274
293
|
end
|
294
|
+
|
295
|
+
def self.extract_client_domain_account(transaction)
|
296
|
+
client_domain_account_op =
|
297
|
+
transaction
|
298
|
+
.operations
|
299
|
+
.find { |op| op.body.value.data_name == "client_domain" }
|
300
|
+
|
301
|
+
return if client_domain_account_op.blank?
|
302
|
+
|
303
|
+
Util::StrKey.encode_muxed_account(client_domain_account_op.source_account)
|
304
|
+
end
|
275
305
|
end
|
276
306
|
end
|
data/lib/stellar-sdk.rb
CHANGED
@@ -1,18 +1,13 @@
|
|
1
1
|
require "stellar-base"
|
2
|
-
|
2
|
+
require "stellar-horizon"
|
3
3
|
|
4
4
|
module Stellar
|
5
|
-
|
6
|
-
|
7
|
-
autoload :Client
|
8
|
-
autoload :SEP10
|
9
|
-
|
10
|
-
module Horizon
|
11
|
-
extend ActiveSupport::Autoload
|
12
|
-
|
13
|
-
autoload :Problem
|
14
|
-
autoload :Result
|
5
|
+
module SDK
|
6
|
+
VERSION = ::Stellar::VERSION
|
15
7
|
end
|
8
|
+
Client = Horizon::Client
|
16
9
|
|
17
|
-
autoload :
|
10
|
+
autoload :Amount
|
11
|
+
autoload :Federation
|
12
|
+
autoload :SEP10
|
18
13
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stellar-sdk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.30.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Scott Fleckenstein
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: exe
|
12
12
|
cert_chain: []
|
13
|
-
date: 2021-
|
13
|
+
date: 2021-10-13 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: stellar-base
|
@@ -18,81 +18,75 @@ dependencies:
|
|
18
18
|
requirements:
|
19
19
|
- - '='
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version: 0.
|
21
|
+
version: 0.30.0
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
requirements:
|
26
26
|
- - '='
|
27
27
|
- !ruby/object:Gem::Version
|
28
|
-
version: 0.
|
28
|
+
version: 0.30.0
|
29
29
|
- !ruby/object:Gem::Dependency
|
30
|
-
name:
|
30
|
+
name: stellar-horizon
|
31
31
|
requirement: !ruby/object:Gem::Requirement
|
32
32
|
requirements:
|
33
|
-
- -
|
34
|
-
- !ruby/object:Gem::Version
|
35
|
-
version: 5.0.0
|
36
|
-
- - "<"
|
33
|
+
- - '='
|
37
34
|
- !ruby/object:Gem::Version
|
38
|
-
version:
|
35
|
+
version: 0.30.0
|
39
36
|
type: :runtime
|
40
37
|
prerelease: false
|
41
38
|
version_requirements: !ruby/object:Gem::Requirement
|
42
39
|
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
version: 5.0.0
|
46
|
-
- - "<"
|
40
|
+
- - '='
|
47
41
|
- !ruby/object:Gem::Version
|
48
|
-
version:
|
42
|
+
version: 0.30.0
|
49
43
|
- !ruby/object:Gem::Dependency
|
50
|
-
name:
|
44
|
+
name: activesupport
|
51
45
|
requirement: !ruby/object:Gem::Requirement
|
52
46
|
requirements:
|
53
47
|
- - ">="
|
54
48
|
- !ruby/object:Gem::Version
|
55
|
-
version: 0.
|
49
|
+
version: 5.0.0
|
56
50
|
- - "<"
|
57
51
|
- !ruby/object:Gem::Version
|
58
|
-
version: '
|
52
|
+
version: '7.0'
|
59
53
|
type: :runtime
|
60
54
|
prerelease: false
|
61
55
|
version_requirements: !ruby/object:Gem::Requirement
|
62
56
|
requirements:
|
63
57
|
- - ">="
|
64
58
|
- !ruby/object:Gem::Version
|
65
|
-
version: 0.
|
59
|
+
version: 5.0.0
|
66
60
|
- - "<"
|
67
61
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
62
|
+
version: '7.0'
|
69
63
|
- !ruby/object:Gem::Dependency
|
70
|
-
name:
|
64
|
+
name: faraday
|
71
65
|
requirement: !ruby/object:Gem::Requirement
|
72
66
|
requirements:
|
73
67
|
- - ">="
|
74
68
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
69
|
+
version: 1.6.0
|
76
70
|
- - "<"
|
77
71
|
- !ruby/object:Gem::Version
|
78
|
-
version: '
|
72
|
+
version: '2.0'
|
79
73
|
type: :runtime
|
80
74
|
prerelease: false
|
81
75
|
version_requirements: !ruby/object:Gem::Requirement
|
82
76
|
requirements:
|
83
77
|
- - ">="
|
84
78
|
- !ruby/object:Gem::Version
|
85
|
-
version:
|
79
|
+
version: 1.6.0
|
86
80
|
- - "<"
|
87
81
|
- !ruby/object:Gem::Version
|
88
|
-
version: '
|
82
|
+
version: '2.0'
|
89
83
|
- !ruby/object:Gem::Dependency
|
90
|
-
name:
|
84
|
+
name: tomlrb
|
91
85
|
requirement: !ruby/object:Gem::Requirement
|
92
86
|
requirements:
|
93
87
|
- - ">="
|
94
88
|
- !ruby/object:Gem::Version
|
95
|
-
version:
|
89
|
+
version: 2.0.1
|
96
90
|
- - "<"
|
97
91
|
- !ruby/object:Gem::Version
|
98
92
|
version: '3.0'
|
@@ -102,7 +96,7 @@ dependencies:
|
|
102
96
|
requirements:
|
103
97
|
- - ">="
|
104
98
|
- !ruby/object:Gem::Version
|
105
|
-
version:
|
99
|
+
version: 2.0.1
|
106
100
|
- - "<"
|
107
101
|
- !ruby/object:Gem::Version
|
108
102
|
version: '3.0'
|
@@ -112,14 +106,14 @@ dependencies:
|
|
112
106
|
requirements:
|
113
107
|
- - "~>"
|
114
108
|
- !ruby/object:Gem::Version
|
115
|
-
version: '2.
|
109
|
+
version: '2.2'
|
116
110
|
type: :development
|
117
111
|
prerelease: false
|
118
112
|
version_requirements: !ruby/object:Gem::Requirement
|
119
113
|
requirements:
|
120
114
|
- - "~>"
|
121
115
|
- !ruby/object:Gem::Version
|
122
|
-
version: '2.
|
116
|
+
version: '2.2'
|
123
117
|
- !ruby/object:Gem::Dependency
|
124
118
|
name: rake
|
125
119
|
requirement: !ruby/object:Gem::Requirement
|
@@ -161,21 +155,18 @@ files:
|
|
161
155
|
- LICENSE
|
162
156
|
- README.md
|
163
157
|
- lib/stellar-sdk.rb
|
164
|
-
- lib/stellar/
|
165
|
-
- lib/stellar/amount.rb
|
166
|
-
- lib/stellar/client.rb
|
167
|
-
- lib/stellar/horizon/problem.rb
|
168
|
-
- lib/stellar/sdk/version.rb
|
158
|
+
- lib/stellar/federation.rb
|
169
159
|
- lib/stellar/sep10.rb
|
170
|
-
|
171
|
-
homepage: https://github.com/stellar/ruby-stellar-sdk/tree/master/sdk
|
160
|
+
homepage: https://github.com/astroband/ruby-stellar-sdk
|
172
161
|
licenses:
|
173
162
|
- Apache-2.0
|
174
163
|
metadata:
|
164
|
+
bug_tracker_uri: https://github.com/astroband/ruby-stellar-sdk/issues
|
165
|
+
changelog_uri: https://github.com/astroband/ruby-stellar-sdk/blob/v0.30.0/sdk/CHANGELOG.md
|
166
|
+
documentation_uri: https://rubydoc.info/gems/stellar-sdk/0.30.0/
|
175
167
|
github_repo: ssh://github.com/astroband/ruby-stellar-sdk
|
176
|
-
|
177
|
-
|
178
|
-
source_code_uri: https://github.com/astroband/ruby-stellar-sdk/tree/v0.26.0/sdk
|
168
|
+
homepage_uri: https://github.com/astroband/ruby-stellar-sdk/tree/main/sdk
|
169
|
+
source_code_uri: https://github.com/astroband/ruby-stellar-sdk/tree/v0.30.0/sdk
|
179
170
|
post_install_message:
|
180
171
|
rdoc_options: []
|
181
172
|
require_paths:
|
@@ -191,7 +182,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
182
|
- !ruby/object:Gem::Version
|
192
183
|
version: '0'
|
193
184
|
requirements: []
|
194
|
-
rubygems_version: 3.2.
|
185
|
+
rubygems_version: 3.2.22
|
195
186
|
signing_key:
|
196
187
|
specification_version: 4
|
197
188
|
summary: Stellar client library
|
data/lib/stellar/account.rb
DELETED
@@ -1,89 +0,0 @@
|
|
1
|
-
require "toml-rb"
|
2
|
-
require "uri"
|
3
|
-
require "faraday"
|
4
|
-
require "json"
|
5
|
-
|
6
|
-
module Stellar
|
7
|
-
class Account
|
8
|
-
delegate :address, to: :keypair
|
9
|
-
|
10
|
-
def self.random
|
11
|
-
keypair = Stellar::KeyPair.random
|
12
|
-
new(keypair)
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.from_seed(seed)
|
16
|
-
keypair = Stellar::KeyPair.from_seed(seed)
|
17
|
-
new(keypair)
|
18
|
-
end
|
19
|
-
|
20
|
-
def self.from_address(address)
|
21
|
-
keypair = Stellar::KeyPair.from_address(address)
|
22
|
-
new(keypair)
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.lookup(federated_name)
|
26
|
-
_, domain = federated_name.split("*")
|
27
|
-
if domain.nil?
|
28
|
-
raise InvalidFederationAddress.new
|
29
|
-
end
|
30
|
-
|
31
|
-
domain_req = Faraday.new("https://#{domain}/.well-known/stellar.toml").get
|
32
|
-
|
33
|
-
unless domain_req.status == 200
|
34
|
-
raise InvalidStellarDomain.new("Domain does not contain stellar.toml file")
|
35
|
-
end
|
36
|
-
|
37
|
-
fed_server_url = TomlRB.parse(domain_req.body)["FEDERATION_SERVER"]
|
38
|
-
if fed_server_url.nil?
|
39
|
-
raise InvalidStellarTOML.new("Invalid Stellar TOML file")
|
40
|
-
end
|
41
|
-
|
42
|
-
unless fed_server_url&.match?(URI::DEFAULT_PARSER.make_regexp)
|
43
|
-
raise InvalidFederationURL.new("Invalid Federation Server URL")
|
44
|
-
end
|
45
|
-
|
46
|
-
lookup_req = Faraday.new(fed_server_url).get { |req|
|
47
|
-
req.params[:q] = federated_name
|
48
|
-
req.params[:type] = "name"
|
49
|
-
}
|
50
|
-
|
51
|
-
unless lookup_req.status == 200
|
52
|
-
raise AccountNotFound.new("Account not found")
|
53
|
-
end
|
54
|
-
|
55
|
-
JSON.parse(lookup_req.body)["account_id"]
|
56
|
-
end
|
57
|
-
|
58
|
-
def self.master
|
59
|
-
keypair = Stellar::KeyPair.from_raw_seed("allmylifemyhearthasbeensearching")
|
60
|
-
new(keypair)
|
61
|
-
end
|
62
|
-
|
63
|
-
attr_reader :keypair
|
64
|
-
|
65
|
-
# @param [Stellar::KeyPair] keypair
|
66
|
-
def initialize(keypair)
|
67
|
-
@keypair = keypair
|
68
|
-
end
|
69
|
-
|
70
|
-
def to_keypair
|
71
|
-
keypair
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
class AccountNotFound < StandardError
|
76
|
-
end
|
77
|
-
|
78
|
-
class InvalidStellarTOML < StandardError
|
79
|
-
end
|
80
|
-
|
81
|
-
class InvalidFederationAddress < StandardError
|
82
|
-
end
|
83
|
-
|
84
|
-
class InvalidStellarDomain < StandardError
|
85
|
-
end
|
86
|
-
|
87
|
-
class InvalidFederationURL < StandardError
|
88
|
-
end
|
89
|
-
end
|
data/lib/stellar/amount.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
module Stellar
|
2
|
-
class Amount
|
3
|
-
attr_reader :amount
|
4
|
-
attr_reader :asset
|
5
|
-
|
6
|
-
# @param [Fixnum] amount
|
7
|
-
# @param [Stellar::Asset] asset
|
8
|
-
def initialize(amount, asset = Stellar::Asset.native)
|
9
|
-
# TODO: how are we going to handle decimal considerations?
|
10
|
-
|
11
|
-
@amount = amount
|
12
|
-
@asset = asset
|
13
|
-
end
|
14
|
-
|
15
|
-
# @return [Array(Symbol, Fixnum)] in case of a native asset
|
16
|
-
# @return [Array(Symbol, String, Stellar::KeyPair, Fixnum)] in case of alphanum asset
|
17
|
-
def to_payment
|
18
|
-
case asset.type
|
19
|
-
when AssetType.asset_type_native
|
20
|
-
[:native, amount]
|
21
|
-
when AssetType.asset_type_credit_alphanum4
|
22
|
-
keypair = KeyPair.from_public_key(asset.issuer.value)
|
23
|
-
[:alphanum4, asset.code, keypair, amount]
|
24
|
-
when AssetType.asset_type_credit_alphanum12
|
25
|
-
keypair = KeyPair.from_public_key(asset.issuer.value)
|
26
|
-
[:alphanum12, asset.code, keypair, amount]
|
27
|
-
else
|
28
|
-
raise "Unknown asset type: #{asset.type}"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def inspect
|
33
|
-
"#<Stellar::Amount #{asset}(#{amount})>"
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
data/lib/stellar/client.rb
DELETED
@@ -1,298 +0,0 @@
|
|
1
|
-
require "hyperclient"
|
2
|
-
require "active_support/core_ext/object/blank"
|
3
|
-
require "securerandom"
|
4
|
-
|
5
|
-
module Stellar
|
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
|
15
|
-
|
16
|
-
class Client
|
17
|
-
DEFAULT_FEE = 100
|
18
|
-
|
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
|
23
|
-
|
24
|
-
def self.default(options = {})
|
25
|
-
new options.merge(
|
26
|
-
horizon: HORIZON_MAINNET_URL
|
27
|
-
)
|
28
|
-
end
|
29
|
-
|
30
|
-
def self.default_testnet(options = {})
|
31
|
-
new options.merge(
|
32
|
-
horizon: HORIZON_TESTNET_URL,
|
33
|
-
friendbot: HORIZON_TESTNET_URL
|
34
|
-
)
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.localhost(options = {})
|
38
|
-
new options.merge(
|
39
|
-
horizon: HORIZON_LOCALHOST_URL
|
40
|
-
)
|
41
|
-
end
|
42
|
-
|
43
|
-
attr_reader :horizon
|
44
|
-
|
45
|
-
# @option options [String] :horizon The Horizon server URL.
|
46
|
-
def initialize(options)
|
47
|
-
@options = options
|
48
|
-
@horizon = Hyperclient.new(options[:horizon]) { |client|
|
49
|
-
client.faraday_block = lambda do |conn|
|
50
|
-
conn.use Faraday::Response::RaiseError
|
51
|
-
conn.use FaradayMiddleware::FollowRedirects
|
52
|
-
conn.request :url_encoded
|
53
|
-
conn.response :hal_json, content_type: /\bjson$/
|
54
|
-
conn.adapter :excon
|
55
|
-
end
|
56
|
-
client.headers = {
|
57
|
-
"Accept" => "application/hal+json,application/problem+json,application/json",
|
58
|
-
"X-Client-Name" => "ruby-stellar-sdk",
|
59
|
-
"X-Client-Version" => VERSION
|
60
|
-
}
|
61
|
-
}
|
62
|
-
end
|
63
|
-
|
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
|
72
|
-
end
|
73
|
-
|
74
|
-
# @option options [Stellar::Account] :account
|
75
|
-
# @option options [Stellar::Account] :destination
|
76
|
-
def account_merge(options = {})
|
77
|
-
account = options[:account]
|
78
|
-
destination = options[:destination]
|
79
|
-
sequence = options[:sequence] || (account_info(account).sequence.to_i + 1)
|
80
|
-
|
81
|
-
transaction = Stellar::TransactionBuilder.account_merge(
|
82
|
-
source_account: destination.keypair,
|
83
|
-
sequence_number: sequence,
|
84
|
-
destination: destination.keypair
|
85
|
-
)
|
86
|
-
|
87
|
-
envelope = transaction.to_envelope(account.keypair)
|
88
|
-
submit_transaction(tx_envelope: envelope)
|
89
|
-
end
|
90
|
-
|
91
|
-
def friendbot(account)
|
92
|
-
uri = URI.parse(FRIENDBOT_URL)
|
93
|
-
uri.query = "addr=#{account.address}"
|
94
|
-
Faraday.post(uri.to_s)
|
95
|
-
end
|
96
|
-
|
97
|
-
# @option options [Stellar::Account] :account
|
98
|
-
# @option options [Stellar::Account] :funder
|
99
|
-
# @option options [Integer] :starting_balance
|
100
|
-
def create_account(options = {})
|
101
|
-
funder = options[:funder]
|
102
|
-
sequence = options[:sequence] || (account_info(funder).sequence.to_i + 1)
|
103
|
-
# In the future, the fee should be grabbed from the network's last transactions,
|
104
|
-
# instead of using a hard-coded default value.
|
105
|
-
fee = options[:fee] || DEFAULT_FEE
|
106
|
-
|
107
|
-
payment = Stellar::TransactionBuilder.create_account(
|
108
|
-
source_account: funder.keypair,
|
109
|
-
sequence_number: sequence,
|
110
|
-
base_fee: fee,
|
111
|
-
destination: options[:account].keypair,
|
112
|
-
starting_balance: options[:starting_balance]
|
113
|
-
)
|
114
|
-
envelope = payment.to_envelope(funder.keypair)
|
115
|
-
submit_transaction(tx_envelope: envelope)
|
116
|
-
end
|
117
|
-
|
118
|
-
# @option options [Stellar::Account] :from The source account
|
119
|
-
# @option options [Stellar::Account] :to The destination account
|
120
|
-
# @option options [Stellar::Amount] :amount The amount to send
|
121
|
-
def send_payment(options = {})
|
122
|
-
from_account = options[:from]
|
123
|
-
tx_source_account = options[:transaction_source] || from_account
|
124
|
-
op_source_account = from_account if tx_source_account.present?
|
125
|
-
|
126
|
-
sequence = options[:sequence] ||
|
127
|
-
(account_info(tx_source_account).sequence.to_i + 1)
|
128
|
-
|
129
|
-
payment = Stellar::TransactionBuilder.new(
|
130
|
-
source_account: tx_source_account.keypair,
|
131
|
-
sequence_number: sequence
|
132
|
-
).add_operation(
|
133
|
-
Stellar::Operation.payment(
|
134
|
-
source_account: op_source_account.keypair,
|
135
|
-
destination: options[:to].keypair,
|
136
|
-
amount: options[:amount].to_payment
|
137
|
-
)
|
138
|
-
).set_memo(options[:memo]).set_timeout(0).build
|
139
|
-
|
140
|
-
signers = [tx_source_account, op_source_account].uniq(&:address)
|
141
|
-
to_envelope_args = signers.map(&:keypair)
|
142
|
-
|
143
|
-
envelope = payment.to_envelope(*to_envelope_args)
|
144
|
-
submit_transaction(tx_envelope: envelope)
|
145
|
-
end
|
146
|
-
|
147
|
-
# @option options [Stellar::Account] :account
|
148
|
-
# @option options [Integer] :limit
|
149
|
-
# @option options [Integer] :cursor
|
150
|
-
# @return [Stellar::TransactionPage]
|
151
|
-
def transactions(options = {})
|
152
|
-
args = options.slice(:limit, :cursor)
|
153
|
-
|
154
|
-
resource = if options[:account]
|
155
|
-
args = args.merge(account_id: options[:account].address)
|
156
|
-
@horizon.account_transactions(args)
|
157
|
-
else
|
158
|
-
@horizon.transactions(args)
|
159
|
-
end
|
160
|
-
|
161
|
-
TransactionPage.new(resource)
|
162
|
-
end
|
163
|
-
|
164
|
-
# @param [Array(Symbol,String,Stellar::KeyPair|Stellar::Account)] asset
|
165
|
-
# @param [Stellar::Account] source
|
166
|
-
# @param [Integer] sequence
|
167
|
-
# @param [Integer] fee
|
168
|
-
# @param [Integer] limit
|
169
|
-
def change_trust(
|
170
|
-
asset:,
|
171
|
-
source:,
|
172
|
-
sequence: nil,
|
173
|
-
fee: DEFAULT_FEE,
|
174
|
-
limit: nil
|
175
|
-
)
|
176
|
-
sequence ||= (account_info(source).sequence.to_i + 1)
|
177
|
-
|
178
|
-
op_args = {
|
179
|
-
account: source.keypair,
|
180
|
-
sequence: sequence,
|
181
|
-
line: asset
|
182
|
-
}
|
183
|
-
op_args[:limit] = limit unless limit.nil?
|
184
|
-
|
185
|
-
tx = Stellar::TransactionBuilder.change_trust(
|
186
|
-
source_account: source.keypair,
|
187
|
-
sequence_number: sequence,
|
188
|
-
**op_args
|
189
|
-
)
|
190
|
-
|
191
|
-
envelope = tx.to_envelope(source.keypair)
|
192
|
-
submit_transaction(tx_envelope: envelope)
|
193
|
-
end
|
194
|
-
|
195
|
-
# @param [Stellar::TransactionEnvelope] tx_envelope
|
196
|
-
# @option options [Boolean] :skip_memo_required_check (false)
|
197
|
-
def submit_transaction(tx_envelope:, options: {skip_memo_required_check: false})
|
198
|
-
unless options[:skip_memo_required_check]
|
199
|
-
check_memo_required(tx_envelope)
|
200
|
-
end
|
201
|
-
@horizon.transactions._post(tx: tx_envelope.to_xdr(:base64))
|
202
|
-
end
|
203
|
-
|
204
|
-
# Required by SEP-0029
|
205
|
-
# @param [Stellar::TransactionEnvelope] tx_envelope
|
206
|
-
def check_memo_required(tx_envelope)
|
207
|
-
tx = tx_envelope.tx
|
208
|
-
|
209
|
-
if tx.is_a?(Stellar::FeeBumpTransaction)
|
210
|
-
tx = tx.inner_tx.v1!.tx
|
211
|
-
end
|
212
|
-
|
213
|
-
# Check transactions where the .memo field is nil or of type MemoType.memo_none
|
214
|
-
if !tx.memo.nil? && tx.memo.type != Stellar::MemoType.memo_none
|
215
|
-
return
|
216
|
-
end
|
217
|
-
|
218
|
-
destinations = Set.new
|
219
|
-
ot = Stellar::OperationType
|
220
|
-
|
221
|
-
tx.operations.each_with_index do |op, idx|
|
222
|
-
destination = case op.body.type
|
223
|
-
when ot.payment, ot.path_payment_strict_receive, ot.path_payment_strict_send
|
224
|
-
op.body.value.destination
|
225
|
-
when ot.account_merge
|
226
|
-
# There is no AccountMergeOp, op.body is an Operation object
|
227
|
-
# and op.body.value is a PublicKey (or AccountID) object.
|
228
|
-
op.body.value
|
229
|
-
else
|
230
|
-
next
|
231
|
-
end
|
232
|
-
|
233
|
-
if destinations.include?(destination) || destination.switch == Stellar::CryptoKeyType.key_type_muxed_ed25519
|
234
|
-
next
|
235
|
-
end
|
236
|
-
|
237
|
-
destinations.add(destination)
|
238
|
-
kp = Stellar::KeyPair.from_public_key(destination.value)
|
239
|
-
|
240
|
-
begin
|
241
|
-
info = account_info(kp.address)
|
242
|
-
rescue Faraday::ResourceNotFound
|
243
|
-
# Don't raise an error if its a 404, but throw one otherwise
|
244
|
-
next
|
245
|
-
end
|
246
|
-
if info.data["config.memo_required"] == "MQ=="
|
247
|
-
# MQ== is the base64 encoded string for the string "1"
|
248
|
-
raise AccountRequiresMemoError.new("account requires memo", destination, idx)
|
249
|
-
end
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
# DEPRECATED: this function has been moved Stellar::SEP10.build_challenge_tx and
|
254
|
-
# will be removed in the next major version release.
|
255
|
-
#
|
256
|
-
# A wrapper function for Stellar::SEP10::build_challenge_tx.
|
257
|
-
#
|
258
|
-
# @param server [Stellar::KeyPair] Keypair for server's signing account.
|
259
|
-
# @param client [Stellar::KeyPair] Keypair for the account whishing to authenticate with the server.
|
260
|
-
# @param anchor_name [String] Anchor's name to be used in the manage_data key.
|
261
|
-
# @param timeout [Integer] Challenge duration (default to 5 minutes).
|
262
|
-
#
|
263
|
-
# @return [String] A base64 encoded string of the raw TransactionEnvelope xdr struct for the transaction.
|
264
|
-
def build_challenge_tx(server:, client:, anchor_name:, timeout: 300)
|
265
|
-
Stellar::SEP10.build_challenge_tx(
|
266
|
-
server: server, client: client, anchor_name: anchor_name, timeout: timeout
|
267
|
-
)
|
268
|
-
end
|
269
|
-
|
270
|
-
# DEPRECATED: this function has been moved to Stellar::SEP10::read_challenge_tx and
|
271
|
-
# will be removed in the next major version release.
|
272
|
-
#
|
273
|
-
# A wrapper function for Stellar::SEP10.verify_challenge_transaction
|
274
|
-
#
|
275
|
-
# @param challenge [String] SEP0010 transaction challenge in base64.
|
276
|
-
# @param server [Stellar::KeyPair] Stellar::KeyPair for server where the challenge was generated.
|
277
|
-
#
|
278
|
-
# @return [Boolean]
|
279
|
-
def verify_challenge_tx(challenge:, server:)
|
280
|
-
Stellar::SEP10.verify_challenge_tx(challenge_xdr: challenge, server: server)
|
281
|
-
true
|
282
|
-
end
|
283
|
-
|
284
|
-
# DEPRECATED: this function has been moved to Stellar::SEP10::verify_tx_signed_by and
|
285
|
-
# will be removed in the next major version release.
|
286
|
-
#
|
287
|
-
# @param transaction_envelope [Stellar::TransactionEnvelope]
|
288
|
-
# @param keypair [Stellar::KeyPair]
|
289
|
-
#
|
290
|
-
# @return [Boolean]
|
291
|
-
#
|
292
|
-
def verify_tx_signed_by(transaction_envelope:, keypair:)
|
293
|
-
Stellar::SEP10.verify_tx_signed_by(
|
294
|
-
tx_envelope: transaction_envelope, keypair: keypair
|
295
|
-
)
|
296
|
-
end
|
297
|
-
end
|
298
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
module Stellar
|
2
|
-
module Horizon
|
3
|
-
class Problem
|
4
|
-
def initialize(attributes)
|
5
|
-
@attributes = attributes.reverse_merge({
|
6
|
-
type: "about:blank",
|
7
|
-
title: "Unknown Error",
|
8
|
-
status: 500
|
9
|
-
})
|
10
|
-
|
11
|
-
@meta = @attributes.except!(:type, :title, :status, :detail, :instance)
|
12
|
-
end
|
13
|
-
|
14
|
-
# @return [String]
|
15
|
-
def type
|
16
|
-
@attributes[:type]
|
17
|
-
end
|
18
|
-
|
19
|
-
# @return [String]
|
20
|
-
def title
|
21
|
-
@attributes[:title]
|
22
|
-
end
|
23
|
-
|
24
|
-
# @return [Integer]
|
25
|
-
def status
|
26
|
-
@attributes[:status]
|
27
|
-
end
|
28
|
-
|
29
|
-
# @return [String]
|
30
|
-
def detail
|
31
|
-
@attributes[:detail]
|
32
|
-
end
|
33
|
-
|
34
|
-
# @return [String]
|
35
|
-
def instance
|
36
|
-
@attributes[:instance]
|
37
|
-
end
|
38
|
-
|
39
|
-
# @return [{String => Object}]
|
40
|
-
def meta
|
41
|
-
@attributes[:instance]
|
42
|
-
end
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|
data/lib/stellar/sdk/version.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module Stellar
|
2
|
-
class TransactionPage
|
3
|
-
include Enumerable
|
4
|
-
|
5
|
-
# @param [Hyperclient::Link] resource
|
6
|
-
def initialize(resource)
|
7
|
-
@resource = resource
|
8
|
-
end
|
9
|
-
|
10
|
-
def each
|
11
|
-
@resource.records.each do |tx|
|
12
|
-
yield tx if block_given?
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
# @return [Stellar::TransactionPage]
|
17
|
-
def next_page
|
18
|
-
self.class.new(@resource.next)
|
19
|
-
end
|
20
|
-
|
21
|
-
def next_page!
|
22
|
-
@resource = @resource.next
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|