Register your Wallet and Create Transactions with the TypeScript SDK
In the previous section, you created and saved a wallet to disk (.ukey).
In this section, you’ll:
- Load that wallet from a
.ukeyfile. - Open a transaction session against a ULedger node.
- Use that session to:
- register the wallet on-chain (
CREATE_WALLET), - and then send
DATAtransactions using the same wallet.
- register the wallet on-chain (
Conceptually:
- Register wallet = create your identity on-chain (
CREATE_WALLET). - Data transactions = write data to the chain (
DATA).
1. Prerequisites
Before you start, you should have:
- A running ULedger node (or access to dev nodes).
- A wallet file created in the previous guide (e.g.
./wallets/my_wallet.ukey). - A config file listing node endpoints.
Example config.json:
{
"nodeEndpoints": [
"https://your-node-url",
"https://your-node-2-url",
"https://your-node-3-url"
],
"verbose": true
}
2. Load configuration and wallet
import fs from "node:fs";
import { getULedgerSDK } from "@uledgerinc/typescript-sdk";
type Config = {
nodeEndpoints: string[];
verbose?: boolean;
};
function loadConfig(path: string): Config {
const raw = fs.readFileSync(path, "utf8");
const cfg = JSON.parse(raw) as Config;
if (!cfg.nodeEndpoints?.length) {
throw new Error("config must contain at least one node endpoint");
}
return cfg;
}
async function loadWalletFromFile(walletPath: string, password = "") {
const sdk = await getULedgerSDK();
const raw = fs.readFileSync(walletPath, "utf8");
const wallet = sdk.walletFromJson(raw, password);
return { sdk, wallet };
}
3. Create a transaction session
A TransactionSession connects to a node endpoint, fetches health/chain info, and stores the node’s ID as the suggestor.
Use the SDK helper:
sdk.createSession(nodeEndpoint, wallet)
function pickRandom<T>(items: T[]): T {
return items[Math.floor(Math.random() * items.length)];
}
async function newRandomSession(params: {
sdk: any;
nodeEndpoints: string[];
wallet: any;
}) {
const { sdk, nodeEndpoints, wallet } = params;
const nodeEndpoint = pickRandom(nodeEndpoints);
const session = await sdk.createSession(nodeEndpoint, wallet);
console.log("Using node:", session.getNodeEndpoint());
console.log("Suggestor (nodeId):", session.getSuggestor());
return session;
}
4. Register your wallet (registerWallet)
Before a wallet can participate in on-chain rules, it must usually be created on-chain.
The session exposes a high-level helper:
session.registerWallet(blockchainId, walletToRegister?, customAuthGroups?)
If you omit walletToRegister, it registers the session wallet (self-registration).
import { DEFAULT_ADMIN_AUTH_GROUP } from "@uledgerinc/typescript-sdk";
async function registerWallet(params: {
session: any;
blockchainId: string;
}) {
const { session, blockchainId } = params;
const tx = await session.registerWallet(
blockchainId,
undefined, // omit to self-register the session wallet
DEFAULT_ADMIN_AUTH_GROUP, // optional: defaults to admin full permissions
);
console.log("CREATE_WALLET txId:", tx.transactionId);
console.log("status:", tx.status);
console.log("output:", tx.output);
return tx;
}
5. Send DATA transactions (submitData)
:::info Send large integers as strings
Integers larger than 2^53 − 1 (Number.MAX_SAFE_INTEGER) are stored rounded and the transaction
still succeeds, so a 19-digit ID comes back as a different number.
// rounded on chain, becomes 1234567890123456800
{ orderId: 1234567890123456789 }
// safe, stored exactly as sent
{ orderId: "1234567890123456789" }
Send big integers as strings. JSON.stringify has the same limit on the way in, so the value is
already lossy before it leaves your process.
:::
Once the wallet is registered, you can submit data transactions.
Use:
session.submitData({ blockchainId, to, data })
data can be a string or an object.
async function sendDataTransaction(params: {
session: any;
blockchainId: string;
to: string;
data: string | object;
}) {
const { session, blockchainId, to, data } = params;
const tx = await session.submitData({
blockchainId,
to,
data,
});
console.log("DATA txId:", tx.transactionId);
console.log("status:", tx.status);
console.log("output:", tx.output);
console.log("payloadRoot:", tx.payloadRoot);
return tx;
}
:::warning A submitted transaction is not an accepted transaction
The status and output in the submit response describe the transaction as it was handed to the node.
They do not confirm it. Confirm it by reading the transaction back from the node until it has a
blockHeight and output is SUCCESS, or check GET {node}/blockchains/{blockchainId}/transactions/{transactionId}/status
for state: "committed". A transaction the network refuses is dropped and never appears, so if it has not
been confirmed within your wait window, treat it as failed and not as pending.
:::
6. Putting it all together
This program:
- Loads config + wallet.
- Creates a session.
- Registers the wallet (
CREATE_WALLET). - Sends a few
DATAtransactions.
import fs from "node:fs";
import { getULedgerSDK } from "@uledgerinc/typescript-sdk";
function pickRandom<T>(items: T[]): T {
return items[Math.floor(Math.random() * items.length)];
}
async function main() {
const configPath = "config.json";
const walletPath = "./wallets/my_wallet.ukey";
const password = "";
const blockchainId = "your-blockchain-id-here";
const txCount = 3;
const cfg = JSON.parse(fs.readFileSync(configPath, "utf8")) as {
nodeEndpoints: string[];
};
if (!cfg.nodeEndpoints?.length) throw new Error("Missing nodeEndpoints in config.json");
const sdk = await getULedgerSDK();
const walletJson = fs.readFileSync(walletPath, "utf8");
const wallet = sdk.walletFromJson(walletJson, password);
const nodeEndpoint = pickRandom(cfg.nodeEndpoints);
const session = await sdk.createSession(nodeEndpoint, wallet);
console.log("Using node:", session.getNodeEndpoint());
console.log("Suggestor (nodeId):", session.getSuggestor());
// 1) Register wallet (one-time per wallet/chain)
const regTx = await session.registerWallet(blockchainId);
console.log("Registered wallet tx:", regTx.transactionId, regTx.status, regTx.output);
// 2) Send DATA transactions
for (let i = 0; i < txCount; i++) {
const tx = await session.submitData({
blockchainId,
to: wallet.address,
data: { message: `hello from ${wallet.address}`, index: i + 1 },
});
console.log("DATA tx:", tx.transactionId, tx.status, tx.output, tx.payloadRoot);
}
}
main().catch(console.error);
Notes
registerWallet(...)creates aCREATE_WALLETtransaction internally.submitData(...)submits aDATAtransaction and serializes objects automatically.