@konemono/nostr-login 1.7.57 → 1.7.58
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { NDKUser } from '@nostr-dev-kit/ndk';
|
|
2
1
|
import { Signer } from './Nostr';
|
|
3
2
|
|
|
4
3
|
export class AmberDirectSigner implements Signer {
|
|
5
4
|
private _pubkey: string = '';
|
|
5
|
+
private static pendingResolves: Map<string, (result: any) => void> = new Map();
|
|
6
6
|
|
|
7
7
|
constructor(pubkey?: string) {
|
|
8
8
|
this._pubkey = pubkey || '';
|
|
@@ -29,9 +29,9 @@ export class AmberDirectSigner implements Signer {
|
|
|
29
29
|
private getHash(content: string): string {
|
|
30
30
|
let hash = 0;
|
|
31
31
|
for (let i = 0; i < content.length; i++) {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
const char = content.charCodeAt(i);
|
|
33
|
+
hash = (hash << 5) - hash + char;
|
|
34
|
+
hash |= 0;
|
|
35
35
|
}
|
|
36
36
|
return hash.toString(36);
|
|
37
37
|
}
|
|
@@ -41,8 +41,8 @@ export class AmberDirectSigner implements Signer {
|
|
|
41
41
|
const cacheKey = `amber_result_${type}_${hash}`;
|
|
42
42
|
const cached = sessionStorage.getItem(cacheKey);
|
|
43
43
|
if (cached) {
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
sessionStorage.removeItem(cacheKey);
|
|
45
|
+
return cached;
|
|
46
46
|
}
|
|
47
47
|
return null;
|
|
48
48
|
}
|
|
@@ -52,19 +52,40 @@ export class AmberDirectSigner implements Signer {
|
|
|
52
52
|
sessionStorage.setItem(`amber_pending_${id}`, JSON.stringify({ hash, type }));
|
|
53
53
|
}
|
|
54
54
|
|
|
55
|
+
public static resolvePending(id: string, result: string) {
|
|
56
|
+
const resolve = this.pendingResolves.get(id);
|
|
57
|
+
if (resolve) {
|
|
58
|
+
console.log('Resolving pending Amber promise', id);
|
|
59
|
+
resolve(result);
|
|
60
|
+
this.pendingResolves.delete(id);
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
return false;
|
|
64
|
+
}
|
|
65
|
+
|
|
55
66
|
async signEvent(event: any): Promise<any> {
|
|
56
67
|
const content = JSON.stringify(event);
|
|
57
68
|
const cached = this.checkCache(content, 'sign_event');
|
|
58
69
|
if (cached) {
|
|
59
|
-
|
|
70
|
+
return JSON.parse(cached);
|
|
60
71
|
}
|
|
61
72
|
|
|
62
73
|
const id = Math.random().toString(36).substring(7);
|
|
63
74
|
this.setPending(id, content, 'sign_event');
|
|
64
75
|
const url = this.generateUrl(content, 'sign_event', id);
|
|
65
76
|
window.location.href = url;
|
|
66
|
-
|
|
67
|
-
|
|
77
|
+
return new Promise((resolve) => {
|
|
78
|
+
AmberDirectSigner.pendingResolves.set(id, (res) => resolve(JSON.parse(res)));
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
async getPublicKey(): Promise<string> {
|
|
83
|
+
const id = Math.random().toString(36).substring(7);
|
|
84
|
+
const url = this.generateUrl('', 'get_public_key', id);
|
|
85
|
+
window.location.href = url;
|
|
86
|
+
return new Promise((resolve) => {
|
|
87
|
+
AmberDirectSigner.pendingResolves.set(id, resolve);
|
|
88
|
+
});
|
|
68
89
|
}
|
|
69
90
|
|
|
70
91
|
async encrypt04(pubkey: string, plaintext: string): Promise<string> {
|
|
@@ -75,7 +96,9 @@ export class AmberDirectSigner implements Signer {
|
|
|
75
96
|
this.setPending(id, plaintext, 'nip04_encrypt');
|
|
76
97
|
const url = this.generateUrl(plaintext, 'nip04_encrypt', id, pubkey);
|
|
77
98
|
window.location.href = url;
|
|
78
|
-
return new Promise(() => {
|
|
99
|
+
return new Promise((resolve) => {
|
|
100
|
+
AmberDirectSigner.pendingResolves.set(id, resolve);
|
|
101
|
+
});
|
|
79
102
|
}
|
|
80
103
|
|
|
81
104
|
async decrypt04(pubkey: string, ciphertext: string): Promise<string> {
|
|
@@ -86,7 +109,9 @@ export class AmberDirectSigner implements Signer {
|
|
|
86
109
|
this.setPending(id, ciphertext, 'nip04_decrypt');
|
|
87
110
|
const url = this.generateUrl(ciphertext, 'nip04_decrypt', id, pubkey);
|
|
88
111
|
window.location.href = url;
|
|
89
|
-
return new Promise(() => {
|
|
112
|
+
return new Promise((resolve) => {
|
|
113
|
+
AmberDirectSigner.pendingResolves.set(id, resolve);
|
|
114
|
+
});
|
|
90
115
|
}
|
|
91
116
|
|
|
92
117
|
async encrypt44(pubkey: string, plaintext: string): Promise<string> {
|
|
@@ -97,7 +122,9 @@ export class AmberDirectSigner implements Signer {
|
|
|
97
122
|
this.setPending(id, plaintext, 'nip44_encrypt');
|
|
98
123
|
const url = this.generateUrl(plaintext, 'nip44_encrypt', id, pubkey);
|
|
99
124
|
window.location.href = url;
|
|
100
|
-
return new Promise(() => {
|
|
125
|
+
return new Promise((resolve) => {
|
|
126
|
+
AmberDirectSigner.pendingResolves.set(id, resolve);
|
|
127
|
+
});
|
|
101
128
|
}
|
|
102
129
|
|
|
103
130
|
async decrypt44(pubkey: string, ciphertext: string): Promise<string> {
|
|
@@ -108,34 +135,39 @@ export class AmberDirectSigner implements Signer {
|
|
|
108
135
|
this.setPending(id, ciphertext, 'nip44_decrypt');
|
|
109
136
|
const url = this.generateUrl(ciphertext, 'nip44_decrypt', id, pubkey);
|
|
110
137
|
window.location.href = url;
|
|
111
|
-
return new Promise(() => {
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
public async getPublicKey(): Promise<string> {
|
|
115
|
-
const id = Math.random().toString(36).substring(7);
|
|
116
|
-
const url = this.generateUrl('', 'get_public_key', id);
|
|
117
|
-
window.location.href = url;
|
|
118
|
-
return new Promise(() => {});
|
|
138
|
+
return new Promise((resolve) => {
|
|
139
|
+
AmberDirectSigner.pendingResolves.set(id, resolve);
|
|
140
|
+
});
|
|
119
141
|
}
|
|
120
142
|
|
|
121
143
|
private generateUrl(content: string, type: string, id: string, recipient?: string): string {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
const
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
params
|
|
130
|
-
|
|
144
|
+
const callbackUrl = new URL(window.location.origin + window.location.pathname);
|
|
145
|
+
callbackUrl.searchParams.set('amberType', type);
|
|
146
|
+
callbackUrl.searchParams.set('amberId', id);
|
|
147
|
+
|
|
148
|
+
const action = `com.greenart7c3.nostrsigner.${type.toUpperCase()}`;
|
|
149
|
+
const name = document.title || window.location.hostname || 'Nostr Login';
|
|
150
|
+
|
|
151
|
+
const params = [
|
|
152
|
+
`S.type=${encodeURIComponent(type)}`,
|
|
153
|
+
`S.name=${encodeURIComponent(name)}`,
|
|
154
|
+
`S.callbackUrl=${encodeURIComponent(callbackUrl.toString())}`,
|
|
155
|
+
`S.id=${encodeURIComponent(id)}`
|
|
156
|
+
];
|
|
157
|
+
|
|
131
158
|
if (recipient) {
|
|
132
|
-
|
|
159
|
+
params.push(`S.pubKey=${encodeURIComponent(recipient)}`);
|
|
133
160
|
} else if (this._pubkey) {
|
|
134
|
-
|
|
161
|
+
params.push(`S.pubKey=${encodeURIComponent(this._pubkey)}`);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if (type === 'sign_event') {
|
|
165
|
+
params.push(`S.event=${encodeURIComponent(content)}`);
|
|
166
|
+
} else {
|
|
167
|
+
params.push(`S.content=${encodeURIComponent(content)}`);
|
|
135
168
|
}
|
|
136
169
|
|
|
137
|
-
|
|
138
|
-
return `nostrsigner:${dataPart}?${params.toString()}`;
|
|
170
|
+
return `intent:#Intent;action=${action};package=com.greenart7c3.nostrsigner;${params.join(';')};end`;
|
|
139
171
|
}
|
|
140
172
|
|
|
141
173
|
public static parseResponse(): { type: string; id: string; result: string } | null {
|
|
@@ -143,19 +175,19 @@ export class AmberDirectSigner implements Signer {
|
|
|
143
175
|
const params = new URLSearchParams(url.search);
|
|
144
176
|
const hashParams = new URLSearchParams(url.hash.substring(1));
|
|
145
177
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
178
|
+
const type = params.get('amberType') || hashParams.get('amberType');
|
|
179
|
+
const id = params.get('amberId') || hashParams.get('amberId');
|
|
180
|
+
const result = params.get('signature') || params.get('result') || params.get('pubKey') || params.get('pubkey') ||
|
|
181
|
+
hashParams.get('signature') || hashParams.get('result') || hashParams.get('pubKey') || hashParams.get('pubkey');
|
|
150
182
|
|
|
151
183
|
if (type && id && result) {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
184
|
+
// Clean up URL
|
|
185
|
+
const newUrl = new URL(window.location.href);
|
|
186
|
+
['amberType', 'amberId', 'signature', 'result', 'pubKey', 'pubkey'].forEach(p => newUrl.searchParams.delete(p));
|
|
187
|
+
newUrl.hash = '';
|
|
188
|
+
window.history.replaceState({}, '', newUrl.toString());
|
|
157
189
|
|
|
158
|
-
|
|
190
|
+
return { type, id, result };
|
|
159
191
|
}
|
|
160
192
|
return null;
|
|
161
193
|
}
|
|
@@ -98,6 +98,10 @@ class AuthNostrService extends EventEmitter implements Signer {
|
|
|
98
98
|
const response = AmberDirectSigner.parseResponse();
|
|
99
99
|
if (response) {
|
|
100
100
|
console.log('Amber response detected', response);
|
|
101
|
+
|
|
102
|
+
// Resolve pending promises if any (for non-reload cases)
|
|
103
|
+
AmberDirectSigner.resolvePending(response.id, response.result);
|
|
104
|
+
|
|
101
105
|
if (response.type === 'get_public_key') {
|
|
102
106
|
const info: Info = {
|
|
103
107
|
pubkey: response.result,
|