diff --git a/examples/typescript/move/facoin/sources/fa_coin.move b/examples/typescript/move/facoin/sources/fa_coin.move index 14c5c4017..3431a7b10 100644 --- a/examples/typescript/move/facoin/sources/fa_coin.move +++ b/examples/typescript/move/facoin/sources/fa_coin.move @@ -7,12 +7,15 @@ module FACoin::fa_coin { use aptos_framework::primary_fungible_store; use std::error; use std::signer; + use std::string; use std::string::utf8; use std::option; /// Only fungible asset metadata owner can make changes. const ENOT_OWNER: u64 = 1; + // TODO: For the "Your First Fungible Asset" guide, please update these values to change the ASSET NAME and SYMBOL when this is published. + const ASSET_NAME: vector = b"Tutorial Token"; const ASSET_SYMBOL: vector = b"FA"; #[resource_group_member(group = aptos_framework::object::ObjectGroup)] @@ -28,13 +31,13 @@ module FACoin::fa_coin { fun init_module(admin: &signer) { let constructor_ref = &object::create_named_object(admin, ASSET_SYMBOL); primary_fungible_store::create_primary_store_enabled_fungible_asset( - constructor_ref, - option::none(), - utf8(b"FA Coin"), /* name */ - utf8(ASSET_SYMBOL), /* symbol */ - 8, /* decimals */ - utf8(b"http://example.com/favicon.ico"), /* icon */ - utf8(b"http://example.com"), /* project */ + constructor_ref, /* ConstructorRef - The temporary ConstructorRef gives permission to create this PrimaryStore */ + option::none(), /* Supply - option::none() indicates the supply is uncapped */ + utf8(ASSET_NAME), /* Name - Used to indicate which asset this is */ + utf8(ASSET_SYMBOL), /* Symbol - A shortened acronym used interchangeably with the name. Usually 3 letters long. */ + 8, /* Decimals - The number of digits of precision in the fungible asset. */ + utf8(b"http://example.com/favicon.ico"), /* Icon - A link to an icon which can be rendered in application front-ends. */ + utf8(b"http://example.com"), /* Project - A link to where people using this token can learn more about it or the organization behind it. */ ); // Create mint/burn/transfer refs to allow creator to manage the fungible asset. @@ -55,6 +58,12 @@ module FACoin::fa_coin { object::address_to_object(asset_address) } + #[view] + public fun get_name(): string::String { + let metadata = get_metadata(); + fungible_asset::name(metadata) + } + // :!:>mint /// Mint as the owner of metadata object and deposit to a specific account. public entry fun mint(admin: &signer, to: address, amount: u64) acquires ManagedFungibleAsset { diff --git a/examples/typescript/your_fungible_asset.ts b/examples/typescript/your_fungible_asset.ts index 845841dc0..b8ae43b2e 100644 --- a/examples/typescript/your_fungible_asset.ts +++ b/examples/typescript/your_fungible_asset.ts @@ -10,6 +10,7 @@ import { InputViewFunctionData, Network, NetworkToNetworkName, + MoveValue, } from "@aptos-labs/ts-sdk"; import { compilePackage, getPackageBytesToPublish } from "./utils"; /** @@ -80,6 +81,34 @@ async function burnCoin(admin: Account, fromAddress: AccountAddress, amount: Any return pendingTxn.hash; } +/** + * Fetches the name of the fungible asset created by the given account. + * This function interacts with the `get_name` view function in the Move module. + * + * @param aptos - An instance of the Aptos client. + * @param admin - The account that deployed the fungible asset module. + * @returns The name of the token as a string. + */ +async function fetchTokenName(aptos: Aptos, admin: Account): Promise { + try { + const payload: InputViewFunctionData = { + function: `${admin.accountAddress}::fa_coin::get_name`, + functionArguments: [], + }; + + const result: MoveValue[] = await aptos.view({ payload }); + + if (!Array.isArray(result) || result.length === 0 || typeof result[0] !== "string") { + throw new Error("Invalid response format. Ensure the module is deployed correctly."); + } + + return result[0]; + } catch (error) { + console.error("Error fetching token name:", error); + throw error; + } +} + /** Admin freezes the primary fungible store of the specified account */ async function freeze(admin: Account, targetAddress: AccountAddress): Promise { const transaction = await aptos.transaction.build.simple({ @@ -145,10 +174,15 @@ async function main() { console.log(`Bob: ${bob.accountAddress.toString()}`); console.log(`Charlie: ${charlie.accountAddress.toString()}`); - await aptos.fundAccount({ accountAddress: alice.accountAddress, amount: 100_000_000 }); + await aptos.fundAccount({ + accountAddress: alice.accountAddress, + amount: 100_000_000, + options: { waitForIndexer: false }, + }); await aptos.fundAccount({ accountAddress: bob.accountAddress, amount: 100_000_000, + options: { waitForIndexer: false }, }); console.log("\n=== Compiling FACoin package locally ==="); @@ -175,16 +209,17 @@ async function main() { console.log("metadata address:", metadataAddress); console.log("All the balances in this example refer to balance in primary fungible stores of each account."); - console.log(`Alice's initial FACoin balance: ${await getFaBalance(alice, metadataAddress)}.`); - console.log(`Bob's initial FACoin balance: ${await getFaBalance(bob, metadataAddress)}.`); + console.log(`Alice's initial balance: ${await getFaBalance(alice, metadataAddress)}.`); + console.log(`Bob's initial balance: ${await getFaBalance(bob, metadataAddress)}.`); console.log(`Charlie's initial balance: ${await getFaBalance(charlie, metadataAddress)}.`); + const tokenName = `"${await fetchTokenName(aptos, alice)}"`; // Adding quotes so when it's printed later it's clear it's a name. console.log("Alice mints Charlie 100 coins."); const mintCoinTransactionHash = await mintCoin(alice, charlie, 100); await aptos.waitForTransaction({ transactionHash: mintCoinTransactionHash }); console.log( - `Charlie's updated FACoin primary fungible store balance: ${await getFaBalance(charlie, metadataAddress)}.`, + `Charlie's updated ${tokenName} primary fungible store balance: ${await getFaBalance(charlie, metadataAddress)}.`, ); console.log("Alice freezes Bob's account."); @@ -192,11 +227,11 @@ async function main() { await aptos.waitForTransaction({ transactionHash: freezeTransactionHash }); console.log( - "Alice as the admin forcefully transfers the newly minted coins of Charlie to Bob ignoring that Bob's account is frozen.", + `Alice as the admin forcefully transfers the newly minted coins of Charlie to Bob ignoring that Bob's account is frozen.`, ); const transferCoinTransactionHash = await transferCoin(alice, charlie.accountAddress, bob.accountAddress, 100); await aptos.waitForTransaction({ transactionHash: transferCoinTransactionHash }); - console.log(`Bob's updated FACoin balance: ${await getFaBalance(bob, metadataAddress)}.`); + console.log(`Bob's updated ${tokenName} balance: ${await getFaBalance(bob, metadataAddress)}.`); console.log("Alice unfreezes Bob's account."); const unfreezeTransactionHash = await unfreeze(alice, bob.accountAddress); @@ -205,7 +240,7 @@ async function main() { console.log("Alice burns 50 coins from Bob."); const burnCoinTransactionHash = await burnCoin(alice, bob.accountAddress, 50); await aptos.waitForTransaction({ transactionHash: burnCoinTransactionHash }); - console.log(`Bob's updated FACoin balance: ${await getFaBalance(bob, metadataAddress)}.`); + console.log(`Bob's updated ${tokenName} balance: ${await getFaBalance(bob, metadataAddress)}.`); /// Normal fungible asset transfer between primary stores console.log("Bob transfers 10 coins to Alice as the owner."); @@ -220,8 +255,8 @@ async function main() { transaction: transferFungibleAssetRawTransaction, }); await aptos.waitForTransaction({ transactionHash: transferFungibleAssetTransaction.hash }); - console.log(`Alice's updated FACoin balance: ${await getFaBalance(alice, metadataAddress)}.`); - console.log(`Bob's updated FACoin balance: ${await getFaBalance(bob, metadataAddress)}.`); + console.log(`Alice's updated ${tokenName} balance: ${await getFaBalance(alice, metadataAddress)}.`); + console.log(`Bob's updated ${tokenName} balance: ${await getFaBalance(bob, metadataAddress)}.`); console.log("done."); }