Skip to main content

Using Managed Wallets

Managed wallets provide a seamless experience for your users by allowing you to create and manage blockchain wallets on their behalf. Users don't need to download any special apps or take extra steps, making it easier for them to get started with your application.

This approach offers transparency, allowing users to easily track their digital assets. It simplifies user onboarding and provides clear, immutable on-chain data for tracking tokens, enhancing trust and engagement within your platform.

Here's how the typical flow works:

  1. Managed Wallet Creation: When a new user starts using your application, you initiate the creation of a managed wallet for them, and assign the user's internal ID from your database to the newly created managed wallet. This ensures a consistent link between the user and their wallet.
  2. Asset Management: As the user earns or deposits digital assets within your application, these assets are automatically stored in their managed wallet.
  3. In-App Transactions: Any actions the user performs within your application that involve their wallet (e.g., spending tokens, participating in in-game economies) are executed directly on their managed wallet.
  4. User Withdrawal (Optional): If a user decides they want to take full control of their assets, you can facilitate the transfer of all funds from their managed wallet to their own self-custodial wallet.

This process ensures that users can interact with blockchain assets seamlessly within your application without needing to understand the underlying complexities of blockchain technology or operating his own crypto wallet.

Building a real-time game?

A managed wallet can serve as a player's on-chain cold inventory. For fast-paced games where some items must be used the instant a player taps them (drinking a potion mid-fight), you can pair it with an off-chain hot inventory so consumption never waits on the chain. See Hot & Cold Inventories to understand the pattern.

What you'll need:
  • Some Enjin Coin on Enjin Matrixchain to pay for Transaction Fees. You can obtain cENJ (Canary ENJ) for testing from the built-in Canary faucet in the Platform UI.
  • An Enjin Platform Account.
  • A Collection and a Token to add to the wallet.

SDKs are not yet available

The C# and C++ SDK examples below are out of date and will not work against the current Enjin Platform API. This section will be updated once new SDKs are published. Until then, use the GraphQL, cURL, Javascript, Node.js, or Python examples.

Creating a Managed Wallet

To create a managed wallet, run the CreateManagedWallet mutation with a unique ID as a parameter.

Choose a unique externalId for each player/user that can be cross-referenced later. This unique identifier should be something already associated with the player in your database, such as a player ID or username. By doing so, you will be able to consistently link the Managed Wallet to the respective player.

mutation CreateManagedWallet {
CreateManagedWallet(externalId: "docs-example-player") #Replace this with a unique ID
}
Lost database data?

Recreate the managed wallets by running the CreateManagedWallet mutation again for each of the externalIds. Make sure to use the same Daemon wallet seed and password used to create the managed wallets prior, as managed wallets are derived with the following derivation path: walletSeed/externalId///password

Finding a Managed Wallet

Once a managed wallet is created, use the GetManagedWallet query to look it up by its externalId and retrieve its on-chain publicKey.

You'll need this public key to mint tokens to the wallet, and it can also be used to identify the wallet when signing transactions on its behalf.

Query:

query GetManagedWallet {
GetManagedWallet(network: CANARY, chain: MATRIX, externalId: "docs-example-player") { #Specify the managed wallet's unique ID
publicKey
externalId
}
}

Response:

{
"data": {
"GetManagedWallet": {
"publicKey": "0xded3c8f0296f5ee023f07aa5617fc261bd5991c4474ee775a16ec35c1d1a1e3a",
"externalId": "docs-example-player"
}
}
}

Minting tokens to a Managed Wallet

With the managed wallet's public key in hand, you can mint tokens directly to it by setting it as the recipient.

mutation MintToManagedWallet {
CreateTransaction(
network: CANARY
chain: MATRIX
transaction: {
mintToken: {
recipient: "0xded3c8f0296f5ee023f07aa5617fc261bd5991c4474ee775a16ec35c1d1a1e3a" #The managed wallet's public key, from the GetManagedWallet query
collectionId: 36105 #Specify the collection ID
tokenId: 1 #Token ID to mint
amount: 1 #Amount to mint
}
}
) {
uuid
action
state
}
}

Signing transactions as a Managed Wallet

By default, every transaction the Enjin Platform creates is signed by your Wallet Daemon. To act on a user's behalf instead, you can have the platform sign a transaction with that user's managed wallet.

Both CreateTransaction and CreateBatchTransaction accept two optional arguments for this:

  • signerExternalId — the managed wallet's externalId. This is the most direct option, as you don't need to look the wallet's public key up first.
  • signerAccount — the managed wallet's public key, as returned by GetManagedWallet.

Set either one, and the platform signs that transaction with the corresponding managed wallet instead of the Wallet Daemon. Because these arguments live on CreateTransaction itself, any on-chain action — a transfer, a listing, an attribute change, anything you set on the transaction input — can be performed as a managed wallet.

Transferring tokens from a Managed Wallet

If you followed along with the previous snippets of code, you should have a managed wallet with a token in it. To transfer it out to another wallet, set signerExternalId to the managed wallet and use the transferToken action.

mutation TransferFromManagedWallet {
CreateTransaction(
network: CANARY
chain: MATRIX
signerExternalId: "docs-example-player" #The managed wallet that will sign this transaction
transaction: {
transferToken: {
recipient: "cxLf6yvvtscKrHRfKDphnzsT3eoRY45VbJvqXKub5pmj5mdbQ" #The recipient of the transfer
collectionId: 36105 #Specify the collection ID
tokenId: 1 #Token ID to transfer
amount: 1 #Amount to transfer
}
}
) {
uuid
action
state
}
}

Make sure signerExternalId (or signerAccount) is set to the managed wallet that holds the token being transferred.

Whether you're minting into a managed wallet or transferring out of one, the on-chain transaction emits the usual events on FINALIZED (e.g. MultiTokens.Minted, MultiTokens.Transferred) — with the managed wallet's address as the signer. See Working with Events for how to read them.

Explore More Arguments

For a comprehensive view of all available arguments for queries and mutations, please refer to our API Reference. This resource will guide you on how to use the GraphiQL Playground to explore the full structure and functionality of our API.