You can easily integrate with Streambird Auth Magic Link flow with Solana wallet access. We keep track of all Streambird provisioned wallets with the associated user and securely provide access to your users client-side.

1 - Implement Email Login/Register UI

Implement an UI for initiating login/register via Email.

2 - Configure Redirect URLs

For security reasons, we only allow you to use redirect URL preconfigured with Streambird to ensure that we send emails to your users ONLY containing redirect_urls you whitelisted with us.

Each user must be stored on Streambird Auth, so we recommend ensuring that you store our auto generated User ID from the response into your database/backend in a column or field against that user (as long as you can associate your user with the auto generated ID returned by Streambird).

We will ensure that each email is ONLY attached to a single user at any time. We will be using the LoginOrCreateUserViaMagicLink, if a user is found with the provided email, it will be returned and magic link email sent out, otherwise, a new user will be created on the fly (aka JIT, Just in time).

In this example, we assume you are calling Streambird Auth API from your client-side via our SDK or your custom frontend Api Client. We will be using your PublicToken, which is publishable.

cURL
curl --location --request POST 'https://api.streambird.io/v1/auth/magic_links/public/email/login_or_create' \
--header 'Authorization: PublicToken {{public_token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "email": "sandbox@streambird.io",
    "expires_in": 0,
    "login_redirect_url": "http://localhost:8081/signin/authenticate",
    "registration_redirect_url": "http://localhost:8081/register/authenticate",
    "wallet_type": "SOL"
}'

If successful, we will return the Streambird user_id of the user who owns the token (example response below)

JSON
{
    "user_id": "user_24wFP9pDa9YiMJLun94iKykoZs2",
    "app_id": "app_24ydphdixx2ydhF0E5WUFUKWNqi",
    "first_name": "",
    "middle_name": "",
    "last_name": "",
    "active": true,
    "updated_at": 1627502169,
    "created_at": 1627502169,
    "emails": null,
    "phone_numbers": null,
    "wallets": null,
    "email_id": "email_24oXBL3PufzHkH1Jzyjc2EXYeo7",
    "phone_number_id": "",
    "request_origin_token": "H1C1XGdieAhhkUzclEKl4mAFqyxhysrzE9R7sT6aFqtYzMIZGJUuBEXF9MXSGDdFKr0x7uzep2I2hVGsBbD8evri368kI6ArvXcolEOyk3Esy4YmxW381SYKzfhlNRSQ"
}

Since this is a client-side SDK authentication, we issue you a request_origin_token that you can use to query our backend to retrieve magic link authentication status. To ensure ONLY the original device and browser session can login to the wallet address, this request_origin_token will ONLY be shown once to you in the browser when you requested the login. An email with an associated magic_token will be sent to your user.

With this setup, even if you user leaked the emails before the magic_token is expired, the person will still need the original request_origin_token only shown to the requester to access the wallet address.

In the previous step, your user will receive an email containing the magic_link they can click on (the magic_link has the redirect_url you specified combined with the magic_token. This will then redirect the user to your app with the token in the Query parameters. A sample link is shown below,

http://localhost:8081/register/authenticate?token=supermagictoken

Your application should parse the token and send it back to your app’s backend where you can authenticate with Streambird on the validity of this token using your ApiKey with VerifyMagicLink endpoint.

In this example, we assume you are calling Streambird Auth API from your backend/server side. Please ensure that you NEVER expose your ApiKey

cURL
curl --location --request POST 'https://api.streambird.io/v1/auth/magic_links/verify' \
--header 'Authorization: ApiKey sk_test_KJuRUZmh1XC342h1n39gH84MuSZDyD13NfhtDkaY6IfwpQA0H' \
--header 'Content-Type: application/json' \
--data-raw '{
    "magic_token": "supermagictoken"
}'

If successful, we will return the Streambird user_id of the user who owns the token (example response below)

JSON
{
    "user_id": "user_24wFP9pDa9YiMJLun94iKykoZs2",
    "app_id": "app_24ydphdixx2ydhF0E5WUFUKWNqi",
    "first_name": "John",
    "middle_name": "",
    "last_name": "Smith",
    "active": true,
    "updated_at": 1627502169,
    "created_at": 1627502169,
    "emails": null,
    "phone_numbers": null,
    "email_id": "email_24oXBL3PufzHkH1Jzyjc2EXYeo7",
    "phone_number_id": ""
}

However, if you have not previously attached the user_id to your users table for example, you can also use our GetIdentityUser endpoint to retrieve the emails and phone_numbers attached to the user using the user_id returned by VerifyMagicLink endpoint.

cURL
curl --location --request GET 'https://api.streambird.io/v1/auth/users/user_24wFP9pDa9YiMJLun94iKykoZs2' \
--header 'Authorization: ApiKey sk_test_KJuRUZmh1XC342h1n39gH84MuSZDyD13NfhtDkaY6IfwpQA0H'

Sample response below:

