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 | nullreturnValue() 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.