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 validityExecPending
: Awaiting executionWaitingForConfirmation
: Waiting for block confirmationExecSuccess
: Transaction was successfully executedCancelled
: Transaction was cancelled (i.e., did not enter theExecPending
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.