Skip to main content
ClaudeWave
ToolsRegistry oficial0 estrellas0 forksPythonMITActualizado today
ClaudeWave Trust Score
77/100
Trusted
Passed
  • Open-source license (MIT)
  • Actively maintained (<30d)
  • Documented (README)
Flags
  • !No description
Last scanned: 9/17/2026
Get started
Method: Clone
Terminal
git clone https://github.com/Ensi81/Avel
1. Clone the repository.
2. Follow the README for installation and usage instructions.
Casos de uso

Resumen de Tools

# agent-interchange

SDK Python per **AVEL** (Agent Verification Layer) — verifica
identità/reputazione di chi paga e chi riceve, su qualunque metodo di
pagamento, senza mai custodire denaro. Il server è closed-source; questo
pacchetto è lo strato client, pensato per essere pubblico e riusabile
(licenza MIT). Standalone — nessuna dipendenza dal codice del server,
solo `httpx`, `eth-account` e l'URL di un'istanza raggiungibile
(`https://aisrail.fly.dev`).

<!-- mcp-name: io.github.Ensi81/avel -->

## Install

```bash
pip install -e .
```

## Uso

```python
from agent_interchange import InterchangeClient

client = InterchangeClient("https://aisrail.fly.dev")
result = client.verify(
    payer_address=agent_a_address,
    payee_id="merchant-42",
    amount=25.0,
    currency="EUR",
    private_key=agent_a_private_key,
    fee_payment_method_id="pm_...",   # con cosa si paga LA VERIFICA
)
```

