--- title: Transports and codegen description: gRPC and gRPC-web on one endpoint, and how to generate clients from the protobuf definition. --- import { API_URL, API_JSON_URL, PROTO_URL } from "/snippets/vars.mdx"; Both services are served from a single endpoint at {API_URL}, in three transports. | Transport | Base URL | Use from | | --- | --- | --- | | gRPC over HTTP/2 | {API_URL} | Servers, CLIs, any native gRPC client. | | gRPC-web | {API_URL} | Browsers. CORS is open, so a page can call it directly. | | JSON over HTTP | {API_JSON_URL} | Anything that speaks HTTP. Same methods, REST-style routes. | The JSON transport is the same gRPC service behind a transcoder, not a second API: identical methods, identical field names, identical status codes. Read methods are `GET`s with query or path parameters, mutating methods are `POST`s with a JSON body, and revocation is a `DELETE`. The routes are in the [API reference](/api-reference/overview). ```bash curl https://api.hular.dev/json/v1/chains \ -H "x-api-key: $HULAR_API_KEY" ``` Errors arrive as the gRPC status mapped onto HTTP, with the code in the body: ```json { "code": 3, "message": "unsupported pair", "details": [] } ``` ## Services | Service | Auth | Purpose | | --- | --- | --- | | `hular.v1.HularApi` | Optional `x-api-key` | Quoting, catalog, order state. Public. | | `hular.v1.PartnerApi` | `authorization: Bearer ` | Partner sign-in, API keys, referral claims. | | `grpc.health.v1.Health` | None | Liveness and readiness. | | `grpc.reflection.v1.ServerReflection` | None | Schema discovery, v1 and v1alpha. | ## Generating a client The protobuf definition is the contract. Fetch it from {PROTO_URL} and generate stubs for your language. The SDK ships generated types and a configured transport: ```bash npm install @mayanfinance/hular-sdk ``` ```ts import { createHularClient } from "@mayanfinance/hular-sdk"; const client = createHularClient({ apiKey: process.env.HULAR_API_KEY, }); ``` To generate your own instead, use `buf` with `protoc-gen-es` and Connect's `createGrpcWebTransport` in browsers or `createGrpcTransport` on Node. ```bash protoc --go_out=. --go-grpc_out=. hular/v1/api.proto ``` ```go conn, err := grpc.NewClient(hularHost, grpc.WithTransportCredentials(creds)) client := hularv1.NewHularApiClient(conn) ctx := metadata.AppendToOutgoingContext(ctx, "x-api-key", key) quote, err := client.GetQuote(ctx, req) ``` ```bash tonic-build compile_protos("hular/v1/api.proto") ``` ```rust let mut client = HularApiClient::connect(hular_api_url).await?; let mut request = Request::new(quote_request); request.metadata_mut().insert("x-api-key", key.parse()?); let quote = client.get_quote(request).await?; ``` Server reflection is enabled, so no proto file is needed: ```bash grpcurl $HULAR_HOST list grpcurl \ -H "x-api-key: $HULAR_API_KEY" \ -d '{}' \ $HULAR_HOST hular.v1.HularApi/GetChains ``` ## Calling it without writing code Reflection means any gRPC client can discover the schema and call the API with no local setup. | Tool | How | | --- | --- | | Playground | Every method in this reference has a Send button. Fill the body, add your key, run it against mainnet. | | `grpcurl` | `grpcurl api.hular.dev:443 list` to enumerate, then call a method as above. | | `grpcui` | `grpcui api.hular.dev:443` opens a local browser UI over the live schema. | | Postman | Create a gRPC request, point it at the endpoint, and let it import the schema by reflection. | | Buf Studio | A hosted browser client that speaks gRPC-web against the endpoint directly. | There is no sandbox. Every one of these hits mainnet: quotes are real quotes, and partner methods really create keys, revoke them, and mark referral orders claimed. ## Field naming Protobuf field names are `snake_case` on the wire and in `grpcurl` payloads. Most generated clients expose them as `camelCase`, which is what the TypeScript examples in these docs use. Both refer to the same field. ## Value conventions | Kind | Representation | | --- | --- | | Token amounts | Decimal strings in base units. Never floats. | | USD values | Integer strings in micros. `1000000` is one dollar. | | Chain names | Lowercase strings: `arbitrum`, `solana`. | | EVM addresses | `0x`-prefixed hex. | | Solana addresses | Base58. | | Quote hashes | `0x`-prefixed 32-byte hex. | | Timestamps | RFC 3339 strings with microsecond precision. | Amounts are strings because they exceed the precision of a JSON number. Parse them into a big integer type, not a float, at every boundary. ## Health ```bash grpc_health_probe -addr $HULAR_HOST ``` The health service reports readiness, which flips to not-serving when the API cannot reach its dependencies. Use it for load balancer checks rather than polling `GetChains`.