npm.io
0.1.0 • Published 16h ago

touchstone-sdk

Licence
Apache-2.0
Version
0.1.0
Deps
1
Size
34 kB
Vulns
0
Weekly
0

Touchstone SDK

The SDK is the small external-consumer surface for Touchstone policy gates and Registry v2 events. The checked-in deployment table carries the live addresses for both chains — the legacy registries and, since 2026-08-19, the Registry v2 deployments the owner approved — so a consumer reads real contracts out of the box.

Five-minute integration

npm install touchstone-sdk ethers

Or from a checkout of this repository:

cd sdk
npm ci
npm run build
npm test

Read a policy gate and execute only when it permits:

import { JsonRpcProvider, Wallet } from "ethers";
import {
  AssetGateClient,
  DEPLOYMENTS,
  GuardedActionClient,
  POLICIES,
} from "touchstone-sdk";

const provider = new JsonRpcProvider(process.env.RPC_URL, 1952);
const wallet = new Wallet(process.env.PRIVATE_KEY!, provider);
const gate = new AssetGateClient(
  process.env.GATE_ADDRESS!,
  POLICIES.disclosureFreshness.registryKey,
  wallet
);
const action = new GuardedActionClient(
  process.env.GUARDED_ACTION_ADDRESS!,
  wallet
);

const decision = await gate.check();
if (decision.allowed) await action.execute();

The example at examples/check-and-act.ts uses the same path with explicit environment variables. AssetGateClient.demand() separately exercises the gate's state-changing demand method and rejects a known refusal before submitting. Only GuardedActionClient.execute() executes the guarded action.

Registry event indexing

import { JsonRpcProvider } from "ethers";
import { DEPLOYMENTS, indexPublished } from "touchstone-sdk";

const deployment = DEPLOYMENTS.xlayerMainnet;
const events = await indexPublished(
  new JsonRpcProvider("https://rpc.xlayer.tech", deployment.chainId),
  deployment.v2RegistryAddress!,
  deployment.v2RegistryDeploymentBlock!,
  "latest"
);

The indexer reads logs in windows of 100 blocks because the public X Layer RPC rejects wider eth_getLogs ranges; pass { blockRange } as a fifth argument for a provider that allows more. Start from v2RegistryDeploymentBlock (or a checkpoint you persist) rather than block 0. The result includes both Published and Corrected events in canonical log order. Corrections carry kind: "corrected" and their non-null correctedSequence; consumers must process both kinds so a correction cannot leave cached permissive state behind.

Use policyRegistryKey(assetKey, policyId, version) rather than hand-hashing policy keys. The included policy ids are disclosure-freshness:1 and nav-settlement:1; they are the policy keys produced by this repository's committed manifests.

The SDK does not embed private keys, submit owner actions, or treat legacy v1 reports as v2 attestations. The Solidity interface in solidity/ITouchstoneGuard.sol is the minimum dependency for a consumer contract that wants to read a gate directly.

Registry v2 policy mapping

Use registryAssetKey(fullReportAssetKey) for the onchain asset key, including the complete #policy:<id>:<version> suffix. Use policyIdDigest(id, version) for the onchain policy id and policyDigestRoot(report.policy.policy_digest) for the policy root. The shared vector in fixtures/registry-v2-policy-vector.json locks these derivations to the Python publisher.

ERC-8021 attribution

Pass a registered Builder Code to GuardedActionClient.execute([code]). The SDK appends the canonical ERC-8021 schema-0 suffix to the action calldata. Touchstone's registered code is f0axgs7smtk2nfa7; its first attributed mainnet admission execution is public. External applications must register and pass their own code rather than reusing Touchstone's attribution.

Keywords