cryptomus 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f60a4f81086d5b7e88b0fe308a09f62180cd353f373b48942ac13fd0bb474139
4
+ data.tar.gz: d965a52db2e10cbdce4f4ec5c6b54fd2f9f8e6a2d466847962adbc6bf2cbf013
5
+ SHA512:
6
+ metadata.gz: 97b863cb937d0c5da1c1592692df174809dcf513b8d1e1d2c24d9dc68242572974552cb067e5f7b36b56cef103f4bf9ca1c21761587e9ab1ca3d826996b33ec8
7
+ data.tar.gz: e971b602839afee23d5cafc9c5bd8deb32f7999d47f07492f70a4df9c52ea167953a86d3e04158ecd43b9ea8cf3b2fd29e45403a0b0e33174046fa8ba364bf71
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,113 @@
1
+ require:
2
+ - rubocop-performance
3
+ - rubocop-rake
4
+ - rubocop-rspec
5
+
6
+ AllCops:
7
+ TargetRubyVersion: 3.2
8
+ DisplayCopNames: true
9
+ NewCops: enable
10
+
11
+ Layout/LineLength:
12
+ Max: 120
13
+
14
+ Layout/DotPosition:
15
+ EnforcedStyle: leading
16
+
17
+ Layout/SpaceInsideArrayLiteralBrackets:
18
+ EnforcedStyle: no_space
19
+
20
+ Layout/MultilineArrayBraceLayout:
21
+ EnforcedStyle: new_line
22
+
23
+ Layout/MultilineHashBraceLayout:
24
+ EnforcedStyle: new_line
25
+
26
+ Layout/MultilineMethodCallBraceLayout:
27
+ EnforcedStyle: new_line
28
+
29
+ Layout/FirstArgumentIndentation:
30
+ EnforcedStyle: consistent
31
+
32
+ Lint/AmbiguousBlockAssociation:
33
+ Enabled: true
34
+ AllowedMethods: [ change, not_change ]
35
+
36
+ Metrics/BlockLength:
37
+ Max: 80
38
+ Exclude:
39
+ - "spec/**/*.rb"
40
+
41
+ Metrics/MethodLength:
42
+ Max: 40
43
+ Exclude:
44
+ - "spec/**/*.rb"
45
+
46
+ Metrics/ParameterLists:
47
+ Max: 3
48
+ CountKeywordArgs: false
49
+
50
+ Metrics/AbcSize:
51
+ Enabled: false
52
+
53
+ Metrics/BlockNesting:
54
+ Max: 5
55
+ Exclude:
56
+ - "spec/**/*.rb"
57
+
58
+ Metrics/ClassLength:
59
+ Enabled: false
60
+
61
+ Metrics/CyclomaticComplexity:
62
+ Enabled: false
63
+
64
+ Metrics/ModuleLength:
65
+ Enabled: false
66
+
67
+ Metrics/PerceivedComplexity:
68
+ Enabled: false
69
+
70
+ Style/Documentation:
71
+ Enabled: false
72
+
73
+ Style/SymbolArray:
74
+ EnforcedStyle: brackets
75
+
76
+ Style/WordArray:
77
+ EnforcedStyle: brackets
78
+
79
+ # All lambda will be like `->() {}`, `->() do end`.
80
+ Style/Lambda:
81
+ EnforcedStyle: literal
82
+
83
+ Style/ConditionalAssignment:
84
+ Enabled: false
85
+
86
+ Style/EmptyMethod:
87
+ EnforcedStyle: expanded
88
+
89
+ Style/SingleLineMethods:
90
+ AllowIfMethodIsEmpty: false
91
+
92
+ Style/FormatStringToken:
93
+ Enabled: false
94
+
95
+ Style/BlockDelimiters:
96
+ Enabled: true
97
+ BracesRequiredMethods: [ 'expect', 'change' ]
98
+
99
+ Style/GuardClause:
100
+ Enabled: false
101
+
102
+ # internal concerns must be written in compact style.
103
+ # classes in a namespace should be written in expanded style.
104
+ Style/ClassAndModuleChildren:
105
+ Enabled: false
106
+
107
+ Style/StringLiterals:
108
+ Enabled: true
109
+ EnforcedStyle: single_quotes
110
+
111
+ Style/StringLiteralsInInterpolation:
112
+ Enabled: true
113
+ EnforcedStyle: single_quotes
data/CHANGELOG.md ADDED
@@ -0,0 +1,5 @@
1
+ ## [Unreleased]
2
+
3
+ ## [0.1.0] - 2023-07-15
4
+
5
+ - Initial release
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023 Denis Talakevich
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,64 @@
1
+ # Cryptomus
2
+
3
+ Ruby SDK for Cryptomus Crypto Payment Gateway.
4
+ See the [documentation](https://doc.cryptomus.com)
5
+
6
+ ## Installation
7
+
8
+ Install the gem and add to the application's Gemfile by executing:
9
+
10
+ $ bundle add cryptomus
11
+
12
+ If bundler is not being used to manage dependencies, install the gem by executing:
13
+
14
+ $ gem install cryptomus
15
+
16
+ ## Usage
17
+
18
+ ```ruby
19
+ require 'cryptomus'
20
+
21
+ Cryptomus.configure do |config|
22
+ config.merchant_id = 'your_merchant_id'
23
+ config.api_key = 'your_api_key'
24
+ end
25
+
26
+ crypto_payment = Cryptomus::Client.create_payment(
27
+ order_id: 'your_unique_order_id_from_your_system',
28
+ amount: '100',
29
+ currency: 'USD',
30
+ lifetime: 24 * 60 * 60, # expires in 24 hours
31
+ subtract: 100 # client will pay 100% of commission
32
+ )
33
+
34
+ puts "Pay URL: #{crypto_payment[:result][:url]}"
35
+ ```
36
+
37
+ ```ruby
38
+ crypto_payment = Cryptomus::Client.payment(order_id: 'your_unique_order_id_from_your_system')
39
+ if !crypto_payment[:result][:is_final]
40
+ puts "Waiting for client to pay (status=#{crypto_payment[:result][:status]})"
41
+ elsif %w[paid paid_over].include?(crypto_payment[:result][:status])
42
+ puts "Payment completed (amount=#{crypto_payment[:result][:payer_amount]}, status=#{crypto_payment[:result][:status]})"
43
+ else
44
+ puts "Payment failed (status=#{crypto_payment[:result][:status]})"
45
+ end
46
+ ```
47
+
48
+ ## Development
49
+
50
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests.
51
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
52
+
53
+ To install this gem onto your local machine, run `bundle exec rake install`.
54
+ To release a new version, update the version number in `version.rb`,
55
+ and then run `bundle exec rake release`, which will create a git tag for the version,
56
+ push git commits and the created tag, and push the `.gem` file to [rubygems.org](https://rubygems.org).
57
+
58
+ ## Contributing
59
+
60
+ Bug reports and pull requests are welcome on GitHub at https://github.com/senid231/cryptomus.
61
+
62
+ ## License
63
+
64
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptomus
4
+ module Client
5
+ module_function
6
+
7
+ # https://doc.cryptomus.com/payments/creating-invoice
8
+ # @param attributes [Hash]
9
+ # @option attributes [String] :order_id required
10
+ # @option attributes [String] :currency required
11
+ # @option attributes [String] :amount required
12
+ # @return [Hash]
13
+ # @raise [Cryptomus::Errors::ApiError]
14
+ # @example
15
+ # Cryptomus::Client.create_invoice(
16
+ # order_id: '123',
17
+ # currency: 'USD',
18
+ # amount: '100'
19
+ # )
20
+ def create_payment(attributes)
21
+ connection.post('/v1/payment', body: attributes)
22
+ end
23
+
24
+ # https://doc.cryptomus.com/payments/payment-history
25
+ # @param cursor [String,nil] from previous response paginate.nextCursor or paginate.previousCursor
26
+ # @param date_from [String,nil] format: 'YYYY-MM-DD H:mm:ss'
27
+ # @param date_to [String,nil] format: 'YYYY-MM-DD H:mm:ss'
28
+ # @return [Hash]
29
+ # @raise [Cryptomus::Errors::ApiError]
30
+ def list_payments(cursor: nil, date_from: nil, date_to: nil)
31
+ attributes = { date_from:, date_to: }.compact
32
+ attributes = nil if attributes.empty?
33
+ query = { cursor: }.compact
34
+ query = nil if query.empty?
35
+ connection.post('/v1/payment/list', body: attributes, query:)
36
+ end
37
+
38
+ # https://doc.cryptomus.com/payments/payment-information
39
+ # @param uuid [String,nil] uuid or order_id must be passed.
40
+ # @param order_id [String,nil] uuid or order_id must be passed.
41
+ # @return [Hash]
42
+ # @raise [Cryptomus::Errors::ApiError]
43
+ def payment(uuid: nil, order_id: nil)
44
+ attributes = { uuid:, order_id: }.compact
45
+ connection.get('/v1/payment/info', body: attributes)
46
+ end
47
+
48
+ # https://doc.cryptomus.com/payments/creating-static
49
+ # @param attributes [Hash]
50
+ # @option attributes [String] :order_id required
51
+ # @option attributes [String] :currency required
52
+ # @option attributes [String] :network required
53
+ # @return [Hash]
54
+ # @raise [Cryptomus::Errors::ApiError]
55
+ # @example
56
+ # Cryptomus::Client.create_wallet(
57
+ # order_id: '123',
58
+ # currency: 'USDT',
59
+ # network: 'tron'
60
+ # )
61
+ def create_wallet(attributes)
62
+ connection.post('/v1/wallet', body: attributes)
63
+ end
64
+
65
+ # https://doc.cryptomus.com/balance
66
+ # @return [Hash]
67
+ # @raise [Cryptomus::Errors::ApiError]
68
+ # @example
69
+ # Cryptomus::Client.balance
70
+ def balance
71
+ connection.post('/v1/balance')
72
+ end
73
+
74
+ def connection
75
+ @connection ||= Connection.new
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptomus
4
+ class Configuration
5
+ attr_accessor :api_key,
6
+ :merchant_id,
7
+ :user_agent,
8
+ :connection_config,
9
+ :on_error,
10
+ :logger
11
+
12
+ def initialize
13
+ self.user_agent = "Cryptomus Ruby SDK #{Cryptomus::VERSION} (Ruby #{RUBY_VERSION})"
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'faraday'
4
+
5
+ module Cryptomus
6
+ class Connection
7
+ MIME_TYPE = 'application/json'
8
+
9
+ # @param path [String]
10
+ # @param body [Hash, nil]
11
+ # @raise [Cryptomus::Errors::ApiError]
12
+ def post(path, body: nil, query: nil)
13
+ response = connection.post do |req|
14
+ req.url(path, query)
15
+ raw_body = body&.to_json
16
+ req.body = raw_body
17
+ req[:sign] = Signature.generate(raw_body)
18
+ end
19
+ handle_response(response)
20
+ response.body
21
+ end
22
+
23
+ private
24
+
25
+ def connection
26
+ Faraday.new(connection_options) do |builder|
27
+ builder.adapter Faraday.default_adapter
28
+ builder.request :json
29
+ builder.response :json, parser_options: { symbolize_names: true }
30
+ builder.response :logger, Cryptomus.config.logger, bodies: true if Cryptomus.config.logger
31
+ Cryptomus.config.connection_config&.call(builder)
32
+ end
33
+ end
34
+
35
+ def handle_response(response)
36
+ return if response.success?
37
+ return if Cryptomus.config.handle_response&.call(response)
38
+
39
+ raise Cryptomus::Errors::ApiError, response
40
+ end
41
+
42
+ def connection_options
43
+ {
44
+ url: Cryptomus::CONST::URL,
45
+ headers: {
46
+ 'Content-Type' => MIME_TYPE,
47
+ merchant: Cryptomus.config.merchant_id,
48
+ user_agent: Cryptomus.config.user_agent
49
+ }
50
+ }
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptomus
4
+ module CONST
5
+ URL = 'https://api.cryptomus.com'
6
+ end
7
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptomus
4
+ module Errors
5
+ class Error < StandardError
6
+ end
7
+
8
+ class ApiError < Error
9
+ # @!method response [Faraday::Response,nil]
10
+ # @!method status [Integer,nil]
11
+ # @!method response_body [Hash,nil]
12
+ attr_reader :response, :status, :response_body
13
+
14
+ # @param msg [String]
15
+ # @param response [Faraday::Response,nil]
16
+ def initialize(msg, response = nil)
17
+ @response = response
18
+ @status = response&.status
19
+ @response_body = response&.body
20
+ super(msg)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'base64'
4
+ require 'digest'
5
+
6
+ module Cryptomus
7
+ module Signature
8
+ module_function
9
+
10
+ # https://doc.cryptomus.com/getting-started/request-format
11
+ # @param raw_body [String]
12
+ # @return [String]
13
+ def generate(raw_body)
14
+ raw_body_encoded = Base64.encode64(raw_body || '')
15
+ Digest::MD5.hexdigest("#{raw_body_encoded}#{Cryptomus.config.api_key}")
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Cryptomus
4
+ VERSION = '0.1.0'
5
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+
5
+ module Cryptomus
6
+ module WebhookValidator
7
+ module_function
8
+
9
+ # https://doc.cryptomus.com/payments/webhook
10
+ # @param payload [Hash]
11
+ # @param sign [String]
12
+ # @return [Boolean]
13
+ def validate(payload:, sign:)
14
+ payload_json = JSON.generate(payload)
15
+ generated_sign = Cryptomus::Signature.generate(payload_json)
16
+ generated_sign == sign
17
+ end
18
+ end
19
+ end
data/lib/cryptomus.rb ADDED
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'cryptomus/version'
4
+ require_relative 'cryptomus/const'
5
+ require_relative 'cryptomus/errors'
6
+ require_relative 'cryptomus/configuration'
7
+ require_relative 'cryptomus/signature'
8
+ require_relative 'cryptomus/webhook_validator'
9
+ require_relative 'cryptomus/connection'
10
+ require_relative 'cryptomus/client'
11
+
12
+ # Cryptomus Crypto Payment Gateway
13
+ # [https://doc.cryptomus.com]
14
+ module Cryptomus
15
+ module_function
16
+
17
+ def configure
18
+ yield config
19
+ end
20
+
21
+ def config
22
+ @config ||= Configuration.new
23
+ end
24
+ end
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cryptomus
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Denis Talakevich
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2023-07-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: faraday
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.7'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.7'
27
+ description: Ruby SDK for Cryptomus Crypto Payment Gateway.
28
+ email:
29
+ - senid231@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - ".rspec"
35
+ - ".rubocop.yml"
36
+ - CHANGELOG.md
37
+ - LICENSE.txt
38
+ - README.md
39
+ - lib/cryptomus.rb
40
+ - lib/cryptomus/client.rb
41
+ - lib/cryptomus/configuration.rb
42
+ - lib/cryptomus/connection.rb
43
+ - lib/cryptomus/const.rb
44
+ - lib/cryptomus/errors.rb
45
+ - lib/cryptomus/signature.rb
46
+ - lib/cryptomus/version.rb
47
+ - lib/cryptomus/webhook_validator.rb
48
+ homepage: https://github.com/senid231/cryptomus-ruby-sdk
49
+ licenses:
50
+ - MIT
51
+ metadata:
52
+ homepage_uri: https://github.com/senid231/cryptomus-ruby-sdk
53
+ source_code_uri: https://github.com/senid231/cryptomus-ruby-sdk
54
+ changelog_uri: https://github.com/senid231/cryptomus-ruby-sdk/blob/master/CHANGELOG.md
55
+ rubygems_mfa_required: 'true'
56
+ post_install_message:
57
+ rdoc_options: []
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 3.2.0
65
+ required_rubygems_version: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ requirements: []
71
+ rubygems_version: 3.4.12
72
+ signing_key:
73
+ specification_version: 4
74
+ summary: Ruby SDK for Cryptomus Crypto Payment Gateway.
75
+ test_files: []