applesauce-accounts 0.12.0 → 1.0.0
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/dist/__tests__/manager.test.js +65 -0
- package/dist/accounts/nostr-connect-account.d.ts +2 -4
- package/dist/accounts/nostr-connect-account.js +1 -7
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/manager.js +3 -0
- package/dist/proxy-signer.d.ts +7 -6
- package/dist/proxy-signer.js +17 -31
- package/package.json +5 -5
- package/dist/manager.test.js +0 -58
- /package/dist/{manager.test.d.ts → __tests__/manager.test.d.ts} +0 -0
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
+
import { AccountManager } from "../manager.js";
|
|
3
|
+
import { SimpleAccount } from "../accounts/simple-account.js";
|
|
4
|
+
import { generateSecretKey, getPublicKey } from "nostr-tools";
|
|
5
|
+
import { bytesToHex } from "@noble/hashes/utils";
|
|
6
|
+
let manager;
|
|
7
|
+
beforeEach(() => {
|
|
8
|
+
manager = new AccountManager();
|
|
9
|
+
});
|
|
10
|
+
describe("toJSON", () => {
|
|
11
|
+
it("should return an array of serialized accounts", () => {
|
|
12
|
+
manager.addAccount(SimpleAccount.fromKey(generateSecretKey()));
|
|
13
|
+
manager.setAccountMetadata(manager.accounts[0], { name: "testing" });
|
|
14
|
+
expect(manager.toJSON()).toEqual([
|
|
15
|
+
{
|
|
16
|
+
id: expect.any(String),
|
|
17
|
+
type: "nsec",
|
|
18
|
+
pubkey: expect.any(String),
|
|
19
|
+
metadata: { name: "testing" },
|
|
20
|
+
signer: { key: expect.any(String) },
|
|
21
|
+
},
|
|
22
|
+
]);
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
describe("fromJSON", () => {
|
|
26
|
+
it("should recreate accounts", () => {
|
|
27
|
+
const key = generateSecretKey();
|
|
28
|
+
const json = [
|
|
29
|
+
{
|
|
30
|
+
id: "custom-id",
|
|
31
|
+
type: "nsec",
|
|
32
|
+
pubkey: getPublicKey(key),
|
|
33
|
+
metadata: { name: "testing" },
|
|
34
|
+
signer: { key: bytesToHex(key) },
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
manager.registerType(SimpleAccount);
|
|
38
|
+
manager.fromJSON(json);
|
|
39
|
+
expect(manager.getAccount("custom-id")).toBeInstanceOf(SimpleAccount);
|
|
40
|
+
expect(manager.getAccountForPubkey(getPublicKey(key))).toBeInstanceOf(SimpleAccount);
|
|
41
|
+
expect(manager.getAccountMetadata("custom-id")).toEqual({ name: "testing" });
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
describe("signer", () => {
|
|
45
|
+
it("should proxy active account", async () => {
|
|
46
|
+
const account = SimpleAccount.generateNew();
|
|
47
|
+
manager.addAccount(account);
|
|
48
|
+
manager.setActive(account);
|
|
49
|
+
expect(await manager.signer.getPublicKey()).toBe(getPublicKey(account.signer.key));
|
|
50
|
+
});
|
|
51
|
+
it("should throw if there is no active account", () => {
|
|
52
|
+
expect(() => {
|
|
53
|
+
manager.signer.getPublicKey();
|
|
54
|
+
}).toThrow("No active account");
|
|
55
|
+
});
|
|
56
|
+
});
|
|
57
|
+
describe("removeAccount", () => {
|
|
58
|
+
it("should clear active account if removed account was active", () => {
|
|
59
|
+
const account = SimpleAccount.generateNew();
|
|
60
|
+
manager.addAccount(account);
|
|
61
|
+
manager.setActive(account);
|
|
62
|
+
manager.removeAccount(account);
|
|
63
|
+
expect(manager.active).toBeUndefined();
|
|
64
|
+
});
|
|
65
|
+
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NostrConnectSigner } from "applesauce-signers";
|
|
2
2
|
import { BaseAccount } from "../account.js";
|
|
3
3
|
import { SerializedAccount } from "../types.js";
|
|
4
4
|
export type NostrConnectAccountSignerData = {
|
|
@@ -10,7 +10,5 @@ export type NostrConnectAccountSignerData = {
|
|
|
10
10
|
export declare class NostrConnectAccount<Metadata extends unknown> extends BaseAccount<NostrConnectSigner, NostrConnectAccountSignerData, Metadata> {
|
|
11
11
|
static readonly type = "nostr-connect";
|
|
12
12
|
toJSON(): SerializedAccount<NostrConnectAccountSignerData, Metadata>;
|
|
13
|
-
|
|
14
|
-
static createConnectionMethods(): NostrConnectConnectionMethods;
|
|
15
|
-
static fromJSON<Metadata extends unknown>(json: SerializedAccount<NostrConnectAccountSignerData, Metadata>, connection?: NostrConnectConnectionMethods): NostrConnectAccount<Metadata>;
|
|
13
|
+
static fromJSON<Metadata extends unknown>(json: SerializedAccount<NostrConnectAccountSignerData, Metadata>): NostrConnectAccount<Metadata>;
|
|
16
14
|
}
|
|
@@ -15,14 +15,8 @@ export class NostrConnectAccount extends BaseAccount {
|
|
|
15
15
|
},
|
|
16
16
|
});
|
|
17
17
|
}
|
|
18
|
-
|
|
19
|
-
static createConnectionMethods() {
|
|
20
|
-
throw new Error("Cant create NostrConnectAccount without either passing in connection methods or setting NostrConnectAccount.createConnectionMethods");
|
|
21
|
-
}
|
|
22
|
-
static fromJSON(json, connection) {
|
|
23
|
-
connection = connection || NostrConnectAccount.createConnectionMethods();
|
|
18
|
+
static fromJSON(json) {
|
|
24
19
|
const signer = new NostrConnectSigner({
|
|
25
|
-
...connection,
|
|
26
20
|
relays: json.signer.relays,
|
|
27
21
|
pubkey: json.pubkey,
|
|
28
22
|
remote: json.signer.remote,
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/dist/manager.js
CHANGED
|
@@ -62,6 +62,9 @@ export class AccountManager {
|
|
|
62
62
|
removeAccount(account) {
|
|
63
63
|
const id = typeof account === "string" ? account : account.id;
|
|
64
64
|
this.accounts$.next(this.accounts$.value.filter((a) => a.id !== id));
|
|
65
|
+
// if the removed account was active, clear the active account
|
|
66
|
+
if (this.active$.value?.id === id)
|
|
67
|
+
this.active$.next(undefined);
|
|
65
68
|
}
|
|
66
69
|
/** Replaces an account with another */
|
|
67
70
|
replaceAccount(old, account) {
|
package/dist/proxy-signer.d.ts
CHANGED
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import { Nip07Interface } from "applesauce-signers";
|
|
2
2
|
import { EventTemplate, NostrEvent } from "nostr-tools";
|
|
3
|
-
import {
|
|
3
|
+
import { Observable } from "rxjs";
|
|
4
4
|
export declare class ProxySigner<T extends Nip07Interface> implements Nip07Interface {
|
|
5
|
-
protected upstream:
|
|
5
|
+
protected upstream: Observable<T | undefined>;
|
|
6
6
|
protected error?: string | undefined;
|
|
7
|
-
|
|
7
|
+
private _signer;
|
|
8
|
+
protected get signer(): T;
|
|
9
|
+
get nip04(): {
|
|
8
10
|
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
|
9
11
|
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
10
12
|
};
|
|
11
|
-
nip44: {
|
|
13
|
+
get nip44(): {
|
|
12
14
|
encrypt: (pubkey: string, plaintext: string) => Promise<string> | string;
|
|
13
15
|
decrypt: (pubkey: string, ciphertext: string) => Promise<string> | string;
|
|
14
16
|
};
|
|
15
|
-
constructor(upstream:
|
|
16
|
-
protected get signer(): Nip07Interface;
|
|
17
|
+
constructor(upstream: Observable<T | undefined>, error?: string | undefined);
|
|
17
18
|
signEvent(template: EventTemplate): Promise<NostrEvent> | NostrEvent;
|
|
18
19
|
getPublicKey(): Promise<string> | string;
|
|
19
20
|
}
|
package/dist/proxy-signer.js
CHANGED
|
@@ -1,40 +1,26 @@
|
|
|
1
1
|
export class ProxySigner {
|
|
2
2
|
upstream;
|
|
3
3
|
error;
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
_signer;
|
|
5
|
+
get signer() {
|
|
6
|
+
if (!this._signer)
|
|
7
|
+
throw new Error(this.error || "Missing signer");
|
|
8
|
+
return this._signer;
|
|
9
|
+
}
|
|
10
|
+
get nip04() {
|
|
11
|
+
if (!this.signer.nip04)
|
|
12
|
+
throw new Error("Signer does not support nip04");
|
|
13
|
+
return this.signer.nip04;
|
|
14
|
+
}
|
|
15
|
+
get nip44() {
|
|
16
|
+
if (!this.signer.nip44)
|
|
17
|
+
throw new Error("Signer does not support nip44");
|
|
18
|
+
return this.signer.nip44;
|
|
19
|
+
}
|
|
6
20
|
constructor(upstream, error) {
|
|
7
21
|
this.upstream = upstream;
|
|
8
22
|
this.error = error;
|
|
9
|
-
this.
|
|
10
|
-
encrypt: (pubkey, plaintext) => {
|
|
11
|
-
if (!this.signer.nip04)
|
|
12
|
-
throw new Error("Signer does not support nip04");
|
|
13
|
-
return this.signer.nip04.encrypt(pubkey, plaintext);
|
|
14
|
-
},
|
|
15
|
-
decrypt: (pubkey, ciphertext) => {
|
|
16
|
-
if (!this.signer.nip04)
|
|
17
|
-
throw new Error("Signer does not support nip04");
|
|
18
|
-
return this.signer.nip04.decrypt(pubkey, ciphertext);
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
this.nip44 = {
|
|
22
|
-
encrypt: (pubkey, plaintext) => {
|
|
23
|
-
if (!this.signer.nip44)
|
|
24
|
-
throw new Error("Signer does not support nip44");
|
|
25
|
-
return this.signer.nip44.encrypt(pubkey, plaintext);
|
|
26
|
-
},
|
|
27
|
-
decrypt: (pubkey, ciphertext) => {
|
|
28
|
-
if (!this.signer.nip44)
|
|
29
|
-
throw new Error("Signer does not support nip44");
|
|
30
|
-
return this.signer.nip44.decrypt(pubkey, ciphertext);
|
|
31
|
-
},
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
get signer() {
|
|
35
|
-
if (!this.upstream.value)
|
|
36
|
-
throw new Error(this.error || "Missing signer");
|
|
37
|
-
return this.upstream.value;
|
|
23
|
+
this.upstream.subscribe((signer) => (this._signer = signer));
|
|
38
24
|
}
|
|
39
25
|
signEvent(template) {
|
|
40
26
|
return this.signer.signEvent(template);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "applesauce-accounts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "A simple nostr account management system",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -33,14 +33,14 @@
|
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@noble/hashes": "^1.7.1",
|
|
36
|
-
"applesauce-signers": "^0.
|
|
37
|
-
"nanoid": "^5.
|
|
36
|
+
"applesauce-signers": "^1.0.0",
|
|
37
|
+
"nanoid": "^5.1.5",
|
|
38
38
|
"nostr-tools": "^2.10.4",
|
|
39
39
|
"rxjs": "^7.8.1"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"typescript": "^5.
|
|
43
|
-
"vitest": "^3.
|
|
42
|
+
"typescript": "^5.8.3",
|
|
43
|
+
"vitest": "^3.1.1"
|
|
44
44
|
},
|
|
45
45
|
"funding": {
|
|
46
46
|
"type": "lightning",
|
package/dist/manager.test.js
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach } from "vitest";
|
|
2
|
-
import { AccountManager } from "./manager.js";
|
|
3
|
-
import { SimpleAccount } from "./accounts/simple-account.js";
|
|
4
|
-
import { generateSecretKey, getPublicKey } from "nostr-tools";
|
|
5
|
-
import { bytesToHex } from "@noble/hashes/utils";
|
|
6
|
-
describe("AccountManager", () => {
|
|
7
|
-
let manager;
|
|
8
|
-
beforeEach(() => {
|
|
9
|
-
manager = new AccountManager();
|
|
10
|
-
});
|
|
11
|
-
describe("toJSON", () => {
|
|
12
|
-
it("should return an array of serialized accounts", () => {
|
|
13
|
-
manager.addAccount(SimpleAccount.fromKey(generateSecretKey()));
|
|
14
|
-
manager.setAccountMetadata(manager.accounts[0], { name: "testing" });
|
|
15
|
-
expect(manager.toJSON()).toEqual([
|
|
16
|
-
{
|
|
17
|
-
id: expect.any(String),
|
|
18
|
-
type: "nsec",
|
|
19
|
-
pubkey: expect.any(String),
|
|
20
|
-
metadata: { name: "testing" },
|
|
21
|
-
signer: { key: expect.any(String) },
|
|
22
|
-
},
|
|
23
|
-
]);
|
|
24
|
-
});
|
|
25
|
-
});
|
|
26
|
-
describe("fromJSON", () => {
|
|
27
|
-
it("should recreate accounts", () => {
|
|
28
|
-
const key = generateSecretKey();
|
|
29
|
-
const json = [
|
|
30
|
-
{
|
|
31
|
-
id: "custom-id",
|
|
32
|
-
type: "nsec",
|
|
33
|
-
pubkey: getPublicKey(key),
|
|
34
|
-
metadata: { name: "testing" },
|
|
35
|
-
signer: { key: bytesToHex(key) },
|
|
36
|
-
},
|
|
37
|
-
];
|
|
38
|
-
manager.registerType(SimpleAccount);
|
|
39
|
-
manager.fromJSON(json);
|
|
40
|
-
expect(manager.getAccount("custom-id")).toBeInstanceOf(SimpleAccount);
|
|
41
|
-
expect(manager.getAccountForPubkey(getPublicKey(key))).toBeInstanceOf(SimpleAccount);
|
|
42
|
-
expect(manager.getAccountMetadata("custom-id")).toEqual({ name: "testing" });
|
|
43
|
-
});
|
|
44
|
-
});
|
|
45
|
-
describe("signer", () => {
|
|
46
|
-
it("should proxy active account", async () => {
|
|
47
|
-
const account = SimpleAccount.generateNew();
|
|
48
|
-
manager.addAccount(account);
|
|
49
|
-
manager.setActive(account);
|
|
50
|
-
expect(await manager.signer.getPublicKey()).toBe(getPublicKey(account.signer.key));
|
|
51
|
-
});
|
|
52
|
-
it("should throw if there is no active account", () => {
|
|
53
|
-
expect(() => {
|
|
54
|
-
manager.signer.getPublicKey();
|
|
55
|
-
}).toThrow("No active account");
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
});
|
|
File without changes
|