client

Client for interacting with the Fewsats API

The Fewsats class handles authentication and provides the foundation for our API interactions.


source

Fewsats

 Fewsats (api_key:str=None,
          base_url:str='https://hub-5n97k.ondigitalocean.app')

Client for interacting with the Fewsats API

Type Default Details
api_key str None The API key for the Fewsats account
base_url str https://hub-5n97k.ondigitalocean.app The Fewsats API base URL
k = os.getenv("FEWSATS_API_KEY")
fs = Fewsats(api_key=k)
# k = os.getenv("FEWSATS_LOCAL_API_KEY")
# fs = Fewsats(api_key=k, base_url="http://localhost:8000")

test_eq(fs.api_key, k)
test_eq(fs._httpx_client.headers["Authorization"], f"Token {k}")

Methods

r  = fs._request("GET", "v0/users/me")
test_eq(r.status_code, 200)

Let’s use a helper function to process the response.

# #| export
# def _process_response(r):
#     try:
#         r.raise_for_status()
#         return r.json()
#     except (json.JSONDecodeError, HTTPError) as e:
#         if isinstance(e, json.JSONDecodeError):
#             error = str(e)
#         else:
#             reason = e.reason
#             details = e.details  # Includes additional info like headers
#             error = f"{reason}: {details}"
#         raise Exception(f"Status: {e.status_code}, Error: {error}")
#     except Exception as e:
#         raise Exception(str(e))

User Info


source

Fewsats.me

 Fewsats.me ()

Retrieve the user’s info.

r = fs.me()
r.status_code, r.json()
(200,
 {'name': 'Fewsats',
  'last_name': 'Tester',
  'email': 'test@fewsats.com',
  'billing_info': None,
  'id': 15,
  'created_at': '2024-12-18T18:19:00.531Z',
  'webhook_url': 'https://api.fewsats.com'})

Balance


source

Fewsats.balance

 Fewsats.balance ()

Retrieve the balance of the user’s wallet.

r = fs.balance()
r.status_code, r.json()
(200, [{'id': 15, 'balance': 2374, 'currency': 'usd'}])

Payment Methods

Retrieve the user’s payment methods. Useful for checking which card will be used for purchases.


source

Fewsats.payment_methods

 Fewsats.payment_methods ()

Retrieve the user’s payment methods, raises an exception for error status codes.

r = fs.payment_methods()
payment_methods = r.json()
r.status_code, payment_methods
(200,
 [{'id': 5,
   'last4': '4242',
   'brand': 'Visa',
   'exp_month': 12,
   'exp_year': 2034,
   'is_default': True}])
assert isinstance(payment_methods, list)

Preview a Purchase

Preview the resulting state of a purchase. Useful, for example, to check if a CC charge is needed or the purchase will use the balance.

r = fs._preview_payment(amount="300") # 3.00 USD
preview = r.json()
r.status_code = preview

Create offers

How to use the client to generate L402 offers


source

Fewsats.create_offers

 Fewsats.create_offers (offers:List[Dict[str,Any]])

Create offers for L402 payment server

Type Details
offers List List of offer objects following OfferCreateV0 schema
Returns dict
test_offers = [{
    "offer_id": "test_offer_2",
    "amount": 1,
    "currency": "USD",
    "description": "Test offer",
    "title": "Test Package",
    "tye": "top-up",
    "payment_methods": ["lightning", "credit_card"]
}]

r = fs.create_offers(test_offers)
l402_offers = r.json()
r.status_code, l402_offers
(200,
 {'offers': [{'offer_id': 'test_offer_2',
    'amount': 1,
    'currency': 'USD',
    'description': 'Test offer',
    'title': 'Test Package',
    'payment_methods': ['lightning', 'credit_card'],
    'type': 'one-off'}],
  'payment_context_token': '8a49b581-ab9e-4469-979c-187261303b7a',
  'payment_request_url': 'https://api.fewsats.com/v0/l402/payment-request',
  'version': '0.2.2'})

Get Payment Details


source

