The TN SDK provides developers with tools to interact with the TRUF.NETWORK, a decentralized platform for publishing, composing, and consuming economic data streams.
TN supports two main types of streams:
- Primitive Streams: Direct data sources from providers.
- Composed Streams: Aggregate data from multiple streams using weights.
These streams form the basis of economic data flows on the TRUF.NETWORK, allowing for flexible and transparent data provision and consumption.
A streamID
is an identifier used in the TRUF.NETWORK (TN) to identify the deployed contract. It is a unique string generated from a descriptive name, such as an English name, to ensure easy reference and management of data streams.
For a deeper dive into these and other foundational concepts, please see our Core Concepts documentation.
This section will guide you through the initial setup and a basic client initialization. For a more detailed step-by-step tutorial, please refer to our Getting Started Guide.
- Node.js 18 or later (For enabling Explorer-related features, please use Node.js 18)
- A valid Ethereum private key
npm install @trufnetwork/sdk-js
# or
yarn add @trufnetwork/sdk-js
# or
pnpm install @trufnetwork/sdk-js
Here's a quick example of how to initialize the client for a Node.js environment. The initialized client
and wallet
instances can typically be reused for subsequent operations shown in later examples.
import { NodeTNClient } from "@trufnetwork/sdk-js";
import { Wallet } from "ethers";
// Create a wallet.
const wallet = new Wallet("YOUR_PRIVATE_KEY");
// Initialize client for Node.js
const client = new NodeTNClient({
// Use the mainnet gateway or your own local node endpoint
endpoint: "https://gateway.mainnet.truf.network", // e.g., http://localhost:8484 for a local node
signerInfo: {
address: wallet.address,
signer: wallet, // Any object that implements signMessage
},
chainId: "tn-v2", // or use NodeTNClient.getDefaultChainId(endpoint)
});
Note:
YOUR_PRIVATE_KEY
is a placeholder. Never hardcode private keys. For Node.js, store it in a.env
file (e.g.,PRIVATE_KEY="0xabc..."
) and usedotenv
(npm install dotenv
) to load it asprocess.env.PRIVATE_KEY
. Your private key is essential for signing and authenticating requests.
Import the client relevant to your JavaScript environment:
// For Node.js applications
import { NodeTNClient } from "@trufnetwork/sdk-js";
// For browser applications
import { BrowserTNClient } from "@trufnetwork/sdk-js";
For detailed configuration options for both clients, please see our API Reference.
Here is a common use case for the SDK. For a wider range of examples and advanced scenarios, please explore the example scripts in this repository and our detailed API Reference.
Assuming you have initialized client
as shown in the Basic Client Initialization section, you can read from any public stream. The following example demonstrates how to read from AI Index.
import { StreamId, EthereumAddress } from "@trufnetwork/sdk-js";
// Create a stream locator for the AI Index
const aiIndexLocator = {
streamId: StreamId.fromString("st527bf3897aa3d6f5ae15a0af846db6").throw(),
dataProvider: EthereumAddress.fromString(
"0x4710a8d8f0d845da110086812a32de6d90d7ff5c"
).throw(),
};
// Load the action client
const streamAction = client.loadAction();
// Get the latest records
const records = await streamAction.getRecord({
stream: aiIndexLocator,
});
Note: For streams that you have deployed using the same wallet, you can use
client.ownStreamLocator(streamId)
as a convenient shorthand to create the stream locator. This is equivalent to specifying thestreamId
and your wallet'sdataProvider
address explicitly.
You can create two types of streams in the TRUF.NETWORK: Primitive and Composed streams.
A primitive stream is a direct data source that allows you to insert individual records.
// Generate a unique stream ID
const streamId = await StreamId.generate("my_first_stream");
// Deploy the primitive stream
const deployResult = await client.deployStream(streamId, StreamType.Primitive);
// Load the primitive action to insert records
const primitiveAction = client.loadPrimitiveAction();
// Insert a record
await primitiveAction.insertRecord({
stream: client.ownStreamLocator(streamId),
eventTime: Math.floor(Date.now() / 1000), // Unix timestamp in seconds
value: "100.50", // Value as a string for precision
});
A composed stream aggregates data from multiple primitive streams with configurable weights.
// Generate stream IDs for parent and child streams
const parentStreamId = await StreamId.generate("composite_economic_index");
const childStream1Id = await StreamId.generate("child_stream_1");
const childStream2Id = await StreamId.generate("child_stream_2");
// Deploy the parent composed stream
await client.deployStream(parentStreamId, StreamType.Composed);
// Load the composed action to set taxonomy
const composedAction = client.loadComposedAction();
// Set stream taxonomy (how child streams are combined)
await composedAction.setTaxonomy({
stream: client.ownStreamLocator(parentStreamId),
taxonomyItems: [
{
childStream: client.ownStreamLocator(childStream1Id),
weight: "0.6", // 60% weight
},
{
childStream: client.ownStreamLocator(childStream2Id),
weight: "0.4", // 40% weight
},
],
startDate: Math.floor(Date.now() / 1000), // When this taxonomy becomes effective
});
You can control stream visibility and access permissions:
// Set read visibility (public or private)
await streamAction.setReadVisibility(
client.ownStreamLocator(streamId),
visibility.public // or visibility.private
);
// Allow specific wallets to read the stream
await streamAction.allowReadWallet(
client.ownStreamLocator(streamId),
EthereumAddress.fromString("0x1234...")
);
Notes:
- Stream IDs are generated deterministically from a descriptive string.
- Always use string values for numeric data to maintain precision.
- Weights in composed streams must sum to 1.0.
- Streams can be made public or private, with fine-grained access control.
If you are running your own TRUF.NETWORK node, you can configure the SDK to interact with your local instance by changing the endpoint
in the client configuration, as shown in the Basic Client Initialization section. This is useful for development, testing, or when operating within a private network.
For more detailed instructions, prerequisites, and examples, please see our Using the SDK with Your Local Node Guide.
This package works with Deno when using the --allow-net
permission flag:
import { ... } from "npm:@trufnetwork/sdk-js"
By default, some dependencies require environment permissions. If you need to run without environment permissions, please see this GitHub issue for potential workarounds.
Need Immediate Deno Support?
- Open an issue on our GitHub repository
- Reach out to our support team
- Provide details of your specific use case
When deploying to some serverless environments, Node.js modules like crypto-hash
may encounter compatibility issues. To resolve this, you can create a shim for the
crypto-hash
module and use
Webpack's NormalModuleReplacementPlugin
to replace it during the build process.
Add a new file named crypto-hash-sync.js
to your project:
import { createHash } from "crypto";
export const sha1 = (input) => createHash("sha1").update(input).digest("hex");
export const sha256 = (input) =>
createHash("sha256").update(input).digest("hex");
export const sha384 = (input) =>
createHash("sha384").update(input).digest("hex");
export const sha512 = (input) =>
createHash("sha512").update(input).digest("hex");
If you are using Webpack (common in Next.js or custom serverless setups), modify your configuration (e.g., next.config.js
or webpack.config.js
):
const path = require("path");
module.exports = {
// ... other configurations
webpack: (config, { isServer, webpack }) => {
// Add shim for crypto-hash
config.plugins.push(
new webpack.NormalModuleReplacementPlugin(
/crypto-hash/,
path.resolve(__dirname, "crypto-hash-sync.js")
)
);
return config;
},
// ... other configurations
};
For other bundlers or serverless platforms, consult their documentation on module aliasing or replacement.
To continue learning and building with the TN SDK, explore the following resources:
-
Tutorials & Guides:
- Getting Started Guide: A detailed walkthrough for setting up and making your first interactions with the SDK.
- Core Concepts Explained: Understand the fundamental building blocks of the TRUF.NETWORK and the SDK.
-
Detailed Documentation:
- API Reference: Comprehensive details on all SDK classes, methods, types, and parameters.
- Examples & Demos:
- Whitepaper:
The mainnet network is available at: https://gateway.mainnet.truf.network
For support, please open an issue on our GitHub repository.
Licensed under the Apache License, Version 2.0. See LICENSE.md for details.