mobileRumblefishLogo
Menu
  1. Software
  2. Blockchain
  3. Web3 product
  4. Smart Contracts
  5. Mobile app
  6. Web platform
  7. AWS Cloud
  8. NFT marketplace
  9. DeFi
  10. Fintech
  11. AI product
  12. dApp
  13. Crypto wallet
development tailored to your needs!

Rumble Fish helps entrepreneurs build and launch bespoke digital products.
We take care of the technology, so you can focus on your business

Join the ecosystem
of our satisfied customers:
companiesCarouselLogo0
companiesCarouselLogo1
companiesCarouselLogo2
companiesCarouselLogo3
companiesCarouselLogo4
companiesCarouselLogo0
companiesCarouselLogo1
companiesCarouselLogo2
companiesCarouselLogo3
companiesCarouselLogo4
Who we are?

Hi there! We're Rumble Fish - a team of world-class experts in bespoke software development. Our engineers are highly skilled in blockchain, cloud solutions, and defi/fintech development. Our strength and pride is the ability to take ownership of the entire development process and be a true partner and advisor for our customers. Our mission is to craft state-of-the-art digital products using battle-tested technologies. Try us!

40uniquely skilled devs
1pet-friendly office
8years in business
42projects
999passion for coding
What do we do?
Software Development Services and Skills for your needs To deliver the highest quality of services, our experts are always gaining new skills and knowledge. That’s how we make sure our solutions follow the latest industry standards and take advantage of the most innovative technologies.

Our team is well-versed and experienced in various blockchain development tools and technologies. Our unique skillset allows us to be at the forefront of Web3 development services so if you’re looking for a trusted IT partner to boost your decentralized product - look no further!

We deliver production-ready zero-knowledge proof solutions that actually ship to mainnet, specializing in custom ZK development, rollup scaling solutions, and privacy-preserving smart contracts that reduce processing times from hours to minutes. Try us!

We build fast, compliant, and cost-effective blockchain solutions on the XRP Ledger. From payment systems and tokenization platforms to enterprise DeFi applications, our team delivers production-ready systems that work when billions are on the line.

We build smart contracts that handle real business complexity without the usual blockchain headaches. From DeFi protocols to custom on-chain systems, we deliver production-ready solutions that scale.

Decentralized Finance (DeFi) development requires an extensive amount of blockchain knowledge, as well as a great understanding of financial mechanisms. We’ve got both that bases covered! Our team has successfully built an impressive number of DeFi products like cryptocurrency exchanges, dApps, lending protocols, or staking platforms. Try us!

Our experienced team will take your AWS cloud solutions to the next level. AWS provides purpose-built tools to support your needs, and it is the preferred choice for any blockchain project. From the plethora of cloud tools and solutions offered by Amazon Web Services, we’ll help you choose and implement the ones that serve your business the best way possible.

AI chatbots can bring value to a wide range of industries by enhancing customer interactions, streamlining processes, and improving overall efficiency. We'll craft a perfect AI assistant for your product.

Need realistic data for AI training, testing, or product development—but privacy, scale, or availability is blocking you? We engineer custom synthetic data solutions that capture the complexity of real-world data without the constraints. From multi-modal generation to domain-specific datasets, we build what platforms can't deliver.

We build custom AI knowledge management systems that turn your scattered enterprise knowledge into instant, accurate answers - no more employees wasting their valuable time hunting through SharePoint and Slack for information. Unlike platforms that trap you in subscriptions, we engineer RAG solutions specifically for your data and security requirements, then hand you complete ownership of the source code and infrastructure.

Looking for a skilled team to help you build an advanced fintech platform able to compete with the biggest in the game? At Rumble Fish, we’ve got what it takes to engineer innovative financial technology systems. We offer end-to-end fintech software development, consulting, and expertise.

Our experts provide you with knowledge, skills, and experience that elevates every project to another level. We’ll gladly take ownership of the entire process and guide you and your team through the intricacies of cutting-edge technology development.

If you’re in need of professional web development services, look no further! Rumble Fish's talented team has extensive experience in delivering top-tier web apps and websites with the use of battle-tested tools and technologies like React or Nest. We know just the right solutions to exceed your business requirements.