Fewsats.get_payment_details

 Fewsats.get_payment_details (payment_request_url:str, offer_id:str,
                              payment_method:str,
                              payment_context_token:str)
r = fs.get_payment_details(l402_offers["payment_request_url"], l402_offers["offers"][0]["offer_id"], "lightning", l402_offers["payment_context_token"])
payment_details = r.json()
ln_invoice = payment_details["payment_request"]['lightning_invoice']
r.status_code, payment_details
(200,
 {'expires_at': '2025-02-10T14:53:01.452963+00:00',
  'offer_id': 'test_offer_2',
  'payment_request': {'lightning_invoice': 'lnbc100n1pn65z5mpp5jxd6gk0536wxdx3trktg7kxk6egxx58qrj2xkrpkvs4j3msljx2sdq523jhxapq2pskx6mpvajscqzpgxqrzpjrzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5ymum4ydvhkxuusxa607cjlgrufxs7w7yqltj4228nh78g6s5xlps9qxpqysgq9ugkyrjzusq0cj6zs8dtq77r4h0kxjau6fc35gyydmt2a02hnvaz4zmnjgaplgnj3dc5pjvf8qcg3j3dkq4d62crgy9hqqz9t7v0ndqquj387a'},
  'version': '0.2.2'})

Get Payment Status


source

Fewsats.get_payment_status

 Fewsats.get_payment_status (payment_context_token:str)
r = fs.get_payment_status(l402_offers["payment_context_token"])
r.status_code, r.json()
(200,
 {'payment_context_token': '8a49b581-ab9e-4469-979c-187261303b7a',
  'status': 'pending',
  'offer_id': None,
  'paid_at': None,
  'amount': None,
  'currency': None})

source

Fewsats.set_webhook

 Fewsats.set_webhook (webhook_url:str)
r = fs.set_webhook("https://example.com")
r, r.json()
(<Response [200 OK]>,
 {'name': 'Fewsats',
  'last_name': 'Tester',
  'email': 'test@fewsats.com',
  'billing_info': None,
  'id': 15,
  'created_at': '2024-12-18T18:19:00.531Z',
  'webhook_url': 'https://example.com'})

Pay Lightning Invoice


source

Fewsats.pay_lightning

 Fewsats.pay_lightning (invoice:str, amount:int, currency:str='USD',
                        description:str='')

Pay for a lightning invoice

Type Default Details
invoice str lightning invoice
amount int amount in cents
currency str USD currency
description str description of the payment
r = fs.pay_lightning(invoice=ln_invoice,
                     description="fewsats webhook trial", amount=1)
lightning_payment = r.json()
r.status_code, lightning_payment
(200,
 {'id': 300,
  'created_at': '2025-02-10T14:18:20.217Z',
  'status': 'success',
  'payment_request_url': '',
  'payment_context_token': '',
  'invoice': 'lnbc100n1pn65z5mpp5jxd6gk0536wxdx3trktg7kxk6egxx58qrj2xkrpkvs4j3msljx2sdq523jhxapq2pskx6mpvajscqzpgxqrzpjrzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5ymum4ydvhkxuusxa607cjlgrufxs7w7yqltj4228nh78g6s5xlps9qxpqysgq9ugkyrjzusq0cj6zs8dtq77r4h0kxjau6fc35gyydmt2a02hnvaz4zmnjgaplgnj3dc5pjvf8qcg3j3dkq4d62crgy9hqqz9t7v0ndqquj387a',
  'preimage': '4e17a5ec0606daf55afd55f81b9fb0bc963eb53182b1b56ce73e6e3535c1c63b',
  'amount': 1,
  'currency': 'usd',
  'payment_method': 'lightning',
  'title': '',
  'description': 'fewsats webhook trial',
  'type': ''})
fs.get_payment_status(l402_offers["payment_context_token"]).json()
{'payment_context_token': '8a49b581-ab9e-4469-979c-187261303b7a',
 'status': 'success',
 'offer_id': 'test_offer_2',
 'paid_at': '2025-02-10T14:18:24.596788+00:00',
 'amount': 1,
 'currency': 'USD'}

