@ckb-ccc/core 0.0.5-alpha.2 → 0.0.6-alpha.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/ckb/transaction.d.ts +17 -6
- package/dist/ckb/transaction.d.ts.map +1 -1
- package/dist/ckb/transaction.js +39 -15
- package/dist/client/client.d.ts +7 -6
- package/dist/client/client.d.ts.map +1 -1
- package/dist/client/client.js +9 -7
- package/dist/client/clientPublicMainnet.advanced.d.ts +1 -1
- package/dist/client/clientPublicMainnet.advanced.d.ts.map +1 -1
- package/dist/client/clientPublicMainnet.advanced.js +1 -0
- package/dist/client/clientPublicMainnet.d.ts.map +1 -1
- package/dist/client/clientPublicMainnet.js +5 -1
- package/dist/client/clientPublicTestnet.advanced.d.ts.map +1 -1
- package/dist/client/clientPublicTestnet.advanced.js +4 -0
- package/dist/signer/btc/signerBtc.d.ts.map +1 -1
- package/dist/signer/btc/signerBtc.js +4 -2
- package/dist/signer/btc/signerBtcPublicKeyReadonly.d.ts +0 -6
- package/dist/signer/btc/signerBtcPublicKeyReadonly.d.ts.map +1 -1
- package/dist/signer/btc/signerBtcPublicKeyReadonly.js +0 -8
- package/dist/signer/btc/verify.d.ts.map +1 -1
- package/dist/signer/btc/verify.js +5 -2
- package/dist/signer/ckb/signerCkbScriptReadonly.d.ts +0 -6
- package/dist/signer/ckb/signerCkbScriptReadonly.d.ts.map +1 -1
- package/dist/signer/ckb/signerCkbScriptReadonly.js +0 -8
- package/dist/signer/dummy/alwaysError.d.ts +9 -0
- package/dist/signer/dummy/alwaysError.d.ts.map +1 -0
- package/dist/signer/dummy/alwaysError.js +10 -0
- package/dist/signer/dummy/dummy.d.ts +12 -0
- package/dist/signer/dummy/dummy.d.ts.map +1 -0
- package/dist/signer/dummy/dummy.js +19 -0
- package/dist/signer/dummy/index.d.ts +4 -0
- package/dist/signer/dummy/index.d.ts.map +1 -0
- package/dist/signer/dummy/index.js +3 -0
- package/dist/signer/dummy/openLink.d.ts +9 -0
- package/dist/signer/dummy/openLink.d.ts.map +1 -0
- package/dist/signer/dummy/openLink.js +10 -0
- package/dist/signer/evm/signerEvm.d.ts.map +1 -1
- package/dist/signer/evm/signerEvm.js +3 -3
- package/dist/signer/evm/signerEvmAddressReadonly.d.ts +0 -6
- package/dist/signer/evm/signerEvmAddressReadonly.d.ts.map +1 -1
- package/dist/signer/evm/signerEvmAddressReadonly.js +0 -8
- package/dist/signer/index.d.ts +2 -0
- package/dist/signer/index.d.ts.map +1 -1
- package/dist/signer/index.js +2 -0
- package/dist/signer/nostr/index.d.ts +2 -0
- package/dist/signer/nostr/index.d.ts.map +1 -0
- package/dist/signer/nostr/index.js +1 -0
- package/dist/signer/nostr/signerNostr.d.ts +66 -0
- package/dist/signer/nostr/signerNostr.d.ts.map +1 -0
- package/dist/signer/nostr/signerNostr.js +84 -0
- package/dist/signer/nostr/verify.d.ts +5 -0
- package/dist/signer/nostr/verify.d.ts.map +1 -0
- package/dist/signer/nostr/verify.js +48 -0
- package/dist/signer/{signer.d.ts → signer/index.d.ts} +14 -19
- package/dist/signer/signer/index.d.ts.map +1 -0
- package/dist/signer/{signer.js → signer/index.js} +14 -7
- package/dist/utils/index.d.ts +60 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +20 -0
- package/dist.commonjs/ckb/transaction.d.ts +17 -6
- package/dist.commonjs/ckb/transaction.d.ts.map +1 -1
- package/dist.commonjs/ckb/transaction.js +39 -15
- package/dist.commonjs/client/client.d.ts +7 -6
- package/dist.commonjs/client/client.d.ts.map +1 -1
- package/dist.commonjs/client/client.js +9 -7
- package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts +1 -1
- package/dist.commonjs/client/clientPublicMainnet.advanced.d.ts.map +1 -1
- package/dist.commonjs/client/clientPublicMainnet.advanced.js +1 -0
- package/dist.commonjs/client/clientPublicMainnet.d.ts.map +1 -1
- package/dist.commonjs/client/clientPublicMainnet.js +5 -1
- package/dist.commonjs/client/clientPublicTestnet.advanced.d.ts.map +1 -1
- package/dist.commonjs/client/clientPublicTestnet.advanced.js +4 -0
- package/dist.commonjs/signer/btc/signerBtc.d.ts.map +1 -1
- package/dist.commonjs/signer/btc/signerBtc.js +4 -2
- package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.d.ts +0 -6
- package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.d.ts.map +1 -1
- package/dist.commonjs/signer/btc/signerBtcPublicKeyReadonly.js +0 -8
- package/dist.commonjs/signer/btc/verify.d.ts.map +1 -1
- package/dist.commonjs/signer/btc/verify.js +5 -2
- package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.d.ts +0 -6
- package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.d.ts.map +1 -1
- package/dist.commonjs/signer/ckb/signerCkbScriptReadonly.js +0 -8
- package/dist.commonjs/signer/dummy/alwaysError.d.ts +9 -0
- package/dist.commonjs/signer/dummy/alwaysError.d.ts.map +1 -0
- package/dist.commonjs/signer/dummy/alwaysError.js +14 -0
- package/dist.commonjs/signer/dummy/dummy.d.ts +12 -0
- package/dist.commonjs/signer/dummy/dummy.d.ts.map +1 -0
- package/dist.commonjs/signer/dummy/dummy.js +23 -0
- package/dist.commonjs/signer/dummy/index.d.ts +4 -0
- package/dist.commonjs/signer/dummy/index.d.ts.map +1 -0
- package/dist.commonjs/signer/dummy/index.js +19 -0
- package/dist.commonjs/signer/dummy/openLink.d.ts +9 -0
- package/dist.commonjs/signer/dummy/openLink.d.ts.map +1 -0
- package/dist.commonjs/signer/dummy/openLink.js +14 -0
- package/dist.commonjs/signer/evm/signerEvm.d.ts.map +1 -1
- package/dist.commonjs/signer/evm/signerEvm.js +3 -3
- package/dist.commonjs/signer/evm/signerEvmAddressReadonly.d.ts +0 -6
- package/dist.commonjs/signer/evm/signerEvmAddressReadonly.d.ts.map +1 -1
- package/dist.commonjs/signer/evm/signerEvmAddressReadonly.js +0 -8
- package/dist.commonjs/signer/index.d.ts +2 -0
- package/dist.commonjs/signer/index.d.ts.map +1 -1
- package/dist.commonjs/signer/index.js +2 -0
- package/dist.commonjs/signer/nostr/index.d.ts +2 -0
- package/dist.commonjs/signer/nostr/index.d.ts.map +1 -0
- package/dist.commonjs/signer/nostr/index.js +17 -0
- package/dist.commonjs/signer/nostr/signerNostr.d.ts +66 -0
- package/dist.commonjs/signer/nostr/signerNostr.d.ts.map +1 -0
- package/dist.commonjs/signer/nostr/signerNostr.js +88 -0
- package/dist.commonjs/signer/nostr/verify.d.ts +5 -0
- package/dist.commonjs/signer/nostr/verify.d.ts.map +1 -0
- package/dist.commonjs/signer/nostr/verify.js +53 -0
- package/dist.commonjs/signer/{signer.d.ts → signer/index.d.ts} +14 -19
- package/dist.commonjs/signer/signer/index.d.ts.map +1 -0
- package/dist.commonjs/signer/{signer.js → signer/index.js} +14 -7
- package/dist.commonjs/utils/index.d.ts +60 -0
- package/dist.commonjs/utils/index.d.ts.map +1 -1
- package/dist.commonjs/utils/index.js +23 -1
- package/package.json +4 -3
- package/src/ckb/transaction.ts +50 -18
- package/src/client/client.ts +12 -10
- package/src/client/clientPublicMainnet.advanced.ts +2 -1
- package/src/client/clientPublicMainnet.ts +7 -1
- package/src/client/clientPublicTestnet.advanced.ts +5 -0
- package/src/signer/btc/signerBtc.ts +4 -7
- package/src/signer/btc/signerBtcPublicKeyReadonly.ts +0 -9
- package/src/signer/btc/verify.ts +6 -3
- package/src/signer/ckb/signerCkbScriptReadonly.ts +0 -9
- package/src/signer/dummy/alwaysError.ts +17 -0
- package/src/signer/dummy/dummy.ts +28 -0
- package/src/signer/dummy/index.ts +3 -0
- package/src/signer/dummy/openLink.ts +17 -0
- package/src/signer/evm/signerEvm.ts +7 -9
- package/src/signer/evm/signerEvmAddressReadonly.ts +0 -9
- package/src/signer/index.ts +2 -0
- package/src/signer/nostr/index.ts +1 -0
- package/src/signer/nostr/signerNostr.ts +134 -0
- package/src/signer/nostr/verify.ts +63 -0
- package/src/signer/{signer.ts → signer/index.ts} +24 -20
- package/src/utils/index.ts +108 -0
- package/dist/signer/signer.d.ts.map +0 -1
- package/dist.commonjs/signer/signer.d.ts.map +0 -1
package/src/signer/btc/verify.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { secp256k1 } from "@noble/curves/secp256k1";
|
|
2
|
+
import { magicHash } from "bitcoinjs-message";
|
|
3
|
+
import { BytesLike, bytesFrom } from "../../bytes";
|
|
3
4
|
import { hexFrom } from "../../hex";
|
|
4
5
|
|
|
5
6
|
export function verifyMessageBtcEcdsa(
|
|
@@ -10,5 +11,7 @@ export function verifyMessageBtcEcdsa(
|
|
|
10
11
|
const challenge =
|
|
11
12
|
typeof message === "string" ? message : hexFrom(message).slice(2);
|
|
12
13
|
|
|
13
|
-
|
|
14
|
+
const [_, ...rawSign] = bytesFrom(signature, "base64");
|
|
15
|
+
|
|
16
|
+
return secp256k1.verify(bytesFrom(rawSign), magicHash(challenge), publicKey);
|
|
14
17
|
}
|
|
@@ -30,15 +30,6 @@ export class SignerCkbScriptReadonly extends Signer {
|
|
|
30
30
|
this.script = Script.from(script);
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
/**
|
|
34
|
-
* Construct a new signer with the client replaced.
|
|
35
|
-
*
|
|
36
|
-
* @returns A promise that resolves the new Signer.
|
|
37
|
-
*/
|
|
38
|
-
async replaceClient(client: Client): Promise<SignerCkbScriptReadonly> {
|
|
39
|
-
return new SignerCkbScriptReadonly(client, this.script);
|
|
40
|
-
}
|
|
41
|
-
|
|
42
33
|
/**
|
|
43
34
|
* Connects to the client. This implementation does nothing as the class is read-only.
|
|
44
35
|
*
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Client } from "../../client";
|
|
2
|
+
import { SignerType } from "../signer";
|
|
3
|
+
import { SignerDummy } from "./dummy";
|
|
4
|
+
|
|
5
|
+
export class SignerAlwaysError extends SignerDummy {
|
|
6
|
+
constructor(
|
|
7
|
+
client: Client,
|
|
8
|
+
type: SignerType,
|
|
9
|
+
private readonly message: string,
|
|
10
|
+
) {
|
|
11
|
+
super(client, type);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async connect(): Promise<void> {
|
|
15
|
+
throw new Error(this.message);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Address } from "../../address";
|
|
2
|
+
import { Client } from "../../client";
|
|
3
|
+
import { Signer, SignerSignType, SignerType } from "../signer";
|
|
4
|
+
|
|
5
|
+
export abstract class SignerDummy extends Signer {
|
|
6
|
+
get signType(): SignerSignType {
|
|
7
|
+
return SignerSignType.Unknown;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
constructor(
|
|
11
|
+
client: Client,
|
|
12
|
+
public readonly type: SignerType,
|
|
13
|
+
) {
|
|
14
|
+
super(client);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async isConnected(): Promise<boolean> {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async getInternalAddress(): Promise<string> {
|
|
22
|
+
throw new Error("Can't get address from SignerDummy");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
async getAddressObjs(): Promise<Address[]> {
|
|
26
|
+
throw new Error("Can't get addresses from SignerDummy");
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Client } from "../../client";
|
|
2
|
+
import { SignerType } from "../signer";
|
|
3
|
+
import { SignerDummy } from "./dummy";
|
|
4
|
+
|
|
5
|
+
export class SignerOpenLink extends SignerDummy {
|
|
6
|
+
constructor(
|
|
7
|
+
client: Client,
|
|
8
|
+
type: SignerType,
|
|
9
|
+
private readonly link: string,
|
|
10
|
+
) {
|
|
11
|
+
super(client, type);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
async connect(): Promise<void> {
|
|
15
|
+
window.open(this.link, "_blank")?.focus();
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -4,6 +4,7 @@ import { Script, Transaction, TransactionLike, WitnessArgs } from "../../ckb";
|
|
|
4
4
|
import { KnownScript } from "../../client";
|
|
5
5
|
import { hexFrom } from "../../hex";
|
|
6
6
|
import { numToBytes } from "../../num";
|
|
7
|
+
import { reduceAsync } from "../../utils";
|
|
7
8
|
import { Signer, SignerSignType, SignerType } from "../signer";
|
|
8
9
|
|
|
9
10
|
/**
|
|
@@ -71,14 +72,11 @@ export abstract class SignerEvm extends Signer {
|
|
|
71
72
|
* @returns A promise that resolves to the prepared Transaction object.
|
|
72
73
|
*/
|
|
73
74
|
async prepareTransaction(txLike: TransactionLike): Promise<Transaction> {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
tx.prepareSighashAllWitness(script, 85, this.client),
|
|
80
|
-
),
|
|
81
|
-
Promise.resolve(Transaction.from(txLike)),
|
|
75
|
+
return reduceAsync(
|
|
76
|
+
await this.getAddressObjs(),
|
|
77
|
+
(tx: Transaction, { script }) =>
|
|
78
|
+
tx.prepareSighashAllWitness(script, 85, this.client),
|
|
79
|
+
Transaction.from(txLike),
|
|
82
80
|
);
|
|
83
81
|
}
|
|
84
82
|
|
|
@@ -139,7 +137,7 @@ export abstract class SignerEvm extends Signer {
|
|
|
139
137
|
),
|
|
140
138
|
);
|
|
141
139
|
|
|
142
|
-
tx.
|
|
140
|
+
tx.setWitnessArgsAt(info.position, witness);
|
|
143
141
|
|
|
144
142
|
return tx;
|
|
145
143
|
}
|
|
@@ -21,15 +21,6 @@ export class SignerEvmAddressReadonly extends SignerEvm {
|
|
|
21
21
|
this.address = hexFrom(address);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
/**
|
|
25
|
-
* Construct a new signer with the client replaced.
|
|
26
|
-
*
|
|
27
|
-
* @returns A promise that resolves the new Signer.
|
|
28
|
-
*/
|
|
29
|
-
async replaceClient(client: Client): Promise<SignerEvmAddressReadonly> {
|
|
30
|
-
return new SignerEvmAddressReadonly(client, this.address);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
24
|
/**
|
|
34
25
|
* Connects to the client. This implementation does nothing as the class is read-only.
|
|
35
26
|
*
|
package/src/signer/index.ts
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./signerNostr";
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { bech32 } from "bech32";
|
|
2
|
+
import { Address } from "../../address";
|
|
3
|
+
import { BytesLike, bytesConcat, bytesFrom } from "../../bytes";
|
|
4
|
+
import { Transaction, TransactionLike, WitnessArgs } from "../../ckb";
|
|
5
|
+
import { KnownScript } from "../../client";
|
|
6
|
+
import { ckbHash } from "../../hasher";
|
|
7
|
+
import { Hex, hexFrom } from "../../hex";
|
|
8
|
+
import { Signer, SignerSignType, SignerType } from "../signer";
|
|
9
|
+
import { buildNostrEventFromMessage } from "./verify";
|
|
10
|
+
|
|
11
|
+
export interface NostrEvent {
|
|
12
|
+
id?: string;
|
|
13
|
+
pubkey?: string;
|
|
14
|
+
sig?: string;
|
|
15
|
+
created_at: number;
|
|
16
|
+
kind: number;
|
|
17
|
+
tags: string[][];
|
|
18
|
+
content: string;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export abstract class SignerNostr extends Signer {
|
|
22
|
+
static CKB_SIG_HASH_ALL_TAG = "ckb_sighash_all";
|
|
23
|
+
static CKB_UNLOCK_EVENT_KIND = 23334;
|
|
24
|
+
static CKB_UNLOCK_EVENT_CONTENT =
|
|
25
|
+
"Signing a CKB transaction\n\nIMPORTANT: Please verify the integrity and authenticity of connected Nostr client before signing this message\n";
|
|
26
|
+
|
|
27
|
+
get type(): SignerType {
|
|
28
|
+
return SignerType.Nostr;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
get signType(): SignerSignType {
|
|
32
|
+
return SignerSignType.NostrEvent;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Gets the Nostr public key associated with the signer.
|
|
37
|
+
*
|
|
38
|
+
* @returns A promise that resolves to a string representing the Nostr public key.
|
|
39
|
+
*/
|
|
40
|
+
abstract getNostrPublicKey(): Promise<Hex>;
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Sign a nostr event.
|
|
44
|
+
*
|
|
45
|
+
* @returns A promise that resolves to the signed event.
|
|
46
|
+
*/
|
|
47
|
+
abstract signNostrEvent(event: NostrEvent): Promise<Required<NostrEvent>>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Sign a message.
|
|
51
|
+
*
|
|
52
|
+
* @returns A promise that resolves to the signature.
|
|
53
|
+
*/
|
|
54
|
+
async signMessageRaw(message: string | BytesLike): Promise<Hex> {
|
|
55
|
+
return hexFrom(
|
|
56
|
+
(await this.signNostrEvent(buildNostrEventFromMessage(message))).sig,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Gets the internal address, which is the EVM account in this case.
|
|
62
|
+
*
|
|
63
|
+
* @returns A promise that resolves to a string representing the internal address.
|
|
64
|
+
*/
|
|
65
|
+
async getInternalAddress(): Promise<string> {
|
|
66
|
+
return bech32.encode(
|
|
67
|
+
"npub",
|
|
68
|
+
bech32.toWords(bytesFrom(await this.getNostrPublicKey())),
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Gets an array of Address objects representing the known script addresses for the signer.
|
|
74
|
+
*
|
|
75
|
+
* @returns A promise that resolves to an array of Address objects.
|
|
76
|
+
*/
|
|
77
|
+
async getAddressObjs(): Promise<Address[]> {
|
|
78
|
+
const publicKey = await this.getNostrPublicKey();
|
|
79
|
+
return [
|
|
80
|
+
await Address.fromKnownScript(
|
|
81
|
+
KnownScript.NostrLock,
|
|
82
|
+
hexFrom(bytesConcat([0x00], ckbHash(publicKey).slice(0, 42))),
|
|
83
|
+
this.client,
|
|
84
|
+
),
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* prepare a transaction before signing.
|
|
90
|
+
*
|
|
91
|
+
* @param txLike - The transaction to prepare, represented as a TransactionLike object.
|
|
92
|
+
* @returns A promise that resolves to the prepared Transaction object.
|
|
93
|
+
*/
|
|
94
|
+
async prepareTransaction(txLike: TransactionLike): Promise<Transaction> {
|
|
95
|
+
const tx = Transaction.from(txLike);
|
|
96
|
+
const { script } = await this.getRecommendedAddressObj();
|
|
97
|
+
await tx.prepareSighashAllWitness(script, 572, this.client);
|
|
98
|
+
return tx;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Signs a transaction without modifying it.
|
|
103
|
+
*
|
|
104
|
+
* @param txLike - The transaction to sign, represented as a TransactionLike object.
|
|
105
|
+
* @returns A promise that resolves to a signed Transaction object.
|
|
106
|
+
*/
|
|
107
|
+
async signOnlyTransaction(txLike: TransactionLike): Promise<Transaction> {
|
|
108
|
+
let tx = Transaction.from(txLike);
|
|
109
|
+
const { script } = await this.getRecommendedAddressObj();
|
|
110
|
+
const info = await tx.getSignHashInfo(script, this.client);
|
|
111
|
+
if (!info) {
|
|
112
|
+
return tx;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const signedEvent = bytesFrom(
|
|
116
|
+
JSON.stringify(
|
|
117
|
+
await this.signNostrEvent({
|
|
118
|
+
pubkey: (await this.getNostrPublicKey()).slice(2),
|
|
119
|
+
tags: [[SignerNostr.CKB_SIG_HASH_ALL_TAG, info.message.slice(2)]],
|
|
120
|
+
created_at: Math.floor(Date.now() / 1000),
|
|
121
|
+
kind: SignerNostr.CKB_UNLOCK_EVENT_KIND,
|
|
122
|
+
content: SignerNostr.CKB_UNLOCK_EVENT_CONTENT,
|
|
123
|
+
}),
|
|
124
|
+
),
|
|
125
|
+
"utf8",
|
|
126
|
+
);
|
|
127
|
+
|
|
128
|
+
const witness = WitnessArgs.fromBytes(tx.witnesses[info.position]);
|
|
129
|
+
witness.lock = hexFrom(signedEvent);
|
|
130
|
+
tx.setWitnessArgsAt(info.position, witness);
|
|
131
|
+
|
|
132
|
+
return tx;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { schnorr } from "@noble/curves/secp256k1";
|
|
2
|
+
import { sha256 } from "@noble/hashes/sha256";
|
|
3
|
+
import { bech32 } from "bech32";
|
|
4
|
+
import { BytesLike, bytesFrom } from "../../bytes";
|
|
5
|
+
import { hexFrom } from "../../hex";
|
|
6
|
+
import { NostrEvent } from "./signerNostr";
|
|
7
|
+
|
|
8
|
+
export function buildNostrEventFromMessage(
|
|
9
|
+
message: string | BytesLike,
|
|
10
|
+
): NostrEvent {
|
|
11
|
+
if (typeof message === "string") {
|
|
12
|
+
try {
|
|
13
|
+
const event = JSON.parse(message);
|
|
14
|
+
if (
|
|
15
|
+
typeof event === "object" &&
|
|
16
|
+
typeof event.created_at === "number" &&
|
|
17
|
+
typeof event.kind === "number" &&
|
|
18
|
+
typeof event.content === "string" &&
|
|
19
|
+
Array.isArray(event.args) &&
|
|
20
|
+
(event.args as unknown[]).every(
|
|
21
|
+
(tag) =>
|
|
22
|
+
Array.isArray(tag) &&
|
|
23
|
+
(tag as unknown[]).every((v) => typeof v === "string"),
|
|
24
|
+
)
|
|
25
|
+
) {
|
|
26
|
+
return event;
|
|
27
|
+
}
|
|
28
|
+
} catch (_) {}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
return {
|
|
32
|
+
kind: 23335,
|
|
33
|
+
created_at: 0,
|
|
34
|
+
content: typeof message === "string" ? message : hexFrom(message),
|
|
35
|
+
tags: [],
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function verifyMessageNostrEvent(
|
|
40
|
+
message: string | BytesLike,
|
|
41
|
+
signature: string,
|
|
42
|
+
address: string,
|
|
43
|
+
): boolean {
|
|
44
|
+
const { words } = bech32.decode(address);
|
|
45
|
+
const publicKey = hexFrom(bech32.fromWords(words)).slice(2);
|
|
46
|
+
|
|
47
|
+
const event = buildNostrEventFromMessage(message);
|
|
48
|
+
const serialized = JSON.stringify([
|
|
49
|
+
0,
|
|
50
|
+
publicKey,
|
|
51
|
+
event.created_at,
|
|
52
|
+
event.kind,
|
|
53
|
+
event.tags,
|
|
54
|
+
event.content,
|
|
55
|
+
]);
|
|
56
|
+
const eventHash = hexFrom(sha256(bytesFrom(serialized, "utf8")));
|
|
57
|
+
|
|
58
|
+
try {
|
|
59
|
+
return schnorr.verify(signature.slice(2), eventHash.slice(2), publicKey);
|
|
60
|
+
} catch (_) {
|
|
61
|
+
return false;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -1,18 +1,20 @@
|
|
|
1
|
-
import { Address } from "
|
|
2
|
-
import { BytesLike } from "
|
|
3
|
-
import { Transaction, TransactionLike } from "
|
|
4
|
-
import { Client } from "
|
|
5
|
-
import { Hex } from "
|
|
6
|
-
import { Num } from "
|
|
7
|
-
import { verifyMessageBtcEcdsa } from "
|
|
8
|
-
import { verifyMessageJoyId } from "
|
|
9
|
-
import { verifyMessageEvmPersonal } from "
|
|
1
|
+
import { Address } from "../../address";
|
|
2
|
+
import { BytesLike } from "../../bytes";
|
|
3
|
+
import { Transaction, TransactionLike } from "../../ckb";
|
|
4
|
+
import { Client } from "../../client";
|
|
5
|
+
import { Hex } from "../../hex";
|
|
6
|
+
import { Num } from "../../num";
|
|
7
|
+
import { verifyMessageBtcEcdsa } from "../btc";
|
|
8
|
+
import { verifyMessageJoyId } from "../ckb/verifyJoyId";
|
|
9
|
+
import { verifyMessageEvmPersonal } from "../evm/verify";
|
|
10
|
+
import { verifyMessageNostrEvent } from "../nostr/verify";
|
|
10
11
|
|
|
11
12
|
export enum SignerSignType {
|
|
12
13
|
Unknown = "Unknown",
|
|
13
14
|
BtcEcdsa = "BtcEcdsa",
|
|
14
15
|
EvmPersonal = "EvmPersonal",
|
|
15
16
|
JoyId = "JoyId",
|
|
17
|
+
NostrEvent = "NostrEvent",
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
/**
|
|
@@ -22,6 +24,7 @@ export enum SignerType {
|
|
|
22
24
|
EVM = "EVM",
|
|
23
25
|
BTC = "BTC",
|
|
24
26
|
CKB = "CKB",
|
|
27
|
+
Nostr = "Nostr",
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
export class Signature {
|
|
@@ -69,17 +72,25 @@ export abstract class Signer {
|
|
|
69
72
|
signature.signature,
|
|
70
73
|
signature.identity,
|
|
71
74
|
);
|
|
75
|
+
case SignerSignType.NostrEvent:
|
|
76
|
+
return verifyMessageNostrEvent(
|
|
77
|
+
message,
|
|
78
|
+
signature.signature,
|
|
79
|
+
signature.identity,
|
|
80
|
+
);
|
|
72
81
|
case SignerSignType.Unknown:
|
|
73
82
|
throw new Error("Unknown signer sign type");
|
|
74
83
|
}
|
|
75
84
|
}
|
|
76
85
|
|
|
77
86
|
/**
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
* @returns A promise that resolves the new Signer.
|
|
87
|
+
* Replace the current client.
|
|
88
|
+
* returns false if the new client is invalid for this signer.
|
|
81
89
|
*/
|
|
82
|
-
|
|
90
|
+
async replaceClient(client: Client): Promise<boolean> {
|
|
91
|
+
this.client_ = client;
|
|
92
|
+
return true;
|
|
93
|
+
}
|
|
83
94
|
|
|
84
95
|
/**
|
|
85
96
|
* Connects to the signer.
|
|
@@ -88,13 +99,6 @@ export abstract class Signer {
|
|
|
88
99
|
*/
|
|
89
100
|
abstract connect(): Promise<void>;
|
|
90
101
|
|
|
91
|
-
/**
|
|
92
|
-
* Disconnects to the signer.
|
|
93
|
-
*
|
|
94
|
-
* @returns A promise that resolves when disconnected.
|
|
95
|
-
*/
|
|
96
|
-
async disconnect(): Promise<void> {}
|
|
97
|
-
|
|
98
102
|
/**
|
|
99
103
|
* Check if the signer is connected.
|
|
100
104
|
*
|
package/src/utils/index.ts
CHANGED
|
@@ -1,21 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A type safe way to apply a transformer on a value if it's not empty.
|
|
3
|
+
*
|
|
4
|
+
* @param transformer - The transformer.
|
|
5
|
+
* @param value - The value to be transformed.
|
|
6
|
+
* @returns If the value is empty, it remains its type. Otherwise it will be transformed.
|
|
7
|
+
*/
|
|
1
8
|
export function apply<T, R>(
|
|
2
9
|
transformer: (val: T) => R,
|
|
3
10
|
value: undefined,
|
|
4
11
|
): undefined;
|
|
12
|
+
/**
|
|
13
|
+
* A type safe way to apply a transformer on a value if it's not empty.
|
|
14
|
+
*
|
|
15
|
+
* @param transformer - The transformer.
|
|
16
|
+
* @param value - The value to be transformed.
|
|
17
|
+
* @returns If the value is empty, it remains its type. Otherwise it will be transformed.
|
|
18
|
+
*/
|
|
5
19
|
export function apply<T, R>(transformer: (val: T) => R, value: null): null;
|
|
20
|
+
/**
|
|
21
|
+
* A type safe way to apply a transformer on a value if it's not empty.
|
|
22
|
+
*
|
|
23
|
+
* @param transformer - The transformer.
|
|
24
|
+
* @param value - The value to be transformed.
|
|
25
|
+
* @returns If the value is empty, it remains its type. Otherwise it will be transformed.
|
|
26
|
+
*/
|
|
6
27
|
export function apply<T, R>(transformer: (val: T) => R, value: T): R;
|
|
28
|
+
/**
|
|
29
|
+
* A type safe way to apply a transformer on a value if it's not empty.
|
|
30
|
+
*
|
|
31
|
+
* @param transformer - The transformer.
|
|
32
|
+
* @param value - The value to be transformed.
|
|
33
|
+
* @returns If the value is empty, it remains its type. Otherwise it will be transformed.
|
|
34
|
+
*/
|
|
7
35
|
export function apply<T, R>(
|
|
8
36
|
transformer: (val: T) => R,
|
|
9
37
|
value: T | undefined,
|
|
10
38
|
): R | undefined;
|
|
39
|
+
/**
|
|
40
|
+
* A type safe way to apply a transformer on a value if it's not empty.
|
|
41
|
+
*
|
|
42
|
+
* @param transformer - The transformer.
|
|
43
|
+
* @param value - The value to be transformed.
|
|
44
|
+
* @returns If the value is empty, it remains its type. Otherwise it will be transformed.
|
|
45
|
+
*/
|
|
11
46
|
export function apply<T, R>(
|
|
12
47
|
transformer: (val: T) => R,
|
|
13
48
|
value: T | null,
|
|
14
49
|
): R | null;
|
|
50
|
+
/**
|
|
51
|
+
* A type safe way to apply a transformer on a value if it's not empty.
|
|
52
|
+
*
|
|
53
|
+
* @param transformer - The transformer.
|
|
54
|
+
* @param value - The value to be transformed.
|
|
55
|
+
* @returns If the value is empty, it remains its type. Otherwise it will be transformed.
|
|
56
|
+
*/
|
|
15
57
|
export function apply<T, R>(
|
|
16
58
|
transformer: (val: T) => R,
|
|
17
59
|
value: undefined | null,
|
|
18
60
|
): undefined | null;
|
|
61
|
+
/**
|
|
62
|
+
* A type safe way to apply a transformer on a value if it's not empty.
|
|
63
|
+
*
|
|
64
|
+
* @param transformer - The transformer.
|
|
65
|
+
* @param value - The value to be transformed.
|
|
66
|
+
* @returns If the value is empty, it remains its type. Otherwise it will be transformed.
|
|
67
|
+
*/
|
|
19
68
|
export function apply<T, R>(
|
|
20
69
|
transformer: (val: T) => R,
|
|
21
70
|
value: T | undefined | null,
|
|
@@ -26,3 +75,62 @@ export function apply<T, R>(
|
|
|
26
75
|
|
|
27
76
|
return transformer(value);
|
|
28
77
|
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Similar to Array.reduce, but the accumulator can returns Promise.
|
|
81
|
+
*
|
|
82
|
+
* @param values - The array to be reduced.
|
|
83
|
+
* @param accumulator - A callback to be called for each value. If it returns null, the previous result will be kept.
|
|
84
|
+
* @returns The accumulated result.
|
|
85
|
+
*/
|
|
86
|
+
export async function reduceAsync<T, V>(
|
|
87
|
+
values: T[],
|
|
88
|
+
accumulator: (
|
|
89
|
+
a: T,
|
|
90
|
+
b: T,
|
|
91
|
+
) => Promise<T | undefined | null | void> | T | undefined | null | void,
|
|
92
|
+
): Promise<T>;
|
|
93
|
+
/**
|
|
94
|
+
* Similar to Array.reduce, but the accumulator can returns Promise.
|
|
95
|
+
*
|
|
96
|
+
* @param values - The array to be reduced.
|
|
97
|
+
* @param accumulator - A callback to be called for each value. If it returns null, the previous result will be kept.
|
|
98
|
+
* @param init - The initial value.
|
|
99
|
+
* @returns The accumulated result.
|
|
100
|
+
*/
|
|
101
|
+
export async function reduceAsync<T, V>(
|
|
102
|
+
values: V[],
|
|
103
|
+
accumulator: (
|
|
104
|
+
a: T,
|
|
105
|
+
b: V,
|
|
106
|
+
) => Promise<T | undefined | null | void> | T | undefined | null | void,
|
|
107
|
+
init: T,
|
|
108
|
+
): Promise<T>;
|
|
109
|
+
export async function reduceAsync<T, V>(
|
|
110
|
+
values: (V | T)[],
|
|
111
|
+
accumulator: (
|
|
112
|
+
a: T,
|
|
113
|
+
b: T | V,
|
|
114
|
+
) => Promise<T | undefined | null | void> | T | undefined | null | void,
|
|
115
|
+
init?: T,
|
|
116
|
+
): Promise<T> {
|
|
117
|
+
if (init === undefined) {
|
|
118
|
+
if (values.length === 0) {
|
|
119
|
+
throw new TypeError("Reduce of empty array with no initial value");
|
|
120
|
+
}
|
|
121
|
+
init = values[0] as T;
|
|
122
|
+
values = values.slice(1);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return values.reduce(
|
|
126
|
+
(current: Promise<T>, b: T | V) =>
|
|
127
|
+
current.then((v) =>
|
|
128
|
+
Promise.resolve(accumulator(v, b)).then((r) => r ?? v),
|
|
129
|
+
),
|
|
130
|
+
Promise.resolve(init),
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function isWebview(userAgent: string): boolean {
|
|
135
|
+
return /webview|wv|ip((?!.*Safari)|(?=.*like Safari))/i.test(userAgent);
|
|
136
|
+
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/signer/signer.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"signer.d.ts","sourceRoot":"","sources":["../../src/signer/signer.ts"],"names":[],"mappings":"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"}
|