JSON
{
    "user_id": "user_24wFP9pDa9YiMJLun94iKykoZs2",
    "app_id": "app_24ydphdixx2ydhF0E5WUFUKWNqi",
    "first_name": "John",
    "middle_name": "",
    "last_name": "Smith",
    "active": false,
    "updated_at": 1627081626,
    "created_at": 1627081626,
    "emails": [
        {
            "id": "email_24oXBL3PufzHkH1Jzyjc2EXYeo7",
            "verified": true,
            "email": "johnsmith@example.com",
            "updated_at": 1627081626,
            "created_at": 1627081626
        }
    ],
    "phone_numbers": [
        {
            "id": "pn_24oXBLRv6BoHXbNZoTAZkAFlRsy",
            "verified": false,
            "phone_number": "+14152222222",
            "updated_at": 1627081626,
            "created_at": 1627081626
        }
    ]
}

5 - Access Wallet Address

Once your user has clicked on the link in the email and your redirect_url and your server calls Streambird to verify magic_token, the original requester/device session of this login will be able to retrieve wallet addresses via the request_origin_token we sent back. We also recommend polling to be done in the frontend as soon as request_origin_token is sent back to provide a loading screen for better UI/UX for the end users.

In this example, we assume you are calling Streambird Auth API from your client-side via our SDK or your custom frontend Api Client. We will be using your PublicToken, which is publishable.

cURL
curl --location --request POST 'https://api.streambird.io/v1/auth/magic_links/public/email/login_status' \
--header 'Authorization: PublicToken {{public_token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "request_origin_token": "H1C1XGdieAhhkUzclEKl4mAFqyxhysrzE9R7sT6aFqtYzMIZGJUuBEXF9MXSGDdFKr0x7uzep2I2hVGsBbD8evri368kI6ArvXcolEOyk3Esy4YmxW381SYKzfhlNRSQ",
    "email_id": "email_24oXBL3PufzHkH1Jzyjc2EXYeo7"
}'

This request will return a success response once the user has verified the magic link. Example response shown below.

JSON
{
    "user_id": "user_24wFP9pDa9YiMJLun94iKykoZs2",
    "app_id": "app_24ydphdixx2ydhF0E5WUFUKWNqi",
    "first_name": "",
    "middle_name": "",
    "last_name": "",
    "active": true,
    "updated_at": 1627502169,
    "created_at": 1627502169,
    "emails": [
        {
            "id": "email_24oXBL3PufzHkH1Jzyjc2EXYeo7",
            "verified": true,
            "email": "sandbox@streambird.io",
            "updated_at": 1627503141,
            "created_at": 1627502169
        }
    ],
    "phone_numbers": [],
    "wallets": [
        {
            "id": "wallet_24oXBMIvyVJGrbqmh1pTgY6BLbM",
            "app_id": "app_24ydphdixx2ydhF0E5WUFUKWNqi",
            "user_id": "user_24wFP9pDa9YiMJLun94iKykoZs2",
            "public_address": "GaqqqFdYtADV2cN56njn2jE5RKjVQpMXsAxUwCAEfZSF",
            "wallet_type": "SOL",
            "is_default": true,
            "signature_exp": 1634340607,
            "request_signature": "0xfb0556fdb27075ab8915bfa6b0e2e879a434ecae08c254778e1c69a9f494e2ed7d820d179e261a429d198197b751ed696e7057b3634e79fde3292caccc61eeac00",
            "updated_at": 1634152344,
            "created_at": 1634152344
        }
    ]
}

Each Wallet object contains a request_signature (request_signature is signed by randomly generated and rotating ethereum private key that provide the holder limited time access for private key retrieval in the Vault) that can be used with PublicToken to retrieve the private key for wallet access client-side. Streambird NEVER access your private key directly and all data are stored on a third-party Vault to ensure security.

cURL
curl --location --request POST 'https://api.streambird.io/v1/auth/vault/public/wallets/retrieve' \
--header 'Authorization: PublicToken {{public_token}}' \
--header 'Content-Type: application/json' \
--data-raw '{
    "public_address": "GaqqqFdYtADV2cN56njn2jE5RKjVQpMXsAxUwCAEfZSF",
    "wallet_type": "SOL",
    "signature_exp": 1634340607,
    "request_signature": "0xfb0556fdb27075ab8915bfa6b0e2e879a434ecae08c254778e1c69a9f494e2ed7d820d179e261a429d198197b751ed696e7057b3634e79fde3292caccc61eeac00"
}'

Example Response:

JSON
{
    "pk": "5ySwMAHswNcVPpXjCAgX3m1uBfP3o14huBT2YvTwWamaQaT9JExPHo8aUpdt8fJ4efvmL6HQ37HGu5xHCjRCavqm",
    "public_address": "GaqqqFdYtADV2cN56njn2jE5RKjVQpMXsAxUwCAEfZSF",
    "valid": true,
    "wallet_type": "SOL"
}

Congrats! You now have access to your private key in your browser that can be sent into Web3.js or any other Solana blockchain clients to access your wallet.