From device to onchain wallet.
Comprehensive developer guides for hardware roboticists, smart contract engineers, and fleet operators. Official SDK libraries available in TypeScript, Python, and ROS2.
Integrate in three lines of code.
The target design signs inside a hardware secure element so keys never leave the device. That support is planned: the SDK key stores are software today. Gas is sponsored by the PINELY Paymaster.
// 1. Install the SDK
bun add @pinely/sdk
// 2. Connect. The development key store is for testing only: never use it in production.
import { Pinely } from "@pinely/sdk";
const pinely = await Pinely.connect({
chain: "elysiumTestnet", // chain 99801
registryAddress: "0x...", // MachineRegistry, from the address book
paymasterAddress: "0x...", // PinelyPaymaster
keyStore: { type: "file-dev-only", privateKey: "0x..." },
rpcUrl: process.env.RPC_URL_ELYSIUM_TESTNET,
});
const machine = await pinely.machines.create({ name: "charger-01", operator: "0x..." });
// 3. Pay a charging dock over HTTP 402. The SDK reads the dock's 402 challenge, has the
// Facilitator prepare a gas-sponsored UserOperation, checks it, signs it and submits it.
const result = await machine.pay({
url: "https://facilitator.example/v1/charge/dock-001",
maxAmount: 100_000n, // 0.10 USDC (6 decimals): the most this machine will pay
facilitatorUrl: "https://facilitator.example",
});
// "settled" only after the Facilitator confirms the payment onchain.
console.log(result.status, result.txHash);
// Command line equivalent:
// pinely pay --url https://facilitator.example/v1/charge/dock-001 \
// --max-amount 100000 --facilitator https://facilitator.exampleThe Four-Stage Execution Pipeline
How an autonomous physical device triggers a transaction on a public street and settles on Elysium without custody risk.
Device signing
The device builds an EIP-712 spend intent and signs it with its session key. The goal is to hold that key in a secure element such as the NXP SE050 or a TPM 2.0 so it cannot be exported; today the SDK signs with a software key store.
UserOp Dispatch
The intent becomes an ERC-4337 UserOperation. The machine signs its hash with its session key and submits it to a bundler.
PinelyPaymaster
Paymaster checks the account's prepaid USDC credit, advances native HYPE gas for EVM execution, and bills it in canonical USDC.
PinelyHook (Uniswap v4, Stage 2)
Hook evaluates 4 immutable guards (Machine Gate, Spend Policy, Kill Switch, and Tier Fee Cooling). Any violation reverts onchain fail-closed.
How a machine pays over HTTP 402.
The Facilitator lets a charging dock, an API or a data provider get paid in USDC by a machine, using the x402 pattern. It prepares and confirms the payment; it never holds the machine's key.
The service answers HTTP 402
The machine asks a charging dock, API or data provider for a resource. The provider answers HTTP 402 with the payment requirements: the amount, USDC, the address to pay and the network.
The machine signs what it will pay
The machine signs an EIP-712 Payment402Intent: machine ID, resource, amount, a one-time nonce and a deadline. The signing domain is PINELYFacilitator, bound to the chain ID.
The Facilitator checks and prepares
It checks the signature against the session key registered in MachineRegistry, rejects an expired or reused intent and a frozen machine or fleet, then returns an unsigned, gas-sponsored UserOperation.
The machine verifies before it signs
The SDK checks the UserOperation field by field and refuses one that pays another recipient or token, a larger amount, another Paymaster or inflated gas. Only then does it sign and submit.
Confirmation unlocks access
The Facilitator returns an access token only after the payment is confirmed onchain. The provider receives the amount minus the Facilitator fee.
What you can rely on
- Rail: ERC-4337 with the PINELY Paymaster. The machine needs no HYPE for gas.
- Fee: 0.1% of each payment (10 basis points by default), taken only when a fee recipient is configured. The SDK refuses a fee above its limit, 1% by default.
- Never simulated: without a Facilitator URL the SDK returns a failed result, never a made-up success.
- Replay protection: every intent carries a one-time nonce and a deadline; a reused nonce is rejected.
- Spend limits: enforced onchain by the Stage 2 PinelyHook Spend Policy, not by the Facilitator.
Facilitator endpoints
| Endpoint | Purpose |
|---|---|
| GET /v1/charge/:id | Reference HTTP 402 challenge for a charging request |
| GET /v1/capability | Reports the settlement rail |
| POST /v1/verify | Verifies a signed payment intent before payment |
| POST /v1/settle/prepare | Returns the unsigned, gas-sponsored UserOperation |
| POST /v1/settle | Submits the signed UserOperation and returns the access token after confirmation |
Official SSOT Contract Registry
Official deployment addresses synchronized from Foundry compilation artifacts across Elysium Testnet (99801) and Mainnet (99901).
| Contract Name | Functional Scope | Rollout Stage | Onchain Address (SSOT) | Action |
|---|---|---|---|---|
| MachineRegistry | Hardware chip registry & onchain status tracker | Stage 1 | 0xbf1f9ea8...547fbc07 | |
| PinelyAccountFactory | ERC-4337 factory with CREATE2 deterministic salt (PINELY_ACCOUNT_V1) | Stage 1 | 0xdab0099e...7ce18227 | |
| PinelyPaymaster | Native HYPE gas sponsor & canonical USDC settlement with bounded rates | Stage 1 | 0x9960a800...e5aea936 | |
| SurplusSweeper | Automated machine surplus keeper & Safe treasury sweeper | Stage 1 | 0xb1f5c1d5...b1fcd2ba | |
| Canonical USDC | Elysium official 6-decimal bridged settlement stablecoin | Official | 0x7D29d804...edcB47b2 | |
| Wrapped HYPE (WHYPE) | Canonical ERC-20 wrapped native gas token | Official | 0xCD57F65c...46E1F234 | |
| ERC-4337 EntryPoint v0.7 | Canonical ERC-4337 v0.7 EntryPoint singleton | Official | 0x00000000...f37da032 | |
| Multicall3 | Canonical batch and read aggregator | Official | 0xcA11bde0...3976CA11 | |
| Safe Multisig Factory | Safe 1.3.0 proxy factory for 2-of-3 multisig governance & treasury | Governance | 0xa6B71E26...6a896AB2 | |
| Uniswap v4 PoolManager | Singleton liquidity manager for Elysium private pools | Stage 2 | Stage 2 Planned | — |
| PinelyHook | Uniswap v4 BaseHook: Machine, Policy, Freeze & Tier guards | Stage 2 | Stage 2 Planned | — |
| PinelyRouter | Stateless swap router binding machine session key to pool via hookData | Stage 2 | Stage 2 Planned | — |
| BurnVault | Protocol fee recipient & permissionless $PINELY burner | Stage 2 | Stage 2 Planned | — |
| PinelyStake | Reputational staking vault with 7-day timelock cooldown | Stage 2 | Stage 2 Planned | — |
Arbitrum Nitro Orbit on Elysium produces blocks every 100–200ms. Never assume block.number as a unit of time. Always evaluate daily limits, cooldowns, and authorization deadlines strictly using block.timestamp. In addition, viem's built-in elysiumTestnet refers to a legacy chain (1338); always import the canonical chain configuration from @pinely/shared/chains.