Ride REPL#
The Ride REPL evaluates Ride one line at a time, so you can try out an expression, a function or a built-in without writing and deploying a whole script. Connected to a node, it also reads live chain state: heights, balances, account data and transactions.
The REPL is published as @decentralchain/ride-repl, a JavaScript build of the Scala REPL in packages/ride/repl of the DecentralChain monorepo. It has no command-line front end: you call it from a script, as below, or embed it in a web page.
Note
Verified on 2026-10-25 with @decentralchain/ride-repl@1.6.2 on Node.js 24 and later, against the public Testnet node. The package ships no TypeScript declarations; the sample adds its own in ride-repl-types.d.ts.
Install#
npm install @decentralchain/ride-repl@1.6.2 @decentralchain/ts-lib-crypto@2.0.1
ts-lib-crypto provides the hash functions the REPL needs (see below).
Run the REPL#
import { blake2b, keccak, sha256 } from '@decentralchain/ts-lib-crypto';
import { repl, NodeConnectionSettings } from '@decentralchain/ride-repl';
// The REPL calls host functions for hashing and for reading chain state: provide them as globals
const hash = (fn: (bytes: Uint8Array) => Uint8Array) => (message: ArrayBuffer) =>
fn(new Uint8Array(message)).slice().buffer;
globalThis.blake2b256 = hash(blake2b);
globalThis.keccak256 = hash(keccak);
globalThis.sha256 = hash(sha256);
globalThis.httpGet = async ({ url }) => {
const response = await fetch(url);
return { status: response.status, body: await response.text() };
};
// Connect to the Testnet node (chain ID '!'), with `this` bound to an account
const session = repl(
new NodeConnectionSettings('https://testnet-node.decentralchain.io', '!'.charCodeAt(0), '31LAqgqVTLySNCPuYqgLAYhcgS76wvBaLr9'),
);
for (const line of [
'func double(n: Int) = n * 2',
'double(21)',
'sha256(toBytes("hello"))',
'height',
'dccBalance(this).regular',
'getString(this, "greeting")',
]) {
const { result, error } = await session.evaluate(line);
console.log(`> ${line}\n${result ?? `error: ${error}`}`);
}
Output on the Testnet:
> func double(n: Int) = n * 2
defined func double(n: Int): Int
> double(21)
res1: Int = 42
> sha256(toBytes("hello"))
res2: ByteVector = base58'42TEXg1vFAbcJ65y7qdYG9iCPvYfy3NDdVLd75akX2P5'
> height
res3: Int = 94609
> dccBalance(this).regular
res4: Int = 4696800003
> getString(this, "greeting")
res5: String|Unit = Unit
How It Works#
Host functions. The REPL doesn’t hash or fetch anything itself. It calls functions that the host page or script defines as globals:
Global |
Needed for |
|---|---|
|
Anything that reads the chain: |
|
The matching Ride hash functions |
|
|
Pure expressions such as arithmetic, strings, lists and your own functions need none of them.
Sessions. repl(settings) starts a session. Its methods are:
evaluate(line), which resolves to{ result }or{ error }. Aletorfuncstays defined for later lines.info(name)prints the declaration of a name you defined, andtotalInfo()lists everything in scope.clear()forgets your definitions.reconfigure(settings)returns a session connected to another node or account.
Connection settings. new NodeConnectionSettings(url, chainId, address) takes the node URL, the chain ID as a number ('!'.charCodeAt(0), 33, for the Testnet; '?', 63, for Mainnet) and the address that this refers to. Call repl() without settings to work offline.
Standard library. The REPL compiles each line against the latest standard library version it supports. A script you deploy declares its own with {-# STDLIB_VERSION ... #-}. A built-in that works in the REPL can therefore be missing from an older script version.
Limits#
Each line is one expression or one declaration. To try a whole dApp, or a function with
@Callable, compile it with a node instead; see Compile with a Node.FOLD<N>is a compile-time macro, and the REPL can’t parse it.The REPL only reads the chain. It never signs or broadcasts anything.