Skip to main content

Overview

The Kotlin SDK allows you to customize the sub-organization creation process in your Kotlin application. This is useful if you want to create a more tailored experience for your users, including automatically creating wallets, having multiple authentication methods, default usernames, and more. These can be individually configured for each authentication method.

Customization

You can customize the createSuborgParams object inside the authConfig object in the TurnkeyContext.init configuration. This object allows you to set various parameters for the sub-organization creation process. Each authentication method can have its own set of parameters. For example, you can set a different default userName for emailOtpAuth and passkeyAuth methods, or create different wallets for each authentication method.
class App : Application() {
    override fun onCreate() {
        super.onCreate()

        TurnkeyContext.init(
            app = this,
            config = TurnkeyConfig(
                // ... your existing configuration
                authConfig = AuthConfig(
                    rpId = "your-relying-party-id",
                    createSubOrgParams = MethodCreateSubOrgParams(
                        emailOtpAuth = CreateSubOrgParams(
                            userName = "An email user",
                            customWallet = CustomWallet(
                                walletName = "Email Wallet",
                                walletAccounts = listOf(
                                    // This will create one Ethereum wallet account for users that sign up with email OTP
                                    V1WalletAccountParams(
                                        curve = V1Curve.CURVE_SECP256K1,
                                        pathFormat = V1PathFormat.PATH_FORMAT_BIP32,
                                        path = "m/44'/60'/0'/0/0",
                                        addressFormat = V1AddressFormat.ADDRESS_FORMAT_ETHEREUM
                                    )
                                )
                            )
                        ),
                        passkeyAuth = CreateSubOrgParams(
                            userName = "A passkey user",
                            customWallet = CustomWallet(
                                walletName = "Passkey Wallet",
                                walletAccounts = listOf(
                                    // This will create one Solana wallet account for users that sign up with passkeys
                                    V1WalletAccountParams(
                                        curve = V1Curve.CURVE_ED25519,
                                        pathFormat = V1PathFormat.PATH_FORMAT_BIP32,
                                        path = "m/44'/501'/0'/0'",
                                        addressFormat = V1AddressFormat.ADDRESS_FORMAT_SOLANA
                                    )
                                )
                            )
                        )
                    )
                )
            )
        )
    }
}
Or, you can set the same parameters for all authentication methods:
class App : Application() {
    override fun onCreate() {
        super.onCreate()

        val createSubOrgParams = CreateSubOrgParams(
            userName = "User-${System.currentTimeMillis()}",
            customWallet = CustomWallet(
                walletName = "Wallet-${System.currentTimeMillis()}",
                walletAccounts = listOf(
                    V1WalletAccountParams(
                        addressFormat = V1AddressFormat.ADDRESS_FORMAT_ETHEREUM,
                        curve = V1Curve.CURVE_SECP256K1,
                        path = "m/44'/60'/0'/0/0",
                        pathFormat = V1PathFormat.PATH_FORMAT_BIP32
                    )
                )
            )
        )

        TurnkeyContext.init(
            app = this,
            config = TurnkeyConfig(
                // ... your existing configuration
                authConfig = AuthConfig(
                    rpId = "your-relying-party-id",
                    createSubOrgParams = MethodCreateSubOrgParams(
                        emailOtpAuth = createSubOrgParams,
                        smsOtpAuth = createSubOrgParams,
                        passkeyAuth = createSubOrgParams,
                        oAuth = createSubOrgParams
                    )
                )
            )
        )
    }
}
The complete list of customizable parameters:

CreateSubOrgParams

PropertyTypeRequiredDefaultDescription
userNameString?nonullDisplay name for the user being created.
subOrgNameString?nonullName for the new sub-organization.
userEmailString?no*nullEmail for OTP flow. If set, you must also supply a valid verificationToken.
userTagString?nonullArbitrary label for the user (e.g., CRM tag, cohort).
authenticatorsList<CreateSubOrgAuthenticator>?nonullSeed passkey(s)/WebAuthn authenticators at creation time.
userPhoneNumberString?no*nullPhone number for SMS OTP. If set, also provide verificationToken.
verificationTokenString?no*nullToken proving ownership of userEmail/userPhoneNumber (returned by your OTP verification step).
apiKeysList<CreateSubOrgApiKey>?nonullCreate API keys for the sub-org on day one.
customWalletCustomWallet?nonullProvision a wallet and accounts immediately.
oauthProvidersList<V1OauthProviderParams>?nonullAttach OAuth identities the user authenticated with.
*“Required” depends on flow:
  • Email OTP → userEmail + verificationToken
  • SMS OTP → userPhoneNumber + verificationToken
  • Passkey → authenticators (or you’ll register after)
  • OAuth → oauthProviders

CreateSubOrgAuthenticator

Represents a passkey/WebAuthn authenticator to attach at sub-org creation.
PropertyTypeRequiredDescription
authenticatorNameString?noFriendly label. If omitted, the SDK can generate one.
challengeStringyesAttestation challenge you verified during registration.
attestationV1AttestationyesWebAuthn attestation payload (format depends on your API types).

CreateSubOrgApiKey

Creates an API key scoped to the new sub-org.
PropertyTypeRequiredDefaultDescription
apiKeyNameString?nonullDisplay name for the key.
publicKeyStringyesHex-encoded public key.
expirationSecondsString?nonullTTL in seconds (as string).
curveTypeV1ApiKeyCurve?nonullCurve for the key pair (e.g., API_KEY_CURVE_P256, API_KEY_CURVE_SECP256K1, API_KEY_CURVE_ED25519)

CustomWallet

Create a wallet (container) plus one or more accounts at signup.
PropertyTypeRequiredDescription
walletNameStringyesFriendly name for the new wallet.
walletAccountsList<V1WalletAccountParams>yesAt least one account. See V1WalletAccountParams fields (curve, derivation path, address format, etc.).