Used to check for browser translation.
用于检测浏览器翻译。
ブラウザの翻訳を検出する
Client Capabilities

Sending Transactions (Mutations)


Mutations in the @arcblock/graphql-client library allow your application to send data and execute operations on the blockchain. This section provides a comprehensive guide to the transaction lifecycle, including encoding, signing (single and multi-party), and broadcasting transactions to a Forge-powered blockchain node.

For a deeper understanding of blockchain entities, refer to Wallets and Accounts. For detailed explanations of specific transaction types and their usage, see Transaction Types and Usage.

Transaction Lifecycle#

Every transaction sent to the blockchain follows a general lifecycle: it's first encoded into a binary format, then cryptographically signed by the sender (and potentially other parties), and finally broadcast to the blockchain node.

Encoding Transactions#

The client provides specific encode<TxType>Tx methods for each supported transaction type. These methods convert a human-readable transaction object into its binary protobuf representation, which is required for signing and broadcasting.

Method Signature (General)

client.encode<TxType>Tx(params: GraphQLClient.TxParam<PartialDeep<GraphQLClient.<TxType>Tx>>): Promise<GraphQLClient.EncodeTxResult>

Parameters

Name

Type

Description

params.tx

object

The transaction payload containing the inner transaction (itx) and other common transaction fields.

params.wallet

WalletObject

The wallet used for signing the transaction, providing the sender's public key.

params.delegator

string

Optional. The wallet address that delegated permissions to the params.wallet address, if applicable.

Returns

Name

Type

Description

object

object

The encoded transaction as a JavaScript object.

buffer

Buffer

The encoded transaction as a binary Buffer.

Signing Transactions#

After encoding, a transaction must be signed using the sender's private key. The GraphQLClient supports both single and multi-party signatures.

Single Signature#

Use the sign<TxType>Tx methods when a single wallet needs to sign a transaction. This method takes the transaction object (which may or may not be encoded yet) and applies the signature using the provided wallet.

Method Signature (General)

client.sign<TxType>Tx(params: GraphQLClient.TxParam<PartialDeep<GraphQLClient.<TxType>Tx>> & { encoding?: 'base64' | 'base58' | 'base16' | 'hex' }): Promise<GraphQLClient.Transaction | string | Buffer>

Parameters

Name

Type

Description

params.tx

object

The transaction payload. If tx.signature already exists, it will be removed before re-signing.

params.wallet

WalletObject

The wallet instance used to sign the transaction.

params.delegator

string

Optional. The wallet address that delegated permissions.

params.encoding

string

Optional. The desired encoding for the returned signed transaction ('base64', 'base58', 'base16', 'hex'). If not specified, returns a Transaction object.

Returns

Name

Type

Description

transaction

GraphQLClient.Transaction or string or Buffer

The signed transaction object or its encoded string/buffer representation.

Multi-Signature#

For transactions requiring signatures from multiple parties, use the multiSign<TxType>Tx methods. These methods are designed to add a signature to a transaction that might already have other signatures, typically used in scenarios like multi-sig wallets or complex smart contract interactions.

Method Signature (General)

client.multiSign<TxType>Tx(params: GraphQLClient.TxParam<PartialDeep<GraphQLClient.<TxType>Tx>> & { data?: any; encoding?: 'base64' | 'base58' | 'base16' | 'hex' }): Promise<GraphQLClient.Transaction | string | Buffer>

Parameters

Name

Type

Description

params.tx

object

The transaction payload, which should include an array of existing signatures or signaturesList.

params.wallet

WalletObject

The wallet instance of the current signer. Must be a valid wallet with toAddress function.

params.delegator

string

Optional. The wallet address that delegated permissions. If present, the signature will reflect delegation.

params.data

any

Optional. Additional data to include in the multi-signature.

params.encoding

string

Optional. The desired encoding for the returned multi-signed transaction.

Returns

Name

Type

Description

transaction

GraphQLClient.Transaction or string or Buffer

The multi-signed transaction object or its encoded string/buffer representation.

Broadcasting Transactions#

The send<TxType>Tx methods are used to broadcast the signed transaction to the blockchain network. Upon successful broadcast and processing, the transaction hash is returned.

Method Signature (General)

client.send<TxType>Tx(params: GraphQLClient.TxParam<PartialDeep<GraphQLClient.<TxType>Tx>> & { commit?: boolean; extra?: any }, requestExtra?: any): Promise<string>

Parameters

Name

Type

Description

params.tx

object

The transaction payload, which must include the signature field.

params.wallet

WalletObject

The wallet instance used for signing (if params.signature is not provided, the method will sign internally).

params.signature

string

Optional. The pre-computed transaction signature. If provided, the method skips the internal signing step.

params.delegator

string

Optional. The wallet address that delegated permissions.

params.commit

boolean

Optional. If true, the method will wait for the transaction to be committed to a block before resolving. Defaults to false.

params.extra

any

Optional. Extra parameters to verify the transaction, often used for passkeys.

requestExtra

any

Optional. Additional headers or request options for the underlying HTTP request (e.g., extra.headers).

Returns

Name

Type

Description

hash

string

The hash of the successfully broadcasted transaction.

Common Transaction Parameters (TxParam)#

All transaction-sending methods in the GraphQLClient accept a TxParam object, which encapsulates the transaction details and the signing wallet. The tx field within TxParam contains the core transaction data.

Field

Type

Description

tx.nonce

number

