Securing Private Keys in the "Crypto" Node for Automated DEX Swaps?

Hi everyone,

I’m currently building a workflow to automate some rebalancing between my hardware wallet and a hot wallet for liquidity providing on Uniswap. I’m using the HTTP Request node to interact with the blockchain via Infura, but I’ve hit a bit of a roadblock regarding security.

Right now, I’m using the n8n Crypto Node to handle some basic hashing, but I need to sign transactions before sending them to the RPC endpoint.

My setup:

Trigger: Schedule node (every 4 hours).

Logic: Checking price floor via CoinGecko API.

Action: If price < $X, sign a ‘Swap’ transaction.

My questions:

Credential Management: For those doing similar DeFi automation, are you storing your private keys in n8n’s internal credentials store, or are you fetching them from an external vault like HashiCorp or 1Password at runtime?

Transaction Signing: Is there a community node that handles EIP-1559 transaction signing natively, or is everyone just using a Code Node with ethers.js or web3.js? I’m worried about the performance of loading those libraries in every execution.

Error Handling: How do you handle ‘Gas Price’ spikes? My last execution failed because the gas limit was too low, and the workflow just stopped. Is there a way to ‘retry with higher gas’ without creating an infinite loop?

I’m running a self-hosted Docker instance of n8n. Any advice on the safest way to handle the signing part would be huge!

Don’t use n8n’s credential store for private keys with real funds. Fetch from a vault like 1Password Connect at runtime in a Code Node, sign with ethers.js there, then null the variable after. For gas spikes I just do estimateGas() with a buffer and cap retries at 3, hasnt failed me yet tho.

Hi @tarunnagar

What I’d focus on is isolating the signing step as much as possible. Even if you keep everything inside n8n, it’s safer to treat signing as its own step, for example via a dedicated service or a very minimal Code node, rather than mixing it into the main workflow logic.
For gas handling, instead of retrying blindly, I’d gate the execution before sending the transaction. For example, fetch current fee data first and only proceed if it’s within an acceptable range. That avoids failed executions and removes the need for aggressive retry logic.
So I’d structure it as: check conditions > validate gas > sign > send, and abort early if something is out of bounds.