Skip to main content

Usage

const {
  transfer,
  transferAsync,
  data,
  isLoading,
  isError,
  error,
  isSuccess,
  reset,
} = useTransfer();

Parameters

  • transfer / transferAsync both accept an object with:
    • params (TransferHookInput):
      • encryptKey (string): PIN used to decrypt the private key.
      • wallet (WalletData): Object with publicKey and encryptedPrivateKey.
      • token (ChainToken): Token identifier (for example: "USDC").
      • otherToken (optional): Custom token configuration with:
        • contractAddress (string): ERC-20 token contract address.
        • decimals (number): Token decimals.
      • recipient (string): Destination wallet address.
      • amount (number): Transfer amount (will be converted to a string internally).
    • bearerToken (string): Bearer token for authentication (e.g. from your auth provider).

Return Value

Returns an object containing:
  • transfer: Function to trigger the transfer (fire-and-forget style).
  • transferAsync: Promise-based function that resolves with the transaction hash.
  • data: Transaction hash of the transfer (string | undefined).
  • isLoading: Boolean indicating if the operation is in progress.
  • isError: Boolean indicating if an error occurred.
  • error: Error instance when isError is true, otherwise null.
  • isSuccess: Boolean indicating if the transfer completed successfully.
  • reset: Function to reset the mutation state.

Example Implementation

export function TransferForm() {
  const { transferAsync, data, isLoading, isError, error } = useTransfer();
  const [form, setForm] = useState({
    pin: '',
    recipient: '',
    amount: ''
  });

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    const { getBearerToken } = useAuth();
    const bearerToken = await getBearerToken();

    try {
      await transferAsync({
        params: {
          amount: Number(form.amount),
          encryptKey: form.pin,
          wallet: {
            publicKey: "0x123...yourPublicKeyHere",
            encryptedPrivateKey: "encrypted:key:data"
          },
          token: "USDC" as ChainToken,
          recipient: form.recipient
        },
        bearerToken,
      });
    } catch (err) {
      console.error('Transfer failed:', err);
    }}
  };

  return (
    <div className="bg-white rounded-xl shadow-lg p-6">
      <h2 className="text-2xl font-bold mb-4">Transfer Tokens</h2>
      
      <form onSubmit={handleSubmit} className="space-y-4">
        <div>
          <label className="block text-sm font-medium mb-1">Security PIN</label>
          <input
            type="password"
            value={form.pin}
            onChange={(e) => setForm({...form, pin: e.target.value})}
            className="w-full p-2 border rounded-md"
            required
          />
        </div>

        <div>
          <label className="block text-sm font-medium mb-1">Recipient Address</label>
          <input
            type="text"
            value={form.recipient}
            onChange={(e) => setForm({...form, recipient: e.target.value})}
            className="w-full p-2 border rounded-md"
            required
          />
        </div>

        <div>
          <label className="block text-sm font-medium mb-1">Amount</label>
          <input
            type="number"
            step={`0.${'0'.repeat(BROTHER_TOKEN.decimals-1)}1`}
            value={form.amount}
            onChange={(e) => setForm({...form, amount: e.target.value})}
            className="w-full p-2 border rounded-md"
            required
          />
        </div>

        <button 
          type="submit" 
          disabled={isLoading}
          className="w-full bg-green-600 text-white py-2 px-4 rounded-md hover:bg-green-700 disabled:bg-gray-400"
        >
          {isLoading ? 'Processing...' : 'Transfer'}
        </button>
      </form>

      {transferData && (
        <div className="mt-4 p-3 bg-gray-50 rounded-md">
          <p className="text-sm font-mono break-all">
            TX Hash: {transferData}
          </p>
        </div>
      )}

      {error && (
        <div className="mt-4 p-3 bg-red-50 text-red-700 rounded-md">
          Error: {error.message}
        </div>
      )}
    </div>
  );
}

Security Considerations

  • Always verify recipient addresses
  • Use encrypted private keys
  • Implement proper PIN validation
  • Monitor transaction status

Error Handling

  • Handle insufficient token balance
  • Validate wallet addresses
  • Monitor gas fees
  • Implement retry logic for failed transactions
Always verify recipient addresses. Transfers on StarkNet are irreversible.
  • Approve - Required before transferring new token types
  • Stake - For staking tokens