Build an Xion OAuth2 Application
This guide provides a comprehensive walkthrough for integrating Xion into your application by OAuth2 authentication.
This guide provides a comprehensive walkthrough for integrating Xion into your application by OAuth2 authentication. By following this guide, you'll enable secure and efficient user authentication, leveraging the OAuth2 protocol to provide a Web2-style experience with blockchain capabilities.
A fully functional demo of OAuth2 integration is available in the Xion OAuth2 App Demo repository.
1. Understanding OAuth2 and Its Benefits
OAuth 2.0 is an industry-standard protocol for authorization, designed to provide specific authorization flows for web applications, desktop applications, mobile phones, and living room devices. The specification and its extensions are being developed within the IETF OAuth Working Group. For more information about OAuth 2.0, visit oauth.net/2/.
Benefits of OAuth2 Integration with Xion:
No Wallet Management: Eliminates the complexity of wallet installation, seed phrase management, and transaction signing for end users
Web2 User Experience: Users can authenticate using familiar Web2 methods (social logins, email, passkeys) without needing to manage blockchain wallets or private keys
Secure Token-Based Authentication: Uses industry-standard OAuth2 tokens for secure API access without exposing user credentials
Gasless Transactions: Leverages Treasury contracts to enable gasless transactions, removing the need for users to hold native tokens
Delegated Authorization: Allows applications to execute transactions on behalf of users with explicit permissions
Scalability: Facilitates integration with multiple services and platforms, promoting interoperability
Xion OAuth2 currently supports the Authorization Code flow with PKCE (Proof Key for Code Exchange) for enhanced security. This flow is recommended for both public and confidential clients.
2. Prerequisites - Treasury Contract Setup
Before integrating OAuth2 with Xion Auth, you must first deploy and configure a Treasury Contract. The Treasury contract manages gasless transactions and permission grants, which are essential for the OAuth2 flow.
For detailed instructions on deploying a Treasury contract, refer to the Treasury Contracts Documentation.
2.1. Critical Treasury Configuration Requirements
When configuring your Treasury contract, there are two critical requirements for OAuth2 integration:
2.1.1. Redirect URI Configuration
The redirect_uri parameter configured in your Treasury contract MUST exactly match the redirect URI used in your OAuth2 application. This redirect URI is where users will be redirected after successful authentication.

Example:
If your OAuth2 app uses
http://localhost:3000/callbackas the redirect URIYour Treasury contract's redirect URI must also be set to
http://localhost:3000/callback
2.1.2. OAuth2 App Toggle
You MUST enable the "IS OAUTH2 APP" toggle in the Treasury contract's Update Params section. This setting indicates that the Treasury contract is being used for OAuth2 authentication.

To enable the OAuth2 toggle:
Navigate to your Treasury contract in the Xion Developer Portal
Click the "Update Params" button
Enable the "IS OAUTH2 APP" toggle switch
Save the changes
OAuth2 Toggle Required: Without enabling the "IS OAUTH2 APP" toggle, users will see redirect URI mismatch warnings when attempting to authenticate, even if the redirect URIs match correctly.
2.1.3. Treasury Permissions and OAuth2 Transactions
The permissions (grant configs) you define in your Treasury contract determine which types of transactions can be executed through the OAuth2 API. Only message types that are explicitly authorized in your Treasury contract's permissions can be used in OAuth2 transaction requests.
For example:
If your Treasury only has permission for
MsgSend(token transfers), you can only send tokens via OAuth2 Protected APIIf your Treasury has permission for
MsgExecuteContract, you can execute smart contract calls via OAuth2 Protected APIYou can configure multiple permissions to allow different transaction types
For more information on configuring Treasury permissions, see the Treasury Contracts Documentation.
3. Creating OAuth2 Clients
Once your Treasury contract is configured, you can create OAuth2 clients in the XION OAuth2 Portal. The portal allows you to manage OAuth2 clients that will authenticate users and access protected APIs.
3.1. Accessing the OAuth2 Portal
Testnet: https://oauth2.testnet.burnt.com/
Mainnet: (Available when mainnet is launched)

