Skip to main content

Call native services

Native services expose Solidity-style interfaces at reserved addresses. They share the caller context, ledger policy and transaction journal with EVM execution.

Install the Solidity SDK​

Use @joltzu/solidity-sdk, the precompile SDK in cpp-node's sdk/solidity directory. The examples import its typed call libraries, interfaces and address constants instead of maintaining separate ABI declarations.

Install from a cpp-node checkout containing the SDK. Run this from your Solidity project, replacing the checkout path. If the project has no package.json, run npm init -y there first:

export JOLTZU_NODE_DIR=/path/to/cpp-node
npm install --save --install-links "$JOLTZU_NODE_DIR/sdk/solidity"

For Foundry, add this remapping to the [profile.default] section of the project configuration:

remappings = ["@joltzu/solidity-sdk/=node_modules/@joltzu/solidity-sdk/"]

The SDK is under development; public registry installation and a stable release version are TBD. Match your SDK checkout to the node version you target, and pin that revision for reproducible builds. --install-links installs the local package inside node_modules instead of linking outside the project, which keeps compiler imports within allowed directories. Reinstall after updating your SDK checkout.

Use the SDK's call libraries for native services. Precompile addresses have no EVM bytecode, and Solidity's high-level interface calls can reject targets without code. The libraries use CALL or STATICCALL, decode results and preserve native revert data. Import an interface when you need selectors, errors or event declarations.

Read an account policy​

The account service is 0x0000000000000000000000000000000000001009:

// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.37;

import {NativeAccounts} from "@joltzu/solidity-sdk/contracts/NativeAccounts.sol";

contract PolicyReader {
function policy(address account) external view returns (
uint64 policyVersion, uint64 nonce, uint8 threshold, uint8 signerCount
) {
return NativeAccounts.accountState(account);
}
}

Save this example as src/PolicyReader.sol in your configured Foundry project and run forge build.

Query an explicitly registered policy account. An unregistered address reverts with AccountError(4); its implicit key policy still governs top-level authority. The returned nonce is the account's authority nonce, separate from its ordinary transaction nonce.

With cast:

: "${JOLTZU_POLICY_ACCOUNT:?Set this to an explicitly registered policy account}"
cast call 0x0000000000000000000000000000000000001009 \
'accountState(address)(uint64,uint64,uint8,uint8)' \
"$JOLTZU_POLICY_ACCOUNT" \
--rpc-url http://127.0.0.1:30400

Design a write integration​

Select the service from the precompile directory and follow its linked integration guide. Use its SDK library and available encoding helpers; match the ABI and binary payload schema to the deployed version, and test authorization plus rollback. An ABI function accepting bytes does not mean arbitrary bytes are valid; these payloads are bounded, versioned protocol encodings.

Caller identity matters. A service authenticating the immediate caller sees your contract when called through that contract. It does not automatically treat tx.origin as the owner. Account relaying uses the account service's explicit authorization path.

Calls that move JOLT or native assets consume the same locks, energy and debit budgets as ordinary transfers. A passing EVM simulation does not authorize a signed write or establish future state.