# MultiCurrencyWallet: a client-side crypto wallet you can embed in a site

> MultiCurrencyWallet is an MIT licensed TypeScript wallet that runs in the browser, holds Bitcoin, Ethereum, BSC, Matic and ERC20 and BEP20 tokens, and includes an atomic swap exchange with an orderbook. It is meant to be white labelled and embedded into other products rather than used as a standalone app.

**swaponline/MultiCurrencyWallet** — Bitcoin, Ethereum, ERC20 crypto wallets with 0x and atomic swap exchange. 

- Repository: https://github.com/swaponline/MultiCurrencyWallet
- Website: https://swaponline.github.io
- Stars: 543 · Forks: 487
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/swaponline-multicurrencywallet

## A wallet as an embeddable component, not an app

MultiCurrencyWallet is a crypto wallet for BTC, ETH with ERC20 tokens, BSC with BEP20, Matic with tokens, USDT and other custom tokens, described as open-source and client-side, and listed as embeddable into your site. That last bullet is the one that determines who this is for.

The README frames the product in terms of what it can be deployed as: a live demo at swaponline.github.io, a WordPress plugin with an admin panel for people without coding skills, and a self-built version following an installation guide in the docs directory. It also advertises one-click white label deployment to AWS, and points at a marketplace listing for it.

So the intended users are people building a product that needs a wallet, not people looking for a wallet to hold their own coins. The feature list of the wallet itself is standard: add many assets to your wallet, an ERC20 token wallet, and a secondary market for trading between users with an orderbook demo.

The primary language is TypeScript, the licence is MIT, and the homepage is swaponline.github.io. The project also sits inside a wider open-source DeFi toolkit from onout.org, alongside a DEX, a farming tool, a cross-chain bridge, a DAO widget, an NFT showcase plugin and a prediction market, which tells you it was built as one component of a suite rather than as a standalone product.

## Atomic swaps and the orderbook exchange

The exchange side is peer to peer with atomic swaps, which is the mechanism that lets two parties trade without a third party holding the funds or an escrow service locking them up.

The difference in approach from a centralised exchange is worth spelling out, because it determines the user experience. In a centralised orderbook, the exchange holds the assets and the trades settle against its ledger, which is fast and liquid. In an atomic swap, the two sides of the trade settle through cryptographic mechanisms rather than through a balance held by the platform, which means the platform is not a trusted custodian but also cannot guarantee that a counterparty will complete their half.

The README advertises the orderbook demo and the onout DEX as a separate product, and the wallet apps container is described as experimental, for opening external dApps such as Onout DEX or Uniswap inside the wallet interface, with bridge documentation in the docs directory under WALLET_APPS_BRIDGE.md and a dApp guide under WALLET_APPS_DAPP_GUIDE.md. The word experimental is the maintainers' own qualifier and should be taken at face value for the dApp container.

For fiat, the wallet lists a fiat gateway for USD, EUR, RUB, UAH and other currencies through itez.com, which is a third-party onramp rather than something the wallet implements. That distinction matters for compliance: the wallet is the custody and interface layer, and the fiat side is delegated to a provider whose own terms and availability you inherit.

## Running it in Docker

The repository ships a Dockerfile and a docker-compose.yml, and they are worth reading closely because they describe how the project is actually run.

The compose file defines a single service:

```yaml
version: '3'
services:
  mcw_bot:
    build: .
    image: swaponline/mcw
    container_name: mcw_mainnet_bot
    restart: unless-stopped
    volumes:
      - ${PWD}/config:/root/MulticurrencyWallet/config
      - ${PWD}/.storage:/root/MulticurrencyWallet/.storage
      - ${PWD}/config/tradeconfig.mainnet.json:/root/MultiCurrencyWallet/tradeconfig.mainnet.json
      - ${PWD}/config/tradeconfig.testnet.json:/root/MultiCurrencyWallet/tradeconfig.testnet.json    
    env_file: .env
    ports:
      - "${PORT}:${PORT}"
```

