Class: X402::RequirementGenerator

Inherits:
Object
  • Object
show all
Defined in:
lib/x402/requirement_generator.rb

Class Method Summary collapse

Class Method Details

.build_extra_data(chain_name, token_config, fee_payer_override) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
# File 'lib/x402/requirement_generator.rb', line 86

def self.build_extra_data(chain_name, token_config, fee_payer_override)
  if X402.solana_chain?(chain_name)
    fee_payer = fee_payer_override || X402.fee_payer_for(chain_name)
    { feePayer: fee_payer }
  else
    {
      name: token_config[:name],
      version: token_config[:version]
    }
  end
end

.build_formatted_requirement(amount:, resource:, description:, chain:, currency:, wallet_address:, fee_payer:, version_strategy:) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/x402/requirement_generator.rb', line 41

def self.build_formatted_requirement(amount:, resource:, description:, chain:, currency:,
                                     wallet_address:, fee_payer:, version_strategy:)
  token_config = X402.token_config_for(chain, currency)
  asset_address = X402.asset_address_for(chain, currency)
  atomic_amount = convert_to_atomic(amount, token_config[:decimals])
  extra_data = build_extra_data(chain, token_config, fee_payer)

  internal_requirement = {
    scheme: "exact",
    network: chain,
    amount: atomic_amount,
    asset: asset_address,
    pay_to: wallet_address,
    resource: resource,
    description: description || "Payment required for #{resource}",
    max_timeout_seconds: 600,
    mime_type: "application/json",
    extra: extra_data
  }

  version_strategy.format_requirement(internal_requirement)
end

.convert_to_atomic(amount, decimals) ⇒ Object



82
83
84
# File 'lib/x402/requirement_generator.rb', line 82

def self.convert_to_atomic(amount, decimals)
  (amount.to_f * (10**decimals)).to_i
end

.generate(amount:, resource:, description: nil, chain: nil, currency: nil, wallet_address: nil, fee_payer: nil, version: nil, accepts: nil) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/x402/requirement_generator.rb', line 5

def self.generate(amount:, resource:, description: nil, chain: nil, currency: nil,
                  wallet_address: nil, fee_payer: nil, version: nil, accepts: nil)
  config = X402.configuration
  protocol_version = version || config.version
  version_strategy = X402::Versions.for(protocol_version)

  accepted_payments = resolve_accepted_payments(
    accepts: accepts,
    chain: chain,
    currency: currency
  )

  formatted_accepts = accepted_payments.map do |payment|
    build_formatted_requirement(
      amount: amount,
      resource: resource,
      description: description,
      chain: payment[:chain],
      currency: payment[:currency],
      wallet_address: wallet_address || payment[:wallet_address] || config.wallet_address,
      fee_payer: fee_payer,
      version_strategy: version_strategy
    )
  end

  version_strategy.format_requirement_response(
    accepts: formatted_accepts,
    resource: {
      url: resource,
      description: description || "Payment required for #{resource}",
      mime_type: "application/json"
    },
    error: "Payment required to access this resource"
  )
end

.resolve_accepted_payments(accepts:, chain:, currency:) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/x402/requirement_generator.rb', line 64

def self.resolve_accepted_payments(accepts:, chain:, currency:)
  config = X402.configuration

  if accepts && !accepts.empty?
    accepts.map do |acc|
      {
        chain: acc[:chain],
        currency: acc[:currency] || "USDC",
        wallet_address: acc[:wallet_address]
      }
    end
  elsif chain
    [{ chain: chain, currency: currency || config.currency, wallet_address: nil }]
  else
    config.effective_accepted_payments
  end
end