curl --request POST \
--url https://api.ternswap.xyz/v1/quote/{id}/submit \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"call": {
"calldata": [
"0x4",
"0x1"
],
"contractAddress": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a",
"entrypoint": "apply_actions"
},
"proof": "AAAAAQ…",
"proofFacts": [
"0x50524f4f4632",
"0x5649525455414c5f534e4f53"
]
}
'import requests
url = "https://api.ternswap.xyz/v1/quote/{id}/submit"
payload = {
"call": {
"calldata": ["0x4", "0x1"],
"contractAddress": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a",
"entrypoint": "apply_actions"
},
"proof": "AAAAAQ…",
"proofFacts": ["0x50524f4f4632", "0x5649525455414c5f534e4f53"]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
call: {
calldata: ['0x4', '0x1'],
contractAddress: '0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a',
entrypoint: 'apply_actions'
},
proof: 'AAAAAQ…',
proofFacts: ['0x50524f4f4632', '0x5649525455414c5f534e4f53']
})
};
fetch('https://api.ternswap.xyz/v1/quote/{id}/submit', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ternswap.xyz/v1/quote/{id}/submit",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'call' => [
'calldata' => [
'0x4',
'0x1'
],
'contractAddress' => '0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a',
'entrypoint' => 'apply_actions'
],
'proof' => 'AAAAAQ…',
'proofFacts' => [
'0x50524f4f4632',
'0x5649525455414c5f534e4f53'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.ternswap.xyz/v1/quote/{id}/submit"
payload := strings.NewReader("{\n \"call\": {\n \"calldata\": [\n \"0x4\",\n \"0x1\"\n ],\n \"contractAddress\": \"0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a\",\n \"entrypoint\": \"apply_actions\"\n },\n \"proof\": \"AAAAAQ…\",\n \"proofFacts\": [\n \"0x50524f4f4632\",\n \"0x5649525455414c5f534e4f53\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ternswap.xyz/v1/quote/{id}/submit")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"call\": {\n \"calldata\": [\n \"0x4\",\n \"0x1\"\n ],\n \"contractAddress\": \"0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a\",\n \"entrypoint\": \"apply_actions\"\n },\n \"proof\": \"AAAAAQ…\",\n \"proofFacts\": [\n \"0x50524f4f4632\",\n \"0x5649525455414c5f534e4f53\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ternswap.xyz/v1/quote/{id}/submit")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"call\": {\n \"calldata\": [\n \"0x4\",\n \"0x1\"\n ],\n \"contractAddress\": \"0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a\",\n \"entrypoint\": \"apply_actions\"\n },\n \"proof\": \"AAAAAQ…\",\n \"proofFacts\": [\n \"0x50524f4f4632\",\n \"0x5649525455414c5f534e4f53\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "q_01M63G8Z0K7W2YQ5VJ6E3R9T4N",
"status": "awaiting_deposit",
"txHash": "0x3af816e76304424920bbc91c44cf34cfa46027593b01810ff19f8ed6819e8a8"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}Submit a private swap
Hands the private swap the user’s wallet proved (strk20PrepareInvoke over the quote’s execute.strk20) to Tern’s
relayer. The relayer simulates it with its proof and sends it only if it calls the pool’s apply_actions, pays the
relayer the quoted fee, and swaps for this quote; its account is the sender, so the user’s never appears. Submit
before expiresAt. A repeated call returns the same transaction.
curl --request POST \
--url https://api.ternswap.xyz/v1/quote/{id}/submit \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"call": {
"calldata": [
"0x4",
"0x1"
],
"contractAddress": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a",
"entrypoint": "apply_actions"
},
"proof": "AAAAAQ…",
"proofFacts": [
"0x50524f4f4632",
"0x5649525455414c5f534e4f53"
]
}
'import requests
url = "https://api.ternswap.xyz/v1/quote/{id}/submit"
payload = {
"call": {
"calldata": ["0x4", "0x1"],
"contractAddress": "0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a",
"entrypoint": "apply_actions"
},
"proof": "AAAAAQ…",
"proofFacts": ["0x50524f4f4632", "0x5649525455414c5f534e4f53"]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
call: {
calldata: ['0x4', '0x1'],
contractAddress: '0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a',
entrypoint: 'apply_actions'
},
proof: 'AAAAAQ…',
proofFacts: ['0x50524f4f4632', '0x5649525455414c5f534e4f53']
})
};
fetch('https://api.ternswap.xyz/v1/quote/{id}/submit', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ternswap.xyz/v1/quote/{id}/submit",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'call' => [
'calldata' => [
'0x4',
'0x1'
],
'contractAddress' => '0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a',
'entrypoint' => 'apply_actions'
],
'proof' => 'AAAAAQ…',
'proofFacts' => [
'0x50524f4f4632',
'0x5649525455414c5f534e4f53'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.ternswap.xyz/v1/quote/{id}/submit"
payload := strings.NewReader("{\n \"call\": {\n \"calldata\": [\n \"0x4\",\n \"0x1\"\n ],\n \"contractAddress\": \"0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a\",\n \"entrypoint\": \"apply_actions\"\n },\n \"proof\": \"AAAAAQ…\",\n \"proofFacts\": [\n \"0x50524f4f4632\",\n \"0x5649525455414c5f534e4f53\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.ternswap.xyz/v1/quote/{id}/submit")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"call\": {\n \"calldata\": [\n \"0x4\",\n \"0x1\"\n ],\n \"contractAddress\": \"0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a\",\n \"entrypoint\": \"apply_actions\"\n },\n \"proof\": \"AAAAAQ…\",\n \"proofFacts\": [\n \"0x50524f4f4632\",\n \"0x5649525455414c5f534e4f53\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ternswap.xyz/v1/quote/{id}/submit")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"call\": {\n \"calldata\": [\n \"0x4\",\n \"0x1\"\n ],\n \"contractAddress\": \"0x040337b1af3c663e86e333bab5a4b28da8d4652a15a69beee2b677776ffe812a\",\n \"entrypoint\": \"apply_actions\"\n },\n \"proof\": \"AAAAAQ…\",\n \"proofFacts\": [\n \"0x50524f4f4632\",\n \"0x5649525455414c5f534e4f53\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"id": "q_01M63G8Z0K7W2YQ5VJ6E3R9T4N",
"status": "awaiting_deposit",
"txHash": "0x3af816e76304424920bbc91c44cf34cfa46027593b01810ff19f8ed6819e8a8"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}{
"code": "invalid_request",
"detail": "<string>",
"status": 1,
"title": "<string>",
"type": "<string>"
}Authorizations
A partner's API key. Optional: without it a request is anonymous. An invalid key is 401 unauthorized.
Headers
Repeats with the same key and body get the first response; 1 to 255 visible ASCII characters
Path Parameters
The private swap's quote ID
Body
The body of POST /v1/quote/{id}/submit: a private swap's transaction as the wallet proved it
(strk20PrepareInvoke). Debug shows the proof's size only.
Response
The relayer sends the private swap; follow the quote's status
202 Accepted from POST /v1/quote/{id}/submit: the relayer is sending the private swap. Follow the quote with
GET /v1/quote/{id}.
A quote's public status (design/03-server.md, Quote lifecycle).
awaiting_deposit, deposit_confirmed, in_progress, completed, refunded, expired The transaction's hash, once the relayer has signed it; the quote's status names it in any case.