Minor fixes and README

This commit is contained in:
2026-08-21 12:34:28 +09:00
parent 8fd6d0a8a4
commit b6d96e1bc9
6 changed files with 107 additions and 18 deletions
+6 -9
View File
@@ -1,15 +1,12 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
local.properties
.idea
.DS_Store
/build
/captures
build
captures
.artifacts
.externalNativeBuild
.cxx
local.properties
erl_crash.dump
+1
View File
@@ -3,6 +3,7 @@
<component name="PlanningModeManager">
<option name="approvalStates">
<map>
<entry key="530b5232-7563-454f-bdcb-0099e4b00732" value="false" />
<entry key="a82de12b-d0aa-44d8-b9e8-e753cde67ff4" value="false" />
<entry key="b3cb996b-7f1f-4810-999d-5be96c526f74" value="false" />
</map>
+95
View File
@@ -0,0 +1,95 @@
# GajuMobile
The Android implementation of the GajuMobile wallet.
This wallet is primarily a signature device. Its purpose is not to be an
all-in-one app for every possible Gajumaru feature. It is also not intended to
integrate directly with every major app that is integrated with the Gajumaru.
## Scope
GajuMobile covers the bare minimum features necessary to interact with the
Gajumaru and, specifically, support functionality that can be expressed via
GRIDS.
App-specific functionality (direct integration with a DEX or other type of
exchange, interpretation of NFTs, transaction history tracking, etc.) are
outside of scope for GajuMobile.
Other applications can be linked to by GajuMobile, and other applications can
form Gajumaru transactions that GajuMobile can then be prompted to sign through
GRIDS, whether over the LAN or WAN.
## Project rules
GajuMobile (whether on Android, iOS, or Pine) is not permitted to include any
foreign dependencies, where "foreign" is defined as any libraries coming from
outside the Gajumaru project itself. As we cannot escape Android, at a
minimum, we are forced to trust that Android itself is trustworthy, and as
Jetpack Compose and Kotlin are now part of the core definition, those must be
trusted as well.
I don't like it, and my opinions are objectively correct, but this is the
baseline scope of trust we must accept. At least it is well defined.
This project is not permitted to use Kotlin for most primitive operations due
to basic language, build and runtime constraints imposed by the (ridiculous)
language definition. For this reason primitives that provide the functionality
found in Hakuzaru and supporting Erlang libraries have been ported in
self-contained plain-Java libraries provided by the gm-java project. In general
gm-java is written in such a way that fragments of old object memory is not
left scattered across the heap awaiting GC, and what garbage there is that
might be sensitive can be zeroed before leaving scope (yes, that was pretty
annoying to achieve in Java, and it is actually impossible to achieve in
Kotlin).
Android provides a number of facilities to achieve some memory isolation,
however, and these facilities must be used. As most of the facilities that are
of greatest interest to us in the wallet context did not exist prior to Android
14, that is the oldest version we may currently support. Hopefully we can
retire that version sooner than later, and absolutely *must* retire support for
Android 14 once it leaves the official support window.
It would be entirely possible to augment this project to work on older Android
phones, and this may even be a good idea because it would make GajuMobile a
more inclusive platform. The method to support that would be to build a second,
parallel project with support for legacy devices instead, though, rather than
force this project to maintain support for more fallback security mechanisms
and platform detection than it already is forced to.
### Reasoning
Kotlin is a rats' nest of antisensical decisions and techniques designed by
smart people for consumption by less smart people. This results in a so-called
"expressive" mess of language featuritis that can't decide what paradigm it
lives in, so it lives in them all while achieving none of them.
It is impossible to tell from the code alone what is actually going to happen
in the runtime, or even understand what is going to happen in the potentially
limitless number of pre-compilation steps based on what files are even included
in a given module, much less pin down a truly deterministic build profile if
external dependencies are included. This is the primary reason for the "no
foreign deps" rule.
## Terms
Copyright (c) 2026 QPQ AG <info@qpq.swiss>. All rights reserved. Project:
Gajumaru Core Java Libraries
This program is dual-licensed: 1) Under the GNU Affero General Public License
as published by the Free Software Foundation, either version 3 of the License,
or (at your option) any later version (AGPL-3.0-or-later). (See LICENSE file.)
2) Under a commercial/proprietary license available directly from QPQ AG. If
you wish to use this software outside the strict constraints of the AGPLv3
(e.g. within a closed-source or proprietary product), you must purchase a
commercial license from QPQ AG.
Authors:
- Craig Everett <craigeverett@qpq.swiss>
SPDX-License-Identifier: AGPL-3.0-or-later OR LicenseRef-QPQ-Commercial
-1
View File
@@ -53,7 +53,6 @@ dependencies {
implementation(libs.androidx.lifecycle.runtime.ktx)
implementation(libs.kotlinx.serialization.json)
testImplementation(libs.junit)
androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.compose.ui.test.junit4)
androidTestImplementation(libs.androidx.espresso.core)
androidTestImplementation(libs.androidx.junit)
+1 -3
View File
@@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
@@ -14,7 +13,6 @@
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.App.Starting"
android:windowSoftInputMode="adjustResize">
<intent-filter>
@@ -67,11 +67,10 @@ class MainActivity : FragmentActivity() {
lockErrorMessage = null
SecurityManager.unlock()
},
onError = { err ->
android.util.Log.e("GajuSecurity", "Unlock error: $err")
lockErrorMessage = err
}
)
) { err ->
android.util.Log.e("GajuSecurity", "Unlock error: $err")
lockErrorMessage = err
}
}
)
} else {