> ## 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 Web SDK.

Portal's Web 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>

## 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

```typescript theme={null}
async function approveEVMDelegation(portal: Portal) {
  const tx = await portal.delegations.approve({
    chain: 'eip155:11155111', // Sepolia testnet
    token: 'USDC',
    delegateAddress: '0xb52a818536341003c9d923103abd3659c27e5a2b',
    amount: '10',
  })

  console.log('Approve response:', tx)
  
  // Sign and send the transaction
  const hash = await portal.request({
    chainId: 'eip155:11155111',
    method: 'eth_sendTransaction',
    params: [tx.transactions[0]]
  })
  
  console.log('Transaction hash:', hash)
  return hash
}
```

Solana Approval

```typescript theme={null}
async function approveSolanaDelegation(portal: Portal) {
  const tx = await portal.delegations.approve({
    chain: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1', // Solana Devnet
    token: 'USDC',
    delegateAddress: '7EYg9HUZBoCeCfWbcj3EFNX5Ecgjn9FTY2UhnRny5NYv',
    amount: '10',
  })

  console.log('Approve response:', tx)
  
  // Sign and send the transaction
  const hash = await portal.request({
    chainId: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    method: 'sol_signAndSendTransaction',
    params: [tx.encodedTransactions[0]]
  })
  
  console.log('Transaction hash:', hash)
  return hash
}
```

***

## Checking Delegation Status

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

EVM Status Check

```typescript theme={null}
async function getEVMDelegationStatus(portal: Portal) {
  const status = await portal.delegations.getStatus({
    chain: 'eip155:11155111',
    token: 'USDC',
    delegateAddress: '0xb52a818536341003c9d923103abd3659c27e5a2b',
  })

  console.log('Delegation status:', status)
  console.log('Balance:', status.balance)
  console.log('Delegations:', status.delegations)
}
```

Solana Status Check

```typescript theme={null}
async function getSolanaDelegationStatus(portal: Portal) {
  const status = await portal.delegations.getStatus({
    chain: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    token: 'USDC',
    delegateAddress: '7EYg9HUZBoCeCfWbcj3EFNX5Ecgjn9FTY2UhnRny5NYv',
  })

  console.log('Delegation status:', status)
}
```

***

## Revoking Delegations

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

EVM Revoke

```typescript theme={null}
async function revokeEVMDelegation(portal: Portal) {
  const tx = await portal.delegations.revoke({
    chain: 'eip155:11155111',
    token: 'USDC',
    delegateAddress: '0xb52a818536341003c9d923103abd3659c27e5a2b',
  })

  console.log('Revoke response:', tx)
  
  const hash = await portal.request({
    chainId: 'eip155:11155111',
    method: 'eth_sendTransaction',
    params: [tx.transactions[0]]
  })
  
  console.log('Transaction hash:', hash)
  return hash
}
```

Solana Revoke

```typescript theme={null}
async function revokeSolanaDelegation(portal: Portal) {
  const tx = await portal.delegations.revoke({
    chain: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    token: 'USDC',
    delegateAddress: '7EYg9HUZBoCeCfWbcj3EFNX5Ecgjn9FTY2UhnRny5NYv',
  })

  console.log('Revoke response:', tx)
  
  const hash = await portal.request({
    chainId: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    method: 'sol_signAndSendTransaction',
    params: [tx.encodedTransactions[0]]
  })
  
  console.log('Transaction hash:', hash)
  return hash
}
```

<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

```typescript theme={null}
async function transferFromEVM(portal: Portal) {
  const tx = await portal.delegations.transferFrom({
    chain: 'eip155:11155111',
    token: 'USDC',
    fromAddress: '0x03c66353df426e18e6e7866fa9e2e73ef6833500', // Token owner
    toAddress: '0xdFd8302f44727A6348F702fF7B594f127dE3A902', // Recipient
    amount: '0.0001',
  })

  console.log('TransferFrom response:', tx)
  
  const hash = await portal.request({
    chainId: 'eip155:11155111',
    method: 'eth_sendTransaction',
    params: [tx.transactions[0]]
  })
  
  console.log('Transaction hash:', hash)
  return hash
}
```

Solana Transfer From

```typescript theme={null}
async function transferFromSolana(portal: Portal) {
  const tx = await portal.delegations.transferFrom({
    chain: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    token: 'USDC',
    fromAddress: 'GoFBWzCVxSEGYxgSAmdm2itS3EUbYmLpgzEcQ4J3WnsN', // Token owner
    toAddress: 'GPsPXxoQA51aTJJkNHtFDFYui5hN5UxcFPnheJEHa5Du', // Recipient
    amount: '0.0001',
  })

  console.log('TransferFrom response:', tx)
  
  const hash = await portal.request({
    chainId: 'solana:EtWTRABZaYq6iMfeYKouRu166VU2xqa1',
    method: 'sol_signAndSendTransaction',
    params: [tx.encodedTransactions[0]]
  })
  
  console.log('Transaction hash:', hash)
  return hash
}
```

<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 [Portal API methods](./portal-api-methods)
* Review [delegation concepts](/resources/delegations)
* Check out [wallet lifecycle management](./manage-wallet-lifecycle-states)
