Configuration
High-level configuration guidance for external client teams.
What This Page Covers
This page focuses on the configuration most host applications need to provide to mount the SDK successfully. It does not document every internal tuning or development-only option.
The Main Idea
Most applications pass a small configuration object to VECUProvider.
The most important inputs are:
authTokendeploymentStage
At a high level:
- your host app obtains the authentication token from its own login or authorization flow
- your host app passes that token into the SDK config
- the SDK uses that configuration to initialize the wallet experience
Minimum Configuration
import { VECUProvider } from '@vecu/wallet-react-native-sdk';
function App() {
const authToken = tokenFromYourLoginFlow;
return (
<VECUProvider
config={{
authToken,
deploymentStage: 'sandbox',
}}
>
<WalletScreen />
</VECUProvider>
);
}
Required Configuration
authToken
This is the authentication token your host app provides after the user logs in or completes your app's authorization flow.
Keep in mind:
- the SDK does not own your login experience
- your app is responsible for obtaining and storing the token
- the token must be available before rendering
VECUProvider
Authentication Ownership
Your application is responsible for user authentication. The SDK expects the host app to provide the token it should use.
deploymentStage
This tells the SDK which environment to use.
deploymentStage: 'sandbox';
For external-facing documentation, the main values clients need to understand are:
sandboxfor development and integration testingproductionfor live production environments
useTokenExchange
By default, the SDK exchanges your authToken for a VECU token internally.
Pass your IdP token directly — your app does not need to fetch a VECU-specific
token before mounting the provider. The SDK calls the VECU token exchange
endpoint automatically and uses the exchanged token for all subsequent API
calls.
If your app has already exchanged the IdP token and authToken is a
VECU-specific token, set useTokenExchange: false to skip the internal
exchange:
<VECUProvider
config={{
authToken: vecuToken, // already-exchanged VECU token
deploymentStage: 'sandbox',
useTokenExchange: false,
}}
>
<WalletScreen />
</VECUProvider>
| Value | Meaning |
|---|---|
true (default) | authToken is your IdP token; SDK handles the exchange |
false | authToken is a VECU token already; SDK skips the exchange |
See Access and Authorization for IdP registration requirements.
Common Host App Pattern
Many applications keep the auth token in app state and build the SDK config from that token.
function App() {
const authToken = tokenFromYourLoginFlow;
const sdkConfig = {
authToken,
deploymentStage: 'sandbox',
};
return (
<VECUProvider config={sdkConfig}>
<WalletScreen />
</VECUProvider>
);
}
The demo application follows the same high-level pattern: the host app manages
authentication, creates SDK config, and then mounts VECUProvider.
Optional Configuration
Some applications may also use optional callbacks or environment-specific settings. These are commonly used for:
- handling token expiry
- responding to unauthorized access
- application logging
- analytics or error reporting
External client teams usually do not need to start with all of these options. Begin with the minimum configuration first, then add optional behavior only if your app requires it.
Operational Options
The SDK also exposes a small set of operational settings through the public configuration type.
These options are useful when your host app needs more control over request behavior or SDK logging.
Logging
The public configuration supports:
logLevelonLog
Use these when your application wants to control how much SDK logging is emitted or forward SDK log events into your own logging pipeline.
Common log levels include:
errorwarninfodebug
High-level example:
<VECUProvider
config={{
authToken,
deploymentStage: 'sandbox',
logLevel: 'info',
onLog: (level, message, meta) => {
console.log(level, message, meta);
},
}}
>
<WalletScreen />
</VECUProvider>
Resilience and Timeouts
The public configuration also includes:
maxRetriesretryBackoffMsrequestTimeoutMs
Use these when your host app needs to tune retry or timeout behavior for your environment.
High-level example:
<VECUProvider
config={{
authToken,
deploymentStage: 'sandbox',
maxRetries: 3,
retryBackoffMs: 1000,
requestTimeoutMs: 30000,
}}
>
<WalletScreen />
</VECUProvider>
Two-tier config for background polling vs. active wallet UI
Some applications mount VECUProvider in two places: once near the top of the
app for background notification polling, and once on the wallet screen for
active user interactions.
The two surfaces have different reliability requirements. Background polling runs silently — a failed poll simply waits for the next interval. The wallet screen is user-facing — failures should retry more aggressively and give the user more time to complete flows like QR scanning or NFC.
You can tune maxRetries and requestTimeoutMs per provider accordingly:
// Lightweight config for background polling (e.g. notification badge)
const notificationConfig = {
authToken,
deploymentStage,
maxRetries: 2,
requestTimeoutMs: 15000,
};
// Heavier config for the active wallet screen (QR, NFC, credential flows)
const walletConfig = {
authToken,
deploymentStage,
maxRetries: 3,
requestTimeoutMs: 30000,
};
Token Refresh
If your application refreshes authentication tokens, update the token in host app state and pass the new value into the SDK configuration.
Reactive refresh (via onTokenExpired)
The SDK calls onTokenExpired when it detects an expired token during a
request. Refresh your token and update state so the provider reinitializes with
a fresh token.
function App() {
const [authToken, setAuthToken] = useState(initialToken);
const handleTokenExpired = async () => {
const nextToken = await refreshTokenFromYourAuthFlow();
setAuthToken(nextToken);
};
return (
<VECUProvider
config={{
authToken,
deploymentStage: 'sandbox',
onTokenExpired: handleTokenExpired,
}}
>
<WalletScreen />
</VECUProvider>
);
}
Proactive refresh before mounting
The reactive pattern covers mid-session expiry, but if your token is already
stale when the provider first mounts, the SDK's initial requests will fail
before onTokenExpired can fire.
To guard against this, check token freshness before rendering VECUProvider
and refresh proactively if needed:
function WalletProvider({ children }) {
const [authToken, setAuthToken] = useState(null);
const [isRefreshing, setIsRefreshing] = useState(false);
useEffect(() => {
async function ensureFreshToken() {
if (isTokenExpired(storedTokenExpiry)) {
setIsRefreshing(true);
const nextToken = await refreshTokenFromYourAuthFlow();
setAuthToken(nextToken);
setIsRefreshing(false);
} else {
setAuthToken(storedToken);
}
}
ensureFreshToken();
}, []);
if (!authToken || isRefreshing) {
return children; // render without SDK until token is ready
}
return (
<VECUProvider
config={{
authToken,
deploymentStage: 'sandbox',
onTokenExpired: async () => {
const nextToken = await refreshTokenFromYourAuthFlow();
setAuthToken(nextToken);
},
}}
>
{children}
</VECUProvider>
);
}
Both patterns work together: the proactive check prevents a stale-at-mount
failure, and onTokenExpired handles expiry that occurs during an active
session.
Avoid forcing remount with key
A common mistake is passing the auth token as the key prop on VECUProvider:
// ❌ Do not do this
<VECUProvider key={authToken} config={{ authToken, deploymentStage }}>
<WalletScreen />
</VECUProvider>
React treats a key change as a signal to unmount and remount the component
from scratch. Every token rotation — which can happen silently every few minutes
— forces the entire SDK to tear down and reinitialize. This produces a
multi-second blank state on the wallet screen on every refresh cycle.
The SDK watches authToken via its config prop. When the token changes,
the provider updates internally without a remount. Pass the token through
config only and let the SDK handle the transition:
// ✅ Correct — update config.authToken, no key needed
<VECUProvider config={{ authToken, deploymentStage }}>
<WalletScreen />
</VECUProvider>
Error Handling
The SDK supports callbacks for common host-app error handling patterns. The
callbacks are split between config (passed inside the config object) and
direct VECUProvider props.
Config callbacks (passed via config={{ ... }}):
onTokenExpired— lets your app refresh the token and update provider configonUnauthorized— lets your app react to permission or access issuesonError— lets your app capture SDK errors with context for logging, analytics, or support
Provider props (passed directly on VECUProvider, not inside config):
onReady— fires once the SDK has initialized successfully. Useful for analytics or gating UI that depends on SDK readiness.
High-level example showing both:
<VECUProvider
config={{
authToken,
deploymentStage: 'sandbox',
onTokenExpired: handleTokenExpired,
onUnauthorized: () => {
navigation.navigate('Login');
},
onError: (error, context) => {
console.error(context.operation, error.message);
},
}}
onReady={() => {
analytics.track('wallet_sdk_initialized');
}}
>
<WalletScreen />
</VECUProvider>
Error Code References
Some SDK features expose exported error types or error code unions as part of their public API surface.
For example, specific flows may expose public error code types for:
- credential presentation
- NFC send or receive flows
- Bluetooth send flows
These should be documented alongside the flow-specific guidance where they are most relevant, rather than treated as one large universal error-code list.
Related Guidance
- Installation for package setup and platform requirements
- Quick Start for the minimum integration path
- Integration Approaches for how the wallet screen fits into your app
- Authentication Guide for identity provider and token setup details