Kaia Account Migration
This document is a reference for those who want to migrate their DApps from their individual ENs to KAS. It will mainly deal with the differences between using EN and KAS.
Steps for Migration
-
Sign up on KAS, generate authentication key
: Before you can use KAS, you have to sign up and generate an API authentication key. For more information, please refer to this link:
Sign Up, Auth, Permission, SDK
Note) Using this authentication key directly in the frontend code can be very risky in terms of security. Use it on a backend server with limited access.
-
Add the authentication key to the existing codes
: All APIs on KAS can be called via HTTP. And these calls must contain authentication data in the headers. Once that call is made, it will look something like this with caver.js:
const accessKeyId = "{{your_accessKeyId}}"; const secretAccessKey = "{{your_secretAccessKey}}"; const option = { headers: [ {name: 'Authorization', value: 'Basic ' + Buffer.from(accessKeyId + ':' + secretAccessKey).toString('base64')}, {name: 'x-chain-id', value: '8217'}, ] } const caver = new Caver(new Caver.providers.HttpProvider("https://node-api.klaytnapi.com/v1/klaytn", option))
- Migrate the old key : If you have been using EN as a keystore instead of an individual wallet, you may also have to migrate your old key. In order to use your old key on KAS, you need a separate Wallet API, which also contains the API for migrating old keys. Please contact support@klaytnapi.com.
- Additional modifications : There are certain JSON RPC APIs supported by an average EN but not on KAS. If you are using any of these APIs, you may have to make certain modifications to the API. You can find out whether your JSON RPC API is supported or not in this link: JSON-RPC API
For any other issues or inquiries, you can visit our KAS Forum, or contact us by email at support@klaytnapi.com.
Migrating with KAS SDK
To migrate your Kaia accounts to KAS, you can either use KAS SDK or write your own migration code.
The below example demonstrates how you can use KAS SDK.
const keyring = caver.keyringContainer.keyring.generate();
const address = keyring.address;
const key = keyring.key.privateKey;
const ret = await caver.kas.wallet.migrateAccounts([
{ address, key, nonce: 0 },
]);
// You can use it without entering the nonce manually as shown below.
// If you do not manually enter the nonce value, it will automatically be filled in during the migration process.
// const ret = await caver.kas.wallet.migrateAccounts([{ address, key }])
ArrayList<MigrationAccount> accountsToBeMigrated = new ArrayList<>();
SingleKeyring keyring = KeyringFactory.generate();
String address = keyring.getAddress();
String key = keyring.getKey().getPrivateKey();
String nonce = "0x0";
MigrationAccount migrationAccount = new MigrationAccount(address, key, nonce);
// You can use it without entering the nonce manually as shown below. If you do not manually enter the nonce value, it will automatically be filled in during the migration process.
// MigrationAccount migrationAccount = new MigrationAccount(address, key);
accountsToBeMigrated.add(migrationAccount);
RegistrationStatusResponse response = caver.kas.wallet.migrateAccounts(accountsToBeMigrated);
Migrating with REST API
Creating a Public Key
In order to migrate your Kaia accounts to KAS, you need to update the accounts using the public key managed by KAS. To generate a public key to be managed by KAS, use Create Key API. You can create up to 100 public keys at a time. Pass the desired number of keys as size
parameter.
API Request
curl --location --request POST 'https://wallet-api.klaytnapi.com/v2/key' \
--header 'x-chain-id: 1001' \
-u {access-key-id}:{secret-access-key} \
--header 'Content-Type: application/json' \
--data-raw '{
"size": 1
}'
API Response
The response for Create Key API is shown below:
// Example response for a generated key
{
"items": [
{
"blob": "0x43bfd97caaeacc818cd6b62abccf21de569649f31f644142eb1fcfd5beb69e61",
"keyId": "krn:1001:wallet:test:account-pool:default:0xd80ff4019cfd96f0812adece82dd956c5e781b79ca707cb5e957c97f27593221",
"krn": "krn:1001:wallet:test:account-pool:default",
"publicKey": "0x04a081eaf8603b9be528b86da338ba8051bfc073876dbdf00f5161b393b5735f85a76634ea38c43fbbc5d7a630b76ca2a1d81d446debc937b24a77eb3b352a1b6d"
}
]
}
Creating Account Update Transaction
You have to create an account update transaction with the key from your old account.
danger
Make sure to use Fee Delegation Account Update Transaction from Public Key Type. Creating account update transations with key types other than the public key type may prevent you from using your account.
If you wish to use multisig account, first complete the procedures for migration and then make the changes using Wallet API's Multisig Account Update API.
API Request
// In order to migrate Kaia account to KAS Wallet API, you have to create a transaction and sign it before sending it to KAS.
// In order to sign the transaction, create a Keyring instance with Kaia account and add it to KeyringContainer.
// If a Kaia account's key is either `AccountKeyWeigthedMultiSig`or `AccountKeyRoleBased`,
// pass the second parameter of `keyringContainer.keyring.create` as array or double-array.
// For more details, please refer to https://docs.kaia.io/references/sdk/caver-js/api/caver-wallet/keyring/#caverwalletkeyringcreate-
const keyringContainer = new caver.keyringContainer();
const keyring = keyringContainer.keyring.create(
"0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3",
"0x{private key}"
);
keyringContainer.add(keyring);
// Create key for KAS Wallet API
// `caver.kas.wallet.createKeys` returns the following values.
// {
// items: [
// { blob: '0x06000...', keyId: 'krn:1001:...', krn: 'krn:1001:...', publicKey: '0x0400e...', },
// ],
// }
const createdKeys = await caver.kas.wallet.createKeys(1);
const key = createdKeys.items[0];
// FeeDelegatedAccountUpdate Create transation.
// The value assigned to `account` field can be created using `caver.account.createWithAccountKeyPublic`.
// Address of the account to be migrated, public key (in the form of public key string) and KAS Wallet API must be passed as parameters.
const updateTx = new caver.transaction.feeDelegatedAccountUpdate({
from: keyring.address,
account: caver.account.createWithAccountKeyPublic(
keyring.address,
key.publicKey
),
gas: 1000000,
});
// Sign transaction.
await keyringContainer.sign(keyring.address, updateTx);
const result = {
keyId: key.keyId,
address: keyring.address,
rlp: updateTx.getRLPEncoding(),
};
// In order to migrate your Kaia account to KAS Wallet API, you have to create and sign a transaction before sending it to KAS.
// In order to sign the transaction, create a Keyring instance with the Kaia account and pass it as a parameter when signing the transaction.
// If a Kaia account's key is either `AccountKeyWeigthedMultiSig`or `AccountKeyRoleBased`,
// pass the second parameter of `KeyringFactory.create` as a String[] or a List<String[]>.
// For more details, please refer to https://javadoc.io/doc/com.klaytn.caver/core/latest/com/klaytn/caver/wallet/keyring/KeyringFactory.html.
AbstractKeyring keyring = KeyringFactory.create("0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3", "0x{private key}");
// Create key for KAS Wallet API
// `caver.kas.wallet.createKeys` returns the following values.
// {
// items: [
// { blob: '0x06000...', keyId: 'krn:1001:...', krn: 'krn:1001:...', publicKey: '0x0400e...', },
// ],
// }
KeyCreationResponse keyCreationResponse = caver.kas.wallet.createKeys(1);
List<Key> createdKeys = keyCreationResponse.getItems();
Key key = createdKeys.get(0);
// Create the FeeDelegatedAccountUpdate transaction.
// The value assigned to `account` field can be created using `caver.account.createWithAccountKeyPublic`.
// Address of the account to be migrated, public key (in the form of public key string) and KAS Wallet API must be passed as parameters.
FeeDelegatedAccountUpdate updateTx = caver.transaction.feeDelegatedAccountUpdate.create(
TxPropertyBuilder.feeDelegatedAccountUpdate()
.setFrom(keyring.getAddress())
.setAccount(
caver.account.createWithAccountKeyPublic(
keyring.getAddress(),
key.getPublicKey()
)
)
.setGas(BigInteger.valueOf(1000000))
);
// Sign the transaction.
updateTx.sign(keyring);
System.out.println("keyId: " + key.getKeyId());
System.out.println("address: " + keyring.getAddress());
System.out.println("rlp: " + updateTx.getRLPEncoding());
Account Migration
You can run the account migration process based on the account update transaction results from the previous section. For a quick reminder before calling the API:
{
"keyId": "krn:1001:wallet:test:account-pool:default:0xd80ff4019cfd96f0812adece82dd956c5e781b79ca707cb5e957c97f27593221",
"address": "0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3",
"rlp": "0x...."
}
API Request
curl --location --request POST 'https://wallet-api.klaytnapi.com/v2/registration/account' \
--header 'x-chain-id: 1001' \
-u {access-key-id}:{secret-access-key} \
--header 'Content-Type: application/json' \
--data-raw '[
{
"keyId": "krn:1001:wallet:test:account-pool:default:0xd80ff4019cfd96f0812adece82dd956c5e781b79ca707cb5e957c97f27593221",
"address": "0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3",
"rlp": "0x..."
}
]'
API Response
// Success
{
"status": "ok"
}
// Failure
{
"failures": {
"0xc756f6809bc34c2458fcb82fb16d5add3dbad9e3": "failed to send a raw transaction to klaytn node; -32000::invalid transaction v, r, s values of the sender"
},
"status": "all failed"
}
For more details regarding this API, please refer to here. For any inquiries regarding this document or KAS in general, please visit KAS Developers Forum.