Core SDK for integrating with Gemini Wallet through secure popup-based communication.
@gemini-wallet/core
provides the fundamental communication layer for interacting with Gemini Wallet. It handles secure cross-origin communication via the postMessage API, managing popup windows for user authentication and transaction approvals.
- 🔒 Secure Communication: PostMessage-based cross-origin communication
- 🪟 Popup Management: Automatic popup window lifecycle management
- 🔄 Event-Driven: Promise-based request/response pattern
- 🌐 Cross-Browser: Works across all modern browsers
- ⚡ Lightweight: Minimal dependencies for optimal bundle size
npm install @gemini-wallet/core
# or
yarn add @gemini-wallet/core
# or
pnpm add @gemini-wallet/core
import { Communicator, GeminiSdkEvent } from '@gemini-wallet/core';
// Initialize the communicator
const communicator = new Communicator({
appMetadata: {
name: 'My DApp',
description: 'My decentralized application',
url: 'https://mydapp.com',
icons: ['https://mydapp.com/icon.png']
},
onDisconnectCallback: () => {
console.log('Wallet disconnected');
}
});
// Send a connect request
const connectMessage = {
event: GeminiSdkEvent.SDK_CONNECT,
requestId: crypto.randomUUID(),
chainId: 1,
origin: window.location.origin
};
const response = await communicator.postRequestAndWaitForResponse(connectMessage);
console.log('Connected:', response.data.address);
// Listen for specific events
communicator.onMessage(
(message) => message.event === GeminiSdkEvent.ACCOUNTS_CHANGED
).then(response => {
console.log('Accounts changed:', response.data);
});
// Send transaction
const txMessage = {
event: GeminiSdkEvent.SDK_SEND_TRANSACTION,
requestId: crypto.randomUUID(),
chainId: 1,
origin: window.location.origin,
data: {
from: '0x...',
to: '0x...',
value: '1000000000000000000', // 1 ETH in wei
data: '0x'
}
};
const txResponse = await communicator.postRequestAndWaitForResponse(txMessage);
console.log('Transaction hash:', txResponse.hash);
The main class for handling communication with Gemini Wallet.
interface CommunicatorConfigParams {
appMetadata: AppMetadata;
onDisconnectCallback?: () => void;
}
interface AppMetadata {
name?: string;
description?: string;
url?: string;
icons?: string[];
}
Posts a message to the popup window without waiting for a response.
Posts a request and waits for a matching response based on requestId
.
Listens for messages that match the given predicate.
Ensures the popup is loaded and ready for communication.
Enumeration of all supported events:
-
POPUP_LOADED
- Popup window has loaded -
POPUP_UNLOADED
- Popup window was closed -
POPUP_APP_CONTEXT
- App metadata sent to popup -
SDK_CONNECT
- Connect wallet request -
SDK_DISCONNECT
- Disconnect wallet request -
SDK_SEND_TRANSACTION
- Send transaction request -
SDK_SIGN_MESSAGE
- Sign message request -
SDK_SIGN_TYPED_DATA
- Sign typed data request -
SDK_SWITCH_CHAIN
- Switch chain request -
ACCOUNTS_CHANGED
- Accounts changed event -
CHAIN_CHANGED
- Chain changed event -
DISCONNECT
- Disconnect event
-
SDK_BACKEND_URL
:"https://keys.gemini.com"
-
DEFAULT_CHAIN_ID
:1
(Ethereum mainnet) -
POPUP_WIDTH
:420
-
POPUP_HEIGHT
:650
- Origin Validation: All messages are validated against the expected origin
- Request ID Matching: Responses are matched to requests using unique IDs
- User Consent: All actions require explicit user approval in the popup
- No Private Keys: The SDK never handles private keys directly
- Chrome/Edge 80+
- Firefox 78+
- Safari 14+
- Opera 67+
We welcome contributions! Please see our Contributing Guide for details.
MIT License - see LICENSE for details.