grid402 2.2.0__py3-none-any.whl

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/__init__.py ADDED
@@ -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
+
grid402/agentkit.py ADDED
@@ -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
+
grid402/client.py ADDED
@@ -0,0 +1,156 @@
1
+ """
2
+ Cliente HTTP oficial para a API de Micropagamentos Grid402.
3
+ """
4
+
5
+ from typing import Any, Dict, Optional
6
+ import json
7
+ import ssl
8
+ import urllib.error
9
+ import urllib.parse
10
+ import urllib.request
11
+
12
+ from grid402.exceptions import Grid402Error, Grid402PaymentRequiredError
13
+
14
+
15
+ DEFAULT_ENDPOINT = "https://grid402.com.br"
16
+
17
+
18
+ class Grid402Client:
19
+ """
20
+ Cliente Python para consumo das ferramentas públicas do Grid402.
21
+
22
+ Suporta modo de producao na Base Mainnet, modo Sandbox gratuito para testes
23
+ e tratamento estruturado de desafios HTTP 402.
24
+ """
25
+
26
+ def __init__(
27
+ self,
28
+ base_url: str = DEFAULT_ENDPOINT,
29
+ sandbox: bool = False,
30
+ payment_tx_hash: Optional[str] = None,
31
+ timeout: int = 10,
32
+ raise_for_payment: bool = False,
33
+ ):
34
+ """
35
+ Inicializa uma nova instancia do Grid402Client.
36
+
37
+ Args:
38
+ base_url: Endereco base da API do Grid402.
39
+ sandbox: Se True, ativa o modo Sandbox gratuito para homologacao sem custo.
40
+ payment_tx_hash: Hash de transacao USDC opcional padrao para as requisicoes.
41
+ timeout: Tempo limite em segundos para cada requisicao HTTP.
42
+ raise_for_payment: Se True, lanca Grid402PaymentRequiredError ao receber HTTP 402.
43
+ Se False, retorna o dicionario com o desafio e dados parciais.
44
+ """
45
+ self.base_url = base_url.rstrip("/")
46
+ self.sandbox = sandbox
47
+ self.payment_tx_hash = payment_tx_hash
48
+ self.timeout = timeout
49
+ self.raise_for_payment = raise_for_payment
50
+
51
+ def _get_ssl_context(self) -> ssl.SSLContext:
52
+ ctx = ssl.create_default_context()
53
+ if "hostingersite.com" in self.base_url:
54
+ ctx.check_hostname = False
55
+ ctx.verify_mode = ssl.CERT_NONE
56
+ return ctx
57
+
58
+ def _request(
59
+ self,
60
+ path: str,
61
+ params: Optional[Dict[str, Any]] = None,
62
+ payment_tx_hash: Optional[str] = None,
63
+ ) -> Dict[str, Any]:
64
+ """Executa a requisicao HTTP para a API Grid402."""
65
+ filtered_params = {k: v for k, v in (params or {}).items() if v is not None}
66
+ query_string = urllib.parse.urlencode(filtered_params)
67
+
68
+ url = f"{self.base_url}{path}"
69
+ if query_string:
70
+ url += f"?{query_string}"
71
+
72
+ headers = {
73
+ "Accept": "application/json",
74
+ "User-Agent": "Grid402-Python-SDK/2.2",
75
+ }
76
+
77
+ active_tx_hash = payment_tx_hash or self.payment_tx_hash
78
+ if active_tx_hash:
79
+ headers["X-Payment"] = active_tx_hash
80
+ elif self.sandbox:
81
+ headers["X-Payment"] = "demo"
82
+
83
+ req = urllib.request.Request(url, headers=headers)
84
+ ctx = self._get_ssl_context()
85
+
86
+ try:
87
+ with urllib.request.urlopen(req, context=ctx, timeout=self.timeout) as response:
88
+ return json.loads(response.read().decode("utf-8"))
89
+ except urllib.error.HTTPError as exc:
90
+ raw_body = exc.read().decode("utf-8")
91
+ try:
92
+ error_data = json.loads(raw_body)
93
+ except Exception:
94
+ error_data = {"error": raw_body, "status_code": exc.code}
95
+
96
+ if exc.code == 402:
97
+ if self.raise_for_payment:
98
+ raise Grid402PaymentRequiredError(error_data) from exc
99
+ error_data["payment_required"] = True
100
+ return error_data
101
+
102
+ raise Grid402Error(
103
+ f"Erro na API Grid402 (HTTP {exc.code}): {error_data.get('error') or raw_body}"
104
+ ) from exc
105
+ except urllib.error.URLError as exc:
106
+ raise Grid402Error(f"Falha de conexao com {self.base_url}: {exc.reason}") from exc
107
+
108
+ def get_summary(self) -> Dict[str, Any]:
109
+ """Consulta o resumo e status operacional consolidado do Grid402 (gratuito)."""
110
+ return self._request("/status")
111
+
112
+ def get_forex(self, payment_tx_hash: Optional[str] = None) -> Dict[str, Any]:
113
+ """Consulta cotacoes fiduciarias oficiais em tempo real de USD, EUR e GBP para BRL."""
114
+ return self._request("/api/v1/forex", payment_tx_hash=payment_tx_hash)
115
+
116
+ def get_crypto(
117
+ self, symbol: Optional[str] = None, payment_tx_hash: Optional[str] = None
118
+ ) -> Dict[str, Any]:
119
+ """Consulta precos de mercado spot de criptoativos em tempo real."""
120
+ params = {"symbol": symbol} if symbol else {}
121
+ return self._request("/api/v1/crypto", params=params, payment_tx_hash=payment_tx_hash)
122
+
123
+ def get_dns(self, domain: str, payment_tx_hash: Optional[str] = None) -> Dict[str, Any]:
124
+ """Executa resolucao DNS autoritativa de registros A, AAAA, MX, TXT, NS e CNAME."""
125
+ return self._request("/api/v1/dns", params={"domain": domain}, payment_tx_hash=payment_tx_hash)
126
+
127
+ def get_ssl(self, host: str, payment_tx_hash: Optional[str] = None) -> Dict[str, Any]:
128
+ """Inspeciona e valida o certificado TLS e SSL na porta 443 de um host remoto."""
129
+ return self._request("/api/v1/ssl", params={"host": host}, payment_tx_hash=payment_tx_hash)
130
+
131
+ def get_asn(
132
+ self, ip: Optional[str] = None, payment_tx_hash: Optional[str] = None
133
+ ) -> Dict[str, Any]:
134
+ """Consulta inteligencia de rede BGP, identificando numero de ASN e organizacao."""
135
+ params = {"ip": ip} if ip else {}
136
+ return self._request("/api/v1/asn", params=params, payment_tx_hash=payment_tx_hash)
137
+
138
+ def get_cep(self, code: str, payment_tx_hash: Optional[str] = None) -> Dict[str, Any]:
139
+ """Consulta a base publica de enderecamento postal brasileiro e codigo IBGE por CEP."""
140
+ return self._request("/api/v1/cep", params={"code": code}, payment_tx_hash=payment_tx_hash)
141
+
142
+ def get_cnpj(self, cnpj: str, payment_tx_hash: Optional[str] = None) -> Dict[str, Any]:
143
+ """Consulta dados cadastrais publicos de Pessoa Juridica na Receita Federal."""
144
+ return self._request("/api/v1/cnpj", params={"cnpj": cnpj}, payment_tx_hash=payment_tx_hash)
145
+
146
+ def get_indicators(self, payment_tx_hash: Optional[str] = None) -> Dict[str, Any]:
147
+ """Consulta indicadores economicos oficiais (Selic, CDI e IPCA) do Banco Central e IBGE."""
148
+ return self._request("/api/v1/indicators", payment_tx_hash=payment_tx_hash)
149
+
150
+ def get_holidays(
151
+ self, year: Optional[int] = None, payment_tx_hash: Optional[str] = None
152
+ ) -> Dict[str, Any]:
153
+ """Consulta calendario oficial de feriados nacionais e bancarios (ANBIMA e Febraban)."""
154
+ params = {"year": year} if year is not None else {}
155
+ return self._request("/api/v1/holidays", params=params, payment_tx_hash=payment_tx_hash)
156
+
grid402/exceptions.py ADDED
@@ -0,0 +1,34 @@
1
+ """
2
+ Excecoes oficiais do SDK Grid402.
3
+ """
4
+
5
+ from typing import Any, Dict, Optional
6
+
7
+
8
+ class Grid402Error(Exception):
9
+ """Excecao base para erros do SDK Grid402."""
10
+ pass
11
+
12
+
13
+ class Grid402PaymentRequiredError(Grid402Error):
14
+ """
15
+ Excecao levantada quando um endpoint do Grid402 retorna HTTP 402 Payment Required.
16
+
17
+ Contem todos os metadados do desafio de pagamento x402 e pre-visualizacao parcial.
18
+ """
19
+
20
+ def __init__(self, challenge: Dict[str, Any], message: Optional[str] = None):
21
+ self.challenge = challenge
22
+ self.price_usdc: str = challenge.get("price_usdc", "0.0005")
23
+ self.recipient: str = challenge.get("recipient_wallet", "")
24
+ self.network: str = challenge.get("network", "Base")
25
+ self.token: str = challenge.get("token", "USDC")
26
+ self.preview_data: Optional[Dict[str, Any]] = challenge.get("preview_data")
27
+ self.payment_details: Optional[Dict[str, Any]] = challenge.get("payment_details")
28
+
29
+ default_msg = (
30
+ f"Pagamento obrigatorio de {self.price_usdc} {self.token} na rede {self.network} "
31
+ f"para a carteira {self.recipient}."
32
+ )
33
+ super().__init__(message or challenge.get("message") or default_msg)
34
+
grid402/models.py ADDED
@@ -0,0 +1,119 @@
1
+ """
2
+ Modelos tipados Pydantic para entradas e saidas do Grid402.
3
+ """
4
+
5
+ from typing import Any, Dict, Optional
6
+ from pydantic import BaseModel, Field
7
+
8
+
9
+ class CnpjInput(BaseModel):
10
+ """Parametros para consulta cadastral de Pessoa Juridica na Receita Federal."""
11
+ cnpj: str = Field(
12
+ ...,
13
+ description="Numero do CNPJ com 14 digitos numericos, com ou sem mascara de pontuacao.",
14
+ examples=["00.000.000/0001-91", "00000000000191"],
15
+ )
16
+
17
+
18
+ class CepInput(BaseModel):
19
+ """Parametros para consulta de endereco postal e codigo IBGE por CEP."""
20
+ code: str = Field(
21
+ ...,
22
+ description="Codigo de CEP brasileiro com 8 digitos numericos, com ou sem hifen.",
23
+ examples=["01310-100", "01310100"],
24
+ )
25
+
26
+
27
+ class DnsInput(BaseModel):
28
+ """Parametros para resolucao DNS autoritativa."""
29
+ domain: str = Field(
30
+ ...,
31
+ description="Nome de dominio da internet para resolucao de registros A, AAAA, MX, TXT, NS e CNAME.",
32
+ examples=["base.org", "ethereum.org"],
33
+ )
34
+
35
+
36
+ class SslInput(BaseModel):
37
+ """Parametros para inspecao e auditoria de certificado TLS e SSL."""
38
+ host: str = Field(
39
+ ...,
40
+ description="Hostname ou dominio para inspecao de certificado TLS na porta 443.",
41
+ examples=["base.org", "google.com"],
42
+ )
43
+
44
+
45
+ class AsnInput(BaseModel):
46
+ """Parametros para consulta de BGP e numero ASN."""
47
+ ip: Optional[str] = Field(
48
+ None,
49
+ description="Endereco IPv4 ou IPv6 a consultar. Se omitido, inspeciona o IP publico requisitante.",
50
+ examples=["1.1.1.1", "8.8.8.8"],
51
+ )
52
+
53
+
54
+ class CryptoInput(BaseModel):
55
+ """Parametros opcionais para cotacao spot de criptoativos."""
56
+ symbol: Optional[str] = Field(
57
+ None,
58
+ description="Simbolo opcional do criptoativo (ex: BTC, ETH, SOL, USDC, BASE).",
59
+ examples=["BTC", "ETH"],
60
+ )
61
+
62
+
63
+ class HolidaysInput(BaseModel):
64
+ """Parametros opcionais para consulta de feriados nacionais e bancarios."""
65
+ year: Optional[int] = Field(
66
+ None,
67
+ description="Ano calendario de 4 digitos entre 1900 e 2100. Se omitido, utiliza o ano corrente.",
68
+ ge=1900,
69
+ le=2100,
70
+ examples=[2026],
71
+ )
72
+
73
+
74
+ class EconomicIndicators(BaseModel):
75
+ selic_target: float = Field(..., description="Taxa Selic meta anual em percentual.")
76
+ selic_daily: float = Field(..., description="Taxa Selic acumulada diaria anualizada.")
77
+ cdi_annual: float = Field(..., description="Taxa CDI anualizada em percentual.")
78
+ cdi_daily: float = Field(..., description="Taxa CDI diaria efetiva em percentual.")
79
+ ipca_12m: float = Field(..., description="IPCA acumulado nos ultimos 12 meses.")
80
+ ipca_monthly: float = Field(..., description="IPCA do ultimo mes fechado.")
81
+ reference_date: str = Field(..., description="Data de referencia dos indicadores diarios.")
82
+ ipca_reference_month: str = Field(..., description="Mes de referencia da divulgacao do IPCA.")
83
+
84
+
85
+ class IndicatorsResponse(BaseModel):
86
+ status: str = Field(..., description="Status da consulta.")
87
+ service: str = Field("indicators", description="Nome do micro-servico.")
88
+ timestamp: str = Field(..., description="Data e hora ISO 8601 da resposta.")
89
+ indicators: EconomicIndicators = Field(..., description="Conjunto de indicadores economicos.")
90
+ source: str = Field(..., description="Fontes oficiais primarias.")
91
+ cached: Optional[bool] = Field(None, description="Indica se os dados foram servidos do cache.")
92
+
93
+
94
+ class HolidayItem(BaseModel):
95
+ date: str = Field(..., description="Data do feriado no formato AAAA-MM-DD.")
96
+ name: str = Field(..., description="Nome oficial do feriado ou celebracao.")
97
+ type: str = Field(..., description="Tipo do feriado: national, banking ou religious.")
98
+ day_of_week: str = Field(..., description="Dia da semana correspondente em portugues.")
99
+ is_banking_holiday: bool = Field(..., description="Indica se nao ha expediente bancario ao publico.")
100
+
101
+
102
+ class HolidaysResponse(BaseModel):
103
+ status: str = Field(..., description="Status da consulta.")
104
+ service: str = Field("holidays", description="Nome do micro-servico.")
105
+ year: int = Field(..., description="Ano calendario consultado.")
106
+ total_holidays: int = Field(..., description="Contagem total de feriados cadastrados no ano.")
107
+ holidays: list[HolidayItem] = Field(..., description="Lista de feriados ordenada cronologicamente.")
108
+ source: str = Field(..., description="Fontes oficiais primarias.")
109
+ cached: Optional[bool] = Field(None, description="Indica se os dados foram servidos do cache.")
110
+
111
+
112
+ class SettlementInfo(BaseModel):
113
+ """Informacoes de liquidacao on-chain de micropagamento x402."""
114
+ settled: bool = Field(True, description="Indica se o pagamento foi liquidado com sucesso.")
115
+ tx_hash: str = Field(..., description="Hash da transacao confirmada na rede Base.")
116
+ price_usdc: str = Field(..., description="Valor pago em USDC.")
117
+ network: str = Field("Base", description="Rede blockchain da liquidacao.")
118
+ token: str = Field("USDC", description="Token utilizado no pagamento.")
119
+
grid402/py.typed ADDED
@@ -0,0 +1 @@
1
+
@@ -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
+
@@ -0,0 +1,11 @@
1
+ grid402/__init__.py,sha256=p1HZHRS9O0uzEnkDmT3AVupBNuNvrz27AIv7QUfPw4s,1115
2
+ grid402/agentkit.py,sha256=omtsTx_HKb9fl8hAUj-FzIP5H1arYT_xJTQb9WTXsrU,8126
3
+ grid402/client.py,sha256=LB5ywWrCw_-uqsAMPr8t_dici3M4CvcBRV2_YSHYJrI,6652
4
+ grid402/exceptions.py,sha256=VLcNcFvMOj4LiacXDaZHgGaFtKSk2QJ_TZ1hwB6WG70,1224
5
+ grid402/models.py,sha256=BqS4IVxc1ya1TDleqoDbul2wNkRXJd_FheNYKVHHYIg,5092
6
+ grid402/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
7
+ grid402-2.2.0.dist-info/licenses/LICENSE,sha256=AygoXt4UY-kO63c6vOPbjBDt_5pr7-fPv8qbaP6kvTk,1078
8
+ grid402-2.2.0.dist-info/METADATA,sha256=c6w1sM9_TL9toCZgp91_Jn36pAXNRPy0h9WDC3quaQc,6453
9
+ grid402-2.2.0.dist-info/WHEEL,sha256=mOdXR9C3wMVov7cSY8PY-XCzo3SmmWCHvGQr5csJoao,91
10
+ grid402-2.2.0.dist-info/top_level.txt,sha256=_7wfocziRC4JW_lvgWdBsKMB-1Uf3gBOiSa3fFSpGEk,8
11
+ grid402-2.2.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.2.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -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
+
@@ -0,0 +1 @@
1
+ grid402