rectangle-terminaldGEN1 Terminal SDK

Android library for controlling the dGEN1 terminal screen and the 3x3 LED array via a clean, coroutine-based Kotlin API. Both subsystems communicate with hidden system services through reflection and gracefully no-op on non-dGEN1 hardware.

Table of Contents


Installation

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

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:

Running from source: If you've cloned or forked this repo, include the SDK module directly in settings.gradle.kts:

Then reference it from your app module:


Quick Start


Terminal Button

The terminal screen is a 428x142 pixel display on the back of the dGEN1 device. The SDK ships with pre-built button layouts that render as bitmaps and register touch handlers automatically.

Dual-Button Layouts

Single-Button Layouts

Each renders a full-width button and fires the callback on any tap:

Status Text

Display arbitrary text on a black background (no touch handler):

Dismiss

Restore the default system display (status bar) and remove touch handlers:

All show* methods are suspend functions. Call them from a coroutine scope (e.g. lifecycleScope.launch { ... }).


LED Matrix Patterns

The 3x3 LED array on the front of the device supports a library of built-in patterns. Each accepts an optional hex colour string — when omitted, the system accent colour is used.

Displaying Patterns

Display by Name

You can also display a pattern dynamically by its string name:

List Available Patterns


Flash Patterns

Flash patterns display a status indicator briefly (default 1 second), then automatically revert to the chad branding pattern. Useful for confirming actions like successful transactions or errors.

Practical Example: Transaction Flow


Custom LED Matrix Grid

Beyond predefined patterns, you have full control over individual LEDs in the 3x3 grid.

Grid Layout

Set a Single LED

Set All LEDs to One Colour

Custom 3x3 Pattern

Pass a 3x3 array of hex colour strings. Use "#000000" for off:

Adjust Brightness

Colour Format

The SDK accepts colours in any of these formats — they're normalised internally:

Format
Example

#RRGGBB

"#FF0000"

#AARRGGBB

"#FFFF0000"

0xRRGGBB

"0xFF0000"

0xAARRGGBB

"0xFFFF0000"


Building Custom Terminal Screens

The SDK ships with pre-built button layouts, but you can design your own terminal screen with custom buttons, icons, text, and touch regions. The terminal screen is 428x142 pixels — everything you show is an XML layout rendered into a bitmap.

How It Works

  1. Create an XML layout sized to 428x142 px

  2. Render it into a Bitmap using LayoutRenderer (or manually)

  3. Push the bitmap to the terminal screen with showOnDisplay()

  4. Register a touch handler to make regions interactive

Step 1: Create Your XML Layout

Create a layout file in your app's res/layout/ directory. The root must be 428px wide and 142px high with a black background to match the terminal screen:

Design tips:

  • Always use a #000000 background (OLED-friendly, matches the device)

  • Use the included @font/monomaniac font for the authentic terminal aesthetic, or apply the @style/terminal_text style

  • Keep text uppercase with letter spacing for readability at small sizes

  • Use the system accent colour for icons/labels (see Step 2)

  • The ConstraintLayout dependency is already included in the SDK

Step 2: Render the Layout to a Bitmap

Inflate your layout, apply the system accent colour, and convert it to a bitmap:

Shortcut: You can also use the SDK's built-in LayoutRenderer as a reference or extend it. The renderer in terminal.renderer already handles inflation, measuring, accent colouring, and bitmap conversion for the built-in layouts.

Step 3: Display It with Touch Handling

Push the bitmap to the terminal screen and register touch zones:

Step 4: Clean Up

Always dismiss your custom screen when leaving:

Full Example: Custom Approve/Reject Screen

Putting it all together in a ViewModel-driven flow:

Advanced: Three-Zone Touch Layout

You're not limited to a left/right split. Divide the 428px width into any number of zones:

Advanced: Programmatic Bitmap (No XML)

If you prefer to skip XML entirely, draw directly onto a Canvas:


Custom Bitmaps

For any fully custom content, render any Bitmap to the terminal screen:

You can also use the built-in LayoutRenderer to render the SDK's pre-built layouts manually:


Terminal Screen Power Control

Control the terminal screen power state directly:


Lifecycle Management

Proper lifecycle management prevents resource leaks and ensures the terminal screen returns to its default state when your app is backgrounded or destroyed.

Activity Lifecycle

Jetpack Compose Lifecycle

Use DisposableEffect tied to the composable lifecycle:

ViewModel Scoped Usage

If you use the SDK from a ViewModel, clean up in onCleared():


Architecture Patterns for Production Apps

For larger apps (like the ethOS Wallet Manager), structure your terminal interactions through a repository layer with dependency injection.

Repository Pattern