**Il pagamento fra i due agenti non passa da qui.** Questa chiamata dice
soltanto se è sicuro procedere; poi l'agente paga sul rail che già usa.
Noi incassiamo solo la provvigione per il controllo eseguito (1%
dell'importo verificato, minimo 0,50 su carta) — **dovuta anche su un
verdetto DENIED**, se la firma di chi chiama è comunque valida: è il
prezzo del controllo, non dell'esito.

Tre esiti possibili:

| Risposta | Significato |
|---|---|
| `verdict: "APPROVED"` | Controllo superato, provvigione incassata: si procede |
| `verdict: "DENIED"` | Non procedere. Provvigione comunque dovuta se la firma di chi chiama è valida — gratuito solo quando non lo è (nessuno da addebitare con certezza) |
| `verdict_withheld: true` | Verifica eseguita ma provvigione non ancora incassata: il verdetto (APPROVED o DENIED) resta trattenuto finché non si paga |

`private_key` è la chiave EVM dell'agente (mai la nostra). Il primo uso
autenticato lega quell'identità all'indirizzo che firma
(trust-on-first-use): ogni chiamata successiva deve firmare con la
STESSA chiave. Nessuna registrazione preventiva.

`verify()` usa `protocol="native"`. Se l'agente sta già pagando con
x402, AP2 o MPP non serve una seconda firma: si manda la prova che ha
già prodotto per il pagamento — un esempio per ciascun protocollo è in
`scripts/protocol_adapters_demo.py`.

### Verifica simmetrica di B

Se il venditore (B) dichiara un indirizzo (`payee_address`), deve anche
provare di controllarlo — altrimenti il verdetto è negato. La firma va
calcolata da B (o da chi negozia per suo conto) su
`build_counterparty_message(payer_address, payee_id, amount, currency,
nonce)` e passata come `payee_signature`:

```python
from agent_interchange.client import build_counterparty_message

message = build_counterparty_message(payer_address, payee_id, amount, currency, nonce)
payee_signature = "0x" + Account.sign_message(encode_defunct(text=message), private_key=b_private_key).signature.hex()

result = client.verify(
    payer_address=a_address, payee_id="merchant-42", amount=25.0, currency="EUR",
    private_key=a_private_key, nonce=nonce,
    payee_address=b_address, payee_signature=payee_signature,
)
```

### Modello B-driven (protocollo `challenge`)

Più vicino a come funzionano davvero x402/MPP: è il venditore (B) a
fissare prezzo e termini e a firmarli per primo, l'acquirente (A) li
accetta firmando lo stesso testo.

```python
# Lato B — nessuna chiamata di rete, va consegnato ad A fuori banda
challenge = client.issue_challenge(
    payee_address=b_address, payee_id="merchant-42", amount=25.0, currency="EUR",
    private_key=b_private_key, ttl_seconds=600,
)

# Lato A — accetta il challenge e chiede il verdetto in un colpo solo
result = client.verify_challenge(
    challenge, payer_address=a_address, private_key=a_private_key,
    fee_payment_method_id="pm_...",   # o fee_method="x402" per pagare in stablecoin
)
```

Il challenge è valido una sola volta per la transazione esatta che lo
accetta: un ritentativo identico (necessario per completare il
pagamento della commissione dopo un 402) resta ammesso, un riuso con
termini diversi no.

### Verdetto bidirezionale

Entrambe le parti possono leggere l'esito di una transazione specifica
— non solo chi ha chiamato `verify()`/`verify_challenge()`:

```python
verdetto = client.get_verdict(
    payee_address=b_address, nonce=nonce,
    address=b_address, private_key=b_private_key,   # o quella di A
)
```

Richiede una firma che provi di essere il pagante o il ricevente di
quella transazione — a differenza dello storico aggregato
(`GET /ais/reputation/{address}`, pubblico), il dettaglio di una singola
transazione non lo è.

### Caso marketplace

Quando `payee_id`/`payee_address` sono una vetrina e non chi fornisce
davvero il prodotto/servizio, `verify()` accetta anche
`sub_merchant_address`/`sub_merchant_signature` (stesso principio di B:
la firma va calcolata su `build_sub_merchant_message(payer_address,
payee_id, amount, currency, nonce, sub_merchant_address)`). Se
dichiarato, la sua reputazione (`sub_merchant_reputation` nella
risposta) entra nel verdetto tanto quanto quella di B.

Vedi `example.py` per una versione eseguibile del flusso base.

## Metodi degli Agent Vaults — SPENTI

`pay()`, `get_balance()`, `deposit()` e `withdraw()` appartengono al
modello precedente, in cui il servizio custodiva un saldo interno. Il
server risponde ora `410` a quegli endpoint: **non custodiamo più
denaro**, nemmeno per un istante. Il codice resta ed è riattivabile lato
server con `AGENT_VAULTS_ENABLED=true`; la documentazione qui sotto è
conservata come riferimento storico.

## `InterchangeClient`

- **`verify(payer_address, payee_id, amount, currency, private_key, nonce="", payee_address=None, payee_signature=None, sub_merchant_address=None, sub_merchant_signature=None, fee_payment_method_id=None)`**
  → `dict`. Il metodo da usare per il modello "A dichiara, B conferma".
  Firma EIP-191 sul testo canonico della transazione, chiede il verdetto
  e paga la provvigione. Un `402` non è un errore ma una risposta
  prevista ("verifica passata, ora paga"): viene restituito, non
  sollevato.

- **`issue_challenge(payee_address, payee_id, amount, currency, private_key, ttl_seconds=600)`**
  → `dict`. Lato B (venditore), modello B-driven: emette e firma un
  challenge vincolante, nessuna chiamata di rete. Il risultato va
  consegnato ad A fuori banda.

- **`verify_challenge(challenge, payer_address, private_key, fee_payment_method_id=None, fee_method=None)`**
  → `dict`. Lato A (acquirente): accetta il challenge di `issue_challenge()`
  e chiede il verdetto in un'unica chiamata.

- **`get_verdict(payee_address, nonce, address, private_key)`**
  → `dict`. Verdetto bidirezionale: legge l'esito di una transazione
  specifica, utilizzabile da entrambe le parti coinvolte. Solleva
  `InterchangeAPIError` (403) se `address` non è né il pagante né il
  ricevente di quella transazione, (404) se non esiste alcun verdetto
  registrato per quel `payee_address`/`nonce`.

- **`get_agent_reputation` non è un metodo del client** — è pubblico e
  senza autenticazione: `GET {base_url}/ais/reputation/{address}` con
  una semplice richiesta HTTP.

- ~~**`pay(payer_ref, payee_ref, amount, private_key, currency="USDC", task_id=None)`**~~ *(spento, 410)*
  → `PaymentResult`. `private_key` signs an EIP-191 message binding this
  exact transaction (trust-on-first-use — see Usage above); mandatory
  since the Interchange added wallet authentication to `/pay`.
  Auto-derives `agent_request_id` from `task_id` +
  the call's own parameters (see `client._derive_request_id`) — pass your
  agent framework's own task/run id so a genuine retry (same task_id,
  same arguments) is safely idempotent, while a different payment under
  the same task_id never false-collides with it. Omitting `task_id`
  still works but loses the retry-safety property (a fresh random id is
  used, so a real retry would be treated as a brand new transaction).

  Raises:
  - `InsufficientBalanceError` — payer's balance can't cover amount + fee.
  - `RequestConflictError` — HTTP 409: the derived id was already used
    for *different* content (a possible replay/hijack of a captured
    payment proof by untrusted middleware — rejected, not executed) or
    was reserved but never completed (never retried automatically).
  - `InterchangeAPIError` — any other non-2xx response, or the
    Interchange being unreachable. 401 means `private_key` doesn't
    match the signature; 403 means `payer_ref` is already bound to a
    different address (not this key).

  A risk-score `DENY` (as opposed to an insufficient-balance one) is
  *not* raised — it comes back as a normal `PaymentResult` with
  `.success == False`; check `.decision` / `.reasons` for why.