Whether you need an Android, an IOS app, or both, the Rumble Fish team is here to help you deliver the beautiful and efficient mobile product that your customers will simply love to use! We craft fast and secure mobile apps with a wow factor to help our customers grow their businesses and reach their goals quicker.

If you're looking for a team capable of turning your product concept into a beautiful and technologically intricate digital solution - look no further! Rumble Fish is your trusted software development partner ready to take you through the entire process of custom digital product creation - from the early stages of ideation to the post-launch support. Whether you're on a mission to build a mobile app, a Web3 product, or an advanced platform - we are here for you!

We design sleek, intuitive, and highly effective interfaces to help you overcome your business challenges. After carefully evaluating and understanding your requirements we switch to the designing mode - the end goal is the beautiful digital solution that people love to use!
Testimonials
See what our customers say about working with us
Latest case studyPorting Merkl to Stellar: Full Protocol Migration to Soroban
Porting Merkl to Stellar: Full Protocol Migration to Soroban
Merkl is the leading DeFi incentive distribution platform, backed by a16z, that has distributed over $1.5 billion in rewards across 60+ chains for 200+ protocols.
Collaboration timeframe:4 weeks
Services:Smart Contract Development, Blockchain Development
We're trusted by global innovators and leaders.Join them!
TURNTABLE
A hybrid of a social network and a music app
TURNTABLE
MAKERDAO
The first truly decentralized stablecoin crypto on Ethereum
MAKERDAO
ZBAY
A private inbox, wallet, and marketplace all in one
ZBAY
VERIFYID
An identity verification MVP
VERIFYID
Rumblefish Blog
Check a piece of expert knowledge
Serverless at the Edge of a Blockchain: Architecture Decisions Behind Our Soroban Explorer_BlogPostImageServerless at the Edge of a Blockchain: Architecture Decisions Behind Our Soroban Explorer
Marek-Kowalski.png_BlogPostAuthorAvatarBy Marek Kowalski
Earlier this year, Rumble Fish received a $131,200 grant from the Stellar Community Fund to build a Soroban-first block explorer,  a publicly accessible tool for navigating transactions, smart contracts, accounts, and events on the Stellar network. The grant comes with a public mandate: the repository is open source, the infrastructure is reproducible, and the whole thing has to work reliably at mainnet scale. Block explorers sound like a solved problem. They are not, at least not for Soroban. Soroban is Stellar's smart contract platform, and it produces data structures that existing explorers don't fully surface: decoded contract invocation arguments, return values, nested call trees, and CAP-67 contract events. Beyond that, the Stellar protocol produces a new binary payload, a \`LedgerCloseMeta\` XDR file, every five to six seconds, containing the complete record of every change that occurred in that ledger close. You need to ingest it in near-real time, decode it, store it, and serve it through a public API before the next one arrives. This article walks through the decisions that shaped our architecture. Some of them are conventional. A few are not. We replaced a planned 7 TB PostgreSQL database with a 900 MB ClickHouse instance. We run our backend Lambdas in Rust. We ran the historical backfill on local machines because that was the right tool for that specific job. Here is how we got there. ## Why We Don't Call Any External API The straightforward approach to building a block explorer is wrapping an existing one. Horizon has been the standard Stellar API for years. Soroban RPC provides contract-level access. Both were options, and we rejected both of them. **Horizon is deprecated** for the indexing use cases we need. The Stellar Foundation's own tooling has moved beyond it, and building on a deprecated API means inheriting its limitations permanently. **Rate limits are fine until they're not.** A block explorer that depends on another service's API inherits that service's reliability ceiling. Traffic spikes on the Stellar network, exactly when users want a block explorer most, are also when upstream APIs are most likely to throttle requests. **Soroban-specific data isn't pre-assembled anywhere.** We need decoded contract invocation trees showing nested contract-to-contract calls. We need function arguments and return values decoded from their binary \`ScVal\` representation into structured, readable data. We need function signatures extracted from the WASM bytecode at contract deployment time. None of this exists in a form we can simply fetch from an existing API. The decision to own the pipeline end-to-end was made early in the process and has not been reconsidered since. Every other architectural choice in this article follows from it. If we had accepted an external API dependency, most of what follows wouldn't have been necessary. ## **One Monorepo, Multiple Languages - The Nx Choice** The project has eight distinct packages spanning TypeScript and Rust:   | Package | Language | Role | | --- | --- | --- | | \`apps/indexer\` | Rust | Ledger Processor Lambda - XDR ingestion | | \`apps/workers\` | Rust | Event Interpreter Lambda - enrichment | | \`apps/api\` | Rust | REST API Lambda | | \`apps/web\` | TypeScript | React SPA | | \`infra/aws-cdk\` | TypeScript | CDK infrastructure | | \`libs/domain\` | TypeScript | Shared explorer types | | \`libs/shared\` | TypeScript | Generic utilities | | \`libs/ui\` | TypeScript | Reusable React components | These are not independent microservices that happen to live in the same repository, but they are genuinely coupled. The domain types the frontend uses to render a transaction are the same concepts the indexer writes to the database. A change to how we store Soroban invocations touches both the Ledger Processor and the API. The CDK stack deploys all three Lambdas and knows their artifact paths. The coupling is real; the only question is whether to make it visible or hide it across repository boundaries. We chose [Nx](https://nx.dev) to make it visible. With Nx, \`nx affected --target=build\` builds only the packages touched by a given change. On a workspace with eight packages across two languages, this matters: a change to \`libs/ui\` should not trigger a Rust compilation. \`nx run-many -t typecheck\` runs TypeScript type checking across all TypeScript packages in one command. The project dependency graph is explicit and visualisable - you can see at a glance that \`apps/api\` depends on \`libs/domain\`, and that \`infra/aws-cdk\` depends on nothing in the application layer but deploys everything. The alternative (one repository per service) would have distributed the coupling across network boundaries rather than eliminated it. You would end up with shared type packages, inter-repo version pinning, and deployment coordination scripts that reinvent what a monorepo gives you for free. We have seen that pattern enough times to prefer the explicit version. ## Why We Write Our Lambdas in Rust Rumble Fish has historically written backends in TypeScript. It is ergonomic, the ecosystem is extensive, and getting a new engineer productive in a Node.js Lambda takes hours, not weeks. For this project, we made a different choice: all three backend Lambda functions are Rust crates. Here is why. ### Cold start performance Lambda cold starts are a function of two things: how large the deployment artifact is and how expensive the runtime initialisation is. A TypeScript Lambda ships a Node.js runtime plus your application code plus its \`node\_modules\` - commonly several megabytes, sometimes significantly more. A compiled Rust Lambda is a single statically-linked binary, typically under five megabytes, with no runtime to initialise. It starts in milliseconds. For the Ledger Processor, which fires on every S3 event - roughly 17,000 times a day - provisioned concurrency is not a practical solution. Provisioned concurrency keeps instances warm, but it makes most sense for steady-state traffic, not for a function that needs to respond to an event every five seconds indefinitely. A fast cold start is preferable to paying for warmth. ### Execution speed XDR parsing is not lightweight. Each \`LedgerCloseMeta\` payload contains every transaction, every operation, every Soroban invocation, every CAP-67 event, and every ledger entry change for a complete ledger close. For an active ledger, that can mean thousands of decode operations: binary deserialisation, tree traversal, type-tagged value decoding. Rust does this with predictable memory usage, no garbage collection pauses, and throughput that is roughly an order of magnitude higher than equivalent Node.js. Our target is under ten seconds from ledger close to database write. With the Ledger Processor in Rust, we are well inside it with headroom. ### The AI development loop This is the argument we did not expect to be making when the project started. The Rust compiler is famously strict. Ownership violations, type mismatches, and lifetime errors all surface at compile time with precise, often instructive messages. This turns out to be highly productive when working with AI-assisted development: the agent writes code, the compiler rejects it with a specific error, the agent reads the error, and corrects it. The loop is fast and deterministic. There is no class of "it ran but produced the wrong output" error that requires runtime investigation. With TypeScript or Python, AI-generated code can be syntactically valid and dynamically typed in ways that fail silently at runtime or produce subtly wrong results. With Rust, the compiler acts as a continuous integration step on every compilation. Errors are loud, early, and actionable. As AI tooling has made Rust more accessible, removing much of the manual borrow-checker wrestling that historically made it a steep climb, the performance and correctness benefits have become easier to capture. We now consider it the better default for backend Lambda work, and this project is the system that shifted our thinking. AWS supports Rust as a first-class Lambda runtime. The \`lambda\_runtime\` crate, \`aws-sdk-rust\`, and the \`cargo-lambda\` build toolchain cover everything needed from local development to deployment. ## The Ingestion Pipeline: Matching Compute to Workload Shape The ingestion pipeline has three distinct jobs. We use three different execution models for them, because the workloads have different shapes, and applying one model to all three would have been a mistake. ```plaintext Stellar peers → Galexie (ECS Fargate, continuous) → S3: stellar-ledger-data/ (~1 file per ledger, zstd-compressed XDR) → Ledger Processor Lambda (Rust, S3 PutObject trigger) → ClickHouse (Hetzner) ↑ Event Interpreter Lambda (Rust, EventBridge every 5 min) API Gateway → API Lambda (Rust) → ClickHouse (Hetzner) CloudFront → React SPA ``` ### Galexie on ECS Fargate Galexie is the Stellar Foundation's tool for streaming canonical ledger data. It connects to Stellar network peers via an embedded Captive Core process, maintains a persistent connection, and exports one \`LedgerCloseMeta\` XDR file to S3 for each ledger close - roughly every five to six seconds, indefinitely. Lambda is the wrong shape for this. Galexie is a long-running, stateful process. It maintains a peer connection across ledger closes, tracks which ledger it last exported, and resumes from that checkpoint on restart. Lambda has a fifteen-minute execution limit and no concept of resumption. ECS Fargate gives us a managed container runtime - one task, always running, no EC2 to provision or patch. ### Lambda (Rust) for the Ledger Processor When Galexie writes a file to S3, an S3 PutObject notification triggers the Ledger Processor Lambda. This is the primary ingestion worker, and it is exactly the shape that Lambda is designed for: one event, one bounded unit of work, invoked per ledger close, completing in well under ten seconds. The Lambda downloads and decompresses the XDR file, parses every entity it contains, and writes structured records to ClickHouse in a single operation. If the Lambda fails, Lambda retries automatically. If there is a permanent failure, the file remains in S3 and we can replay any ledger by re-triggering the Lambda with its S3 key. That replayability is the reason S3 is the handoff between Galexie and the Ledger Processor, rather than a direct invocation or a queue. A durable artifact per ledger close means the ingestion pipeline can recover from failures, schema migrations, or bugs in the parsing logic by replaying affected ledgers without re-ingesting from the network. ### Lambda (Rust) for the Event Interpreter A third Lambda fires every five minutes via EventBridge. It reads recently stored Soroban events and pattern-matches against known DeFi protocols - Soroswap, Aquarius, Phoenix - to generate human-readable summaries: "Swapped 100 USDC for 95.2 XLM." This lives in a separate Lambda from the Ledger Processor deliberately. Our interpretation heuristics improve over time as we recognise new protocols and refine existing patterns. Keeping enrichment separate from ingestion means we can update interpretation logic, redeploy the Event Interpreter, and re-run it over historical events, all without touching the ingestion path. ## The Historical Backfill: When Architecture Meets Reality Soroban launched on the Stellar mainnet in late 2023. Our explorer needs to surface data from the beginning, which means indexing roughly two years of history before going live. The design called for a separate ECS Fargate task to read from Stellar's public history archives and feed data through the same S3 → Lambda → ClickHouse pipeline as live ingestion; one code path for both problems, clean separation, no special cases. We did not do that. Instead, we ran the backfill on local machines, writing directly to a local ClickHouse instance. Once the backfill was complete, we migrated the data to production ClickHouse on Hetzner.  There were two reasons for that approach: speed and cost. The event-driven pipeline is optimised for steady, continuous work - one ledger at a time, one S3 event at a time, with the overhead of Lambda invocations, S3 round-trips, and network hops to the database. That overhead is trivially small for live ingestion, where a new ledger arrives every five seconds. For a one-time bulk operation across millions of historical ledgers, the same overhead becomes the bottleneck. A local machine writing directly to a local database processes historical data at a rate that the serverless pipeline cannot match. Cost follows the same logic. Lambda invocations, S3 data transfer, and remote database writes during a multi-week bulk ingest all accumulate. Running on hardware you already own costs nothing beyond electricity. The lesson is straightforward: the event-driven architecture is the right shape for what it was designed for - continuous, low-latency, per-ledger ingestion. It is not the right shape for a one-time bulk operation. Treating the backfill as its own case is the architecture working as intended. ## ClickHouse on Hetzner: Why We Left AWS for the Database When we designed the database schema in PostgreSQL and tested it against a batch of ledgers, the extrapolated storage size for the full Stellar history came to approximately 7 TB. The same data in ClickHouse takes roughly 900 MB. ClickHouse is a columnar database. Instead of storing rows, all fields for a given record are adjacent in storage, it stores columns, all values for a given field adjacent. For blockchain data, this is a significant advantage. Account IDs, contract addresses, operation types, ledger sequences, and status codes repeat millions of times across the dataset. Column-adjacent storage lets the compression algorithm - LZ4 or ZSTD per column - exploit that repetition far more aggressively than a row-oriented layout allows. The result is storage that is not marginally smaller but categorically smaller: a dataset you would otherwise manage in terabytes fits comfortably in gigabytes. Beyond compression, ClickHouse's columnar layout is naturally suited to the queries a block explorer serves. Every page is some form of time-range scan: recent transactions, recent invocations of a contract, event history for a ledger sequence range. Columnar databases read only the columns a query touches, which, for range scans over a subset of fields, is substantially less I/O than a row store that reads entire rows. **Why not DynamoDB?** DynamoDB is optimised for single-row lookups at a very large scale. A block explorer's queries, all invocations of contract X ordered by ledger, all transactions from account Y in the last thirty days, aggregate event counts by type, are not single-row lookups. Modelling them efficiently in DynamoDB would require denormalising every read pattern at write time. With a query surface as wide as ours, that is an ongoing maintenance burden every time the frontend adds a new page. **Why Hetzner?** ClickHouse is not available as a managed service on AWS. Running it on Hetzner gives us a dedicated server with NVMe storage at a fraction of the cost of an equivalent managed database instance. Hetzner's pricing is particularly favourable for storage-heavy analytical workloads. This makes our architecture hybrid: compute on AWS (Lambda, ECS Fargate, API Gateway, CloudFront) and database on Hetzner. The Lambda runtime does not care which cloud the database lives in. The connection is a standard TCP connection to a ClickHouse HTTP interface, the same way any other client would connect. Keeping everything under one vendor's roof is a convenience, not a technical requirement, and in this case, it was a convenience we traded for a 7 TB reduction in storage. ## CDK in TypeScript: Infrastructure in the Monorepo All infrastructure is defined in AWS CDK using TypeScript, in \`infra/aws-cdk\` inside the same Nx monorepo as the application code. The concrete benefit is that the same language, the same toolchain, and the same compiler that validates the application also validates the infrastructure. Environment names are typed constants shared across CDK and application code. S3 bucket key formats are defined once. A misconfigured Lambda environment variable that references a non-existent secret name fails at \`cdk synth\` rather than at runtime. One choice worth being explicit about: GitHub Actions authenticates to AWS using OIDC rather than long-lived credentials. The Actions workflow assumes a scoped IAM role at deploy time; no AWS keys are stored in GitHub secrets. For a public repository, this is not optional - any credential committed to a public repo is compromised immediately. OIDC eliminates the credential management problem at its source. The CDK stack is fully reproducible. The design intention from the beginning was that anyone - including the Stellar Foundation or any other team in the ecosystem - should be able to clone the repository and \`cdk deploy\` a complete working copy of the system in a fresh AWS account. The architecture is public infrastructure, not proprietary tooling. ## What We Would Do the Same Way Again The Soroban block explorer is past Milestone 1 - historical backfill complete, live ingestion running, indexing the Stellar mainnet in real time and looking back at the architectural choices, a few stand out as clearly right. **Owning the pipeline.** The decision to ingest directly from the canonical ledger rather than wrapping an external API has paid for itself many times over. We control what data we store, how we store it, and how we serve it. There is no upstream reliability dependency, no rate limit, and no undocumented behaviour we cannot inspect. **Rust for Lambdas.** The cold start performance is real, the XDR parsing throughput is real, and the AI development loop has been a genuine productivity multiplier. We would make the same choice again, and we expect to make it on future projects. **Nx for the hybrid monorepo.** Coupling between frontend, backend, infrastructure, and shared libraries is not something you can wish away by splitting into multiple repositories. Making it explicit, making it visible, and tooling around it has made the codebase easier to navigate and the CI pipeline faster to run. **ClickHouse on Hetzner.** Seven terabytes versus nine hundred megabytes is not a marginal improvement. It is a different order of infrastructure, and once we saw that number, we did not seriously consider the alternative. **The pragmatic backfill.** Running history on local machines and migrating the result was the right call. The elegant solution and the correct solution are not always the same. --- The repository is [public on GitHub.](https://github.com/rumblefishdev/soroban-block-explorer)  The grant announcement with more background on the project is [on our blog.](https://www.rumblefish.dev/blog/post/rumble-fish-grant-stellar-block-explorer/) If you are building something with a similar shape - event-driven ingestion, analytical storage, serverless compute - we are happy [to talk through it.](https://rumblefish.dev/contact)
Blockchain
From Block Explorer to Prices API: Rumble Fish Receives Its Second Stellar Community Fund Grant_BlogPostImageFrom Block Explorer to Prices API: Rumble Fish Receives Its Second Stellar Community Fund Grant
375165173_10223182974989698_6377842045490346765_n.jpg_BlogPostAuthorAvatarBy Agnieszka Dobosz
We're excited to announce that Rumble Fish has been awarded a $55,000 grant from the Stellar Community Fund (SCF #42) to build a Prices API - a unified, standardized data infrastructure layer for real-time and historical price information across all Stellar assets, both classic and SEP-41 Soroban tokens. This is our second grant from the Stellar Community Fund, following the $131,200 award from SCF #41 to build the Soroban-first Block Explorer. Together, they reflect a clear direction: Rumble Fish is here to build the infrastructure that makes the Stellar ecosystem stronger, more transparent, and more developer-friendly. ## What Problem Are We Solving? Today, price data on Stellar is scattered. Different applications pull from different sources, use different formats, and cover different assets, creating a fragmented landscape that makes life harder for everyone building on the network. For a DeFi protocol, this means unreliable inputs that can affect the accuracy of trades and liquidity calculations. For a portfolio tracking tool, it means incomplete or inconsistent data that erodes user trust. For a developer building anything price-sensitive, it means spending weeks solving an infrastructure problem that should already be solved. The Prices API is built to eliminate that fragmentation, providing a single, standardized source of price data covering all Stellar assets, both classic and Soroban-based. ## What the Team Says Marek Kowalski, CEO of Rumble Fish, sees the Prices API as a natural complement to the team's broader work in the Stellar ecosystem: #### "Price data is one of those things that every serious DeFi application needs, but that nobody wants to build from scratch. The fragmentation on Stellar today creates real friction for developers. With this API, we're building something that can become shared infrastructure for the whole ecosystem." ## What This Means for the Stellar Ecosystem Price data infrastructure might not be the most visible part of a blockchain ecosystem, but it's one of the most critical. Every DeFi protocol, every analytics dashboard, every portfolio application depends on it. When that layer is fragmented and unreliable, the applications built on top of it suffer - and so does adoption. By delivering a unified Prices API with 8+ years of historical coverage, real-time ingestion, and production-grade reliability, Rumble Fish is giving Stellar developers a foundation they can actually build on. The kind of infrastructure that turns good ideas into real products. You can explore the full architecture documentation on [GitHub](https://github.com/rumblefishdev/stellar-scf-submissions/blob/master/prices-api-design-after-2nd-review.md) and track the project's progress on the [Stellar Community Fund](https://communityfund.stellar.org/submissions/rec0QBqMONJbGabzq). If you're building on Stellar and need a technical partner who knows the ecosystem inside out, our team is ready to help - [get in touch](https://www.rumblefish.dev/contact/).
Blockchain
Have an idea?
Let’s work
together!
We will answer any questions you may have related to your startup journey!Do you prefer e-mail?
hello@rumblefish.pl