Pay

The pay method pays for a specific offer. The user is not required to fetch the payment details beforehand. It is asynchronous and returns the payment_id and status. Using the payment_id we can check the status of the payment.


source

Fewsats.pay_offer

 Fewsats.pay_offer (l402_offer:Dict, payment_method:str='')

*Pays an L402 response. Fewsats will choose payment method if left blank. If multiple offers are passed, the first one will be chosen.

This method is not recommended for LLMs as they struggle with complex types like Dicts during function calling. This method should be used by a higher-level abstraction SDK that is in turn exposed to the LLM, for example, with the as_tools() paradigm.

Returns payment status response*

Type Default Details
l402_offer Dict a dictionary containing the response of an L402 endpoint
payment_method str preferred payment method (optional)
Returns dict payment status response
r = fs.pay_offer(l402_offers)
payment_response = r.json() if r.is_success else r.text
r.status_code, payment_response
(400,
 '{"detail": "Invalid payment request received. Could not get payment details. Traceback (most recent call last):\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/connection.py\\", line 198, in _new_conn\\n    sock = connection.create_connection(\\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/util/connection.py\\", line 60, in create_connection\\n    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):\\n               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/socket.py\\", line 976, in getaddrinfo\\n    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):\\n               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\nsocket.gaierror: [Errno -2] Name or service not known\\n\\nThe above exception was the direct cause of the following exception:\\n\\nTraceback (most recent call last):\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py\\", line 787, in urlopen\\n    response = self._make_request(\\n               ^^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py\\", line 488, in _make_request\\n    raise new_e\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py\\", line 464, in _make_request\\n    self._validate_conn(conn)\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py\\", line 1093, in _validate_conn\\n    conn.connect()\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/connection.py\\", line 704, in connect\\n    self.sock = sock = self._new_conn()\\n                       ^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/connection.py\\", line 205, in _new_conn\\n    raise NameResolutionError(self.host, self, e) from e\\nurllib3.exceptions.NameResolutionError: <urllib3.connection.HTTPSConnection object>: Failed to resolve \'api.lightspark.com\' ([Errno -2] Name or service not known)\\n\\nThe above exception was the direct cause of the following exception:\\n\\nTraceback (most recent call last):\\n  File \\"/usr/local/lib/python3.12/site-packages/requests/adapters.py\\", line 667, in send\\n    resp = conn.urlopen(\\n           ^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/connectionpool.py\\", line 841, in urlopen\\n    retries = retries.increment(\\n              ^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/urllib3/util/retry.py\\", line 519, in increment\\n    raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]\\n    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\nurllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host=\'api.lightspark.com\', port=443): Max retries exceeded with url: /graphql/server/2023-09-13 (Caused by NameResolutionError(\\"<urllib3.connection.HTTPSConnection object>: Failed to resolve \'api.lightspark.com\' ([Errno -2] Name or service not known)\\"))\\n\\nDuring handling of the above exception, another exception occurred:\\n\\nTraceback (most recent call last):\\n  File \\"/usr/local/lib/python3.12/site-packages/ninja/operation.py\\", line 341, in run\\n    result = await self.view_func(request, **values)\\n             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/opt/hub_api/l402/api/common/decorators.py\\", line 17, in wrapper\\n    return await func(request, *args, **kwargs)\\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/opt/hub_api/l402/api/v0/views.py\\", line 127, in create_payment_request_v0\\n    return await create_payment_request(\\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/opt/hub_api/l402/server.py\\", line 68, in create_payment_request\\n    provider = LightningProvider()\\n               ^^^^^^^^^^^^^^^^^^^\\n  File \\"/opt/hub_api/l402/providers/lightning.py\\", line 22, in __init__\\n    self.client = LightsparkAPI()\\n                  ^^^^^^^^^^^^^^^\\n  File \\"/opt/hub_api/l402/utils/lightspark_api.py\\", line 38, in __init__\\n    signing_key = self.client.recover_node_signing_key(self.node_id, self.node_password)\\n                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/lightspark/lightspark_client.py\\", line 502, in recover_node_signing_key\\n    json = self._requester.execute_graphql(\\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/lightspark/requests/requester.py\\", line 96, in execute_graphql\\n    r = self.graphql_session.post(\\n        ^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/requests/sessions.py\\", line 637, in post\\n    return self.request(\\"POST\\", url, data=data, json=json, **kwargs)\\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/requests/sessions.py\\", line 589, in request\\n    resp = self.send(prep, **send_kwargs)\\n           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/requests/sessions.py\\", line 703, in send\\n    r = adapter.send(request, **kwargs)\\n        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^\\n  File \\"/usr/local/lib/python3.12/site-packages/requests/adapters.py\\", line 700, in send\\n    raise ConnectionError(e, request=request)\\nrequests.exceptions.ConnectionError: HTTPSConnectionPool(host=\'api.lightspark.com\', port=443): Max retries exceeded with url: /graphql/server/2023-09-13 (Caused by NameResolutionError(\\"<urllib3.connection.HTTPSConnection object>: Failed to resolve \'api.lightspark.com\' ([Errno -2] Name or service not known)\\"))\\n"}')

