Transfer Tokens
Here's an example how to make a Token transfer.
import {
Base16,
DomainSettings,
PhantasmaAPI,
PhantasmaKeys,
ScriptBuilder,
Transaction,
TransactionData,
} from "phantasma-sdk-ts";
const soulTokenDecimals = 8;
const soulTokenSymbol = "SOUL";
const runningTxStateName = "Running";
const breakTxStateName = "Break";
const faultTxStateName = "Fault";
const haltTxStateName = "Halt";
export async function transferSoulTokens() {
// const rpcUrl = "https://pharpc1.phantasma.info/rpc";
const rpcUrl = "https://testnet.phantasma.info/rpc";
// const nexus = "mainnet";
const nexus = "testnet";
const amountFloat = 1.01; // 1.01 SOUL, sample value
let senderWif = "YOUR_WIF"; //Private key in WIF format
let amount = (amountFloat * 10 ** soulTokenDecimals).toString(); // Convert to blockchain units
let keys = PhantasmaKeys.fromWIF(senderWif);
let senderAddress = keys.Address;
let recepientAddress = "P2KHhbVZWDv1ZLLoJccN3PUAb9x9BqRnUyH3ZEhu5YwBeJQ";
// Creating RPC connection
let rpc = new PhantasmaAPI(rpcUrl, null, nexus);
// Set Gas parameters for Runtime.TransferTokens
let gasPrice = DomainSettings.DefaultMinimumGasFee;
let gasLimit = 2100;
// Creating a new Script Builder Object
let sb = new ScriptBuilder();
// Making a Script
let script = sb
.BeginScript()
.AllowGas(senderAddress, sb.NullAddress, gasPrice, gasLimit)
.CallInterop("Runtime.TransferTokens", [
senderAddress,
recepientAddress,
soulTokenSymbol,
amount,
])
.SpendGas(senderAddress)
.EndScript();
// Set expiration date
let expiration = Math.floor(Date.now() / 1000) + 30;
let expiration_date = new Date(expiration * 1000);
let payload = Base16.encode("sdk-ts");
// Creating New Transaction Object
let transaction = new Transaction(
nexus,
"main",
script,
expiration_date,
payload,
);
transaction.signWithKeys(keys);
let hexEncodedTx = transaction.toString(true); //converts trasnaction to base16 string -true means transaction is signed-
console.log("Broadcasting transaction:", hexEncodedTx);
// Broadcasting transaction
let txHash = await rpc.sendRawTransaction(hexEncodedTx);
console.log("Broadcased tx hash:", txHash);
const start = Date.now();
const timeoutMs = 60_000; // 60 seconds total
const intervalMs = 2_000; // poll every 2 seconds
let verified = false;
console.log("Waiting up to 60s for transaction execution state...");
while (Date.now() - start < timeoutMs) {
try {
const txInfo: TransactionData = await rpc.getTransaction(txHash);
// Print only the state field for clarity
console.log("getTransaction response: state:", txInfo.state);
// txInfo.state is provided by the SDK as a string name (e.g. "Running","Halt", etc.)
const stateStr = txInfo.state;
if (stateStr === runningTxStateName) {
// still running -> continue polling
} else if (
stateStr === breakTxStateName ||
stateStr === faultTxStateName
) {
// Break or Fault -> failure
console.log(
`Transaction failed: ${stateStr} result: '${txInfo.result}'`,
);
verified = true;
break;
} else if (stateStr === haltTxStateName) {
// Halt -> success
console.log("Transaction succeeded");
return { success: true, result: txInfo.result };
} else {
// Unknown state name -> log and continue polling
console.log("Unknown ExecutionState value:", stateStr);
}
} catch (err) {
// Transient RPC errors are logged and retried until timeout
const e = err as Error;
console.log(
"Error while checking transaction status (will retry):",
e && e.message ? e.message : String(err),
);
}
// wait before next poll
await new Promise((r) => setTimeout(r, intervalMs));
}
if (!verified) {
console.log(
"Unable to verify transaction execution state within 60 seconds. Please check manually. txHash:",
txHash,
);
}
return { success: false, result: "" };
}Last updated