Four volumes are mounted: the config directory, a .storage directory, and the mainnet and testnet trade configuration files as separate mounts. The repo root contains tradeconfig.mainnet.json.example and tradeconfig.testnet.json.example, which are the templates for those two files, so the pattern is to copy the example into the config directory and edit it. The service reads its environment from a .env file and publishes a single port from the environment variable PORT.

The Dockerfile is where the age of the project shows:

```dockerfile
FROM node:14-slim

RUN apt-get update && apt-get install -yq curl git  g++ python make mc screen nano

ADD https://api.github.com/repos/swaponline/MultiCurrencyWallet/git/refs/heads/master version.json
RUN git clone -b master https://github.com/swaponline/MultiCurrencyWallet.git /root/MultiCurrencyWallet

WORKDIR /root/MultiCurrencyWallet

RUN npm i

CMD [ "npm", "start" ]

EXPOSE 80
```

Node 14 is the base image, which reached end of life in April 2023. The image installs build tools, clones the master branch at build time, runs npm i and starts with npm start, exposing port 80. There is no pinned commit and no pinned dependency tree, so two builds of the same Dockerfile can produce different images, which is a real reproducibility problem for anything running in production.

## The package structure and how the code is tested

The package manifest is named swap.online, is marked private, and sits at version 1.0.422. The main entry point is ./src/front/bin/server, which tells you the project has a server component alongside the client side wallet, even though the marketing describes the wallet as client-side.

The scripts reveal the architecture and, more usefully, the testing strategy. There is a core built separately from the front end: core:build runs babel over ./src/core, core:dev runs it in watch mode, core:clean removes the output with rimraf, and core:build:umd produces a UMD bundle through webpack, with a Windows-specific variant using webpack.config.babel.js directly. The core is therefore a separate library, published or at least built independently, that other products in the ecosystem can consume.

The test scripts are the most revealing part. There is a unit suite for the core with jest and a DEBUG swap.core* flag, unit tests under tests/unit run with cross-env CONFIG=testnet.dev, and a dedicated bitcoin send test. Then there are end to end suites with names that describe the actual flows: prepareToSwap, swap_btc_to_ethWbtc, swap_maticWbtc_to_btc, e2e_send_btc, e2e_send_evm, e2e_swap, and a send:actions variant that sets ACTIONS=true. The --detectOpenHandles flag on the e2e suites is what a test suite uses when it suspects handles are being left open, typically around wallets or network connections.

So the flows that matter to a wallet user, sending Bitcoin, sending on an EVM chain, and performing swaps between chains, are covered by dedicated end to end tests running against testnet configuration. The postinstall script runs patch-package, and there is a patches/ directory at the root, so the build applies local patches to dependencies.

## Customisation, white labelling and localisation

The project separates the two ways of building it. If you use the WordPress plugin, customisation happens in the admin panel, with images, colours and texts all adjustable. If you make your own build, there is a customisation guide in the docs directory alongside the installation guide.

That split is a deliberate product decision rather than an accident of documentation. The plugin is sold as a way for people without coding skills to deploy a wallet, so it has to expose configuration through a form. The own-build path is for developers who want to change the source, and the guides are split to match.

Localisation is a fixed set of five languages: English, Russian, Dutch, Spanish and Polish, with work in progress to add more. For a wallet aimed at the onout ecosystem and at the fiat providers itez.com supports, that language list is a reasonable proxy for where the intended users are, and it is worth checking before you commit to a market that is not on it.

The repository layout also contains mobile/, android/ and an android_archive/ directory, plus a wordpress/ directory, which tells you the project has had or has native app ambitions alongside the browser build. The presence of android_archive/ suggests that effort was shelved rather than completed, which is worth knowing before you plan an app on top of this.

## Funding, token promotion and what to be careful about