After the stripe payment settles, the status will be updated to success.

Payment Info

We can check the status of a payment as follows:


source

Fewsats.payment_info

 Fewsats.payment_info (pid:str)

Retrieve the details of a payment.

Type Details
pid str purchase id
fs.payment_info('2')
<Response [404 Not Found]>

Wait for settlement

For convenience we can use the method wait_for_settlement to wait for the payment to settle.


source

Fewsats.wait_for_settlement

 Fewsats.wait_for_settlement (pid:str, max_interval:int=120,
                              max_wait:int=600)

Wait for payment settlement with exponential backoff

Type Default Details
pid str purchase id
max_interval int 120 maximum interval between checks in seconds
max_wait int 600 maximum total wait time in seconds
try:
    r = fs.wait_for_settlement('223') # test payment already settled
except Exception as e:
    print(e)
Client error '404 Not Found' for url 'http://localhost:8000/v0/l402/purchases/223'
For more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404

As tools


source

Fewsats.as_tools

 Fewsats.as_tools ()

Return list of available tools for AI agents

fs.as_tools()
[<bound method Client.me of <__main__.Client object>>,
 <bound method Client.balance of <__main__.Client object>>,
 <bound method Client.payment_methods of <__main__.Client object>>,
 <bound method Client.pay of <__main__.Client object>>,
 <bound method Client.payment_info of <__main__.Client object>>]

Both the preview and purchase methods automatically use the default payment method if a charge is needed. This client provides a straightforward way to interact with the Fewsats API, making it easy for developers to integrate Fewsats functionality into their applications.

Agent Demo

We will use Claudette to demonstrate how to pay for content using the Fewsats API.

