Tub iOS Trading App

Tub

tub

Tub is a mobile trading app for memecoins on Solana with a full backend stack.

Introduction

The source code for this repository is available on Github here (opens in a new tab). This monorepo is composed of an ios package for the Swift iOS app, and a few components for the backend stack that are modified versions of published libraries.

Refer to their dedicated pages for documentation on the Solana DEX Server and the Solana DEX GraphQL packages.

Overview

The iOS app (opens in a new tab) is a SwiftUI app that allows users to trade memecoins indexed by our indexer (opens in a new tab) in the database (opens in a new tab).

They can onramp to an embedded Solana wallet with Privy (opens in a new tab) using the Coinbase onramp SDK (opens in a new tab).

Trades are constructed and submitted using our server (opens in a new tab), which handles priority fees that are sponsored by a provided wallet.

Installation

This monorepo uses pnpm as its package manager. First, install node, then npm (opens in a new tab), then install pnpm.

npm install -g pnpm

This repository is tested with node version 23.5.0 and pnpm version 9.15.2.

Then, clone the repository and install the necessary npm packages with the following from the root folder:

git clone https://github.com/primodiumxyz/tub-ios.git
cd tub-ios
pnpm i

See each respective package's README for more information on installation and requirements.

Environment

To set the current environment variables for both local development and production, copy /.env.example to a new /.env.

cp .env.example .env

See the example environment file (opens in a new tab) for information on each variable.

You will need to the the server and database instance URLs in the Constants.swift (opens in a new tab) file for the built app to work.

Same is true for the Privy app ID and client ID in the Privy.swift (opens in a new tab) file.

Dependencies

This stack—or specifically the indexer—requires some external services to request and subscribe to onchain data.

All of these are available from QuickNode through add-ons, which is the recommended way to run the indexer.

Otherwise, Hasura and Timescale will be run locally during development, and can be either self-hosted or cloud-hosted with their respective offerings.

Development

First, install Docker Desktop (opens in a new tab), or any other preferred Docker alternative. OrbStack (opens in a new tab) is a good and efficient alternative for Mac users. This will be required to run the database.

Running the following in the root directory of this monorepo will spin up both the indexer and databases/interfaces, as well as the dashboard for analytics.

pnpm dev

You can run the dashboard only to monitor remote analytics; first set NODE_ENV=production in the .env file, then run the following:

pnpm dev:dashboard

If you would like to test the app on a physical device and point to the local instances, you will need to set up a tool such as ngrok (opens in a new tab) to tunnel the local development URLs to a public endpoint. This would be done for both the local server and database instances. And then, update the Constants.swift (opens in a new tab) file to read the ngrok environment variables. Note that this might be tricky to configure for the GraphQL URLs.

Refer to the Tub iOS docs to test the latest user-facing features, such as launching the app in Xcode.

Details

Indexing and database

The entire flow for writing indexed trades to the database, and interacting with the database from the client, can be illustrated in the following diagram:

Indexing and database

Structure

The codebase is structured as a pnpm monorepo with the following packages:

apps - "Applications that compose the entire stack"
├── dashboard - "A React dashboard for visualizing top-ranked tokens and analytics data from the app"
├── ios - "The Swift iOS app"
└── server - "A modified version of the published `@primodiumxyz/dex-server` package"
packages - "Libraries that compose the stack"
└── gql - "A modified version of the published `@primodiumxyz/dex-graphql` package"

Contributing

If you wish to contribute to the package, please open an issue first to make sure that this is within the scope of the repository, and that it is not already being worked on.

License

This project is licensed under the MIT License - see LICENSE (opens in a new tab) for details.