Phoenix Wallet

Authentication

Secure your Phoenix Wallet API requests with OAuth 2.0

Phoenix Wallet uses OAuth 2.0 with the Client Credentials flow for API authentication. This guide explains how to obtain and use access tokens.

Overview

All API requests must include a valid access token in the Authorization header:

Authorization: Bearer <access_token>

Obtaining an Access Token

Use your client credentials to request an access token from the token endpoint:

curl -X POST https://auth.phoenixwallet.io/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "scope=wallets:read wallets:write"
const response = await fetch('https://auth.phoenixwallet.io/oauth/token', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded',
  },
  body: new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: process.env.CLIENT_ID,
    client_secret: process.env.CLIENT_SECRET,
    scope: 'wallets:read wallets:write',
  }),
});

const { access_token, expires_in } = await response.json();
console.log('Token expires in:', expires_in, 'seconds');
import os
import requests

response = requests.post(
    'https://auth.phoenixwallet.io/oauth/token',
    data={
        'grant_type': 'client_credentials',
        'client_id': os.environ['CLIENT_ID'],
        'client_secret': os.environ['CLIENT_SECRET'],
        'scope': 'wallets:read wallets:write',
    },
)

token_data = response.json()
access_token = token_data['access_token']
expires_in = token_data['expires_in']
print(f'Token expires in: {expires_in} seconds')

Response:

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "wallets:read wallets:write"
}

Token Lifecycle

Access tokens expire after the duration specified in expires_in (typically 1 hour). Your application should refresh tokens before they expire.

Token Caching

For optimal performance, cache your access token and reuse it until it expires:

class TokenManager {
  constructor(clientId, clientSecret) {
    this.clientId = clientId;
    this.clientSecret = clientSecret;
    this.token = null;
    this.expiresAt = null;
  }

  async getToken() {
    // Return cached token if still valid (with 5-minute buffer)
    if (this.token && this.expiresAt > Date.now() + 300000) {
      return this.token;
    }

    // Fetch new token
    const response = await fetch('https://auth.phoenixwallet.io/oauth/token', {
      method: 'POST',
      headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
      body: new URLSearchParams({
        grant_type: 'client_credentials',
        client_id: this.clientId,
        client_secret: this.clientSecret,
        scope: 'wallets:read wallets:write',
      }),
    });

    const data = await response.json();
    this.token = data.access_token;
    this.expiresAt = Date.now() + data.expires_in * 1000;

    return this.token;
  }
}

Available Scopes

Request only the scopes your application needs:

ScopeDescription
wallets:readRead wallet data and balances
wallets:writeCreate wallets and perform operations
policies:readRead policy configurations
policies:writeCreate and modify policies
ledger:readRead ledger entries and history
events:subscribeSubscribe to webhook events

Security Best Practices

Never expose your client secret in client-side code, version control, or logs.

Credential Management

  • Store credentials in environment variables or a secure secrets manager
  • Use different credentials for development and production environments
  • Rotate client secrets periodically

Token Handling

  • Never log access tokens
  • Use HTTPS for all API requests
  • Implement token refresh logic to avoid service interruptions
  • Set appropriate token expiry for your use case

Network Security

  • Allowlist Phoenix Wallet API endpoints in your firewall
  • Use mutual TLS (mTLS) for enhanced security if available
  • Monitor for unauthorized access attempts

Error Handling

Common authentication errors:

ErrorDescriptionSolution
invalid_clientInvalid client credentialsVerify your client ID and secret
invalid_scopeRequested scope not allowedCheck your allowed scopes
invalid_grantGrant type not supportedUse client_credentials
unauthorizedToken expired or invalidRefresh your access token
{
  "error": "invalid_client",
  "error_description": "Client authentication failed"
}

Next Steps