BluxBlux

Write Contract

Invoke a Soroban smart contract method that changes on-chain state.

writeContract is a Soroban helper that invokes a state-changing contract method. It builds the call, simulates it to gather the resource fees, footprint, and authorization, assembles the final transaction, and then submits it through Blux's signing flow — so the connected user signs and the change lands on-chain.

Unlike readContracts, this requires a connected user (the source account) and produces a real, fee-paying transaction.

Type

type IContractCall = {
  address: string;   // C… contract ID, SEP-2 address, or .xlm name
  fn: string;        // function name to invoke
  args: unknown[];   // native values in the function's positional order
};

type WriteContractsOptions = {
  network?: string;    // Omit to use the active network
};

const writeContract: <TReturnValue = unknown>(
  call: IContractCall,
  options?: WriteContractsOptions,
) => Promise<ISubmittedTransaction<TReturnValue>>;

Native contract arguments

Pass ordinary JavaScript values in the order declared by the contract function. Blux reads the deployed contract spec and converts them to the required Soroban types; you do not need to wrap arguments with ToScVal.

args: [
  "GA...FROM",       // Address
  "bob.xlm",         // Address; resolved before encoding
  "1000000000",      // i128
]

Use a safe number, bigint, or decimal string for integers. Decimal strings and bigint values avoid precision loss for wide types such as i128. Arrays, maps, bytes, and contract-defined values must match the shape declared in the contract spec.

Both the call's contract address and every ABI-declared Address argument can be a .xlm name or SEP-2 federation address. Nested address values are resolved inside options, vectors, tuples, maps, structs, and unions. See address resolution.

Pre-encoded xdr.ScVal arguments remain supported for backward compatibility, but they are optional.

Usage

Call a token's transfer method. Blux prompts the user to sign before the transaction is submitted:

import { core } from "@bluxcc/core";

const result = await core.writeContract<bigint>({
  address: "token.xlm",
  fn: "transfer",
  args: [
    "GA...FROM",       // from: Address
    "bob.xlm",         // to: Address
    "1000000000",      // amount: i128
  ],
});

console.log(result.hash);
console.log(await result.returnValue());

Return type

The ABI is inspected at runtime, so TypeScript cannot derive the result from runtime address, fn, and network values. Supply the decoded function return type as the generic:

const result = await core.writeContract<bigint>({
  address: TOKEN,
  fn: "mint",
  args: ["alice.xlm", "10000000"],
});

const minted = await result.returnValue(); // bigint | null

returnValue() includes null because void Soroban functions and classic transactions have no decoded value. If you omit the generic, the type is unknown | null.

writeContract must be called after createConfig and while a user is connected — the connected account is used as the transaction source. Wrap the call in a try/catch to handle simulation failures and user rejection.

On this page