Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.privy.io/llms.txt

Use this file to discover all available pages before exploring further.

Bitso is the largest crypto exchange in Mexico. The Juno platform lets businesses issue and redeem MXNB. MXNB is a stablecoin pegged 1:1 to the Mexican Peso, deployed on Arbitrum. Juno automatically triggers an issuance when a user deposits MXN via SPEI to a Juno-issued CLABE. This recipe shows how to combine Privy embedded wallets with the Juno API to build an MXNB onramp flow. It is most useful for centralized exchanges or fintech apps serving Mexico-based users. Using Privy and Juno, your app can:
  • Provision an embedded wallet for each user
  • Guide users through Bitso’s KYB process
  • Issue a CLABE to receive SPEI deposits
  • Automatically mint MXNB when Juno receives MXN
  • Withdraw MXNB to the user’s Privy wallet on Arbitrum

Prerequisites

SPEI and CLABE

SPEI (Sistema de Pagos Electrónicos Interbancarios) is Mexico’s interbank electronic payment network, operated by Banco de México. It enables near-instant MXN transfers between any Mexican bank account. CLABE (Clave Bancaria Estandarizada) is the standardized 18-digit account number used for SPEI transfers. Juno issues each user a dedicated AUTO_PAYMENT CLABE. When MXN arrives at that CLABE, Juno automatically mints the equivalent MXNB to the user’s Juno balance.
All API examples use the Juno staging environment at stage.buildwithjuno.com. Switch to buildwithjuno.com for production.

1. Complete KYB with Bitso

Before MXNB can be issued to a user, Bitso requires KYB (Know Your Business) verification. Your app should redirect users to the Bitso onboarding flow and track their verification status via the Juno API.
Refer to Bitso’s KYB documentation for verification requirements and endpoints. KYB approval is required before any issuance or redemption.
After KYB is approved, users must log in to the Juno web platform and accept the Terms & Conditions via the UI before your app can use the Juno API or UI on their behalf.

2. Create a CLABE for the user

Juno issues AUTO_PAYMENT CLABEs — when MXN arrives via SPEI to a user’s CLABE, Juno automatically mints MXNB to that user’s Juno balance.
curl --request POST \
  --url https://stage.buildwithjuno.com/mint_platform/v1/clabes \
  --header 'Authorization: Bitso:<api-key>:<nonce>:<signature>' \
  --header 'BitsoAuth: Bearer <your-bearer-token>'
{
  "success": true,
  "payload": {
    "clabe": "710969000000329002",
    "type": "AUTO_PAYMENT"
  }
}
Save the clabe value. Each CLABE is assigned to one user and must not be reused across different users.

3. Display the CLABE to the user

Your app must show the user the CLABE so they can initiate a SPEI transfer from their bank. Once Bitso receives the MXN deposit (minimum 100 MXN), MXNB is automatically minted to the user’s Juno balance.
To retrieve an existing CLABE for a user, call GET https://stage.buildwithjuno.com/spei/v1/clabes?clabe_type=AUTO_PAYMENT.

4. Create a Privy wallet for the user

Your app can create an embedded Ethereum wallet for the user via the Privy API. MXNB is deployed on Arbitrum, an EVM-compatible chain, so a standard Ethereum wallet can hold it.
curl --request POST \
  --url https://api.privy.io/v1/wallets \
  -u "<your-privy-app-id>:<your-privy-app-secret>" \
  --header 'privy-app-id: <your-privy-app-id>' \
  --header 'Content-Type: application/json' \
  --data '{
    "owner": {
      "user_id": "<privy-user-id>"
    },
    "chain_type": "ethereum"
  }'
Save the returned wallet address. Juno uses this address as the MXNB withdrawal destination.

5. Register the Privy wallet as a blockchain account in Juno

Before withdrawing MXNB to the Privy wallet, your app must register the wallet address with Juno as a blockchain account.
curl --request POST \
  --url https://stage.buildwithjuno.com/mint_platform/v1/accounts/blockchain \
  --header 'Authorization: Bitso:<api-key>:<nonce>:<signature>' \
  --header 'BitsoAuth: Bearer <your-bearer-token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "tag": "<user-identifier>",
    "network": "arbitrum",
    "address": "<privy-wallet-address>"
  }'
{
  "success": true,
  "payload": {}
}

6. Withdraw MXNB to the Privy wallet

Once MXNB is in the user’s Juno balance, your app can withdraw it to the user’s Privy wallet on Arbitrum.
curl --request POST \
  --url https://stage.buildwithjuno.com/mint_platform/v1/withdrawals \
  --header 'Authorization: Bitso:<api-key>:<nonce>:<signature>' \
  --header 'BitsoAuth: Bearer <your-bearer-token>' \
  --header 'Content-Type: application/json' \
  --data '{
    "blockchain": "ARBITRUM",
    "asset": "MXNB",
    "amount": "1000",
    "address": "<privy-wallet-address>",
    "compliance": {}
  }'
The compliance field is required. Pass an empty object {} for amounts under the travel rule threshold. Refer to Bitso’s travel rule documentation for larger amounts.
Pass an X-Idempotency-Key header (UUID v1) to prevent duplicate withdrawals if the request is retried.

Juno docs

Learn more about MXNB issuances, redemptions, and withdrawals

Create a Privy wallet

API reference for provisioning embedded wallets