Transfer Actions
Simple & Interactive Native Token Transfers
Transfer Actions are designed for simple, user-friendly native token transfers (ETH, AVAX, CELO). They provide the easiest way to send blockchain native currencies with built-in interactive UI components - no ABI knowledge required.
Why Transfer Actions?
Unlike Blockchain Actions that require contract knowledge, or Dynamic Actions that need server logic, Transfer Actions are:
- Purpose-built for native token transfers
- Highly interactive with built-in UI configurability
- Zero complexity - no ABIs, no contracts, just send tokens
- Mobile-optimized with beautiful selection interfaces
- Instant setup - works in minutes, not hours
Interface
interface TransferAction {
type: 'transfer';
label: string; // Button text shown to users
description?: string; // Optional help text
chains: ChainContext; // Source and optional destination
// Simple Configuration (fixed values)
to?: `0x${string}`; // Fixed recipient address
amount?: number; // Fixed amount in native units
// Interactive Configuration (user choices)
recipient?: RecipientConfig; // Let user choose recipient
amountConfig?: AmountConfig; // Let user choose amount
}
Configuration Options
Simple Fixed Transfers
For straightforward transfers with predetermined values:
const simpleDonation: TransferAction = {
type: 'transfer',
label: 'Donate 0.1 AVAX',
description: 'Support our project development',
chains: { source: 43114 },
to: '0x742d35Cc6734C0532925a3b8D4ccd306f6F4B26C',
amount: 0.1,
};
Interactive Recipient Selection
Let users choose from predefined recipients:
const charityDonation: TransferAction = {
type: 'transfer',
label: 'Support a Cause',
description: 'Choose your preferred charity',
chains: { source: 42220 },
recipient: {
type: 'select',
label: 'Select Charity',
required: true,
options: [
{
label: 'Education Fund 🎓',
value: '0x1234567890123456789012345678901234567890',
description: 'Supporting education initiatives worldwide',
},
{
label: 'Climate Action 🌍',
value: '0x2345678901234567890123456789012345678901',
description: 'Fighting climate change through technology',
},
{
label: 'Healthcare Access 🏥',
value: '0x3456789012345678901234567890123456789012',
description: 'Improving healthcare in underserved communities',
},
],
},
amount: 0.05, // Fixed amount, user chooses recipient
};
Interactive Amount Selection
Let users choose from predefined amounts:
const creatorTipping: TransferAction = {
type: 'transfer',
label: 'Tip Creator',
description: 'Show appreciation for great content',
chains: { source: 43114 },
to: '0x9876543210987654321098765432109876543210', // Fixed recipient
amountConfig: {
type: 'radio',
label: 'Tip Amount',
required: true,
options: [
{
label: 'Coffee ☕',
value: 0.01,
description: '0.01 AVAX (~$0.50)',
},
{
label: 'Lunch 🍕',
value: 0.05,
description: '0.05 AVAX (~$2.50)',
},
{
label: 'Dinner 🍽️',
value: 0.1,
description: '0.1 AVAX (~$5.00)',
},
{
label: 'Generous 💰',
value: 0.5,
description: '0.5 AVAX (~$25.00)',
},
],
},
};
Fully Interactive (Both Recipient and Amount)
Let users customize everything:
const flexiblePayment: TransferAction = {
type: 'transfer',
label: 'Send Payment',
description: 'Send AVAX to team members',
chains: { source: 43114 },
recipient: {
type: 'select',
label: 'Team Member',
required: true,
options: [
{
label: 'Alice - Frontend Dev 👩💻',
value: '0x1111111111111111111111111111111111111111',
description: 'Lead Frontend Developer',
},
{
label: 'Bob - Backend Dev 👨💻',
value: '0x2222222222222222222222222222222222222222',
description: 'Senior Backend Engineer',
},
{
label: 'Carol - Designer 🎨',
value: '0x3333333333333333333333333333333333333333',
description: 'UI/UX Designer',
},
],
},
amountConfig: {
type: 'select',
label: 'Payment Amount',
required: true,
options: [
{
label: 'Bonus Payment',
value: 0.5,
description: '0.5 AVAX bonus',
},
{
label: 'Weekly Salary',
value: 2.0,
description: '2.0 AVAX weekly',
},
{
label: 'Project Completion',
value: 5.0,
description: '5.0 AVAX milestone',
},
],
},
};
Cross-Chain Transfers
Transfer Actions support cross-chain operations:
const crossChainTransfer: TransferAction = {
type: 'transfer',
label: 'Bridge to Celo',
description: 'Send tokens from Avalanche to Celo network',
chains: {
source: 43114,
destination: 42220,
},
// When neither to/amount nor configs are specified,
// user gets standard input fields for both
};
Configuration Interfaces
RecipientConfig
interface RecipientConfig {
type?: 'select' | 'radio'; // UI component type
label?: string; // Field label
description?: string; // Help text
required?: boolean; // Is selection required
defaultValue?: `0x${string}`; // Default selection
options?: SelectOption[]; // Predefined recipients
}
AmountConfig
interface AmountConfig {
type?: 'select' | 'radio'; // UI component type
label?: string; // Field label
description?: string; // Help text
required?: boolean; // Is selection required
defaultValue?: number; // Default amount
options?: SelectOption[]; // Predefined amounts
}
SelectOption
interface SelectOption {
label: string; // Display text
value: string | number; // Actual value (address or amount)
description?: string; // Optional help text
}
Advanced Examples
Social Media Tipping with Context
const contextualTipping: TransferAction = {
type: 'transfer',
label: 'Tip for this Post',
description: 'Reward quality content creation',
chains: { source: 42220 },
to: '0xContentCreatorAddress',
amountConfig: {
type: 'radio',
label: 'How much did you enjoy this?',
required: true,
options: [
{
label: 'Liked it 👍',
value: 0.01,
description: '0.01 CELO - Quick appreciation',
},
{
label: 'Loved it ❤️',
value: 0.05,
description: '0.05 CELO - Great content!',
},
{
label: 'Mind blown 🤯',
value: 0.1,
description: '0.1 CELO - This was amazing!',
},
],
},
};
Crowdfunding with Milestones
const crowdfunding: TransferAction = {
type: 'transfer',
label: 'Fund This Project',
description: 'Help us reach our funding goal',
chains: { source: 43114 },
to: '0xProjectFundingAddress',
amountConfig: {
type: 'select',
label: 'Contribution Level',
required: true,
options: [
{
label: 'Supporter 🙌',
value: 0.1,
description: '0.1 AVAX - Every bit helps!',
},
{
label: 'Believer 💪',
value: 0.5,
description: '0.5 AVAX - You believe in us!',
},
{
label: 'Champion 🏆',
value: 1.0,
description: '1.0 AVAX - Major supporter!',
},
{
label: 'Hero 🦸',
value: 5.0,
description: '5.0 AVAX - Project hero status!',
},
],
},
};
Split Payment System
const splitPayment: TransferAction = {
type: 'transfer',
label: 'Pay Team Share',
description: 'Distribute project earnings',
chains: { source: 43113 },
recipient: {
type: 'radio',
label: 'Team Member (Equal Split)',
required: true,
options: [
{
label: 'Development Team (40%)',
value: '0xDevTeamMultisig',
description: '4 developers, 10% each',
},
{
label: 'Marketing Team (30%)',
value: '0xMarketingTeamMultisig',
description: '3 marketers, 10% each',
},
{
label: 'Operations (20%)',
value: '0xOperationsAddress',
description: 'Infrastructure and support',
},
{
label: 'Reserve Fund (10%)',
value: '0xReserveFundAddress',
description: 'Emergency fund',
},
],
},
amountConfig: {
type: 'select',
label: 'Distribution Amount',
required: true,
options: [
{ label: 'Weekly Distribution', value: 0.5 },
{ label: 'Monthly Distribution', value: 2.0 },
{ label: 'Quarterly Distribution', value: 6.0 },
],
},
};
UI Components Generated
Select Component (Dropdown)
type: 'select';
// Renders as:
// [Select Recipient ▼]
// ├─ Education Fund 🎓
// ├─ Climate Action 🌍
// └─ Healthcare Access 🏥
Radio Component (Button Group)
type: 'radio';
// Renders as:
// ○ Coffee ☕ (0.01 AVAX)
// ○ Lunch 🍕 (0.05 AVAX)
// ● Dinner 🍽️ (0.1 AVAX) [selected]
Validation
Transfer Actions automatically validate:
- Address format - Ensures valid Ethereum addresses
- Amount ranges - Prevents negative or excessive amounts
- Chain compatibility - Verifies supported chains
- Required fields - Enforces required selections
- Option existence - Ensures selected options are valid
// Validation happens automatically
import { createMetadata } from '@sherrylinks/sdk';
try {
const validated = createMetadata({
// ... your metadata with transfer actions
});
console.log('✅ Transfer actions validated');
} catch (error) {
console.error('❌ Validation failed:', error.message);
}
Comparison with Other Action Types
Feature | Transfer Action | Blockchain Action | Dynamic Action |
---|---|---|---|
Purpose | Native token transfers | Contract interactions | Complex server logic |
Complexity | Simple | Medium | Advanced |
Setup Time | Minutes | Hours | Days |
ABI Required | No | Yes | No |
Server Logic | No | No | Yes |
UI Configurability | High | Medium | Medium |
Gas Efficiency | High | Medium | Variable |
When to Use Transfer Actions
Perfect for:
- Tips and donations
- Social media rewards
- Simple payments
- Crowdfunding contributions
- Team payouts
- Event ticket purchases (native token)
- Membership fees
- Content creator support
Not suitable for:
- Token transfers (ERC-20) - use Blockchain Actions
- Complex DeFi operations - use Dynamic Actions
- Multi-step workflows - use Action Flows
- Contract function calls - use Blockchain Actions
Best Practices
1. Make Options Descriptive
// Good - Clear context and value
{
label: 'Premium Support 💎',
value: 0.1,
description: '0.1 AVAX - Priority support for 1 month'
}
// Avoid - Unclear value proposition
{ label: 'Option 1', value: 0.1 }
2. Use Appropriate UI Components
// Radio for 2-5 options (visual comparison)
type: 'radio'; // Good for tip amounts
// Select for 5+ options (saves space)
type: 'select'; // Good for many recipients
3. Provide Context in Descriptions
{
label: 'Monthly Subscription',
description: 'Renews automatically, cancel anytime'
}
4. Use Meaningful Defaults
amountConfig: {
defaultValue: 0.05, // Common tip amount
options: [/* ... */]
}
5. Group Related Options
// Group by purpose or value range
options: [
// Small tips
{ label: 'Quick Thanks ☕', value: 0.01 },
{ label: 'Nice Work 👍', value: 0.02 },
// Medium tips
{ label: 'Great Content 🔥', value: 0.05 },
{ label: 'Excellent Post ⭐', value: 0.1 },
// Large tips
{ label: 'Outstanding 🏆', value: 0.5 },
{ label: 'Life Changing 🚀', value: 1.0 },
];
Common Patterns
Pattern 1: Fixed Recipient, Variable Amount
// Use case: Tipping a content creator
{
to: '0xCreatorAddress', // Fixed
amountConfig: { /* variable amounts */ }
}
Pattern 2: Variable Recipient, Fixed Amount
// Use case: Equal donations to different charities
{
amount: 0.1, // Fixed
recipient: { /* different charities */ }
}
Pattern 3: Both Variable
// Use case: Flexible team payments
{
recipient: { /* team members */ },
amountConfig: { /* payment amounts */ }
}
Pattern 4: Both Fixed
// Use case: Simple one-click donation
{
to: '0xCharityAddress',
amount: 0.05
}
Next Steps
- Dynamic Actions - For complex server-side logic
- Blockchain Actions - For contract interactions
- Action Flows - Combine transfers in multi-step workflows
- Parameters Guide - Advanced parameter configuration