Migração para accounts
Três pacotes do SDK — @cactus-agents/auth, @cactus-agents/user e @cactus-agents/wallet — foram removidos e unificados em um único pacote, @cactus-agents/accounts.
Se o seu fork ainda declara qualquer um dos três no package.json, o pnpm install não consegue resolvê-los: eles não existem mais no registry. Esta página é o caminho de saída.
:::info Quem precisa desta página
Só quem está em um fork anterior à unificação. Se o seu package.json já declara @cactus-agents/accounts e nenhum dos três pacotes antigos, não há nada a fazer aqui.
:::
O que mudou
Os três pacotes cobriam fatias do mesmo domínio — sessão, dados cadastrais e saldo do mesmo usuário — e compartilhavam tipos entre si (o user, por exemplo, reexportava tipos do wallet). A unificação eliminou essa dependência cruzada.
A boa notícia: a esmagadora maioria dos nomes exportados foi preservada sem alteração. Na prática a migração é uma troca de caminho de import, com quatro exceções pontuais descritas abaixo.
O pacote novo tem dois entry points:
| Import | O que expõe |
|---|---|
@cactus-agents/accounts | Serviços, transforms, helpers puros e todos os tipos. Não depende de React. |
@cactus-agents/accounts/react | Hooks e a store reativa (useAccountsStore). Requer React e Zustand. |
react (>=18) e zustand (>=4) são peer dependencies opcionais: se você usar só o entry point raiz, não precisa instalá-las por causa do accounts.
Passo 1 — trocar a dependência
Remova os três pacotes antigos e adicione o novo:
pnpm remove @cactus-agents/auth @cactus-agents/user @cactus-agents/wallet
pnpm add @cactus-agents/accounts
A versão mínima que cobre todo o conteúdo desta página é a 2.9.0. Confirme o range que ficou no seu package.json depois do comando.
Passo 2 — trocar os caminhos de import
Todo import que apontava para um dos três pacotes passa a apontar para @cactus-agents/accounts:
- import { createAuthService, type AuthUser } from "@cactus-agents/auth";
- import { createUserService, type UpdateUserPayload } from "@cactus-agents/user";
- import { createWalletService, type WalletData } from "@cactus-agents/wallet";
+ import {
+ createAuthService,
+ createUserService,
+ createWalletService,
+ type AuthUser,
+ type UpdateUserPayload,
+ type WalletData,
+ } from "@cactus-agents/accounts";
Para varrer o projeto de uma vez (macOS/BSD sed — no Linux use sed -i sem o ''):
grep -rl '@cactus-agents/\(auth\|user\|wallet\)' app/ workers/ \
| xargs sed -i '' -E 's#@cactus-agents/(auth|user|wallet)#@cactus-agents/accounts#g'
Ajuste a lista de diretórios ao seu fork — se você tem código em scripts/ ou em plugins de build, inclua também. Confirme no fim que não sobrou nada:
grep -rn '@cactus-agents/\(auth\|user\|wallet\)' . --exclude-dir=node_modules
Depois disso você provavelmente terá imports duplicados do mesmo módulo no mesmo arquivo. pnpm check:write (Biome) resolve a formatação; a consolidação dos blocos é manual.
Nomes preservados
Não precisam de nenhuma alteração além do caminho. Todos os nomes abaixo existem em @cactus-agents/accounts exatamente como existiam antes:
- Do
auth: todos, sem exceção —createAuthService,createAuthFromClient,createRecoveryService,createRecoveryFromClient,shouldRefreshToken,markRefreshStarted,markRefreshCompleted,markTokenSaved,initialRefreshState, e os tiposAuthUser,AuthUserInfo,AuthService,LoginPayload,LoginResponse,RegisterSimplifiedPayload,ValidateDocumentPayload,TokenRefreshState,RecoveryServiceetc. - Do
user:createUserService,createUserFromClient,getAccountRestriction,isAccountRestricted,getRestrictionType,filterSelfExclusionOptions,filterTimeoutOptions,getMinSelfExclusionMonths,getMinTimeoutDays,isLimitChangeBlocked,getLimitChangeUnblocksAt,isPermanentExclusion,isoDurationToHours,hoursToIsoDuration,parseLimitPeriod,transformLoginHistoryItem,transformLoginHistoryResponse, e as constantesLIMIT_PERIOD,SELF_EXCLUSION_MONTHS_OPTIONS,TIMEOUT_DAYS_OPTIONS,SPA_EXCLUSION_CODES. - Do
wallet:createWalletService,createWalletFromClient,fetchWalletData,aggregateWalletData,transformWalletResponse,transformTransaction,transformTransactionResponse,transformRollover, e os tiposWallet,WalletData,RealWallet,BonusWallet,CashbackWallet,Rollover,Transaction,TransactionFilter,TransactionStatusetc.
Passo 3 — corrigir os quatro símbolos renomeados
Estes são os únicos que não compilam depois da troca de caminho:
| Nome antigo | Pacote antigo | Nome novo |
|---|---|---|
PostalCodeLookupResponse | user | PostalCodeLookupResult |
RawPostalCodeLookupResponse | user | RawPostalCodeLookup |
RolloverData | user | RolloverRaw |
TransactionType | wallet | TransactionFilterType ou TransactionCategory — veja abaixo |
Sobre os três primeiros:
PostalCodeLookupResulttem a mesma forma que o tipo antigo (street,city,state) — é só o nome.RawPostalCodeLookupperdeu o campo opcionalstate?. Os demais (street?,logradouro?,city?,cidade?,uf?) continuam iguais. Se o seu código liaraw.state, passe a lerraw.uf.RolloverDataera apenas um alias que ouserpublicava para oRolloverRawdowallet. UseRolloverRawdireto.
TransactionType virou dois tipos
O antigo TransactionType acumulava dois papéis. Ele foi separado:
| Novo tipo | Papel |
|---|---|
TransactionFilterType | O valor que você envia no campo type ao listar o extrato |
TransactionCategory | A categoria semântica que a UI recebe, derivada da resposta |
Isso importa porque dois valores mudaram no lado do filtro:
Antes (TransactionType) | Agora (TransactionFilterType) |
|---|---|
"casino_bet" | "casino" |
"sports_bet" | "sports" |
"deposit", "withdraw", "coupon", "bonus", "cashback", "clubevip" | iguais |
"full" (era passado à parte do tipo) | "full", agora parte do próprio tipo |
:::caution Falha silenciosa
Mandar "casino_bet" ou "sports_bet" como filtro não dá erro — o backend simplesmente devolve o extrato inteiro, sem filtro. O usuário vê uma lista que parece certa e não é. Se o seu fork monta filtros de extrato à mão, revise esses dois valores explicitamente; o typecheck pega o caso quando o valor é literal, mas não quando vem de uma string dinâmica.
:::
TransactionCategory é mais granular que o tipo antigo: separa aposta de prêmio (casino_bet / casino_win, sports_bet / sports_win) e tem um "other" de fallback. Use-o para escolher título e ícone do card, não para montar a requisição.
TransactionStatus ganhou três valores
TransactionStatus manteve o nome e todos os valores antigos (approved, denied, expired, pending, processing, credit, debit, transfer), mas ganhou três: failed, integration_failure e provider_rejected. São variantes de falha distintas de denied, que passa a significar só rejeição manual.
Como a mudança é aditiva, código que apenas consome o tipo continua compilando. O que quebra é código exaustivo sobre ele:
Record<TransactionStatus, ...>— passa a faltar três chaves e otypecheckacusaswitchcomdefaultinalcançável ou checagem de exaustividade vianever- mapas de label, cor ou ícone por status
Nesses pontos, decida o rótulo das três novas variantes de falha em vez de deixá-las cair em um fallback genérico — o objetivo delas é justamente permitir que a UI diferencie a causa.
Passo 4 — a camada React (opcional)
Os três pacotes removidos publicavam um único entry point, sem subpath ./react: eles não traziam hooks nem store. Se o seu fork mantém o estado de sessão/carteira em uma store própria, ela continua funcionando — nada obriga você a trocar.
O que o pacote novo oferece, e que antes não existia, é uma camada React pronta em @cactus-agents/accounts/react:
- Store reativa:
useAccountsStore— expõeuser,userInfo,isAuthenticated,wallet,transactions,authHydratede as ações correspondentes (setAuthUser,clearAuth,refetchWallet,fetchTransactions…). Além dehydrateAccountseuseAccountsHydrationpara o boot em SSR. - Hooks de auth:
useCurrentUser,useLogin,useLogout,useRegister,useRecovery,useValidateDocument,useRefreshProfile. - Hooks de carteira:
useWallet,useRealBalance,useBonusBalance,useCashbackBalance,useTransactions,useRollover,useTransferBonus,useTransferCashback,useWithdrawReceipt,useWalletFlags,useRefreshWallet. - Formatação de dinheiro:
useFormatMoneyeformatMoney. - Perfil:
useProfile.
A camada precisa ser inicializada uma vez, com locale, moeda e casas decimais. O template faz isso em um componente dedicado que não renderiza nada, alimentado pelo ambiente e pela configuração de país — não por valores fixos:
import { useAccountsInit } from "@cactus-agents/accounts/react";
import { useCountry } from "~/context/country";
import { useClientEnv } from "~/context/env";
export function AccountsBootstrap() {
const env = useClientEnv();
const country = useCountry();
useAccountsInit({
locale: env.BRAND_LANGUAGE,
currency: env.BRAND_CURRENCY,
displayDecimalDigits: country.displayDecimalDigits,
});
return null;
}
BRAND_LANGUAGE chega em minúsculas (pt-br). O Intl casa tags de idioma sem diferenciar caixa, então passar o valor direto funciona; o template ainda assim normaliza para a forma canônica (pt-BR) antes de repassar, e vale imitar isso se você comparar o locale como string em algum ponto.
:::caution displayDecimalDigits não é sempre 2
Passe sempre o displayDecimalDigits da configuração de país, nunca um literal: Nigéria e Chile exibem valores sem casas decimais, os demais países com duas. Um 2 fixo quebra a exibição de saldo nesses dois mercados. Veja a nota em Installation.
:::
Passando essa configuração, useFormatMoney, useTransactions e os hooks de saldo derivam a formatação sozinhos — você não precisa montar Intl.NumberFormat à mão.
AccountsConfig aceita ainda callbacks opcionais para você substituir qualquer chamada HTTP que a camada faz por padrão (fetchTransactions, refetchWallet, login, transferBonus…). Só passe os que precisar sobrescrever.
Passo 5 — verificar
pnpm install
pnpm typecheck
O typecheck é o que efetivamente prova a migração: qualquer import não resolvido ou símbolo renomeado aparece aqui. Depois:
pnpm dev
E teste manualmente os fluxos que atravessam os três domínios unificados:
- Login e logout — inclusive recuperação de senha
- Cadastro — com validação de documento, se a sua marca usa
- Saldo no header — real, bônus e cashback, com o número de casas decimais correto para o seu país
- Extrato — e cada filtro por tipo, um a um (é onde o
casino_bet→casinose manifesta) - Transferência de bônus/cashback para a carteira real
Próximos passos
Com a migração fechada, volte ao fluxo normal de atualização em Updating SDK Packages. Se algum símbolo que o seu fork usa não aparece em nenhuma das listas acima, fale com o time Cactus antes de reimplementá-lo localmente.