Optional. A unique number for the transaction from the sender's perspective. Defaults to Date.now() if not set.

tx.from

string

Optional. The sender's address. If not provided, it will be derived from the wallet object.

tx.pk

string

Optional. The sender's public key. If not provided, it will be derived from the wallet object.

tx.chainId

string

Optional. The ID of the blockchain network. If not provided, it will be fetched from the client's context.

tx.delegator

string

Optional. The address of the delegator if this transaction is sent on behalf of another account.

tx.signature

string

Optional. The cryptographic signature of the transaction. Usually generated internally by sign or multiSign methods.

tx.signatures

PartialDeep<GraphQLClient.Multisig>[]

Optional. An array of multi-signatures, used for multi-party transactions.

tx.itx

T

Required. The inner transaction object, specific to the type of operation (e.g., DeclareTx, CreateAssetTx). This is where the core business logic of the transaction is defined.

wallet

WalletObject

Required. The wallet instance responsible for signing this transaction.

delegator

string

Optional. The address of the delegator if the transaction is being signed by a delegatee.

signature

string

Optional. An externally provided signature for the transaction, bypassing internal signing.

Helper Methods for Transaction Management#

The GraphQLClient provides convenient methods to list all available transaction-related functions:

Method

Description

getTxSendMethods()

Returns a list of all send_TxType methods available on the client.

getTxEncodeMethods()

Returns a list of all encode_TxType methods available on the client.

getTxSignMethods()

Returns a list of all sign_TxType methods available for single signatures.

getTxMultiSignMethods()

Returns a list of all multiSign_TxType methods available for multi-signatures.

Example: Declaring an Identity#

This example demonstrates the full transaction lifecycle for declaring a new identity on the blockchain using the declare transaction type. We'll show both the explicit encoding/signing/sending steps and the convenient shortcut method.

Blockchain NodeGraphQLClientUser ApplicationBlockchain NodeGraphQLClientUser ApplicationPrepare DeclareTx PayloadCall encodeDeclareTx({ tx: { itx: TDeclareTx }, wallet })Encode transaction to protobuf bufferReturn EncodeTxResult { object, buffer }Call signDeclareTx({ tx: object, wallet })Sign transaction buffer using walletReturn signed TTransaction objectCall sendDeclareTx({ tx: signedTx, wallet, commit: true })Broadcast signed transaction (txStr)Process transactionReturn transaction hashReturn transaction hash

const Mcrypto = require('@ocap/mcrypto');
const GraphQLClient = require('@ocap/client');
const { fromRandom, WalletType } = require('@ocap/wallet');
const { bytesToHex } = require('@ocap/util');

// 1. Initialize GraphQLClient
const client = new GraphQLClient('http://localhost:8210/api');

(async () => {
// Ensure client context is ready (fetches chain info, etc.)
await client.getContext();

// 2. Create a new wallet for the identity
const wallet = fromRandom(
WalletType({
role: Mcrypto.types.RoleType.ROLE_ACCOUNT,
pk: Mcrypto.types.KeyType.SECP256K1,
hash: Mcrypto.types.HashType.SHA3,
})
);
console.log(`New wallet address: ${wallet.address}`);

// 3. Define the inner transaction payload (itx)
const declareItx = {
moniker: `username-${Date.now().toString().slice(-4)}`,
};

// --- Explicit Transaction Lifecycle ---

// 4. Encode the transaction
console.log('\n--- Explicit Lifecycle ---');
const { object: encodedTxObject, buffer: encodedTxBuffer } = await client.encodeDeclareTx({
tx: {
itx: declareItx,
},
wallet,
});
console.log('Encoded Transaction Object:', encodedTxObject);
console.log('Encoded Transaction Buffer (Hex):', bytesToHex(encodedTxBuffer));

// 5. Sign the encoded transaction
const signedTx = await client.signDeclareTx({
tx: encodedTxObject,
wallet,
});
console.log('Signed Transaction Object:', signedTx);

// 6. Send the signed transaction to the blockchain
try {
const explicitTxHash = await client.sendDeclareTx({
tx: signedTx,
wallet, // Wallet is still needed for context/gas payer logic in sendTx
commit: true, // Wait for the transaction to be included in a block
});
console.log(`Explicitly sent DeclareTx hash: ${explicitTxHash}`);
} catch (error) {
console.error('Error sending explicit DeclareTx:', error.message);
}

// --- Shortcut Method ---

console.log('\n--- Shortcut Method ---');
try {
const shortcutTxHash = await client.declare({
moniker: `username-shortcut-${Date.now().toString().slice(-4)}`,
wallet,
commit: true,
});
console.log(`Shortcut sent DeclareTx hash: ${shortcutTxHash}`);
} catch (error) {
console.error('Error sending shortcut DeclareTx:', error.message);
}

})().catch(console.error);

This example first demonstrates the explicit steps of encoding, signing, and sending a DeclareTx. It then shows the equivalent shortcut method client.declare(), which internally handles the encoding and signing for convenience. The commit: true option ensures that the method waits for the transaction to be confirmed on the blockchain.

Conclusion#

Understanding the process of sending transactions is crucial for interacting with the blockchain. The GraphQLClient simplifies this by providing intuitive methods for encoding, signing, and broadcasting, alongside convenient shortcuts for common operations. You are now equipped to initiate and manage various types of on-chain interactions.

To learn more about specific transaction types and their parameters, proceed to the Account Transactions section.