Portals Logo

Documentation
Guides
Gasless Transactions

POST v2/portal

This POST endpoint is for submitting a signedOrder transaction onchain via the Galaxy Broadcasting System, allowing you to take advantage of gas-free swaps and zaps. This endpoint requires that you submit both the orderId found in the context object and the signature of the signedOrder by the sender. To learn more about signing orders, see the Metamask documentation.

Example

Submitting a signedOrder to zap into Curve.fi am3CRV with USDC on Polygon

Request

The request must include the orderId and signature of the signedOrder object which was signed by the sender

"orderId": "e63d29b9-e52f-4baf-9b27-6f..."
"signature": "0x5a98f3a678396f0efcdaad1466ab01..."

Response

The response is similar to the GET response, with additional objects including steps and stepsSignedOrder, which describes each step the Portals Router will take to complete the order, a nonce for replay protection, the permitSignature if a gasless approval was used, and a status object which describes the status of the transaction being broadcasted for the sender

{
  "tx": {
    "data": "0x9d02210100...",
    "to": "0xC74063fdb47fe6dCE6d029A489BAb37b167Da57f"
  },
  "context": {
    "orderId": "e63d29b9-e52f-4baf-9b27-6f...",
    "isPermit": true,
    "minOutputAmount": "4603976404781646314",
    "minOutputAmountUsd": 4.969199395294698,
    "minOutputAmountSignedOrder": "4563913171814201419",
    "minOutputAmountUsdSignedOrder": 4.9259580370573675,
    "slippageTolerancePercentage": 0.32,
    "gasLimit": "914479",
    "inputAmount": "5000555",
    "inputAmountUsd": 4.999999938395001,
    "inputToken": "polygon:0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
    "outputToken": "polygon:0xe7a24ef0c5e95ffb0f6684b813a78f2a3ad7d171",
    "outputAmount": "4615515192763555202",
    "outputAmountUsd": 4.981653529117492,
    "outputAmountSignedOrder": "4575493148879352212",
    "outputAmountUsdSignedOrder": 4.938456627399818,
    "partner": "0x508ee1b661c7DeE089A5b5c3fD234f1058F03c38",
    "feeToken": "polygon:0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
    "feeAmount": "15002",
    "feeAmountUsd": 0.015000334778,
    "feeAmountSignedOrder": "58204",
    "feeAmountUsdSignedOrder": 0.05819723649567414,
    "sender": "0x4689CFF824d63117F9C4C42F3EC0001676F00d25",
    "recipient": "0x4689CFF824d63117F9C4C42F3EC0001676F00d25",
    "target": "0xC74063fdb47fe6dCE6d029A489BAb37b167Da57f",
    "value": "0",
    "route": ["USDC", "amUSDC", "am3CRV"],
    "steps": [
      "Transfer 0.015002 USDC to fee collector at polygon:0x508ee1b661c7DeE089A5b5c3fD234f1058F03c38",
      "Approve USDC to 0x8dFf5E27EA6b7AC08EbFdf9eB090F32ee9a30fcf",
      "Aavev2 deposit from USDC to amUSDC",
      "Approve amUSDC to 0x445fe580ef8d70ff569ab36e80c647af338db351",
      "Curve add_liquidity from amUSDC to am3CRV",
      "Transfer am3CRV to 0x4689CFF824d63117F9C4C42F3EC0001676F00d25"
    ],
    "stepsSignedOrder": [
      "Transfer 0.058204 USDC to fee collector at polygon:0x508ee1b661c7DeE089A5b5c3fD234f1058F03c38",
      "Approve USDC to 0x8dFf5E27EA6b7AC08EbFdf9eB090F32ee9a30fcf",
      "Aavev2 deposit from USDC to amUSDC",
      "Approve amUSDC to 0x445fe580ef8d70ff569ab36e80c647af338db351",
      "Curve add_liquidity from amUSDC to am3CRV",
      "Transfer am3CRV to 0x4689CFF824d63117F9C4C42F3EC0001676F00d25"
    ],
    "routeHash": "0x42bf5bdf545032ce6238759376ad938bc4daf7379a9929d305a500a96373f451"
  },
  "signedOrder": {
    "types": {
      "Order": [
        {
          "name": "inputToken",
          "type": "address"
        },
        {
          "name": "inputAmount",
          "type": "uint256"
        },
        {
          "name": "outputToken",
          "type": "address"
        },
        {
          "name": "minOutputAmount",
          "type": "uint256"
        },
        {
          "name": "recipient",
          "type": "address"
        }
      ],
      "SignedOrder": [
        {
          "name": "order",
          "type": "Order"
        },
        {
          "name": "routeHash",
          "type": "bytes32"
        },
        {
          "name": "sender",
          "type": "address"
        },
        {
          "name": "deadline",
          "type": "uint64"
        },
        {
          "name": "nonce",
          "type": "uint64"
        }
      ]
    },
    "domain": {
      "name": "PortalsRouter",
      "version": "1",
      "chainId": 137,
      "verifyingContract": "0xC74063fdb47fe6dCE6d029A489BAb37b167Da57f"
    },
    "value": {
      "order": {
        "inputToken": "0x2791bca1f2de4661ed88a30c99a7a9449aa84174",
        "outputToken": "0xe7a24ef0c5e95ffb0f6684b813a78f2a3ad7d171",
        "inputAmount": "5000555",
        "minOutputAmount": "4563913171814201419",
        "recipient": "0x4689CFF824d63117F9C4C42F3EC0001676F00d25"
      },
      "routeHash": "0xfe849489c01c33f9d2ee0f5eabbbc7a1e6c29f7cbcb393464f48637b790a9e79",
      "sender": "0x4689CFF824d63117F9C4C42F3EC0001676F00d25",
      "deadline": "1691403078",
      "nonce": "3"
    }
  },
  "steps": [
    ...,
    {
      "inputToken": "0x1a13f4ca1d028320a707d99520abfefca3998b7f",
      "target": "0x445fe580ef8d70ff569ab36e80c647af338db351",
      "amountIndex": {
        "type": "BigNumber",
        "hex": "0x01"
      },
      "data": "0x4515cef30000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
      "needsApproval": true,
      "approvalTarget": "0x445fe580ef8d70ff569ab36e80c647af338db351",
      "expectedReturn": 0.9999,
      "outputToken": "0xe7a24ef0c5e95ffb0f6684b813a78f2a3ad7d171",
      "comment": "Curve add_liquidity from amUSDC to am3CRV"
    },
    ...
  ],
  "nonce": "3",
  "permitSignature": "0x9fdc1d7...",
  "hash": "",
  "gelatoTaskId": "0xc148ce99ff485361148f4013540356f7cc2d970f8559175f12de...",
  "status": {
    "task": {
      "chainId": 137,
      "taskId": "0xc148ce99ff485361148f4013540356f7cc2d970f8559175f12de...",
      "taskState": "WaitingForConfirmation",
      "creationDate": "2023-08-07T10:01:23.601Z",
      "transactionHash": "0xe5a0878f736f4ecaee5820db8082750c82c390a4216b4620590546e2dcf75e67"
    }
  }
}

