Sign in with OpenDunes from Python — get an API key on your user's wallet with the PKCE flow.
With Sign in with OpenDunes, your app gets an API key on its user's wallet, with the user's approval. The flow is PKCE; the whole of it is on OAuth PKCE. The exchange needs no key of its own.
import base64
import hashlib
import secrets
from urllib.parse import urlencode
code_verifier = secrets.token_urlsafe(64) # keep it until the exchange
code_challenge = (
base64.urlsafe_b64encode(hashlib.sha256(code_verifier.encode()).digest())
.rstrip(b"=")
.decode()
)
auth_url = "https://opendunes.com/auth?" + urlencode({
"callback_url": "http://localhost:8765/callback",
"code_challenge": code_challenge,
"code_challenge_method": "S256",
"key_label": "Souk Bot CLI",
})
# open auth_url in the user's browsercallback_url is HTTPS, or HTTP on localhost or 127.0.0.1 — for a CLI tool or a local app. The user signs in, may set a spending cap on the key, and chooses Authorize or Deny. On Authorize they come back to your callback with ?code=…; on Deny, with error=access_denied.
import httpx
resp = httpx.post(
"https://opendunes.com/v1/auth/keys",
json={
"code": code, # from the callback's query string
"code_verifier": code_verifier,
"code_challenge_method": "S256",
},
)
resp.raise_for_status()
user_key = resp.json()["key"] # also: user_idA code lives ten minutes and trades once. An unknown, expired or used code, or a verifier that does not match, is a 400.
from openai import OpenAI
client = OpenAI(base_url="https://opendunes.com/v1", api_key=user_key)Every request on this key spends the user's wallet. The user sees the key among their own and can cap, pause or delete it.