Integrating a new blockchain into an existing fintech platform is never straightforward. Every chain has its own quirks. Solana is fast, cheap, and popular. But that speed comes with trade-offs that affect how you build payment systems.

At Unbanked, we partnered with Zebec to bring Solana support to our users. Zebec specializes in streaming payments on Solana. They wanted to offer their users access to traditional banking services. We wanted to expand our crypto support. The partnership made sense.

My job was to build the infrastructure that connects both worlds.

The Challenge

Traditional payment systems rely on webhooks. A bank tells you when money arrives. You update your database. Simple.

Blockchains don’t work that way. There’s no central authority to notify you. You have to watch the chain yourself and detect incoming transfers in real time.

Solana processes thousands of transactions per second. Missing a payment means a frustrated user. Double-counting a payment means losing money. The system had to be reliable.

Transaction Poller

The core of the integration is a transaction poller. It runs continuously and watches the blockchain for incoming transfers.

Here’s how it works. The poller queries Solana’s RPC nodes at regular intervals. It fetches recent transactions for wallet addresses we control. Then it parses each transaction to identify deposits.

Solana transactions are complex. A single transaction can contain multiple instructions. Each instruction can move tokens between accounts. The poller has to understand the structure and extract the relevant data.

I used @solana/web3.js to interact with the network. The library provides methods to fetch transactions, decode instructions, and verify signatures. It handles the low-level RPC communication so you can focus on business logic.

The tricky part is handling edge cases. Network congestion can delay confirmations. RPC nodes can return stale data. The poller has to retry failed requests and track confirmation counts to avoid processing unconfirmed transactions.

Proxy Wallets

We needed a way to attribute deposits to specific users. The solution: proxy wallets.

Each user gets a unique Solana address. When they want to deposit, they send funds to their proxy wallet. The poller detects the incoming transfer and credits their account.

Behind the scenes, the proxy wallet is just a keypair we control. Funds don’t stay there long. A separate process sweeps deposits to a central treasury wallet. This keeps the system secure and simplifies accounting.

Generating keypairs is straightforward with @solana/web3.js. The challenge is managing thousands of them securely. We store the private keys encrypted and only decrypt them when needed for sweeping operations.

USDC SPL vs Native SOL

Solana has two types of tokens: native SOL and SPL tokens. SOL is the chain’s native currency. SPL tokens are like ERC-20 tokens on Ethereum.

USDC on Solana is an SPL token. Handling it requires different code than handling SOL.

For SOL transfers, you check the lamports field in the transaction. Lamports are the smallest unit of SOL, like satoshis for Bitcoin.

For SPL tokens like USDC, you need to parse token program instructions. The Token Program is a smart contract that manages all SPL tokens. You look for Transfer or TransferChecked instructions and decode the amount and accounts involved.

The Zebec integration used USDC SPL. Users could stream payments in stablecoins and then off-ramp through Unbanked. The main Unbanked program supported native SOL deposits. Both required separate parsing logic in the poller.

Handling Solana’s Speed

Solana’s speed is a double-edged sword. Transactions confirm in seconds. But that means the poller has to process data quickly to keep up.

I implemented a queue-based architecture. The poller fetches transactions and pushes them to a processing queue. Worker processes pick up items from the queue and handle the business logic. This decouples fetching from processing and prevents bottlenecks.

Idempotency is critical. The same transaction might be fetched multiple times during retries or if the poller restarts. Each transaction has a unique signature. We store processed signatures in the database and skip duplicates.

Error handling had to be robust. Network issues, rate limits, malformed data. Any of these could crash a naive implementation. The system logs errors, retries with backoff, and alerts on persistent failures.

Results

The integration went live without major issues. Users could deposit SOL and USDC from Solana wallets. The Zebec partnership opened up streaming payment use cases. Both platforms benefited from the expanded functionality.

Building on Solana taught me a lot about blockchain infrastructure. The ecosystem moves fast. Documentation is sometimes outdated. You learn by reading source code and experimenting.

If you’re building payment systems on Solana, invest time in understanding the transaction structure. Use the official libraries. Build for reliability first, then optimize for speed.


If you’re working on blockchain integrations or fintech infrastructure, I’d love to chat. Feel free to reach out.

Back to Projects