DEV Community

Cover image for Building a crypto app for Madagascar: gasless swaps with NEAR Intents and a P2P escrow for Mobile Money
Varika
Varika

Posted on AI-assisted

Building a crypto app for Madagascar: gasless swaps with NEAR Intents and a P2P escrow for Mobile Money

In Madagascar, a lot of people already use crypto, mostly USDT, the "digital dollar". They use it to keep part of their savings in dollars, to get paid by clients abroad, or to send money to family.

But the way most people get their first USDT is fragile. And the way they use it afterwards is full of traps for beginners.

We're a small Malagasy team building Varika to fix both. This post is about the two technical choices at the heart of the app, and what we learned along the way.

The problem: "pay first, and hope"

There is no simple on-ramp from Malagasy Ariary (MGA) to USDT. In practice, people buy and sell USDT peer to peer: in Facebook groups, on WhatsApp, or through P2P marketplaces. Payment goes through Mobile Money, which is how most people here move money: MVola, Orange Money, Airtel Money.

Outside a marketplace with an escrow, a typical trade looks like this:

  1. You find a seller in a Facebook group.
  2. You send them Ariary with MVola.
  3. You wait, and hope the USDT arrives.

Scams are common: fake payment screenshots, sellers who disappear, fake "support agents" asking for your recovery phrase. Buyers don't trust sellers, and honest sellers struggle to prove they're honest.

The second problem appears right after you get your first USDT.

The second problem: gas

Ask anyone who helps beginners with crypto and you'll hear the same story:

"I have 50 USDT on TRON, but I can't send it."

The reason: they have 0 TRX. On most chains, every transaction pays a network fee (gas) in the chain's native token, not in the token you're sending. So a beginner who only owns USDT is stuck. Their money is there, but they can't move it.

Then come the follow-up questions. Which network: TRC20, ERC20 or BEP20? Why do I need ETH to swap a token on Ethereum? Why do I need BNB on BNB Chain? For people whose first financial app is Mobile Money, this is a wall.

We wanted an app where you never have to think about gas.

A classic wallet with 50 USDT and 0 TRX cannot send; with Varika the user only signs a message

Choice #1: NEAR Intents for gasless, cross-chain swaps

We built Varika's swaps on NEAR Intents.

The idea of an intent-based system is simple. Instead of building and paying for a transaction yourself, you sign an intent: "I want to swap X of token A for at least Y of token B". Market makers called solvers compete to fill that intent, and they take care of the execution on the underlying chains.

For our users, this changes three things:

  • No native gas token needed. The user signs a message. They don't need to hold TRX, ETH or BNB to swap.
  • One flow for many chains. NEAR Intents can route across more than 30 blockchains, so swapping USDT for Bitcoin or Ethereum is the same experience on every network.
  • A price known before signing. The user sees the quote, and the Varika fee (0.15%), before they sign anything.

How a gasless swap works: quote, signed intent, relayer, solvers

How it works under the hood

  • Quotes come from the 1Click API: our server requests a quote for the pair and amount, and passes Varika's 0.15% as the appFees parameter, so the fee is part of the quote the user sees, not added afterwards.
  • Execution: for funds already held inside NEAR Intents, the user only signs an EIP-191 message (the intent). A relayer submits it on-chain, so the user never pays gas and never needs a native token.
  • Wallets: users can connect an extension wallet (MetaMask, Rabby) or use "Continue with Google". The Google path creates a non-custodial embedded wallet: the key is split into shares and only rebuilt in an isolated context at signing time. We never hold a full key.

The user keeps control of their funds at every step: nothing moves without their signature, and Varika never asks for a recovery phrase.

Lesson learned: networks can pause

Building on a routing layer means relying on what it supports at any given moment. Since 1 October 2026, some networks (BNB Chain, Polygon, TON, among others) have been paused on NEAR Intents.

So the app can't hardcode a list of networks. It asks which routes are available at the time and only offers those. For users, we recommend Tron (TRC20) for USDT transfers, but the UI never shows a network we can't actually serve.

Choice #2: an escrow for P2P trades against Mobile Money

Swaps solve the crypto-to-crypto side. But people in Madagascar still need to go between Ariary and USDT, and that means Mobile Money, which no blockchain can see.

Our answer is a classic P2P design with an escrow:

