= Sherlock(priv)
s s
Sherlock(pubkey=90ba884688884277e49080712f386eebc88806efa8345ca937f75fe80950156d)
This is the main class for the SDK. If a private key is not provided, we will try to load it from the config file. If neither the private key nor the config file is provided, we will generate a new one and store it in the config file.
Sherlock (priv:str='')
Sherlock client class to interact with the Sherlock API.
Type | Default | Details | |
---|---|---|---|
priv | str | private key |
Let’s do an authenticated request to verify we’re authenticated.
(<Response [200 OK]>,
{'logged_in': True,
'email': 'jordi@fewsats.com',
'public_key': '90ba884688884277e49080712f386eebc88806efa8345ca937f75fe80950156d'})
Sherlock.me ()
Get authenticated user information
Accounts created by AI Agents can link an email. After confirming the account users will be able log in and use the web interface for Sherlock Domains.
An email cannot be claimed more than once.
Sherlock.claim_account (email:str)
Claim an account by linking an email address
Search domains returns domain availability and its prices in USD cents.
Sherlock.search (q:str)
Search for domains with a query. Returns prices in USD cents.
Type | Details | |
---|---|---|
q | str | query |
sr = s.search("trakwiska")
# Don't print the whole lists
sr['available'] = sr['available'][:1]
sr['unavailable'] = sr['unavailable'][:1]
sr
{'id': '49350e55-aaf1-4acd-93f1-304d33271207',
'created_at': '2025-01-14T03:34:33.957Z',
'available': [{'name': 'trakwiska.com',
'tld': 'com',
'tags': [],
'price': 1105,
'currency': 'USD',
'available': True}],
'unavailable': []}
Contact information is required for ICANN domain registration and billing.
Contact (first_name, last_name, email, address, city, state, postal_code, country)
Contact information for a domain purchase
Sherlock.get_contact_information ()
Get the contact information for the Sherlock user.
Sherlock.set_contact_information (cfn:str='', cln:str='', cem:str='', cadd:str='', cct:str='', cst:str='', cpc:str='', ccn:str='')
Set the contact information for the Sherlock user
Type | Default | Details | |
---|---|---|---|
cfn | str | contact first name | |
cln | str | contact last name | |
cem | str | contact email | |
cadd | str | contact address | |
cct | str | contact city | |
cst | str | contact state | |
cpc | str | contact postal code | |
ccn | str | contact country |
Contact.is_valid ()
Check if the contact information is valid
info = {
"first_name": "Test",
"last_name": "User",
"email": "test@example.com",
"address": "123 Test St",
"city": "Test City",
"state": "CA",
"country": "US",
"postal_code": "12345",
}
c = Contact(**info)
c, c.is_valid()
(Contact(first_name='Test', last_name='User', email='test@example.com', address='123 Test St', city='Test City', state='CA', postal_code='12345', country='US'),
True)
A purchase needs to be linked to a search id. The purchase flow implements the L402 protocol. The flow has two steps:
{'domain': 'trakwiska.com',
'contact_information': {'first_name': 'Test',
'last_name': 'User',
'email': 'test@example.com',
'address': '123 Test St',
'city': 'Test City',
'state': 'CA',
'postal_code': '12345',
'country': 'US'},
'search_id': '49350e55-aaf1-4acd-93f1-304d33271207'}
(<Response [402 Payment Required]>,
{'version': '0.2.1',
'payment_request_url': 'https://api.sherlockdomains.com/api/v0/payments/l402/payment_request',
'payment_context_token': '90ba884688884277e49080712f386eebc88806efa8345ca937f75fe80950156d',
'offers': [{'id': '0c1e9f4a-8cc9-430e-9d40-1f74753ca8c5',
'title': 'trakwiska.com',
'description': 'Purchase trakwiska.com for 11.05 USD',
'type': 'one-time',
'amount': 1105,
'currency': 'USD',
'payment_methods': ['credit_card', 'lightning']}]})
Sherlock.get_purchase_offers (sid:str, domain:str, c:__main__.Contact)
Request available payment options for a domain.
Type | Details | |
---|---|---|
sid | str | search id |
domain | str | domain |
c | Contact | contact information |
Requesting a purchase will return a list of available offers and payment methods.
{'version': '0.2.1',
'payment_request_url': 'https://api.sherlockdomains.com/api/v0/payments/l402/payment_request',
'payment_context_token': '90ba884688884277e49080712f386eebc88806efa8345ca937f75fe80950156d',
'offers': [{'id': 'dcaa88c0-e29f-4075-921f-83e6cde56ef3',
'title': 'trakwiska.com',
'description': 'Purchase trakwiska.com for 11.05 USD',
'type': 'one-time',
'amount': 1105,
'currency': 'USD',
'payment_methods': ['credit_card', 'lightning']}]}
In order to pay for the domain you will have to request the payment details of the offer you want to pay for.
data = {
"offer_id": first(ofs['offers'])['id'],
"payment_method": 'credit_card',
"payment_context_token": ofs['payment_context_token']
}
r = httpx.post(ofs['payment_request_url'], json=data)
r, r.json()
(<Response [200 OK]>,
{'payment_method': {'checkout_url': 'https://checkout.stripe.com/c/pay/cs_live_a1Om85Efvv1lgfE8BbhUNibQyzwoEfG8qvKPeOVoSt5tv0wx2rxcgiKofV#fidkdWxOYHwnPyd1blppbHNgWjA0S3VzXDdBbTFNVlJzfDVRQVQ2dVdBTnJTSH1QMGs2dHRsanJMbkY0PTxKbUtRaWowT2NwMGM8RlVBbGRqSWo3UFYwcVdqR3F9N2BtM2ZTPXc1Z3dQXGc2NTVPYVVSQkM8bycpJ2N3amhWYHdzYHcnP3F3cGApJ2lkfGpwcVF8dWAnPyd2bGtiaWBabHFgaCcpJ2BrZGdpYFVpZGZgbWppYWB3dic%2FcXdwYHgl',
'lightning_invoice': None},
'expires_at': '2025-01-14T04:04:35.484Z'})
Sherlock.get_payment_details (prurl:str, oid:str, pm:str, pct:str)
Get payment details for an offer.
Type | Details | |
---|---|---|
prurl | str | payment request url |
oid | str | offer id |
pm | str | payment method |
pct | str | payment context token |
Sherlock.request_payment_details (sid:str, domain:str, payment_method:str='credit_card', contact:__main__.Contact=None)
Request payment information for purchasing a domain. Returns the details needed to complete the payment (like a checkout URL).
Type | Default | Details | |
---|---|---|---|
sid | str | search id | |
domain | str | domain | |
payment_method | str | credit_card | payment method {‘credit_card’, ‘lightning’} |
contact | Contact | None | contact information |
Sherlock.domains ()
List of domains owned by the authenticated user
[{'id': 'd9b2cc30-c15d-44b9-9d39-5d33da504484',
'domain_name': 'h402.org',
'created_at': '2024-12-28T18:58:49.899Z',
'expires_at': '2024-12-31T18:58:42Z',
'auto_renew': False,
'locked': True,
'private': True,
'nameservers': [],
'status': 'active'}]
Sherlock.dns_records (domain_id:str)
Get DNS records for a domain.
Type | Details | |
---|---|---|
domain_id | str | domain id |
{'domain': 'h402.org',
'records': [{'id': '8c1df0e3ad7ff4b30695a11e20d84b72',
'type': 'A',
'name': 'h402.org',
'value': '76.76.21.21',
'ttl': 3600}]}
Sherlock.create_dns (domain_id:str, type:str='TXT', name:str='test', value:str='test-1', ttl:int=3600)
Create a new DNS record
Type | Default | Details | |
---|---|---|---|
domain_id | str | domain id | |
type | str | TXT | type |
name | str | test | name |
value | str | test-1 | value |
ttl | int | 3600 | ttl |
entry = s.create_dns(
domain_id=did,
type="TXT",
name="test-sherlock", # This will create test-sherlock.yourdomain.com
value="hello-world", # The actual text content
ttl=3600 # Time to live in seconds
)
created_record_id = first(entry['records'])['id']
created_record_id, entry
('b22820c45b6f2a48461c3a52ca486b5a',
{'domain': 'h402.org',
'records': [{'id': 'b22820c45b6f2a48461c3a52ca486b5a',
'type': 'TXT',
'name': 'test-sherlock',
'value': 'hello-world',
'ttl': 3600}]})
{'domain': 'h402.org',
'records': [{'id': '8c1df0e3ad7ff4b30695a11e20d84b72',
'type': 'A',
'name': 'h402.org',
'value': '76.76.21.21',
'ttl': 3600},
{'id': 'b22820c45b6f2a48461c3a52ca486b5a',
'type': 'TXT',
'name': 'test-sherlock.h402.org',
'value': 'hello-world',
'ttl': 3600}]}
Sherlock.update_dns (domain_id:str, record_id:str, type:str='TXT', name:str='test-2', value:str='test-2', ttl:int=3600)
Update a DNS record
Type | Default | Details | |
---|---|---|---|
domain_id | str | domain id | |
record_id | str | record id | |
type | str | TXT | type |
name | str | test-2 | name |
value | str | test-2 | value |
ttl | int | 3600 | ttl |
updated_record = s.update_dns(
domain_id=did,
record_id=entry['records'][0]['id'],
type="TXT",
name="test-sherlock",
value="hello-world-updated",
ttl=3600
)
updated_record_id = first(updated_record['records'])['id']
updated_record_id, updated_record
('3944584c93667d49c774e7823a039cd8',
{'domain': 'h402.org',
'records': [{'id': '3944584c93667d49c774e7823a039cd8',
'type': 'TXT',
'name': 'test-sherlock',
'value': 'hello-world-updated',
'ttl': 3600}]})
Sherlock.delete_dns (domain_id:str, record_id:str)
Delete a DNS record
Type | Details | |
---|---|---|
domain_id | str | domain id |
record_id | str | record id |
{'domain': 'h402.org', 'deleted_records': ['3944584c93667d49c774e7823a039cd8']}
We expose Sherlock’s core functionality as tools for AI agents. Note that payment handling for L402 offers requires additional tools like fewsats.Client().pay
.
Sherlock.as_tools ()
Return the Sherlock class as a list of tools ready for agents to use
Sherlock.as_cli ()
Return the Sherlock class as a list of tools ready for agents to use
You can use the Sherlock class as a CLI tool.
❯ sherlock
usage: sherlock [-h] {me,set_contact_information,get_contact_information,search,purchase_domain,domains,dns_records,create_dns,update_dns,delete_dns} ...
positional arguments:
{me,set_contact_information,get_contact_information,search,purchase_domain,domains,dns_records,create_dns,update_dns,delete_dns}
me Get authenticated user information
set_contact_information
Set the contact information for the Sherlock user
get_contact_information
Get the contact information for the Sherlock user.
search Search for domains with a query. Returns prices in USD cents.
purchase_domain Request payment information for purchasing a domain. Returns the details needed to complete the payment (like a checkout URL).
domains List of domains owned by the authenticated user
dns_records Get DNS records for a domain.
create_dns Create a new DNS record
update_dns Update a DNS record
delete_dns Delete a DNS record
options:
-h, --help show this help message and exit
main ()
CLI interface for Sherlock