> ## Documentation Index
> Fetch the complete documentation index at: https://docs.inco.org/llms.txt
> Use this file to discover all available pages before exploring further.

# Node.js

> Use the same client and session flow in services, scripts, native ESM, and CommonJS.

## Run a standalone example

Requires Node.js 20+.

```bash theme={null}
mkdir ctoken-example
cd ctoken-example
npm init -y
npm install @inco/ctoken@^0.2.0 viem @inco/lightning-js
```

Save the following as `ctoken.mjs`:

```js theme={null}
import { createPublicClient, http } from "viem";
import { baseSepolia } from "viem/chains";
import { CTokenClient } from "@inco/ctoken";

const rpcUrl = process.env.RPC_URL;
if (!rpcUrl) throw new Error("Set RPC_URL to your Base Sepolia read endpoint.");

const publicClient = createPublicClient({
  chain: baseSepolia,
  transport: http(rpcUrl),
});
const ctoken = new CTokenClient({ network: "baseSepolia", publicClient });
const token = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";

console.log("USDC wrapper:", await ctoken.wrapperOf({ token }));
```

Run it with your own Base Sepolia read endpoint:

```bash theme={null}
RPC_URL="https://your-read-endpoint.example" node ctoken.mjs
```

This wrapper lookup needs no wallet or indexer.

## Supply your own wallet client

```ts theme={null}
const ctoken = new CTokenClient({ network: "baseSepolia", publicClient, walletClient });
```

Add a wallet client with an account for owner balances, signing, and transactions. Node uses the same constructor and [sessions](/ctoken/sessions) as browsers.

## Example: an external signing RPC

```ts theme={null}
import { createPublicClient, createWalletClient, getAddress, http } from "viem";
import { baseSepolia } from "viem/chains";
import { CTokenClient } from "@inco/ctoken";

const readRpc = process.env.RPC_URL;
if (!readRpc) throw new Error("Configure your read RPC endpoint.");
const publicClient = createPublicClient({ chain: baseSepolia, transport: http(readRpc) });
const address = process.env.WALLET_ADDRESS;
const signingRpc = process.env.WALLET_RPC_URL;
if (!address || !signingRpc) throw new Error("Configure your signing service.");

const walletClient = createWalletClient({
  account: getAddress(address),
  chain: baseSepolia,
  transport: http(signingRpc),
});
const ctoken = new CTokenClient({
  network: "baseSepolia",
  publicClient,
  walletClient,
});

const token = "0x036CbD53842c5426634e7929541eC2318f3dCF7e";
const balance = await ctoken.publicBalanceExact({ token });
console.log(balance.formatted);
```

The signing RPC must sign and submit for your account; a public read RPC cannot. Keep signing credentials in your wallet integration.

Next: [transactions](/ctoken/transactions) · [testnet faucets](/ctoken/overview#testnet-tokens).

## CJS and ESM

```js theme={null}
// CommonJS
const { CTokenClient } = require("@inco/ctoken");
const ctoken = new CTokenClient({ network: "baseSepolia", publicClient, walletClient });
```

The standalone example above uses ESM.