- **`get_balance(agent_ref, private_key)`** → `dict[str, int]`, atomic
  units per currency, e.g. `{"USDC": 500000}`. `private_key` proves
  control of `agent_ref` (same trust-on-first-use binding as `pay()`);
  allowed with any key only if `agent_ref` was never used in `pay()`/
  `withdraw()` yet.

- **`withdraw(agent_ref, amount_usdc, payout_address, private_key, task_id=None)`**
  → `dict`. `private_key` is `agent_ref`'s own key, proving it
  controls the balance being withdrawn — the Interchange's own treasury
  still signs and pays out on-chain, `private_key` here only
  authenticates the withdrawal request itself. Same `task_id`
  derivation and exception contract as `pay()` (`InsufficientBalanceError`
  on HTTP 402, `RequestConflictError` on 409, 401/403 same meaning as
  `pay()`'s); any other non-2xx (e.g. 403 for an unwhitelisted
  platform-treasury withdrawal) raises `InterchangeAPIError`.

- **`await deposit(agent_ref, amount_usdc, private_key, task_id=None)`**
  → `dict`. **Async** (unlike the other three methods) and needs the
  `deposit` extra — `pip install agent-interchange[deposit]` — because
  it signs a real x402 payment with the depositing agent's own key.
  Calling it without the extra installed raises `InterchangeAPIError`
  (not an ImportError) with ins

Lo que la gente pregunta sobre Avel

¿Qué es Ensi81/Avel?

+

Ensi81/Avel es tools para el ecosistema de Claude AI con 0 estrellas en GitHub.

¿Cómo se instala Avel?

+

Puedes instalar Avel clonando el repositorio (https://github.com/Ensi81/Avel) o siguiendo las instrucciones del README en GitHub. ClaudeWave también te ofrece bloques de instalación rápida en esta misma página.

¿Es seguro usar Ensi81/Avel?

+

Nuestro agente de seguridad ha analizado Ensi81/Avel y le ha asignado un Trust Score de 77/100 (tier: Trusted). Revisa el desglose completo de comprobaciones superadas y flags en esta página.

¿Quién mantiene Ensi81/Avel?

+

Ensi81/Avel es mantenido por Ensi81. La última actividad registrada en GitHub es del 2026-09-16, con 0 issues abiertos.

¿Hay alternativas a Avel?

+

Sí. En ClaudeWave puedes explorar tools similares en /categories/tools, ordenados por popularidad o actividad reciente.

Despliega Avel en tu cloud

Lleva este repo a producción en minutos. Cada plataforma genera su propio entorno con variables de entorno editables.

¿Mantienes este repo? Añade un badge a tu README

Pega el badge en tu README de GitHub para mostrar que está auditado por ClaudeWave. Cada badge enlaza de vuelta a esta página y muestra el Trust Score actual.

Featured on ClaudeWave: Ensi81/Avel
[![Featured on ClaudeWave](https://claudewave.com/api/badge/ensi81-avel)](https://claudewave.com/repo/ensi81-avel)
<a href="https://claudewave.com/repo/ensi81-avel"><img src="https://claudewave.com/api/badge/ensi81-avel" alt="Featured on ClaudeWave: Ensi81/Avel" width="320" height="64" /></a>

Más Tools

Alternativas a Avel