Add custom data to a namespace.
Metadata can be attached to namespaces to help users verify the ownership of the registered name. The data attached could include information such as registrant, administrative, or technical contact information.
Imagine that the company ComfyClothingCompany wants to add their information to their namespace cc
so that any user of the network can quickly identify the company’s details.
In this guide, you are going to implement a program to add metadata entries to a namespace.
symbol.xym
to pay for transaction fees, create mosaics and register namespaces.cc
with the ComfyClothingCompany’s account.symbol-cli transaction namespace --sync
Enter namespace name: cc
Do you want to create a root namespace? [y/n]: y
Enter the namespace rental duration: 1000
Enter max_fee (absolute amount): 0
Transaction confirmed.
Key | Value |
---|---|
NAME | ComfyClothingCompany |
info@comfyclothingcompany | |
ADDRESS | ComfyClothingCompany HQ |
PHONE | 000-0000 |
// replace with network type
const networkType = NetworkType.TEST_NET;
// replace with company private key
const companyPrivateKey = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
const companyAccount = Account.createFromPrivateKey(companyPrivateKey, networkType);
// replace with namespace name
const namespaceId = new NamespaceId('cc');
const name = 'ComfyClothingCompany';
const email = 'info@comfyclothingcompany';
const address = 'ComfyClothingCompany HQ';
const phone = '000-0000';
const nameMetadataTransaction = NamespaceMetadataTransaction.create(
Deadline.create(),
companyAccount.address,
KeyGenerator.generateUInt64Key('NAME'),
namespaceId,
name.length,
name,
networkType,
);
const emailMetadataTransaction = NamespaceMetadataTransaction.create(
Deadline.create(),
companyAccount.address,
KeyGenerator.generateUInt64Key('EMAIL'),
namespaceId,
email.length,
email,
networkType,
);
const addressMetadataTransaction = NamespaceMetadataTransaction.create(
Deadline.create(),
companyAccount.address,
KeyGenerator.generateUInt64Key('ADDRESS'),
namespaceId,
address.length,
address,
networkType,
);
const phoneMetadataTransaction = NamespaceMetadataTransaction.create(
Deadline.create(),
companyAccount.address,
KeyGenerator.generateUInt64Key('PHONE'),
namespaceId,
phone.length,
phone,
networkType,
);
// replace with network type
const networkType = symbol_sdk_1.NetworkType.TEST_NET;
// replace with company private key
const companyPrivateKey = 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA';
const companyAccount = symbol_sdk_1.Account.createFromPrivateKey(companyPrivateKey, networkType);
// replace with namespace name
const namespaceId = new symbol_sdk_1.NamespaceId('cc');
const name = 'ComfyClothingCompany';
const email = 'info@comfyclothingcompany';
const address = 'ComfyClothingCompany HQ';
const phone = '000-0000';
const nameMetadataTransaction = symbol_sdk_1.NamespaceMetadataTransaction.create(symbol_sdk_1.Deadline.create(), companyAccount.address, symbol_sdk_1.KeyGenerator.generateUInt64Key('NAME'), namespaceId, name.length, name, networkType);
const emailMetadataTransaction = symbol_sdk_1.NamespaceMetadataTransaction.create(symbol_sdk_1.Deadline.create(), companyAccount.address, symbol_sdk_1.KeyGenerator.generateUInt64Key('EMAIL'), namespaceId, email.length, email, networkType);
const addressMetadataTransaction = symbol_sdk_1.NamespaceMetadataTransaction.create(symbol_sdk_1.Deadline.create(), companyAccount.address, symbol_sdk_1.KeyGenerator.generateUInt64Key('ADDRESS'), namespaceId, address.length, address, networkType);
const phoneMetadataTransaction = symbol_sdk_1.NamespaceMetadataTransaction.create(symbol_sdk_1.Deadline.create(), companyAccount.address, symbol_sdk_1.KeyGenerator.generateUInt64Key('PHONE'), namespaceId, phone.length, phone, networkType);
2. All metadata is attached only with the consent of the namespace creator through Aggregate Transactions. Wrap the metadata transactions inside an AggregateCompleteTransaction and sign the aggregate with the company’s account.
const aggregateTransaction = AggregateTransaction.createComplete(
Deadline.create(),
[
nameMetadataTransaction.toAggregate(companyAccount.publicAccount),
emailMetadataTransaction.toAggregate(companyAccount.publicAccount),
addressMetadataTransaction.toAggregate(companyAccount.publicAccount),
phoneMetadataTransaction.toAggregate(companyAccount.publicAccount),
],
networkType,
[],
UInt64.fromUint(2000000));
const aggregateTransaction = symbol_sdk_1.AggregateTransaction.createComplete(symbol_sdk_1.Deadline.create(), [
nameMetadataTransaction.toAggregate(companyAccount.publicAccount),
emailMetadataTransaction.toAggregate(companyAccount.publicAccount),
addressMetadataTransaction.toAggregate(companyAccount.publicAccount),
phoneMetadataTransaction.toAggregate(companyAccount.publicAccount),
], networkType, [], symbol_sdk_1.UInt64.fromUint(2000000));
Note
If a namespace was owned by a different account, you would need to set the aggregate as bonded. Then, the namespace creator needs to accept the metadata request by cosigning the transaction.
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash = '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = companyAccount.sign(aggregateTransaction, networkGenerationHash);
console.log(signedTransaction.hash);
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
transactionHttp
.announce(signedTransaction)
.subscribe((x) => console.log(x), (err) => console.error(err));
// replace with meta.networkGenerationHash (nodeUrl + '/node/info')
const networkGenerationHash = '1DFB2FAA9E7F054168B0C5FCB84F4DEB62CC2B4D317D861F3168D161F54EA78B';
const signedTransaction = companyAccount.sign(aggregateTransaction, networkGenerationHash);
console.log(signedTransaction.hash);
const nodeUrl = 'http://api-01.us-east-1.096x.symboldev.network:3000';
const repositoryFactory = new symbol_sdk_1.RepositoryFactoryHttp(nodeUrl);
const transactionHttp = repositoryFactory.createTransactionRepository();
transactionHttp
.announce(signedTransaction)
.subscribe((x) => console.log(x), (err) => console.error(err));
symbol-cli transaction namespacemetadata --target-address TCM6YD-BC3BW2-ZYXOXC-HHIRDV-MEZUIP-BRISYI-TPQ --namespace-id 85BBEA6CC462B244 --key 8B5DD479E6AB718A --value ComfyClothingCompany
symbol-cli transaction namespacemetadata --target-address TCM6YD-BC3BW2-ZYXOXC-HHIRDV-MEZUIP-BRISYI-TPQ --namespace-id 85BBEA6CC462B244 --key 802FE471ADA04D9D --value info@comfyclothingcompany
symbol-cli transaction namespacemetadata --target-address TCM6YD-BC3BW2-ZYXOXC-HHIRDV-MEZUIP-BRISYI-TPQ --namespace-id 85BBEA6CC462B244 --key D14E8FE298386BF5 --value ComfyClothingCompanyHQ
symbol-cli transaction namespacemetadata --target-address TCM6YD-BC3BW2-ZYXOXC-HHIRDV-MEZUIP-BRISYI-TPQ --namespace-id 85BBEA6CC462B244 --key FAAE8FBA0227A914 --value 000-0000
Did you find what you were looking for? Give us your feedback.