Class: X402::Payments::Solana::Generator

Inherits:
Object
  • Object
show all
Defined in:
lib/x402/payments/solana/generator.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(config = X402::Payments.configuration) ⇒ Generator

Returns a new instance of Generator.



14
15
16
# File 'lib/x402/payments/solana/generator.rb', line 14

def initialize(config = X402::Payments.configuration)
  @config = config
end

Instance Attribute Details

#configObject (readonly)

Returns the value of attribute config.



12
13
14
# File 'lib/x402/payments/solana/generator.rb', line 12

def config
  @config
end

Instance Method Details

#generate_header(amount:, resource:, description: nil, network: nil, private_key: nil, pay_to: nil, version: nil, fee_payer: nil) ⇒ Object

Raises:



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/x402/payments/solana/generator.rb', line 18

def generate_header(amount:, resource:, description: nil, network: nil, private_key: nil, pay_to: nil, version: nil, fee_payer: nil)
  chain_name = network || config.chain
  raise ConfigurationError, "Solana chain required" unless X402::Payments.solana_chain?(chain_name)

  key = private_key || ENV["X402_SOL_PRIVATE_KEY"] || config.private_key
  raise ConfigurationError, "Solana private key is required (X402_SOL_PRIVATE_KEY)" if key.nil? || key.empty?

  recipient = pay_to || ENV["X402_SOL_PAY_TO"] || config.default_pay_to
  raise ConfigurationError, "Recipient address is required (X402_SOL_PAY_TO)" if recipient.nil? || recipient.empty?

  facilitator_fee_payer = fee_payer || X402::Payments.fee_payer_for(chain_name)
  raise ConfigurationError, "Facilitator fee payer is required for Solana" if facilitator_fee_payer.nil? || facilitator_fee_payer.empty?

  protocol_version = X402::Payments.normalize_version(version) || config.protocol_version
  token_config = X402::Payments.token_config_for(chain_name)
  mint_address = X402::Payments.asset_address_for(chain_name)
  decimals = token_config[:decimals]

  atomic_amount = convert_to_atomic(amount, decimals)

  keypair = load_keypair(key)
  sender_pubkey = keypair[:public_key]

  rpc_url = X402::Payments.rpc_url_for(chain_name)
  client = SolanaRuby::HttpClient.new(rpc_url)

  recent_blockhash = client.get_latest_blockhash["blockhash"]

  source_ata = derive_associated_token_address(mint_address, sender_pubkey)
  destination_ata = derive_associated_token_address(mint_address, recipient)

  serialized_tx = build_transfer_transaction(
    source_ata: source_ata,
    destination_ata: destination_ata,
    mint_address: mint_address,
    owner: sender_pubkey,
    amount: atomic_amount,
    decimals: decimals,
    recent_blockhash: recent_blockhash,
    keypair: keypair,
    fee_payer: facilitator_fee_payer
  )

  payload = build_payload(
    version: protocol_version,
    chain_name: chain_name,
    serialized_transaction: serialized_tx,
    resource: resource,
    description: description,
    mint_address: mint_address,
    recipient: recipient,
    atomic_amount: atomic_amount,
    fee_payer: facilitator_fee_payer
  )

  encode_payment(payload)
end