openreceive-server 0.2.1

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.
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "openreceive"
4
+
5
+ module OpenReceive
6
+ module Server
7
+ # NIP-47 wallet service info normalization (the kind 13194 info payload),
8
+ # ported from the JS summarizeWalletCapabilities and locked to the shared
9
+ # spec/test-vectors/nwc-info.json vectors: method-name normalization,
10
+ # encryption-mode choice, spend-capability detection, and receive
11
+ # readiness must be identical in both engines.
12
+ module WalletInfo
13
+ REQUIRED_RECEIVE_METHODS = %w[make_invoice list_transactions].freeze
14
+ SPEND_METHODS = %w[pay_invoice multi_pay_invoice pay_keysend multi_pay_keysend].freeze
15
+
16
+ module_function
17
+
18
+ def summarize(raw_info)
19
+ unwrapped = OpenReceive::Nwc.unwrap(raw_info)
20
+ info = OpenReceive.stringify(unwrapped)
21
+ raw_methods = %w[methods capabilities supported_methods supportedMethods]
22
+ .map { |key| info[key] }
23
+ .find { |value| !value.nil? }
24
+ raw_methods = unwrapped if raw_methods.nil? && unwrapped.is_a?(String)
25
+ methods = string_list(raw_methods).map { |name| normalize_method_name(name) }
26
+ encryption = choose_encryption_mode(
27
+ string_list(info["encryption"].nil? ? info["encryptions"] : info["encryption"])
28
+ )
29
+ spend_methods = methods.select { |name| SPEND_METHODS.include?(name) }
30
+ missing_methods = REQUIRED_RECEIVE_METHODS.reject { |name| methods.include?(name) }
31
+ {
32
+ "methods" => methods,
33
+ "encryption" => encryption,
34
+ "spend_capability_advertised" => !spend_methods.empty?,
35
+ "receive_checkout_ready" => missing_methods.empty?,
36
+ "warnings" => spend_methods.map do |name|
37
+ "Wallet advertises spend method '#{name}'; OpenReceive checkout will not expose it."
38
+ end
39
+ }
40
+ end
41
+
42
+ def choose_encryption_mode(encryption_modes)
43
+ normalized = encryption_modes.map { |mode| mode.downcase.gsub(/[- ]/, "_") }
44
+ if (normalized & %w[nip44_v2 nip44 nip_44]).any?
45
+ "nip44_v2"
46
+ elsif normalized.empty? || normalized.include?("nip04") || normalized.include?("nip_04")
47
+ # No advertised list at all: assume the NIP-47 baseline (NIP-04).
48
+ "nip04"
49
+ end
50
+ # An advertised list containing no mode we speak returns nil so
51
+ # preflight can fail loudly instead of failing cryptically at RPC time.
52
+ end
53
+
54
+ def string_list(value)
55
+ if value.is_a?(Array)
56
+ value.select { |item| item.is_a?(String) }.map(&:strip).reject(&:empty?)
57
+ elsif value.is_a?(String)
58
+ value.split(/[,\s]+/).map(&:strip).reject(&:empty?)
59
+ else
60
+ []
61
+ end
62
+ end
63
+
64
+ def normalize_method_name(value)
65
+ value.strip.gsub(/([a-z0-9])([A-Z])/, '\1_\2').gsub(/[-\s]+/, "_").downcase
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ # OpenReceive::Server — storage-agnostic receive checkout service,
4
+ # config loader, and framework-agnostic HTTP (Rack) routes.
5
+ #
6
+ # This gem builds on the dependency-free core gem (`openreceive`) and reuses its exact-money,
7
+ # settlement, NWC normalization, error, and receive-client primitives.
8
+ #
9
+ # Receive-only invariant: nothing here ever exposes a spend method, and the NWC connection
10
+ # secret never leaves the server (never logged, never serialized to a wire payload).
11
+
12
+ require "openreceive"
13
+
14
+ module OpenReceive
15
+ module Server
16
+ # Generation of the openreceive_payments / openreceive_meta schema this gem
17
+ # writes and reads. Mirrors the JS OPENRECEIVE_PAYMENTS_SCHEMA_VERSION; both
18
+ # engines share one host database, so they must agree.
19
+ PAYMENTS_SCHEMA_VERSION = 1
20
+
21
+ # Oldest-first page size for one reconciliation pass. Mirrors the JS
22
+ # OPENRECEIVE_RECONCILE_BATCH_SIZE: a backlog of pending attempts is
23
+ # drained over several passes instead of loading every row (and scanning
24
+ # every invoice's window) in one unbounded query.
25
+ RECONCILE_BATCH_SIZE = 200
26
+ end
27
+ end
28
+
29
+ require "openreceive/server/version"
30
+ require "openreceive/server/errors"
31
+ require "openreceive/server/client_ip"
32
+ require "openreceive/server/wallet_info"
33
+ require "openreceive/server/lsc_uri"
34
+ require "openreceive/server/swap"
35
+ require "openreceive/server/service"
36
+ require "openreceive/server/reconciliation"
37
+ require "openreceive/server/config"
38
+ require "openreceive/server/request_handler"
39
+ require "openreceive/server/rack_app"
metadata ADDED
@@ -0,0 +1,83 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: openreceive-server
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - OpenReceive
8
+ bindir: bin
9
+ cert_chain: []
10
+ date: 1980-01-02 00:00:00.000000000 Z
11
+ dependencies:
12
+ - !ruby/object:Gem::Dependency
13
+ name: openreceive
14
+ requirement: !ruby/object:Gem::Requirement
15
+ requirements:
16
+ - - '='
17
+ - !ruby/object:Gem::Version
18
+ version: 0.2.1
19
+ type: :runtime
20
+ prerelease: false
21
+ version_requirements: !ruby/object:Gem::Requirement
22
+ requirements:
23
+ - - '='
24
+ - !ruby/object:Gem::Version
25
+ version: 0.2.1
26
+ description: 'Server building blocks for OpenReceive: a storage-free Service that
27
+ mirrors the Node engine and a framework-agnostic Rack app implementing the shipped
28
+ HTTP routes while the host owns order and payment persistence. Receive-only: it
29
+ never exposes a spend path and the NWC secret never leaves the server.'
30
+ email:
31
+ - info@openreceive.org
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - CHANGELOG.md
37
+ - LICENSE
38
+ - README.md
39
+ - lib/openreceive/server.rb
40
+ - lib/openreceive/server/client_ip.rb
41
+ - lib/openreceive/server/config.rb
42
+ - lib/openreceive/server/errors.rb
43
+ - lib/openreceive/server/lsc_uri.rb
44
+ - lib/openreceive/server/rack_app.rb
45
+ - lib/openreceive/server/reconciliation.rb
46
+ - lib/openreceive/server/request_handler.rb
47
+ - lib/openreceive/server/service.rb
48
+ - lib/openreceive/server/swap.rb
49
+ - lib/openreceive/server/swap/assets.rb
50
+ - lib/openreceive/server/swap/fixedfloat.rb
51
+ - lib/openreceive/server/swap/rates_feed.rb
52
+ - lib/openreceive/server/swap/transient_cache.rb
53
+ - lib/openreceive/server/swap/weight_budget.rb
54
+ - lib/openreceive/server/version.rb
55
+ - lib/openreceive/server/wallet_info.rb
56
+ homepage: https://openreceive.org
57
+ licenses:
58
+ - MIT
59
+ metadata:
60
+ homepage_uri: https://openreceive.org
61
+ source_code_uri: https://github.com/openreceive/openreceive
62
+ changelog_uri: https://github.com/openreceive/openreceive/blob/master/packages/ruby/openreceive-server/CHANGELOG.md
63
+ bug_tracker_uri: https://github.com/openreceive/openreceive/issues
64
+ documentation_uri: https://rubydoc.info/gems/openreceive-server
65
+ rubygems_mfa_required: 'true'
66
+ rdoc_options: []
67
+ require_paths:
68
+ - lib
69
+ required_ruby_version: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - ">="
72
+ - !ruby/object:Gem::Version
73
+ version: '3.2'
74
+ required_rubygems_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ requirements: []
80
+ rubygems_version: 3.6.8
81
+ specification_version: 4
82
+ summary: Storage-free OpenReceive receive-only service and HTTP routes for Ruby.
83
+ test_files: []