Class: Blockchain0xX402::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/blockchain0x_x402/client.rb

Constant Summary collapse

DEFAULT_CONFIRM_TIMEOUT_SECONDS =
30
DEFAULT_CONFIRM_POLL_SECONDS =
1.0

Instance Method Summary collapse

Constructor Details

#initialize(sdk:, agent_id:, confirm_timeout_seconds: DEFAULT_CONFIRM_TIMEOUT_SECONDS, confirm_poll_seconds: DEFAULT_CONFIRM_POLL_SECONDS, connection: nil, sleep_proc: nil) ⇒ Client

Returns a new instance of Client.

Parameters:

  • sdk (#network, #payments_create, #transactions_get)
  • agent_id (String)

    wallet that funds the on-chain payment

  • confirm_timeout_seconds (Integer) (defaults to: DEFAULT_CONFIRM_TIMEOUT_SECONDS)
  • confirm_poll_seconds (Float) (defaults to: DEFAULT_CONFIRM_POLL_SECONDS)
  • connection (Faraday::Connection, nil) (defaults to: nil)

    test seam

  • sleep_proc (#call, nil) (defaults to: nil)

    test seam for the poll loop



46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/blockchain0x_x402/client.rb', line 46

def initialize(
  sdk:,
  agent_id:,
  confirm_timeout_seconds: DEFAULT_CONFIRM_TIMEOUT_SECONDS,
  confirm_poll_seconds: DEFAULT_CONFIRM_POLL_SECONDS,
  connection: nil,
  sleep_proc: nil
)
  @sdk = sdk
  @agent_id = agent_id
  @confirm_timeout = confirm_timeout_seconds
  @confirm_poll = confirm_poll_seconds
  @conn = connection || Faraday.new
  @sleep = sleep_proc || Kernel.method(:sleep)
end

Instance Method Details

#request(method, url, body: nil, headers: {}) ⇒ Faraday::Response

Perform an HTTP request that handles 402 automatically.

Parameters:

  • method (Symbol)

    :get, :post, :patch, :delete

  • url (String)
  • body (Object, nil) (defaults to: nil)

    body the request adapter will encode

  • headers (Hash<String, String>) (defaults to: {})

Returns:

  • (Faraday::Response)

    the final response (after the retry on the 402 branch)

Raises:



68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/blockchain0x_x402/client.rb', line 68

def request(method, url, body: nil, headers: {})
  first = perform(method, url, body, headers)
  return first unless first.status == 402

  spec = Wire.parse_402_response(first)
  requirement = pick_requirement(spec.accepts)
  payment = @sdk.payments_create(
    agent_id: @agent_id,
    to: requirement.pay_to_address,
    amount_wei: requirement.amount_wei_usdc,
  )
  payment_id = payment.is_a?(Hash) ? (payment['id'] || payment[:id]) : payment.id
  raise ClientError.new('chain_failed', 'payments_create did not return an id.') if payment_id.nil?

  confirmed = wait_for_confirmation(payment_id)

  header = Wire.build_payment_header(
    Wire::ExactUsdcPayment.new(
      scheme: 'exact-usdc',
      version: 1,
      payment_request_id: requirement.payment_request_id,
      tx_hash: tx_field(confirmed, :tx_hash, 'txHash').to_s,
      payer_address: tx_field(confirmed, :from_address, 'fromAddress').to_s,
      amount_usdc: wei_to_usdc(requirement.amount_wei_usdc),
      network: requirement.network,
    ),
  )
  perform(method, url, body, headers.merge('X-Payment' => header))
end