Build and Publish the FACoin package

Move contracts are effectively a set of Move modules known as a package. When deploying or upgrading a new package, the compiler must be invoked with --save-metadata to publish the package.

In the case of FACoin, the following output files are critical:

build/Examples/package-metadata.bcs: Contains the metadata associated with the package. build/Examples/bytecode_modules/ Contains the bytecode for the fa_coin.move module. These are read by the example and published to the Aptos blockchain:

In the TypeScript example, we use aptos move build-publish-payload command to compile and build the module. That command builds the build folder that contains the package-metadata.bcs and the bytecode for the module. The command also builds a publication transaction payload and stores it in a JSON output file that we can later read from to get the metadataBytes and byteCode to publish the contract to chain with.

Compile the package

export function compilePackage(
packageDir: string,
outputFile: string,
namedAddresses: Array<{ name: string; address: AccountAddress }>,
) {
const addressArg = namedAddresses
.map(({ name, address }) => `${name}=${address}`)
.join(" ");
// Assume-yes automatically overwrites the previous compiled version, only do this if you are sure you want to overwrite the previous version.
const compileCommand = `aptos move build-publish-payload --json-output-file ${outputFile} --package-dir ${packageDir} --named-addresses ${addressArg} --assume-yes`;
compilePackage("move/facoin", "move/facoin/facoin.json", [
{ name: "FACoin", address: alice.accountAddress },

Publish the package to chain

export function getPackageBytesToPublish(filePath: string) {
// current working directory - the root folder of this repo
const cwd = process.cwd();
// target directory - current working directory + filePath (filePath json file is generated with the previous, compilePackage, CLI command)
const modulePath = path.join(cwd, filePath);
const jsonData = JSON.parse(fs.readFileSync(modulePath, "utf8"));
const metadataBytes = jsonData.args[0].value;
const byteCode = jsonData.args[1].value;
return { metadataBytes, byteCode };
const { metadataBytes, byteCode } = getPackageBytesToPublish(
// Publish FACoin package to chain
const transaction = await aptos.publishPackageTransaction({
account: alice.accountAddress,
moduleBytecode: byteCode,
const pendingTransaction = await aptos.signAndSubmitTransaction({
signer: alice,
await aptos.waitForTransaction({ transactionHash: pendingTransaction.hash });