Verifying Wallets

Substantiate each wallet address before sending it tokens and requests.

The Enjin Platform offers a Wallet verifying process that you can use to verify the authenticity of a user's blockchain address.

🚧

If you need to send requests to user wallets, use WalletConnect instead.

📘

What you'll need:

By using wallet verification, you can receive the user's wallet address with 100% certainty that this wallet is owned by the user.

Wallet Verifying with the Enjin API

Step 1. Initiating an Account Request

To initiate the account request process, run the following query:

Query:

query RequestAccount{
  RequestAccount{
    qrCode #Returns a QR code for your user to scan
    verificationId #Save this for next step
  }
}
using System.Text.Json;
using Enjin.Platform.Sdk;

// Setup the query
var requestAccount = new RequestAccount();

// Define and assign the return data fragment to the query
var accountRequestFragment = new AccountRequestFragment()
    .WithQrCode()
    .WithVerificationId();

requestAccount.Fragment(accountRequestFragment);

// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
    .SetBaseAddress("https://platform.canary.enjin.io")
    .Build();
client.Auth("Your_Platform_Token_Here");

// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendRequestAccount(requestAccount);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
#include "EnjinPlatformSdk/CoreQueries.hpp"
#include <iostream>

using namespace enjin::platform::sdk;
using namespace std;

int main() {

    // Set up the query
    RequestAccount requestAccount = RequestAccount();

    // Define and assign the return data fragments to the query
    AccountRequestFragment accountRequestFragment = AccountRequestFragment()
            .WithQrCode()
            .WithVerificationId();

    requestAccount.SetFragment(make_shared<AccountRequestFragment>(accountRequestFragment));

    // Create and auth a client to send the request to the platform
    unique_ptr<PlatformClient> client = PlatformClient::Builder()
            .SetBaseAddress("https://platform.canary.enjin.io")
            .Build();
    client->Auth("Your_Platform_Token_Here");

    // Send the request then get the response and write the output to the console.
    // Only the fields that were requested in the fragment will be filled in,
    // other fields which weren't requested in the fragment will be set to null.
    future<PlatformResponsePtr<GraphQlResponse<AccountRequest>>> futureResponse = SendRequestAccount(*client, requestAccount);

    // Get the platform response holding the HTTP data
    PlatformResponsePtr<GraphQlResponse<AccountRequest>> response = futureResponse.get();

    // Get the result, a GraphQL response, holding the GraphQL data
    const optional<GraphQlResponse<AccountRequest>>& gqlResult = response->GetResult();

    // Write the result data to the console
    if (gqlResult.has_value() && gqlResult->IsSuccess())
    {
        const optional<AccountRequest>& getAccountRequestResult = gqlResult->GetData()->GetResult();

        std::cout << getAccountRequestResult->GetVerificationId().value() << std::endl;
    }

    // Write any error messages to the console
    if (gqlResult.has_value() && gqlResult->HasErrors())
    {
        const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();

        for (const GraphQlError& error : errors.value()) {
            std::cout << error.GetMessage().value() << std::endl;
        }
    }

    client.reset();

    return 0;
}

