BitChicken é um ecossistema de NFT na BNB Smart Chain: você abre ovos (gacha resolvido por Chainlink VRF) e choca Chickens de espécies/raridades; aloja casais na granja para gerar produção em BCKN (a token utilitária); e negocia no marketplace. Há também um programa de indicação on-chain de 1 nível: quando seu indicado abre o primeiro ovo, você ganha uma fatia em BNB do preço (2% a 10%, conforme seu rank), sacável via pull-payment.
Monorepo com quatro camadas independentes, comunicando-se só por ABI, um Postgres compartilhado e HTTP —
veja CLAUDE.md para os detalhes de arquitetura e convenções.
| Projeto | Stack | Papel |
|---|---|---|
RW.BC.Crypto/ |
Solidity 0.8.35 + Hardhat 3 (BSC) | Contratos: BCKN (ERC-20), NFT (ERC-721), Forge (gacha/VRF), Staking, Marketplace |
RW.BC.Indexer/ |
Ponder + viem (TypeScript) | Indexador on-chain: materializa eventos dos contratos num schema Postgres indexer (read-model) |
RW.BC.DApp/ |
Angular 22 + PrimeNG 21 + Tailwind v4 + ethers v6 + Reown AppKit + Firebase | dApp: loja (ovos), granja, marketplace, coleção, contas (login/cadastro) |
RW.BC.Api/ |
.NET 10 + Aspire + EF Core/PostgreSQL + Firebase + Wolverine | API de contas: email/senha + vínculo de carteira (SIWE) |
RW.BC.AppHost/ |
.NET Aspire | Orquestra o ambiente de dev local num comando |
📚 Documentação técnica em
docs/— inventário regenerável (pipeline/docs-refresh) cobrindo os 4 projetos + o ecossistema (docs/meta/: arquitetura, domínios e ADRs). O código é a fonte da verdade; se a doc divergir, está velha.
- Como tudo se conecta
- Pré-requisitos
- Configuração inicial (do zero)
- Início rápido
- Testnet interna via Docker
- Ambientes do dApp
- Variáveis de ambiente
- Testes e cobertura
- CI/CD
- Troubleshooting
- Contribuindo
- Licença
O dApp fala direto com os contratos para qualquer ação (comprar, vender, reivindicar rendimento) e fala com a API por HTTP sempre que precisa de conta, autenticação ou uma consulta rápida de dados. A API nunca inventa nada — ela só lê o que o indexer já organizou a partir dos eventos reais da blockchain. E o indexer só existe porque os contratos, ao emitirem eventos, deixam um rastro público e verificável de tudo que acontece.
Cada camada faz exatamente um tipo de trabalho, e a comunicação entre elas é sempre por meio de um contrato bem definido — seja uma ABI, um schema de banco compartilhado ou uma chamada HTTP autenticada.
- Node.js 24 (
nvm use 24; há.nvmrcemRW.BC.CryptoeRW.BC.Indexer). Hardhat 3 e Angular 22 abortam no Node 20. - .NET 10 SDK (para
RW.BC.Api/RW.BC.AppHost). - Docker (testnet interna, Postgres da API, e os Testcontainers dos testes da API).
git clone https://github.com/robertvbs/BitChicken.git
cd BitChicken
nvm use 24Instale as dependências de cada projeto Node:
(cd RW.BC.Crypto && npm install)
(cd RW.BC.Indexer && npm install)
(cd RW.BC.DApp && npm install)Copie os arquivos de configuração de exemplo (veja Variáveis de ambiente abaixo para o que preencher em cada um):
cp RW.BC.Crypto/.env.example RW.BC.Crypto/.env
cp RW.BC.Indexer/.env.example RW.BC.Indexer/.env
cp RW.BC.DApp/src/environments/environment.local.example.ts RW.BC.DApp/src/environments/environment.local.tsOs dois primeiros (RW.BC.Crypto/.env, RW.BC.Indexer/.env) podem ficar com os valores de exemplo —
os defaults já cobrem o deploy local, e as credenciais reais só importam para deploy em testnet/mainnet,
verificação no BSCScan, e para as telas de conta/login (Firebase) e conexão de carteira (Reown)
funcionarem com suas próprias credenciais.
⚠️ O terceirocp(environment.local.ts) não é opcional: o Angular exige que esse arquivo exista fisicamente (é umfileReplacementda configlocal), mesmo que você não preencha nenhuma credencial real nele. Sem ele,npm run start:local— e por consequência o comando único do Aspire abaixo — falha no build do dApp.
Garanta que o Docker esteja rodando antes de começar. Então:
dotnet run --project RW.BC.AppHostSobe Postgres + API + anvil (chain 1337) + Otterscan + deploy/fund dos contratos + forge:watch + indexer
Ponder + o dApp orquestrados. dApp em http://localhost:4200, dashboard Aspire em https://localhost:17190.
Detalhes em RW.BC.AppHost/README.md.
Em alguns ambientes o build da API pode exigir o flag
-p:AllowMissingPrunePackageData=true(erro de SDKNETSDK1226) — veja Troubleshooting.
Ovo travado em "Chocando…": o gacha usa Chainlink VRF; no localnet o mock só responde com
npm run forge:watchrodando (o AppHost já sobe isso automaticamente).
npm test # hardhat test (mocha + testes Solidity)
npm run compile # hardhat clean && compile
npm run lint # solhint + eslintnpm start # ng serve (dev → BSC testnet)
npm test # ng test (Vitest, cobertura 100% imposta)
npm run build # build de produção → dist/browserdotnet build RW.BC.Api.slnx -p:AllowMissingPrunePackageData=true
dotnet test RW.BC.Api.slnx -p:AllowMissingPrunePackageData=true # xUnit + Testcontainers (precisa Docker)npm run typecheck # type-check é o gate principal
npm run test:cov # testes + coberturaCom o ambiente Aspire no ar, o smoke valida o pipeline contratos → indexer → API (edições, NFTs por
LEFT JOIN, listings status="Active", forge, transparência):
# após `dotnet run --project RW.BC.AppHost` + seed (ver RW.BC.AppHost/README.md)
cd RW.BC.Crypto && npm run seed-nfts:localhost && npm run seed-market:localhost && cd ..
API_PORT=$(ss -ltnp 2>/dev/null | grep RW.BC.Api | grep -oE '127.0.0.1:[0-9]+' | cut -d: -f2 | head -1) # Linux
API_BASE="http://localhost:${API_PORT}" RW.BC.AppHost/e2e-smoke.shO
ssacima é específico de Linux. No macOS/Windows, pegue a porta da API direto no dashboard do Aspire (https://localhost:17190 → recursoapi→ endpoint) e definaAPI_BASEmanualmente.
O E2E de contas/auth (Firebase + carteira) fica em RW.BC.Api/scripts/.
Se não quiser subir a API junto, use os npm scripts do Crypto. Sobe anvil (chain 1337) + Otterscan, só a chain, sem API.
# em RW.BC.Crypto
npm run node:up # anvil em http://localhost:8545 + Otterscan em http://localhost:5100
npm run deploy:localhost # token + NFT + forge + staking + marketplace (endereços determinísticos);
# semeia tier prices, edições 1–5 e staking
npm run fund:localhost # 10000 BNB nas contas dev — ou: FUND_ADDRESS=0x... npm run fund:localhost
npm run forge:watch # DEIXE RODANDO: auto-fulfill do VRF mock (senão os ovos não chocam)
# em RW.BC.DApp
npm run start:local # http://localhost:4200 lendo da chain internaPara parar/limpar: npm run node:down (mantém estado) ou npm run node:reset (chain limpa).
Auxiliares: npm run seed:localhost (popula dados de exemplo) e npm run stress:localhost (harness de stress).
Conectar a MetaMask: rede RPC http://localhost:8545, Chain ID 1337, símbolo BNB. Ligue
"Mostrar redes de teste" no seletor. Explorer local: http://localhost:5100.
| Config | Rede | Quando |
|---|---|---|
local (environment.local.ts, gitignored — copie de environment.local.example.ts) |
nó Docker (chain 1337) + API local | npm run start:local |
development (padrão) |
BSC testnet | npm start / npm test |
production |
BSC mainnet | npm run build |
Cada um traz rpcUrl, endereços dos contratos, explorer, appKit.local, apiBaseUrl e a config
firebase (web). Os arquivos environment.ts/environment.development.ts (versionados) trazem
placeholders — preencha com o seu próprio projeto Firebase/Reown para usar login e vínculo de
carteira; o resto do dApp (navegar loja/mercado/coleção, conectar carteira e ler a chain) funciona sem
essas credenciais. Ao reimplantar/upgradar um contrato, atualize os endereços (e a ABI, se a
interface mudou).
| Variável | Uso |
|---|---|
MAIN_PRIVATE_KEY |
Chave da carteira de deploy (testnet/mainnet). Use uma carteira dedicada, nunca a principal. |
BSC_RPC_URL / BSC_TESTNET_RPC_URL |
RPCs da BSC mainnet/testnet. |
BSCSCAN_API_KEY |
Verificação de contratos no BSCScan — obtenha em bscscan.com/myapikey. |
ADMIN_WALLET |
Carteira que recebe a governança dos contratos no deploy; se vazia, o deployer permanece admin. Se você definir essa variável para um deploy local, atualize também o campo admin em environment.local.ts (dApp) para o mesmo endereço — senão o painel /admin local não reconhece sua carteira. |
FEE_SINK, PLATFORM_FEE_BPS |
Destino e percentual da taxa do marketplace. |
VRF_* |
Configuração do Chainlink VRF (coordinator/subId/keyHash) — só para testnet/mainnet; localnet usa mock. |
TOKEN_PROXY, NFT_PROXY, STAKING_PROXY, MARKETPLACE_PROXY |
Endereços de proxy para npm run upgrade:*. |
| Variável | Uso |
|---|---|
DATABASE_URL |
Connection string do Postgres onde o indexer materializa o schema indexer. |
CHAIN_ID, PONDER_RPC_URL_<chainId> |
Rede indexada e seu RPC. |
MARKETPLACE_ADDRESS, MARKETPLACE_START_BLOCK |
Endereço do contrato e bloco inicial de indexação. |
| Campo | Uso |
|---|---|
firebase.* |
Config web de um projeto Firebase (Email/Password habilitado) — console.firebase.google.com. |
reown.projectId |
Project ID do WalletConnect/Reown — cloud.reown.com. |
ipfsGateway |
Gateway IPFS (o público gateway.pinata.cloud funciona; um dedicado é opcional). |
| Chave | Uso |
|---|---|
Identity:Firebase:ProjectId |
Projeto Firebase usado para validar o JWT (OIDC discovery). Mesmo projeto do dApp. |
ConnectionStrings:bitchicken (ou ConnectionStrings__bitchicken) |
Connection string do Postgres da API — injetada automaticamente pelo Aspire. |
.env, environment.local.ts e qualquer chave privada/API key não são versionados (.gitignore
cobre .env*, node_modules/ e os overrides locais). Nunca faça commit de chaves privadas, service
accounts ou connection strings reais — use os arquivos *.example como ponto de partida.
Política: toda mudança vem com testes. No RW.BC.DApp, 100% (statements/funcs/lines, 98% branches)
imposto a cada ng test via angular.json. No RW.BC.Crypto, cobertura por construção (sem
ferramenta no HH3). Na RW.BC.Api, xUnit + Testcontainers (Postgres real) via dotnet test.
.github/workflows/ci.yml roda em push/PR para main:
- Crypto — lint (solhint + eslint), testes (Hardhat mocha), upgrade-safety, ABI drift, invariantes/ cobertura via Foundry, análise estática (Slither).
- API — build + testes (xUnit + Testcontainers) + cobertura.
- Indexer — codegen + typecheck + testes com gate de cobertura.
- dApp — i18n, lint, testes (cobertura imposta), build.
- Segurança —
gitleaks(varredura de segredos no histórico) +npm auditnos três projetos Node.
NETSDK1226no build da API/AppHost: anexe-p:AllowMissingPrunePackageData=truea tododotnet build/test/restore/ef(não commite esse flag em csproj/props).- MetaMask com nonce/saldo desatualizado após
node:reset: limpe em Configurações → Avançado → Limpar dados da aba de atividade. - No WSL,
localhostnão conecta do Windows: use o IP do WSL (ip -4 addr show eth0 | grep inet).
Veja CONTRIBUTING.md para o passo a passo de build/teste por projeto e convenções de
código. Para reportar uma vulnerabilidade de segurança, veja SECURITY.md — não abra uma
issue pública para isso.
MIT © Robert Wagner