What are Blockchain Links? (Blinks)

icon picker
Implementing Solana Blinks

Detect Action URLs:
• Implement a mechanism to detect and handle Action URLs.
const actionUrl = 'solana-action://https://actions.example.com/transaction';

if (actionUrl.startsWith('solana-action:')) {
// Process the Action URL
}
Render Blinks:
• Use Blinks clients to render the actions.
const blink = new BlinkClient();
blink.render(actionUrl);
Advanced Implementation
Interstitial URLs: Use interstitial URLs to specify the client and action for signing.
const interstitialUrl = 'https://backpack.app/?action=solana-action:https://actions.example.com/transaction';
window.location.href = interstitialUrl;
Custom Client Integration: Build custom clients to render and handle Action URLs in unique environments.
class CustomBlinkClient {
constructor() {
// Custom client logic
}

render(actionUrl) {
// Render the action URL
}
}

const customBlink = new CustomBlinkClient();
customBlink.render(actionUrl);
Basic Implementation
1. Install Blinks SDK:
# npm
npm install @dialectlabs/blinks

# yarn
yarn add @dialectlabs/blinks
2. Add the Blink Component to Your dApp:
import '@dialectlabs/blinks/index.css';
import { useState, useEffect } from 'react';
import { Action, Blink } from "@dialectlabs/blinks";
import { useAction } from '@dialectlabs/blinks/react';

const App = () => {
const actionApiUrl = 'https://actions.example.com/transaction';
const { action } = useAction(actionApiUrl, { rpcUrlOrConnection: YOUR_CONNECTION_OR_RPC });

return action ? <Blink action={action} websiteText={new URL(actionApiUrl).hostname} /> : null;
};

3. Use Action Hooks:
• useAction hook: Fetches the action, sets up an adapter, and refreshes the registry every 10 minutes.
• Ensure your component tree has <WalletProvider /> and <WalletModalProvider /> above the component using the hook.
Advanced Implementation
1. Using Multiple Actions:
import { useState, useEffect, useMemo } from 'react';
import { Action, Blink, type ActionAdapter } from "@dialectlabs/blinks";
import { useActionAdapter, useActionsRegistryInterval } from '@dialectlabs/blinks/react';

const App = () => {
const { isRegistryLoaded } = useActionsRegistryInterval();
const { adapter } = useActionAdapter(YOUR_RPC_URL_OR_CONNECTION);

return isRegistryLoaded ? <ManyActions adapter={adapter} /> : null;
};

const ManyActions = ({ adapter }) => {
const apiUrls = useMemo(() => ['https://actions.example.com/transaction1', 'https://actions.example.com/transaction2'], []);
const [actions, setActions] = useState([]);

useEffect(() => {
const fetchActions = async () => {
const promises = apiUrls.map(url => Action.fetch(url).catch(() => null));
const results = await Promise.all(promises);
setActions(results.filter(Boolean));
};

fetchActions();
}, [apiUrls]);

useEffect(() => {
actions.forEach(action => action.setAdapter(adapter));
}, [actions, adapter]);

return actions.map(action => (
<div key={action.url} className="flex gap-2">
<Blink action={action} websiteText={new URL(action.url).hostname} />
</div>
));
};
2. Customizing Blink Styles:
import { Blink } from '@dialectlabs/blinks';

return <Blink stylePreset="x-dark" action={action} websiteText={new URL(action.url).hostname} />;
Override CSS Variables:
.blink.x-dark {
--blink-bg-primary: #202327;
--blink-button: #1d9bf0;
--blink-icon-primary: #6e767d;
// Add other overrides as needed
}
3. Render Blinks via Chrome Extensions:
import { setupTwitterObserver } from "@dialectlabs/blinks/ext/twitter";
import { ActionConfig, ActionContext } from "@dialectlabs/blinks";

setupTwitterObserver(new ActionConfig(YOUR_RPC_URL, {
signTransaction: async (tx, context) => { /* signing logic */ },
connect: async (context) => { /* connection logic */ }
}));
Want to print your doc?
This is not the way.
Try clicking the ⋯ next to your doc name or using a keyboard shortcut (
CtrlP
) instead.