Skip to content

Commit

Permalink
feature: update metadata field of fungible and non-fungible tokens, a…
Browse files Browse the repository at this point in the history
…nd dynamic NFTs (#2210)

* feature: mutable metadata fields for dynamic NFTs

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: TokenCreateTransaction class and related intergration test

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: TokenUpdateTransaction class and integration test

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: TokenInfo class and integration test

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: formatting

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: formatting

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: example

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: integration tests

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: update examples

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: adding all integration tests

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: add tests for fungible token

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: integration tests

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: unit tests

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: proto version

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: examples for fungible token

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: integration tests

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: network tag

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: formatting

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: examples

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: integration tests

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: network tag

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: network tag

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: examples

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: test change

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: update network tag 0.49.0-alpha.5

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: protobufs

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: proto package version

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: examples

Signed-off-by: svetoslav-nikol0v <[email protected]>

* chore: formatting

Signed-off-by: svetoslav-nikol0v <[email protected]>

* update: codeowners

Signed-off-by: svetoslav-nikol0v <[email protected]>

---------

Signed-off-by: svetoslav-nikol0v <[email protected]>
  • Loading branch information
svetoslav-nikol0v authored Apr 24, 2024
1 parent 473d67c commit 5fffabe
Show file tree
Hide file tree
Showing 18 changed files with 1,881 additions and 21 deletions.
2 changes: 1 addition & 1 deletion .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
# Default code owners for entire repository
* @SimiHunjan @ochikov @petreze
* @SimiHunjan @ochikov @petreze @svetoslav-nikol0v @agadzhalov
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ async function main() {
.setCustomFees([nftCustomFee])
.setAdminKey(adminKey)
.setSupplyKey(supplyKey)
// .setPauseKey(pauseKey)
.setFreezeKey(freezeKey)
.setWipeKey(wipeKey)
.freezeWith(client)
Expand Down
104 changes: 104 additions & 0 deletions examples/update-fungible-token-metadata-with-admin-key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import {
TokenCreateTransaction,
TokenInfoQuery,
TokenType,
PrivateKey,
Client,
AccountId,
TokenUpdateTransaction,
} from "@hashgraph/sdk";
import dotenv from "dotenv";

dotenv.config();

/**
* @summary E2E-HIP-646 https://hips.hedera.com/hip/hip-646
* @description Update fungible token metadata with admin key
*/
async function main() {
if (
!process.env.OPERATOR_KEY ||
!process.env.OPERATOR_ID ||
!process.env.HEDERA_NETWORK
) {
throw new Error("Please set required keys in .env file.");
}

const operatorId = AccountId.fromString(process.env.OPERATOR_ID);
const operatorKey = PrivateKey.fromStringDer(process.env.OPERATOR_KEY);
const network = process.env.HEDERA_NETWORK;
const client = Client.forName(network).setOperator(operatorId, operatorKey);

// Generate a admin key
const adminKey = PrivateKey.generateED25519();
// Initial metadata
const metadata = new Uint8Array([1]);
// New metadata
const newMetadata = new Uint8Array([1, 2]);

let tokenInfo;

try {
// Create a non fungible token
let createTokenTx = new TokenCreateTransaction()
.setTokenName("Test")
.setTokenSymbol("T")
.setMetadata(metadata)
.setTokenType(TokenType.FungibleCommon) // The same flow can be executed with a TokenType.NON_FUNGIBLE_UNIQUE (i.e. HIP-765)
.setDecimals(3)
.setInitialSupply(10000)
.setTreasuryAccountId(operatorId)
.setAdminKey(adminKey)
.freezeWith(client);

// Sign and execute create token transaction
const tokenCreateTxResponse = await (
await createTokenTx.sign(adminKey)
).execute(client);

// Get receipt for create token transaction
const tokenCreateTxReceipt =
await tokenCreateTxResponse.getReceipt(client);
console.log(
`Status of token create transction: ${tokenCreateTxReceipt.status.toString()}`,
);

// Get token id
const tokenId = tokenCreateTxReceipt.tokenId;
console.log(`Token id: ${tokenId.toString()}`);

// Get token info
tokenInfo = await new TokenInfoQuery()
.setTokenId(tokenId)
.execute(client);
console.log(`Token metadata:`, tokenInfo.metadata);

const tokenUpdateTx = new TokenUpdateTransaction()
.setTokenId(tokenId)
.setMetadata(newMetadata)
.freezeWith(client);

// Sign transactions with admin key and execute it
const tokenUpdateTxResponse = await (
await tokenUpdateTx.sign(adminKey)
).execute(client);

// Get receipt for token update transaction
const tokenUpdateTxReceipt =
await tokenUpdateTxResponse.getReceipt(client);
console.log(
`Status of token update transction: ${tokenUpdateTxReceipt.status.toString()}`,
);

tokenInfo = await new TokenInfoQuery()
.setTokenId(tokenId)
.execute(client);
console.log(`Token updated metadata:`, tokenInfo.metadata);
} catch (error) {
console.log(error);
}

client.close();
}

void main();
104 changes: 104 additions & 0 deletions examples/update-fungible-token-metadata-with-metadata-key.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import {
TokenCreateTransaction,
TokenInfoQuery,
TokenType,
PrivateKey,
Client,
AccountId,
TokenUpdateTransaction,
} from "@hashgraph/sdk";
import dotenv from "dotenv";

dotenv.config();

/**
* @summary E2E-HIP-646 https://hips.hedera.com/hip/hip-646
* @description Update fungible token metadata with metadata key
*/
async function main() {
if (
!process.env.OPERATOR_KEY ||
!process.env.OPERATOR_ID ||
!process.env.HEDERA_NETWORK
) {
throw new Error("Please set required keys in .env file.");
}

const operatorId = AccountId.fromString(process.env.OPERATOR_ID);
const operatorKey = PrivateKey.fromStringDer(process.env.OPERATOR_KEY);
const network = process.env.HEDERA_NETWORK;
const client = Client.forName(network).setOperator(operatorId, operatorKey);

// Generate a metadata key
const metadataKey = PrivateKey.generateED25519();
// Initial metadata
const metadata = new Uint8Array([1]);
// New metadata
const newMetadata = new Uint8Array([1, 2]);

let tokenInfo;

try {
// Create a non fungible token
let createTokenTx = new TokenCreateTransaction()
.setTokenName("Test")
.setTokenSymbol("T")
.setMetadata(metadata)
.setTokenType(TokenType.FungibleCommon) // The same flow can be executed with a TokenType.NON_FUNGIBLE_UNIQUE (i.e. HIP-765)
.setDecimals(3)
.setInitialSupply(10000)
.setTreasuryAccountId(operatorId)
.setMetadataKey(metadataKey)
.freezeWith(client);

// Sign and execute create token transaction
const tokenCreateTxResponse = await (
await createTokenTx.sign(operatorKey)
).execute(client);

// Get receipt for create token transaction
const tokenCreateTxReceipt =
await tokenCreateTxResponse.getReceipt(client);
console.log(
`Status of token create transction: ${tokenCreateTxReceipt.status.toString()}`,
);

// Get token id
const tokenId = tokenCreateTxReceipt.tokenId;
console.log(`Token id: ${tokenId.toString()}`);

// Get token info
tokenInfo = await new TokenInfoQuery()
.setTokenId(tokenId)
.execute(client);
console.log(`Token metadata:`, tokenInfo.metadata);

const tokenUpdateTx = new TokenUpdateTransaction()
.setTokenId(tokenId)
.setMetadata(newMetadata)
.freezeWith(client);

// Sign transactions with metadata key and execute it
const tokenUpdateTxResponse = await (
await tokenUpdateTx.sign(metadataKey)
).execute(client);

// Get receipt for token update transaction
const tokenUpdateTxReceipt =
await tokenUpdateTxResponse.getReceipt(client);
console.log(
`Status of token update transction: ${tokenUpdateTxReceipt.status.toString()}`,
);

tokenInfo = await new TokenInfoQuery()
.setTokenId(tokenId)
.execute(client);
console.log(`Token updated metadata:`, tokenInfo.metadata);
} catch (error) {
console.log(error);
}

client.close();
}

void main();
Loading

0 comments on commit 5fffabe

Please sign in to comment.