To access the portal, click "Connect with XION" and authenticate using your Xion account. After authentication, you'll be redirected to the OAuth2 Clients Dashboard.
3.2. Creating a New OAuth2 Client
Navigate to the Dashboard
After logging in, you'll see the OAuth2 Clients Dashboard showing all your created clients.

OAuth2 Clients Dashboard with Create Client button Click "Create Client"
Click the "Create Client" button located in the top right corner of the dashboard.
Configure Client Settings
The client creation form will appear.

OAuth2 Client creation form You need to complete the following fields:
Treasury Address: Select a Treasury contract from your existing deployments or enter a new Treasury address. The redirect URI from this Treasury will be used as your OAuth2 redirect URI.
Client Name (optional): A descriptive name for your application. If not provided, the name of this client will be untitled.
Client URI (optional): Your application's homepage URL
Default Configuration:
By default, clients are created as Public Clients with PKCE enabled, which is suitable for frontend applications.
Advanced Options - Confidential Client
If you're building a backend application and need a Confidential Client, click to expand the "Advanced Options" section.

Advanced Options showing Confidential Client selection In the Advanced Options:
Token Endpoint Auth Method: Select "Client Secret Post (Confidential Client)" to create a confidential client
You can also configure optional fields like Policy URI, Terms of Service URI, and JWKS URI
Create the Client
Click the "Create Client" button to create your OAuth2 client.
Save Client Credentials
If you created a Confidential Client, a dialog will appear showing your Client ID and Client Secret.

