from fewsats.core import *
from fastcore.all import *
import json
Note: you may need to restart the kernel to use updated packages.
from sherlock.core import Sherlock, Contact
# Initialize the Sherlock client
= Sherlock()
s
# Search for domain
= s.search("notahuman.me")
r r
{'id': '9573872e-f0d8-43e9-bc7f-604e77e642d2',
'created_at': '2025-02-02T02:06:19.197Z',
'available': [{'name': 'notahuman.dev',
'tld': 'dev',
'tags': [],
'price': 1489,
'currency': 'USD',
'available': True},
{'name': 'notahuman.net',
'tld': 'net',
'tags': [],
'price': 1185,
'currency': 'USD',
'available': True},
{'name': 'notahuman.info',
'tld': 'info',
'tags': [],
'price': 429,
'currency': 'USD',
'available': True},
{'name': 'notahuman.biz',
'tld': 'biz',
'tags': [],
'price': 685,
'currency': 'USD',
'available': True},
{'name': 'notahuman.design',
'tld': 'design',
'tags': [],
'price': 4585,
'currency': 'USD',
'available': True},
{'name': 'notahuman.me',
'tld': 'me',
'tags': [],
'price': 489,
'currency': 'USD',
'available': True},
{'name': 'notahuman.tech',
'tld': 'tech',
'tags': [],
'price': 819,
'currency': 'USD',
'available': True},
{'name': 'notahuman.xyz',
'tld': 'xyz',
'tags': [],
'price': 269,
'currency': 'USD',
'available': True}],
'unavailable': [{'name': 'notahuman.com',
'tld': 'com',
'tags': None,
'price': 0,
'currency': '',
'available': False},
{'name': 'notahuman.org',
'tld': 'org',
'tags': None,
'price': 0,
'currency': '',
'available': False},
{'name': 'notahuman.co',
'tld': 'co',
'tags': None,
'price': 0,
'currency': '',
'available': False},
{'name': 'notahuman.io',
'tld': 'io',
'tags': None,
'price': 0,
'currency': '',
'available': False},
{'name': 'notahuman.ai',
'tld': 'ai',
'tags': None,
'price': 0,
'currency': '',
'available': False}]}
= dict2obj(r)
d d
{ 'available': [{'name': 'notahuman.dev', 'tld': 'dev', 'tags': [], 'price': 1489, 'currency': 'USD', 'available': True}, {'name': 'notahuman.net', 'tld': 'net', 'tags': [], 'price': 1185, 'currency': 'USD', 'available': True}, {'name': 'notahuman.info', 'tld': 'info', 'tags': [], 'price': 429, 'currency': 'USD', 'available': True}, {'name': 'notahuman.biz', 'tld': 'biz', 'tags': [], 'price': 685, 'currency': 'USD', 'available': True}, {'name': 'notahuman.design', 'tld': 'design', 'tags': [], 'price': 4585, 'currency': 'USD', 'available': True}, {'name': 'notahuman.me', 'tld': 'me', 'tags': [], 'price': 489, 'currency': 'USD', 'available': True}, {'name': 'notahuman.tech', 'tld': 'tech', 'tags': [], 'price': 819, 'currency': 'USD', 'available': True}, {'name': 'notahuman.xyz', 'tld': 'xyz', 'tags': [], 'price': 269, 'currency': 'USD', 'available': True}],
'created_at': '2025-02-02T02:06:19.197Z',
'id': '9573872e-f0d8-43e9-bc7f-604e77e642d2',
'unavailable': [{'name': 'notahuman.com', 'tld': 'com', 'tags': None, 'price': 0, 'currency': '', 'available': False}, {'name': 'notahuman.org', 'tld': 'org', 'tags': None, 'price': 0, 'currency': '', 'available': False}, {'name': 'notahuman.co', 'tld': 'co', 'tags': None, 'price': 0, 'currency': '', 'available': False}, {'name': 'notahuman.io', 'tld': 'io', 'tags': None, 'price': 0, 'currency': '', 'available': False}, {'name': 'notahuman.ai', 'tld': 'ai', 'tags': None, 'price': 0, 'currency': '', 'available': False}]}
= first(L(d.available).filter(lambda x: x['name'] == "notahuman.me"))
it it
{ 'available': True,
'currency': 'USD',
'name': 'notahuman.me',
'price': 489,
'tags': [],
'tld': 'me'}
= next((x for x in d.available if x['name'] == "notahuman.me"), None)
it it
{ 'available': True,
'currency': 'USD',
'name': 'notahuman.me',
'price': 489,
'tags': [],
'tld': 'me'}
= s.purchase_domain(
p id,
d.
it.name,='lightning'
payment_method
) p
{'payment_method': {'checkout_url': None,
'lightning_invoice': 'lnbc48360n1pnea5cupp59wn2hxrnt38u45daxxr5s5hvq9hn49va7u20xx82ky6meq7rvydqdp4g3hk6ctfdcs8yet8d9ehgunpw35k7m3qvehhygrwda6xz6r4d4skucqzpgxqrpc8rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5vg7qs509ack29pdcqvr2fu9zvv3hmpfw9dl3r9yqe6ledtja80qs9qxpqysgqxkhcearydnmt4srwlnt5z6jq2qzdxwkgmr34mul965jux5p20rdj2utjgmkk0q6kgcjpv0mkgwaspqq2gqksdknc9vvup5pyc4w27ygpcyd84s'},
'expires_at': '2025-02-02T02:36:20.299Z'}
from claudette import Chat, models
import os
'ANTHROPIC_LOG'] = 'debug'
os.environ[
= models[1]; model model
'claude-3-5-sonnet-20240620'
@patch
def pay_lightning(self: Fewsats,
str, # lightning invoice
invoice: str = "" ): # description of the payment
description: "Pay for a lightning invoice"
= {
data "invoice": invoice,
"description": description
}return self._request("POST", "v0/l402/purchases/lightning", json=data)
= Client(base_url="http://localhost:8000", api_key=os.getenv("FEWSATS_LOCAL_API_KEY"))
fs # fs = Client()
= Chat(model=model, sp='You are a helpful assistant, always use lightning payment method.', tools=[*s.as_tools(), fs.pay_lightning])
chat "can you search for notahuman.me and purchase it for me?") chat.toolloop(
Great! The purchase request has been processed, and we have received a lightning invoice for the payment. To complete the purchase, you’ll need to pay this invoice using a Lightning-compatible wallet. Here’s the Lightning invoice:
lnbc48360n1pnea5e9pp52dhq66qdc0arqpxgu6j0h9ewtza5wjjp7hnec0gc2a0lsaxfmavsdp4g3hk6ctfdcs8yet8d9ehgunpw35k7m3qvehhygrwda6xz6r4d4skucqzpgxqrpc8rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5pa5wjl9a6sn4kuycyqzqdx6vfhd96chagy0zh4d2p8swmre9achq9qxpqysgqp27ejsxe5ljv9u4sjkepz8urwfuuku69jy9g0ha5xld0e5fmrqtzzkxmtaftu3p5vh8ts5djy000e5qcv0dxfqzpqju5x8v7r0xd4pcq7lg57u
To complete the purchase, you need to pay this invoice using a Lightning wallet before it expires. The expiration time for this invoice is: 2025-02-02T02:36:29.631Z
Would you like me to proceed with paying this Lightning invoice for you?
- id:
msg_01XZtqQsg5rRvtw7ijn4DJbw
- content:
[{'text': "Great! The purchase request has been processed, and we have received a lightning invoice for the payment. To complete the purchase, you'll need to pay this invoice using a Lightning-compatible wallet. Here's the Lightning invoice:\n\nlnbc48360n1pnea5e9pp52dhq66qdc0arqpxgu6j0h9ewtza5wjjp7hnec0gc2a0lsaxfmavsdp4g3hk6ctfdcs8yet8d9ehgunpw35k7m3qvehhygrwda6xz6r4d4skucqzpgxqrpc8rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5pa5wjl9a6sn4kuycyqzqdx6vfhd96chagy0zh4d2p8swmre9achq9qxpqysgqp27ejsxe5ljv9u4sjkepz8urwfuuku69jy9g0ha5xld0e5fmrqtzzkxmtaftu3p5vh8ts5djy000e5qcv0dxfqzpqju5x8v7r0xd4pcq7lg57u\n\nTo complete the purchase, you need to pay this invoice using a Lightning wallet before it expires. The expiration time for this invoice is: 2025-02-02T02:36:29.631Z\n\nWould you like me to proceed with paying this Lightning invoice for you?", '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': 4024, 'output_tokens': 470}
"you should be able to make the payment using fs.pay method") chat.toolloop(
{
"invoice": "lnbc48360n1pnea5e9pp52dhq66qdc0arqpxgu6j0h9ewtza5wjjp7hnec0gc2a0lsaxfmavsdp4g3hk6ctfdcs8yet8d9ehgunpw35k7m3qvehhygrwda6xz6r4d4skucqzpgxqrpc8rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5pa5wjl9a6sn4kuycyqzqdx6vfhd96chagy0zh4d2p8swmre9achq9qxpqysgqp27ejsxe5ljv9u4sjkepz8urwfuuku69jy9g0ha5xld0e5fmrqtzzkxmtaftu3p5vh8ts5djy000e5qcv0dxfqzpqju5x8v7r0xd4pcq7lg57u",
"description": "Payment for notahuman.me domain purchase"
}
I apologize for the confusion. You’re absolutely right, and I appreciate you pointing that out. We can indeed use the pay_lightning
function to make the payment directly. Let’s proceed with that right away.
- id:
msg_01S4jL5nZ9ogUaP83vae3EkG
- content:
[{'text': "I apologize for the confusion. You're absolutely right, and I appreciate you pointing that out. We can indeed use the
pay_lightningfunction to make the payment directly. Let's proceed with that right away.", 'type': 'text'}, {'id': 'toolu_01HBdjkAZcDXqoSKhAyiv8JV', 'input': {'invoice': 'lnbc48360n1pnea5e9pp52dhq66qdc0arqpxgu6j0h9ewtza5wjjp7hnec0gc2a0lsaxfmavsdp4g3hk6ctfdcs8yet8d9ehgunpw35k7m3qvehhygrwda6xz6r4d4skucqzpgxqrpc8rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5pa5wjl9a6sn4kuycyqzqdx6vfhd96chagy0zh4d2p8swmre9achq9qxpqysgqp27ejsxe5ljv9u4sjkepz8urwfuuku69jy9g0ha5xld0e5fmrqtzzkxmtaftu3p5vh8ts5djy000e5qcv0dxfqzpqju5x8v7r0xd4pcq7lg57u', 'description': 'Payment for notahuman.me domain purchase'}, 'name': 'pay_lightning', 'type': 'tool_use'}]
- model:
claude-3-5-sonnet-20240620
- role:
assistant
- stop_reason:
tool_use
- stop_sequence:
None
- type:
message
- usage:
{'cache_creation_input_tokens': 0, 'cache_read_input_tokens': 0, 'input_tokens': 4510, 'output_tokens': 483}
# pip install fewsats
from fewsats.core import Client
= Client(api_key=os.getenv("FEWSATS_API_KEY"))
fs
="lnbc....", description="..") fs.pay_lightning(invoice
{
"invoice": "lnbc....",
"description": ".."
}
<Response [400 Bad Request]>
# chat.toolloop("""{"first_name": "Pol", "last_name": "Avec", "email": "p@fewsats.com", "address": "Lexington 525", "city": "NYC", "state": "NY", "postal_code": "19808", "country": "US"}""")
{
"invoice": "lnbc48360n1pnea56qpp5aatkhxtmuun2grf29jx2020ufhznnkjvvhvjyurcxg2x2wvvvwyqdp4g3hk6ctfdcs8yet8d9ehgunpw35k7m3qvehhygrwda6xz6r4d4skucqzpgxqrpc8rzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5c9zjfam3262pk0k0jd99rgaz49drh0ndqdt8uhxuycv2qkeya3ls9qxpqysgq7hakg72fflzmxygy6f0evc66l5jqlmn99maldxu8kfj4fcncxcdhzqamvhssc22k72fw78dm595esk4727wwj2a9x29gqvrxj4sy2lcqwuulg5",
"description": "Payment for notahuman.me domain purchase"
}
--------------------------------------------------------------------------- KeyboardInterrupt Traceback (most recent call last) Cell In[12], line 1 ----> 1 chat.toolloop("""{"first_name": "Pol", "last_name": "Avec", "email": "p@fewsats.com", "address": "Lexington 525", "city": "NYC", "state": "NY", "postal_code": "19808", "country": "US"}""") File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/claudette/toolloop.py:27, in toolloop(self, pr, max_steps, trace_func, cont_func, **kwargs) 25 if r.stop_reason!='tool_use': break 26 if trace_func: trace_func(r) ---> 27 r = self(**kwargs) 28 if not (cont_func or noop)(self.h[-2]): break 29 if trace_func: trace_func(r) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/claudette/core.py:312, in __call__(self, pr, temp, maxtok, stream, prefill, tool_choice, **kw) 310 if temp is None: temp=self.temp 311 self._append_pr(pr) --> 312 res = self.c(self.h, stream=stream, prefill=prefill, sp=self.sp, temp=temp, maxtok=maxtok, 313 tools=self.tools, tool_choice=tool_choice,**kw) 314 if stream: return self._stream(res) 315 self.h += mk_toolres(self.c.result, ns=self.tools, obj=self) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/claudette/core.py:221, in __call__(self, msgs, sp, temp, maxtok, prefill, stream, stop, tools, tool_choice, **kwargs) 219 msgs = self._precall(msgs, prefill, stop, kwargs) 220 if stream: return self._stream(msgs, prefill=prefill, max_tokens=maxtok, system=sp, temperature=temp, **kwargs) --> 221 res = self.c.messages.create(model=self.model, messages=msgs, max_tokens=maxtok, system=sp, temperature=temp, **kwargs) 222 return self._log(res, prefill, msgs, maxtok, sp, temp, stream=stream, stop=stop, **kwargs) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/anthropic/_utils/_utils.py:275, in required_args.<locals>.inner.<locals>.wrapper(*args, **kwargs) 273 msg = f"Missing required argument: {quote(missing[0])}" 274 raise TypeError(msg) --> 275 return func(*args, **kwargs) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/anthropic/resources/messages/messages.py:901, in Messages.create(self, max_tokens, messages, model, metadata, stop_sequences, stream, system, temperature, tool_choice, tools, top_k, top_p, extra_headers, extra_query, extra_body, timeout) 894 if model in DEPRECATED_MODELS: 895 warnings.warn( 896 f"The model '{model}' is deprecated and will reach end-of-life on {DEPRECATED_MODELS[model]}.\nPlease migrate to a newer model. Visit https://docs.anthropic.com/en/docs/resources/model-deprecations for more information.", 897 DeprecationWarning, 898 stacklevel=3, 899 ) --> 901 return self._post( 902 "/v1/messages", 903 body=maybe_transform( 904 { 905 "max_tokens": max_tokens, 906 "messages": messages, 907 "model": model, 908 "metadata": metadata, 909 "stop_sequences": stop_sequences, 910 "stream": stream, 911 "system": system, 912 "temperature": temperature, 913 "tool_choice": tool_choice, 914 "tools": tools, 915 "top_k": top_k, 916 "top_p": top_p, 917 }, 918 message_create_params.MessageCreateParams, 919 ), 920 options=make_request_options( 921 extra_headers=extra_headers, extra_query=extra_query, extra_body=extra_body, timeout=timeout 922 ), 923 cast_to=Message, 924 stream=stream or False, 925 stream_cls=Stream[RawMessageStreamEvent], 926 ) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/anthropic/_base_client.py:1279, in SyncAPIClient.post(self, path, cast_to, body, options, files, stream, stream_cls) 1265 def post( 1266 self, 1267 path: str, (...) 1274 stream_cls: type[_StreamT] | None = None, 1275 ) -> ResponseT | _StreamT: 1276 opts = FinalRequestOptions.construct( 1277 method="post", url=path, json_data=body, files=to_httpx_files(files), **options 1278 ) -> 1279 return cast(ResponseT, self.request(cast_to, opts, stream=stream, stream_cls=stream_cls)) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/anthropic/_base_client.py:956, in SyncAPIClient.request(self, cast_to, options, remaining_retries, stream, stream_cls) 953 else: 954 retries_taken = 0 --> 956 return self._request( 957 cast_to=cast_to, 958 options=options, 959 stream=stream, 960 stream_cls=stream_cls, 961 retries_taken=retries_taken, 962 ) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/anthropic/_base_client.py:992, in SyncAPIClient._request(self, cast_to, options, retries_taken, stream, stream_cls) 989 log.debug("Sending HTTP Request: %s %s", request.method, request.url) 991 try: --> 992 response = self._client.send( 993 request, 994 stream=stream or self._should_stream_response_body(request=request), 995 **kwargs, 996 ) 997 except httpx.TimeoutException as err: 998 log.debug("Encountered httpx.TimeoutException", exc_info=True) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpx/_client.py:914, in Client.send(self, request, stream, auth, follow_redirects) 910 self._set_timeout(request) 912 auth = self._build_request_auth(request, auth) --> 914 response = self._send_handling_auth( 915 request, 916 auth=auth, 917 follow_redirects=follow_redirects, 918 history=[], 919 ) 920 try: 921 if not stream: File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpx/_client.py:942, in Client._send_handling_auth(self, request, auth, follow_redirects, history) 939 request = next(auth_flow) 941 while True: --> 942 response = self._send_handling_redirects( 943 request, 944 follow_redirects=follow_redirects, 945 history=history, 946 ) 947 try: 948 try: File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpx/_client.py:979, in Client._send_handling_redirects(self, request, follow_redirects, history) 976 for hook in self._event_hooks["request"]: 977 hook(request) --> 979 response = self._send_single_request(request) 980 try: 981 for hook in self._event_hooks["response"]: File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpx/_client.py:1014, in Client._send_single_request(self, request) 1009 raise RuntimeError( 1010 "Attempted to send an async request with a sync Client instance." 1011 ) 1013 with request_context(request=request): -> 1014 response = transport.handle_request(request) 1016 assert isinstance(response.stream, SyncByteStream) 1018 response.request = request File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpx/_transports/default.py:250, in HTTPTransport.handle_request(self, request) 237 req = httpcore.Request( 238 method=request.method, 239 url=httpcore.URL( (...) 247 extensions=request.extensions, 248 ) 249 with map_httpcore_exceptions(): --> 250 resp = self._pool.handle_request(req) 252 assert isinstance(resp.stream, typing.Iterable) 254 return Response( 255 status_code=resp.status, 256 headers=resp.headers, 257 stream=ResponseStream(resp.stream), 258 extensions=resp.extensions, 259 ) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpcore/_sync/connection_pool.py:256, in ConnectionPool.handle_request(self, request) 253 closing = self._assign_requests_to_connections() 255 self._close_connections(closing) --> 256 raise exc from None 258 # Return the response. Note that in this case we still have to manage 259 # the point at which the response is closed. 260 assert isinstance(response.stream, typing.Iterable) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpcore/_sync/connection_pool.py:236, in ConnectionPool.handle_request(self, request) 232 connection = pool_request.wait_for_connection(timeout=timeout) 234 try: 235 # Send the request on the assigned connection. --> 236 response = connection.handle_request( 237 pool_request.request 238 ) 239 except ConnectionNotAvailable: 240 # In some cases a connection may initially be available to 241 # handle a request, but then become unavailable. 242 # 243 # In this case we clear the connection and try again. 244 pool_request.clear_connection() File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpcore/_sync/connection.py:103, in HTTPConnection.handle_request(self, request) 100 self._connect_failed = True 101 raise exc --> 103 return self._connection.handle_request(request) File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpcore/_sync/http11.py:136, in HTTP11Connection.handle_request(self, request) 134 with Trace("response_closed", logger, request) as trace: 135 self._response_closed() --> 136 raise exc File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpcore/_sync/http11.py:106, in HTTP11Connection.handle_request(self, request) 95 pass 97 with Trace( 98 "receive_response_headers", logger, request, kwargs 99 ) as trace: 100 ( 101 http_version, 102 status, 103 reason_phrase, 104 headers, 105 trailing_data, --> 106 ) = self._receive_response_headers(**kwargs) 107 trace.return_value = ( 108 http_version, 109 status, 110 reason_phrase, 111 headers, 112 ) 114 network_stream = self._network_stream File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpcore/_sync/http11.py:177, in HTTP11Connection._receive_response_headers(self, request) 174 timeout = timeouts.get("read", None) 176 while True: --> 177 event = self._receive_event(timeout=timeout) 178 if isinstance(event, h11.Response): 179 break File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpcore/_sync/http11.py:217, in HTTP11Connection._receive_event(self, timeout) 214 event = self._h11_state.next_event() 216 if event is h11.NEED_DATA: --> 217 data = self._network_stream.read( 218 self.READ_NUM_BYTES, timeout=timeout 219 ) 221 # If we feed this case through h11 we'll raise an exception like: 222 # 223 # httpcore.RemoteProtocolError: can't handle event type (...) 227 # perspective. Instead we handle this case distinctly and treat 228 # it as a ConnectError. 229 if data == b"" and self._h11_state.their_state == h11.SEND_RESPONSE: File ~/go/github.com/Fewsats/fewsats-python/venv/lib/python3.12/site-packages/httpcore/_backends/sync.py:128, in SyncStream.read(self, max_bytes, timeout) 126 with map_exceptions(exc_map): 127 self._sock.settimeout(timeout) --> 128 return self._sock.recv(max_bytes) File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/ssl.py:1233, in SSLSocket.recv(self, buflen, flags) 1229 if flags != 0: 1230 raise ValueError( 1231 "non-zero flags not allowed in calls to recv() on %s" % 1232 self.__class__) -> 1233 return self.read(buflen) 1234 else: 1235 return super().recv(buflen, flags) File /Library/Frameworks/Python.framework/Versions/3.12/lib/python3.12/ssl.py:1106, in SSLSocket.read(self, len, buffer) 1104 return self._sslobj.read(len, buffer) 1105 else: -> 1106 return self._sslobj.read(len) 1107 except SSLError as x: 1108 if x.args[0] == SSL_ERROR_EOF and self.suppress_ragged_eofs: KeyboardInterrupt:
@patch
def _get_offers(self: Sherlock,
str, # search id
sid: str): # domain name
domain: """
Purchase a domain. This method won't charge your account, it will return the payment information needed to complete the purchase.
Contact information must be set before calling this method.
sid: Search ID from a previous search request
domain: Domain name to purchase
"""
= Contact(**self.get_contact_information())
contact if not contact.is_valid(): raise ValueError("Contact information is required")
return self.get_purchase_offers(sid, domain, contact)
= s._get_offers(d.id, it.name)
o o
= Client()
fs fs.me()
# TODO make this version work
@patch
def pay_offer(self: Fewsats, ofr: dict):
= {
data "payment_request_url": ofr["payment_request_url"],
"payment_context_token": ofr["payment_context_token"],
"payment_method": "lightning",
"offer": first(ofr["offers"])
}print(json.dumps(data, indent=2))
return self._request("POST", "v0/l402/purchases/from-offer", json=data)
= fs.pay_offer(o)
r r
# TODO it is VERY IMPORTANT to make sure we return this error to the LLM, maybe the "process_response" shoudl always be used
r, r.status_code, r.text
@patch
def pay_offer(self: Fewsats, ofr: dict):
= {
data "payment_request_url": ofr["payment_request_url"],
"payment_context_token": ofr["payment_context_token"],
"payment_method": "lightning",
"offer": first(ofr["offers"])
}print(json.dumps(data, indent=2))
'offer']['offer_id'] = data['offer']['id']
data[return self._request("POST", "v0/l402/purchases/from-offer", json=data)