Two things in this README deserve a careful reading before anyone builds on the project.

The first is how the project asks for support. The list offers three things: buy the SWAP token, donate, and, described as the easiest, star the project. The SWAP token documentation in the docs directory is framed around an investment opportunity, with a target price, and the README links it under a heading about investment. That is a token promotion sitting inside the documentation of an MIT licensed wallet, and it is a distinction worth keeping clear: the code is permissively licensed and you can use it without buying anything, while the project's own funding model points at a token whose value depends on the ecosystem you build on top of it. Reading the two separately is the sensible approach.

The second is the maturity of the codebase. The Dockerfile is on Node 14, the compose file mounts a directory called .storage which is where wallet state would live, and the version number 1.0.422 indicates a project that has been iterating for a long time without reaching a 2.0. There is no changelog or release history visible in the repository entries, and there are no GitHub releases, so there is no published upgrade path to follow.

On the licensing side, MIT applies to the code, and the WordPress plugin is sold separately through a marketplace, so the commercial support route is that listing rather than the repository. The repository also contains a CLAUDE.md and a SKILL.md, which is a sign that machine-written contributions and a structured agent workflow are part of how this project is developed now.

## Conclusion

MultiCurrencyWallet suits a team that needs to put a crypto wallet inside its own product and wants the keys handled client-side in the browser, since the whole architecture is a build you embed rather than an app you deploy. It is the wrong tool if you need a custodial or audited production wallet, and it is the wrong tool if you need exchange-grade liquidity, since the P2P orderbook is between users rather than a market maker. Verify first whether atomic swaps work on the pairs you need, whether the fiat gateway providers still support your jurisdictions, and note that the Dockerfile is built on node:14-slim and the package version is 1.0.422 with the last push on 2026-05-27.

## FAQ

### What is MultiCurrencyWallet and who is it for?

It is an MIT licensed client-side crypto wallet for BTC, ETH with ERC20, BSC with BEP20, Matic and other tokens, with an atomic swap exchange. It is aimed at teams who want to embed a wallet into their own product, since it is listed as embeddable into your site and is offered as a white label build.

### How do I run MultiCurrencyWallet with Docker?

The repository ships a docker-compose.yml with a single service built from the Dockerfile, mounting config, .storage and the mainnet and testnet tradeconfig files, reading a .env file and publishing ${PORT}. The repository root holds tradeconfig.mainnet.json.example and tradeconfig.testnet.json.example as templates.

### What does MultiCurrencyWallet use for its exchanges?

The exchange is peer to peer with atomic swaps, and the README shows an orderbook demo for trading between users. Fiat on and off ramps are delegated to itez.com for USD, EUR, RUB, UAH and other currencies.

### Which languages does the MultiCurrencyWallet interface support?

English, Russian, Dutch, Spanish and Polish, with work in progress to add more languages.

### How is the MultiCurrencyWallet project tested?

The package scripts define a core jest suite with a DEBUG swap.core* flag, unit tests under tests/unit run with cross-env CONFIG=testnet.dev, and end to end suites covering prepareToSwap, BTC to ETH WBTC swaps, Matic WBTC to BTC swaps, sending BTC and sending on EVM chains, all using --detectOpenHandles.

### Can I customise the look of the wallet?

Yes, images, colours and texts can all be changed. The WordPress plugin exposes this in its admin panel, while your own build follows the customisation guide in the docs directory.

## Sources

- [Issues](https://github.com/swaponline/MultiCurrencyWallet/issues)
- [License: MIT](https://github.com/swaponline/MultiCurrencyWallet/blob/master/LICENSE)
- [Project website](https://swaponline.github.io)
- [README](https://github.com/swaponline/MultiCurrencyWallet/blob/master/README.md)
- [swaponline/MultiCurrencyWallet on GitHub](https://github.com/swaponline/MultiCurrencyWallet)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/swaponline-multicurrencywallet
