Overview
TypeScript is a strongly-typed superset of JavaScript, offering improved developer experience and tooling support. This document provides a step-by-step process for setting up a TypeScript environment for interacting with Sui gRPC, including setting up a project, configuring dependencies, and implementing authentication mechanisms.
Authentication Required for TypeScript
Creates a client in order to communicate with a Sui gRPC service. It uses an endpoint URL and an authentication token for secure access.
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
// QuickNode endpoints consist of two crucial components: the endpoint name and the corresponding token
// For eg: QN Endpoint: https://docs-demo.sui-mainnet.quiknode.pro/abcde123456789
// endpoint will be: docs-demo.sui-mainnet.quiknode.pro:9000 {9000 is the port number for Sui gRPC}
// token will be : abcde123456789
const ENDPOINT = 'docs-demo.sui-mainnet.quiknode.pro:9000';
const TOKEN = 'abcde123456789';
// Load proto and create client
const proto = grpc.loadPackageDefinition(packageDefinition) as any;
const LedgerService = proto.sui.rpc.v2beta.LedgerService;
const client = new LedgerService(ENDPOINT, grpc.credentials.createSsl());
// Prepare authentication metadata
const metadata = new grpc.Metadata();
metadata.add('x-token', TOKEN);
Setting up TypeScript
To run our TypeScript code examples, you'll need to have Node.js installed, as TypeScript is built on top of JavaScript. Ensure you also have TypeScript installed globally by running:
Step 1: Create a New Project Directory
Create a dedicated directory for your Sui gRPC project and navigate into it:
mkdir sui-grpc
cd sui-grpc
Step 2: Initialize a Node.js Project
Create a package.json file for your project to manage dependencies and scripts:
npm init -y
Step 3: Install gRPC and Protobuf Dependencies
Ensure you have Node.js (v16 or higher) installed on your machine. Install the core gRPC and Protocol Buffer libraries by following commands:
npm install @grpc/grpc-js @grpc/proto-loader
Install development dependencies for TypeScript execution:
npm install -D tsx
Step 4: Organize Your Project Directory
Create a protos
folder to store the original Protocol Buffer definition files:
mkdir protos
Download the official Sui proto files from the MystenLabs/sui repository. Extract and place the entire sui
directory structure into your newly created protos
folder. Alternatively, you can run the following commands:
# Clone the repository with minimal depth
git clone https://github.com/MystenLabs/sui.git --depth=1
# Copy the proto files to your working directory
cp -r sui/crates/sui-rpc-api/proto protos
# Remove the cloned repository (optional)
rm -rf sui
Your project structure should look like this:
sui-grpc/
├── protos/
│ └── sui/
│ └── rpc/
│ └── v2beta/
│ ├── ledger_service.proto
│ ├── common.proto
│ ├── transaction.proto
│ └── ... (other proto files)
└── package.json
Step 5: Create a client.ts File
Set up a client.ts file for implementing client or server logic:
touch client.ts
You can copy and paste the following sample code into your client.ts file to get started. The example demonstrates how to interact with the Sui gRPC service to fetch object information. Make sure to update the endpoint and token in the below code with your endpoint values.
import * as grpc from '@grpc/grpc-js';
import * as protoLoader from '@grpc/proto-loader';
import * as path from 'path';
// Proto file path (protos/sui/rpc/v2beta/ledger_service.proto or protos/sui/rpc/v2beta/transaction_execution_service.proto)
const PROTO_PATH = path.join(__dirname, 'protos/sui/rpc/v2beta/ledger_service.proto');
// Load proto definitions
const packageDefinition = protoLoader.loadSync(PROTO_PATH, {
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true,
includeDirs: [path.join(__dirname, 'protos')],
});
const suiProto = grpc.loadPackageDefinition(packageDefinition) as any;
const LedgerService = suiProto.sui.rpc.v2beta.LedgerService;
// QuickNode endpoints consist of two crucial components: the endpoint name and the corresponding token
// For eg: QN Endpoint: https://docs-demo.sui-mainnet.quiknode.pro/abcde123456789
// endpoint will be: docs-demo.sui-mainnet.quiknode.pro:9000 {9000 is the port number for Sui gRPC}
// token will be : abcde123456789
const endpoint = 'docs-demo.sui-mainnet.quiknode.pro:9000';
const token = 'abcde123456789';
// Create gRPC client
const client = new LedgerService(endpoint, grpc.credentials.createSsl());
// Prepare metadata
const metadata = new grpc.Metadata();
metadata.add('x-token', token);
// Define the request
const request = {
object_id: '0x27c4fdb3b846aa3ae4a65ef5127a309aa3c1f466671471a806d8912a18b253e8',
read_mask: {
paths: [
'bcs',
'object_id',
'version',
'digest',
'owner',
'object_type',
'has_public_transfer',
'contents',
'modules',
'type_origin_table',
'linkage_table',
'previous_transaction',
'storage_rebate'
],
},
};
// Decode Buffer/Uint8Array fields into hex strings
function decodeBytes(obj: any): any {
if (Array.isArray(obj)) {
return obj.map(decodeBytes);
} else if (obj && typeof obj === 'object') {
const result: any = {};
for (const key in obj) {
const val = obj[key];
if (val instanceof Uint8Array || (val?.type === 'Buffer' && Array.isArray(val.data))) {
const buffer = val instanceof Uint8Array ? val : Buffer.from(val.data);
result[key] = buffer.toString('hex');
} else {
result[key] = decodeBytes(val);
}
}
return result;
} else {
return obj;
}
}
// Make the gRPC call
client.GetObject(request, metadata, (err: any, response: any) => {
if (err) {
console.error('gRPC Error:', err);
} else {
const decoded = decodeBytes(response);
console.log('Response:', JSON.stringify(decoded, null, 2));
}
});
Step 6: Run Your Code
You can run your client.ts file by the following command:
npx tsx client.ts
We ❤️ Feedback!
If you have any feedback or questions about this documentation, let us know. We'd love to hear from you!