TypeScript / JavaScript SDK
Official typed SDK for Wirex BaaS — Account Abstraction (ZeroDev Kernel V3.1), token transfers, FX swaps, yield and smart deposit addresses in a single npm package.
Before You Start
| Requirement | Notes |
|---|---|
| Node.js ≥ 18 | Required runtime |
viem ^2.49.3 | Peer dependency — install separately |
CLIENT_ID / CLIENT_SECRET | OAuth2 credentials from Wirex partner onboarding |
COMPANY_ID | Your company identifier in hex format |
@wirexapp/wpay-baas-sdk is the SDK for integration with the Wirex BaaS platform. It supports Account Abstraction (ZeroDev Kernel V3.1), token transfers, FX swaps, yield, and smart deposit addresses, and wraps the BaaS REST API in typed services.
The SDK is published on npm: @wirexapp/wpay-baas-sdk.
This is not the card-data SDK. Card collection, card reveal and 3DS in a browser are covered by the PCI Compliant SDK, a separate package family. The two are installed and versioned independently and can be used together.
Installation
npm install @wirexapp/wpay-baas-sdk viemPeer dependency: viem ^2.49.3
SDK Initialization
import { createSDK, type SDKEnvironment } from '@wirexapp/wpay-baas-sdk';
const sdk = await createSDK({
env: 'dev', // 'dev' | 'prod'
companyId: '0x...', // Company ID in hex format
chainId: 8453, // optional, defaults to the remote config's defaultChain
getMainWalletClient: () => mainWalletClient, // Embedded wallet with EthereumProvider
enableLogging: true, // optional, default false
logger: customLogger, // optional, custom logger
});Configuration Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
env | 'dev' | 'prod' | Yes | Environment |
companyId | string | Yes | Company ID in hex format |
companyName | string | No | Sent as X-Company-Name on the remote-config fetch, selects that company's chain / contracts / default company |
configUrl | string | No | Explicit remote-config URL, overrides env |
chainId | number | No | Chain to run on: 8453 Base, 84532 Base Sepolia, 5042 Arc, 5042002 Arc Testnet. Defaults to remote config defaultChain |
getMainWalletClient | () => MainWalletClient | Yes | Function that returns embedded wallet with EthereumProvider |
enableLogging | boolean | No | Enable logging (default false) |
logger | Logger | No | Custom logger (requires enableLogging: true) |
rhinoApiKey | string | No | Rhino.fi API key, required only for sdk.crypto.smartDepositAddress |
MainWalletClient Contract
getMainWalletClient must return an object implementing this interface:
interface MainWalletClient {
address: string;
getEthereumProvider(): Promise<{
request(args: { method: string; params?: unknown[] }): Promise<unknown>;
}>;
}The EIP-1193 provider must handle at minimum:
| RPC Method | Used for |
|---|---|
eth_accounts | Resolve the signer address |
personal_sign | Sign messages (SIWE, auth challenges) |
eth_signTypedData_v4 | Sign typed data (UserOperations, EIP-712) |
Adapter example — raw private key (tests / embedded wallets)
import { createWalletClient, http } from 'viem';
import { privateKeyToAccount } from 'viem/accounts';
import { baseSepolia } from 'viem/chains';
import type { MainWalletClient } from '@wirexapp/wpay-baas-sdk';
export function createWalletClientFromKey(
privateKey: `0x${string}`,
rpcUrl: string,
): MainWalletClient {
const account = privateKeyToAccount(privateKey);
const client = createWalletClient({ account, chain: baseSepolia, transport: http(rpcUrl) });
return {
address: account.address,
getEthereumProvider: async () => ({
request: async ({ method, params = [] }) => {
if (method === 'eth_accounts') return [account.address];
if (method === 'personal_sign') {
const [data] = params as [`0x${string}`, string];
return client.signMessage({ account, message: { raw: data } });
}
if (method === 'eth_signTypedData_v4') {
const [, json] = params as [string, string];
const { domain, types, primaryType, message } = JSON.parse(json);
const { EIP712Domain: _, ...filteredTypes } = types;
return client.signTypedData({ account, domain, types: filteredTypes, primaryType, message });
}
return (client.transport as any).request({ method, params });
},
}),
};
}Adapter example — Privy embedded wallet
import type { MainWalletClient } from '@wirexapp/wpay-baas-sdk';
// Inside a React component / hook where usePrivy is available:
function getPrivyWalletClient(wallet: ConnectedWallet): MainWalletClient {
return {
address: wallet.address,
getEthereumProvider: () => wallet.getEthereumProvider(),
};
}Authentication
The SDK supports three authentication paths depending on your integration type.
Option A — Company OAuth2 (client_credentials)
Used when your backend calls the Wirex API on behalf of users. This is the standard B2B partner flow.
// Step 1 — Exchange company credentials
const tokenRes = await sdk.api.baas.token.getToken({
grant_type: 'client_credentials',
client_id: process.env.CLIENT_ID,
client_secret: process.env.CLIENT_SECRET,
audience: 'https://api-business.wirexpaychain.tech', // same for dev and prod
});
// Step 2 — Prime SDK auth state with the company token + user EOA wallet
sdk.auth.setAuthState(
{ access_token: tokenRes.access_token, expires_at: tokenRes.expires_at },
userEoaWallet,
);
// Step 3 — (After user registration) Login to get a per-user PSI token.
// All sdk.api.baas.* calls automatically use the PSI token after this.
await sdk.auth.login({
authorizationToken: tokenRes.access_token,
userWallet: userEoaWallet,
});
console.log('Authenticated:', sdk.auth.isAuthenticated()); // true
console.log('Token:', sdk.auth.getAccessToken());Option B — Privy
Used in consumer apps where users authenticate through Privy.
import { getAccessToken, useIdentityToken } from '@privy-io/react-auth';
const accessToken = await getAccessToken();
const { identityToken } = useIdentityToken();
// Login (existing user)
const authResponse = await sdk.auth.login({
privy: { accessToken, identityToken },
});
// Or register (new user)
const userResponse = await sdk.auth.registerUser({
privy: { accessToken, identityToken },
country: 'FR',
});Option C — JWT
Used when you issue your own tokens or use an auth provider other than Privy.
// Login
const authResponse = await sdk.auth.login({
authorizationToken: 'your-jwt-token',
userWallet: userEoaWallet,
});
// Register
const userResponse = await sdk.auth.registerUser({
authorizationToken: 'your-jwt-token',
userWallet: userEoaWallet,
country: 'FR',
initialData, // see Step 6 below
});Token Management
After login the SDK holds the token internally. Use these methods to inspect or manage auth state:
| Method | Returns | Description |
|---|---|---|
sdk.auth.isAuthenticated() | boolean | Whether a valid token is held |
sdk.auth.getAccessToken() | string | null | Current token, or null if expired |
sdk.auth.ensureAuthenticated() | void | Throws AuthenticationError if not authenticated |
sdk.auth.getAuthHeaders() | object | { Authorization, X-User-Wallet } headers |
sdk.auth.getUserWallet() | string | Current user wallet address |
sdk.auth.setUserWallet(wallet) | void | Update user wallet address |
sdk.auth.setAuthState(response, wallet?) | void | Restore auth state from a stored response |
sdk.auth.clearAuth() | void | Clear all auth state (logout) |
User Registration Flow
1: Get Smart Wallet Address
const address = await sdk.crypto.wallet.getSmartWalletAddress();
console.log('Smart Wallet:', address);2: Check Policy & Executor Status
const isPolicyInstalled = await sdk.crypto.accountAbstraction.isPolicyInstalled();
const isExecutorInstalled = await sdk.crypto.accountAbstraction.isExecutorInstalled();
console.log('Policy installed:', isPolicyInstalled);
console.log('Executor installed:', isExecutorInstalled);3: Install Policy & Executor (if not installed)
if (!isPolicyInstalled || !isExecutorInstalled) {
const result = await sdk.crypto.accountAbstraction.signInPolicyAndExecutor();
console.log('Transaction hash:', result?.receipt?.transactionHash);
}Single-signature alternative (steps 3 + 5 combined). For a wallet with neither the executor nor the policy installed, sdk.crypto.onboarding.allInOneStepOnboarding() batches the executor install, the root-validator switch and the Accounts registration into one UserOperation, so the user signs once instead of three times:
if (!isPolicyInstalled && !isExecutorInstalled) {
const receipt = await sdk.crypto.onboarding.allInOneStepOnboarding();
console.log('Transaction hash:', receipt.receipt.transactionHash);
} else {
// fall back to the per-step calls below
}4: If you use Privy as auth — Link Smart Wallet to Privy (SIWE)
import { useLinkWithSiwe } from '@privy-io/react-auth';
const { generateSiweMessage, linkWithSiwe } = useLinkWithSiwe();
const smartWalletClient = await sdk.crypto.wallet.getSmartWalletClient();
const message = await generateSiweMessage({
address: smartWalletClient.account.address,
chainId: 'eip155:' + smartWalletClient.chain?.id,
});
const signature = await smartWalletClient.signMessage({
account: smartWalletClient.account,
message: message,
});
await linkWithSiwe({
message: message,
chainId: 'eip155:' + smartWalletClient.chain?.id,
signature,
walletClientType: 'smart_wallet',
connectorType: 'kernel',
});5: Register in Accounts Smart Contract
const receipt = await sdk.crypto.accountContract.registerInAccounts();
const isRegistered = await sdk.crypto.accountContract.isWalletInAccounts();
console.log('Registered in contract:', isRegistered);6: Register in API
Option A: Using Privy auth
import { getAccessToken, useIdentityToken } from '@privy-io/react-auth';
const accessToken = await getAccessToken();
const { identityToken } = useIdentityToken();
const userResponse = await sdk.auth.registerUser({
privy: {
accessToken: accessToken,
identityToken: identityToken,
},
country: 'FR',
});Option B: Using JWT token
// The API sees the wallet a few seconds after step 5, once its indexer has picked up the
// Accounts registration. Until then this returns 400 ErrorNotFound — wait and call again.
const userResponse = await sdk.auth.registerUser({
authorizationToken: 'your-jwt-token',
userWallet: userEoaAddress, // the user's EOA, sent as wallet_address
country: 'FR', // required by the type, not sent on this path
initialData: { // required for companies on the Full verification model
profile: {
first_name: 'Alex',
last_name: 'Grey',
date_of_birth: '1990-01-15',
nationality: 'FR',
phone_number: '+33612345678',
email: '[email protected]',
},
residence_address: {
line1: '10 Rue de Rivoli',
city: 'Paris',
post_code: '75001',
country: 'FR',
},
},
});Option A posts to POST /api/v1/user/retail; Option B posts to POST /api/v2/user.
7: Login to API
Option A: Using Privy auth
const authResponse = await sdk.auth.login({
privy: {
accessToken: accessToken,
identityToken: identityToken,
},
});
console.log('Access token:', authResponse.access_token);Option B: Using JWT token
const authResponse = await sdk.auth.login({
authorizationToken: 'your-jwt-token',
userWallet: userEoaAddress, // sent as X-User-Wallet on every later call
});SDK Modules
sdk.auth — Authentication Service
sdk.auth — Authentication Service| Method | Description |
|---|---|
login(params) | Login retail user (Privy or JWT) |
loginCompany(params) | Login company/corporation |
registerUser(params) | Register retail user |
registerCompany(params) | Register company/corporation |
getAccessToken() | Get current access token (returns null if expired) |
isAuthenticated() | Check if user is authenticated |
getUserWallet() | Get current user wallet address |
setUserWallet(wallet) | Set user wallet address |
setAuthState(response, userWallet?) | Manually set auth state from an auth response |
ensureAuthenticated() | Throws AuthenticationError if not authenticated |
clearAuth() | Clear all authentication state |
getAuthHeaders() | Get Authorization and X-User-Wallet headers |
Authentication Parameters:
All auth methods accept either Privy tokens or a JWT authorization token:
// Option 1: Privy authentication
{
privy: {
accessToken: string; // Privy access token
identityToken: string; // Privy identity token
}
}
// Option 2: JWT authentication
{
authorizationToken: string; // Your JWT token
}Company Registration Parameters:
interface RegisterCompanyParams {
privy?: PrivyAuth;
authorizationToken?: string;
companyAddress: string;
companyName: string;
registrationCountry: string;
registrationNumber: string;
}sdk.crypto.wallet — Wallet Service
sdk.crypto.wallet — Wallet Service| Method | Description |
|---|---|
getSmartWalletAddress() | Get Smart Wallet address |
getSmartWalletClient() | Get Kernel client with Policy |
getSmartWalletClientWithoutPolicy() | Get Kernel client without Policy |
getSmartAccountSigner() | Get signer for Smart Account |
getMainWalletClient() | Get main wallet client |
sendUserOperationsAndWaitReceipt(callData, smartWalletClient?, config?) | Send user operations and wait for receipt |
sendUserOperationsWithNonceAndWaitReceipt(callData, nonce, config?) | Send user operations with specific nonce |
invalidateLocalCache() | Clear cached wallet clients |
config on both send methods is { waitOnChainBlocks?: number; applyUnwrapGasFloor?: boolean }. applyUnwrapGasFloor estimates the UserOperation first and raises callGasLimit to a gas floor when the estimate comes back lower. The transfer service sets it for the batches that unwrap a synthetic token before transferring (makeErc20TransferFull execution step, makeErc20TransferFinal, makeTransferWithoutDelayPolicy); plain transfers, policy installs and batch transfers keep the bundler estimate.
sdk.crypto.accountAbstraction — Account Abstraction Service
sdk.crypto.accountAbstraction — Account Abstraction Service| Method | Description |
|---|---|
isPolicyInstalled() | Check if Execution Delay Policy is installed |
isExecutorInstalled() | Check if Funds Management Executor is installed |
signInPolicyAndExecutor() | Install Policy and Executor together |
signInPolicy() | Install Policy only |
signInExecutor() | Install Executor only |
getExecutorInstallCall() | Executor install as a batchable call (used by onboarding) |
getPolicyInstallCall() | Policy install as a batchable call (used by onboarding) |
sdk.crypto.accountContract — Account Contract Service
sdk.crypto.accountContract — Account Contract Service| Method | Description |
|---|---|
isWalletInAccounts() | Check if wallet is registered in Accounts contract |
registerInAccounts() | Register wallet in Accounts contract (retail) |
isWalletInCorporateAccounts() | Check if wallet is registered in Corporate Accounts contract |
registerInCorporateAccounts() | Register wallet in Corporate Accounts contract (B2B) |
getAccountRegistrationCall() | Accounts registration as a batchable call (used by onboarding) |
sdk.crypto.onboarding — Onboarding Service
sdk.crypto.onboarding — Onboarding Service| Method | Description |
|---|---|
allInOneStepOnboarding() | Executor install + policy switch + Accounts registration in a single UserOperation, signed by the pre-policy client. Use only when neither the executor nor the policy is installed; otherwise run the per-step methods. |
sdk.crypto.transfer — Transfer Service
sdk.crypto.transfer — Transfer Service| Method | Description |
|---|---|
makeErc20TransferFull(params) | Full transfer in one call: request(...) → wait out the ExecutionDelayPolicy delay on-chain → submit the final execution under its custom nonce. No backend/withdrawal-request polling. |
makeFullErc20Transfer(params) | Full transfer driven by the backend: firstPart → poll withdrawal requests and wait for valid_after → final. Requires the Withdrawal API. |
makeErc20TransferFirstPart(params) | First part only: submit the ExecutionDelayPolicy request(...) (creates the withdrawal request) |
makeErc20TransferFinal(callData) | Second part only: complete the transfer with the request's calldata under its custom nonce |
makeErc20TransferSynthetic(params) | Transfer synthetic tokens directly (no unwrap, no delay policy) |
makeTransferWithoutDelayPolicy(params) | Unwrap a synthetic and transfer its base token in a single op, bypassing the ExecutionDelayPolicy. Used for the on-chain payment leg of an FX swap. |
batchTransfer(params) | Execute multiple transfers in a batch |
Transfer Parameters:
interface Erc20TransferParams {
tokenAddress: `0x${string}`;
recipientAddress: `0x${string}`;
amount: number;
}
interface BatchTransferParams {
tokenAddress: `0x${string}`;
responses: BatchTransferResponse[];
}
interface BatchTransferResponse {
transaction_id: string; // GUID
operation_id: string; // GUID
crypto_transfers: {
address: string;
precise_amount: string; // amount in the token's smallest unit
}[];
}
// Used by makeTransferWithoutDelayPolicy (FX swap payment leg)
interface SwapTransferParams {
tokenAddress: `0x${string}`; // wrapped synthetic token to unwrap and send (e.g. WUSD)
recipientAddress: `0x${string}`; // FX deposit address returned by swap.estimate
amount: string; // amount of the source token (decimal string)
}sdk.crypto.yield — Yield Service
sdk.crypto.yield — Yield Service| Method | Description |
|---|---|
fetchYieldData() | Get yield data (APY, pending, weekly, lifetime) |
getYieldDataForGraphic() | Get data for graph visualization |
getWeeklyYield() | Get weekly yield |
withdraw() | Withdraw accumulated yield |
switchYieldToken(token) | Switch yield token (TokenInfo, e.g. sdk.crypto.getToken('WEUR')) |
Yield Data Structure:
interface IYieldData {
apy: number; // annual rate in percent
currentPendingYield: string; // accumulated yield pending withdrawal
weeklyYield: string; // weekly yield
lifeTimeYield: string; // claimed + pending
}sdk.crypto.smartDepositAddress — Smart Deposit Addresses
sdk.crypto.smartDepositAddress — Smart Deposit Addresses| Method | Description |
|---|---|
initializeSmartDepositAddresses(forceRefresh?) | Create/get all deposit addresses |
getAddresses() | Get cached addresses |
getDestinationChain() | Rhino.fi chain code funds are bridged to |
clearAddresses() | Clear address cache |
Destination chain follows the SDK chainId: 8453 / 84532 → BASE, 5042 / 5042002 → ARC. Rhino.fi has no testnet chains, so testnet ids resolve to the mainnet code.
The destination chain is itself requested as a deposit chain, so the EVM group also holds a same-chain address — ARC → ARC when the SDK runs on Arc, BASE → BASE on Base.
Deposit chains the destination rejects are skipped with a warning and the remaining chains in the group are still created: no bridgeable route (Rhino.fi DepositAddressNoBridgableTokens, e.g. USDT-only Kaia and TRON towards Arc) and chains Rhino.fi has not enabled for deposit addresses (DepositAddressChainsNotSupported).
Supported deposit networks:
- EVM: the destination chain (Base or Arc), Base, Arbitrum, BNB Chain, Ethereum, Kaia, Polygon, Optimism
- TRON
- Solana
- Stellar
sdk.api.withdrawal — Withdrawal API
sdk.api.withdrawal — Withdrawal API| Method | Description |
|---|---|
getWithdrawalRequests() | Get list of withdrawal requests |
sdk.api.baas — BaaS Module
sdk.api.baas — BaaS ModuleBanking-as-a-Service module with the following sub-services:
sdk.api.baas.user — User Service
sdk.api.baas.user — User Service| Method | Description |
|---|---|
getUser() | Get current user |
getUserV2() | Get current user (v2) |
createUser(request) | Create a new user |
createRetailUser(request) | Create a retail user |
validateRetailUser() | Validate retail user |
authorizeUser(params) | Authorize user |
updatePhoneNumber(request) | Update phone number |
confirmPhoneNumber(request) | Confirm phone number via OTP |
uploadDocument(formData) | Upload verification document |
updateFreshdeskId(request) | Update Freshdesk ID |
getSharingToken(request) | Get sharing token |
setSharingToken(request) | Set sharing token |
getVerificationToken() | Get verification token |
getVerificationLink() | Get verification link |
sdk.api.baas.activity — Activity Service
sdk.api.baas.activity — Activity Service| Method | Description |
|---|---|
getFeed(request?) | Get activity feed |
getById(request) | Get activity by ID |
getFullStatement(request) | Get full statement |
getRequestedErcWithdrawals() | Get requested ERC withdrawals |
sdk.api.baas.bank — Bank Service
sdk.api.baas.bank — Bank Service| Method | Description |
|---|---|
getAccounts(request?) | Get bank accounts |
activateAccount(request) | Activate bank account |
estimateTransfer(request) | Estimate bank transfer |
executeTransfer(request) | Execute bank transfer |
estimateCorridorTransferV2(corridor, request) | Estimate corridor transfer (v2) |
executeCorridorTransferV2(corridor, request) | Execute corridor transfer (v2) |
sdk.api.baas.swap — Swap Service (FX)
sdk.api.baas.swap — Swap Service (FX)Circle FX stablecoin swaps. Three-step flow: estimate (issues a deposit address) → on-chain payment to that address (crypto.transfer.makeTransferWithoutDelayPolicy) → execute.
| Method | Description |
|---|---|
estimate(request) | Create a swap estimation and deposit address. Send exactly one of source_asset_amount / destination_asset_amount. |
execute(request) | Execute the swap after the source tokens were sent to the deposit address. |
type SwapEstimateRequest = {
source_asset_address: string; // token to swap from (e.g. USDC)
destination_asset_address: string; // token to receive (e.g. EURC)
correlation_id?: string;
} & (
| { source_asset_amount: string; destination_asset_amount?: never }
| { destination_asset_amount: string; source_asset_amount?: never }
);
interface SwapEstimateResponse {
estimation_id: string;
destination_address: string; // send source tokens here (preferred)
deposit_address: string; // @deprecated — mirrors destination_address
source_asset_address: string;
source_asset_amount: string;
destination_asset_address: string;
destination_asset_amount: string;
trade_rate: string;
expiration_time: string; // RFC3339, estimation expiry
}
interface SwapExecuteRequest {
estimation_id: string;
payment_transaction_hash: string; // hash of the on-chain payment
}
interface SwapExecuteResponse {
trade_id: string;
}sdk.api.baas.cards — Cards Service
sdk.api.baas.cards — Cards Service| Method | Description |
|---|---|
getCards(request?) | Get user cards |
getCard(cardId) | Get card details |
getCardTransactions(request?) | Get card transactions |
issuePlasticCard(request) | Issue a plastic card |
issueVirtualCard(request) | Issue a virtual card |
activateCard(cardId, request) | Activate card |
blockCard(cardId) | Block card |
unblockCard(cardId) | Unblock card |
closeCard(cardId) | Close card |
getCardDetails(cardId, request) | Get card PAN and expiry |
getCardCvv(cardId, request) | Get card CVV |
getCardPin(cardId, request) | Get card PIN |
changeCardLimit(cardId, request) | Change card limit |
changeCardName(cardId, request) | Change card name |
estimateCardTransfer(request) | Estimate card transfer |
executeCardTransfer(request) | Execute card transfer |
estimateCardWithdrawal(cardId, request) | Estimate card withdrawal |
executeCardWithdrawal(cardId, request) | Execute card withdrawal |
getActive3dsRequests() | Get active 3DS requests |
approve3dsRequest(transactionId) | Approve 3DS request |
decline3dsRequest(transactionId) | Decline 3DS request |
getDeliveryCountries() | Get card delivery countries |
getDeliveryMethods(country) | Get card delivery methods |
getOrderFees(type, country) | Get card order fees |
createOrderFeesInvoice(type, country, request) | Create order fees invoice |
Sensitive card data (PAN, CVV, PIN) requires an action token obtained via SMS OTP:
// 1. Request SMS OTP
const session = await sdk.api.baas.confirmation.requestSms({
action_type: 'GetCardDetails',
});
// 2. Verify OTP → receive action token (UAT code is '000000')
const tokenRes = await sdk.api.baas.confirmation.verifySms({
session_id: session.session_id,
code: userInputCode,
});
const actionToken = tokenRes.token;
// 3. Use action token to retrieve sensitive data
const details = await sdk.api.baas.cards.getCardDetails(cardId, { action_token: actionToken });
// → { card_number: '4111111111111111', expiry_date: '12/2028' }
const cvv = await sdk.api.baas.cards.getCardCvv(cardId, { action_token: actionToken });
// → { cvv: '123' }sdk.api.baas.config — Config Service
sdk.api.baas.config — Config Service| Method | Description |
|---|---|
getConfig() | Get client app config |
sdk.api.baas.confirmation — Confirmation Service
sdk.api.baas.confirmation — Confirmation Service| Method | Description |
|---|---|
verifySignature(request) | Verify signature for action confirmation |
requestSms(request) | Request SMS confirmation code |
verifySms(request) | Verify SMS confirmation code |
sdk.api.baas.recipients — Recipients Service
sdk.api.baas.recipients — Recipients Service| Method | Description |
|---|---|
getRecipients(request?) | Get all recipients |
getRecipientsByCatalog(request) | Get recipients by catalog |
getRecipientsByCurrency(request) | Get recipients by currency |
getRecipientsByName(request) | Get recipients by name |
getRecipientsByType(request) | Get recipients by type |
getRecipientById(recipientId) | Get recipient by ID |
createRecipient(request) | Create recipient |
createRecipientV2(request) | Create recipient (v2) |
updateRecipient(recipientId, request) | Update recipient |
deleteRecipient(recipientId) | Delete recipient |
createRecipientPaymentDetails(recipientId, request) | Create payment details |
updateRecipientPaymentDetails(recipientId, paymentDetailsId, request) | Update payment details |
deleteRecipientPaymentDetails(recipientId, paymentDetailsId) | Delete payment details |
incrementRecipientUsage(recipientId) | Increment recipient usage counter |
sdk.api.baas.rates — Rates Service
sdk.api.baas.rates — Rates Service| Method | Description |
|---|---|
getRates(request) | Get exchange rates |
sdk.api.baas.token — Token Service
sdk.api.baas.token — Token Service| Method | Description |
|---|---|
getToken(request) | Get OAuth2 token |
sdk.api.baas.wallet — Wallet Service
sdk.api.baas.wallet — Wallet Service| Method | Description |
|---|---|
getWallet(request?) | Get wallet by ID or default |
getWallets() | Get all wallets |
createGlobalWallet(request) | Create global wallet |
Examples
Full Token Transfer (single call, on-chain delay)
Runs the whole ExecutionDelayPolicy cycle in one call — no backend/withdrawal-request polling. tokenAddress must be a synthetic token (it is unwrapped, then its base token is transferred).
const finalTxHash = await sdk.crypto.transfer.makeErc20TransferFull({
tokenAddress: '0x...', // synthetic token, e.g. WUSD
recipientAddress: '0x...',
amount: 100,
});
console.log('Final tx:', finalTxHash);Full Token Transfer (backend-driven)
const result = await sdk.crypto.transfer.makeFullErc20Transfer({
tokenAddress: '0x...', // synthetic token, e.g. WUSD
recipientAddress: '0x...',
amount: 100,
});
console.log('First part tx:', result.firstPartTxHash);
console.log('Final tx:', result.finalTxHash);
console.log('Success:', result.success);Two-Step Transfer
// Step 1: Initiate transfer
const txHash = await sdk.crypto.transfer.makeErc20TransferFirstPart({
tokenAddress: '0x...', // synthetic token, e.g. WUSD
recipientAddress: '0x...',
amount: 100,
});
// Step 2: Get withdrawal requests
const withdrawals = await sdk.api.withdrawal.getWithdrawalRequests();
const withdrawal = withdrawals.find(w => w.to_address === recipientAddress && w.amount === 100);
// Step 3: Complete transfer (after valid_after time)
await sdk.crypto.transfer.makeErc20TransferFinal(withdrawal.call_data);Batch Transfer
const txHashes = await sdk.crypto.transfer.batchTransfer({
tokenAddress: '0x...', // token to send
responses: [
{
transaction_id: '6f1c2a4e-8b3d-4f5a-9c7e-1d2b3c4d5e6f',
operation_id: '7a2d3b5f-9c4e-4a6b-8d1f-2e3c4d5e6f7a',
crypto_transfers: [
{ address: '0x...', precise_amount: '100000000' },
{ address: '0x...', precise_amount: '50000000' },
],
},
],
});FX Swap (estimate → pay → execute)
// Step 1: estimate — issues a deposit address and locks a rate
const estimate = await sdk.api.baas.swap.estimate({
source_asset_address: '0x...', // e.g. USDC
destination_asset_address: '0x...', // e.g. EURC
source_asset_amount: '100',
});
// Step 2: on-chain payment to the deposit address (unwraps the synthetic, no delay policy)
const paymentTransactionHash = await sdk.crypto.transfer.makeTransferWithoutDelayPolicy({
tokenAddress: '0x...', // wrapped synthetic of the source asset, e.g. WUSD
recipientAddress: estimate.destination_address,
amount: estimate.source_asset_amount,
});
// Step 3: execute — settles the swap
const { trade_id } = await sdk.api.baas.swap.execute({
estimation_id: estimate.estimation_id,
payment_transaction_hash: paymentTransactionHash,
});Yield Operations
const yieldData = await sdk.crypto.yield.fetchYieldData();
console.log('APY:', yieldData.apy);
console.log('Pending yield:', yieldData.currentPendingYield);
await sdk.crypto.yield.withdraw();Smart Deposit Addresses
const addresses = await sdk.crypto.smartDepositAddress.initializeSmartDepositAddresses();
addresses.forEach(addr => {
console.log(`Chain: ${addr.depositChain}`);
console.log(`Address: ${addr.depositAddress}`);
console.log(`Tokens: ${addr.supportedTokens.join(', ')}`);
});Types
import type {
SDKConfig,
SDKEnvironment,
Logger,
TokenInfo,
ContractAddresses,
Hex,
TransactionHash,
MainWalletClient,
PrivyAuth,
LoginUserParams,
LoginCompanyParams,
RegisterUserParams,
RegisterCompanyParams,
AuthResponse,
RegisterUserResponse,
} from '@wirexapp/wpay-baas-sdk';Error Handling
The SDK provides typed error classes:
| Error | Description |
|---|---|
SDKError | Base error class |
ConfigurationError | Invalid configuration |
NetworkError | Network/HTTP errors |
ContractError | Smart contract interaction errors |
WalletError | Wallet-related errors |
TransactionError | Transaction execution errors |
AuthenticationError | Authentication failures |
ValidationError | Input validation errors |
import { SDKError, AuthenticationError } from '@wirexapp/wpay-baas-sdk';
try {
await sdk.auth.login({ authorizationToken: 'token' });
} catch (error) {
if (error instanceof AuthenticationError) {
// handle auth error
}
}Next Steps
| Guide | Description |
|---|---|
| Getting Started | Platform overview and environments |
| Wallet Deployment | Full ZeroDev / Crossmint deployment options |
| Developer Onboarding | User registration and KYC flows |
| Authentication | Token exchange and header management |
Updated 5 days ago

