# Especificação do protocolo

Este documento fornece a especificação técnica do Network-Agnostic Secure Payment Instruction Protocol (NASPIP) conforme implementado pela Fluxis e [naspip-go](https://github.com/fluxisus/naspip-go).

## Visão geral

NASPIP define um formato padronizado para instruções de pagamento que podem ser transmitidas e validadas com segurança em qualquer rede de pagamento. Tokens são **PASETO v4 public** (assinados, não criptografados) — qualquer pessoa com a chave pública do emissor pode verificar autenticidade e integridade do payload.

## Estrutura de dados

### Formato do token NASPIP

Um token NASPIP é uma string delimitada por ponto e vírgula envolvendo um token PASETO v4 public:

```
naspip;{key_issuer};{key_id};v4.public.{paseto_token}
```

| Component | Description | Example |
| --------- | ----------- | ------- |
| Prefix | Identificador do protocolo | `naspip` |
| Key issuer (`kis`) | Entidade que emitiu a chave de assinatura | `fluxis.us` |
| Key ID (`kid`) | Identificador da chave de assinatura | `fluxis.qr.dyn.1` |
| PASETO token | Token PASETO v4 public contendo o payload assinado | `v4.public.IhYyMDI...` |

O payload interno PASETO usa claims padrão (`iss`, `sub`, `exp`, `iat`, `kid`, `kis`, `kep`) mais um campo `data` contendo instruções de pagamento ou um payload URL.

### Esquemas de payload

NASPIP suporta dois tipos de payload dentro do campo `data` do token PASETO.

#### Payload de instrução (pagamento direto)

```json
{
  "payment": {
    "id": "180ede28-2968-4ac7-8e81-ca446f201949",
    "address": "0x1234567890abcdef1234567890abcdef12345678",
    "unique_asset_id": "npolygon_t0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359",
    "is_open": false,
    "amount": "49.99",
    "expires_at": 1759397652
  },
  "order": {
    "total": "49.99",
    "coin_code": "USD",
    "description": "Order description",
    "merchant": {
      "name": "Merchant #1",
      "description": "Merchant description"
    },
    "items": []
  }
}
```

#### Payload URL (checkout / instruções diferidas)

```json
{
  "url": "https://api.fluxis.us/v1/pos/{posID}/payment-request-checkout",
  "payment_options": ["npolygon_t0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359"],
  "order": {
    "total": "49.99",
    "coin_code": "USD",
    "merchant": { "name": "Merchant #1" }
  }
}
```

QR codes estáticos de PoS podem omitir `payment_options`; wallets chamam `POST /v1/naspip/read` e a Fluxis resolve instruções buscando a URL quando `payment_options` está ausente.

## Operações criptográficas

NASPIP usa **tokens PASETO v4 public** com chaves Ed25519. Payloads são codificados em protobuf antes de assinar. Na Fluxis, use [naspip-go](https://github.com/fluxisus/naspip-go) ou a REST API — não implemente Ed25519+SHA-256 bruto sobre JSON.

### Assinatura (create)

1. Construir `InstructionPayload` ou `UrlPayload`
2. Codificar payload como protobuf
3. Assinar com PASETO v4 usando a chave privada Ed25519 do emissor
4. Prefixar com `naspip;{kis};{kid};`

TTL padrão do token: **1 hora** para instruções de pagamento; **10 anos** (`87600h`) para payloads somente URL.

### Verificação (read)

1. Dividir token por `;` e validar prefixo `naspip`
2. Resolver chave pública por `kis` + `kid`
3. Verificar assinatura PASETO v4 e claims de expiração
4. Retornar `PasetoCompleteResult` com `payload.data` parseado

### Formato de resposta Fluxis `POST /v1/naspip/read`

```json
{
  "status": "success",
  "data": {
    "version": "v4",
    "purpose": "public",
    "footer": null,
    "payload": {
      "iss": "fluxis.us",
      "sub": "naspip",
      "exp": "2026-12-31T23:59:59.000Z",
      "iat": "2026-01-01T00:00:00.000Z",
      "kid": "fluxis.qr.dyn.1",
      "kis": "fluxis.us",
      "data": { "payment": { "...": "..." } }
    }
  }
}
```

::::warning Divergência no Swagger
OpenAPI atualmente documenta `data` como `PasetoV4PayloadData` plano (`url`, `payment`, `order`). A resposta em runtime é `PasetoCompleteResult` conforme mostrado acima. Consulte `NASPIP_ENHANCEMENTS.md` para a correção planejada.
:::::

## Suporte de redes

Instruções de pagamento referenciam ativos por **`unique_asset_id`** (UAI), não por nome de rede ou chain ID. A Fluxis suporta múltiplas redes — consulte [UAI](/pt/docs/key-concepts/uai) para a lista completa de ativos.

UAIs de exemplo:

| Network | Asset | Example UAI |
| ------- | ----- | ----------- |
| Polygon | USDC | `npolygon_t0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359` |
| Base | USDC | `nbase_t0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913` |
| Avalanche | USDC | `navalanche_t0xB97EF9Ef8734C71904D8002F8b6Bc66Dd9c48a6E` |
| Avalanche | ARGt | `navalanche_t0x2E4e93eCA2E16E4989b894e188B7F7fC0175703B` |
| Arbitrum | USDC | `narbitrum_t0xaf88d065e77c8cC2239327C5EDb3A432268e5831` |
| Arbitrum | USDT | `narbitrum_t0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9` |

## Formato de QR code

Tokens NASPIP são codificados em QR codes como a **string de token bruta** (não uma URI `naspip://`):

```
naspip;fluxis.us;fluxis.qr.dyn.1;v4.public.IhYyMDI...
```

### Especificações do QR code

- **Error Correction**: Level M (15% recovery)
- **Size**: Minimum 256x256 pixels
- **Format**: Standard QR Code (ISO/IEC 18004)

## Versionamento

Tokens NASPIP usam **PASETO v4** (`v4.public.*`). O prefixo delimitador por ponto e vírgula é `naspip`. Mudanças incompatíveis em esquemas de payload são gerenciadas por releases do naspip-go.

## Tratamento de erros

### Códigos de erro da API Fluxis (relacionados ao NASPIP)

| Code | HTTP | Description |
| ---- | ---- | ----------- |
| `MD0006` | 406 | Token NASPIP expirado |
| `GE0003` | 404 | Chave pública expirada |
| `MD0004` | 400 | Dados inválidos (ex.: token ou URL inválidos) |
| `PR0006` | 404 | Nenhuma solicitação de pagamento ativa (PoS caixa; retornado ao resolver payload URL) |

### Formato de resposta de erro

```json
{
  "status": "error",
  "error": {
    "code": "MD0006",
    "message": "NASPIP token expired"
  }
}
```

## Considerações de segurança

### Boas práticas

1. **Gerenciamento de chaves**: A Fluxis gerencia chaves de assinatura; integradores verificam via busca de chave pública (`kis` + `kid`)
2. **Expiração do token**: Tokens de instrução de pagamento expiram após 1 hora por padrão
3. **Validação de valores**: Valide valores no lado do remetente e do receptor
4. **Verificação de ativos**: Confirme que `unique_asset_id` corresponde à rede e token esperados
5. **Verificação de assinatura**: Sempre verifique tokens PASETO antes de processar pagamentos

### Modelo de ameaças

NASPIP protege contra:

- **Manipulação de dados**: Assinaturas PASETO v4 impedem modificações
- **Ataques de replay**: Expiração do token e ciclo de vida da solicitação de pagamento impedem reutilização
- **Impersonação**: Verificação de chave pública via `kis` + `kid` garante autenticidade

## Diretrizes de implementação

### Campos obrigatórios (payload de instrução)

- `payment.address` — endereço de destino
- `payment.unique_asset_id` — ativo alvo (UAI)
- `payment.amount` — valor do pagamento
- `payment.is_open` — se o valor é aberto

### Campos opcionais

- `payment.id` — identificador da solicitação de pagamento
- `payment.expires_at` — expiração timestamp Unix
- `order` — metadados de comerciante e pedido

### Regras de validação

1. Token deve parsear como `naspip;{kis};{kid};v4.public.{paseto}`
2. Assinatura PASETO e expiração devem ser válidas
3. Chave pública para `kis` + `kid` não deve estar expirada
4. `unique_asset_id` deve ser um UAI suportado

## Resolução de payload URL (Fluxis)

Quando `POST /v1/naspip/read` recebe um token cujo `payload.data` contém uma `url` não vazia **e** não `payment_options`:

1. A Fluxis realiza um HTTP GET nessa URL
2. Em caso de sucesso, substitui `payload.data` pelas instruções de checkout/pagamento obtidas
3. Em caso de falha, retorna `MD0004` ou `PR0006` conforme apropriado

Se `payment_options` estiver presente, o token é retornado como está e a wallet seleciona um ativo antes de uma chamada de checkout subsequente.

## Endpoints da API Fluxis

| Endpoint | Method | Auth | Description |
| -------- | ------ | ---- | ----------- |
| `/v1/naspip/read` | POST | Bearer + `x-fluxis-api-key` | Verificar token e retornar `PasetoCompleteResult` |
| `/v1/naspip/create` | POST | Bearer + `x-fluxis-api-key` | Criar token a partir de payload de instrução ou URL |

Consulte o [Implementation Guide](/pt/docs/key-concepts/naspip/implementation-guide) para exemplos curl.

## Referências

- [NASPIP Protocol (GitHub)](https://github.com/fluxisus/naspip)
- [naspip-go library](https://github.com/fluxisus/naspip-go)
- [PASETO specification](https://paseto.io/)
- [ISO/IEC 18004 - QR Code](https://www.iso.org/standard/62021.html)
