1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
// Copyright (C) 2024 Vaughn Nugent
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of 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.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import { cloneDeep } from "lodash";
import { Endpoints } from "./server-api";
import { type FeatureApi, type BgRuntime, type IFeatureExport, optionsOnly, exportForegroundApi } from "./framework";
import { type AppSettings } from "./settings";
import { EventTagFilterApi } from "./tagfilter-api";
import type { NostrRelay, EncryptionRequest, NostrEvent } from './types';
import { HistoryApi } from "./history";
/**
* The NostrApi is the foreground api for nostr events via
* the background script.
*/
export interface NostrApi extends FeatureApi {
getRelays: () => Promise<NostrRelay[]>;
signEvent: (event: NostrEvent) => Promise<NostrEvent | undefined>;
setRelay: (relay: NostrRelay) => Promise<NostrRelay | undefined>;
nip04Encrypt: (data: EncryptionRequest) => Promise<string>;
nip04Decrypt: (data: EncryptionRequest) => Promise<string>;
}
export const useNostrApi = (): IFeatureExport<AppSettings, NostrApi> => {
return{
background: ({ state, openBackChannel }: BgRuntime<AppSettings>) =>{
const { execRequest } = state.useServerApi();
let tagFilter: EventTagFilterApi | undefined;
let evHistory: HistoryApi | undefined;
//Register for tag filter, and history back channel
openBackChannel<EventTagFilterApi>('useEventTagFilterApi', (feature) => tagFilter = feature)
openBackChannel<HistoryApi>('useHistoryApi', (feature) => evHistory = feature)
return {
getRelays: async (): Promise<NostrRelay[]> => {
//Get preferred relays for the current user
const [...relays] = await execRequest(Endpoints.GetRelays)
return relays;
},
signEvent: async (req: NostrEvent): Promise<NostrEvent | undefined> => {
//Store copy to prevent mutation
const event = cloneDeep(req)
//If tag filter is enabled, filter before continuing
if (tagFilter){
//Filter tags
await tagFilter.filterTags(event);
}
//Sign the event
const result = await execRequest(Endpoints.SignEvent, event);
//Refresh history
evHistory?.refresh();
return result;
},
nip04Encrypt: async (data: EncryptionRequest): Promise<string> => {
const message: EncryptionRequest = {
content: data.content,
KeyId: data.KeyId,
pubkey: data.pubkey
}
return execRequest(Endpoints.Encrypt, message);
},
nip04Decrypt: (data: EncryptionRequest): Promise<string> => {
const message: EncryptionRequest = {
content: data.content,
KeyId: data.KeyId,
pubkey: data.pubkey
}
return execRequest(Endpoints.Decrypt, message);
},
setRelay: optionsOnly((relay: NostrRelay): Promise<NostrRelay | undefined> => {
return execRequest(Endpoints.SetRelay, relay)
}),
}
},
foreground: exportForegroundApi([
'getRelays',
'signEvent',
'setRelay',
'nip04Encrypt',
'nip04Decrypt'
])
}
}
|