Skip to main content
Check out working demo: Live Demo
Repo: crossmint-machines-cards-example
Deploy with Vercel
This guide is for partners already using Crossmint embedded wallets. Scope:
  • Partner API integration (/partner/v1) only.
  • Crossmint for auth + embedded wallet UX.
  • Your backend holds partner credentials and calls Machines.
  • Simple EVM-first path for create card, deposits, and withdrawals.

Architecture

  • Frontend uses Crossmint for sign-in and wallet creation.
  • Frontend calls your backend only.
  • Your backend calls Machines Partner API.
  • Your backend executes withdrawal transactions with the embedded wallet signer path you control.

Prerequisites

  • Crossmint project with:
    • client key for frontend
    • server key for backend (if you run server-side wallet operations)
    • embedded EVM wallet creation enabled
  • Machines partner API key
  • A backend service that can securely store:
    • X-Partner-Key
    • Crossmint server credentials (if used)

Crossmint Embedded Wallet Checklist

Before sending traffic:
  1. Wallet creation
    • New users get an embedded EVM wallet at login.
    • You can read the wallet address after auth.
  2. Stable mapping
    • You persist partner userId + Crossmint user id + wallet address.
    • You always send the same mapped user identity to Machines.
  3. Session bootstrap server-side
    • POST /partner/v1/users/resolve and POST /partner/v1/sessions happen on your backend.
    • X-Partner-Key is never exposed to browser code.
  4. Browser request path
    • Browser calls your backend routes, not Machines directly.
    • This avoids CORS failures and secret leakage.
  5. Withdrawal execution
    • Use one signer path consistently.
    • Persist tx ids/hashes and reconcile status.
Per user:
  • machinesUserId
  • crossmintUserId
  • embeddedWalletAddress
  • linkedAt / lastUsedAt
Per session:
  • sessionId
  • scopes
  • expiresAt
Per withdrawal execution:
  • idempotency key
  • execution path (controller_v1 or coordinator_v2)
  • submitted tx id/hash
  • confirmed tx hash

End-to-End Partner Flow

1) Set up Crossmint providers (frontend)

2) Resolve user + create partner session (backend)

3) Call Machines through your backend proxy

Use the partner session token from step 2. At minimum, support these routes:
  • GET /partner/v1/kyc/values
  • POST /partner/v1/kyc/applications
  • GET /partner/v1/kyc/status
  • GET /partner/v1/agreements
  • POST /partner/v1/agreements
  • GET /partner/v1/cards
  • POST /partner/v1/cards
  • GET /partner/v1/deposits/assets
  • POST /partner/v1/deposits/range
  • POST /partner/v1/deposits/estimate
  • POST /partner/v1/deposits
  • GET /partner/v1/transactions

4) Create withdrawals

Call sequence:
  1. GET /partner/v1/withdrawals/assets
  2. POST /partner/v1/withdrawals/range
  3. POST /partner/v1/withdrawals/estimate
  4. POST /partner/v1/withdrawals
Create request example:

5) Execute withdrawal transaction

Use response fields:
  • execution.callTarget
  • execution.callPath
  • parameters
Rules:
  • send tx to execution.callTarget
  • sender must match adminAddress used in create request
  • if status is pending, retry create with the same idempotency key

Execution Model and Contract Call Paths

Machines withdrawal create response includes:
  • execution.callTarget
  • execution.callPath (controller_v1 or coordinator_v2)
  • parameters (7-arg withdrawal payload)
Contract paths:
  • controller_v1: call 7-arg withdrawAsset(...)
  • coordinator_v2: build admin typed-data signature, then call 10-arg withdrawAsset(...)

Common Integration Pitfalls

  • Calling Machines directly from browser code.
    • Use your backend proxy for all partner calls.
  • Creating sessions without wallet context.
    • Always pass wallet data when resolving users/sessions.
  • Not reusing idempotency keys on pending withdrawals.
    • Retry with the same Idempotency-Key.
  • Executing on the wrong target contract.
    • Always use execution.callTarget from response.

Further Reading