This document is a brief description of the swap flow, with examples, using the Junction API.

Entry point and graphQL playground: https://router-dev.junction.exchange/graphql

Flow description

The swap flow is a sequence of queries and mutations.

  1. Check all available assets or search for a specific token

    The tokenFilterV5 query allows you to search for a crypto asset by symbol, name, address or chain. If no “search phrase” provided, a paginated list of assets is returned. This is a good way to check all of the supported assets.

    // Example code to search tokens
    const query = `
      query TokenFilterV5 {
      routingV2 {
        tokenFilterV5(searchPhrase: "COIN", limit: 2) {
          tokens {
            name
            symbol
            chainSymbol
            cryptoAsset {
              id
              name
              symbol
              chain
              decimals
              contract
            }
          }
        }
      }
    }
    `;
    
    fetch('<https://router-dev.junction.exchange/graphql>', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ query })
    })
    .then(res => res.json())
    .then(data => console.log(data));
    
    

    Output:

    {
      "data": {
        "routingV2": {
          "tokenFilterV5": {
            "tokens": [
              {
                "name": "TONCOIN",
                "symbol": "TONCOIN",
                "chainSymbol": "BSC",
                "cryptoAsset": {
                  "id": "91d36892-8bfa-4b6e-a91c-6c9dc4f0fdc4",
                  "name": "Toncoin",
                  "symbol": "TON",
                  "chain": "BinanceSmartChain",
                  "decimals": 9,
                  "contract": "0x76a797a59ba2c17726896976b7b3747bfd1d220f"
                }
              },
              {
                "name": "TONCOIN",
                "symbol": "TONCOIN",
                "chainSymbol": "ETH",
                "cryptoAsset": {
                  "id": "91d36892-8bfa-4b6e-a91c-6c9dc4f0fdc4",
                  "name": "Toncoin",
                  "symbol": "TONCOIN",
                  "chain": "Ethereum",
                  "decimals": 9,
                  "contract": "0x582d872a1b094fc48f5de31d3b73f2d9be47def1"
                }
              }
            ]
          }
        }
      }
    }
    
  2. Once you find tokens to swap, one can get a quote via the routeV7 query. A few parameters are required like a list of addresses by chain, the amount and tokens to swap…

    // Example code to get swap route and quote
    const query = `
      query RouteV7($srcToken: String!, $destToken: String!, $addresses: [AddressRouteInputTypeV2!]!, $destAddress: String!, $infiniteApproval: Boolean, $slippage: String, $amountSource: String) {
      routingV2 {
        routeV7(srcToken: $srcToken, destToken: $destToken, addresses: $addresses, destAddress: $destAddress, infiniteApproval: $infiniteApproval, slippage: $slippage, amountSource: $amountSource) {
          ... on RouteTypeV5 {
            addresses {
              chain
              address
            }
            destAddress
            priceRate
            priceRateText
            slippage
            autoSlippageEnabled
            estimatedExecutionTime
            maxExecutionTime
            gasPrices
            priceImpact
            amountIn
            approvalInfiniteFlag
            tradesRoute {
              provider {
                id
                name
                time
                icon
              }
              amountIn
              amountOut
              minAmountReceived
              assetIn {
                id
                chainSymbol
                asset {
                  decimals
                  symbol
                  chain
                  contract
                  price {
                    amount
                  }
                }
                listProviders
              }
              assetOut {
                id
                chainSymbol
                asset {
                  decimals
                  symbol
                  chain
                  contract
                }
                listProviders
              }
              fee {
                networkFeeDollar
                networkFeeAsset
                inboundFeeDollar
                inboundFeeAsset
                swapFee
                feeRateTransaction
                xdefiSwapFee
                xdefiSwapFeeDollar
              }
              priceRateUsdAssetOut
              priceRateUsdAssetIn
              tradeType
              referral {
                medium
                link
              }
              reward {
                asset {
                  id
                  chainSymbol
                  asset {
                    chain
                    contract
                  }
                  listProviders
                }
                amount
                amountUsd
              }
              isStreaming
            }
            errorBuildingRoute
            feeTier
            quoteOrigin
          }
          ... on RouteNotAvailableV2 {
            label
            reason
          }
        }
      }
    }
    `;
    
    const vars = `
    	{
    	  "srcToken": "ETH.ETH",
    	  "destToken": "ETH.USDC",
    	  "addresses": [
    	    {
    	      "address": "0x6bE3FeDC542904fB25B7b76b247e47248c0F9Ff2",
    	      "chain": "ETH"
    	    }
    	  ],
    	  "destAddress": "0x6bE3FeDC542904fB25B7b76b247e47248c0F9Ff2",
    	  "infiniteApproval": false,
    	  "slippage": "1.5",
    	  "amountSource": "1"
    	}
    `;
    
    fetch('<https://router-dev.junction.exchange/graphql>', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ query: query, variables: vars })
    })
    .then(res => res.json())
    .then(data => console.log(data));
    
    

    Output:

    {
      "data": {
        "routingV2": {
          "routeV7": {
            "addresses": [
              {
                "chain": "ETH",
                "address": "0x6bE3FeDC542904fB25B7b76b247e47248c0F9Ff2"
              }
            ],
            "destAddress": "0x6bE3FeDC542904fB25B7b76b247e47248c0F9Ff2",
            "priceRate": "2611.7006220287599533103352390000000000000000",
            "priceRateText": "1 ETH = 2611.700622 USDC",
            "slippage": "1.5",
            "autoSlippageEnabled": false,
            "estimatedExecutionTime": 60,
            "maxExecutionTime": 60,
            "gasPrices": {},
            "priceImpact": "-1.00%",
            "amountIn": "1.0000000000000000000000000000000000000000",
            "approvalInfiniteFlag": false,
            "tradesRoute": [
              {
                "provider": {
                  "id": "5f15f329-ebf2-4dd9-b350-f20d26a2b633",
                  "name": "0x",
                  "time": "60",
                  "icon": "<https://assets.website-files.com/640bf70a17d12b42d97a052b/641a0fd580cd8c857eef8cb7_0x-logo-light.svg>"
                },
                "amountIn": "1.0000000000000000000000000000000000000000",
                "amountOut": "2585.7056150000000000000000000000000000000000",
                "minAmountReceived": "2546.9200307750000000000000000000000000000000",
                "assetIn": {
                  "id": "bfb420ba-31d9-491f-9de2-7507fa6c6341",
                  "chainSymbol": "ETH",
                  "asset": {
                    "decimals": 18,
                    "symbol": "ETH",
                    "chain": "Ethereum",
                    "contract": null,
                    "price": {
                      "amount": "2619.68"
                    }
                  },
                  "listProviders": [
                    "OpenOceanV4",
                    "Socket",
                    "Squid",
                    "SwapKit",
                    "0x"
                  ]
                },
                "assetOut": {
                  "id": "7f139aeb-17ae-4e98-a745-4dc6ec48796a",
                  "chainSymbol": "ETH",
                  "asset": {
                    "decimals": 6,
                    "symbol": "USDC",
                    "chain": "Ethereum",
                    "contract": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
                  },
                  "listProviders": [
                    "OpenOceanV4",
                    "Socket",
                    "Circle",
                    "Squid",
                    "SwapKit",
                    "0x"
                  ]
                },
                "fee": {
                  "networkFeeDollar": "3.8835919300280000000000000000000000000000",
                  "networkFeeAsset": "3.8843960000000000000000000000000000000000",
                  "inboundFeeDollar": "5.6546761418652080473380000000000000000000",
                  "inboundFeeAsset": "0.0021655801030443205500000000000000000000",
                  "swapFee": "9.5382680718932080473380000000000000000000",
                  "feeRateTransaction": "12.8700000000000000000000000000000000000000",
                  "xdefiSwapFee": "0.000000",
                  "xdefiSwapFeeDollar": "0E-12"
                },
                "priceRateUsdAssetOut": "0.9997930000000000000000000000000000000000",
                "priceRateUsdAssetIn": "2611.1600000000000000000000000000000000000000",
                "tradeType": "SWAP",
                "referral": {
                  "medium": null,
                  "link": null
                },
                "reward": null,
                "isStreaming": false
              }
            ],
            "errorBuildingRoute": null,
            "feeTier": 0,
            "quoteOrigin": null
          }
        }
      }
    }
    
  3. In order to validate the quote, the generated route needs to be sent to Junction via the transactionsV4 mutation. As result, a route Id is returned.

    // Example code to validate route
    const mutation = `
    mutation transactionsV4($routeData: RouteInputTypeV4!) {
      transactionsV4(routeData: $routeData) {
        routeId
      }
    }
    `;
    
    // Paste contents of previous step here
    const vars = `
    {
    	"routeData": {
    		"addresses": [{}],
    		"destAddress: ""
    }`;
    
    fetch('<https://router-dev.junction.exchange/graphql>', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ query: mutation, variables: vars })
    })
    .then(res => res.json())
    .then(data => console.log(data));
    
    

    Output:

    {
      "data": {
        "transactionsV4": {
          "routeId": "669672ea-6d98-440a-94ad-bd7321998bd0"
        }
      }
    }
    
  4. This route Id will be used to generate transaction data to sign and broadcast in order to execute the swap or bridge. The query for that is tradesV2.

    // Example code to fetch tx data
    const query = `
      query tradesV2 {
      routingV2 {
        tradesV2(routeId: "669672ea-6d98-440a-94ad-bd7321998bd0") {
          transaction {
            chain
            amount
            signer
            recipient
            feeRate
            txType
            tradeId
            routeId
            gasPrice
            data
            unsignedStdTx
            gasLimit
            memo
            actions
            signerId
            receiverId
            isMultiSig
          }
          tradeRoute {
            provider {
              id
              name
              time
              icon
            }
            amountIn
            amountOut
            minAmountReceived
            assetIn {
              id
              chainSymbol
              asset {
                contract
                chain
              }
              isHotNewToken
              listProviders
            }
            assetOut {
              id
              chainSymbol
              asset {
                chain
                contract
              }
              isHotNewToken
              listProviders
            }
            fee {
              networkFeeDollar
              networkFeeAsset
              inboundFeeDollar
              inboundFeeAsset
              swapFee
              feeRateTransaction
              xdefiSwapFee
              xdefiSwapFeeDollar
            }
            priceRateUsdAssetOut
            priceRateUsdAssetIn
            tradeType
            isStreaming
          }
          routeId
          tradeId
          status {
            status
            txHash
          }
        }
      }
    }
    `;
    
    fetch('<https://router-dev.junction.exchange/graphql>', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ query })
    })
    .then(res => res.json())
    .then(data => console.log(data));
    
    

    Output:

    {
      "data": {
        "routingV2": {
          "tradesV2": [
            {
              "transaction": {
                "chain": "ETH",
                "amount": "1000000000000000000",
                "signer": "0x6bE3FeDC542904fB25B7b76b247e47248c0F9Ff2",
                "recipient": "0x0000000000001fF3684f28c67538d4D072C22734",
                "feeRate": "6730113172",
                "txType": "SWAP",
                "tradeId": "365",
                "routeId": null,
                "gasPrice": "6730113172",
                "data": "0x2213bc0b0000000000000000000000005418226af9c8d5d287a78fbbbcd337b86ec07d6100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000005418226af9c8d5d287a78fbbbcd337b86ec07d6100000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000005a41fff991f0000000000000000000000006be3fedc542904fb25b7b76b247e47248c0f9ff2000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000097dc6ee500000000000000000000000000000000000000000000000000000000000000a04b2b29c389f0adf5dd1d463100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004000000000000000000000000000000000000000000000000000000000000008000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000002e00000000000000000000000000000000000000000000000000000000000000380000000000000000000000000000000000000000000000000000000000000010438c9c147000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000000000000000000000000000000000000000002710000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000024d0e30db00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e48d68a1560000000000000000000000005418226af9c8d5d287a78fbbbcd337b86ec07d61000000000000000000000000000000000000000000000000000000000000271000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002cc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2010001f4a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000064c876d21d000000000000000000000000f5c4f3dc02c3fb9279495a8fef7b0741da956157000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000009a6c21af00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012438c9c147000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000000f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48000000000000000000000000000000000000000000000000000000000000002400000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000044a9059cbb000000000000000000000000ad01c20d5886137e056775af56915de824c8fce50000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
                "unsignedStdTx": null,
                "gasLimit": "487372",
                "memo": null,
                "actions": null,
                "signerId": null,
                "receiverId": null,
                "isMultiSig": false
              },
              "tradeRoute": {
                "provider": {
                  "id": "5f15f329-ebf2-4dd9-b350-f20d26a2b633",
                  "name": "0x",
                  "time": "60",
                  "icon": "<https://assets.website-files.com/640bf70a17d12b42d97a052b/641a0fd580cd8c857eef8cb7_0x-logo-light.svg>"
                },
                "amountIn": "1.0000000000000000000000000000000000000000",
                "amountOut": "2585.7056150000000000000000000000000000000000",
                "minAmountReceived": "2546.9200307750000000000000000000000000000000",
                "assetIn": {
                  "id": "bfb420ba-31d9-491f-9de2-7507fa6c6341",
                  "chainSymbol": "ETH",
                  "asset": {
                    "contract": null,
                    "chain": "Ethereum"
                  },
                  "isHotNewToken": false,
                  "listProviders": [
                    "OpenOceanV4",
                    "Socket",
                    "Squid",
                    "SwapKit",
                    "0x"
                  ]
                },
                "assetOut": {
                  "id": "7f139aeb-17ae-4e98-a745-4dc6ec48796a",
                  "chainSymbol": "ETH",
                  "asset": {
                    "chain": "Ethereum",
                    "contract": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
                  },
                  "isHotNewToken": false,
                  "listProviders": [
                    "OpenOceanV4",
                    "Socket",
                    "Circle",
                    "Squid",
                    "SwapKit",
                    "0x"
                  ]
                },
                "fee": {
                  "networkFeeDollar": "3.8835919300280000000000000000000000000000",
                  "networkFeeAsset": "3.8843960000000000000000000000000000000000",
                  "inboundFeeDollar": "5.6546761418652080473380000000000000000000",
                  "inboundFeeAsset": "0.0021655801030443205500000000000000000000",
                  "swapFee": "9.5382680718932080473380000000000000000000",
                  "feeRateTransaction": "12.0000000000000000000000000000000000000000",
                  "xdefiSwapFee": "0.000000",
                  "xdefiSwapFeeDollar": "0E-12"
                },
                "priceRateUsdAssetOut": "0.9997930000000000000000000000000000000000",
                "priceRateUsdAssetIn": "2611.1600000000000000000000000000000000000000",
                "tradeType": "SWAP",
                "isStreaming": false
              },
              "routeId": "669672ea-6d98-440a-94ad-bd7321998bd0",
              "tradeId": "365",
              "status": {
                "status": null,
                "txHash": null
              }
            }
          ]
        }
      }
    }
    
  5. Once the transaction in data.routingV2.tradesV2.transaction.data is signed and broadcast by the user, the transaction hash needs to be passed to Junction’s API to track its progress. The transactionHashV3 mutation allows that.

    // Example code to search tokens
    const mutation = `
      mutation TransactionHashV3($routeId: String!, $tradeId: String!, $transactionHash: String!, $accountId: String!) {
      transactionHashV3(routeId: $routeId, tradeId: $tradeId, transactionHash: $transactionHash, accountId: $accountId)
    }
    `;
    
    const vars = `
    	{
    	  "routeId": "669672ea-6d98-440a-94ad-bd7321998bd0",
    	  "tradeId": "365",
    	  "transactionHash": "0xa4a03447154f2387cb7986b0ba05a30fd18aecb5d8de19f4fc46149fcb4dad75",
    	  "accountId": "junction:0x6bE3FeDC542904fB25B7b76b247e47248c0F9Ff2"
    	}
    `;
    
    fetch('<https://router-dev.junction.exchange/graphql>', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ query: mutation, variables: vars })
    })
    .then(res => res.json())
    .then(data => console.log(data));
    
    

    Output:

    {
      "data": {
        "transactionHashV3": "Success"
      }
    }
    
  6. After the hash is posted, one can track transaction status by calling tradesV2 query until the status is SUCCESS.