GET v2/portal/status

Example

Getting the status of the signedOrder to zap into Curve.fi am3CRV with USDC on Polygon from the previous example

Request:

As in the POST request, this request must include the orderId and signature of the signedOrder object which was signed by the sender.

"orderId": "e63d29b9-e52f-4baf-9b27-6f..."
"signature": "0x5a98f3a678396f0efcdaad1466ab01..."

Response:

The object returned from this endpoint is identical to the one returned in the POST request described above, allowing you to monitor the status object associated with the transaction. The status object will update throughout the lifecycle of the gasless transaction, from confirmation of receipt through to execution and inclusion in a block

{
  "tx": {
  ...
  },
  "context": {
  ...
  },
  "signedOrder": {
  ...
  },
  "steps": [
  ...
  ],
  "stepsSignedOrder": [
   ...
  ],
  "nonce": "4",
  "permitSignature": "0x9fdc1d7...",
  "hash": "",
  "gelatoTaskId": "0xbb8c4b6c4...",
  "status": {
    "task": {
      "chainId": 137,
      "taskId": "0xbb8c4b6c4...",
      "taskState": "WaitingForConfirmation",
      "creationDate": "2023-08-07T11:21:43.726Z",
      "executionDate": "2023-08-07T11:22:00.006Z",
      "transactionHash": "0x12c5a4efbf144b015865acbe62ff8fe0da1d9219d63a63ce3b478e1a267f124a",
      "blockNumber": 46016374
    }
  }
}

Tracking Status

The taskState property in the status object will update to reflect the current state of the transaction. The possible states are:

  • CheckPending: The transaction has been received and is being checked for validity
  • ExecPending: Awaiting execution
  • WaitingForConfirmation: Waiting for block confirmation
  • ExecSuccess: Transaction was successfully executed
  • Cancelled: Transaction was cancelled (i.e., did not enter the ExecPending state) due to an error.
  • ExecReverted: The onchain transaction has reverted.

Once the transactionHash field is populated, you can monitor the transaction using a Web3 library like Ethers.js or directly on Etherscan or equivalent.