P2P escrow in 5 steps: lock, check, Mobile Money payment, seller confirmation, release

  1. The seller locks their USDT in the Varika escrow, a contract that holds the funds during the trade.
  2. The buyer sees the USDT are locked before paying. That is the trust signal that was missing in Facebook groups.
  3. The buyer pays with Mobile Money (MVola, Orange Money or Airtel Money), for the exact amount shown.
  4. The seller checks the money in their Mobile Money balance (never on a screenshot), then confirms.
  5. The escrow releases the USDT to the buyer.

If something goes wrong, either side can open a dispute, and an arbiter decides based on evidence.

How it works under the hood

  • The escrow is a Rust smart contract (near-sdk) on NEAR mainnet. It holds the seller's USDT inside NEAR Intents, so locked funds sit in the same place as the rest of the user's balance, and the release is a gasless transfer for both sides.
  • In a normal trade, funds are released only with the seller's own signature.
  • Disputes are the only exception: an arbiter role defined in the contract can settle a disputed order on-chain, based on the evidence both sides provide.
  • The fiat leg stays off-chain and manual. The Mobile Money payment (MVola, Orange Money, Airtel Money) is a normal person-to-person transfer. No operator API is involved, which is why the seller has to check their balance before confirming.

A few details turned out to matter a lot:

  • The price is fixed before payment. The buyer agrees to an amount in Ariary and in USDT before sending money, so there is no renegotiation halfway.
  • Seller stats are computed, not declared. Completed orders, success rate and average release time come from real trades on Varika, not from what the seller writes in their bio.
  • The payer's name must match. Sellers are told to check that the Mobile Money payment comes from the buyer's own account.
  • Safety copy is part of the product. "Never pay outside the order" appears at every step. In a market where scams spread fast, the UI has to teach.

Meeting users where they already are: shareable ad links

P2P sellers in Madagascar already have their customers in Facebook groups and WhatsApp chats. Asking them to move everyone to a new marketplace would be a hard sell.

So every P2P ad on Varika gets a public, shareable link with a preview (image and price in Ariary per USDT). A seller posts it in their group, and the buyer opens it and completes the whole trade from that page: sign in, order, pay with Mobile Money, receive the USDT. The seller keeps their own audience; Varika provides the escrow and the stats.

Lesson learned: in-app browsers break everything

Shared ad links opened in Facebook's in-app browser, and the Android and iPhone workarounds

Most of those links are opened inside Facebook, Messenger or Instagram, and their in-app browsers block Google sign-in and wallet connections. Our workarounds:

  • Android: the page tries to reopen itself in the default browser.
  • iPhone: a banner explains how to copy the link into Safari, or use "Open in external browser".
  • Simplest path for beginners: "Continue with Google". Wallets like MetaMask work too, but they add steps on mobile.

If you build anything that gets shared on social media, test it inside those in-app browsers first. It's where most of your traffic will land.

Small things we didn't expect

  • Language and tone matter. We write in French, the main written language for this kind of content in Madagascar, with Malagasy where it helps. Public pages use the formal "vous"; once you're signed in, the app switches to the friendlier "tu".
  • Education comes before the product. Our free guides (scams to avoid, TRC20 vs ERC20 vs BEP20, how to withdraw to Ariary) get more attention than any feature announcement. People need to understand gas and networks before they care about gasless swaps.
  • "Never" is a feature. We repeat that Varika will never ask for your recovery phrase, password or SMS code. Fake "support" accounts are the most common scam we see.

The stack, in one paragraph

Varika is a Next.js / React app written in TypeScript, backed by PostgreSQL. Swaps use NEAR Intents through the 1Click API, with signed EIP-191 intents submitted by a relayer. Sign-in is either an extension wallet or a non-custodial embedded wallet with split keys. P2P trades rely on a Rust/near-sdk escrow contract on NEAR mainnet, and the Mobile Money side stays a manual, peer-to-peer payment.

What's next

Varika isn't open to the public yet: we're preparing a beta with a first group of sellers who already trade USDT in Madagascar. In the meantime, we publish free, plain-language crypto guides for Malagasy users.

If you've built on NEAR Intents, worked on P2P escrows, or shipped fintech for markets where Mobile Money comes before bank cards, we'd love to hear from you in the comments.

👉 Learn more: varika.net


Crypto assets carry a risk of capital loss. This article describes how we build Varika; it is not investment advice. Screens and figures shown in our demos use fictitious data.

Top comments (0)