from claudette import Chat, models
model = models[1]
model
'claude-3-5-sonnet-20240620'
fs.balance()
[{'id': 15, 'balance': 4959, 'currency': 'usd'}]
chat = Chat(model, sp='You are a helpful assistant that can pay offers.', tools=fs.as_tools())
pr = f"Could you pay the cheapest offer using lightning {ofs}?"
r = chat.toolloop(pr, trace_func=print)
r
Message(id='msg_01RCWZnqoZXUsQJgWpUwqZ7Z', content=[TextBlock(text='Certainly! I\'d be happy to help you pay for the cheapest offer using Lightning. Let\'s analyze the offers and proceed with the payment.\n\nFrom the information you\'ve provided, the cheapest offer is:\n\n- Amount: 1 cent (USD)\n- Balance: 1 credit\n- Offer ID: offer_c668e0c0\n- Title: "1 Credit Package"\n- Type: top-up\n- Payment method: Lightning\n\nNow, let\'s use the `pay` function to process this payment. We\'ll need to use the information from the cheapest offer and the payment context you\'ve provided.', type='text'), ToolUseBlock(id='toolu_01MCXoRCLnskTnYTEwHDVQyw', input={'purl': 'https://stock.l402.org/l402/payment-request', 'pct': 'edb53dec-28f5-4cbb-924a-20e9003c20e1', 'amount': 1, 'balance': 1, 'currency': 'USD', 'description': 'Purchase 1 credit for API access', 'offer_id': 'offer_c668e0c0', 'payment_methods': ['lightning'], 'title': '1 Credit Package', 'type': 'top-up'}, name='pay', type='tool_use')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='tool_use', stop_sequence=None, type='message', usage=In: 1186; Out: 405; Cache create: 0; Cache read: 0; Total: 1591)
Message(id='msg_016QxjwdSQchw5Vmyqqu23ey', content=[TextBlock(text="Great news! The payment for the cheapest offer has been successfully processed. Here's a summary of the transaction:\n\n1. Payment Status: Success\n2. Amount Paid: 1 cent (USD)\n3. Payment Method: Lightning\n4. Title: 1 Credit Package\n5. Description: Purchase 1 credit for API access\n6. Type: Top-up\n7. Transaction ID: 264\n8. Created At: 2025-01-25T19:52:55.228Z (Note: This appears to be a future date, which might be due to a system time discrepancy)\n\nThe payment has been completed, and you should now have 1 credit added to your API access. Is there anything else you would like me to help you with regarding this transaction or any other matters?", type='text')], model='claude-3-5-sonnet-20240620', role='assistant', stop_reason='end_turn', stop_sequence=None, type='message', usage=In: 2146; Out: 181; Cache create: 0; Cache read: 0; Total: 2327)

Great news! The payment for the cheapest offer has been successfully processed. Here’s a summary of the transaction:

  1. Payment Status: Success
  2. Amount Paid: 1 cent (USD)
  3. Payment Method: Lightning
  4. Title: 1 Credit Package
  5. Description: Purchase 1 credit for API access
  6. Type: Top-up
  7. Transaction ID: 264
  8. Created At: 2025-01-25T19:52:55.228Z (Note: This appears to be a future date, which might be due to a system time discrepancy)

The payment has been completed, and you should now have 1 credit added to your API access. Is there anything else you would like me to help you with regarding this transaction or any other matters?

  • id: msg_016QxjwdSQchw5Vmyqqu23ey
  • content: [{'text': "Great news! The payment for the cheapest offer has been successfully processed. Here's a summary of the transaction:\n\n1. Payment Status: Success\n2. Amount Paid: 1 cent (USD)\n3. Payment Method: Lightning\n4. Title: 1 Credit Package\n5. Description: Purchase 1 credit for API access\n6. Type: Top-up\n7. Transaction ID: 264\n8. Created At: 2025-01-25T19:52:55.228Z (Note: This appears to be a future date, which might be due to a system time discrepancy)\n\nThe payment has been completed, and you should now have 1 credit added to your API access. Is there anything else you would like me to help you with regarding this transaction or any other matters?", 'type': 'text'}]
  • model: claude-3-5-sonnet-20240620
  • role: assistant
  • stop_reason: end_turn
  • stop_sequence: None
  • type: message
  • usage: {'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 2146, 'output_tokens': 181}

We can see in the chat history to see that the agent correctlye filled the required information for the payment.

The payment balance has also decreased as expected.

fs.balance(), chat.h
([{'id': 15, 'balance': 4958, 'currency': 'usd'}],
 [{'role': 'user',
   'content': [{'type': 'text',
     'text': "Could you pay the cheapest offer using lightning {'offers': [{'amount': 1, 'balance': 1, 'currency': 'USD', 'description': 'Purchase 1 credit for API access', 'offer_id': 'offer_c668e0c0', 'payment_methods': ['lightning'], 'title': '1 Credit Package', 'type': 'top-up'}, {'amount': 100, 'balance': 120, 'currency': 'USD', 'description': 'Purchase 120 credits for API access', 'offer_id': 'offer_97bf23f7', 'payment_methods': ['lightning', 'coinbase_commerce'], 'title': '120 Credits Package', 'type': 'top-up'}, {'amount': 499, 'balance': 750, 'currency': 'USD', 'description': 'Purchase 750 credits for API access', 'offer_id': 'offer_a896b13c', 'payment_methods': ['lightning', 'coinbase_commerce', 'credit_card'], 'title': '750 Credits Package', 'type': 'top-up'}], 'payment_context_token': 'edb53dec-28f5-4cbb-924a-20e9003c20e1', 'payment_request_url': 'https://stock.l402.org/l402/payment-request', 'terms_url': 'https://link-to-terms.com', 'version': '0.2.1'}?"}]},
  {'role': 'assistant',
   'content': [TextBlock(text='Certainly! I\'d be happy to help you pay for the cheapest offer using Lightning. Let\'s analyze the offers and proceed with the payment.\n\nFrom the information you\'ve provided, the cheapest offer is:\n\n- Amount: 1 cent (USD)\n- Balance: 1 credit\n- Offer ID: offer_c668e0c0\n- Title: "1 Credit Package"\n- Type: top-up\n- Payment method: Lightning\n\nNow, let\'s use the `pay` function to process this payment. We\'ll need to use the information from the cheapest offer and the payment context you\'ve provided.', type='text'),
    ToolUseBlock(id='toolu_01MCXoRCLnskTnYTEwHDVQyw', input={'purl': 'https://stock.l402.org/l402/payment-request', 'pct': 'edb53dec-28f5-4cbb-924a-20e9003c20e1', 'amount': 1, 'balance': 1, 'currency': 'USD', 'description': 'Purchase 1 credit for API access', 'offer_id': 'offer_c668e0c0', 'payment_methods': ['lightning'], 'title': '1 Credit Package', 'type': 'top-up'}, name='pay', type='tool_use')]},
  {'role': 'user',
   'content': [{'type': 'tool_result',
     'tool_use_id': 'toolu_01MCXoRCLnskTnYTEwHDVQyw',
     'content': "{'id': 264, 'created_at': '2025-01-25T19:52:55.228Z', 'status': 'success', 'payment_request_url': 'https://stock.l402.org/l402/payment-request', 'payment_context_token': 'edb53dec-28f5-4cbb-924a-20e9003c20e1', 'invoice': 'lnbc90n1pne2sgkpp5phnen5rzzgr9cqnpndr6p4w70z5w4xwfhe6l7x6pn3nzmfx8g8ssdq6xysyxun9v35hggzsv93kkct8v5cqzpgxqrzpnrzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5hv706efny3f3fv2p7qtt9w0a6tu3fxjcvect067u4dedke776ejq9qxpqysgqcs6dessgwy7cdxtpn5kmg7l43z07m7w27wkkcm3hl6xcj85tzpu54ltvq89s3uldesut68f7l72mjfztz3tklkcqdtvqdwma0l0vg9gqu35tnd', 'preimage': 'b9104824a2a0d7d1d7227f900d62c8b29ee3d20e579e197037f5f0617f3daf58', 'amount': 1, 'currency': 'usd', 'payment_method': 'lightning', 'title': '1 Credit Package', 'description': 'Purchase 1 credit for API access', 'type': 'top-up'}"}]},
  {'role': 'assistant',
   'content': [TextBlock(text="Great news! The payment for the cheapest offer has been successfully processed. Here's a summary of the transaction:\n\n1. Payment Status: Success\n2. Amount Paid: 1 cent (USD)\n3. Payment Method: Lightning\n4. Title: 1 Credit Package\n5. Description: Purchase 1 credit for API access\n6. Type: Top-up\n7. Transaction ID: 264\n8. Created At: 2025-01-25T19:52:55.228Z (Note: This appears to be a future date, which might be due to a system time discrepancy)\n\nThe payment has been completed, and you should now have 1 credit added to your API access. Is there anything else you would like me to help you with regarding this transaction or any other matters?", type='text')]}])