Skip to main content

Deploy a SAC for a Stellar asset using code

Overview

In this guide, you'll learn how to deploy a Stellar Asset Contract (SAC) for a Stellar asset using the Stellar SDK. The Stellar SDK is a set of tools and library designed to help developers build applications that interact with the Stellar blockchain network.

Prerequisites:

Code overview

deployassetcontract.js
import * as StellarSdk from "@stellar/stellar-sdk";

const networkRPC = "https://soroban-testnet.stellar.org";
const server = new StellarSdk.SorobanRpc.Server(networkRPC);
const network_passphrase = StellarSdk.Networks.TESTNET;

async function yeetTx(feedback, message) {
try {
if (feedback.status !== "PENDING") {
throw feedback;
}

let status;
let attempts = 0;
while (attempts++ < 20) {
// A maximum of 20 polls of transaction status
const tmpStatus = await server.getTransaction(feedback.hash);
switch (tmpStatus.status) {
case "FAILED":
throw tmpStatus;
case "NOT_FOUND":
await sleep(1000); // Wait for one minute
continue;
case "SUCCESS":
status = tmpStatus;
console.log(`${message}: Transaction succeeded`, status);
break;
}
if (status) break;
}

if (attempts >= 20 || !status) {
throw new Error(
`Failed to find transaction ${feedback.hash} after ${attempts} attempts.`,
);
}

return status;
} catch (error) {
console.error("Transaction failed:", error);
throw error;
}
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

const deployStellarAssetContract = async () => {
const sourceSecrets =
"SASI6PA4K52GQJF6BC263GLYOADVKFJ4SZ7TFX4QQF2U76T3EJ54DT7Y"; // Replace with your Secret Key
const sourceKeypair = StellarSdk.Keypair.fromSecret(sourceSecrets);
const sourceAccount = await server.getAccount(sourceKeypair.publicKey());

try {
const assetCode = "JOEBOY";
const issuerPublicKey = sourceKeypair.publicKey();
const customAsset = new StellarSdk.Asset(assetCode, issuerPublicKey);

const transaction = new StellarSdk.TransactionBuilder(sourceAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: network_passphrase,
})
.addOperation(
StellarSdk.Operation.createStellarAssetContract({
asset: customAsset,
}),
)
.setTimeout(30)
.build();

const uploadTx = await server.prepareTransaction(transaction);
uploadTx.sign(sourceKeypair);

const result = await server.sendTransaction(uploadTx);
const feedback = await yeetTx(result, `SACTransactionFeeback`);
const contractBuffer = feedback.returnValue._value._value;
const contractID = StellarSdk.StrKey.encodeContract(contractBuffer);
console.log(`ContractID of Our ${customAsset.code} Asset`, contractID);
} catch (e) {
console.error("An error occurred while Deploying assets:", e);
}
};

await deployStellarAssetContract();

Code explanation

Server Setup

import * as StellarSdk from "@stellar/stellar-sdk";

const networkRPC = "https://soroban-testnet.stellar.org";
const server = new StellarSdk.SorobanRpc.Server(networkRPC);
const network_passphrase = StellarSdk.Networks.TESTNET;
  • networkRPC: The URL for the Soroban testnet.
  • server: A new instance of SorobanRpc.Server is created, which will be used to interact with the Soroban testnet.
  • network_passphrase: sets the network passphrase to the TESTNET

yeetTx function

async function yeetTx(feedback, message) {
try {
if (feedback.status !== "PENDING") {
throw feedback;
}

let status;
let attempts = 0;
while (attempts++ < 20) {
const tmpStatus = await server.getTransaction(feedback.hash);
switch (tmpStatus.status) {
case "FAILED":
throw tmpStatus;
case "NOT_FOUND":
await sleep(1000);
continue;
case "SUCCESS":
status = tmpStatus;
console.log(`${message}: Transaction succeeded`, status);
break;
}
if (status) break;
}

if (attempts >= 20 || !status) {
throw new Error(
`Failed to find transaction ${feedback.hash} after ${attempts} attempts.`,
);
}

return status;
} catch (error) {
console.error("Transaction failed:", error);
throw error;
}
}

The yeetTx function handles checking the status of a transaction until it either succeeds, fails, or the number of attempts exceeds a limit.

  • feedback: The initial feedback object returned when a transaction is submitted.
  • message: A custom message to log when the transaction succeeds..

sleep function

function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}

This function is a helper that returns a promise that resolves after a specified number of milliseconds. It's used to delay the next check in yeetTx when the transaction status is "NOT_FOUND."

DeployStellarAssetContract function

const deployStellarAssetContract = async () => {
const sourceSecrets =
"SASI6PA4K52GQJF6BC263GLYOADVKFJ4SZ7TFX4QQF2U76T3EJ54DT7Y"; // Replace with your Secret Key
const network_passphrase = StellarSdk.Networks.TESTNET;
const sourceKeypair = StellarSdk.Keypair.fromSecret(sourceSecrets);
const sourceAccount = await server.getAccount(sourceKeypair.publicKey());

try {
const assetCode = "JOEBOY";
const issuerPublicKey = sourceKeypair.publicKey();
const customAsset = new StellarSdk.Asset(assetCode, issuerPublicKey);

const transaction = new StellarSdk.TransactionBuilder(sourceAccount, {
fee: StellarSdk.BASE_FEE,
networkPassphrase: network_passphrase,
})
.addOperation(
StellarSdk.Operation.createStellarAssetContract({
asset: customAsset,
}),
)
.setTimeout(30)
.build();

const uploadTx = await server.prepareTransaction(transaction);
uploadTx.sign(sourceKeypair);

const result = await server.sendTransaction(uploadTx);
const feedback = await yeetTx(result, `SACTransactionFeeback`);
const contractBuffer = feedback.returnValue._value._value;
const contractID = StellarSdk.StrKey.encodeContract(contractBuffer);
console.log(`ContractID of Our ${customAsset.code} Asset`, contractID);
} catch (e) {
console.error("An error occurred while Deploying assets:", e);
}
};

await deployStellarAssetContract();

This function is designed to deploy a Stellar Asset Contract (SAC) on the Soroban testnet.

  • Secret Key: It starts by defining the secret key for the source account (sourceSecrets), which you must replace with your own.
  • Keypair and Account: Generates the keypair from the secret key and fetches the account details from the Soroban server.
  • Custom Asset: Defines a custom asset with the code JOEBOY and the issuer's public key.
  • Transaction Building: A transaction is built using the TransactionBuilder, which includes the createStellarAssetContract operation for the custom asset. The transaction is then prepared and signed.
  • Send Transaction: The signed transaction is sent to the network using server.sendTransaction.
  • Feedback Handling: It waits for the transaction feedback using the yeetTx function to ensure it has succeeded. extracts the contract buffer from the feedback and converts it to a contract ID using StellarSdk.StrKey.encodeContract. finally, it logs the contract ID for the deployed asset.