Getting Started with Turnkey

Let's get started with a basic example using Turnkey

Pre-requisites

1. Create a delegate user on the Turnkey dashboard

What is a delegate user?

A delegate user is a user created by you, the client application, for the Enclave team, that allows us to issue transaction policies that enforce resource locks on users that wish to enable Magicspend++.

You can create a delegate user on the Turnkey dashboard by following the steps mentioned here.

Once you have created the delegate user, share the all delegate key details with the Enclave team to enable integration. Also note down it's public key and API key name, these values are required for the next step.

2. Creating users and sub-organizations

Modify the existing user creation logic in your onboarding flow to provision a unique sub organization for each user and add the delegate user created in the previous step to the sub organization.

The sub organization structure is such that each unique user has their own sub organization. Each sub organization has 2 users. The end user and the delegate user that issues policies on the end user's wallet.

Given below is some sample code that can be used as reference:

Adding a delegate user

import { useTurnkey, AuthState } from '@turnkey/react-wallet-kit';
...

const LoginComponent = () => {
    const { authState, user, wallets, createWallet, refreshWallets, httpClient } = useTurnkey();
    ...
    
    const delegateApiKeyName = process.env.NEXT_PUBLIC_ENCLAVE_DELEGATE_API_KEY_NAME!;
    const delegatePublicKey = process.env.NEXT_PUBLIC_ENCLAVE_DELEGATE_PUBLIC_KEY!;
    
    if (!delegateApiKeyName || !delegatePublicKey) {
        console.log('⚠️ Delegate API credentials not found in environment variables, skipping');
        return;
    }

    console.log('📝 Adding delegate user to sub-organization...');

    const curveType: "API_KEY_CURVE_P256" = "API_KEY_CURVE_P256";
    
    const delegateApiKeys = [{
        apiKeyName: delegateApiKeyName,
        publicKey: delegatePublicKey,
        curveType,
    }];
    
    const fetchQuote = async () => {
        // Get the current organization info
        const orgInfo = await httpClient.getOrganization();
        const subOrgId = orgInfo?.organizationData?.organizationId;
            
        const response = await httpClient.createUsers({
            organizationId: subOrgId,
            users: [
                {
                    userName: "enclave_delegate_user",
                    userEmail: "[email protected]",
                    userTags: [],
                    apiKeys: delegateApiKeys,
                    authenticators: [],
                    oauthProviders: [],
                }
            ]
        });
    }
}

Adding a new end-user wallet

If the user logging in is a new user, then we create new EVM and Solana wallets for them within the same sub-org

const { createWallet } = useTurnkey();

const walletId = await createWallet({
    walletName: `AutoWallet-${new Date().getTime()}`,
    accounts: ["ADDRESS_FORMAT_ETHEREUM", "ADDRESS_FORMAT_SOLANA"],
});

Next let's see how we can fetch a quote

Fetching a quote

Last updated