> For the complete documentation index, see [llms.txt](https://docs.blockrazor.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.blockrazor.io/tc/transaction-submission/fast/sui/sui_executetransactionblock/ts.md).

# TS

### SDK

请在运行示例代码前安裝`blockrazor-sui-sdk`和`@mysten/sui`，安裝命令：

```bash
## blockrazor-sui-sdk
npm i blockrazor-sui-sdk

## @mysten/sui
npm install @mysten/sui
```

### gRPC

[示例地址](https://github.com/BlockRazorinc/sui_ts_example/blob/main/example/demo_grpc.ts)

```typescript
import { Transaction } from "@mysten/sui/transactions";
import { Ed25519Keypair } from "@mysten/sui/keypairs/ed25519";
import { decodeSuiPrivateKey } from "@mysten/sui/cryptography";
import { SuiClient, SuiHTTPTransport, getFullnodeUrl } from "@mysten/sui/client";
import * as grpc from "@grpc/grpc-js";
import * as protoLoader from "@grpc/proto-loader";
import path from "path";
import { CaculateFee, AddTip } from "blockrazor-sui-sdk";
import { CompressionFilter } from "@grpc/grpc-js/build/src/compression-filter.js";


// Replace with your own private key
const SUI_PRIVATE_KEY = "suiprivkey1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

// Receiver address
const RECIPIENT = "0xaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";

// gRPC endpoint 
const GRPC_ADDR = "your-grpc-host:PORT";

// JSON-RPC endpoint 
const RPC_URL = getFullnodeUrl("mainnet");

// Auth token
const AUTH_TOKEN = "YOUR_AUTH_TOKEN";

// Amount to send (in MIST)
const SEND_AMOUNT_MIST = 1_000_000n;

// Fixed gas price for demo
const GAS_PRICE = 5_000;

/**
 * Local proto root (change this path to match your repo structure)
 */
const PROTO_ROOT = path.resolve("/path/to/your/protos");

/**
 * Proto file for:
 * package sui.rpc.v2;
 * service TransactionExecutionService { rpc ExecuteTransaction(...) ... }
 */
const PROTO_FILE = path.join(
    PROTO_ROOT,
    "sui/rpc/v2/transaction_execution_service.proto"
);

function forceIdentityGrpcEncoding() {
    const proto = CompressionFilter.prototype as CompressionFilter & {
        __identityEncodingPatched?: boolean;
    };
    if (proto.__identityEncodingPatched) {
        return;
    }

    proto.__identityEncodingPatched = true;
    proto.sendMetadata = async function (metadataPromise) {
        const headers = await metadataPromise;
        // Some gateways mis-handle grpc-js advertised encodings and treat
        // the request as gzip-compressed even when the payload is identity.
        headers.set("grpc-accept-encoding", "identity");
        headers.set("accept-encoding", "identity");
        headers.remove("grpc-encoding");
        return headers;
    };
}


function makeGrpcClient() {
    forceIdentityGrpcEncoding();
    const pkgDef = protoLoader.loadSync(PROTO_FILE, {
        includeDirs: [PROTO_ROOT],
        keepCase: false,
        longs: String,
        enums: String,
        defaults: false,
        oneofs: true,
    });

    const loaded: any = grpc.loadPackageDefinition(pkgDef);
    const Svc = loaded.sui.rpc.v2.TransactionExecutionService;
    return new Svc(GRPC_ADDR, grpc.credentials.createInsecure(), {
        "grpc.default_compression_algorithm": grpc.compressionAlgorithms.identity,
    });
}

/**
 * ExecuteTransaction RPC call with auth metadata.
 */
function grpcExecuteTransaction(client: any, req: any, authToken: string): Promise<any> {
    return new Promise((resolve, reject) => {
        const md = new grpc.Metadata();
        md.set("auth_token", authToken);
        client.ExecuteTransaction(req, md, (err: any, resp: any) => {
            if (err) return reject(err);
            resolve(resp);
        });
    });
}


async function main() {
    const { secretKey } = decodeSuiPrivateKey(SUI_PRIVATE_KEY);
    const keypair = Ed25519Keypair.fromSecretKey(secretKey);
    const sender = keypair.getPublicKey().toSuiAddress();
    console.log("sender:", sender);

    // Build a simple transfer transaction ---
    const tx = new Transaction();
    tx.setSender(sender);
    tx.setGasPrice(GAS_PRICE);

    // Split gas coin into payment coin, then transfer to recipient
    const [payCoin] = tx.splitCoins(tx.gas, [tx.pure.u64(SEND_AMOUNT_MIST)]);
    tx.transferObjects([payCoin], tx.pure.address(RECIPIENT));

    // JSON-RPC client used for tx.build()
    const httpTransport = new SuiHTTPTransport({
        url: RPC_URL,
        rpc: {
            headers: {
                auth_token: AUTH_TOKEN,
            },
        },
    });
    const httpClient = new SuiClient({ transport: httpTransport });

    // === Estimate gas & tip 
    const estimatedFee = await CaculateFee({ transaction: tx });
    console.log("Estimated Fee:", estimatedFee);

    tx.setGasBudget(estimatedFee.gasBudget);
    AddTip(tx, Math.max(estimatedFee.tipAmount, 1_000_000));

    // Build transaction
    const transactionBytes = await tx.build({ client: httpClient });

    // Sign transaction
    const signed = await keypair.signTransaction(transactionBytes);

    const sigBytes = Buffer.from(signed.signature, "base64");

    // Create gRPC client + send ExecuteTransaction request
    const grpcClient = makeGrpcClient();
    const req = {
        transaction: { bcs: { value: Buffer.from(transactionBytes) } },
        signatures: [{ bcs: { value: sigBytes } }],
    };

    // Send transaction
    const resp = await grpcExecuteTransaction(grpcClient, req, AUTH_TOKEN);
    console.log("grpc resp:", resp);
}

main().catch((err) => {
    console.error("Execution failed:", err);
    process.exit(1);
});
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.blockrazor.io/tc/transaction-submission/fast/sui/sui_executetransactionblock/ts.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
