Skip to content

Integration with viem

RISE Chain's shreds module leverages viem's client extension system to provide seamless integration with the Shred API. You can extend any viem client with shred actions for full type safety and native integration.

Client Extension with Actions

Extending Clients with shredActions

The recommended approach is to extend your viem clients with shredActions from shreds/viem:

import { createPublicClient, createWalletClient, http, webSocket } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { riseTestnet } from 'viem/chains'
import { shredActions } from 'shreds/viem'
 
// Extend public client with shred actions
const publicClient = createPublicClient({
  chain: riseTestnet,
  transport: http()
}).extend(shredActions)
 
// Extend WebSocket client for subscriptions
const wsClient = createPublicClient({
  chain: riseTestnet,
  transport: webSocket()
}).extend(shredActions)
 
// Extend wallet client for transactions
const account = privateKeyToAccount('0x...')
const walletClient = createWalletClient({
  account,
  chain: riseTestnet,
  transport: http()
}).extend(shredActions)

Available Actions

Once extended, your clients have access to all shred-specific methods with full TypeScript support:

// Watch for new shreds (requires WebSocket transport)
const unwatch = publicClient.watchShreds({
  onShred: (shred) => {
    console.log('New shred:', shred.hash)
  }
})
 
// Send raw transaction synchronously
const receipt = await publicClient.sendRawTransactionSync({
  serializedTransaction: '0x...'
})

Using Actions Directly

You can also use each action directly by importing it individually and passing in a client:

import { 
  watchShreds, 
  sendRawTransactionSync
} from 'shreds/viem'
import { createPublicClient, createWalletClient, http, webSocket } from 'viem'
import { riseTestnet } from 'viem/chains'
 
// Create standard viem clients
const publicClient = createPublicClient({
  chain: riseTestnet,
  transport: webSocket() // WebSocket required for watchShreds
})
 
const walletClient = createWalletClient({
  account,
  chain: riseTestnet,
  transport: http()
})
 
// Use actions directly with clients
const unwatch = watchShreds(publicClient, {
  onShred: (shred) => console.log('New shred:', shred)
})
 
const receipt = await sendRawTransactionSync(walletClient, {
  serializedTransaction: '0x...'
})

Watching for Events

On RISE Chain, you can use the standard viem watchEvent and watchContractEvent actions to listen for events. These automatically receive events from shreds instead of blocks, providing faster and more granular updates.

watchEvent

Watch for specific events using the standard viem action:

import { createPublicClient, webSocket } from 'viem'
import { riseTestnet } from 'viem/chains'
 
const client = createPublicClient({
  chain: riseTestnet,
  transport: webSocket(),
})
 
// Define the event ABI you want to watch
const transferEvent = {
  type: 'event',
  name: 'Transfer',
  inputs: [
    { name: 'from', type: 'address', indexed: true },
    { name: 'to', type: 'address', indexed: true },
    { name: 'value', type: 'uint256', indexed: false },
  ],
} as const
 
// Watch for Transfer events - automatically receives events from shreds
const unsubscribe = client.watchEvent({
  event: transferEvent,
  address: '0x742d35Cc6634C0532925a3b8D0C9e3e0C8b0e8c8', // Optional: filter by contract
  onLogs: (logs) => {
    logs.forEach((log) => {
      console.log('Transfer:', log.args.from, '→', log.args.to, log.args.value)
    })
  },
})

watchContractEvent

Watch for contract events using the full contract ABI with automatic event decoding:

// ERC-20 contract ABI (partial)
const erc20Abi = [
  {
    type: 'event',
    name: 'Transfer',
    inputs: [
      { name: 'from', type: 'address', indexed: true },
      { name: 'to', type: 'address', indexed: true },
      { name: 'value', type: 'uint256', indexed: false },
    ],
  },
  {
    type: 'event',
    name: 'Approval',
    inputs: [
      { name: 'owner', type: 'address', indexed: true },
      { name: 'spender', type: 'address', indexed: true },
      { name: 'value', type: 'uint256', indexed: false },
    ],
  },
] as const
 
// Watch for all events from the contract - events come from shreds
const unsubscribe = client.watchContractEvent({
  abi: erc20Abi,
  address: '0x742d35Cc6634C0532925a3b8D0C9e3e0C8b0e8c8',
  onLogs: (logs) => {
    logs.forEach((log) => {
      console.log(`${log.eventName}:`, log.args)
    })
  },
})
 
// Watch for specific event only
const unsubscribeTransfers = client.watchContractEvent({
  abi: erc20Abi,
  eventName: 'Transfer',
  address: '0x742d35Cc6634C0532925a3b8D0C9e3e0C8b0e8c8',
  onLogs: (logs) => {
    logs.forEach((log) => {
      console.log('Transfer:', log.args.from, '→', log.args.to, log.args.value)
    })
  },
})