grid402 2.2.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- grid402-2.2.0/LICENSE +22 -0
- grid402-2.2.0/PKG-INFO +165 -0
- grid402-2.2.0/README.md +134 -0
- grid402-2.2.0/grid402/__init__.py +50 -0
- grid402-2.2.0/grid402/agentkit.py +186 -0
- grid402-2.2.0/grid402/client.py +156 -0
- grid402-2.2.0/grid402/exceptions.py +34 -0
- grid402-2.2.0/grid402/models.py +119 -0
- grid402-2.2.0/grid402/py.typed +1 -0
- grid402-2.2.0/grid402.egg-info/PKG-INFO +165 -0
- grid402-2.2.0/grid402.egg-info/SOURCES.txt +16 -0
- grid402-2.2.0/grid402.egg-info/dependency_links.txt +1 -0
- grid402-2.2.0/grid402.egg-info/requires.txt +5 -0
- grid402-2.2.0/grid402.egg-info/top_level.txt +1 -0
- grid402-2.2.0/pyproject.toml +59 -0
- grid402-2.2.0/setup.cfg +4 -0
- grid402-2.2.0/tests/test_live_sandbox.py +78 -0
- grid402-2.2.0/tests/test_sdk.py +205 -0
grid402-2.2.0/LICENSE
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Grid402 Contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
grid402-2.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: grid402
|
|
3
|
+
Version: 2.2.0
|
|
4
|
+
Summary: SDK Python oficial do Grid402: Micropagamentos HTTP 402 na Base para Agentes Autonomos e IA
|
|
5
|
+
Author-email: Grid402 Team <contato@grid402.com.br>
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Project-URL: Homepage, https://grid402.com.br
|
|
8
|
+
Project-URL: Documentation, https://grid402.com.br/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/thiagobg90/Grid402
|
|
10
|
+
Project-URL: Issues, https://github.com/thiagobg90/Grid402/issues
|
|
11
|
+
Keywords: x402,http-402,micropayments,base,coinbase-agentkit,agentic-web,mcp,ai-agents
|
|
12
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
21
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
22
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Requires-Dist: pydantic>=2.0.0
|
|
27
|
+
Provides-Extra: dev
|
|
28
|
+
Requires-Dist: build; extra == "dev"
|
|
29
|
+
Requires-Dist: twine; extra == "dev"
|
|
30
|
+
Dynamic: license-file
|
|
31
|
+
|
|
32
|
+
# Grid402 - SDK Python Oficial
|
|
33
|
+
|
|
34
|
+
Biblioteca Python oficial para consumo dos servicos do ecossistema **Grid402** e liquidacao autonoma de micropagamentos sob o protocolo HTTP 402 na rede Base.
|
|
35
|
+
|
|
36
|
+
Projetada especificamente para agentes autonomos de inteligencia artificial, frameworks como Coinbase AgentKit, LangChain, CrewAI e desenvolvedores que buscam APIs abertas sem contas, cadastros ou cartoes de credito.
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## Recursos Principais
|
|
41
|
+
|
|
42
|
+
- **10 Ferramentas Integradas:** Indicadores macroeconomicos (Selic, CDI, IPCA), feriados nacionais e bancarios ANBIMA, CNPJ da Receita Federal, CEP postal e IBGE, cotacoes Forex e Cripto spot, resolucao DNS, auditoria TLS e SSL, analise ASN e BGP e status do ecossistema.
|
|
43
|
+
- **Zero Cadastro e Zero Friccao:** Sem necessidade de chaves de API estaticas ou contratos mensais.
|
|
44
|
+
- **Modo Sandbox Gratuito:** Teste e homologue localmente sem custos informando `sandbox=True`.
|
|
45
|
+
- **Integracao Nativa com IA:** Compativel com Coinbase Developer Platform (CDP) AgentKit, LangChain e CrewAI.
|
|
46
|
+
- **Validacao Estrita Pydantic:** Schemas tipados e compativeis com PEP 561 (`py.typed`).
|
|
47
|
+
- **Arquitetura Resiliente:** Construido com a biblioteca padrao do Python para maxima leveza e portabilidade.
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
## Instalacao
|
|
52
|
+
|
|
53
|
+
Instale o pacote diretamente do PyPI:
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
pip install grid402
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
## Inicio Rapido
|
|
62
|
+
|
|
63
|
+
### 1. Consultas em Modo Sandbox (Sem Custo)
|
|
64
|
+
|
|
65
|
+
Ideal para testes locais, ambientes de integracao continua e desenvolvimento:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from grid402 import Grid402Client
|
|
69
|
+
|
|
70
|
+
# Inicializa o cliente apontando para o ambiente de testes gratuito
|
|
71
|
+
client = Grid402Client(sandbox=True)
|
|
72
|
+
|
|
73
|
+
# Consulta cadastral de Pessoa Juridica na Receita Federal
|
|
74
|
+
cnpj_data = client.get_cnpj("00.000.000/0001-91")
|
|
75
|
+
print("Razao Social:", cnpj_data.get("razao_social"))
|
|
76
|
+
|
|
77
|
+
# Resolucao de endereco postal e codigo IBGE
|
|
78
|
+
cep_data = client.get_cep("01310-100")
|
|
79
|
+
print("Logradouro:", cep_data.get("logradouro"), "-", cep_data.get("localidade"))
|
|
80
|
+
|
|
81
|
+
# Cotacoes fiduciarias oficiais
|
|
82
|
+
forex_data = client.get_forex()
|
|
83
|
+
print("USD para BRL:", forex_data.get("USD", {}).get("bid"))
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
### 2. Tratamento Estruturado de HTTP 402
|
|
89
|
+
|
|
90
|
+
Quando chamado sem comprovante de pagamento, o Grid402 retorna uma resposta estruturada contendo o desafio com pre-visualizacao parcial dos dados (teaser data):
|
|
91
|
+
|
|
92
|
+
```python
|
|
93
|
+
from grid402 import Grid402Client, Grid402PaymentRequiredError
|
|
94
|
+
|
|
95
|
+
# Cliente com raise_for_payment ativado
|
|
96
|
+
client = Grid402Client(raise_for_payment=True)
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
dados = client.get_cnpj("00000000000191")
|
|
100
|
+
except Grid402PaymentRequiredError as erro:
|
|
101
|
+
print("Desafio recebido:")
|
|
102
|
+
print("Valor exigido:", erro.price_usdc, erro.token)
|
|
103
|
+
print("Carteira recebedora:", erro.recipient)
|
|
104
|
+
print("Rede:", erro.network)
|
|
105
|
+
print("Dados parciais (amostra gratuita):", erro.preview_data)
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
---
|
|
109
|
+
|
|
110
|
+
### 3. Utilizacao com Coinbase AgentKit e Auto-Liquidacao
|
|
111
|
+
|
|
112
|
+
Agentes autonomos equipados com carteiras CDP na rede Base podem liquidar chamadas M2M (Machine-to-Machine) de forma transparente:
|
|
113
|
+
|
|
114
|
+
```python
|
|
115
|
+
from grid402 import Grid402ActionProvider
|
|
116
|
+
|
|
117
|
+
# Provedor compativel com Coinbase AgentKit
|
|
118
|
+
provider = Grid402ActionProvider()
|
|
119
|
+
|
|
120
|
+
# Ao fornecer a instancia de carteira CDP do agente (wallet_provider),
|
|
121
|
+
# o provedor detecta o 402, transfere o USDC e repassa os dados completos
|
|
122
|
+
resultado = provider.query_cnpj("00000000000191", wallet_provider=meu_wallet_provider)
|
|
123
|
+
print("Dados completos:", resultado)
|
|
124
|
+
print("Comprovante on-chain:", resultado.get("_x402_settlement"))
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
### 4. Schemas Tipados Pydantic
|
|
130
|
+
|
|
131
|
+
Para fluxos de trabalho tipados e validacao antecipada:
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
from grid402 import CnpjInput, CepInput, DnsInput, SslInput, AsnInput, IndicatorsInput, HolidaysInput
|
|
135
|
+
|
|
136
|
+
# Validacao de entrada antes do envio
|
|
137
|
+
payload_cnpj = CnpjInput(cnpj="00.000.000/0001-91")
|
|
138
|
+
payload_cep = CepInput(code="01310100")
|
|
139
|
+
payload_dns = DnsInput(domain="base.org")
|
|
140
|
+
payload_holidays = HolidaysInput(year=2026)
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
## Catalogo de Ferramentas
|
|
146
|
+
|
|
147
|
+
| Metodo | Descricao | Preco Base (USDC) |
|
|
148
|
+
|---|---|---|
|
|
149
|
+
| `get_summary()` | Resumo operacional consolidado de saude | Gratuito |
|
|
150
|
+
| `get_forex()` | Cotacoes cambiais oficiais de USD, EUR e GBP para BRL | 0.0005 |
|
|
151
|
+
| `get_crypto(symbol)` | Precos spot de BTC, ETH, SOL e USDC | 0.0005 |
|
|
152
|
+
| `get_dns(domain)` | Resolucao DNS com registros A, AAAA, MX, TXT, NS e CNAME | 0.0005 |
|
|
153
|
+
| `get_ssl(host)` | Inspecao e auditoria de certificado TLS e SSL na porta 443 | 0.0005 |
|
|
154
|
+
| `get_asn(ip)` | Inteligencia de roteamento BGP, bloco alocado e ASN | 0.0005 |
|
|
155
|
+
| `get_cep(code)` | Consulta de logradouro postal brasileiro e codigo IBGE | 0.0005 |
|
|
156
|
+
| `get_cnpj(cnpj)` | Dados cadastrais completos de PJ na Receita Federal | 0.0020 |
|
|
157
|
+
| `get_indicators()` | Indicadores macroeconomicos oficiais (Selic meta e diaria, CDI anual e IPCA) | 0.0005 |
|
|
158
|
+
| `get_holidays(year)` | Calendario oficial de feriados nacionais e bancarios ANBIMA | 0.0005 |
|
|
159
|
+
|
|
160
|
+
---
|
|
161
|
+
|
|
162
|
+
## Licenca
|
|
163
|
+
|
|
164
|
+
Distribuido sob os termos da licenca MIT. Consulte o arquivo `LICENSE` para detalhes.
|
|
165
|
+
|
grid402-2.2.0/README.md
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
# Grid402 - SDK Python Oficial
|
|
2
|
+
|
|
3
|
+
Biblioteca Python oficial para consumo dos servicos do ecossistema **Grid402** e liquidacao autonoma de micropagamentos sob o protocolo HTTP 402 na rede Base.
|
|
4
|
+
|
|
5
|
+
Projetada especificamente para agentes autonomos de inteligencia artificial, frameworks como Coinbase AgentKit, LangChain, CrewAI e desenvolvedores que buscam APIs abertas sem contas, cadastros ou cartoes de credito.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Recursos Principais
|
|
10
|
+
|
|
11
|
+
- **10 Ferramentas Integradas:** Indicadores macroeconomicos (Selic, CDI, IPCA), feriados nacionais e bancarios ANBIMA, CNPJ da Receita Federal, CEP postal e IBGE, cotacoes Forex e Cripto spot, resolucao DNS, auditoria TLS e SSL, analise ASN e BGP e status do ecossistema.
|
|
12
|
+
- **Zero Cadastro e Zero Friccao:** Sem necessidade de chaves de API estaticas ou contratos mensais.
|
|
13
|
+
- **Modo Sandbox Gratuito:** Teste e homologue localmente sem custos informando `sandbox=True`.
|
|
14
|
+
- **Integracao Nativa com IA:** Compativel com Coinbase Developer Platform (CDP) AgentKit, LangChain e CrewAI.
|
|
15
|
+
- **Validacao Estrita Pydantic:** Schemas tipados e compativeis com PEP 561 (`py.typed`).
|
|
16
|
+
- **Arquitetura Resiliente:** Construido com a biblioteca padrao do Python para maxima leveza e portabilidade.
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Instalacao
|
|
21
|
+
|
|
22
|
+
Instale o pacote diretamente do PyPI:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
pip install grid402
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
---
|
|
29
|
+
|
|
30
|
+
## Inicio Rapido
|
|
31
|
+
|
|
32
|
+
### 1. Consultas em Modo Sandbox (Sem Custo)
|
|
33
|
+
|
|
34
|
+
Ideal para testes locais, ambientes de integracao continua e desenvolvimento:
|
|
35
|
+
|
|
36
|
+
```python
|
|
37
|
+
from grid402 import Grid402Client
|
|
38
|
+
|
|
39
|
+
# Inicializa o cliente apontando para o ambiente de testes gratuito
|
|
40
|
+
client = Grid402Client(sandbox=True)
|
|
41
|
+
|
|
42
|
+
# Consulta cadastral de Pessoa Juridica na Receita Federal
|
|
43
|
+
cnpj_data = client.get_cnpj("00.000.000/0001-91")
|
|
44
|
+
print("Razao Social:", cnpj_data.get("razao_social"))
|
|
45
|
+
|
|
46
|
+
# Resolucao de endereco postal e codigo IBGE
|
|
47
|
+
cep_data = client.get_cep("01310-100")
|
|
48
|
+
print("Logradouro:", cep_data.get("logradouro"), "-", cep_data.get("localidade"))
|
|
49
|
+
|
|
50
|
+
# Cotacoes fiduciarias oficiais
|
|
51
|
+
forex_data = client.get_forex()
|
|
52
|
+
print("USD para BRL:", forex_data.get("USD", {}).get("bid"))
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
---
|
|
56
|
+
|
|
57
|
+
### 2. Tratamento Estruturado de HTTP 402
|
|
58
|
+
|
|
59
|
+
Quando chamado sem comprovante de pagamento, o Grid402 retorna uma resposta estruturada contendo o desafio com pre-visualizacao parcial dos dados (teaser data):
|
|
60
|
+
|
|
61
|
+
```python
|
|
62
|
+
from grid402 import Grid402Client, Grid402PaymentRequiredError
|
|
63
|
+
|
|
64
|
+
# Cliente com raise_for_payment ativado
|
|
65
|
+
client = Grid402Client(raise_for_payment=True)
|
|
66
|
+
|
|
67
|
+
try:
|
|
68
|
+
dados = client.get_cnpj("00000000000191")
|
|
69
|
+
except Grid402PaymentRequiredError as erro:
|
|
70
|
+
print("Desafio recebido:")
|
|
71
|
+
print("Valor exigido:", erro.price_usdc, erro.token)
|
|
72
|
+
print("Carteira recebedora:", erro.recipient)
|
|
73
|
+
print("Rede:", erro.network)
|
|
74
|
+
print("Dados parciais (amostra gratuita):", erro.preview_data)
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
---
|
|
78
|
+
|
|
79
|
+
### 3. Utilizacao com Coinbase AgentKit e Auto-Liquidacao
|
|
80
|
+
|
|
81
|
+
Agentes autonomos equipados com carteiras CDP na rede Base podem liquidar chamadas M2M (Machine-to-Machine) de forma transparente:
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from grid402 import Grid402ActionProvider
|
|
85
|
+
|
|
86
|
+
# Provedor compativel com Coinbase AgentKit
|
|
87
|
+
provider = Grid402ActionProvider()
|
|
88
|
+
|
|
89
|
+
# Ao fornecer a instancia de carteira CDP do agente (wallet_provider),
|
|
90
|
+
# o provedor detecta o 402, transfere o USDC e repassa os dados completos
|
|
91
|
+
resultado = provider.query_cnpj("00000000000191", wallet_provider=meu_wallet_provider)
|
|
92
|
+
print("Dados completos:", resultado)
|
|
93
|
+
print("Comprovante on-chain:", resultado.get("_x402_settlement"))
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
---
|
|
97
|
+
|
|
98
|
+
### 4. Schemas Tipados Pydantic
|
|
99
|
+
|
|
100
|
+
Para fluxos de trabalho tipados e validacao antecipada:
|
|
101
|
+
|
|
102
|
+
```python
|
|
103
|
+
from grid402 import CnpjInput, CepInput, DnsInput, SslInput, AsnInput, IndicatorsInput, HolidaysInput
|
|
104
|
+
|
|
105
|
+
# Validacao de entrada antes do envio
|
|
106
|
+
payload_cnpj = CnpjInput(cnpj="00.000.000/0001-91")
|
|
107
|
+
payload_cep = CepInput(code="01310100")
|
|
108
|
+
payload_dns = DnsInput(domain="base.org")
|
|
109
|
+
payload_holidays = HolidaysInput(year=2026)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Catalogo de Ferramentas
|
|
115
|
+
|
|
116
|
+
| Metodo | Descricao | Preco Base (USDC) |
|
|
117
|
+
|---|---|---|
|
|
118
|
+
| `get_summary()` | Resumo operacional consolidado de saude | Gratuito |
|
|
119
|
+
| `get_forex()` | Cotacoes cambiais oficiais de USD, EUR e GBP para BRL | 0.0005 |
|
|
120
|
+
| `get_crypto(symbol)` | Precos spot de BTC, ETH, SOL e USDC | 0.0005 |
|
|
121
|
+
| `get_dns(domain)` | Resolucao DNS com registros A, AAAA, MX, TXT, NS e CNAME | 0.0005 |
|
|
122
|
+
| `get_ssl(host)` | Inspecao e auditoria de certificado TLS e SSL na porta 443 | 0.0005 |
|
|
123
|
+
| `get_asn(ip)` | Inteligencia de roteamento BGP, bloco alocado e ASN | 0.0005 |
|
|
124
|
+
| `get_cep(code)` | Consulta de logradouro postal brasileiro e codigo IBGE | 0.0005 |
|
|
125
|
+
| `get_cnpj(cnpj)` | Dados cadastrais completos de PJ na Receita Federal | 0.0020 |
|
|
126
|
+
| `get_indicators()` | Indicadores macroeconomicos oficiais (Selic meta e diaria, CDI anual e IPCA) | 0.0005 |
|
|
127
|
+
| `get_holidays(year)` | Calendario oficial de feriados nacionais e bancarios ANBIMA | 0.0005 |
|
|
128
|
+
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## Licenca
|
|
132
|
+
|
|
133
|
+
Distribuido sob os termos da licenca MIT. Consulte o arquivo `LICENSE` para detalhes.
|
|
134
|
+
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Grid402 Python SDK - Biblioteca oficial para a Internet Agente e Micropagamentos HTTP 402.
|
|
3
|
+
|
|
4
|
+
Suporte para Python 3.9+, Coinbase Developer Platform (CDP) AgentKit,
|
|
5
|
+
LangChain, CrewAI e modo Sandbox gratuito.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from grid402.agentkit import Grid402ActionProvider
|
|
9
|
+
from grid402.client import DEFAULT_ENDPOINT, Grid402Client
|
|
10
|
+
from grid402.exceptions import Grid402Error, Grid402PaymentRequiredError
|
|
11
|
+
from grid402.models import (
|
|
12
|
+
AsnInput,
|
|
13
|
+
CepInput,
|
|
14
|
+
CnpjInput,
|
|
15
|
+
CryptoInput,
|
|
16
|
+
DnsInput,
|
|
17
|
+
EconomicIndicators,
|
|
18
|
+
HolidayItem,
|
|
19
|
+
HolidaysInput,
|
|
20
|
+
HolidaysResponse,
|
|
21
|
+
IndicatorsResponse,
|
|
22
|
+
SettlementInfo,
|
|
23
|
+
SslInput,
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
__version__ = "2.2.0"
|
|
27
|
+
__author__ = "Grid402 Team"
|
|
28
|
+
__license__ = "MIT"
|
|
29
|
+
|
|
30
|
+
__all__ = [
|
|
31
|
+
"Grid402Client",
|
|
32
|
+
"Grid402ActionProvider",
|
|
33
|
+
"Grid402Error",
|
|
34
|
+
"Grid402PaymentRequiredError",
|
|
35
|
+
"CnpjInput",
|
|
36
|
+
"CepInput",
|
|
37
|
+
"DnsInput",
|
|
38
|
+
"SslInput",
|
|
39
|
+
"AsnInput",
|
|
40
|
+
"CryptoInput",
|
|
41
|
+
"HolidaysInput",
|
|
42
|
+
"EconomicIndicators",
|
|
43
|
+
"IndicatorsResponse",
|
|
44
|
+
"HolidayItem",
|
|
45
|
+
"HolidaysResponse",
|
|
46
|
+
"SettlementInfo",
|
|
47
|
+
"DEFAULT_ENDPOINT",
|
|
48
|
+
"__version__",
|
|
49
|
+
]
|
|
50
|
+
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Grid402 Action Provider para Coinbase AgentKit, LangChain e CrewAI.
|
|
3
|
+
|
|
4
|
+
Permite que agentes autonomos com carteiras CDP (Coinbase Developer Platform)
|
|
5
|
+
na rede Base consultem dados cadastrais e utilitarios de rede com auto-liquidacao x402.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any, Dict, Optional
|
|
9
|
+
import json
|
|
10
|
+
import ssl
|
|
11
|
+
import urllib.error
|
|
12
|
+
import urllib.parse
|
|
13
|
+
import urllib.request
|
|
14
|
+
|
|
15
|
+
from grid402.client import DEFAULT_ENDPOINT
|
|
16
|
+
from grid402.models import AsnInput, CepInput, CnpjInput, CryptoInput, DnsInput, SslInput
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
GRID402_ORACLE_WALLET = "0xa31c31069c43ac1c0075a93c325b0dcd7744356c"
|
|
20
|
+
BASE_USDC_CONTRACT = "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
class Grid402ActionProvider:
|
|
24
|
+
"""
|
|
25
|
+
Provedor de acoes do Grid402 compativel com Coinbase AgentKit, LangChain e CrewAI.
|
|
26
|
+
|
|
27
|
+
Gerencia o ciclo de vida completo de micropagamentos x402 de forma autonoma,
|
|
28
|
+
detectando desafios HTTP 402, efetuando a transferencia de USDC on-chain
|
|
29
|
+
na Base e reenviando a requisicao com o comprovante criptografico.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, base_url: str = DEFAULT_ENDPOINT, sandbox: bool = False):
|
|
33
|
+
"""
|
|
34
|
+
Inicializa o provedor de acoes Grid402.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
base_url: URL base da API do Grid402.
|
|
38
|
+
sandbox: Se True, opera em modo Sandbox gratuito sem consumir USDC real.
|
|
39
|
+
"""
|
|
40
|
+
self.base_url = base_url.rstrip("/")
|
|
41
|
+
self.sandbox = sandbox
|
|
42
|
+
|
|
43
|
+
def _get_ssl_context(self) -> ssl.SSLContext:
|
|
44
|
+
ctx = ssl.create_default_context()
|
|
45
|
+
if "hostingersite.com" in self.base_url:
|
|
46
|
+
ctx.check_hostname = False
|
|
47
|
+
ctx.verify_mode = ssl.CERT_NONE
|
|
48
|
+
return ctx
|
|
49
|
+
|
|
50
|
+
def _execute_with_settlement(
|
|
51
|
+
self,
|
|
52
|
+
path: str,
|
|
53
|
+
params: Optional[Dict[str, Any]] = None,
|
|
54
|
+
wallet_provider: Any = None,
|
|
55
|
+
) -> Dict[str, Any]:
|
|
56
|
+
"""
|
|
57
|
+
Executa a requisicao HTTP com auto-liquidacao de desafio x402.
|
|
58
|
+
|
|
59
|
+
Se o endpoint retornar HTTP 402 e um wallet_provider estiver disponivel,
|
|
60
|
+
executa a transferencia de micropagamento em USDC na Base e repete a chamada.
|
|
61
|
+
"""
|
|
62
|
+
filtered_params = {k: v for k, v in (params or {}).items() if v is not None}
|
|
63
|
+
query_string = urllib.parse.urlencode(filtered_params)
|
|
64
|
+
|
|
65
|
+
url = f"{self.base_url}{path}"
|
|
66
|
+
if query_string:
|
|
67
|
+
url += f"?{query_string}"
|
|
68
|
+
|
|
69
|
+
headers = {
|
|
70
|
+
"Accept": "application/json",
|
|
71
|
+
"User-Agent": "Grid402-CoinbaseAgentKit-Python/1.0",
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if self.sandbox:
|
|
75
|
+
headers["X-Payment"] = "demo"
|
|
76
|
+
|
|
77
|
+
req = urllib.request.Request(url, headers=headers)
|
|
78
|
+
ctx = self._get_ssl_context()
|
|
79
|
+
|
|
80
|
+
# 1. Primeira tentativa de requisicao
|
|
81
|
+
try:
|
|
82
|
+
with urllib.request.urlopen(req, context=ctx, timeout=10) as response:
|
|
83
|
+
return json.loads(response.read().decode("utf-8"))
|
|
84
|
+
except urllib.error.HTTPError as exc:
|
|
85
|
+
raw_body = exc.read().decode("utf-8")
|
|
86
|
+
try:
|
|
87
|
+
challenge = json.loads(raw_body)
|
|
88
|
+
except Exception:
|
|
89
|
+
challenge = {"error": raw_body, "status_code": exc.code}
|
|
90
|
+
|
|
91
|
+
# 2. Se retornou HTTP 402 Payment Required
|
|
92
|
+
if exc.code == 402:
|
|
93
|
+
# Se temos wallet_provider e nao estamos no sandbox, auto-liquida on-chain
|
|
94
|
+
if wallet_provider is not None and not self.sandbox:
|
|
95
|
+
price_usdc = challenge.get("price_usdc", "0.0005")
|
|
96
|
+
recipient = challenge.get("recipient_wallet", GRID402_ORACLE_WALLET)
|
|
97
|
+
|
|
98
|
+
try:
|
|
99
|
+
# Executa transferencia de USDC na Base usando a carteira CDP
|
|
100
|
+
transfer_result = wallet_provider.transfer(
|
|
101
|
+
to=recipient,
|
|
102
|
+
amount=price_usdc,
|
|
103
|
+
asset_id="usdc",
|
|
104
|
+
)
|
|
105
|
+
tx_hash = getattr(transfer_result, "transaction_hash", str(transfer_result))
|
|
106
|
+
|
|
107
|
+
# Reenvia com cabecalho X-Payment
|
|
108
|
+
headers["X-Payment"] = tx_hash
|
|
109
|
+
retry_req = urllib.request.Request(url, headers=headers)
|
|
110
|
+
with urllib.request.urlopen(retry_req, context=ctx, timeout=10) as retry_res:
|
|
111
|
+
data = json.loads(retry_res.read().decode("utf-8"))
|
|
112
|
+
data["_x402_settlement"] = {
|
|
113
|
+
"settled": True,
|
|
114
|
+
"tx_hash": tx_hash,
|
|
115
|
+
"price_usdc": price_usdc,
|
|
116
|
+
"network": "Base",
|
|
117
|
+
"token": "USDC",
|
|
118
|
+
}
|
|
119
|
+
return data
|
|
120
|
+
except Exception as pay_err:
|
|
121
|
+
challenge["payment_error"] = str(pay_err)
|
|
122
|
+
challenge["payment_required"] = True
|
|
123
|
+
return challenge
|
|
124
|
+
|
|
125
|
+
challenge["payment_required"] = True
|
|
126
|
+
return challenge
|
|
127
|
+
raise
|
|
128
|
+
|
|
129
|
+
def get_summary(self) -> Dict[str, Any]:
|
|
130
|
+
"""Resumo operacional consolidado e disponibilidade do hub Grid402 (gratuito)."""
|
|
131
|
+
return self._execute_with_settlement("/status")
|
|
132
|
+
|
|
133
|
+
def query_forex(self, wallet_provider: Any = None) -> Dict[str, Any]:
|
|
134
|
+
"""Consulta cotacoes fiduciarias de USD, EUR e GBP para BRL em tempo real."""
|
|
135
|
+
return self._execute_with_settlement("/api/v1/forex", {}, wallet_provider)
|
|
136
|
+
|
|
137
|
+
def query_crypto(
|
|
138
|
+
self, symbol: Optional[str] = None, wallet_provider: Any = None
|
|
139
|
+
) -> Dict[str, Any]:
|
|
140
|
+
"""Consulta precos de mercado spot de criptoativos em USD e BRL."""
|
|
141
|
+
params = {"symbol": symbol} if symbol else {}
|
|
142
|
+
return self._execute_with_settlement("/api/v1/crypto", params, wallet_provider)
|
|
143
|
+
|
|
144
|
+
def query_dns(self, domain: str, wallet_provider: Any = None) -> Dict[str, Any]:
|
|
145
|
+
"""Executa resolucao autoritativa de registros DNS para qualquer dominio."""
|
|
146
|
+
return self._execute_with_settlement("/api/v1/dns", {"domain": domain}, wallet_provider)
|
|
147
|
+
|
|
148
|
+
def query_ssl(self, host: str, wallet_provider: Any = None) -> Dict[str, Any]:
|
|
149
|
+
"""Inspeciona e audita certificado TLS e SSL na porta 443 de um host."""
|
|
150
|
+
return self._execute_with_settlement("/api/v1/ssl", {"host": host}, wallet_provider)
|
|
151
|
+
|
|
152
|
+
def query_asn(self, ip: Optional[str] = None, wallet_provider: Any = None) -> Dict[str, Any]:
|
|
153
|
+
"""Consulta inteligencia de rede BGP, numero de ASN e organizacao titular."""
|
|
154
|
+
params = {"ip": ip} if ip else {}
|
|
155
|
+
return self._execute_with_settlement("/api/v1/asn", params, wallet_provider)
|
|
156
|
+
|
|
157
|
+
def query_cep(self, code: str, wallet_provider: Any = None) -> Dict[str, Any]:
|
|
158
|
+
"""Consulta endereco postal brasileiro e codigo oficial IBGE por CEP."""
|
|
159
|
+
return self._execute_with_settlement("/api/v1/cep", {"code": code}, wallet_provider)
|
|
160
|
+
|
|
161
|
+
def query_cnpj(self, cnpj: str, wallet_provider: Any = None) -> Dict[str, Any]:
|
|
162
|
+
"""Consulta dados cadastrais de Pessoa Juridica na Receita Federal."""
|
|
163
|
+
return self._execute_with_settlement("/api/v1/cnpj", {"cnpj": cnpj}, wallet_provider)
|
|
164
|
+
|
|
165
|
+
def query_indicators(self, wallet_provider: Any = None) -> Dict[str, Any]:
|
|
166
|
+
"""Consulta taxas oficiais Selic meta e diaria, CDI anual e diario, IPCA 12m e mensal."""
|
|
167
|
+
return self._execute_with_settlement("/api/v1/indicators", {}, wallet_provider)
|
|
168
|
+
|
|
169
|
+
def query_holidays(
|
|
170
|
+
self, year: Optional[int] = None, wallet_provider: Any = None
|
|
171
|
+
) -> Dict[str, Any]:
|
|
172
|
+
"""Consulta o calendario oficial de feriados nacionais e dias sem expediente bancario."""
|
|
173
|
+
params = {"year": year} if year is not None else {}
|
|
174
|
+
return self._execute_with_settlement("/api/v1/holidays", params, wallet_provider)
|
|
175
|
+
|
|
176
|
+
# Aliases no padrao snake_case das ferramentas MCP
|
|
177
|
+
get_cnpj = query_cnpj
|
|
178
|
+
get_cep = query_cep
|
|
179
|
+
get_forex = query_forex
|
|
180
|
+
get_crypto = query_crypto
|
|
181
|
+
get_dns = query_dns
|
|
182
|
+
get_ssl = query_ssl
|
|
183
|
+
get_asn = query_asn
|
|
184
|
+
get_indicators = query_indicators
|
|
185
|
+
get_holidays = query_holidays
|
|
186
|
+
|