Wrap the SDK in a repository to decouple UI from hardware control and emit touch events as flows:

Dependency Injection with Hilt

Provide the SDK as a nullable singleton — it will be null on non-dGEN1 devices:

Collecting Events in a ViewModel

Screen-Aware Terminal Updates

Update the terminal screen as the user navigates between screens:


API Reference

TerminalSDK

Property / Method
Description

display: TerminalDisplay?

Terminal screen controller (null if unavailable)

led: TerminalLED?

LED array controller (null if unavailable)

renderer: LayoutRenderer

Renders XML layouts to bitmaps for the terminal screen

isAvailable: Boolean

true if either display or LED is available

isDisplayAvailable: Boolean

true if the terminal screen is available

isLedAvailable: Boolean

true if the LED array is available

showQrOrSend(onQrCode, onSend)

Show QR/Send dual-button (suspend)

showSendNft(onQrCode, onSendNft)

Show QR/Send NFT dual-button (suspend)

showCopy(onCopy)

Show Copy button (suspend)

showCopiedAddress(onTap)

Show Copied confirmation (suspend)

showTopUp(onTopUp)

Show Top Up button (suspend)

showLog(onLog)

Show View on Explorer button (suspend)

showDetailLog(onDetailLog)

Show View TX in Explorer button (suspend)

showSwap(onSwap)

Show Swap button (suspend)

showBlackText(text)

Show text on black background (suspend)

showOnDisplay(bitmap, touchListener?)

Push any bitmap to the terminal screen (suspend)

dismissDisplay()

Restore default terminal screen, remove touch handlers (suspend)

destroy()

Release all resources — call in onDestroy()

TerminalLED

Method
Description

isAvailable: Boolean

Whether the LED subsystem is available

displayChad(color?)

Show ethOS branding pattern

displayPlus(color?) / displayMinus(color?)

Show +/− pattern

displaySend(color?) / displayReceive(color?)

Show arrow up/down pattern

displaySwap(color?) / displaySign(color?)

Show swap/sign pattern

displaySuccess(color?)

Show success checkmark

displayError(color?)

Show error cross

displayWarning(color?)

Show warning symbol

displayInfo(color?)

Show info symbol

displayPattern(name, color?)

Show pattern by string name

flashSuccess(color?, durationMs?)

Flash success then revert to chad

flashError(color?, durationMs?)

Flash error then revert to chad

flashWarning(color?, durationMs?)

Flash warning then revert to chad

flashInfo(color?, durationMs?)

Flash info then revert to chad

setColor(row, col, color)

Set single LED colour (row/col 0-2)

setColor(row, col, color, brightness)

Set single LED with brightness (0-8)

setAllColor(color, brightness?)

Set all LEDs to one colour

setCustomPattern(pattern, brightness?)

Set arbitrary 3x3 colour pattern

setBrightness(brightness)

Set global brightness (0-8)

applyBrightness(hexColor, brightnessPercent)

Adjust colour brightness (0-100%)

getAvailablePatterns(): List<String>

List all predefined pattern names

getSystemColor(): String?

Get cached system accent colour

refreshSystemColor()

Re-read the system accent colour

clear()

Turn off all LEDs

destroy()

Clear LEDs and cancel pending coroutines

TerminalDisplay

Method
Description

isAvailable(): Boolean

Whether the terminal screen is available (suspend)

isScreenOn(): Boolean

Check if terminal screen is on (suspend)

screenOn() / screenOff()

Power the terminal screen on/off (suspend)

refresh(bitmap, layerId): Boolean

Push a bitmap to a display layer (suspend)

resume(layerId)

Restore a display layer (suspend)

registerTouchListener(listener)

Register a touch callback

destroyTouchHandler()

Remove the current touch callback (suspend)

destroyTouchHandlerSync()

Remove touch callback synchronously

finish()

Restore status bar + destroy touch handler

Display Layer Constants

Constant
Description

ID_STATUSBAR

System status bar layer

ID_INCOMINGCALL

Incoming call layer

ID_NOTIFICATIONS

Notification layer

ID_CLOCK

Clock layer

ID_GOOGLEBYE

Always-on display (AOD) layer

ID_PERSISTENT

Persistent layer (stays until replaced)


Requirements

  • Android API 33+ (minSdk)

  • dGEN1 device for hardware features — the SDK gracefully no-ops on standard Android devices

  • Kotlin Coroutines — display methods are suspend functions


Contributing

  1. Fork or clone the repository

  2. Open the project in Android Studio

  3. The app module is a demo app that exercises every SDK feature — run it on an dGEN1 device to test

  4. The TerminalSDK module is the library — make your changes there

  5. Submit a pull request

Project Structure

GitHub Repo:

Last updated