fetch('https://platform.canary.enjin.io/graphql', {
  method: 'POST',
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
  body: JSON.stringify({
    query: `
      query RequestAccount{
        RequestAccount{
          qrCode #Returns a QR code for your user to scan
          verificationId #Save this for next step
        }
      }
    `
  }),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');

axios.post('https://platform.canary.enjin.io/graphql', {
  query: `
    query RequestAccount{
      RequestAccount{
        qrCode #Returns a QR code for your user to scan
        verificationId #Save this for next step
      }
    }
  `
}, {
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests

query = `'''
query RequestAccount{
  RequestAccount{
    qrCode #Returns a QR code for your user to scan
    verificationId #Save this for next step
  }
}
'''`

response = requests.post('https://platform.canary.enjin.io/graphql',
  json={'query': query},
  headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())

Response:

{
  "data": {
    "RequestAccount": {
      "qrCode": "https://platform.canary.enjin.io/qr?s=512&f=png&d=https://platform.canary.enjin.io/proof/MHg3OGFmYWIxYWQxMjk0YzFlZWY4MjdlNmFjNTM1MmJiOTVmNmFmNWJhNmUyNjk5ZGRkOTI3YjAwNmQ3ZDk0MzZjO2Vwc3I6QTIwMTBBSzlM",
      "verificationId": "0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c"
    }
  }
}

The response provides you with a QR code that you will need to get your user to scan using the Enjin Wallet.
When the user scans the QR they are asked to choose a wallet address to verify.
Once verified, you can start safely sending tokens and requests to their wallet address via the API.

Step 2: Verify Account

Once the user has scanned the QR code using the Enjin Wallet, you can retrieve the account using two methods.

Option A: GetWallet

Using GetWallet and passing the verificationId from step 1, you will be able to get any information related to his wallet if the verification process succeeded.

Query:

query GetWallet{
  GetWallet(verificationId: "0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c"){ #Set the verificationId from the RequestAccount response
    account{
      address
    }
    balances{
      free
    }
  }
}
using System.Text.Json;
using Enjin.Platform.Sdk;

// Setup the query
var getWallet = new GetWallet()
    .SetVerificationId("0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c");

// Define and assign the return data fragment to the query
var walletFragment = new WalletFragment()
    .WithAccount(new AccountFragment()
        .WithAddress()
    )
    .WithBalances(new BalancesFragment()
        .WithFree()
    );

getWallet.Fragment(walletFragment);

// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
    .SetBaseAddress("https://platform.canary.enjin.io")
    .Build();
client.Auth("Your_Platform_Token_Here");

// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendGetWallet(getWallet);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));

#include "EnjinPlatformSdk/CoreQueries.hpp"
#include <iostream>

using namespace enjin::platform::sdk;
using namespace std;

int main() {

    // Set up the query
    GetWallet getWallet = GetWallet()
            .SetVerificationId(make_shared<SerializableString>("0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c"));

    // Define and assign the return data fragments to the query
    AccountFragment accountFragment = AccountFragment()
            .WithAddress();
    BalancesFragment balancesFragment = BalancesFragment()
            .WithFree();
    WalletFragment walletFragment = WalletFragment()
            .WithAccount(make_shared<AccountFragment>(accountFragment))
            .WithBalances(make_shared<BalancesFragment>(balancesFragment));

    getWallet.SetFragment(make_shared<WalletFragment>(walletFragment));

    // Create and auth a client to send the request to the platform
    unique_ptr<PlatformClient> client = PlatformClient::Builder()
            .SetBaseAddress("https://platform.canary.enjin.io")
            .Build();
    client->Auth("Your_Platform_Token_Here");

    // Send the request then get the response and write the output to the console.
    // Only the fields that were requested in the fragment will be filled in,
    // other fields which weren't requested in the fragment will be set to null.
    future<PlatformResponsePtr<GraphQlResponse<Wallet>>> futureResponse = SendGetWallet(*client, getWallet);

    // Get the platform response holding the HTTP data
    PlatformResponsePtr<GraphQlResponse<Wallet>> response = futureResponse.get();

    // Get the result, a GraphQL response, holding the GraphQL data
    const optional<GraphQlResponse<Wallet>>& gqlResult = response->GetResult();

    // Write the result data to the console
    if (gqlResult.has_value() && gqlResult->IsSuccess())
    {
        const optional<Wallet>& getWalletResult = gqlResult->GetData()->GetResult();

        std::cout << getWallet.GetName() << std::endl;
    }

    // Write any error messages to the console
    if (gqlResult.has_value() && gqlResult->HasErrors())
    {
        const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();

        for (const GraphQlError& error : errors.value()) {
            std::cout << error.GetMessage().value() << std::endl;
        }
    }

    client.reset();

    return 0;
}

fetch('https://platform.canary.enjin.io/graphql', {
  method: 'POST',
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
  body: JSON.stringify({
    query: `
      query GetVerifiedWallet($verification_id: String!) {
        GetWallet(verificationId: $verification_id) {
          account{
            address
          }
          balances{
            free
          }
        }
      }
    `,
    variables: {
      verification_id: "0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c" //Set the verificationId from the RequestAccount response
    }
  }),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');

axios.post('https://platform.canary.enjin.io/graphql', {
  query: `
    query GetVerifiedWallet($verification_id: String!) {
      GetWallet(verificationId: $verification_id) {
        account{
          address
        }
        balances{
          free
        }
      }
    }
  `,
  variables: {
    verification_id: "0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c" //Set the verificationId from the RequestAccount response
  }
}, {
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests

query = '''
query GetVerifiedWallet($verification_id: String!) {
  GetWallet(verificationId: $verification_id) {
    account{
      address
    }
    balances{
      free
    }
  }
}
'''

variables = {
  'verification_id': "0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c" #Set the verificationId from the RequestAccount response
}

response = requests.post('https://platform.canary.enjin.io/graphql',
  json={'query': query, 'variables': variables},
  headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())

Response: If user has verified

{
  "data": {
    "GetWallet": {
      "account": {
        "address": "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" //The address of the verified account
      },
      "balances": {
        "free": "86010842630734264894" // The amount of free ENJ in the verified account - ~86.0108 ENJ
      }
    }
  }
}

📘

Balances Format

API balances fields are formatted as u128 number type.
to get decimal value, divide the value by 10^18.

Response: If user has not verified

{
  "data": {
    "GetWallet": null
  }
}

Option B: GetAccountVerified

This query can be used to fetch the status of the verification, while you are showing the QR code to the player, for example, when the query returns "verified": true you could hide the QR code and proceed with your onboarding workflow.

Query:

query GetAccountVerified{
  GetAccountVerified(verificationId: "0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c"){ #Set the verificationId from the RequestAccount response
    verified
    account{
      publicKey
      address
    }
  }
}
using System.Text.Json;
using Enjin.Platform.Sdk;

// Setup the query
var getAccountVerified = new GetAccountVerified()
    .SetVerificationId("0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c");

// Define and assign the return data fragment to the query
var accountVerifiedFragment = new AccountVerifiedFragment()
    .WithVerified()
    .WithAccount(new AccountFragment()
        .WithPublicKey()
        .WithAddress()
    );

getAccountVerified.Fragment(accountVerifiedFragment);

// Create and auth a client to send the request to the platform
var client = PlatformClient.Builder()
    .SetBaseAddress("https://platform.canary.enjin.io")
    .Build();
client.Auth("Your_Platform_Token_Here");

// Send the request and write the output to the console.
// Only the fields that were requested in the fragment will be filled in,
// other fields which weren't requested in the fragment will be set to null.
var response = await client.SendGetAccountVerified(getAccountVerified);
Console.WriteLine(JsonSerializer.Serialize(response.Result.Data));
#include "EnjinPlatformSdk/CoreQueries.hpp"
#include <iostream>

using namespace enjin::platform::sdk;
using namespace std;

int main() {

    // Set up the query
    GetAccountVerified getAccountVerified = GetAccountVerified()
            .SetVerificationId(make_shared<SerializableString>("0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c"));

    // Define and assign the return data fragments to the query
    AccountFragment accountFragment = AccountFragment()
            .WithPublicKey()
            .WithAddress();
    AccountVerifiedFragment accountVerifiedFragment = AccountVerifiedFragment()
            .WithVerified()
            .WithAccount(make_shared<AccountFragment>(accountFragment));

    getAccountVerified.SetFragment(make_shared<AccountVerifiedFragment>(accountVerifiedFragment));

    // Create and auth a client to send the request to the platform
    unique_ptr<PlatformClient> client = PlatformClient::Builder()
            .SetBaseAddress("https://platform.canary.enjin.io")
            .Build();
    client->Auth("Your_Platform_Token_Here");

    // Send the request then get the response and write the output to the console.
    // Only the fields that were requested in the fragment will be filled in,
    // other fields which weren't requested in the fragment will be set to null.
    future<PlatformResponsePtr<GraphQlResponse<AccountVerified>>> futureResponse = SendGetAccountVerified(*client, getAccountVerified);

    // Get the platform response holding the HTTP data
    PlatformResponsePtr<GraphQlResponse<AccountVerified>> response = futureResponse.get();

    // Get the result, a GraphQL response, holding the GraphQL data
    const optional<GraphQlResponse<AccountVerified>>& gqlResult = response->GetResult();

    // Write the result data to the console
    if (gqlResult.has_value() && gqlResult->IsSuccess())
    {
        const optional<AccountVerified>& getAccountVerifiedResult = gqlResult->GetData()->GetResult();

        std::cout << getAccountVerifiedResult->GetVerified().value() << std::endl;
    }

    // Write any error messages to the console
    if (gqlResult.has_value() && gqlResult->HasErrors())
    {
        const optional<vector<GraphQlError>>& errors = gqlResult->GetErrors();

        for (const GraphQlError& error : errors.value()) {
            std::cout << error.GetMessage().value() << std::endl;
        }
    }

    client.reset();

    return 0;
}

fetch('https://platform.canary.enjin.io/graphql', {
  method: 'POST',
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'},
  body: JSON.stringify({
    query: `
      query GetAccountVerified($verification_id: String!) {
        GetAccountVerified(verificationId: $verification_id) {
          verified
          account{
            publicKey
            address
          }
        }
      }
    `,
    variables: {
      verification_id: "0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c" //Set the verificationId from the RequestAccount response
    }
  }),
})
.then(response => response.json())
.then(data => console.log(data));
const axios = require('axios');

axios.post('https://platform.canary.enjin.io/graphql', {
  query: `
    query GetAccountVerified($verification_id: String!) {
      GetAccountVerified(verificationId: $verification_id) {
        verified
        account{
          publicKey
          address
        }
      }
    }
  `,
  variables: {
    verification_id: "0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c" //Set the verificationId from the RequestAccount response
  }
}, {
  headers: {'Content-Type': 'application/json','Authorization': 'Your_Platform_Token_Here'}
})
.then(response => console.log(response.data))
.catch(error => console.error(error));
import requests

query = '''
query GetAccountVerified($verification_id: String!) {
  GetAccountVerified(verificationId: $verification_id) {
    verified
    account{
      publicKey
      address
    }
  }
}
'''

variables = {
  'verification_id': "0x78afab1ad1294c1eef827e6ac5352bb95f6af5ba6e2699ddd927b006d7d9436c" #Set the verificationId from the RequestAccount response
}

response = requests.post('https://platform.canary.enjin.io/graphql',
  json={'query': query, 'variables': variables},
  headers={'Content-Type': 'application/json', 'Authorization': 'Your_Platform_Token_Here'}
)
print(response.json())

Response: If user has verified

{
  "data": {
    "GetAccountVerified": {
      "verified": true,
      "account": {
        "publicKey": "0x5a6aae294416f3e875d9a8975658905002cfd3e5e64105d76296c4b0adbfd77e", //The public key of the verified account
        "address": "cxLU94nRz1en6gHnXnYPyTdtcZZ9dqBasexvexjArj4V1Qr8f" //The address of the verified account
      }
    }
  }
}

Response: If user has not verified

{
  "data": {
    "GetAccountVerified": {
      "verified": false,
      "address": null
    }
  }
}

📘

More Fields and Arguments Available!

While the examples here cover the core functionalities of the requesting accounts and getting their wallets, there are a few more settings you can adjust.

To view and understand all the available settings for these operations, refer to our GraphQL Schema on Apollo.

These resources will guide you in tailoring these operations to your specific requirements.