Migration guide for Wallets

This guide is only for existing API users that create WHITE_LABEL wallets. Learn how to migrate your wallets to non-custodial state.

Who needs to migrate?

This guide is ONLY for existing Wallet-API users that create WHITE_LABEL wallets (custodial wallets).

Users who create UNRECOVERABLE_WHITE_LABEL wallets (non-custodial) don't need to migrate.

Why do you need to migrate?

Migration is essential because all wallets must transition to a non-custodial state (from Venly's perspective). This implies that Venly will no longer have the capability to retrieve wallets in case your end-users misplace the PIN codes.

You can still choose to be the custodial where you manage the PIN code (access to wallets) on behalf of your end-users. From Venly's perspective, all wallets need to migrate to non-custodial by the end of 2023.

⚠️DEADLINE!

🚧

Starting in January 2024, transactions will no longer be permitted on custodial wallets (WHITE_LABEL). Nevertheless, you will still have the ability to MIGRATE your custodial wallets to non-custodial ones using one of the following options.

Migration Flow Chart

Migration Options Flow Chart

Migration Options Flow Chart

Option #1 (For Custodial)

This option is for users who are custodial (whose end-users are not exposed to the PIN code). This is the quickest and easiest way to migrate all your wallets with a single script, but carefully read the following disclaimer!

🚧

Migration to non-custodial means that Venly CANNOT DO PIN RESETS anymore.

You can migrate all your wallets to non-custodial with a one-time script using the following endpoint (need to run this for every wallet you own):

Request Endpoint: reference

PATCH /api/wallets/{id}/walletType

Path Parameter:

{id}: This is the wallet ID.

Request Body Parameters:

ParameterTypeRequiredDescription
pincodestringThis is the wallet's PIN code.
custodialbooleanThis property can only be set to false to migrate a wallet to non-custodial.

Request Body:

{
     "pincode": "213123",
     "custodial": false
}

🚧

After running this script, Venly cannot perform PIN resets, unless you create emergency codes by following Option#2.

Option #2 (Recommended)

The second option to migrate includes creating a user, setting up their emergency code (optional), and linking the wallets to users.

The responsibility for wallet recovery will shift to the end-users themselves, hence the introduction of the user concept and the necessity for an emergency code, which can be used to reset a forgotten PIN code.

🚧

Linking the wallets to users will automatically migrate the wallets to non-custodial state (from Venly's perspective). This means Venly CANNOT RECOVER wallets anymore! (Unless you create emergency codes)

Migration Flow

1. Create User

You can create one or multiple users using the same flow. Each of your end-user will correspond to one user created.

If you create only one user and link all wallets to it, then all wallets will be accessible with the signing methods you create for this user.

📘

Signing method is like a password and its used to unlock the wallet for the user. The signing method can also be used to for authenticating calls and executing transactions.

Each user can have multiple signing methods which are: PIN code, Emergency Code, and Biometric.

For this example, we will create a PIN signing method along with creating a user.

📘

The first signing method must always be PIN.

To create a user, call the following endpoint:

Request Endpoint: reference

POST /api/users

Request Body Parameters:

ParameterTypeRequiredDescription
referencestringYou can provide a reference (can be whatever you want) to distinguish between users.
signingMethodobjectThis object contains the type of signing method and it’s value.
typestringThis parameter indicates the type of signing method. (e.g., PIN, EMERGENCY_CODE, BIOMETRIC.)
The first signing method should always be a PIN.
valuestringThis is the value of your signing method. For example, the value for PIN can be “638601”.

Request Body:

{
  "reference": "ABD User 1",
  "signingMethod": {
    "type": "PIN",
    "value": "123456"
  }
}

User Interaction:

You can create a screen where the user can enter their PIN code of choice. This PIN code will be the user's signing method, which is used for authentication and signing transactions.

📘

We recommend that you ask your users to input the same PIN as their existing wallets pincode. Your users can also choose a different PIN, but remember that this PIN will be updated for the user's wallet as well.

Enter PIN Screenshot

Enter PIN Screenshot

Response Body:

📘

Save the following parameters from the response body. They will be used later in the guide.

  • result.id: This is the User ID. Every user you create will have a unique user ID.
  • signingMethods.id: This is the signing method ID and will be used for authentication purposes. Every signing method will have a unique ID.

📘

We recommend to save the PIN signing method ID since it is used during the PIN reset process.

{
  "success": true,
  "result": {
    "id": "e85470a8-5deb-41f6-be6c-de693683a22c",
    "reference": "ABD User 1",
    "createdAt": "2023-08-02T07:18:58.624685414",
    "signingMethods": [
      {
        "id": "4658c064-05b9-4bbd-9f0e-68a9588c7bc3",
        "type": "PIN",
        "incorrectAttempts": 0,
        "remainingAttempts": 10,
        "hasMasterSecret": true
      }
    ]
  }
}

2. Create Emergency Code (optional but recommended)

  1. If PIN code functionality is exposed to the user (where users choose their own PIN) --> EMERGENCY_CODE is recommended
  2. If you are the custodial -->EMERGENCY_CODE is optional (but still recommended)

In this example, we will create an additional emergency code signing method. (PIN signing method already exists for user)

This emergency code can be used to:

  • Reset a forgotten PIN code
  • Sign transactions
  • Authenticate calls

📘

When creating a signing method for a user for the first time, you don’t have to provide another one. When creating additional signing methods, you will have to provide an existing valid signing method in the header.

Call the following endpoint to create an emergency code:

Request Endpoint: reference

POST /api/users/{userId}/signing-methods

Path Parameters:

{userId} : This is the User ID whose signing method you want to create. Paste the previously saved User ID here.

Header Parameters:

For this example, the user already has an existing PIN signing method, that's why we are providing the PIN signing method in the header request to authenticate the call.

ParameterValueDescription
Signing-Methodid:value

  • id: This is the ID of the signing method
  • value: This is the value of the signing method

Request Body Parameters:

ParameterTypeDescription
typestringThis parameter indicates the type of signing method. (e.g., PIN, EMERGENCY_CODE, BIOMETRIC.)
valuestringThis is the value of your signing method. For example, the value for EMERGENCY_CODE can be “w2v7yertaad21lhudqghzwcg4”.
To autogenerate the emergency code, this field can be removed.

The body does not contain the value property because we want to autogenerate the emergency code.

{
  "type": "EMERGENCY_CODE"
}

Response Body:

📘

It is IMPORTANT to save the PIN signing method ID since it is used during the PIN reset process.

Description of parameters:

  • result.id: This is the signing method ID
  • result.value: This is the value of the generated emergency code
{
  "success": true,
  "result": {
    "id": "3eccfcef-467a-42a6-8b6b-6ffce3b3b115",
    "type": "EMERGENCY_CODE",
    "incorrectAttempts": 0,
    "remainingAttempts": 10,
    "value": "taif7dxjikhtb82zm7u93tn26",
    "hasMasterSecret": true
  }
}

User Interaction:

You need to create a screen where the user can enter their PIN code to authenticate the call. The screen should also display the emergency code from the response body so your user can safely save it.

Save Emergency Code Screenshots

Save Emergency Code Screenshots

3. Link Wallet to User

This is the final step. Linking an existing wallet to your user will automatically convert it to a non-custodial wallet (from Venly's perspective).

🚧

After running this endpoint, Venly can no longer recover lost wallets! This is why we recommend creating the emergency code for your users, so their PIN can be reset if forgotten.

To link an existing wallet to a user, use the endpoint:

Request Endpoint: reference

PUT /api/wallets/{id}/user

Path Parameters:

{id} : This is the wallet ID of the wallet you want to link with a User.

Header Parameters:

Provide the User's Signing-Method in the header request to authenticate the call.

ParameterValueDescription
Signing-Methodid:value

  • id: This is the ID of the signing method
  • value: This is the value of the signing method

Request Body Parameters:

In the request body you should provide:

  1. pincode of the existing wallet
  2. userId of the user you want to link the wallet to

👍

This way the wallet’s PIN will be updated to match the user’s PIN signing method and the wallet will be linked to the specified user.

🚧

After running this endpoints, the wallet will only be accessible with the user's PIN signing method. The wallet's pincode will be replaced with user;s signing method.

Request Body:

{
  "pincode": "123456",
  "userId": "e85470a8-5deb-41f6-be6c-de693683a22c"
}

How we do it as Venly

  1. When a user logs in, we check if their wallet is custodial or non-custodial.
  2. If their wallet is custodial, we prompt them that they need to migrate. If they are already non-custodial, they can continue to use their wallet.
  3. We always create an emergency code for our users, and we recommend you to do the same.
  4. We add instructions on how users can safely store their emergency code.
  5. Next, we prompt them to enter their PIN again for confirmation.
  6. Next, we display the emergency code to them and add a checkbox to verify that the user has safely secured the emergency code.
  7. The final screen can display a message saying, "You have migrated successfully!"
Venly Migration Flow Screenshots

Venly Migration Flow Screenshots

How to reset a PIN code

The main goal of the signing methods is for users to have different means to recover their wallets (reset PIN code). In case your user's PIN code is lost, it can be updated by providing another valid signing method (such as an emergency code).

For example, if a user forgets their PIN, the endpoint can be called using the PIN signing method ID and the user's ID within the URL path. To authenticate, include a header that holds a valid alternate Signing-Method, which could be an emergency code or biometric.

The request body will contain the new PIN value, indicated by the value parameter.

That’s done through the endpoint:

Request Endpoint: reference

PUT /api/users/{userId}/signing-methods/{signingMethodId}

Path Parameters:

{userId} : This is the ID of the User whose PIN you want to reset

{signingMethodId}: This is the ID of the User's PIN signing method

Header Parameters:

Provide the User's Signing-Method (emergency code) in the header request to authenticate the call. In this case we are resetting the PIN, so you need to provide either the emergency code or biometric signing method here.

ParameterValueDescription
Signing-Methodid:value

  • id: This is the ID of the signing method
  • value: This is the value of the signing method

Request Body:

  • value: This will the updated PIN code value
{
  "value": "987654"
}

Response Body:

{
  "success": true,
  "result": {
    "id": "4658c064-05b9-4bbd-9f0e-68a9588c7bc3",
    "type": "PIN",
    "incorrectAttempts": 0,
    "remainingAttempts": 10,
    "lastUsedSuccess": "2023-08-02T12:34:57.63061",
    "hasMasterSecret": true
  }
}

👍

You have successfully reset the PIN code!

FAQs

Question#1: Can we no longer create custodial wallets?

From Venly's perspective, all wallets will be non-custodial. You can still choose to create custodian wallets (manage the PIN resets for your end users) or non-custodial wallets.

Question#2: Any API changes required after our end-users migrate?

No, only the migration is needed. The only API change is that you would need to remove the type: WHITE_LABEL when creating new wallets.

Question#3: Do my end-users need to store all the signing methods?

Yes, if going full non-custodial (only the end-user has access). It is the end-user's responsibility to store and safeguard the signingmethods.

Question#4: What's the migration timeline and what happens to wallets that haven't migrated after the deadline?

On 1st of JAN 2024, no transactions are possible anymore on custodial wallets. Any remaining custodial wallets will NEVER be deleted. Only transactions are blocked for them. You are still able to migrate them after this date, and once migrated (non-custodial), can use them as normal.

When creating new wallets, the type: WHITE_LABEL will not be allowed anymore after JAN 2024.

Question#5: For Widget B2B users - what needs to be done from their end?

Nothing needs to be done for our Widget B2B users.