Single-Token Storage Account
1
Account Setup and Initial State
async function main() {
const seed = KeetaNet.lib.Account.generateRandomSeed({ asString: true });
console.log("seed =", seed);
const account = KeetaNet.lib.Account.fromSeed(seed, 0);
const userClient = KeetaNet.UserClient.fromNetwork("test", account);
console.log("account.publicKey =", account.publicKeyString.toString());
console.log("account.storageAccounts[] =", (await userClient.listACLsByPrincipal()).filter(acl => acl.entity.isStorage()));
}2
Creating a Basic Storage Account
async function createStorageAccount(userClient: KeetaNet.UserClient) {
const builder = userClient.initBuilder();
const pendingStorageAccount = builder.generateIdentifier(KeetaNet.lib.Account.AccountKeyAlgorithm.STORAGE);
await builder.computeBlocks();
const storageAccount = pendingStorageAccount.account;
builder.setInfo({
name: '',
description: '',
metadata: '',
defaultPermission: new KeetaNet.lib.Permissions(['STORAGE_DEPOSIT'])
}, { account: storageAccount });
await userClient.publishBuilder(builder);
return storageAccount;
}3
Examining Account State and Permissions
console.log("storageAccount.acls[] =", (await userClient.listACLsByEntity({ account: storageAccount })).map(acl => ({
entity: acl.entity.publicKeyString.toString(),
principal: acl.principal.publicKeyString.toString(),
target: acl.target.publicKeyString.toString(),
permissions: acl.permissions.base.flags,
})));
console.log("storageAccount.defaultPermission =", (await userClient.state({ account: storageAccount })).info.defaultPermission?.base.flags);4
5
Verifying Updated Permissions
console.log("storageAccount.acls[] =", (await userClient.listACLsByEntity({ account: storageAccount })).map(acl => ({
entity: acl.entity.publicKeyString.toString(),
principal: acl.principal.publicKeyString.toString(),
target: acl.target.publicKeyString.toString(),
permissions: acl.permissions.base.flags,
})));Complete Code Example
import * as KeetaNet from "@keetanetwork/keetanet-client";
async function createStorageAccount(userClient: KeetaNet.UserClient) {
// Initialize the user client builder
const builder = userClient.initBuilder();
// Create a new storage account
const pendingStorageAccount = builder.generateIdentifier(KeetaNet.lib.Account.AccountKeyAlgorithm.STORAGE);
// Compute the pending storage account
await builder.computeBlocks();
// Get the storage account
const storageAccount = pendingStorageAccount.account;
console.log("storageAccount.publicKey =", storageAccount.publicKeyString.toString());
// Setting the storage account default permissions
builder.setInfo(
{
name: '',
description: '',
metadata: '',
defaultPermission: new KeetaNet.lib.Permissions([
'STORAGE_DEPOSIT', // Allow everyone to deposit into the storage account
])
},
{ account: storageAccount }
);
// Publish the builder to create the storage account
await userClient.publishBuilder(builder);
return storageAccount;
}
async function main() {
const seed = KeetaNet.lib.Account.generateRandomSeed({ asString: true });
console.log("seed =", seed);
const account = KeetaNet.lib.Account.fromSeed(seed, 0);
const userClient = KeetaNet.UserClient.fromNetwork("test", account);
console.log("account.publicKey =", account.publicKeyString.toString());
console.log("account.storageAccounts[] =", (await userClient.listACLsByPrincipal()).filter(acl => acl.entity.isStorage()));
/**
* Create a new storage account with default permissions allowing deposits.
*
* This will allow anyone to deposit into the storage account, but won't
* allow the storage account to hold any tokens.
*/
const storageAccount = await createStorageAccount(userClient);
console.log("storageAccount.publicKey =", storageAccount.publicKeyString.toString());
console.log("storageAccount.acls[] =", (await userClient.listACLsByEntity({ account: storageAccount })).map(acl => ({
entity: acl.entity.publicKeyString.toString(),
principal: acl.principal.publicKeyString.toString(),
target: acl.target.publicKeyString.toString(),
permissions: acl.permissions.base.flags,
})));
console.log("");
console.log("storageAccount.defaultPermission =", (await userClient.state({ account: storageAccount })).info.defaultPermission?.base.flags);
console.log("");
// Keeta (KTA) base token account
const tokenAccount = userClient.baseToken;
/**
* Add permission to allow the storage account to hold the base token (Keeta - KTA).
*/
await userClient.updatePermissions(
tokenAccount,
new KeetaNet.lib.Permissions(['STORAGE_CAN_HOLD']),
undefined,
KeetaNet.lib.Block.AdjustMethod.ADD,
{ account: storageAccount }
)
console.log("storageAccount.acls[] =", (await userClient.listACLsByEntity({ account: storageAccount })).map(acl => ({
entity: acl.entity.publicKeyString.toString(),
principal: acl.principal.publicKeyString.toString(),
target: acl.target.publicKeyString.toString(),
permissions: acl.permissions.base.flags,
})));
/**
* If you try to send tokens that are not the base token (KTA) to the storage account,
* it will fail with an error:
* "XX does not have required permissions to perform action on YY/undefined -- needs [STORAGE_CAN_HOLD, ACCESS]/[]"
*
* But if you try to send the base token (KTA) to the storage account, it will succeed.
*/
}
main().then(() => {
console.log("Done");
process.exit(0);
}).catch((err) => {
console.error("Error:", err);
process.exit(1);
});Last updated