Skip to content
Back to skills

Voltaire Effect Services

ASecurity

This skill should be used when the user asks about "ProviderService", "SignerService", "TransportService", "HttpTransport", "WebSocketTransport", "JSON-RPC Effect", "getBalance", "getBlock", "getBlockNumber", "sendTransaction", "voltaire-effect provider", "Layer.provide", or needs to understand the voltaire-effect service system.

  • 9 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 10, 2026
businesstypescriptgo

Security analysis

A100/100

Pro scans all 2 files and shows the line behind each finding

Scanned September 10, 2026

npx -y skills add cyotee/indexedex --skill voltaire-effect-services --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Voltaire Effect Services?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Voltaire Effect Services
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/cyotee-voltaire-effect-services/badge)](https://www.skillsdirectory.com/skills/cyotee-voltaire-effect-services)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: Voltaire Effect Services
description: This skill should be used when the user asks about "ProviderService", "SignerService", "TransportService", "HttpTransport", "WebSocketTransport", "JSON-RPC Effect", "getBalance", "getBlock", "getBlockNumber", "sendTransaction", "voltaire-effect provider", "Layer.provide", or needs to understand the voltaire-effect service system.
version: 0.1.0
---

# Voltaire Effect Services

## Overview

Services in voltaire-effect are typed dependencies declared in Effect signatures and injected via layers at program boundaries. This eliminates hidden globals and enables seamless test substitution.

```
┌─────────────────────────────────────────────────────────────────────────────┐
│                        SERVICE ARCHITECTURE                                  │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                              │
│  Application Code                                                           │
│  ┌───────────────────────────────────────────────────────────────────────┐  │
│  │  const bal = yield* getBalance(addr)                                  │  │
│  │  // Type: Effect<bigint, GetBalanceError, ProviderService>           │  │
│  └────────────────────────────────┬──────────────────────────────────────┘  │
│                                   │                                          │
│                      Effect.provide(layers)                                 │
│                                   │                                          │
│  Service Implementations          ▼                                          │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐                     │
│  │  Provider     │  │  Signer      │  │  Transport   │                     │
│  │  ─────────    │  │  ─────────   │  │  ──────────  │                     │
│  │  getBalance   │  │  sign        │  │  HTTP        │                     │
│  │  getBlock     │  │  signMessage │  │  WebSocket   │                     │
│  │  call         │  │  signTyped   │  │  Browser     │                     │
│  │  getLogs      │  │  sendTx      │  │  Test        │                     │
│  └──────────────┘  └──────────────┘  └──────────────┘                     │
│                                                                              │
└─────────────────────────────────────────────────────────────────────────────┘
```

## Provider Service

The primary service for reading blockchain state via JSON-RPC:

### Free Functions (Preferred)

Use free functions instead of yielding ProviderService directly:

```typescript
import { getBlockNumber, getBalance, getBlock, getLogs } from 'voltaire-effect'

const program = Effect.gen(function* () {
  const blockNum = yield* getBlockNumber()
  const balance = yield* getBalance(addr)
  const block = yield* getBlock({ blockNumber: blockNum })
  const logs = yield* getLogs({ fromBlock: 0n, toBlock: 'latest' })
  return { blockNum, balance, block, logs }
})
```

### Provider Operations

| Category | Functions |
|----------|-----------|
| **Blocks** | `getBlockNumber`, `getBlock`, `getBlockReceipts`, `getUncleCount` |
| **Accounts** | `getBalance`, `getTransactionCount`, `getCode`, `getStorageAt` |
| **Transactions** | `getTransaction`, `getTransactionReceipt`, `waitForTransactionReceipt` |
| **Simulation** | `readContract`, `multicall`, `simulateContract`, `simulateV1`, `simulateV2` |
| **Gas** | `getGasPrice`, `getMaxPriorityFeePerGas`, `getFeeHistory` |
| **Events** | `getLogs` |
| **Streaming** | `watchBlocks`, `subscribe`, `unsubscribe` |

### Layer Setup

```typescript
import { Provider, HttpTransport } from 'voltaire-effect'

const ProviderLayer = Provider.pipe(
  Layer.provide(HttpTransport('https://eth.llamarpc.com'))
)
```

## Transport Service

Manages the network connection. Three production transports and one test transport:

### HttpTransport

```typescript
import { HttpTransport } from 'voltaire-effect'

HttpTransport('https://eth.llamarpc.com')

// With options
HttpTransport({
  url: 'https://eth.llamarpc.com',
  timeout: '30 seconds',
  headers: { 'Authorization': 'Bearer ...' },
  retrySchedule: Schedule.exponential('500 millis').pipe(
    Schedule.jittered,
    Schedule.compose(Schedule.recurs(5))
  )
})
```

HTTP transport supports automatic request batching - concurrent requests are batched into a single HTTP call.

### WebSocketTransport

```typescript
import { WebSocketTransport } from 'voltaire-effect'
WebSocketTransport('wss://eth.llamarpc.com')
```

### BrowserTransport

```typescript
import { BrowserTransport } from 'voltaire-effect'
BrowserTransport()  // Uses window.ethereum
```

### TestTransport

```typescript
import { TestTransport } from 'voltaire-effect'

TestTransport({
  eth_blockNumber: '0x10',
  eth_getBalance: '0xde0b6b3a7640000'
})
```

## Signer Service

For state-changing operations. Unlike Provider, Signer still requires direct yielding:

```typescript
import { Signer } from 'voltaire-effect'

const program = Effect.gen(function* () {
  const signer = yield* Signer
  const txHash = yield* signer.sendTransaction({
    to: recipient,
    value: 1000000000000000000n
  })
  return txHash
})
```

### Signer from Provider

Create a Signer from an existing Provider and Account:

```typescript
const SignerLayer = Signer.fromProvider
// Requires ProviderService + AccountService
```

## Layer Composition

### Independent Services

```typescript
const AppLayer = Layer.mergeAll(TransportLayer, CryptoLayer)
```

### Dependent Services

```typescript
// Provider depends on Transport
const ProviderLayer = Provider.pipe(
  Layer.provide(HttpTransport('https://eth.llamarpc.com'))
)
```

### Full Stack

```typescript
import { Secp256k1Live } from 'voltaire-effect/crypto/Secp256k1'
import { KeccakLive } from 'voltaire-effect/crypto/Keccak256'

const FullLayer = Layer.mergeAll(
  ProviderLayer,
  Secp256k1Live,
  KeccakLive,
  SignerLayer
)

await Effect.runPromise(program.pipe(Effect.provide(FullLayer)))
```

## Per-Request Configuration

Override settings for individual calls using FiberRef helpers:

```typescript
import { withTimeout, withRetrySchedule, withoutCache, withTracing } from 'voltaire-effect'

// Timeout
const fast = yield* getBalance(addr).pipe(withTimeout("5 seconds"))

// Custom retry
const resilient = yield* getBalance(addr).pipe(
  withRetrySchedule(Schedule.recurs(1))
)

// Bypass cache
const fresh = yield* getBlockNumber().pipe(withoutCache)

// Debug tracing
const traced = yield* getBlock(n).pipe(withTracing())
```

## Multicall Batching

Reduce network overhead by batching contract reads:

```typescript
import { multicall } from 'voltaire-effect'

const results = yield* multicall({
  contracts: [
    { address: usdc, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
    { address: dai, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
    { address: weth, abi: erc20Abi, functionName: 'balanceOf', args: [user] },
  ],
  allowFailure: true  // Returns Either[] instead of throwing
})
```

## Reference Files

For detailed service method signatures, see:
- [references/service-catalog.md](references/service-catalog.md)

## Reference

- Provider docs: https://voltaire-effect.tevm.sh/services/provider
- Signer docs: https://voltaire-effect.tevm.sh/services/signer
- Transport docs: https://voltaire-effect.tevm.sh/services/presets

Files in this skill

  • SKILL.md8.5 KB
  • references/service-catalog.md3.3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.