JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 4
  • Score
    100M100P100Q42687F
  • License MIT

A NextJS component that populates meta tags based on API key

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 rootstockwinks

Quick 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 start

Then 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-id

Get 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 build

Running Tests

npm test

Publishing

npm publish

License

MIT

Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request