import { SuiChainId } from '@sentio/chain' import { ChainRpc, Endpoints } from '@sentio/runtime' import { SuiGrpcClient } from '@mysten/sui/grpc' import { GrpcWebFetchTransport } from '@protobuf-ts/grpcweb-transport' export type SuiNetwork = SuiChainId export const SuiNetwork = { MAIN_NET: SuiChainId.SUI_MAINNET, TEST_NET: SuiChainId.SUI_TESTNET } function inferNetworkFromUrl(url: string): string { if (url.includes('mainnet')) return 'mainnet' if (url.includes('testnet')) return 'testnet' if (url.includes('devnet')) return 'devnet' if (url.includes('localnet') || url.includes('127.0.0.1') || url.includes('localhost')) return 'localnet' return 'custom' } function rpcFor(network: SuiNetwork): ChainRpc { return Endpoints.INSTANCE.chainRpc.get(network) ?? { url: getRpcEndpoint(network) } } // gRPC client used for the MoveCoder, generated view functions, and exposed to // processor handlers via `ctx.client`. @typemove/sui v2 is gRPC-only. export function getClient(network: SuiNetwork): SuiGrpcClient { const { url, headers } = rpcFor(network) // Chain-config headers (e.g. the X-Forwarded-Host routing key the rpc-node // proxy reads) must be sent on every request. SuiGrpcClient drops its `meta` // option and its `fetchInit` can't carry headers, so we build the transport // ourselves. const transport = new GrpcWebFetchTransport({ baseUrl: url, // GrpcWebFetchTransport defaults to the grpc-web-text (base64) format, which // our rpc-node/super-node proxy rejects with 415. We run under Node, whose // fetch handles binary streams fine, so use the binary format // (application/grpc-web+proto) the proxy supports. format: 'binary', // GrpcWebFetchTransport has no `headers` option: gRPC models per-request // headers as `meta` (metadata), which the grpc-web transport then serializes // as HTTP request headers on the wire. So our HTTP headers go in `meta`. meta: headers }) return new SuiGrpcClient({ network: inferNetworkFromUrl(url) as any, transport }) } export function getRpcEndpoint(network: SuiNetwork): string { switch (network) { case SuiNetwork.TEST_NET: return 'https://fullnode.testnet.sui.io:443' } return 'https://fullnode.mainnet.sui.io:443' }