Skip to Content
Supra Layer 1SupraMVMTypeScript SDKGuidesPublish a Package

Publish a Package

How to publish a package using the TypeScript SDK.

publishPackage function

The function lives on the client’s transaction module and takes a single named-argument object.

await supra.transaction.publishPackage({ senderAccount, packageMetadata, modulesCode })

Parameters

NameType
senderAccountSupraAccount
packageMetadataUint8Array
modulesCodeUint8Array[]
optionalTransactionArgs?OptionalTransactionArgs

Returns

NameType
Promise<TransactionResponse>TransactionResponse

The function returns the transaction, not a { txHash, result } pair. With enableWaitForTransaction: true in enableTransactionWaitAndSimulationArgs, it waits for a final status and returns the committed transaction. A transaction that ends with Fail or Invalid throws SupraTransactionFailedError, and one with no final status within the wait timeout throws SupraTransactionTimeoutError. Without enableWaitForTransaction, it returns the transaction as the node reports it right after the submission, with its hash.

Max gas

When neither the call nor the client sets maxGas, publishPackage estimates it: it simulates the transaction with the largest max gas the sender’s SUPRA balance pays for and submits it with 1.5 times the gas used. A simulation that does not succeed throws SupraSimulationFailedError and nothing is submitted. The sender needs enough SUPRA to cover the estimate at the gas unit price (see Gas price). To set the limit yourself, pass maxGas in optionalTransactionPayloadArgs.


Example

The publishPackage function requires the package metadata and module bytecode as the packageMetadata and modulesCode arguments. These are obtained through the build-publish-payload command of the Supra CLI. Once obtained, parse the JSON file for the data and pass it to the publishPackage function.

Prepare an account and a package

The example publishes a package named counter from a funded account. Create the account as in Create Supra Accounts, keep its private key, and fund its address from the faucet on Devnet. The example uses Devnet; use Network.TESTNET and a Testnet account for Testnet.

Create the counter package as in Create a Move Package, which also covers its Move.toml and the framework dependency. In Move.toml, give the named address counter_addr the address of the account:

[addresses] counter_addr = "<ACCOUNT_ADDRESS>"

Save this module as sources/counter.move:

module counter_addr::counter { use std::signer; use supra_framework::event; struct Counter has key { value: u64, } #[event] struct Bumped has drop, store { account: address, value: u64, } /// Adds one to the signer's counter, creating the counter on the first call. public entry fun bump(account: &signer) acquires Counter { let addr = signer::address_of(account); if (!exists<Counter>(addr)) { move_to(account, Counter { value: 0 }); }; let counter = borrow_global_mut<Counter>(addr); counter.value = counter.value + 1; event::emit(Bumped { account: addr, value: counter.value }); } #[view] public fun get(addr: address): u64 acquires Counter { if (exists<Counter>(addr)) borrow_global<Counter>(addr).value else 0 } }

Build the publish payload with the Supra CLI

supra move tool build-publish-payload --package-dir /supra/move_workspace/{YOUR_PROJECT_NAME} --json-output-file /supra/move_workspace/{YOUR_PROJECT_NAME}/publish-payload.json

The command compiles the package, so every named address in Move.toml needs a value, either under [addresses] or with --named-addresses. Without one, compilation fails with address '<NAME>' is not assigned a value.

supra move tool build-publish-payload --package-dir /supra/move_workspace/{YOUR_PROJECT_NAME} --json-output-file /supra/move_workspace/{YOUR_PROJECT_NAME}/publish-payload.json --named-addresses {NAME}={ACCOUNT_ADDRESS}

Initialize a new project

mkdir supra-publish && cd supra-publish npm init -y npm install supra-ts-sdk@devnet npm install --save-dev tsx

tsx runs TypeScript files directly. The TypeScript SDK page lists the npm dist-tags.

Create publish_example.ts and import dependencies

import fs from 'fs'; import { HexString, SupraAccount, SupraClient, Network } from 'supra-ts-sdk';

Parse the JSON file and extract data

function getPackageData(filePath: string) { const jsonData = JSON.parse(fs.readFileSync(filePath, "utf8")); const packageMetadata = new HexString(jsonData.args[0].value).toUint8Array(); const modulesCode = []; for(let e of jsonData.args[1].value){ modulesCode.push(new HexString(e).toUint8Array()) } return { packageMetadata, modulesCode }; }

Call the publishPackage function

async function main(){ // The path to publish-payload.json, from the command line. const { packageMetadata, modulesCode } = getPackageData(process.argv[2]); const supra = new SupraClient({ network: Network.DEVNET }); // The private key of the funded account, from the environment. const senderAccount = new SupraAccount( new HexString(process.env.PRIVATE_KEY!).toUint8Array() ); const publishTxn = await supra.transaction.publishPackage({ senderAccount, packageMetadata, modulesCode, optionalTransactionArgs: { enableTransactionWaitAndSimulationArgs: { enableWaitForTransaction: true }, }, }) // `Success` when the package is published. A transaction that fails throws // SupraTransactionFailedError. console.log(publishTxn.status, publishTxn.hash); }

Complete code

import fs from "fs"; import { HexString, SupraAccount, SupraClient, Network } from "supra-ts-sdk"; function getPackageData(filePath: string) { const jsonData = JSON.parse(fs.readFileSync(filePath, "utf8")); const packageMetadata = new HexString(jsonData.args[0].value).toUint8Array(); const modulesCode = []; for(let e of jsonData.args[1].value){ modulesCode.push(new HexString(e).toUint8Array()) } return { packageMetadata, modulesCode }; } async function main(){ const { packageMetadata, modulesCode } = getPackageData(process.argv[2]); const supra = new SupraClient({ network: Network.DEVNET }); const senderAccount = new SupraAccount( new HexString(process.env.PRIVATE_KEY!).toUint8Array() ); const publishTxn = await supra.transaction.publishPackage({ senderAccount, packageMetadata, modulesCode, optionalTransactionArgs: { enableTransactionWaitAndSimulationArgs: { enableWaitForTransaction: true }, }, }) console.log(publishTxn.status, publishTxn.hash); } main()

Execute code

PRIVATE_KEY=<PRIVATE_KEY> npx tsx publish_example.ts <PATH_TO_PUBLISH_PAYLOAD_JSON>

The module is then at <ACCOUNT_ADDRESS>::counter. Call a Function and Read Events calls it.

Last updated on