Widget Embed Guide

How to easily add staking and DeFi to your application

📘

Suggestion

Suggested visual tile: High-level architecture diagram showing “Your App” → “Blockdaemon Widget (iframe)” → “Blockdaemon Earn Stack / protocols”.​

Overview

The Blockdaemon Earn Widget lets you offer staking and DeFi lending in your application via a hosted widget, without building protocol integrations or on-chain logic in-house. Blockdaemon deploys the widget on a per-client basis and connects directly to the Blockdaemon Earn Stack.​

The purpose of this guide is to support the evaluation and integration of the widget into your staging or production environments.​


Supported Features

📘

Suggestion

Suggested tiles: One tile each for Staking, DeFi Lending, Swaps, with short descriptions and chain coverage.​

The Blockdaemon Earn Widget currently supports the following functionality:​

  • Staking: Ethereum (via Stakewise vaults); Solana support is planned.​
  • DeFi lending: Aave on Ethereum, Base, Arbitrum, Optimism; Morpho and additional chains (Solana, Polygon) are planned.​
  • Swaps: Ethereum, Base, Arbitrum, Optimism, Kaia.​
📘

Suggestion

Representative UI screenshots for these features are available in Appendix A and can be adapted as inline illustrations or callout images in this page.​


Widget Deployment

Each customer receives a dedicated widget deployment hosted at:

https://<client-slug>.widget.blockdaemon.com

Blockdaemon manages the deployment lifecycle, upgrades, and configuration of the widget instance. A client-specific slug will be provided as part of your implementation onboarding.​

📘

Suggestion

Suggested visual: Small screenshot of a live widget panel embedded in a generic “host app” frame.​


Embedding the Widget

To embed the widget, add the iframe to the relevant view or component in your application:​

`<iframe`  
`id="blockdaemon-widget"`  
`src="https://<client-slug>.widget.blockdaemon.com"`  
`title="Blockdaemon Earn Widget"`  
`allow="clipboard-write"`  
`style="width: 100%; height: 100%;">`  
`</iframe>`

Consider the following when embedding:​

  • Container sizing: Place the iframe in a responsive container; typical layouts use full-width in a main content column or a fixed-height panel in a dashboard card.​
  • Scroll behavior: Decide whether scrolling should occur inside the widget or in the page; this is controlled by your container and CSS rather than the widget itself.​
  • Security & CSP: Ensure your Content Security Policy (CSP) allows the https://<client-slug>.widget.blockdaemon.com origin for iframes and any required scripts.​

Configuration Model

Blockdaemon currently manages widget configuration on your behalf; self-serve configuration will be provided via the Blockdaemon Partner Portal in a future release. Configuration can be applied per widget instance, with certain parameters also available via URL query parameters.​

📘

Suggestion

Suggested visual: JSON configuration excerpt in a code block, next to a labeled UI screenshot highlighting affected areas (features toggled, theme, logo, etc.).​

Features Configuration

The widget’s functionality is controlled through a features configuration object:​

"features": {

   "portfolio": { "enabled": false },
   "staking": { "enabled": true },
   "swap": {
     "enabled": false,
     "chains": { "allowList": [], "blockList": [] },
     "assets": { "allowList": [], "blockList": [] },
     "dexes": { "allowList": [], "blockList": [ ] },
     "bridges": { "allowList": [], "blockList": [] },
     "fees": { "enabled": false }
   },

   "defi": {
     "enabled": true,
     "markets": [],
     "chains": { "allowList": [], "blockList": [] },
     "assets": { "allowList": [], "blockList": [] },
     "customVaults": false
   },
   "walletInfo": false,
   "walletMode": "internal/external"
 }

Typical configuration patterns include:​

  • Enabling only staking for a particular chain or product line.
  • Restricting swap or DeFi to a curated allow-list of assets, chains, or markets.
  • Selecting wallet mode (internal vs external) to match your custody or wallet strategy.

Configuration changes are coordinated with your Blockdaemon contact and applied to your dedicated widget deployment.​


Appearance & Branding

The widget supports appearance configuration to align with your brand and layout:​

json

 "appearance": {
   "width": "mobile"
   "height": "mobile",
   "theme": "light",
   "builtByBlockdaemon": true,
   "logoUrl": "",
   "locale": "en-US",
   "currency": "USD"
 }

Key options:​

  • Dimensions: width and height presets (e.g. “mobile”) can be tuned to your layout; custom sizing is typically handled via the iframe container.​
  • Theme & branding: theme, logoUrl, and builtByBlockdaemon flags control visual presentation and co-branding.​
  • Locale & currency: locale and currency determine language and display currency for balances and yields.​
📘

Suggestion

Suggested visual: Side-by-side light vs dark theme screenshots, branded vs unbranded widget variants.​


Wallet Integration Modes

The widget supports two wallet integration modes:​

  1. Internal mode
    The widget renders its own wallet connection bar, and end users connect wallets directly within the widget UI.​
  2. External mode
    Your application owns wallet connectivity and injects wallet state into the widget via postMessage.​

In both modes, wallet connectivity is non-custodial and your application remains in control of user session and authentication outside the widget.​

📘

Suggestion

Suggested visual: Diagram showing “Host App Wallet” vs “Widget Wallet Bar”, plus before/after screenshots of the widget with disconnected and connected wallet states.​

