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

# Delegated Trading

> Use an agent wallet or backend signer to submit trades for a trader

Delegated trading lets a trader approve another EOA to submit trading transactions on their behalf. This is the on-chain primitive used by [One-Click Trading](/gtrade-leveraged-trading/one-click-trading-1ct), but it can also be used by backend services, bots, and partner integrations.

The trader keeps custody of their collateral and positions. The delegated wallet signs and pays gas for transactions, while the protocol records the trade under the trader address.

## Flow

1. The trader approves an agent wallet with [`setTradingDelegate`](/developer/technical-reference/contracts/interfaces/libraries/itradinginteractionsutils#settradingdelegate).
2. The agent wallet is funded with native gas token.
3. The backend builds the calldata for a normal trading action, such as [`openTrade`](/developer/technical-reference/contracts/interfaces/libraries/itradinginteractionsutils#opentrade), [`closeTradeMarket`](/developer/technical-reference/contracts/interfaces/libraries/itradinginteractionsutils#closetrademarket), [`updateSl`](/developer/technical-reference/contracts/interfaces/libraries/itradinginteractionsutils#updatesl), or [`updateTp`](/developer/technical-reference/contracts/interfaces/libraries/itradinginteractionsutils#updatetp).
4. The backend wraps that calldata in [`delegatedTradingAction`](/developer/technical-reference/contracts/interfaces/libraries/itradinginteractionsutils#delegatedtradingaction), passing the trader address and the action calldata.
5. The agent wallet submits the wrapped transaction to `GNSMultiCollatDiamond`.

During the delegated call, the trading facet resolves the effective sender as the trader address. Collateral transfers, trade ownership, and PnL accounting therefore remain tied to the trader.

## Approve a delegate

The trader must approve the delegate from their own wallet:

```typescript theme={null}
import { ethers } from "ethers";

const diamond = new ethers.Contract(
  GNS_MULTI_COLLAT_DIAMOND,
  [
    "function setTradingDelegate(address delegate)",
    "function getTradingDelegate(address trader) view returns (address)",
    "function removeTradingDelegate()",
  ],
  traderSigner
);

await diamond.setTradingDelegate(agentWalletAddress);

const currentDelegate = await diamond.getTradingDelegate(await traderSigner.getAddress());
```

Each trader has one active trading delegate. Calling `setTradingDelegate` replaces the previous delegate. Calling `removeTradingDelegate` clears it.

## Submit from a backend signer

The agent wallet signs the wrapped transaction. The trader address is still passed into the wrapped call:

```typescript theme={null}
import { Wallet } from "ethers";
import { TradingSDK, SupportedChainId } from "@gainsnetwork/trading-sdk";

const agentWallet = new Wallet(process.env.AGENT_PRIVATE_KEY!, provider);
const trader = "0x..."; // user who approved agentWallet.address

const tradingSdk = new TradingSDK({
  chainId: SupportedChainId.Arbitrum,
  signer: agentWallet,
});

await tradingSdk.initialize();

const openTradeTx = await tradingSdk.build.openTrade({
  user: trader,
  pairIndex: 0,
  collateralAmount: 100_000_000n,
  openPrice: 66108.8,
  long: true,
  leverage: 2,
  tp: 0,
  sl: 0,
  collateralIndex: 3,
  tradeType: 0,
  maxSlippage: 1,
});

const response = await tradingSdk.write.delegatedTradingAction({
  trader,
  data: openTradeTx.data,
});

await response?.wait();
```

The trader must still satisfy the normal requirements for the underlying action. For example, `openTrade` with ERC-20 collateral requires the trader to have enough collateral and to have approved the diamond to pull that collateral.

## Direct contract call

You can also build the wrapped calldata manually:

```typescript theme={null}
import { ethers } from "ethers";

const diamond = new ethers.Contract(
  GNS_MULTI_COLLAT_DIAMOND,
  [
    "function openTrade((address user,uint32 index,uint16 pairIndex,uint24 leverage,bool long,bool isOpen,uint8 collateralIndex,uint8 tradeType,uint120 collateralAmount,uint64 openPrice,uint64 tp,uint64 sl,uint192 __placeholder) trade,uint16 maxSlippageP,address referrer)",
    "function delegatedTradingAction(address trader, bytes callData) returns (bytes)",
  ],
  agentWallet
);

const callData = diamond.interface.encodeFunctionData("openTrade", [
  trade,
  maxSlippageP,
  ethers.ZeroAddress,
]);

await diamond.delegatedTradingAction(trader, callData);
```

## Supported actions

Delegation is designed for trading and trade management. Common supported actions include:

* `openTrade`
* `closeTradeMarket`
* `updateSl`
* `updateTp`
* `updateOpenOrder`
* `cancelOpenOrder`
* `updateLeverage`
* `increasePositionSize`
* `decreasePositionSize`
* `updateMaxClosingSlippageP`
* `cancelOrderAfterTimeout`

The current contracts also allow a delegate to initiate `withdrawPositivePnl`. Any withdrawn PnL is transferred to the trader, not to the delegate.

## Unsupported actions

Functions guarded by `notDelegatedAction` cannot be executed through `delegatedTradingAction`. This includes native-token wrapper flows and trigger-order flows:

* `openTradeNative`
* `increasePositionSizeNative`
* `updateLeverageNative`
* `triggerOrder`
* `triggerOrderWithSignatures`
* nested `delegatedTradingAction`

Use ERC-20 collateral flows for delegated opens and position increases. On ApeChain, delegated trading requires wrapped collateral because native `$APE` does not follow ERC-20 `approve` and `transferFrom` semantics.

## Security notes

Delegated trading is broad trading authority, not a granular permission system. A delegate cannot withdraw user funds to itself through the trading delegation flow, but it can submit trading actions that affect the trader's positions and collateral.

Recommended practices:

* Use a dedicated agent wallet per integration or user group.
* Keep the agent wallet funded only with enough gas for expected operations.
* Let users revoke access with `removeTradingDelegate`.
* Enforce any additional policy, such as max trade size, allowed pairs, or disabled PnL withdrawals, in your backend before signing transactions.
* Treat backend policy as off-chain protection. The current on-chain delegation model does not enforce per-function, per-market, per-size, or expiry-scoped permissions.

## References

* [Trading Contracts](/developer/integrators/trading-contracts)
* [`setTradingDelegate`](/developer/technical-reference/contracts/interfaces/libraries/itradinginteractionsutils#settradingdelegate)
* [`delegatedTradingAction`](/developer/technical-reference/contracts/interfaces/libraries/itradinginteractionsutils#delegatedtradingaction)
* [`getTradingDelegate`](/developer/technical-reference/contracts/interfaces/libraries/itradinginteractionsutils#gettradingdelegate)
