Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update fa_coin and your_fungible_asset #600

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 16 additions & 7 deletions examples/typescript/move/facoin/sources/fa_coin.move
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8> = b"Tutorial Token";
const ASSET_SYMBOL: vector<u8> = b"FA";

#[resource_group_member(group = aptos_framework::object::ObjectGroup)]
Expand All @@ -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.
Expand All @@ -55,6 +58,12 @@ module FACoin::fa_coin {
object::address_to_object<Metadata>(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 {
Expand Down
53 changes: 44 additions & 9 deletions examples/typescript/your_fungible_asset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
InputViewFunctionData,
Network,
NetworkToNetworkName,
MoveValue,
} from "@aptos-labs/ts-sdk";
import { compilePackage, getPackageBytesToPublish } from "./utils";
/**
Expand Down Expand Up @@ -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<string> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These examples use a "global" aptos object, so it doesn't have to be passed here

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<string> {
const transaction = await aptos.transaction.build.simple({
Expand Down Expand Up @@ -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 ===");
Expand All @@ -175,28 +209,29 @@ 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.");
const freezeTransactionHash = await freeze(alice, bob.accountAddress);
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.`,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please replace with "

);
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);
Expand All @@ -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.");
Expand All @@ -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.");
}

Expand Down