Before a wallet is connected, the widget displays a default, disconnected state; once a wallet is connected, the widget updates to a fully interactive state (see Appendix A screenshots).​


External Wallet Mode: Messaging Contract

When using external wallet mode, the host application and the widget communicate via the standard window.postMessage API. All messages must be filtered by origin, and only the widget origin (https://<client-slug>.widget.blockdaemon.com) should be trusted.​

Message Types

The widget may send the following message types to your application:​

  • getWalletState: Request the current wallet state.
  • connectWallet: Request that your app initiate a wallet connection flow.
  • disconnectWallet: Request that your app disconnect the current wallet.
  • sendTransaction: Request that your app submit a transaction on behalf of the user.​

Your application is expected to respond with:​

  • walletState: Current wallet state (e.g. isConnected, address, chainId, and optional walletInfo).
  • sendTransactionResponse: Result of a requested transaction, including success flag, transaction hash, and any error details.​

Example: App ↔ Widget Integration

Below is a reference implementation illustrating event handling and wallet state propagation:​

<script>
    const iframe = document.getElementById('blockdaemon-widget');
    
    // Your app's wallet state (you manage this)
    let walletState = {
        isConnected: false,
        address: null,
        chainId: null,
        walletInfo: "Client Wallet"
    };
    
    // Listen for messages FROM the widget
    window.addEventListener('message', function(event) {
        // Verify origin for security
        if (event.origin !== 'https://<client-slug>.widget.blockdaemon.com') {
            return;
        }
        
        const { type, data } = event.data;
        
        switch (type) {
            case 'getWalletState':
                // Widget is requesting wallet state - send it
                sendWalletState();
                console.log('Widget requested wallet state');
                break;
                
            case 'connectWallet':
                // Widget wants to connect wallet - trigger your wallet connection
                connectYourWallet();
                console.log('Widget requested wallet connection');
                break;
                
            case 'disconnectWallet':
                // Widget wants to disconnect - trigger your wallet disconnection
                disconnectYourWallet();
                console.log('Widget requested wallet disconnection');
                break;
                
            case 'sendTransaction':
                // Widget wants to send a transaction
                handleTransaction(data);
                console.log('Widget requested transaction:', data);
                break;
        }
    });
    
    // Send wallet state TO the widget
    function sendWalletState() {
        iframe.contentWindow.postMessage({
            type: 'walletState',
            data: walletState
        }, 'https://<client-slug>.widget.blockdaemon.com');
    }
    
    // Your wallet connection logic
    function connectYourWallet() {
        // Implement your wallet connection logic here
        // Then update walletState and notify the widget
        walletState = {
            isConnected: true,
            address: '0x1234...', // Your connected address
            chainId: 1, // Current network
            walletInfo: "Client Wallet"
        };
        sendWalletState();
    }
    
    function disconnectYourWallet() {
        // Implement your wallet disconnection logic
        walletState = {
            isConnected: false,
            address: null,
            chainId: null,
            walletInfo: "Client Wallet"
        };
        sendWalletState();
    }
    
    function handleTransaction(transactionData) {
        // Implement your transaction sending logic
        // Send response back to widget
        iframe.contentWindow.postMessage({
            type: 'sendTransactionResponse',
            success: true, // or false
            data: { hash: '0xtxhash...' }, // transaction result
            error: null // or error message if failed
        }, 'https://<client-slug>.widget.blockdaemon.com');
    }
    
    // Send initial wallet state when iframe loads
    iframe.addEventListener('load', function() {
        setTimeout(() => {
            sendWalletState();
        });
    });
</script>
📘

Suggestion

Suggested visual: Sequence diagram showing message flow for connectWallet and sendTransaction between host app and widget.​


Implementation Checklist

📘

Suggestion

Suggested tile or callout box: “Go-live checklist” summarizing the bullets below.​

When preparing to go live, typical steps include:​

  • Confirm your https://<client-slug>.widget.blockdaemon.com deployment and target environment (staging vs production).
  • Embed and size the iframe appropriately within your UI.
  • Align features configuration with your product scope (staking, DeFi, swaps) and regulatory requirements.
  • Configure appearance to meet brand, theme, locale, and currency guidelines.
  • Select wallet mode (internal vs external) and, for external mode, implement the postMessage integration contract.
  • Validate transaction flows, balances, and lifecycle (connect/transact/disconnect) in your staging environment.

Appendix A: UI Examples

Appendix A provides example screenshots of the widget in different modes and product views for reference.​

ScenarioExample UI
Staking – Ethereum (Stakewise vaults), Solana coming soonStaking overview and position details screenshots.​
DeFi lending – Aave (Morpho coming soon): Ethereum, Base, Arbitrum, Optimism; additional chains plannedLending market selection and position views.​
Swaps – Ethereum, Base, Arbitrum, Optimism, KaiaSwap route and confirmation screens.​
📘

Suggestion

Suggested visual: Use the screenshots as inline figures within the relevant sections above (Staking, DeFi, Swaps), rather than only in an appendix.​


Next Steps and Support

For configuration changes, production cutover, or to discuss additional feature flags and chains, please contact your Blockdaemon representative or support channel. Blockdaemon can work with you to align widget behavior, branding, and wallet flows with your institutional requirements.​