Skip to content
This repository was archived by the owner on Apr 21, 2025. It is now read-only.

Commit d54147b

Browse files
committed
Use secure storage for overriding nsec
1 parent a32b6dd commit d54147b

File tree

7 files changed

+76
-5
lines changed

7 files changed

+76
-5
lines changed

android/app/capacitor.build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ dependencies {
1818
implementation project(':capacitor-share')
1919
implementation project(':capacitor-status-bar')
2020
implementation project(':capacitor-toast')
21+
implementation project(':capacitor-secure-storage-plugin')
2122

2223
}
2324

android/capacitor.settings.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ project(':capacitor-status-bar').projectDir = new File('../node_modules/.pnpm/@c
2828

2929
include ':capacitor-toast'
3030
project(':capacitor-toast').projectDir = new File('../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@capacitor/toast/android')
31+
32+
include ':capacitor-secure-storage-plugin'
33+
project(':capacitor-secure-storage-plugin').projectDir = new File('../node_modules/.pnpm/[email protected]_@[email protected]/node_modules/capacitor-secure-storage-plugin/android')

ios/App/Podfile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ def capacitor_pods
2020
pod 'CapacitorShare', :path => '../../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@capacitor/share'
2121
pod 'CapacitorStatusBar', :path => '../../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@capacitor/status-bar'
2222
pod 'CapacitorToast', :path => '../../node_modules/.pnpm/@[email protected]_@[email protected]/node_modules/@capacitor/toast'
23+
pod 'CapacitorSecureStoragePlugin', :path => '../../node_modules/.pnpm/[email protected]_@[email protected]/node_modules/capacitor-secure-storage-plugin'
2324
end
2425

2526
target 'App' do

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"@solid-primitives/upload": "^0.0.111",
6161
"@solidjs/meta": "^0.29.1",
6262
"@solidjs/router": "^0.9.0",
63+
"capacitor-secure-storage-plugin": "^0.9.0",
6364
"i18next": "^22.5.1",
6465
"i18next-browser-languagedetector": "^7.1.0",
6566
"qr-scanner": "^1.4.2",

pnpm-lock.yaml

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/logic/mutinyWalletSetup.ts

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* @refresh reload */
22

3+
import { Capacitor } from "@capacitor/core";
34
import initMutinyWallet, { MutinyWallet } from "@mutinywallet/mutiny-wasm";
5+
import { SecureStoragePlugin } from "capacitor-secure-storage-plugin";
46

57
export type Network = "bitcoin" | "testnet" | "regtest" | "signet";
68

@@ -249,6 +251,17 @@ export async function setupMutinyWallet(
249251
scorer
250252
} = settings;
251253

254+
let nsec;
255+
// get nsec from secure storage
256+
if (Capacitor.isNativePlatform()) {
257+
try {
258+
const value = await SecureStoragePlugin.get({ key: "nsec" });
259+
nsec = value.value;
260+
} catch (e) {
261+
console.log("No nsec stored");
262+
}
263+
}
264+
252265
console.log("Initializing Mutiny Manager");
253266
console.log("Using network", network);
254267
console.log("Using proxy", proxy);
@@ -290,7 +303,8 @@ export async function setupMutinyWallet(
290303
// Safe mode
291304
safeMode || undefined,
292305
// Skip hodl invoices? (defaults to true, so if shouldZapHodl is true that's when we pass false)
293-
shouldZapHodl ? false : undefined
306+
shouldZapHodl ? false : undefined,
307+
nsec
294308
);
295309

296310
sessionStorage.setItem("MUTINY_WALLET_INITIALIZED", Date.now().toString());

src/routes/settings/SyncNostrContacts.tsx

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import { Capacitor } from "@capacitor/core";
12
import { createForm, required, SubmitHandler } from "@modular-forms/solid";
2-
import { createSignal, Match, Show, Switch } from "solid-js";
3+
import { MutinyWallet } from "@mutinywallet/mutiny-wasm";
4+
import { SecureStoragePlugin } from "capacitor-secure-storage-plugin";
5+
import { createResource, createSignal, Match, Show, Switch } from "solid-js";
36

47
import {
58
BackPop,
@@ -31,6 +34,8 @@ function SyncContactsForm() {
3134
const [state, actions] = useMegaStore();
3235
const [error, setError] = createSignal<Error>();
3336

37+
const allowNsec = Capacitor.isNativePlatform();
38+
3439
const [feedbackForm, { Form, Field }] = createForm<NostrContactsForm>({
3540
initialValues: {
3641
npub: ""
@@ -41,7 +46,26 @@ function SyncContactsForm() {
4146
f: NostrContactsForm
4247
) => {
4348
try {
44-
const npub = f.npub.trim();
49+
const string = f.npub.trim();
50+
let npub = string;
51+
52+
// if it is an nsec, save it into secure storage
53+
if (string.startsWith("nsec")) {
54+
if (!allowNsec) {
55+
throw new Error(
56+
"nsec not allowed in web version, please install the app"
57+
);
58+
}
59+
60+
// set in storage
61+
SecureStoragePlugin.set({ key: "nsec", value: string }).then(
62+
(success) => console.log(success)
63+
);
64+
65+
// set npub and continue
66+
npub = await MutinyWallet.nsec_to_npub(string);
67+
}
68+
4569
if (!PRIMAL_API) throw new Error("PRIMAL_API not set");
4670
await state.mutiny_wallet?.sync_nostr_contacts(PRIMAL_API, npub);
4771
actions.saveNpub(npub);
@@ -68,7 +92,7 @@ function SyncContactsForm() {
6892
value={field.value}
6993
error={field.error}
7094
label={i18n.t("settings.nostr_contacts.npub_label")}
71-
placeholder="npub..."
95+
placeholder={allowNsec ? "npub/nsec..." : "npub..."}
7296
/>
7397
)}
7498
</Field>
@@ -97,10 +121,26 @@ export function SyncNostrContacts() {
97121
const [loading, setLoading] = createSignal(false);
98122
const [error, setError] = createSignal<Error>();
99123

100-
function clearNpub() {
124+
async function clearNpub() {
101125
actions.saveNpub("");
126+
if (Capacitor.isNativePlatform()) {
127+
await SecureStoragePlugin.remove({ key: "nsec" });
128+
}
102129
}
103130

131+
const [hasNsec] = createResource(async () => {
132+
if (Capacitor.isNativePlatform()) {
133+
try {
134+
await SecureStoragePlugin.get({ key: "nsec" });
135+
return true;
136+
} catch (_e) {
137+
return false;
138+
}
139+
} else {
140+
return false;
141+
}
142+
});
143+
104144
async function resync() {
105145
setError(undefined);
106146
setLoading(true);

0 commit comments

Comments
 (0)