feat(rn_cli_wallet): add Canton blockchain support#469
Conversation
Add Canton namespace integration with Ed25519 signing via tweetnacl. Implements all 7 Canton RPC methods with auto-approve for read-only methods and manual approval modal for sensitive operations. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Claude finished @ignaciosantise's task in 1m 40s —— View job Code Review
Found 6 issue(s)Issue 1: React hooks called after conditional returnID: canton-modal-hooks-violation-a7c1 Context:
Recommendation: Move all hooks before the conditional return and remove the eslint-disable: export default function SessionSignCantonModal() {
const { currentRequestVerifyContext } = useSnapshot(SettingsStore.state);
const [isLoadingApprove, setIsLoadingApprove] = useState(false);
const [isLoadingReject, setIsLoadingReject] = useState(false);
const requestEvent = ModalStore.state.data?.requestEvent;
const requestSession = ModalStore.state.data?.requestSession;
const { topic, params } = requestEvent ?? { topic: '', params: { request: {} } };
const onApprove = useCallback(async () => { ... }, [requestEvent, topic]);
const onReject = useCallback(async () => { ... }, [requestEvent, topic]);
if (!requestEvent || !requestSession) {
return <Text variant="md-400" color="text-error">Missing request data</Text>;
}
// rest of render
}Issue 2: Unhandled async error in Canton auto-approve pathID: canton-events-unhandled-async-b3d2 Context:
Recommendation: case CANTON_SIGNING_METHODS.LIST_ACCOUNTS:
case CANTON_SIGNING_METHODS.GET_PRIMARY_ACCOUNT:
case CANTON_SIGNING_METHODS.GET_ACTIVE_NETWORK:
case CANTON_SIGNING_METHODS.STATUS:
case CANTON_SIGNING_METHODS.LEDGER_API:
try {
const response = await approveCantonRequest(requestEvent);
return walletKit.respondSessionRequest({ topic, response });
} catch (e) {
LogStore.error((e as Error).message, 'WalletKitEvents', 'onSessionRequest');
Toast.show({ type: 'error', text1: 'Canton request failed', text2: (e as Error).message });
}
return;Issue 3: Canton wallet not in reactive SettingsStore stateID: canton-wallet-nonreactive-state-c5e3 Context:
Recommendation: Add const { cantonWallet } = useSnapshot(SettingsStore.state);
const cantonSecretKey = cantonWallet?.getSecretKey?.() ?? null;Issue 4: Missing Android versionCode incrementID: canton-missing-versioncode-d4f4 Context:
Recommendation: Increment Issue 5: Ed25519 secret key stored and displayed as plaintext (dcl-cantonlib-secret-key-exposed-ui-a3f1 / dcl-cantonwalletutil-plaintext-key-storage-b7e2)ID: dcl-cantonlib-secret-key-exposed-ui-a3f1 Context:
Recommendation: Document explicitly in code comments that the storage utility uses MMKV (verify it's using an encrypted instance) and not plain AsyncStorage. For the UI, consider gating the Secret Phrase screen behind biometric auth, consistent with how production wallets protect key export. Issue 6:
|
There was a problem hiding this comment.
Pull request overview
Adds first-class Canton namespace support to the RN CLI wallet, including key management (Ed25519), WalletConnect session proposal wiring, request routing, and UI affordances for manual approvals and secret display.
Changes:
- Introduce Canton chain/constants, wallet utilities (create/restore/import), and Ed25519 signing via
tweetnacl. - Add Canton WalletConnect RPC handling (auto-approve read-only + modal-driven approval for sensitive methods).
- Fix initialization flow by persisting TON/TRON wallet objects into
SettingsStoreand integrate Canton into initialization/import/secret phrase screens.
Reviewed changes
Copilot reviewed 15 out of 17 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| wallets/rn_cli_wallet/package.json | Adds tweetnacl dependency for Ed25519 signing. |
| wallets/rn_cli_wallet/yarn.lock | Locks tweetnacl dependency. |
| wallets/rn_cli_wallet/src/constants/Canton.ts | Defines Canton chains, methods, events, and network icons. |
| wallets/rn_cli_wallet/src/lib/CantonLib.ts | Implements Ed25519 keypair creation and message signing. |
| wallets/rn_cli_wallet/src/utils/CantonWalletUtil.ts | Canton wallet create/restore and import via secret key. |
| wallets/rn_cli_wallet/src/utils/CantonRequestHandlerUtil.ts | Implements Canton RPC method handlers (read-only + signing/mock execution). |
| wallets/rn_cli_wallet/src/utils/PresetsUtil.ts | Registers Canton chains/icons into presets lookup. |
| wallets/rn_cli_wallet/src/store/SettingsStore.ts | Adds cantonAddress state + setter; fixes TON/TRON wallet object storage. |
| wallets/rn_cli_wallet/src/store/ModalStore.ts | Adds SessionSignCantonModal to modal type union. |
| wallets/rn_cli_wallet/src/modals/SessionSignCantonModal.tsx | New approval modal for Canton sensitive requests. |
| wallets/rn_cli_wallet/src/modals/SessionProposalModal.tsx | Advertises Canton namespace/chains/methods/events during session approval. |
| wallets/rn_cli_wallet/src/hooks/useWalletKitEventsManager.ts | Routes Canton requests (auto-approve vs manual modal). |
| wallets/rn_cli_wallet/src/hooks/useInitializeWalletKit.ts | Initializes Canton wallet and stores Canton address; fixes TON/TRON wallet storage in SettingsStore. |
| wallets/rn_cli_wallet/src/modals/ImportWalletModal.tsx | Adds Canton option for importing a wallet via secret key. |
| wallets/rn_cli_wallet/src/screens/SecretPhrase/index.tsx | Displays Canton secret key on the Secret Phrase screen. |
| wallets/rn_cli_wallet/src/components/Modal.tsx | Wires SessionSignCantonModal into modal switch. |
| wallets/rn_cli_wallet/src/assets/chains/canton.png | Adds Canton chain icon asset. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Fix React hooks rules violation: move useCallback before conditional return in SessionSignCantonModal and remove eslint-disable - Add try/catch around Canton auto-approve path in event manager to prevent unhandled rejections and respond with JSON-RPC error - Send JSON-RPC error response on approve failure in Canton modal so dapp doesn't hang - Add cantonWallet to SettingsStore for reactive SecretPhrase screen - Add __DEV__ warning when storing Canton secret key unencrypted - Make getWallet() return type CantonLib | undefined for type safety - Increment Android versionCode to 62 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The downloaded canton.png was actually a WebP image with a .png extension, causing AAPT2 compilation failure on Android builds. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Summary
canton:mainnet,canton:devnet) to the RN CLI wallet with Ed25519 signing viatweetnaclcanton_listAccounts,canton_getPrimaryAccount,canton_getActiveNetwork,canton_status,canton_ledgerApi) and 2 manual-approve methods (canton_signMessage,canton_prepareSignExecute)Context
Screenshots
iOS
Android
New files
src/constants/Canton.tssrc/lib/CantonLib.tssrc/utils/CantonWalletUtil.tssrc/utils/CantonRequestHandlerUtil.tssrc/modals/SessionSignCantonModal.tsxTest plan
npx tsc --noEmitpasses (verified)canton_signMessageopens approval modal and returns Ed25519 signaturecanton_prepareSignExecuteopens approval modal and returns mock response🤖 Generated with Claude Code