light-mode-image
Learn

Getting started with the Holder SDKs

Set up access to the MATTR Pi mDocs Holder SDKs, configure SDK tethering, and initialize the SDK in your mobile application.

This guide walks you through the steps required to start building with the MATTR Pi mDocs Holder SDKs. By the end, your mobile application will be connected to a MATTR VII tenant and ready to use SDK capabilities such as credential claiming and presentation.

Request SDK access

To access the MATTR Pi mDocs Holder SDKs, complete the Get Started form with the following details:

  • Your organization name and contact information.
  • The platform(s) you plan to build for (iOS, Android, or React Native).
  • A brief description of your use case.

Once your request is reviewed, you will receive access to the relevant SDK packages and the MATTR Portal.

Create a MATTR VII tenant

Your application requires a MATTR VII tenant that serves as the backend for SDK operations including tethering, credential issuance, and verification.

  1. Log into the MATTR Portal.
  2. Create a new tenant to serve as the backend for your application.
  3. Note the tenant URL (e.g., https://your-tenant.vii.mattr.global) — you will need it when initializing the SDK.

Create a Holder Application

SDK Tethering is optional, but we recommend configuring it so your application can use capabilities such as Wallet Attestation and so you can view registered app instances from your tenant. To enable it, create a Holder Application on your MATTR VII tenant for each platform target.

For more details on SDK tethering and the capabilities it enables, see SDK Tethering.

SDK Tethering is optional. To enable it, create a Holder Application on your MATTR VII tenant for each platform target (iOS and Android). This is a one-time setup process that registers your app with the tenant and allows app instances to obtain the necessary tokens for authentication and operation.

Make a request of the following structure to create an iOS Holder Application configuration on your MATTR VII tenant:

Request
POST /v1/holder/applications
Request body
{
    "name": "My iOS Holder Application",
    "clientId": "my-wallet-client",
    "type": "ios",
    "bundleId": "com.yourcompany.holderapp",
    "teamId": "YOUR_APPLE_TEAM_ID",
    "maxTimeOfflineInSecs": 864000,
    "appAttest": {
        "required": true,
        "environment": "production"
    }
}
  • name: A unique name to identify this Holder Application.
  • clientId: OAuth 2.0 client_id value that the holder application uses when requesting client attestations. This value is included as the sub claim in attestation JWTs and must match the client_id configured by issuers who trust this Holder Application.
  • type: Must be ios.
  • bundleId: The Bundle ID of your iOS app (must match your Xcode project configuration).
  • teamId: Your Apple Developer Team ID.
  • maxTimeOfflineInSecs: Maximum number of seconds the SDK can operate offline before requiring a new license token. Must be between 1 day (86400) and 30 days (2592000). Defaults to 7 days (604800).
  • appAttest: App Attest configuration for the iOS holder application:
    • required: When true, the app instance must provide a valid App Attest attestation during registration and token renewal. When false, the app can fall back to assertion-only authentication. See Attestation vs Assertion for more details.
    • environment: The App Attest environment (development or production). Apple recommends using development for testing and production for distribution builds.

A successful response returns a 201 status code with the created Holder Application:

Response
{
    "id": "1ef1f867-20b4-48ea-aec1-bea7aff4964c", 
    "name": "My iOS Holder Application",
    "clientId": "my-wallet-client",
    "type": "ios",
    "bundleId": "com.yourcompany.holderapp",
    "teamId": "YOUR_APPLE_TEAM_ID",
    "maxTimeOfflineInSecs": 864000,
    "appAttest": {
        "required": true,
        "environment": "production"
    }
}
  • id: A unique identifier for the Holder Application (generated by the tenant). You must use this value when initializing the SDK so that it can correctly identify and authenticate your application.

Make a request of the following structure to create an Android Holder Application configuration on your MATTR VII tenant:

Request
POST /v1/holder/applications
Request body
{
    "name": "My Android Holder Application",
    "clientId": "my-wallet-client",
    "type": "android",
    "packageName": "com.yourcompany.holderapp",
    "packageSigningCertificateThumbprints": [
        "1232584B6F6A892D356899FB9576C5F226A179E6199F2B7A1D837B5C234C5A8E"
    ],
    "maxTimeOfflineInSecs": 864000,
    "keyAttestation": {
        "required": true
    }
}
  • name: A unique name to identify this Holder Application.
  • clientId: OAuth 2.0 client_id value that the holder application uses when requesting client attestations. This value is included as the sub claim in attestation JWTs and must match the client_id configured by Issuers who trust this Holder Application.
  • type: Must be android.
  • packageName: The package name of your Android application.
  • packageSigningCertificateThumbprints: SHA-256 hex-encoded fingerprints of the signing key certificates used to sign your APK or app bundle. This ensures the tenant only accepts requests from known and trusted applications. Refer to Android app signing for more information.
  • maxTimeOfflineInSecs: Maximum number of seconds the SDK can operate offline before requiring a new license token. Must be between 1 day (86400) and 30 days (2592000). Defaults to 7 days (604800).
  • keyAttestation: Key Attestation configuration for the Android holder application:
    • required: When true, the app instance must provide a valid Key Attestation during registration and token renewal. When false, the app can register and renew tokens using just an authentication assertion. See Attestation vs Assertion for more details.

A successful response returns a 201 status code with the created Holder Application:

Response
{
    "id": "a82bfa46-72a0-4cde-b6cb-2a0de7e2f3c4", 
    "name": "My Android Holder Application",
    "clientId": "my-wallet-client",
    "type": "android",
    "packageName": "com.yourcompany.holderapp",
    "packageSigningCertificateThumbprints": [
        "1232584B6F6A892D356899FB9576C5F226A179E6199F2B7A1D837B5C234C5A8E"
    ],
    "maxTimeOfflineInSecs": 864000,
    "keyAttestation": {
        "required": true
    }
}
  • id: A unique identifier for the Holder Application (generated by the tenant). You must use this value when initializing the SDK so that it can correctly identify and authenticate your application.

For React Native applications, you must create both an iOS and an Android Holder Application on your MATTR VII tenant, and then conditionally pass the correct configuration based on the platform OS at runtime.

Step 1: Create the iOS Holder Application

Follow the instructions in the iOS tab to create a Holder Application configuration for iOS.

Step 2: Create the Android Holder Application

Follow the instructions in the Android tab to create a Holder Application configuration for Android.

Step 3: Pass the correct configuration based on Platform OS

When initializing the SDK, use Platform.OS to conditionally provide the matching Holder Application configuration:

Example
import { Platform } from "react-native";

const holderApplicationId =
  Platform.OS === "ios"
    ? "YOUR_IOS_HOLDER_APPLICATION_ID"
    : "YOUR_ANDROID_HOLDER_APPLICATION_ID";
  • YOUR_IOS_HOLDER_APPLICATION_ID : The id returned when you created the iOS Holder Application.
  • YOUR_ANDROID_HOLDER_APPLICATION_ID : The id returned when you created the Android Holder Application.

Initialize the SDK

If you are using SDK Tethering, update your SDK initialization to include the platform configuration once your Holder Applications are created. This enables your app to connect to the correct MATTR VII tenant and Holder Application. If you are not using tethering, you can initialize the SDK without a platformConfiguration.

Initialize the SDK with your platform configuration:

Initialization
let platformConfig = PlatformConfiguration(
    tenantHost: URL(string: "https://your-tenant.vii.mattr.global")!,
    applicationId: "1ef1f867-20b4-48ea-aec1-bea7aff4964c"
)
try await MobileCredentialHolder.shared.initialize(
    platformConfiguration: platformConfig
)
  • tenantHost: The URL of your MATTR VII tenant. This must be the tenant where your iOS Holder Application is configured.
  • applicationId: The id of your configured iOS Holder Application.

Initialize the SDK with your platform configuration:

Initialization
val platformConfig = PlatformConfiguration(
    tenantHost = URL("https://your-tenant.vii.mattr.global"),
    applicationId = "1ef1f867-20b4-48ea-aec1-bea7aff4964c"
)
MobileCredentialHolder.initialize(context, platformConfiguration = platformConfig)
  • tenantHost: The URL of your MATTR VII tenant where your Android Holder Application is configured.
  • applicationId: The id of your configured Android Holder Application.

Since React Native bridges both iOS and Android, and each platform has its own Holder Application registered on your MATTR VII tenant (see Create a Holder Application), your initialization code must pass the correct platform-specific applicationId at runtime. Use Platform.OS to select the appropriate value:

Initialization
import { initialize } from "@mattrglobal/mobile-credential-holder-react-native";
import { Platform } from "react-native";

const applicationId =
    Platform.OS === "android"
        ? "your-android-holder-application-id"
        : "your-ios-holder-application-id";

await initialize({
    platformConfiguration: {
        tenantHost: "https://your-tenant.vii.mattr.global",
        applicationId,
    },
});

Replace the placeholder values with the id returned when you created each Holder Application. In practice, you would typically store these values in a configuration file or environment variables.

Next steps

Your application is now initialized and ready to use the SDK. If you configured a platformConfiguration, it is also tethered to your MATTR VII tenant. Explore the following guides to start building:

How would you rate this page?

Last updated on

On this page