This is a demo project showcasing the integration of Fireblocks' Non-Custodial Wallet (NCW) with a web application. The demo demonstrates how to implement a secure cryptocurrency wallet solution using Fireblocks' technology with proxy backend and without proxy backend. see .env file to adjust settings.
- Secure wallet creation and management
- Asset management (view, send, receive)
- Transaction history
- Multi-chain support
- Real-time balance updates
- Secure key management
- Node.js (version specified in .nvmrc)
- Yarn package manager
- Fireblocks API credentials
- A Fireblocks account with NCW enabled
- Clone the repository:
git clone https://github.com/your-organization/ncw-web-demo-v2.git
cd ncw-web-demo-v2Note: Replace the URL above with the actual repository URL.
- Install dependencies:
yarn install- Create a
.envfile in the root directory with the following variables:
VITE_CLOUDKIT_APITOKEN=your-api-token
VITE_CLOUDKIT_CONTAINER_ID=your-container-id
VITE_CLOUDKIT_ENV=production
VITE_NCW_SDK_ENV=sandbox
VITE_USE_EMBEDDED_WALLET_SDK=true
VITE_BASE_FOLDER=/ncw-web-demo-v2/ew
VITE_BACKEND_BASE_URL=your-backend-url
VITE_AUTH_CLIENT_ID=your-client-id
VITE_VAPID_PUBLIC_KEY=your-vapid-public-key
VITE_USE_WEB_PUSH=trueVITE_CLOUDKIT_APITOKEN=your-api-token
VITE_CLOUDKIT_CONTAINER_ID=your-container-id
VITE_CLOUDKIT_ENV=production
VITE_NCW_SDK_ENV=sandbox
VITE_USE_EMBEDDED_WALLET_SDK=false
VITE_BASE_FOLDER=/ncw-web-demo-v2
VITE_BACKEND_BASE_URL=your-backend-url
VITE_USE_WEB_PUSH=falseNote: Choose one of the options above based on your implementation needs. The key difference is the VITE_USE_EMBEDDED_WALLET_SDK setting, which determines whether the application uses direct integration with Fireblocks' Embedded Wallet SDK or communicates through a proxy backend server.
- Start the development server:
yarn dev- Open your browser and navigate to
http://localhost:5173
src/
βββ api-embedded-wallet/ # API integration with Fireblocks
βββ components/ # Reusable UI components
βββ pages/ # Application pages
βββ store/ # State management
βββ types/ # TypeScript type definitions
βββ utils/ # Utility functions
WalletProvider: Manages wallet state and operationsAssetStore: Handles asset-related operations and stateTransactionStore: Manages transaction history and operationsAuthStore: Handles authentication and user session
The project uses Fireblocks' API for:
- Wallet creation and management
- Asset operations
- Transaction processing
- Security operations
- The project uses TypeScript for type safety
- React with Vite for fast development
- MobX for state management
- Tailwind CSS for styling
For more information about Fireblocks NCW, refer to the official documentation.
This application uses Firebase Cloud Messaging (FCM) for push notifications. The implementation requires a service worker file (firebase-messaging-sw.js) to be available at the root path of the application.
The application supports two methods for receiving transaction updates:
- Web Push Notifications (default): Uses Firebase Cloud Messaging to receive real-time updates
- Regular Polling: Periodically checks for updates at a fixed interval
You can configure which method to use with the VITE_USE_WEB_PUSH environment variable:
# Use web push notifications (default)
VITE_USE_WEB_PUSH=true
# Use regular polling instead
VITE_USE_WEB_PUSH=falseWhen web push is disabled, the application will poll for transaction updates every 5-30 seconds (depending on the configuration).
In development mode with Vite, the service worker file must be placed in the public directory to be served at the root path. This ensures that Firebase can register the service worker correctly.
public/
βββ firebase-messaging-sw.js # Service worker for Firebase Cloud Messaging
For more information about the Firebase Cloud Messaging implementation, see the MESSAGING_README.md file.
- Never commit your API keys or secrets
- Always use environment variables for sensitive data
- Follow security best practices when handling wallet operations
- Keep dependencies updated to the latest secure versions
The application supports two different modes of operation, controlled by the USE_EMBEDDED_WALLET_SDK environment variable:
-
Embedded Wallet Mode (
USE_EMBEDDED_WALLET_SDK=true)- Direct integration with Fireblocks' Embedded Wallet SDK
- Handles wallet operations locally in the browser
- Manages MPC (Multi-Party Computation) keys directly
- Provides enhanced security through local key management
- Uses the
api-embedded-walletimplementation
-
Proxy Backend Mode (
USE_EMBEDDED_WALLET_SDK=false)- Uses a proxy backend server to communicate with Fireblocks
- Delegates wallet operations to the backend
- Manages keys through the proxy server
- Provides simpler implementation with backend handling security
- Uses the
apiimplementation
The application uses Vite's alias system to dynamically load the correct implementation based on the environment configuration. All imports use the @api alias, which Vite resolves to either the embedded wallet or proxy backend implementation:
// All imports use the @api alias
import { getAssets } from '@api';
// Vite resolves this to either:
// - src/api-embedded-wallet/assets.embedded.api.ts (when USE_EMBEDDED_WALLET_SDK=true)
// - src/api/assets.api.ts (when USE_EMBEDDED_WALLET_SDK=false)The actual implementation is determined by Vite's configuration:
// vite.config.ts
export default defineConfig({
resolve: {
alias: {
'@api': process.env.USE_EMBEDDED_WALLET_SDK === 'true'
? path.resolve(__dirname, 'src/api-embedded-wallet')
: path.resolve(__dirname, 'src/api')
}
}
});This approach allows for:
- Clean, consistent imports throughout the codebase
- Easy switching between implementations
- No need to modify import statements when changing modes
- Type safety and IDE support through the alias
-
Security Model
- Embedded Wallet: Local key management with MPC
- Proxy Backend: Server-side key management
-
Network Architecture
- Embedded Wallet: Direct communication with Fireblocks
- Proxy Backend: Communication through proxy server
-
Implementation Complexity
- Embedded Wallet: More complex but more secure
- Proxy Backend: Simpler but requires trust in proxy
-
Performance
- Embedded Wallet: Faster for local operations
- Proxy Backend: Additional network latency
-
Development
- Both modes maintain the same API interface
- Environment variable controls the implementation
- Easy to switch between modes for testing
- Consistent import paths using Vite's alias system