curl --request POST \
--url https://staging.apimonaco.xyz/api/v1/auth/verify \
--header 'Content-Type: application/json' \
--data '
{
"address": "0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5",
"signature": "0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0",
"nonce": "abc123def456",
"sessionPublicKey": "3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
"clientId": "monaco-frontend",
"chainId": "1328",
"referralCode": "0x1234567890abcdef1234567890abcdef12345678"
}
'import requests
url = "https://staging.apimonaco.xyz/api/v1/auth/verify"
payload = {
"address": "0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5",
"signature": "0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0",
"nonce": "abc123def456",
"sessionPublicKey": "3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
"clientId": "monaco-frontend",
"chainId": "1328",
"referralCode": "0x1234567890abcdef1234567890abcdef12345678"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
address: '0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5',
signature: '0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0',
nonce: 'abc123def456',
sessionPublicKey: '3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29',
clientId: 'monaco-frontend',
chainId: '1328',
referralCode: '0x1234567890abcdef1234567890abcdef12345678'
})
};
fetch('https://staging.apimonaco.xyz/api/v1/auth/verify', 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://staging.apimonaco.xyz/api/v1/auth/verify",
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([
'address' => '0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5',
'signature' => '0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0',
'nonce' => 'abc123def456',
'sessionPublicKey' => '3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29',
'clientId' => 'monaco-frontend',
'chainId' => '1328',
'referralCode' => '0x1234567890abcdef1234567890abcdef12345678'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$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://staging.apimonaco.xyz/api/v1/auth/verify"
payload := strings.NewReader("{\n \"address\": \"0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5\",\n \"signature\": \"0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0\",\n \"nonce\": \"abc123def456\",\n \"sessionPublicKey\": \"3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29\",\n \"clientId\": \"monaco-frontend\",\n \"chainId\": \"1328\",\n \"referralCode\": \"0x1234567890abcdef1234567890abcdef12345678\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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://staging.apimonaco.xyz/api/v1/auth/verify")
.header("Content-Type", "application/json")
.body("{\n \"address\": \"0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5\",\n \"signature\": \"0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0\",\n \"nonce\": \"abc123def456\",\n \"sessionPublicKey\": \"3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29\",\n \"clientId\": \"monaco-frontend\",\n \"chainId\": \"1328\",\n \"referralCode\": \"0x1234567890abcdef1234567890abcdef12345678\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.apimonaco.xyz/api/v1/auth/verify")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"address\": \"0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5\",\n \"signature\": \"0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0\",\n \"nonce\": \"abc123def456\",\n \"sessionPublicKey\": \"3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29\",\n \"clientId\": \"monaco-frontend\",\n \"chainId\": \"1328\",\n \"referralCode\": \"0x1234567890abcdef1234567890abcdef12345678\"\n}"
response = http.request(request)
puts response.read_body{
"expiresAt": 1699876543,
"user": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"address": "0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5",
"username": "trader123"
},
"isNewUser": true,
"referralApplied": true
}Verify signature and authenticate
Verify signature and authenticate.
Verify the signed challenge message and create an authenticated session. Binds the caller-provided ed25519 session public key to the new session; subsequent requests are signed with the matching private key.
How the signature is checked depends on the address. Almost every address
is verified by recovering the signing key, exactly as before. EIP-1271
verification applies only to an address that is BOTH eligible for
contract-signature login AND has contract code deployed on chain: an
eligible payout wallet that is an ordinary EOA is still verified by
recovery. The two are mutually exclusive, and the request is identical
either way — signature carries whatever the wallet produced, and no
field changes. The one bound is length: a contract signature over 8192
decoded bytes is refused as invalid rather than forwarded to the chain,
which is far above any realistic owner set.
Because deciding that requires reading the chain, this adds one client-visible outcome the recovery path does not have: UNAVAILABLE (REST 503). It is retryable and is NOT a verdict on the signature. It covers three cases, and an eligible address can see any of them even when it turns out to be an EOA, because the code lookup happens first: the chain did not answer, it did not answer within the deadline, or the server declined to ask because its own concurrent-verification capacity was full. That last one is local saturation rather than a chain fault, so an operator diagnosing it should check this service before the RPC endpoint.
A rejected signature is 401, and so is a contract that rejects by REVERTING: that is the wallet answering “no”, not a failure to ask.
curl --request POST \
--url https://staging.apimonaco.xyz/api/v1/auth/verify \
--header 'Content-Type: application/json' \
--data '
{
"address": "0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5",
"signature": "0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0",
"nonce": "abc123def456",
"sessionPublicKey": "3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
"clientId": "monaco-frontend",
"chainId": "1328",
"referralCode": "0x1234567890abcdef1234567890abcdef12345678"
}
'import requests
url = "https://staging.apimonaco.xyz/api/v1/auth/verify"
payload = {
"address": "0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5",
"signature": "0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0",
"nonce": "abc123def456",
"sessionPublicKey": "3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29",
"clientId": "monaco-frontend",
"chainId": "1328",
"referralCode": "0x1234567890abcdef1234567890abcdef12345678"
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({
address: '0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5',
signature: '0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0',
nonce: 'abc123def456',
sessionPublicKey: '3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29',
clientId: 'monaco-frontend',
chainId: '1328',
referralCode: '0x1234567890abcdef1234567890abcdef12345678'
})
};
fetch('https://staging.apimonaco.xyz/api/v1/auth/verify', 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://staging.apimonaco.xyz/api/v1/auth/verify",
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([
'address' => '0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5',
'signature' => '0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0',
'nonce' => 'abc123def456',
'sessionPublicKey' => '3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29',
'clientId' => 'monaco-frontend',
'chainId' => '1328',
'referralCode' => '0x1234567890abcdef1234567890abcdef12345678'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$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://staging.apimonaco.xyz/api/v1/auth/verify"
payload := strings.NewReader("{\n \"address\": \"0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5\",\n \"signature\": \"0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0\",\n \"nonce\": \"abc123def456\",\n \"sessionPublicKey\": \"3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29\",\n \"clientId\": \"monaco-frontend\",\n \"chainId\": \"1328\",\n \"referralCode\": \"0x1234567890abcdef1234567890abcdef12345678\"\n}")
req, _ := http.NewRequest("POST", url, payload)
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://staging.apimonaco.xyz/api/v1/auth/verify")
.header("Content-Type", "application/json")
.body("{\n \"address\": \"0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5\",\n \"signature\": \"0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0\",\n \"nonce\": \"abc123def456\",\n \"sessionPublicKey\": \"3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29\",\n \"clientId\": \"monaco-frontend\",\n \"chainId\": \"1328\",\n \"referralCode\": \"0x1234567890abcdef1234567890abcdef12345678\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://staging.apimonaco.xyz/api/v1/auth/verify")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"address\": \"0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5\",\n \"signature\": \"0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0\",\n \"nonce\": \"abc123def456\",\n \"sessionPublicKey\": \"3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29\",\n \"clientId\": \"monaco-frontend\",\n \"chainId\": \"1328\",\n \"referralCode\": \"0x1234567890abcdef1234567890abcdef12345678\"\n}"
response = http.request(request)
puts response.read_body{
"expiresAt": 1699876543,
"user": {
"id": "123e4567-e89b-12d3-a456-426614174000",
"address": "0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5",
"username": "trader123"
},
"isNewUser": true,
"referralApplied": true
}Body
Ethereum wallet address
42^0x[0-9a-fA-F]{40}$"0x742d35Cc6634C0532925a3b8D4060f31E2C3d8B5"
Wallet authorization of the challenge message, hex with an optional 0x prefix. An EOA sends a 65-byte EIP-191 signature; a contract wallet verified under EIP-1271 sends whatever its own contract accepts, which is usually longer and need not be 65 bytes. Capped at 8192 decoded bytes (16386 characters with the prefix) — enough for well over a hundred owner slots — and a longer value is rejected as an invalid signature rather than forwarded to the chain.
1 - 16386"0x1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0"
Challenge nonce
1"abc123def456"
Lowercase hex (64 chars) ed25519 public key generated locally by the SDK. Subsequent authenticated requests are signed with the matching private key. The wallet's signature on the challenge message proves the user authorized this specific public key.
64^[0-9a-f]{64}$"3b6a27bcceb6a42d62a3a8d02a6f0d73653215771de243a63ac048a18b59da29"
Optional application identifier
"monaco-frontend"
Optional chain ID supplied by SDK clients
"1328"
Optional PitPass TraderCode captured at signup (e.g. from a ?ref=CODE link). When a user verifies for the very first time with a valid code, a referral relationship is recorded atomically. Ignored for users who already exist, and silently ignored if the code is unknown — a bad code never blocks sign-in.
"0x1234567890abcdef1234567890abcdef12345678"
Response
OK
Unix timestamp when the session expires
1699876543
Show child attributes
Show child attributes
True when this verify created the user row — the wallet's first sign-in to THIS application. Identity is per (wallet, application), so a wallet already registered on another application is still is_new_user on its first sign-in to a new one. Use it to gate first-time UX (e.g. showing the optional "have a referral code?" input only to new users) and to confirm a fresh sign-up. False for every returning verify on this application.
true
True when a PitPass referral relationship was recorded on this verify: a valid, non-self TraderCode presented on the wallet's first sign-in to THIS application resolved to a known referrer. Scoped like is_new_user (per (wallet, application)), so a wallet already registered on another application can still see this on its first sign-in to a new one. False for a returning user of this application, an absent or unknown code, or a self-referral. Confirms the referral landed for the signup success screen.
true
Was this page helpful?

