Pilot playbook
For the prospect's engineers.
In short
A pilot lets your engineers see CryptoRail work on an operation your business runs, without installing anything and without putting anything at stake. It runs on our sandbox: a CryptoRail deployment we operate on test networks, which holds test keys and test money only. A sandbox is never for value, and it says so in its logs, on its health answer and on every screen built over it.
This page is the order we suggest: the tutorial first, then a set of failures provoked on purpose, then your own use case. Alongside, the journeys report shows what cannot be provoked on a shared sandbox (a node going down, a process killed mid-flight). At the end, the same integration moves to your own deployment, with your keys.
A pilot environment stood up in minutes with nothing installed on your side.
A sandbox says it is one: in its logs, on its health endpoint and on every screen built over it. It is never supported for value.
flowchart LR
T["1. The tutorial<br/>about an hour"] --> B["2. Break it on purpose<br/>refusals and failure reports"]
B --> U["3. Your use case<br/>your contract, rules, approvers, receiver"]
R["The journeys report<br/>what a sandbox cannot show"] -.-> U
U --> D["4. Decide where it runs<br/>self-hosted, library, or run for you"]
The sandbox
The sandbox is CryptoRail run under its sandbox profile on our own server, over public test
networks (Sepolia and Base Sepolia) and, for the packs that deploy contracts of their own, private
test networks of ours. It is the only profile in which the service may generate and keep keys
itself, which is why it is never used for anything of value.
Your engineers reach its API at https://www.xavinet.com/cryptorail/sandbox/, a sandbox, with their
own API key. Without a key the health check answers and declares the profile, so anyone can check
what they are talking to before sending anything.
You get a space of your own: a tenant, isolated from every other tenant of the sandbox, with its admin key, a key on Sepolia that the sandbox generated for you and keeps sealed, funded with test ether and 20 test USDC, and the tutorial’s rules as your tenant’s own policy version.
A space of your own on our sandbox, never for value: a tenant with its admin key, a key on Sepolia that the sandbox generated and holds, funded with test ether and test USDC, and rules that are your tenant's own policy version and bind nobody else.
A tenant sees only its own resources, proven on every route of the API on every change.
flowchart LR
E[Your engineer's terminal] -->|HTTPS, your tenant's key| API[Sandbox API<br/>profile: sandbox, never for value]
API --> K[Your sandbox key, sealed<br/>test funds only]
K -->|signed transactions| S[Sepolia, a test network]
API -->|signed webhooks| H[Your HTTPS endpoint]
O[Other tenants' spaces] -.-|isolated, never visible to you| API
The key is held by the sandbox because nothing of value is at stake; that is exactly what changes in your own deployment, where the key stays in your HSM, your cloud KMS or your signer. Your admin key is handed to you through a channel agreed with you, never by plain e-mail; keep it secret like any credential, even on a sandbox.
What you need
- A terminal with bash and
curl(Linux, macOS, or Git Bash or WSL on Windows). - Node.js 22 or later, for one verification script.
- Foundry’s
cast, to sign one approval. - An HTTPS address that receives POST requests and shows their headers and raw body: one of your systems, or for a first try a request-inspection service.
What to try, in order
1. The tutorial
The tutorial, in the customer portal, moves test USDC on Sepolia through the sandbox in six steps, showing every command and every answer:
| Step | What you do | What it shows |
|---|---|---|
| 1 | Look at the key the sandbox made for you | An identity holds an address and a signer reference, never a key |
| 2 | Register USDC by a partial ABI and read a balance | Any deployed contract, called by name |
| 3 | Send 1 USDC and follow it to CONFIRMED | The asynchronous answer, the history, finality |
| 4 | Read your policy, then try 50 USDC | A refusal before any signature, with the rule’s reason |
| 5 | Send 6 USDC, then approve it with cast | An operation that waits for an approver, who signs EIP-712 data |
| 6 | Subscribe to USDC leaving your key | A signed webhook, verified by the tutorial’s script |
What the tutorial shows is not a demonstration staged for it: every request it contains is executed by our checks on every change.
Every request of the getting-started tutorial is a file that a journey sends against a fork of Sepolia on every change, so a step that stops working cannot be merged.
Call a function by the contract's name in your registry: arguments checked against the ABI before anything is signed, and the contract's own errors decoded when it refuses.
Payout rules that read the payment itself: only listed beneficiaries, a daily cap in the token's own units, and approval above an amount.
Operations above a threshold wait for a quorum of approvers, who sign an EIP-712 digest that names neither nonce nor fee.
Signed webhooks, retried for about three days, then held in a dead-letter queue an operator can redeliver from.
2. Break it on purpose
The tutorial follows the happy path with one refusal. A pilot is where your engineers look for the edges. Each of these works in your space:
| Try | What you should see |
|---|---|
| Send the same transfer twice with the same idempotency key | The same transaction both times; a second payment is impossible |
| Reuse that idempotency key with a different body | A conflict, not a silent replacement |
Call transfer with an amount that is not a number | A refusal naming the argument, before any signature |
| Send more than the day’s limit has left | REJECTED_BY_POLICY, with the rule’s reason |
| Create a read-only key and submit with it | A refusal naming the role required and the role held |
| Send 6 USDC and have your approver reject it with a reason | The operation ends with that reason; nothing reaches the chain |
| Change one byte of a webhook body and verify it again | The signature no longer matches |
Every failure answers with the same report: the stage, a stable cause, whether a retry can work, and what to do. That report is what your systems will act on, so it is worth reading closely now.
Submitting the same intent twice with the same idempotency key returns the same transaction: a retry never becomes a second payment.
Every failure comes with a report: the stage, a stable cause, whether a retry can work and on what condition, and the suggested action.
Who may do what is checked per call: read-only, submitter, signer, sponsor, operator and admin roles.
Approvers are registered per tenant, their keys rotated and revoked; approvals expire and can be rejected with a reason, and the events of each step reach your workflow system.
The full history of every operation, every transition and every attempt with its time and cause, can be queried.
3. Your use case
Once the mechanics are clear, the pilot turns to one operation your business actually runs. We agree with you beforehand which operation, on which test network, with which approvals, which of your systems must hear about it, and what success looks like. The sandbox is then configured for it: your contract registered, your rules and approvers, your webhook receiver.
Five ready-made pilot packs cover the cases we are asked about most, each with a page on this site describing its use case and its evidence: stablecoin payouts, tokenisation, customer programmes, attestations and a treasury on Aave. Each has a console in the browser, a sandbox screen operated by us, which we use to show the pack live before your engineers drive the same operations over the API.
A ready-made stablecoin pilot pack for the sandbox: token addresses verified against the chain, an example payout policy and a one-command setup.
Each pilot pack has a console in the browser, behind a login, that operates the pack on a sandbox: the API key never reaches the browser and every screen says it is a sandbox with nothing of value.
What a shared sandbox cannot show: your own signer, operations at scale, and failures of the infrastructure itself. Those are what the journeys report is for.
How to read the journeys report
A journey is an end-to-end scenario written as named steps, positive and negative, run on every change against real local chains (Anvil, and Hyperledger Besu for free-gas networks). The run produces one HTML report; we send you the report of a recent run on request. There are 67 journeys, from the first call to a node going away, a reorganisation, a process stopped mid-flight, an HSM signature, a custodian signing hours later and one tenant trying to see another.
Every behaviour a consumer sees has a journey: a scenario run on every change whose HTML report shows, step by step, the request, the response, the resulting state, the events and, for a negative case, the failure report.
flowchart TD
J[A journey: one test in the report] --> RB[First attachment: the runbook<br/>read its Steps table first]
J --> S1[Step: request]
S1 --> S2[response]
S2 --> S3[resulting state]
S3 --> S4[events]
S4 --> S5[failure report, for a negative case]
J --> L[Links: the trace and the dashboard]
- Open one journey. Its annotations give the runbook, and links to the trace and the dashboard of its main transaction. Those links point at the observability stack of the machine that ran it, so in a report we send you they are context, not live links.
- Read the runbook first. It is the first attachment, written in plain language: what is being tested, what each step does, what you should see and why it is correct.
- Then each step. Its attachments are named
<step> · <what>: the request, the response, the resulting state, the events, and for a negative case the failure report, shown as prominently as a success. Some steps add what they measured: fees, nonces, calls to the node. - A red step is a defect, with the expected and received values, never something to retry. A journey that fails blocks the release like any other test.
Good starting points for a pilot: J23 (the first call from outside), J26 (what the API refuses and how it says so), J28 (the policy decides), J19 and J41 (approvals), J34 (webhooks), J39 (a node goes away), J43 (a sandbox for a pilot) and J63 (the tutorial itself). Every claim on this site names its journeys on the evidence page.
How a pilot becomes a deployment
Everything your engineers did keeps working the same way over the service’s API; what changes is who provides each part.
| In the pilot | In your deployment |
|---|---|
| Our sandbox, never for value, on test networks | Your service as a container image, the library inside your application, or the service run for you; your networks and node providers |
| A key the sandbox generated and holds | A key in your HSM, your cloud KMS or your own signer; CryptoRail never sees it |
| Test funds from faucets | Real funds, moved to your key by your treasury |
| One admin key for everything | One key per system with the narrowest role |
| Rules we wrote for your space | Your policy, signed off by the business owner of the operations |
| One approver with a key in a shell variable | Several approvers, each signing on their own device, with a quorum |
| A request-inspection endpoint | An HTTPS endpoint of yours that verifies every delivery |
flowchart TD
A["Pilot on the sandbox"] --> B["Decisions written down, with owners:<br/>networks, signers, approvers, limits, gas, events, operators"]
B --> C["Infrastructure on a test network:<br/>database, secrets, node provider"]
B --> K["Key custody chosen and set up<br/>(a specialist's task)"]
C --> D["Integration on the test network"]
K --> D
D --> P["Policy and approvers signed off"]
P --> R["Rehearsal: failures on purpose"]
R --> G["Production network, small limits first"]
The deployment plan in the customer portal says who does each step and gives a checklist per way of running it. Key custody is usually the longest task and starts as soon as the decisions are taken; the integration proceeds on a test network in the meantime.
Where each piece stands today:
Runs in your infrastructure, as a container image over your PostgreSQL, with schema migrations applied by an explicit command.
Embedded as a library in your Node.js application, or run as a service with an HTTP API described in OpenAPI and generated SDKs.
Your own signer keeps the key: CryptoRail prepares the exact bytes, your system signs them, CryptoRail verifies and broadcasts.
Keys in a hardware security module over PKCS#11 (Thales, Utimaco, Entrust, AWS CloudHSM): tested on every change against SoftHSM2, each vendor declared after a manual test on its device. Built, certification pending
Signing keys in AWS KMS, with the curve checked at startup. Built, certification pending
Run for you in production without ever holding a key of its own: signing stays on your side or in your own cloud account. Available for pilots
Releases per customer: the service image signed with cosign and pushed to that customer's project of a private registry that scans it, and the npm packages and an image archive published with their checksums. On the roadmap
Running CryptoRail for you in production waits for the external security audit; the security model lists what it must cover, and the security questionnaire answers the rest of your reviewer’s questions.
What it does not do
- The sandbox is never for value. It holds keys itself and has no technical lock on the networks it uses; its protection is that it says what it is everywhere.
- The shared sandbox does not show your own signer or operations at scale; those are tested in the journeys and, later, on your own test deployment.
- The sandbox makes no availability commitment. It runs on a single server of ours.
- The pilot consoles are not a product for your end users; they are sandbox screens we use to show a pack.
- Wallets and end-user interfaces. Not supported
Evidence
Every claim above links to its evidence on the evidence page. The main ones:
| Subject | Requirements and decisions | Journeys |
|---|---|---|
| The sandbox profile and spaces | NFR-SEC-10, FR-API-05, FR-POL-08, ADR-0005 | J43, J44, J63 |
| The tutorial, executed | FR-POL-07, FR-EVT-05, NFR-QA-07 | J63 |
| Refusals and failure reports | FR-TX-03, FR-TX-29, FR-API-06, FR-REG-07 | J02, J26 |
| Approvals | FR-APR-01, FR-APR-04, FR-APR-05, FR-APR-06 | J19, J41 |
| Pilot packs and consoles | FR-PLT-01, FR-PLT-07, FR-PLT-09 | J52, J53, J56, J57, J59, J61 |
| The journeys report | NFR-QA-07, NFR-QA-09 | every journey |
| From pilot to deployment | NFR-INT-03, FR-OPS-06, NFR-SEC-07, FR-OPS-10 | J27, J42 |