Important: Save Your Client Secret: For Confidential Clients, the Client Secret is displayed only once during client creation. You must copy and save it securely immediately. If you lose the Client Secret, you'll need to create a new client.
3.3. Understanding Client Types
3.3.1. Type 1: Public Client
Use Case: Frontend applications (React, Vue, Angular, etc.) running in the browser
Characteristics:
No
client_secretrequiredMust use PKCE (Proof Key for Code Exchange) for security
Token exchange happens in the browser
Suitable for Single Page Applications (SPAs) and mobile apps
Security: PKCE provides security equivalent to using a client secret, making it safe for public clients.
3.3.2. Type 2: Confidential Client
Use Case: Backend applications (Node.js, Python, etc.) with server-side token exchange
Characteristics:
Requires
client_secretfor authenticationToken exchange happens on the server
More secure for backend applications
Can optionally use PKCE in addition to client_secret
Security: The client_secret is stored securely on the server and never exposed to the client.
4. OAuth2 Integration Examples
This section provides practical examples for integrating OAuth2 into your application. We'll cover the standard OAuth2 flow and provide complete examples for both frontend (Public Client) and backend (Confidential Client) implementations.
4.1 Standard OAuth2 Flow
The OAuth2 Authorization Code flow with PKCE follows these standard steps:
Discovery: Fetch OAuth2 server metadata
Authorization: Redirect user to authorization endpoint
Callback: Handle authorization code
Token Exchange: Exchange authorization code for access token
API Access: Use access token for protected API calls
Step 0: Endpoints
First of all, the OAuth2 API endpoints are same as the OAuth2 portal:
Testnet: https://oauth2.testnet.burnt.com/
Mainnet: (Available when mainnet is launched)
Step 1: Discovery - Get OAuth2 Server Information
Before starting the OAuth2 flow, you need to discover the OAuth2 server's endpoints. This is done by fetching the .well-known/oauth-authorization-server endpoint:
The response includes:
issuer: The OAuth2 server identifierauthorization_endpoint: URL for the authorization endpointtoken_endpoint: URL for the token exchange endpointscopes_supported: Available OAuth2 scopes
Step 2: Authorization - Build Authorization URL
Build the authorization URL with standard OAuth2 parameters:
For Public Clients (with PKCE):
For Confidential Clients:
OAuth2 Authorization Parameters:
client_id: Your OAuth2 client IDredirect_uri: Must match the redirect URI configured in your Treasury contractresponse_type: Always"code"for Authorization Code flowcode_challenge: (Public Clients) Base64url-encoded SHA256 hash of code_verifiercode_challenge_method: (Public Clients) Always"S256"for SHA256scope: XION's OAuth2 Protected API scopes (e.g.,"xion:transactions:submit")state: Random string for CSRF protection
Step 3: Callback - Handle Authorization Code
After the user authorizes your application, they'll be redirected back to your redirect_uri with an authorization code:
Step 4: Token Exchange - Exchange Code for Access Token
Exchange the authorization code for an access token:
For Public Clients (with PKCE):
For Confidential Clients(Use POST body, without PKCE):
OAuth2 Token Request Parameters:
grant_type: Always"authorization_code"for this flowcode: The authorization code received from the callbackredirect_uri: Must match the redirect_uri used in the authorization requestclient_id: Your OAuth2 client IDclient_secret: (Confidential Clients only) Your client secretcode_verifier: (Public Clients with PKCE) The original code verifier. Should be used in the token exchange request for Public Clients with PKCE.
4.2 Frontend Public Client Example
This example demonstrates a complete frontend OAuth2 integration using a Public Client with PKCE.
Example repository: xion-oauth2-app-demo/examples/frontend+public_client
Following are some of major OAuth2 utility functions for the frontend Public Client example.
Complete OAuth2 Utility Functions:
Callback Component Example(Frontend Public Client):
Key Points for Frontend Implementation:
PKCE is Required: Public clients must use PKCE for security. The code verifier is generated client-side and never sent to the server until token exchange.
State Parameter: Always use a state parameter for CSRF protection. Store it in sessionStorage and verify it in the callback.
Token Storage: Store access tokens securely. Use localStorage for persistence, but be aware of XSS risks. Consider using httpOnly cookies for production applications.
Token Expiration: Check token expiration before making API calls and re-authenticate when tokens expire.
4.3 Backend Confidential Client Example
This example demonstrates a complete backend OAuth2 integration using a Confidential Client with server-side token exchange.
Example repository: xion-oauth2-app-demo/examples/backend+confidential_client
Following are some of major OAuth2 utility functions for the backend Confidential Client example.
OAuth2 Configuration (Server-side):
Authorization Endpoint (Initiate OAuth2 Flow):
Callback Endpoint (Token Exchange):
Key Points for Backend Implementation:
Client Secret Security: Never expose the
client_secretto the client. Store it securely in environment variables and only use it server-side.State Verification: Always verify the state parameter to prevent CSRF attacks. Store it in httpOnly cookies.
Token Storage: Store access tokens securely on the server. Use httpOnly cookies or server-side sessions.
Error Handling: Implement proper error handling for all OAuth2 flow steps and provide user-friendly error messages.
5. OAuth2 Protected APIs
Once you have an access token, you can use it to access protected OAuth2 APIs. These APIs allow you to interact with the XION blockchain on behalf of authenticated users.
API Base URL
Testnet:
https://oauth2.testnet.burnt.com/Mainnet: (Available when mainnet is launched)
API Documentation
For complete API documentation with interactive examples, visit the OAuth2 Protected API Documentation.
Authentication
All protected API endpoints require authentication using a Bearer token in the Authorization header:
Available Endpoints
1. Get Current User Information
Endpoint: GET /api/v1/me
Returns information about the currently authenticated user's MetaAccount.
Request:
Response:
2. Submit Transaction
Endpoint: POST /api/v1/transaction
Submits a blockchain transaction on behalf of the authenticated user. The transaction messages must be constructed using protobuf-based types from @burnt-labs/xion-types.
Request:
Response:
Transaction Messages: The messages array contains protobuf-encoded transaction messages. Each message must have a typeUrl and value field. See section 6: Building Transactions for details on constructing messages.
3. Query Transaction Status
Endpoint: GET /api/v1/transaction/{txHash}/status
Queries the status of a previously submitted transaction.
Request:
Response:
4. Simulate Transaction
Endpoint: POST /api/v1/transaction/simulate
Simulates a transaction execution without actually submitting it to the blockchain. Useful for estimating gas costs and validating transaction logic.
Request:
Response:
Complete API Client Example
Here's a complete example of an API client with automatic token injection:
6. Building Transactions
To submit transactions via the OAuth2 API, you need to construct transaction messages using protobuf-based types from the @burnt-labs/xion-types package. These messages are then encoded and sent to the transaction API endpoint.
Installing Xion Types
Understanding Transaction Messages
Transaction messages in Xion use protobuf encoding. Each message has:
typeUrl: The protobuf message type URL (e.g.,"/cosmos.bank.v1beta1.MsgSend")value: The protobuf-encoded message value
The OAuth2 Transaction API accepts an array of these messages in the messages field.
Critical Relationship: Treasury Permissions
Important: Only message types that are explicitly authorized in your Treasury contract's permissions can be used in OAuth2 transaction requests.
For example:
If your Treasury only has permission for
MsgSend, you can only send tokens via OAuth2If your Treasury has permission for
MsgExecuteContract, you can execute smart contract callsYou can configure multiple permissions to allow different transaction types
Before constructing transaction messages, ensure the corresponding permissions are configured in your Treasury contract. See the Treasury Contracts Documentation for details on configuring permissions.
Message Construction Examples
Sending Tokens (MsgSend)
Reference: xion-types MsgSend Guide
Executing Smart Contracts (MsgExecuteContract)
Reference: xion-types MsgExecuteContract Guide
Instantiating Contracts (MsgInstantiateContract)
Reference: xion-types MsgInstantiateContract Guide
Complete Transaction Example
Here's a complete example combining message construction and API usage:
More Examples
For more transaction message construction examples, see:
7. Querying Blockchain Data
While the OAuth2 API provides endpoints for submitting transactions and querying transaction status, for general blockchain data queries (account balances, contract state, block information, etc.), you should use @cosmjs/stargate directly.
Using CosmJS for Queries
CosmJS is the standard library for interacting with Cosmos SDK-based blockchains, including Xion. For detailed instructions on using CosmJS with Xion, refer to the Interact with XION via your Backend Service guide, specifically the "Querying the Blockchain" section.
Installation
Example: Querying Account Balance
Example: Querying Contract State
Why Use CosmJS for Queries?
Comprehensive Query Support: CosmJS provides access to all Cosmos SDK query endpoints
No Authentication Required: Queries don't require OAuth2 tokens
Standard Library: Well-documented and widely used in the Cosmos ecosystem
Direct RPC Access: Connects directly to Xion RPC nodes
RPC Endpoints
For a list of available RPC endpoints for each network, see the Public Endpoints and Resources documentation.
Additional Resources
OAuth2 API Endpoint: https://oauth2.testnet.burnt.com/
OAuth2 Portal: https://oauth2.testnet.burnt.com/ (for managing OAuth2 clients)
OAuth2 Protected API Documentation: https://oauth2.testnet.burnt.com/protected-api-docs
OAuth2 App Examples: https://github.com/burnt-labs/xion-oauth2-app-demo
Xion Types Repository: https://github.com/burnt-labs/xion-types
Xion Types TypeScript Guide: https://github.com/burnt-labs/xion-types/blob/main/examples/typescript/GUIDE.md
Treasury Contracts Documentation: Enabling Gasless Transactions with Treasury Contracts
Xion Developer Portal: https://dev.testnet.burnt.com/ (for managing Treasury contracts)
If you have any questions or encounter issues, feel free to ask in our Telegram Developer Group or on Discord in our Dev Chat channel.
Last updated
Was this helpful?