> ## Documentation Index
> Fetch the complete documentation index at: https://docs.portalhq.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage Token Delegations

> Learn how to approve, revoke, and manage token delegations using Portal's Flutter SDK.

Portal's Flutter SDK provides token delegation capabilities through the `portal.delegations` API. This enables approving token spending, revoking approvals, checking delegation status, and transferring tokens as a delegate on both EVM and Solana chains.

## Overview

The delegations functionality allows you to:

* **Approve** other addresses to spend tokens on behalf of your wallet
* **Revoke** existing delegations to remove spending permissions
* **Check status** of active delegations and balances
* **Transfer tokens** as a delegate from another address

## Prerequisites

Before using delegation operations, ensure you have:

* A properly initialized Portal client
* An active wallet with tokens on the target network (see [Create a wallet](./create-a-wallet))
* Understanding of [token delegations concepts](/resources/delegations)

<Warning>
  Delegations apply to ERC-20 tokens (EVM) and SPL Tokens (Solana) only. Native assets like ETH, MON, and SOL cannot be delegated — they have no on-chain `approve` / `transferFrom` (or SPL delegate) semantics. Calls using a native asset identifier will be rejected. See [Delegations](/resources/delegations#what-are-token-delegations) for the protocol-level reason and workarounds.
</Warning>

<Note>
  All examples below assume Portal has already been initialized with `await portal.initialize(apiKey: 'YOUR_API_KEY')`. See [Getting Started](./getting-started) for details.
</Note>

## Approving Delegations

Use `approve` to grant another address permission to spend tokens on your behalf. This method works for both EVM and Solana chains.

### EVM Approval

```dart theme={null}
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

try {
  // Approve a delegate to spend USDC on your behalf
  final response = await portal.delegations.approve(
    chain: 'eip155:11155111', // Sepolia testnet
    token: 'USDC',
    delegateAddress: '0xa944e86eb36f039becd1843132347eb5b8501562',
    amount: '0.01',
  );

  // Sign and send the transaction
  final tx = response.transactions!.first!;
  final txResponse = await portal.request(
    chainId: 'eip155:11155111',
    method: 'eth_sendTransaction',
    params: [
      {'from': tx.from, 'to': tx.to, 'data': tx.data, 'value': tx.value}
    ],
  );
  print('Tx hash: ${txResponse.result}');
} catch (e) {
  print('Error approving EVM delegation: $e');
}
```

<Tip>
  Each delegation response includes a `metadata` field with additional details such as `chainId`, `tokenSymbol`, `tokenAddress`, and `delegateAddress`. Access it via `response.metadata?.chainId` for approve/revoke, or `response.metadata.chainId` for transferFrom.
</Tip>

### Solana Approval

```dart theme={null}
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

try {
  // Approve a delegate to spend USDC on your behalf
  final response = await portal.delegations.approve(
    chain: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', // Solana Devnet
    token: 'USDC',
    delegateAddress: '7smgSuU5mjP7QY5yWGdaTfgKn8hUWwvQgfvgcZB3HmJi',
    amount: '0.01',
  );

  // Sign and send the transaction
  final encodedTx = response.encodedTransactions!.first!;
  final txResponse = await portal.request(
    chainId: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    method: 'sol_signAndSendTransaction',
    params: [encodedTx],
  );
  print('Tx hash: ${txResponse.result}');
} catch (e) {
  print('Error approving Solana delegation: $e');
}
```

***

## Checking Delegation Status

Use `getStatus` to check current delegations and token balances for a specific delegate address.

### EVM Status Check

```dart theme={null}
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

try {
  final response = await portal.delegations.getStatus(
    chain: 'eip155:11155111',
    token: 'USDC',
    delegateAddress: '0xa944e86eb36f039becd1843132347eb5b8501562',
  );

  print('Chain ID: ${response.chainId}');
  print('Token: ${response.token}');
  print('Token Address: ${response.tokenAddress}');
  if (response.balance != null) print('Balance: ${response.balance}');
  if (response.balanceRaw != null) print('Balance Raw: ${response.balanceRaw}');
  print('Delegations: ${response.delegations.length}');

  for (final delegation in response.delegations) {
    print('  - Address: ${delegation!.address}, Amount: ${delegation.delegateAmount} (Raw: ${delegation.delegateAmountRaw})');
  }
} catch (e) {
  print('Error getting EVM delegation status: $e');
}
```

### Solana Status Check

```dart theme={null}
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

try {
  final response = await portal.delegations.getStatus(
    chain: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    token: 'USDC',
    delegateAddress: '7smgSuU5mjP7QY5yWGdaTfgKn8hUWwvQgfvgcZB3HmJi',
  );

  print('Chain ID: ${response.chainId}');
  print('Token: ${response.token}');
  if (response.tokenAccount != null) print('Token Account: ${response.tokenAccount}');
  print('Delegations: ${response.delegations.length}');

  for (final delegation in response.delegations) {
    print('  - Address: ${delegation!.address}, Amount: ${delegation.delegateAmount} (Raw: ${delegation.delegateAmountRaw})');
  }
} catch (e) {
  print('Error getting Solana delegation status: $e');
}
```

***

## Revoking Delegations

Use `revoke` to remove spending permissions from a delegate address.

### EVM Revoke

```dart theme={null}
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

try {
  final response = await portal.delegations.revoke(
    chain: 'eip155:11155111',
    token: 'USDC',
    delegateAddress: '0xa944e86eb36f039becd1843132347eb5b8501562',
  );

  // Sign and send the transaction
  final tx = response.transactions!.first!;
  final txResponse = await portal.request(
    chainId: 'eip155:11155111',
    method: 'eth_sendTransaction',
    params: [
      {'from': tx.from, 'to': tx.to, 'data': tx.data, 'value': tx.value}
    ],
  );
  print('Tx hash: ${txResponse.result}');
} catch (e) {
  print('Error revoking EVM delegation: $e');
}
```

### Solana Revoke

```dart theme={null}
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

try {
  final response = await portal.delegations.revoke(
    chain: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    token: 'USDC',
    delegateAddress: '7smgSuU5mjP7QY5yWGdaTfgKn8hUWwvQgfvgcZB3HmJi',
  );

  // Sign and send the transaction
  final encodedTx = response.encodedTransactions!.first!;
  final txResponse = await portal.request(
    chainId: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    method: 'sol_signAndSendTransaction',
    params: [encodedTx],
  );
  print('Tx hash: ${txResponse.result}');
} catch (e) {
  print('Error revoking Solana delegation: $e');
}
```

<Warning>
  Always revoke unused delegations after completing operations to minimize security risks.
</Warning>

***

## Transferring as a Delegate

Use `transferFrom` to transfer tokens from another address that has delegated spending permission to you.

### EVM Transfer From

```dart theme={null}
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

try {
  final response = await portal.delegations.transferFrom(
    chain: 'eip155:11155111',
    token: 'USDC',
    fromAddress: '0x099699ed181517d4ce0ba4487bea671d31bb1db5', // Token owner
    toAddress: '0xdFd8302f44727A6348F702fF7B594f127dE3A902',   // Recipient
    amount: '0.01',
  );

  // Sign and send the transaction
  final tx = response.transactions!.first!;
  final txResponse = await portal.request(
    chainId: 'eip155:11155111',
    method: 'eth_sendTransaction',
    params: [
      {'from': tx.from, 'to': tx.to, 'data': tx.data, 'value': tx.value}
    ],
  );
  print('Tx hash: ${txResponse.result}');
} catch (e) {
  print('Error transferring EVM delegation: $e');
}
```

### Solana Transfer From

```dart theme={null}
import 'package:portal_flutter/portal_flutter.dart';

final portal = Portal();

try {
  final response = await portal.delegations.transferFrom(
    chain: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    token: 'USDC',
    fromAddress: 'ARttPLesu9RiX6H111Pfdc9Y2DhGy1B8P8jyyrD8Cj5b', // Token owner
    toAddress: 'GPsPXxoQA51aTJJkNHtFDFYui5hN5UxcFPnheJEHa5Du',   // Recipient
    amount: '0.01',
  );

  // Sign and send the transaction
  final encodedTx = response.encodedTransactions!.first!;
  final txResponse = await portal.request(
    chainId: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    method: 'sol_signAndSendTransaction',
    params: [encodedTx],
  );
  print('Tx hash: ${txResponse.result}');
} catch (e) {
  print('Error transferring Solana delegation: $e');
}
```

<Note>
  **Delegation Roles**: `fromAddress` is the token owner who approved the delegation. Your wallet (the delegate) signs the transaction to transfer tokens from the owner to the `toAddress` recipient.
</Note>

***

## Supported Networks

Delegations work on all Portal-supported EVM and Solana chains:

* **EVM**: Ethereum, Polygon, Base, Arbitrum, Optimism, Monad, and all other EVM-compatible chains
* **Solana**: Solana Mainnet and Devnet

For a complete list, see [Blockchain Support](/resources/blockchain-support).

***

## Next Steps

* Learn about [signing transactions](./sign-a-transaction)
* Explore [sending tokens](./send-tokens)
* Review [delegation concepts](/resources/delegations)
* Check out [performing swaps](./perform-swaps)
