diagram-projectPaymaster SDK

Android library for interacting with the ethOS Paymaster system. Provides balance management, top-up flows (via Daimo), ERC-4337 gas estimation (via Pimlico), and token price lookups — all wrapped in a clean, synchronous Kotlin API designed for Dispatchers.IO.

Installation

Step 1. Add the JitPack repository to your project's settings.gradle.kts (inside the dependencyResolutionManagement block):

dependencyResolutionManagement {
    repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
    repositories {
        google()
        mavenCentral()
        maven { url = uri("https://jitpack.io") }
    }
}

If your project uses a root build.gradle.kts with allprojects { repositories { ... } } instead, add the maven line there.

Step 2. Add the dependency to your app module's build.gradle.kts:

dependencies {
    implementation("com.github.EthereumPhone:PaymasterSDK:0.1.0")
}

Quick Start

// 1. Create the SDK instance
val paymasterSDK = PaymasterSDK(
    context = applicationContext,
    bundlerApiKey = "your-pimlico-api-key"
)

// 2. Initialize (connects to the on-device PaymasterProxy service)
withContext(Dispatchers.IO) {
    val available = paymasterSDK.initialize()

    if (available) {
        // 3. Read the cached balance
        val balance = paymasterSDK.getBalance()   // e.g. "12.50"

        // 4. Trigger a fresh balance sync from the backend
        paymasterSDK.queryBalanceUpdate()

        // 5. Listen for balance changes
        paymasterSDK.registerBalanceObserver { newBalance ->
            // update your UI
        }

        // 6. Initiate a top-up (returns a Daimo checkout URL)
        val topUp = paymasterSDK.initiateTopUp(
            userId = "0xYourWalletAddress",
            amount = "10"
        )
        topUp?.let {
            // open it.checkoutUrl in a browser / WebView
        }

        // 7. Estimate gas for a UserOperation
        val gasEstimation = paymasterSDK.estimateGas(userOp, chainId = 8453)

        // 8. Fetch token prices for sponsorship
        val prices = paymasterSDK.fetchSponsorshipPrices(
            listOf("0xTokenAddress1", "0xTokenAddress2")
        )
    }
}

// 9. Clean up when done (e.g. in onDestroy)
paymasterSDK.cleanup()

Permissions

The SDK declares the following permissions in its own manifest (merged automatically):

Permission
Purpose

INTERNET

Communicate with the Paymaster backend and Pimlico

ACCESS_NETWORK_STATE

Check network availability

No runtime permissions are required — both are normal permissions granted at install time.

API

PaymasterSDK

Constructor

Parameter
Description

context

Application or Activity context

bundlerApiKey

Your Pimlico API key (used for gas estimation & bundler URL)

baseUrl

(Optional) Paymaster backend base URL

Methods

Method
Return Type
Description

initialize()

Boolean

Connect to the on-device PaymasterProxy system service. Returns true if the service is available (ethOS device), false otherwise. Must be called before any other method.

getBalance()

String?

Returns the cached paymaster balance (e.g. "12.50"), or null if unavailable.

queryBalanceUpdate()

Unit

Triggers an asynchronous balance refresh from the backend. Listen for the result with registerBalanceObserver.

registerBalanceObserver(callback: (String) -> Unit)

Unit

Registers a callback that fires whenever the balance changes.

initiateTopUp(userId: String, amount: String)

TopUpResult?

Starts a top-up flow via Daimo. Returns a TopUpResult with a checkout URL, or null on failure.

estimateGas(userOp: UserOperation, chainId: Int)

GasEstimation

Estimates gas for an ERC-4337 UserOperation on the given chain using the Pimlico bundler. Falls back to safe defaults on failure.

fetchSponsorshipPrices(tokenAddresses: List<String>)

List<TokenPrice>

Fetches USD prices for the given token addresses. Returns an empty list on failure.

getBundlerUrl(chainId: Int)

String

Returns the Pimlico bundler RPC URL for the given chain ID.

cleanup()

Unit

Releases all internal resources. Call in onDestroy() or when the SDK is no longer needed.

Constants

Constant
Value
Description

PaymasterSDK.ERROR

"error"

Sentinel value indicating an error response

PaymasterSDK.UNAVAILABLE

"unavailable"

Sentinel value indicating the service is unavailable

PaymasterSDK.ENTRY_POINT_V06

"0x5FF137D4b0FDCD49DcA30c7CF57E578a026d2789"

ERC-4337 EntryPoint v0.6 contract address

Data Classes

PaymasterSDK.TopUpResult

Returned by initiateTopUp().

Property
Type
Description

daimoPaymentId

String

Unique Daimo payment identifier

checkoutUrl

String

URL to open for the user to complete payment

PaymasterSDK.UserOperation

Input for estimateGas(). Represents an ERC-4337 UserOperation (v0.6).

Property
Type
Description

sender

String

Smart account address

nonce

BigInteger

Account nonce

initCode

String

Init code (empty string if deployed)

callData

String

Encoded call data

callGasLimit

BigInteger

Gas limit for the main execution

verificationGasLimit

BigInteger

Gas limit for verification

preVerificationGas

BigInteger

Pre-verification gas

maxFeePerGas

BigInteger

Maximum fee per gas

maxPriorityFeePerGas

BigInteger

Maximum priority fee per gas

paymasterAndData

String

Paymaster address + data

signature

String

Signature bytes

PaymasterSDK.GasEstimation

Returned by estimateGas().

Property
Type
Description

preVerificationGas

BigInteger

Estimated pre-verification gas

verificationGasLimit

BigInteger

Estimated verification gas limit

callGasLimit

BigInteger

Estimated call gas limit

PaymasterSDK.TokenPrice

Returned by fetchSponsorshipPrices().

Property
Type
Description

address

String

Token contract address

symbol

String?

Token symbol (e.g. "USDC")

priceUsd

Double?

Current price in USD

Error Handling

The SDK does not throw custom exceptions. Instead it uses safe return values:

Scenario
Behavior

Service not available (non-ethOS device)

initialize() returns false

Balance unavailable

getBalance() returns null

Top-up request fails

initiateTopUp() returns null

Gas estimation fails

estimateGas() returns safe defaults (preVerificationGas = 70000, verificationGasLimit = 400000, callGasLimit = 200000)

Price fetch fails

fetchSponsorshipPrices() returns an empty list

Threading: All public methods are synchronous and perform I/O. Call them from a background thread or wrap in withContext(Dispatchers.IO).

Requirements

  • Android API 33+ (minSdk 33)

  • ethOS device (for balance & top-up features via PaymasterProxy system service)

  • Pimlico API key (for gas estimation)

GitHub Repo

Last updated