Package Exports
- rootstockwinks
- rootstockwinks/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (rootstockwinks) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Winks
A NextJS component that automatically populates meta tags based on your API key. Perfect for SEO optimization and social media sharing.
Features
- 🚀 Easy Integration: Simple wrapper component for NextJS apps
- 🔑 API Key Based: Secure metadata management with unique API keys
- 📱 Social Media Ready: Automatic Open Graph and Twitter Card tags
- 🎯 SEO Optimized: Complete meta tag management
- ⚡ Lightweight: Minimal bundle size impact
- 💰 Simple Token Functions: Direct ERC-20 token transfer functions
- 🎨 NFT Support: Simple ERC-721/ERC-1155 NFT functions
- 🔐 Token Approval: Direct token approval functions
- 🔗 Rootstock Ready: Built for Rootstock network
- 🌐 Wallet Integration: RainbowKit & WalletConnect support for 300+ wallets
- ✍️ Signature Management: Transaction, message, and typed data signing
- 🔄 Network Switching: Seamless Rootstock mainnet/testnet switching
Installation
npm install rootstockwinksQuick Start
1. Wrap your React app with Winks
// pages/_app.js or app/layout.js
import { Winks } from 'rootstockwinks';
export default function App({ Component, pageProps }) {
return (
<Winks apikey="your-api-key-here">
<Component {...pageProps} />
</Winks>
);
}2. Create an API key and set metadata
First, start the Winks server:
cd server
npm install
npm run build
npm startThen create an API key:
curl -X POST http://localhost:3001/api/keys \
-H "Content-Type: application/json" \
-d '{"name": "My Website"}'Set your metadata:
curl -X POST http://localhost:3001/api/meta/YOUR_API_KEY \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"title": "My Awesome Website",
"description": "The best website ever created",
"keywords": "awesome, website, nextjs",
"ogTitle": "My Awesome Website",
"ogDescription": "The best website ever created",
"ogImage": "https://example.com/og-image.jpg",
"ogUrl": "https://example.com",
"twitterCard": "summary_large_image",
"twitterTitle": "My Awesome Website",
"twitterDescription": "The best website ever created",
"twitterImage": "https://example.com/twitter-image.jpg",
"canonical": "https://example.com",
"robots": "index, follow",
"viewport": "width=device-width, initial-scale=1",
"charset": "utf-8",
"author": "Your Name"
}'API Reference
Winks Component Props
| Prop | Type | Required | Description |
|---|---|---|---|
apikey |
string | Yes | Your unique API key |
children |
ReactNode | Yes | Your NextJS app components |
fallback |
MetaData | No | Fallback metadata if API fails |
MetaData Interface
interface MetaData {
title?: string;
description?: string;
keywords?: string;
ogTitle?: string;
ogDescription?: string;
ogImage?: string;
ogUrl?: string;
twitterCard?: string;
twitterTitle?: string;
twitterDescription?: string;
twitterImage?: string;
canonical?: string;
robots?: string;
viewport?: string;
charset?: string;
author?: string;
}Server API Endpoints
Create API Key
POST /api/keys
Content-Type: application/json
{
"name": "My Website"
}Set Metadata
POST /api/meta/{apiKey}
X-API-Key: {apiKey}
Content-Type: application/json
{
"metadata": {
"title": "My Website",
"description": "Description here"
}
}Get Metadata
GET /api/meta/{apiKey}Examples
Basic Usage
import { Winks } from 'rootstockwinks';
export default function Layout({ children }) {
return (
<Winks apikey="winks_abc123_def456">
{children}
</Winks>
);
}With Fallback Data
import { Winks } from 'rootstockwinks';
export default function Layout({ children }) {
const fallbackData = {
title: "Default Title",
description: "Default description",
ogTitle: "Default OG Title"
};
return (
<Winks
apikey="winks_abc123_def456"
fallback={fallbackData}
>
{children}
</Winks>
);
}Simple Token Transfer Functions
import { transferERC20, getNFTOwner, transferNFT, approveToken } from 'rootstockwinks';
import { ethers } from 'ethers';
// Initialize provider and signer
const provider = new ethers.BrowserProvider(window.ethereum);
const signer = await provider.getSigner();
// Transfer ERC-20 tokens
const txHash = await transferERC20(
'0x1234567890123456789012345678901234567890', // Token address
'0x0987654321098765432109876543210987654321', // Recipient address
'1.0', // Amount
signer
);
// Get NFT owner
const owner = await getNFTOwner(
'0x1234567890123456789012345678901234567890', // NFT contract address
'123', // Token ID
provider
);
// Transfer NFT
const txHash = await transferNFT(
'0x1234567890123456789012345678901234567890', // NFT contract address
'0x1111111111111111111111111111111111111111', // From address
'0x2222222222222222222222222222222222222222', // To address
'123', // Token ID
signer
);
// Approve tokens
const txHash = await approveToken(
'0x1234567890123456789012345678901234567890', // Token address
'0x3333333333333333333333333333333333333333', // Spender address
'100.0', // Amount to approve
signer
);Additional Utility Functions
import { getTokenBalance, getERC1155Balance, getTokenAllowance } from 'rootstockwinks';
// Get ERC-20 token balance
const balance = await getTokenBalance(
'0x1234567890123456789012345678901234567890', // Token address
'0x1111111111111111111111111111111111111111', // Account address
provider
);
// Get ERC-1155 token balance
const balance = await getERC1155Balance(
'0x1234567890123456789012345678901234567890', // Contract address
'123', // Token ID
'0x1111111111111111111111111111111111111111', // Account address
provider
);
// Get token allowance
const allowance = await getTokenAllowance(
'0x1234567890123456789012345678901234567890', // Token address
'0x1111111111111111111111111111111111111111', // Owner address
'0x3333333333333333333333333333333333333333', // Spender address
provider
);Wallet Integration
The SDK includes comprehensive wallet integration powered by RainbowKit and WalletConnect, supporting 300+ wallets with advanced signature management.
Setup
1. Environment Variables
Create a .env.local file in your project root:
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID=your-walletconnect-project-idGet your WalletConnect Project ID from WalletConnect Cloud.
2. Wrap Your App with WalletProvider
// pages/_app.js or app/layout.js
import { WalletProvider } from 'rootstockwinks';
export default function App({ Component, pageProps }) {
return (
<WalletProvider>
<Component {...pageProps} />
</WalletProvider>
);
}Basic Wallet Connection
Use the pre-built WalletConnection component:
import { WalletConnection } from 'rootstockwinks';
function MyComponent() {
return (
<div>
<WalletConnection
showBalance={true}
showNetwork={true}
/>
</div>
);
}Advanced Wallet Integration Hook
Use the useWalletIntegration hook for advanced wallet functionality:
import { useWalletIntegration } from 'rootstockwinks';
function WalletDemo() {
const {
walletState,
connectWallet,
switchToRootstockMainnet,
switchToRootstockTestnet,
requestMessageSignature,
requestPersonalSignature,
sendTransaction
} = useWalletIntegration();
const handleConnect = async () => {
const result = await connectWallet();
if (result.success) {
console.log('Connected:', result.data.address);
}
};
const handleSignMessage = async () => {
const result = await requestMessageSignature('Hello Rootstock!');
if (result.success) {
console.log('Signature:', result.data.signature);
}
};
return (
<div>
<p>Connected: {walletState.isConnected ? 'Yes' : 'No'}</p>
<p>Address: {walletState.address}</p>
<p>Network: {walletState.isRootstock ? 'Rootstock' : 'Other'}</p>
<p>Balance: {walletState.balance} RBTC</p>
<button onClick={handleConnect}>Connect Wallet</button>
<button onClick={handleSignMessage}>Sign Message</button>
</div>
);
}Enhanced Token Transfer Hook
Use the useEnhancedTokenTransfer hook for better error handling and network management:
import { useEnhancedTokenTransfer } from 'rootstockwinks';
function TokenTransferDemo() {
const {
transferERC20,
transferNFT,
approveToken,
getTokenBalance,
getNFTOwner,
getTokenAllowance,
address,
isConnected,
ensureRootstockNetwork
} = useEnhancedTokenTransfer();
const handleTransfer = async () => {
// Ensure we're on Rootstock network
const isRootstock = await ensureRootstockNetwork();
if (!isRootstock) {
alert('Please switch to Rootstock network');
return;
}
const result = await transferERC20({
tokenAddress: '0x...',
recipientAddress: '0x...',
amount: '1.0',
decimals: 18
});
if (result.success) {
console.log('Transaction Hash:', result.txHash);
} else {
console.error('Error:', result.error);
}
};
return (
<div>
{isConnected ? (
<button onClick={handleTransfer}>Transfer Token</button>
) : (
<p>Please connect your wallet first</p>
)}
</div>
);
}Signature Management
The SDK provides comprehensive signature management capabilities:
import { SignatureManager } from 'rootstockwinks';
import { ethers } from 'ethers';
const provider = new ethers.BrowserProvider(window.ethereum);
const signatureManager = new SignatureManager(provider);
// Sign a transaction
const transaction = {
to: '0x...',
value: ethers.parseEther('0.1'),
gasLimit: 21000
};
const txResult = await signatureManager.requestTransactionSignature(transaction);
// Sign a message
const messageResult = await signatureManager.requestMessageSignature('Hello World');
// Sign personal message
const personalResult = await signatureManager.requestPersonalSignature('Personal message');
// Sign typed data (EIP-712)
const typedData = {
domain: {
name: 'MyApp',
version: '1',
chainId: 30,
verifyingContract: '0x...'
},
types: {
Person: [
{ name: 'name', type: 'string' },
{ name: 'wallet', type: 'address' }
]
},
value: {
name: 'Alice',
wallet: '0x...'
}
};
const typedResult = await signatureManager.requestTypedDataSignature(typedData);Network Management
Switch between Rootstock mainnet and testnet:
const { switchToRootstockMainnet, switchToRootstockTestnet } = useWalletIntegration();
// Switch to mainnet
await switchToRootstockMainnet();
// Switch to testnet
await switchToRootstockTestnet();Network Configuration
Rootstock Mainnet
- Chain ID: 30
- RPC URL:
https://public-node.rsk.co - Explorer:
https://explorer.rootstock.io - Currency: RBTC
Rootstock Testnet
- Chain ID: 31
- RPC URL:
https://public-node.testnet.rsk.co - Explorer:
https://explorer.testnet.rootstock.io - Currency: tRBTC
Wallet Integration API Reference
WalletProvider Props
<WalletProvider>
{children}
</WalletProvider>WalletConnection Props
interface WalletConnectionProps {
showBalance?: boolean; // Show wallet balance (default: true)
showNetwork?: boolean; // Show network info (default: true)
customButton?: React.ReactNode; // Custom button component
}useWalletIntegration Returns
{
walletState: WalletState;
connectWallet(): Promise<WalletIntegrationResult>;
disconnectWallet(): Promise<WalletIntegrationResult>;
switchToRootstockMainnet(): Promise<WalletIntegrationResult>;
switchToRootstockTestnet(): Promise<WalletIntegrationResult>;
requestTransactionSignature(tx): Promise<WalletIntegrationResult>;
requestMessageSignature(message): Promise<WalletIntegrationResult>;
requestPersonalSignature(message): Promise<WalletIntegrationResult>;
requestTypedDataSignature(typedData): Promise<WalletIntegrationResult>;
sendTransaction(to, value, data): Promise<WalletIntegrationResult>;
}useEnhancedTokenTransfer Returns
{
transferERC20(params): Promise<EnhancedTransferResult>;
transferNFT(params): Promise<EnhancedTransferResult>;
approveToken(params): Promise<EnhancedTransferResult>;
getTokenBalance(tokenAddress, accountAddress): Promise<string>;
getNFTOwner(contractAddress, tokenId): Promise<string>;
getTokenAllowance(tokenAddress, ownerAddress, spenderAddress): Promise<string>;
requestMessageSignature(message): Promise<EnhancedTransferResult>;
requestPersonalSignature(message): Promise<EnhancedTransferResult>;
address: string | undefined;
isConnected: boolean;
chain: Chain | undefined;
}For detailed wallet integration documentation, see WALLET_INTEGRATION.md.
Development
Building the Package
npm run buildRunning Tests
npm testPublishing
npm publishLicense
MIT
Contributing
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request