Pular para o conteúdo

Catálogo de operações

O catálogo de operações do Agent espelha as rotas da API uma a uma, e nada mais. Cada operação corresponde a uma rota do contrato: o Agent recebe o pedido em JSON simples, monta o corpo, assina e envia (ou apenas assina). Ele não valida posse de item, não confere preço, não decide nada de negócio — a autoridade é sempre o seu servidor. O nome da operação é o que você passa em operation (interface A) ou action (interface C).

OperaçãoO que fazMétodo e rotaAuth
pingverifica se o Agent está vivolocal (não fala com a plataforma)
characterLinks.createvincular personagemPOST /api/character-linksservice
market.eligibilityconsultar elegibilidade do vendedorGET /api/market/eligibility/{characterRef}service
market.adjustStockajustar estoque do anúncioPUT /api/market/listings (ADJUST_STOCK)service
market.withdrawretirar anúncioPUT /api/market/listings (WITHDRAW)service
transactions.getconsultar transaçãoGET /api/transactions/{id}service
transactions.confirmDeliveryconfirmar entregaPOST /api/transactions/{id}/deliveryservice
transactions.reportDeliveryFailurereportar falha de entregaPOST /api/transactions/{id}/delivery-failureservice
market.createListingregistrar anúncio (assina e envia)POST /api/market/listingssignature
market.signListingregistrar anúncio (assina e devolve, não envia)POST /api/market/listingssignature
transactions.createcriar transação (assina e envia)POST /api/transactionssignature
transactions.signBuyOffercriar transação (assina e devolve, não envia)POST /api/transactionssignature
  • ping — confirma que o Agent está vivo. É local: não fala com a plataforma. Útil para o seu servidor checar que o sidecar está no ar.
  • characterLinks.create — inicia o vínculo de um personagem a uma conta, a partir do jogo. Recebe characterRef e name.
  • market.eligibility — diz se um personagem pode anunciar e o que falta quando não pode. É uma dica, nunca um portão: use para dar um aviso amigável ao vendedor, não para autorizar o anúncio. Recebe characterRef.
  • market.adjustStock — informa à plataforma a quantidade que o seu servidor observa no anúncio. Recebe itemRef e observedQuantity.
  • market.withdraw — retira o anúncio do mercado. Recebe itemRef.
  • transactions.get — devolve o estado atual da transação. Consulte antes de transferir o item. Recebe transactionId.
  • transactions.confirmDelivery — confirma que o item foi transferido. É a fonte da verdade da entrega. Recebe transactionId.
  • transactions.reportDeliveryFailure — reporta uma falha de entrega. OUT_OF_STOCK estorna; TEMPORARY reenfileira. Recebe transactionId, reason, observedQuantity e, opcionalmente, detail.
  • market.createListing / market.signListing — as duas registram um anúncio (POST /api/market/listings); a diferença é quem faz o HTTP (ver abaixo). Recebem itemRef, gameItemId, itemName, attributes, quantityListed, unitAmountCents e sellerCharacterRef.
  • transactions.create / transactions.signBuyOffer — as duas criam uma transação a partir de uma oferta de compra (POST /api/transactions). Recebem apenas itemRef, quantity e buyerCharacterRefpreço e item não viajam, porque já são registro da Lootfy desde o anúncio.

service × signature: a diferença que muda o retry

Seção intitulada “service × signature: a diferença que muda o retry”

Cada operação declara como autentica, e isso não é cosmético — decide se um retry pode reusar o jti.

service

Envia a API key (x-service-api-key) mais o JWS. A plataforma verifica com nonce: reenviar o mesmo jti é recusado como replay. Por isso cada tentativa carrega um jti novo — o Agent cuida disso no backoff.

signature

Envia só o JWS, sem API key. É o modo das rotas que o client do jogo transporta (criar transação, POST /api/transactions, e registrar anúncio, POST /api/market/listings). Aqui o jti é chave de idempotência de domínio: o retry legítimo reusa o mesmo jti, porque um jti novo criaria uma segunda transação ou um segundo anúncio.

Nas rotas transportadas pelo client (criar transação e registrar anúncio), quem faz o POST à Lootfy não é o seu servidor — é o client do jogo, pelo canal do jogo. O papel do servidor ali é só assinar, e as operações market.signListing e transactions.signBuyOffer fazem exatamente isso: assinam o corpo e devolvem o envelope, sem enviar nada.

O envelope devolvido tem quatro campos:

{
"body": "{\"itemRef\":\"...\",\"quantity\":1,\"buyerCharacterRef\":\"...\"}",
"signature": "<protected>..<sig>",
"jti": "b1c2...-...",
"expiresAt": 1757000000
}

As variantes que enviam (market.createListing e transactions.create) existem para quem não tem o client transportando: nesse caso o próprio servidor assina e faz o HTTP. A plataforma não distingue quem fez a requisição — ela confere apenas a assinatura. Escolher entre assinar-e-enviar ou só-assinar é escolher o caminho de integração; a segurança é a mesma.

Pela interface A, um exemplo de operação service (confirmar entrega) e um de operação signature que só assina (a oferta de compra):

Terminal window
curl -s http://127.0.0.1:8899/call \
-H 'content-type: application/json' \
-d '{
"operation": "transactions.confirmDelivery",
"input": { "transactionId": "txn-123" },
"id": "deliver-txn-123"
}'

Resposta em sucesso — o resultado da plataforma vem em data, e o id é ecoado:

{ "ok": true, "id": "deliver-txn-123", "data": null }