AutomationFlowsSlack & Telegram › Automated Range Trading with Uniswap V3, Telegram Alerts & Metamask Delegation

Automated Range Trading with Uniswap V3, Telegram Alerts & Metamask Delegation

By1Shot API @oneshotapi on n8n.io

This workflow will monitor the price of a token trading pair (default is ETH - USDC) and automatically buy into ETH or sell into USDC based on a price window configured by the user.

Cron / scheduled trigger★★★★★ complexity42 nodesN8N Nodes 1ShotTelegram
Slack & Telegram Trigger: Cron / scheduled Nodes: 42 Complexity: ★★★★★ Added:

This workflow corresponds to n8n.io template #8427 — we link there as the canonical source.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "rwBmKKWS8XyIAkrL",
  "name": "My workflow 14",
  "tags": [],
  "nodes": [
    {
      "id": "ce2e7838-e9ff-49ea-93f9-11aacb58191c",
      "name": "Calculate TWAP",
      "type": "n8n-nodes-base.code",
      "position": [
        -704,
        864
      ],
      "parameters": {
        "jsCode": "// Constants\nconst MaxUint256 = (1n << 256n) - 1n;\nconst Q32 = 1n << 32n;\nconst ZERO = 0n;\nconst ONE = 1n;\n\nfunction mulShift(val, mulBy) {\n  return (val * BigInt(mulBy)) >> 128n;\n}\n\n/**\n * Returns the sqrt ratio as a Q64.96 for the given tick.\n * The sqrt ratio is computed as sqrt(1.0001)^tick\n * @param {number} tick the tick for which to compute the sqrt ratio\n */\nfunction getSqrtRatioAtTick(tick) {\n  if (!Number.isInteger(tick)) throw new Error(\"Tick must be integer\");\n  const MIN_TICK = -887272;\n  const MAX_TICK = 887272;\n\n  if (tick < MIN_TICK || tick > MAX_TICK) throw new Error(\"Tick out of bounds\");\n\n  const absTick = tick < 0 ? -tick : tick;\n\n  let ratio =\n    (absTick & 0x1) != 0\n      ? 0xfffcb933bd6fad37aa2d162d1a594001n\n      : 0x1+1234567890+1234567890n;\n  if ((absTick & 0x2) != 0) ratio = mulShift(ratio, 0xfff97272373d413259a46990580e213an);\n  if ((absTick & 0x4) != 0) ratio = mulShift(ratio, 0xfff2e50f5f656932ef12357cf3c7fdccn);\n  if ((absTick & 0x8) != 0) ratio = mulShift(ratio, 0xffe5caca7e10e4e61c3624eaa0941cd0n);\n  if ((absTick & 0x10) != 0) ratio = mulShift(ratio, 0xffcb9843d60f6159c9db58835c926644n);\n  if ((absTick & 0x20) != 0) ratio = mulShift(ratio, 0xff973b41fa98c081472e6896dfb254c0n);\n  if ((absTick & 0x40) != 0) ratio = mulShift(ratio, 0xff2ea16466c96a3843ec78b326b52861n);\n  if ((absTick & 0x80) != 0) ratio = mulShift(ratio, 0xfe5dee046a99a2a811c461f1969c3053n);\n  if ((absTick & 0x100) != 0) ratio = mulShift(ratio, 0xfcbe86c7900a88aedcffc83b479aa3a4n);\n  if ((absTick & 0x200) != 0) ratio = mulShift(ratio, 0xf987a7253ac413176f2b074cf7815e54n);\n  if ((absTick & 0x400) != 0) ratio = mulShift(ratio, 0xf3392b0822b70005940c7a398e4b70f3n);\n  if ((absTick & 0x800) != 0) ratio = mulShift(ratio, 0xe7159475a2c29b7443b29c7fa6e889d9n);\n  if ((absTick & 0x1000) != 0) ratio = mulShift(ratio, 0xd097f3bdfd2022b8845ad8f792aa5825n);\n  if ((absTick & 0x2000) != 0) ratio = mulShift(ratio, 0xa9f746462d870fdf8a65dc1f90e061e5n);\n  if ((absTick & 0x4000) != 0) ratio = mulShift(ratio, 0x70d869a156d2a1b890bb3df62baf32f7n);\n  if ((absTick & 0x8000) != 0) ratio = mulShift(ratio, 0x31be135f97d08fd981231505542fcfa6n);\n  if ((absTick & 0x10000) != 0) ratio = mulShift(ratio, 0x9aa508b5b7a84e1c677de54f3e99bc9n);\n  if ((absTick & 0x20000) != 0) ratio = mulShift(ratio, 0x5d6af8dedb81196699c329225ee604n);\n  if ((absTick & 0x40000) != 0) ratio = mulShift(ratio, 0x2216e584f5fa1ea926041bedfe98n);\n  if ((absTick & 0x80000) != 0) ratio = mulShift(ratio, 0x48a170391f7dc42444e8fa2n);\n\n  if (tick > 0) {\n    ratio = MaxUint256 / ratio;\n  }\n\n  // back to Q96\n  return ratio % Q32 > 0n ? ratio / Q32 + ONE : ratio / Q32;\n}\n\nfunction getPriceFromSqrtPriceX96(sqrtPriceX96, decimals0, decimals1) {\n  // Ensure input is BigInt\n  const sqrtPrice = BigInt(sqrtPriceX96.toString());\n\n  // (sqrtPriceX96 ^ 2)\n  const numerator = sqrtPrice * sqrtPrice;\n\n  // Denominator = 2^192\n  const denominator = 1n << 192n;\n\n  // Raw price ratio (tokenOut per tokenIn, no decimals adjusted)\n  let ratio = Number(numerator * 10n**18n / denominator) / 1e18; \n  // (we scale by 1e18 to stay precise when converting to Number)\n\n  // Adjust for token decimals\n  const decimalFactor = 10 ** (decimals0 - decimals1);\n  const price = ratio * decimalFactor;\n\n  return price;\n}\n\nconst diffTickCumulative = BigInt($('Fetch Pool TWA Observations').first().json.response[0][0]) - BigInt($('Fetch Pool TWA Observations').first().json.response[0][1]);\nconst diffSecondsPerLIquidityX128 = BigInt($('Fetch Pool TWA Observations').first().json.response[1][0]) - BigInt($('Fetch Pool TWA Observations').first().json.response[1][1]);\nconst secondsBetween = parseInt($('Swap Configs').first().json.secondsAgo);\nconst secondsBetweenX128 = BigInt(secondsBetween) << BigInt(128);\nconst averageTick = parseInt(parseFloat(diffTickCumulative)/secondsBetween);\n\n\nconst sqrtTWAPricex96 = getSqrtRatioAtTick(averageTick);\nconst TWAP = getPriceFromSqrtPriceX96(sqrtTWAPricex96, $('Swap Configs').first().json.token0Decimals, $('Swap Configs').first().json.token1Decimals);\nconst TWAL = secondsBetweenX128 / BigInt(diffSecondsPerLIquidityX128);\n\n\n$input.first().json.twap = TWAP; \n$input.first().json.sqrtTWAPriceX96 = sqrtTWAPricex96; \n$input.first().json.twal = TWAL; \n\nreturn $input.all()\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d0ac3258-891a-4770-807f-9cfd70b59ca7",
      "name": "Fetch Pool TWA Observations",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        -928,
        864
      ],
      "parameters": {
        "params": "={\n  \"secondsAgos\": [\"0\",\"{{ $json.secondsAgo }}\"]\n} ",
        "operation": "read",
        "contractMethodId": "98267bd2-13c9-4c27-bc86-ee2389da1025"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "269d4c6d-8031-4341-b0cd-af77ef52985f",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1376,
        864
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 30
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "c23f4ffc-8f6e-491d-ab06-85a5b4699cb6",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1328,
        336
      ],
      "parameters": {
        "width": 800,
        "height": 464,
        "content": "## Swap configs\n\nSince we are using the Uniswap protocol directly, you'll need to set a few parameters in the Swap Configs node. \n\n1. Decide on the amount of USDC to spend to enter ETH, put this in `amountUSDC`. \n2. Set your upper and lower price ranges in `upperPrice` and `lowerPrice`. \n3. Put your wallet address as the `delegator` so that the workflow can execute DCA buys on your behalf. \n4. Set the Telegram chatID for your bot to receive notifications.\n\n### Optional Parameters\nIf you want to change the chain or assets you may have to change these parameters:\n\n1. Set the correct address for the Uniswap [SwapRouter](https://docs.uniswap.org/contracts/v3/reference/deployments/) contract\n2. If you want to trade something besided ETH/USDC, you'll need to set the correct addresses for `token0`, `token1`, `token0Decimals` and `token1Decimals`.\n3. Check the `fee` for the pool you are targeting and make sure it matches. \n4. Edit the slippage percentage to your taste. "
      },
      "typeVersion": 1
    },
    {
      "id": "f3382c3e-85b0-45f2-b1fb-b466ccc9ae72",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        208,
        80
      ],
      "parameters": {
        "width": 720,
        "height": 400,
        "content": "## Connect to Your 1Shot API Account\n\nCreate an API key and secret in your 1Shot API account and connect your n8n instance by creating a credential. \n\n1. The `Fetch Pool TWA Observactions` should point to the `observe` method on your target trading pool (like this [one](https://app.uniswap.org/explore/pools/base/0xfBB6Eed8e7aa03B138556eeDaF5D271A5E1e43ef)). \n2. The `Get Sell Quote` and `Get Buy Quote` nodes should both point to the `quoteExactInputSingle` on the QuoterV2 contract.\n3. The `Give Approval to Router (Buy)` should call `approve` on USDC.\n4. The `Give Approval to Router (Sell)` should call `approve` on WETH. \n5. The `Sell ETH` and `Buy Eth` nodes should point at the `exactInputSingle` function on the Uniswap SwapRouterV2 contract. \n5. In order to get look up your remaining balance of funds that can be used for DCA purchases, point the `Check New Funds` and `Check Remaining Funds` nodes at the `balanceOf` function on USDC."
      },
      "typeVersion": 1
    },
    {
      "id": "988a0381-d6cb-4663-b6bd-7085962a026a",
      "name": "Swap Configs",
      "type": "n8n-nodes-base.code",
      "position": [
        -1152,
        864
      ],
      "parameters": {
        "jsCode": "const amountDCA = 25000000; // amount to swap each time (in atomic units of USDC)\nconst upperPrice = 4613; // in dollars\nconst lowerPrice = 4372; // in dollars\nconst slippage = 0.025 // the amount the price can move by from quote to swap (multiply by 100 for percentage)\nconst secondsAgo = 120; // the size of your TWAP window\nconst delegator = \"0x9fead8b19c044c2f404dac38b925ea16adaa2954\"; // your delegated wallet address.\nconst telegramChatId = 5034284669; // the chat id between you and your Telegram bot\nconst router = \"0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45\"; // the uniswap SwapRouterV2\nconst token0 = \"0x82aF49447D8a07e3bd95BD0d56f35241523fBab1\"; // The pool's token0\nconst token1 = \"0xaf88d065e77c8cC2239327C5EDb3A432268e5831\"; // The pool's token1\nconst token0Decimals = 18; // WETH has 18 decimals\nconst token1Decimals = 6; // USDC has 6 decimals\nconst fee = 500; // the fee of your target pool, most pools have a fee of 500\n\n$input.first().json.amountDCA = amountDCA;\n$input.first().json.upperPrice = upperPrice;\n$input.first().json.lowerPrice = lowerPrice;\n$input.first().json.telegramChatId = telegramChatId;\n$input.first().json.delegator = delegator;\n$input.first().json.router = router;\n$input.first().json.token0 = token0;\n$input.first().json.token0Decimals = token0Decimals;\n$input.first().json.token1 = token1;\n$input.first().json.token1Decimals = token1Decimals;\n$input.first().json.fee = fee;\n$input.first().json.slippage = slippage;\n$input.first().json.secondsAgo = secondsAgo;\n\nreturn $input.all();\n"
      },
      "typeVersion": 2
    },
    {
      "id": "6b937fb5-54c3-4a00-9a87-21545da46b9e",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -544,
        1648
      ],
      "parameters": {
        "width": 800,
        "content": "## Set up a 1Shot API Wallet & Import Required Methods:\n\nClick the sub-workflow trigger to setup you 1Shot API account with a server wallet and all required smart contract methods needed for range trading."
      },
      "typeVersion": 1
    },
    {
      "id": "8b61c2bb-7e6d-4187-a9f6-b8bcac7dfed9",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1568,
        1216
      ],
      "parameters": {
        "width": 768,
        "height": 560,
        "content": "## YouTube Tutorial\n\n@[youtube](Hppd04sM4xE)\n"
      },
      "typeVersion": 1
    },
    {
      "id": "fd90af4e-1631-4437-9f9c-af1764d50e60",
      "name": "Buy, Sell or Hold",
      "type": "n8n-nodes-base.switch",
      "position": [
        -32,
        864
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Sell ETH",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "0080b3b6-9666-4cae-bb60-a157a3bc31c8",
                    "operator": {
                      "type": "number",
                      "operation": "gt"
                    },
                    "leftValue": "={{ $('Calculate TWAP').item.json.twap }}",
                    "rightValue": "={{ $('Swap Configs').item.json.upperPrice }}"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Buy ETH",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "6bb3a399-cb6e-4d37-a402-867dfb857cf1",
                    "operator": {
                      "type": "number",
                      "operation": "lt"
                    },
                    "leftValue": "={{ $('Calculate TWAP').item.json.twap }}",
                    "rightValue": "={{ $('Swap Configs').item.json.lowerPrice }}"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {},
        "looseTypeValidation": true
      },
      "typeVersion": 3.2
    },
    {
      "id": "55c859a3-94c7-4311-9029-92de95cc6fd8",
      "name": "Confirm Buy",
      "type": "n8n-nodes-base.telegram",
      "position": [
        640,
        1088
      ],
      "parameters": {
        "chatId": "={{ $('Swap Configs').item.json.telegramChatId }}",
        "message": "=Purchase {{ parseFloat($json.result.decodedData[0]) / 1e18 }} ETH at ${{ $('Calculate TWAP').item.json.twap }}?",
        "options": {
          "limitWaitTime": {
            "values": {
              "resumeUnit": "minutes"
            }
          }
        },
        "operation": "sendAndWait",
        "formFields": {
          "values": [
            {
              "fieldType": "dropdown",
              "fieldLabel": "Confirm",
              "fieldOptions": {
                "values": [
                  {
                    "option": "yes"
                  },
                  {
                    "option": "no"
                  }
                ]
              },
              "requiredField": true
            }
          ]
        },
        "responseType": "customForm"
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "fd9d7f1f-680f-4c83-9662-404d5b99bfe7",
      "name": "Purchase Cancelled",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1088,
        1184
      ],
      "parameters": {
        "text": "Purchase cancelled",
        "chatId": "={{ $('Swap Configs').item.json.telegramChatId }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "85f19394-a9af-49f4-b7ea-89efed74921a",
      "name": "Buy or Cancel?",
      "type": "n8n-nodes-base.if",
      "position": [
        864,
        1088
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "f021075c-1415-4cf9-825f-eedc01e0a369",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.data.Confirm }}",
              "rightValue": "no"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "9bbddf57-c29b-4e74-ab84-f695c37e202a",
      "name": "Check Remaining Funds",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        1536,
        864
      ],
      "parameters": {
        "params": "={\n  \"account\": \"{{ $('Swap Configs').item.json.delegator }}\"\n}",
        "operation": "read",
        "contractMethodId": "bfc44279-e20b-4452-b809-d422134700b3"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "414cb6e4-55cf-4da0-ad3e-c333bc34217a",
      "name": "Confirm Sell",
      "type": "n8n-nodes-base.telegram",
      "position": [
        640,
        656
      ],
      "parameters": {
        "chatId": "={{ $('Swap Configs').item.json.telegramChatId }}",
        "message": "=Purchase {{ parseFloat($json.result.decodedData[0]) / 1e18 }} ETH at ${{ $('Calculate TWAP').item.json.twap }}?",
        "options": {
          "limitWaitTime": {
            "values": {
              "resumeUnit": "minutes"
            }
          }
        },
        "operation": "sendAndWait",
        "formFields": {
          "values": [
            {
              "fieldType": "dropdown",
              "fieldLabel": "Confirm",
              "fieldOptions": {
                "values": [
                  {
                    "option": "yes"
                  },
                  {
                    "option": "no"
                  }
                ]
              },
              "requiredField": true
            }
          ]
        },
        "responseType": "customForm"
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "78b724f4-e685-431f-b509-c4f697d46521",
      "name": "Sell or Cancel?",
      "type": "n8n-nodes-base.if",
      "position": [
        864,
        656
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "f021075c-1415-4cf9-825f-eedc01e0a369",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.data.Confirm }}",
              "rightValue": "no"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "cfc5e5f0-ae46-45cd-bb77-c01f863996a0",
      "name": "Sell Cancelled",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1088,
        768
      ],
      "parameters": {
        "text": "Purchase cancelled",
        "chatId": "={{ $('Swap Configs').item.json.telegramChatId }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "e06dfd47-fb6e-4f6a-b6b1-11865ee10db6",
      "name": "Give Approval to Router (Sell)",
      "type": "n8n-nodes-1shot.oneShotSynch",
      "onError": "continueRegularOutput",
      "position": [
        1088,
        560
      ],
      "parameters": {
        "params": "={\n  \"spender\": \"{{ $('Swap Configs').item.json.router }}\", \n  \"amount\": \"{{ $('Parse Last Trade').item.json.memo.amoutOut }}\"\n} ",
        "operation": "executeAsDelegator",
        "additionalFields": {
          "memo": "=Range Trade Approve for {{ $('Swap Configs').item.json.amountDCA }} {{ $('Swap Configs').item.json.token0 }}"
        },
        "contractMethodId": "fdd46f58-7871-42e8-870a-cd8736b0d8a3",
        "delegatorWalletAddress": "={{ $('Swap Configs').item.json.delegator }}"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "72ef73ef-0ebb-4764-81f7-dd5e89628c98",
      "name": "Give Approval to Router (Buy)",
      "type": "n8n-nodes-1shot.oneShotSynch",
      "onError": "continueRegularOutput",
      "position": [
        1088,
        992
      ],
      "parameters": {
        "params": "={\n  \"spender\": \"{{ $('Swap Configs').item.json.router }}\", \n  \"value\": \"{{ $('Swap Configs').item.json.amountDCA }}\"\n} ",
        "operation": "executeAsDelegator",
        "additionalFields": {
          "memo": "=Range Trade Approve for {{ $('Swap Configs').item.json.amountDCA }} {{ $('Swap Configs').item.json.token1 }}"
        },
        "contractMethodId": "e35f72f2-6b5b-43af-9382-60458448f32c",
        "delegatorWalletAddress": "={{ $('Swap Configs').item.json.delegator }}"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "c50fb5a5-3564-4899-8a87-d3028ad38dc1",
      "name": "Buy ETH",
      "type": "n8n-nodes-1shot.oneShotSynch",
      "onError": "continueRegularOutput",
      "position": [
        1312,
        912
      ],
      "parameters": {
        "params": "={\n\"params\": {\n\"tokenIn\": \"{{ $('Swap Configs').item.json.token1 }}\",\n\"tokenOut\": \"{{ $('Swap Configs').item.json.token0 }}\",\n\"fee\": \"{{ $('Swap Configs').item.json.fee }}\",\n\"recipient\": \"{{ $('Swap Configs').item.json.delegator }}\",\n\"amountIn\": \"{{ $('Swap Configs').item.json.amountDCA }}\",\n\"amountOutMinimum\": \"{{ Math.ceil(parseFloat($('Get Buy Qoute').item.json.result.decodedData[0]) * ( 1 - parseFloat($('Swap Configs').item.json.slippage))) }}\",\n\"sqrtPriceLimitX96\": \"0\"\n}\n}",
        "operation": "executeAsDelegator",
        "additionalFields": {
          "memo": "={\"rangeTrade\": \"buy\", \"amountIn\": {{ $('Swap Configs').item.json.amountDCA }}, \"amoutOut\": {{ $('Get Buy Qoute').item.json.result.decodedData[0] }}, \"TWAP\": {{ $('Calculate TWAP').item.json.twap }}}"
        },
        "contractMethodId": "ba3cf19f-52cf-4104-88e8-d9be40e23fe2",
        "delegatorWalletAddress": "={{ $('Swap Configs').item.json.delegator }}"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2a80d667-b2ec-43a0-b9ff-780f978ddaa2",
      "name": "Sell ETH",
      "type": "n8n-nodes-1shot.oneShotSynch",
      "onError": "continueRegularOutput",
      "position": [
        1312,
        480
      ],
      "parameters": {
        "params": "={\n\"params\": {\n\"tokenIn\": \"{{ $('Swap Configs').item.json.token0 }}\",\n\"tokenOut\": \"{{ $('Swap Configs').item.json.token1 }}\",\n\"fee\": \"{{ $('Swap Configs').item.json.fee }}\",\n\"recipient\": \"{{ $('Swap Configs').item.json.delegator }}\",\n\"amountIn\": \"{{ $('Parse Last Trade').item.json.memo.amoutOut }}\",\n\"amountOutMinimum\": \"{{ Math.ceil(parseFloat($('Get Sell Qoute').item.json.result.decodedData[0]) * ( 1 - parseFloat($('Swap Configs').item.json.slippage))) }}\",\n\"sqrtPriceLimitX96\": \"0\"\n}\n}",
        "operation": "executeAsDelegator",
        "additionalFields": {
          "memo": "={\"rangeTrade\": \"sell\", \"amountIn\": {{ $('Parse Last Trade').item.json.memo.amoutOut }}, \"amoutOut\": {{ $('Get Sell Qoute').item.json.result.decodedData[0] }}, \"TWAP\": {{ $('Calculate TWAP').item.json.twap }}}"
        },
        "contractMethodId": "ba3cf19f-52cf-4104-88e8-d9be40e23fe2",
        "delegatorWalletAddress": "={{ $('Swap Configs').item.json.delegator }}"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "564d6c6f-195b-4743-a44f-818c8a409ceb",
      "name": "Success Details (Sell)",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1760,
        432
      ],
      "parameters": {
        "text": "=\u2705 Swapped `{{ $('Parse Last Trade').item.json.memo.amoutOut }}` `{{ $('Swap Configs').item.json.token0 }}` for `{{ $('Get Sell Qoute').item.json.result.decodedData[0] }}` `{{ $('Swap Configs').item.json.token1 }}`. \n\nThe `{{ $('Swap Configs').item.json.secondsAgo }}` second TWAP was `{{ $('Calculate TWAP').item.json.twap }}`. Your tx hash is `{{ $('Sell ETH').item.json.transactionHash }}`.\n\nYou have `{{ $json.response }}` of token `{{ $('Swap Configs').item.json.token0 }}` left. ",
        "chatId": "={{ $('Swap Configs').item.json.telegramChatId }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "5caf1b8d-514f-490a-affb-1bf2e5dd1f83",
      "name": "Success Details (Buy)",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1760,
        864
      ],
      "parameters": {
        "text": "=\u2705 Swapped `{{ $('Swap Configs').item.json.amountDCA }}` `{{ $('Swap Configs').item.json.token0 }}` for `{{ $('Get Buy Qoute').item.json.result.decodedData[0] }}` `{{ $('Swap Configs').item.json.token1 }}`. \n\nThe `{{ $('Swap Configs').item.json.secondsAgo }}` second TWAP was `{{ $('Calculate TWAP').item.json.twap }}`. Your tx hash is `{{ $('Buy ETH').item.json.transactionHash }}`.\n\nYou have `{{ $json.response }}` of token `{{ $('Swap Configs').item.json.token0 }}` left. ",
        "chatId": "={{ $('Swap Configs').item.json.telegramChatId }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "fd79c4dc-6e89-4335-97c2-040371411b6f",
      "name": "Buy Failure Notification",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1536,
        1088
      ],
      "parameters": {
        "text": "=\u274c Swap Failed",
        "chatId": "={{ $('Swap Configs').item.json.telegramChatId }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "e0d63f88-2224-42ad-ac1d-c04ef8ff356c",
      "name": "Sell Failure Notification",
      "type": "n8n-nodes-base.telegram",
      "position": [
        1536,
        656
      ],
      "parameters": {
        "text": "=\u274c Swap Failed",
        "chatId": "={{ $('Swap Configs').item.json.telegramChatId }}",
        "additionalFields": {}
      },
      "credentials": {
        "telegramApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "e031ff10-6e4c-46aa-b86e-5d5f014e50c3",
      "name": "Check New Funds",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        1536,
        432
      ],
      "parameters": {
        "params": "={\n  \"account\": \"{{ $('Swap Configs').item.json.delegator }}\"\n}",
        "operation": "read",
        "contractMethodId": "bfc44279-e20b-4452-b809-d422134700b3"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "06a9d916-cbe3-437f-9b99-5537205bac93",
      "name": "Get Buy Qoute",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        416,
        1088
      ],
      "parameters": {
        "params": "={\n  \"params\": \n    {\n  \"tokenIn\": \"{{ $('Swap Configs').item.json.token1 }}\",\n  \"tokenOut\": \"{{ $('Swap Configs').item.json.token0 }}\",\n  \"amountIn\": \"{{ $('Swap Configs').item.json.amountDCA }}\",\n  \"fee\": \"{{ $('Swap Configs').item.json.fee }}\",\n  \"sqrtPriceLimitX96\": \"0\"\n    }\n} ",
        "operation": "simulate",
        "contractMethodId": "48b96850-aea3-4faf-87d5-4e67f2baee89"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b93698b5-b489-409a-8ca9-b645577efc0d",
      "name": "Get Sell Qoute",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        416,
        656
      ],
      "parameters": {
        "params": "={\n  \"params\": \n    {\n  \"tokenIn\": \"{{ $('Swap Configs').item.json.token0 }}\",\n  \"tokenOut\": \"{{ $('Swap Configs').item.json.token1 }}\",\n  \"amountIn\": \"{{ $('Parse Last Trade').item.json.memo.amoutOut }}\",\n  \"fee\": \"{{ $('Swap Configs').item.json.fee }}\",\n  \"sqrtPriceLimitX96\": \"0\"\n    }\n} ",
        "operation": "simulate",
        "contractMethodId": "48b96850-aea3-4faf-87d5-4e67f2baee89"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "436a7bdb-9611-49bf-bf13-8205bae23985",
      "name": "Get Last Trade Type",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        -480,
        864
      ],
      "parameters": {
        "memo": "rangeTrade",
        "status": "Completed",
        "chainId": 42161,
        "pageSize": 1,
        "resource": "transactions",
        "createdAfter": 1758165556,
        "createdBefore": 0
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "5011693c-edc5-435b-adc0-afbd6e837d86",
      "name": "Parse Last Trade",
      "type": "n8n-nodes-base.code",
      "position": [
        -256,
        864
      ],
      "parameters": {
        "jsCode": "try {\n  const memo = JSON.parse($input.first().json.memo)\n  console.log(\"memo:\", memo)\n  $input.first().json.memo = memo; \n} catch {\n  console.log(\"no memo\")\n}\n\nreturn $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "2106c64e-4e47-4929-a8b0-8257eea2c513",
      "name": "Don't Repeat Buys",
      "type": "n8n-nodes-base.if",
      "position": [
        192,
        1088
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "8f1a4e9c-21d1-499b-8221-318875775842",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.memo.rangeTrade }}",
              "rightValue": "sell"
            },
            {
              "id": "7bee6833-7f7e-442e-aef2-99ccb83e34bb",
              "operator": {
                "type": "object",
                "operation": "notExists",
                "singleValue": true
              },
              "leftValue": "={{ $json.memo }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2,
      "alwaysOutputData": true
    },
    {
      "id": "ca115115-772c-41fa-8f6e-443a54f85119",
      "name": "Don't Repeat Sells",
      "type": "n8n-nodes-base.if",
      "position": [
        192,
        656
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "8f1a4e9c-21d1-499b-8221-318875775842",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.memo.rangeTrade }}",
              "rightValue": "buy"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "66f7bee5-ac95-4af1-aebb-370eb07ab418",
      "name": "List wallets",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        -464,
        1872
      ],
      "parameters": {
        "chainId": 42161,
        "resource": "wallets"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "966f9e36-7cb2-4fd3-922f-12aa9948c7c8",
      "name": "When clicking \u2018Execute workflow\u2019",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -688,
        1872
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "a7762d6f-cba4-440d-b395-c8bf6d425f63",
      "name": "Assure WETH Methods",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        432,
        1488
      ],
      "parameters": {
        "chainId": 42161,
        "promptId": "a9bac97d-cf4d-4de0-8523-bad09b6b507d",
        "walletId": "={{ $('Get Wallet ID').item.json.walletId }}",
        "operation": "assureContractMethodsFromPrompt",
        "contractAddress": "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "b98cde01-6b97-4fd8-af01-738cbbd7d304",
      "name": "Assure USDC Methods",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        432,
        1872
      ],
      "parameters": {
        "chainId": 42161,
        "promptId": "7d92d5db-99e3-4b1e-9cfe-74e80eeb842b",
        "walletId": "={{ $('Get Wallet ID').item.json.walletId }}",
        "operation": "assureContractMethodsFromPrompt",
        "contractAddress": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "618bce69-c48d-4310-9f10-ae5e9b27eaa7",
      "name": "Assure QuoterV2 Methods",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        432,
        2256
      ],
      "parameters": {
        "chainId": 42161,
        "promptId": "e439252a-a9e9-43d8-bec8-f4ce3391c49d",
        "walletId": "={{ $('Get Wallet ID').item.json.walletId }}",
        "operation": "assureContractMethodsFromPrompt",
        "contractAddress": "0x61fFE014bA17989E743c5F6cB21bF9697530B21e"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ffaa84b7-baa9-40d5-afb8-31e4cbdd1015",
      "name": "Assure SwapRouter02 Methods",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        432,
        1680
      ],
      "parameters": {
        "chainId": 42161,
        "promptId": "4fa14406-c913-4642-991d-e310ff138a8a",
        "walletId": "={{ $('Get Wallet ID').item.json.walletId }}",
        "operation": "assureContractMethodsFromPrompt",
        "contractAddress": "0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "dab49392-f4dc-4640-9d60-f787fcb00245",
      "name": "Assure ETH/USDC Pool Methods",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        432,
        2064
      ],
      "parameters": {
        "chainId": 42161,
        "promptId": "9a97c00a-797a-4dc9-9a3f-e32596cf9301",
        "walletId": "={{ $('Get Wallet ID').item.json.walletId }}",
        "operation": "assureContractMethodsFromPrompt",
        "contractAddress": "0xC6962004f452bE9203591991D15f6b388e09E8D0"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d06c5736-9e53-4613-a17c-cf1a1467085a",
      "name": "If",
      "type": "n8n-nodes-base.if",
      "position": [
        -240,
        1872
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b2f25fac-5a5d-4963-b1f6-05c8dfce25a6",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.id }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "c679feaf-f1db-4391-9e98-75c0895046db",
      "name": "Create wallet",
      "type": "n8n-nodes-1shot.oneShot",
      "position": [
        -16,
        1952
      ],
      "parameters": {
        "name": "=\"{{ $today }}\"",
        "chainId": 42161,
        "resource": "wallets",
        "operation": "create",
        "description": "Range Trading Wallet"
      },
      "credentials": {
        "oneShotOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "324b3986-de38-43b6-8341-bf600094f555",
      "name": "Get Wallet ID",
      "type": "n8n-nodes-base.code",
      "position": [
        208,
        1872
      ],
      "parameters": {
        "jsCode": "let walletId; \ntry {\n  walletId = $input.first().json.id;\n} catch {\n  walletId = $input.first().json.id;\n}\n\n$input.first().json.walletId = walletId; \n\nreturn $input.all();"
      },
      "typeVersion": 2
    },
    {
      "id": "5239ceb0-6c0d-42a4-ab6b-1a48292bf412",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        160,
        848
      ],
      "parameters": {
        "width": 480,
        "content": "## First Trade Setup\n\nThis workflow will attempt to perform a WETH buy as its first trade. To change it so the first trade is a sell from WETH to USDC, remove the  condition `{{ $json.memo }} does not exist` from `Don't Repeat Buys` and add it to `Don't Repeat Sells`. "
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a8ed007b-44d0-4da5-a0f0-f45b53d9cb36",
  "connections": {
    "If": {
      "main": [
        [
          {
            "node": "Get Wallet ID",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create wallet",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Buy ETH": {
      "main": [
        [
          {
            "node": "Check Remaining Funds",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Buy Failure Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sell ETH": {
      "main": [
        [
          {
            "node": "Check New Funds",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sell Failure Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confirm Buy": {
      "main": [
        [
          {
            "node": "Buy or Cancel?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Confirm Sell": {
      "main": [
        [
          {
            "node": "Sell or Cancel?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List wallets": {
      "main": [
        [
          {
            "node": "If",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Swap Configs": {
      "main": [
        [
          {
            "node": "Fetch Pool TWA Observations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create wallet": {
      "main": [
        [
          {
            "node": "Get Wallet ID",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Buy Qoute": {
      "main": [
        [
          {
            "node": "Confirm Buy",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Wallet ID": {
      "main": [
        [
          {
            "node": "Assure WETH Methods",
            "type": "main",
            "index": 0
          },
          {
            "node": "Assure SwapRouter02 Methods",
            "type": "main",
            "index": 0
          },
          {
            "node": "Assure USDC Methods",
            "type": "main",
            "index": 0
          },
          {
            "node": "Assure ETH/USDC Pool Methods",
            "type": "main",
            "index": 0
          },
          {
            "node": "Assure QuoterV2 Methods",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Buy or Cancel?": {
      "main": [
        [
          {
            "node": "Give Approval to Router (Buy)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Purchase Cancelled",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate TWAP": {
      "main": [
        [
          {
            "node": "Get Last Trade Type",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Sell Qoute": {
      "main": [
        [
          {
            "node": "Confirm Sell",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check New Funds": {
      "main": [
        [
          {
            "node": "Success Details (Sell)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Sell or Cancel?": {
      "main": [
        [
          {
            "node": "Give Approval to Router (Sell)",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sell Cancelled",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Last Trade": {
      "main": [
        [
          {
            "node": "Buy, Sell or Hold",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Swap Configs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Buy, Sell or Hold": {
      "main": [
        [
          {
            "node": "Don't Repeat Sells",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Don't Repeat Buys",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Don't Repeat Buys": {
      "main": [
        [
          {
            "node": "Get Buy Qoute",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Don't Repeat Sells": {
      "main": [
        [
          {
            "node": "Get Sell Qoute",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Last Trade Type": {
      "main": [
        [
          {
            "node": "Parse Last Trade",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Remaining Funds": {
      "main": [
        [
          {
            "node": "Success Details (Buy)",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Pool TWA Observations": {
      "main": [
        [
          {
            "node": "Calculate TWAP",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Give Approval to Router (Buy)": {
      "main": [
        [
          {
            "node": "Buy ETH",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Buy Failure Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Give Approval to Router (Sell)": {
      "main": [
        [
          {
            "node": "Sell ETH",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Sell Failure Notification",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "List wallets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow will monitor the price of a token trading pair (default is ETH - USDC) and automatically buy into ETH or sell into USDC based on a price window configured by the user.

Source: https://n8n.io/workflows/8427/ — original creator credit. Request a take-down →

More Slack & Telegram workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Slack & Telegram

⚠️ Heads up: this is satire. The "Hell Yeah!" workflow is a parody of "automate your whole life with AI agents" grindset content. The API endpoints are fictional and the function nodes are illustrativ

HTTP Request, Salesforce, Telegram +4
Slack & Telegram

This workflow continuously monitors the Meta Ads Library for new creatives from a specific competitor pages, logs them into Google Sheets, and sends a concise Telegram notification with the number of

HTTP Request, Telegram, Google Sheets +1
Slack & Telegram

This n8n workflow template is designed to provide real-time alerts on new cryptocurrency exchange listings and delistings. It caters especially to crypto traders, investors, and enthusiasts who want t

Supabase, HTTP Request, Telegram +2
Slack & Telegram

&gt; n8n, Binance API, Google Sheets, Slack, Telegram, Jira & Email

HTTP Request, Google Sheets, Slack +3
Slack & Telegram

Stay ahead of commodity market movements with automated news collection, translation, and sector impact analysis. This workflow monitors Oil, Gold, and Grain markets from global English sources, trans

HTTP Request, Discord, Telegram +1