All articles
solanaheliuswebhooksrpcdasnftindexing

Helius: enhanced transactions, webhooks, DAS API, smart transactions

Helius parses raw Solana transactions into typed events — NFT_SALE, SWAP, TOKEN_TRANSFER — and pushes them to your webhook. Plus DAS API for digital assets and smart transactions with priority fee estimation.

Share

Helius is a Solana RPC provider that ships three things most developers need immediately: enhanced transactions that parse raw instruction data into typed events, webhooks that push those events to your endpoint, and the DAS API for querying digital assets. On top of that, its smart transaction helper wraps the whole sign-and-land flow with automatic priority fee estimation and retry.

Enhanced transactions

A raw Solana transaction is a list of instructions with encoded account keys and instruction data. To know what it did you have to decode every program's IDL yourself. Helius does that for you. Call getEnrichedTransaction (or the batch variant) and you get a structured object with a top-level type:

typescript
import Helius from "helius-sdk"

const helius = new Helius(process.env.HELIUS_API_KEY!)

const [tx] = await helius.rpc.getEnrichedTransactions([
  "5Nnbjx…",
])

console.log(tx.type)          // "NFT_SALE"
console.log(tx.source)        // "MAGIC_EDEN"
console.log(tx.nativeTransfers)
console.log(tx.tokenTransfers)

Types include NFT_SALE, NFT_LISTING, NFT_BID, SWAP, TOKEN_MINT, TOKEN_TRANSFER, STAKE_SOL, LOAN, and more. The source field tells you which protocol or marketplace originated the event. Native SOL transfers and SPL token transfers are broken out into typed arrays so you don't have to parse inner instructions.

Webhooks

Instead of polling, subscribe Helius to an address (or a set of addresses / program IDs) and it will POST the enriched payload to your URL the moment a matching transaction is confirmed.

typescript
// Create a webhook via SDK
const webhook = await helius.createWebhook({
  accountAddresses: ["<your-program-id>", "<wallet-address>"],
  webhookURL: "https://yourapp.com/api/helius-webhook",
  webhookType: "enhanced",          // raw | enhanced | discord
  transactionTypes: ["NFT_SALE", "SWAP", "TOKEN_TRANSFER"],
})
console.log(webhook.webhookID)

Webhook types: raw sends the vanilla JSON-RPC structure; enhanced sends the parsed event object; and discord formats a message you can pipe straight into a Discord channel without writing a formatter. You can filter by transaction type, so you only receive NFT_SALE events rather than every transaction that touches your address.

typescript
// Handle incoming webhook (Next.js route handler)
export async function POST(req: Request) {
  const events = await req.json() // EnrichedTransaction[]

  for (const event of events) {
    if (event.type === "NFT_SALE") {
      const { amount, buyer, seller } = event.events.nft
      console.log(`Sale: ${amount / 1e9} SOL — ${seller}${buyer}`)
    }
  }
  return new Response("ok")
}

DAS API — querying digital assets

The Digital Asset Standard (DAS) API is a Metaplex spec for reading NFTs, compressed NFTs (cNFTs), fungible tokens, and their metadata without hitting individual on-chain accounts. Helius implements it fully.

typescript
// Get all assets owned by a wallet
const assets = await helius.rpc.getAssetsByOwner({
  ownerAddress: "<wallet>",
  page: 1,
  limit: 100,
})

// Get a single asset (NFT or token)
const asset = await helius.rpc.getAsset({ id: "<mint-address>" })
console.log(asset.content.metadata.name)
console.log(asset.compression?.compressed) // true for cNFTs

// Search across all assets by creator
const byCreator = await helius.rpc.getAssetsByCreator({
  creatorAddress: "<creator-wallet>",
  onlyVerified: true,
  page: 1,
})

Compressed NFTs (state-compression cNFTs) live in a Merkle tree and have no individual on-chain account, so getAccountInfo returns nothing. DAS is the only standard way to read them. The response shape is identical whether the asset is a classic Metaplex NFT, a Token 2022 token, or a cNFT — your code doesn't need to branch.

Smart transactions

Helius's sendSmartTransaction wraps the whole sign-and-land flow: it fetches a fresh blockhash, estimates the right priority fee, sets compute unit limits, and retries until confirmation or timeout.

typescript
import { Keypair, SystemProgram, LAMPORTS_PER_SOL } from "@solana/web3.js"

const sender = Keypair.fromSecretKey(/* … */)

const signature = await helius.rpc.sendSmartTransaction(
  [
    SystemProgram.transfer({
      fromPubkey: sender.publicKey,
      toPubkey: recipient,
      lamports: 0.01 * LAMPORTS_PER_SOL,
    }),
  ],
  [sender],
  [],          // lookup tables
  { skipPreflight: false },
)

console.log("confirmed:", signature)

Priority fee estimation queries recent fee statistics on the target accounts and picks a percentile that balances cost against landing probability. You can override with a priorityLevel option ("min" / "low" / "medium" / "high" / "veryHigh" / "unsafeMax") if you prefer to control it yourself.

The honest read

Helius occupies a sweet spot: you get Geyser-level data (filtered, enriched, pushed) without running a validator plugin or a streaming client. The tradeoff is that you're trusting Helius's parsing — if a protocol they haven't indexed yet shows up, the type will be UNKNOWN. For exotic programs, you'll still need a custom IDL decoder. Webhooks also have a latency floor (HTTP round-trip + their internal processing), whereas gRPC Geyser at the validator is lower. For most product teams — especially those who need NFT/token events without infrastructure overhead — Helius is the fastest path from "I want to react to on-chain events" to working code.

References

Keep reading

Get new articles in your inbox

Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.

Helius: enhanced transactions, webhooks, DAS API, smart transactions | devrels.xyz