npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

seismic-encrypt

v0.1.1

Published

Standalone Seismic transaction encryption — no ShieldedWalletClient needed

Readme

seismic-encrypt

Encrypt a standard viem transaction for the Seismic blockchain. One function, no custom clients — just encrypt, sign, and send via eth_sendRawTransaction.

Install

npm install seismic-encrypt viem

Quick start

import { encryptSeismicTx } from 'seismic-encrypt'
import { createPublicClient, encodeFunctionData, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'

const RPC_URL = 'https://gcp-1.seismictest.net/rpc'

const account = privateKeyToAccount('0xYourPrivateKey')
const client = createPublicClient({ transport: http(RPC_URL) })

// 1. Build a normal transaction — same as any viem tx
const tx = {
  to: '0xYourContractAddress' as `0x${string}`,
  data: encodeFunctionData({
    abi: myContractAbi,
    functionName: 'transfer',
    args: ['0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266', 100n],
  }),
  nonce: await client.getTransactionCount({ address: account.address }),
  gasPrice: await client.getGasPrice(),
  gas: 100_000n,
  chainId: 5124,
}

// 2. Encrypt it for Seismic
const { seismicTx, serialize } = await encryptSeismicTx({
  tx,
  sender: account.address,
  rpcUrl: RPC_URL,
})

// 3. Sign and send — standard viem, nothing special
const signed = await account.signTransaction(
  { ...seismicTx },
  { serializer: (_tx, sig) => serialize(sig!) }
)

const hash = await client.sendRawTransaction({
  serializedTransaction: signed,
})

console.log('tx hash:', hash)

That's it. The calldata is AES-256-GCM encrypted before it hits the network. The Seismic node decrypts it inside its TEE (Trusted Execution Environment).

How it works

encryptSeismicTx does the following under the hood:

  1. Fetches the node's TEE public key via seismic_getTeePublicKey and the latest block (for replay protection) — both in a single parallel RPC round-trip
  2. Generates an ephemeral secp256k1 keypair (or uses one you provide)
  3. Performs ECDH between your ephemeral key and the TEE key, then derives an AES-256 key via SHA-256 + HKDF
  4. Encrypts your calldata with AES-256-GCM, using RLP-encoded transaction metadata as additional authenticated data (AAD) — this binds the ciphertext to this specific transaction so it can't be replayed or tampered with
  5. Returns the encrypted transaction fields and a serialize function that produces the final 0x4a-prefixed bytes

API

encryptSeismicTx(params)

| Parameter | Type | Description | | ---------------------- | --------- | --------------------------------------------------------------- | | tx.to | Address | Destination address | | tx.data | Hex | Plaintext calldata to encrypt | | tx.nonce | number | Sender's transaction nonce | | tx.gasPrice | bigint | Gas price | | tx.gas | bigint | Gas limit | | tx.chainId | number | Chain ID (5124 for Seismic testnet, 31337 for local sanvil) | | tx.value | bigint? | ETH value in wei (default 0) | | sender | Address | Sender address (must match the signer) | | rpcUrl | string | Seismic node RPC URL | | encryptionPrivateKey | Hex? | Your own ephemeral key. One is generated per call if omitted. | | blocksWindow | bigint? | Blocks until the tx expires (default 100) |

Returns a Promise<EncryptSeismicTxResult>:

| Field | Type | Description | | ---------------------- | --------------------------- | --------------------------------------------------------------- | | seismicTx | object | All transaction fields with encrypted data, ready to sign | | serialize | (sig: { v, r, s }) => Hex | Takes a signature and returns final signed bytes (0x4a + RLP) | | unsignedSerializedTx | Hex | The unsigned serialized bytes (for inspection/debugging) |

serializeSeismicTx(tx, signature?)

Lower-level serializer if you want to build the transaction yourself. Takes a full seismic transaction object and an optional signature, returns 0x4a-prefixed RLP-encoded bytes.

SEISMIC_TX_TYPE

The Seismic transaction type constant: 0x4a (74).

Sending ETH (no calldata)

For simple ETH transfers, pass 0x as data — it will be left unencrypted since there's nothing to encrypt:

const { seismicTx, serialize } = await encryptSeismicTx({
  tx: {
    to: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
    data: '0x',
    value: 1_000_000_000_000_000_000n, // 1 ETH
    nonce: 0,
    gasPrice: 1_000_000_000n,
    gas: 21_000n,
    chainId: 5124,
  },
  sender: account.address,
  rpcUrl: 'https://gcp-1.seismictest.net/rpc',
})

Using with local sanvil

const { seismicTx, serialize } = await encryptSeismicTx({
  tx: { ...tx, chainId: 31337 },
  sender: account.address,
  rpcUrl: 'http://127.0.0.1:8545',
})

Relationship to seismic-viem

seismic-viem provides a full-featured ShieldedWalletClient with contract helpers, signed reads, SRC20 support, and more. This package extracts just the encryption and serialization into a single function with no custom client setup. Use this when you want to integrate Seismic encryption into an existing viem workflow without pulling in the full SDK.