@arkecosystem/typescript-crypto 0.0.12 → 0.0.14
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/index.js +19 -45
- package/dist/utils/AbiDecoder.d.ts +1 -0
- package/dist/utils/AbiDecoder.d.ts.map +1 -1
- package/dist/utils/AbiDecoder.js +11 -0
- package/dist/utils/Message.d.ts.map +1 -1
- package/dist/utils/Message.js +12 -9
- package/package.json +1 -1
- package/src/utils/AbiDecoder.ts +15 -0
- package/src/utils/Message.ts +12 -9
- package/tests/fixtures/message-sign.json +1 -1
- package/tests/unit/utils/AbiDecoder.test.ts +29 -0
package/dist/index.js
CHANGED
|
@@ -5657,7 +5657,7 @@ function weierstrass(curveDef) {
|
|
|
5657
5657
|
return drbg(seed, k2sig);
|
|
5658
5658
|
}
|
|
5659
5659
|
Point3.BASE._setWindowSize(8);
|
|
5660
|
-
function
|
|
5660
|
+
function verify(signature, msgHash, publicKey, opts = defaultVerOpts) {
|
|
5661
5661
|
const sg = signature;
|
|
5662
5662
|
msgHash = ensureBytes("msgHash", msgHash);
|
|
5663
5663
|
publicKey = ensureBytes("publicKey", publicKey);
|
|
@@ -5707,7 +5707,7 @@ function weierstrass(curveDef) {
|
|
|
5707
5707
|
getPublicKey,
|
|
5708
5708
|
getSharedSecret,
|
|
5709
5709
|
sign,
|
|
5710
|
-
verify
|
|
5710
|
+
verify,
|
|
5711
5711
|
ProjectivePoint: Point3,
|
|
5712
5712
|
Signature: Signature3,
|
|
5713
5713
|
utils
|
|
@@ -23260,7 +23260,6 @@ var cr = () => (
|
|
|
23260
23260
|
);
|
|
23261
23261
|
var _hmacSync;
|
|
23262
23262
|
var optS = { lowS: true };
|
|
23263
|
-
var optV = { lowS: true };
|
|
23264
23263
|
var prepSig = (msgh, priv, opts = optS) => {
|
|
23265
23264
|
if (["der", "recovered", "canonical"].some((k) => k in opts))
|
|
23266
23265
|
err("option not supported");
|
|
@@ -23368,42 +23367,6 @@ var signAsync = async (msgh, priv, opts = optS) => {
|
|
|
23368
23367
|
const { seed, k2sig } = prepSig(msgh, priv, opts);
|
|
23369
23368
|
return hmacDrbg(true)(seed, k2sig);
|
|
23370
23369
|
};
|
|
23371
|
-
var verify = (sig, msgh, pub, opts = optV) => {
|
|
23372
|
-
let { lowS } = opts;
|
|
23373
|
-
if (lowS == null)
|
|
23374
|
-
lowS = true;
|
|
23375
|
-
if ("strict" in opts)
|
|
23376
|
-
err("option not supported");
|
|
23377
|
-
let sig_, h, P2;
|
|
23378
|
-
const rs = sig && typeof sig === "object" && "r" in sig;
|
|
23379
|
-
if (!rs && toU8(sig).length !== 2 * fLen)
|
|
23380
|
-
err("signature must be 64 bytes");
|
|
23381
|
-
try {
|
|
23382
|
-
sig_ = rs ? new Signature2(sig.r, sig.s).assertValidity() : Signature2.fromCompact(sig);
|
|
23383
|
-
h = bits2int_modN(toU8(msgh));
|
|
23384
|
-
P2 = pub instanceof Point2 ? pub.ok() : Point2.fromHex(pub);
|
|
23385
|
-
} catch (e) {
|
|
23386
|
-
return false;
|
|
23387
|
-
}
|
|
23388
|
-
if (!sig_)
|
|
23389
|
-
return false;
|
|
23390
|
-
const { r, s } = sig_;
|
|
23391
|
-
if (lowS && high(s))
|
|
23392
|
-
return false;
|
|
23393
|
-
let R;
|
|
23394
|
-
try {
|
|
23395
|
-
const is = inv(s, N3);
|
|
23396
|
-
const u1 = M(h * is, N3);
|
|
23397
|
-
const u2 = M(r * is, N3);
|
|
23398
|
-
R = G.mulAddQUns(P2, u1, u2).aff();
|
|
23399
|
-
} catch (error) {
|
|
23400
|
-
return false;
|
|
23401
|
-
}
|
|
23402
|
-
if (!R)
|
|
23403
|
-
return false;
|
|
23404
|
-
const v = M(R.x, N3);
|
|
23405
|
-
return v === r;
|
|
23406
|
-
};
|
|
23407
23370
|
var hashToPrivateKey = (hash2) => {
|
|
23408
23371
|
hash2 = toU8(hash2);
|
|
23409
23372
|
if (hash2.length < fLen + 8 || hash2.length > 1024)
|
|
@@ -27847,6 +27810,17 @@ var AbiDecoder = class extends AbiBase {
|
|
|
27847
27810
|
args: this.interface.decodeFunctionData(functionFragment, data)
|
|
27848
27811
|
};
|
|
27849
27812
|
}
|
|
27813
|
+
decodeError(data) {
|
|
27814
|
+
if (!data.startsWith("0x")) {
|
|
27815
|
+
data = "0x" + data;
|
|
27816
|
+
}
|
|
27817
|
+
const errorSelector = data.slice(0, 10);
|
|
27818
|
+
const errorFragment = this.interface.getError(errorSelector);
|
|
27819
|
+
if (!errorFragment) {
|
|
27820
|
+
throw new Error(`Error selector not found in ABI: ${errorSelector}`);
|
|
27821
|
+
}
|
|
27822
|
+
return errorFragment.name;
|
|
27823
|
+
}
|
|
27850
27824
|
};
|
|
27851
27825
|
|
|
27852
27826
|
// src/utils/AbiEncoder.ts
|
|
@@ -27992,18 +27966,18 @@ var Message = class _Message {
|
|
|
27992
27966
|
static async sign(message, passphrase) {
|
|
27993
27967
|
const privateKey = PrivateKey.fromPassphrase(passphrase);
|
|
27994
27968
|
const publicKey = PublicKey.fromPassphrase(passphrase).publicKey;
|
|
27995
|
-
const signature =
|
|
27969
|
+
const signature = new SigningKey(`0x${privateKey.privateKey}`).sign(hashMessage(message));
|
|
27996
27970
|
return _Message.new({
|
|
27997
27971
|
publicKey,
|
|
27998
|
-
signature: signature.
|
|
27972
|
+
signature: signature.serialized,
|
|
27999
27973
|
message
|
|
28000
27974
|
});
|
|
28001
27975
|
}
|
|
28002
27976
|
verify() {
|
|
28003
|
-
const message =
|
|
28004
|
-
const
|
|
28005
|
-
const
|
|
28006
|
-
return
|
|
27977
|
+
const message = new Uint8Array(new TextEncoder().encode(this.message));
|
|
27978
|
+
const address = Address.fromPublicKey(this.publicKey);
|
|
27979
|
+
const signerAddress = verifyMessage(message, this.signature);
|
|
27980
|
+
return signerAddress === address;
|
|
28007
27981
|
}
|
|
28008
27982
|
toString() {
|
|
28009
27983
|
return JSON.stringify(this.toJson());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"AbiDecoder.d.ts","sourceRoot":"","sources":["../../src/utils/AbiDecoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,qBAAa,UAAW,SAAQ,OAAO;IACtC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;
|
|
1
|
+
{"version":3,"file":"AbiDecoder.d.ts","sourceRoot":"","sources":["../../src/utils/AbiDecoder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,SAAS,CAAC;AACpC,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,qBAAa,UAAW,SAAQ,OAAO;IACtC,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS;IAkB3C,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAcjC"}
|
package/dist/utils/AbiDecoder.js
CHANGED
|
@@ -14,4 +14,15 @@ export class AbiDecoder extends AbiBase {
|
|
|
14
14
|
args: this.interface.decodeFunctionData(functionFragment, data),
|
|
15
15
|
};
|
|
16
16
|
}
|
|
17
|
+
decodeError(data) {
|
|
18
|
+
if (!data.startsWith("0x")) {
|
|
19
|
+
data = "0x" + data;
|
|
20
|
+
}
|
|
21
|
+
const errorSelector = data.slice(0, 10);
|
|
22
|
+
const errorFragment = this.interface.getError(errorSelector);
|
|
23
|
+
if (!errorFragment) {
|
|
24
|
+
throw new Error(`Error selector not found in ABI: ${errorSelector}`);
|
|
25
|
+
}
|
|
26
|
+
return errorFragment.name;
|
|
27
|
+
}
|
|
17
28
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../src/utils/Message.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Message.d.ts","sourceRoot":"","sources":["../../src/utils/Message.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAKxC,qBAAa,OAAO;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;gBAEX,OAAO,EAAE,aAAa;IAMlC,MAAM,CAAC,GAAG,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;WAI9B,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAexE,MAAM,IAAI,OAAO;IASjB,QAAQ,IAAI,MAAM;IAIlB,QAAQ,IAAI,MAAM,EAAE;IAIpB,MAAM,IAAI,aAAa;CAOvB"}
|
package/dist/utils/Message.js
CHANGED
|
@@ -7,10 +7,10 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import { PrivateKey } from "@/identities/PrivateKey";
|
|
11
10
|
import { PublicKey } from "@/identities/PublicKey";
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
11
|
+
import { hashMessage, verifyMessage } from "ethers";
|
|
12
|
+
import { Address, PrivateKey } from "@/identities";
|
|
13
|
+
import { SigningKey } from "ethers";
|
|
14
14
|
export class Message {
|
|
15
15
|
constructor(message) {
|
|
16
16
|
this.publicKey = message.publicKey;
|
|
@@ -24,19 +24,22 @@ export class Message {
|
|
|
24
24
|
return __awaiter(this, void 0, void 0, function* () {
|
|
25
25
|
const privateKey = PrivateKey.fromPassphrase(passphrase);
|
|
26
26
|
const publicKey = PublicKey.fromPassphrase(passphrase).publicKey;
|
|
27
|
-
|
|
27
|
+
// Sign messages using eip-191 signed data specification, to be aligned with ledger signing workflow.
|
|
28
|
+
// @see https://developers.ledger.com/docs/ledger-live/discover/integration/wallet-api/server/handlers/message
|
|
29
|
+
const signature = new SigningKey(`0x${privateKey.privateKey}`).sign(hashMessage(message));
|
|
28
30
|
return Message.new({
|
|
29
31
|
publicKey,
|
|
30
|
-
signature: signature.
|
|
32
|
+
signature: signature.serialized,
|
|
31
33
|
message,
|
|
32
34
|
});
|
|
33
35
|
});
|
|
34
36
|
}
|
|
35
37
|
verify() {
|
|
36
|
-
const message =
|
|
37
|
-
const
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const message = new Uint8Array(new TextEncoder().encode(this.message));
|
|
39
|
+
const address = Address.fromPublicKey(this.publicKey);
|
|
40
|
+
// Messages need to be signed using eip-191 signed data specification
|
|
41
|
+
const signerAddress = verifyMessage(message, this.signature);
|
|
42
|
+
return signerAddress === address;
|
|
40
43
|
}
|
|
41
44
|
toString() {
|
|
42
45
|
return JSON.stringify(this.toJson());
|
package/package.json
CHANGED
package/src/utils/AbiDecoder.ts
CHANGED
|
@@ -19,4 +19,19 @@ export class AbiDecoder extends AbiBase {
|
|
|
19
19
|
args: this.interface.decodeFunctionData(functionFragment, data),
|
|
20
20
|
};
|
|
21
21
|
}
|
|
22
|
+
|
|
23
|
+
decodeError(data: string): string {
|
|
24
|
+
if (!data.startsWith("0x")) {
|
|
25
|
+
data = "0x" + data;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const errorSelector = data.slice(0, 10);
|
|
29
|
+
|
|
30
|
+
const errorFragment = this.interface.getError(errorSelector);
|
|
31
|
+
if (!errorFragment) {
|
|
32
|
+
throw new Error(`Error selector not found in ABI: ${errorSelector}`);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return errorFragment.name;
|
|
36
|
+
}
|
|
22
37
|
}
|
package/src/utils/Message.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { PrivateKey } from "@/identities/PrivateKey";
|
|
2
1
|
import { PublicKey } from "@/identities/PublicKey";
|
|
3
2
|
import { SignedMessage } from "@/types";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { hashMessage, verifyMessage } from "ethers";
|
|
4
|
+
import { Address, PrivateKey } from "@/identities";
|
|
5
|
+
import { SigningKey } from "ethers";
|
|
6
6
|
|
|
7
7
|
export class Message {
|
|
8
8
|
public publicKey: string;
|
|
@@ -23,21 +23,24 @@ export class Message {
|
|
|
23
23
|
const privateKey = PrivateKey.fromPassphrase(passphrase);
|
|
24
24
|
const publicKey = PublicKey.fromPassphrase(passphrase).publicKey;
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
// Sign messages using eip-191 signed data specification, to be aligned with ledger signing workflow.
|
|
27
|
+
// @see https://developers.ledger.com/docs/ledger-live/discover/integration/wallet-api/server/handlers/message
|
|
28
|
+
const signature = new SigningKey(`0x${privateKey.privateKey}`).sign(hashMessage(message));
|
|
27
29
|
|
|
28
30
|
return Message.new({
|
|
29
31
|
publicKey,
|
|
30
|
-
signature: signature.
|
|
32
|
+
signature: signature.serialized,
|
|
31
33
|
message,
|
|
32
34
|
});
|
|
33
35
|
}
|
|
34
36
|
|
|
35
37
|
verify(): boolean {
|
|
36
|
-
const message =
|
|
37
|
-
const
|
|
38
|
-
|
|
38
|
+
const message = new Uint8Array(new TextEncoder().encode(this.message));
|
|
39
|
+
const address = Address.fromPublicKey(this.publicKey);
|
|
40
|
+
// Messages need to be signed using eip-191 signed data specification
|
|
41
|
+
const signerAddress = verifyMessage(message, this.signature);
|
|
39
42
|
|
|
40
|
-
return
|
|
43
|
+
return signerAddress === address;
|
|
41
44
|
}
|
|
42
45
|
|
|
43
46
|
toString(): string {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"message": "Hello, world!",
|
|
3
3
|
"publicKey": "0243333347c8cbf4e3cbc7a96964181d02a2b0c854faa2fef86b4b8d92afcf473d",
|
|
4
|
-
"signature": "
|
|
4
|
+
"signature": "0x2bdd0c58ff8a25f456065fb731c73308a25d0a09f351f23e3c7dd3882776d33d626b0cafc0b99dd7504b24f6ecd2e036a267c8e5e005f36dcbc03b2e33fa7fc31c"
|
|
5
5
|
}
|
|
@@ -44,3 +44,32 @@ it("should decode using a custom abi", () => {
|
|
|
44
44
|
expect(decodedData.args[0]).toEqual(args[0]);
|
|
45
45
|
expect(decodedData.args[1].map((value: BigInt) => value.toString())).toEqual(args[1]);
|
|
46
46
|
});
|
|
47
|
+
|
|
48
|
+
it("should decode error data and return error name", () => {
|
|
49
|
+
const decoder = new AbiDecoder(ContractAbiType.USERNAMES);
|
|
50
|
+
|
|
51
|
+
const errorData = "0xa0ca2f4e";
|
|
52
|
+
|
|
53
|
+
const errorName = decoder.decodeError(errorData);
|
|
54
|
+
|
|
55
|
+
expect(errorName).toBe("TakenUsername");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it("should decode error data without 0x prefix", () => {
|
|
59
|
+
const decoder = new AbiDecoder(ContractAbiType.USERNAMES);
|
|
60
|
+
|
|
61
|
+
// Same as above but without 0x prefix
|
|
62
|
+
const errorData = "a0ca2f4e";
|
|
63
|
+
|
|
64
|
+
const errorName = decoder.decodeError(errorData);
|
|
65
|
+
|
|
66
|
+
expect(errorName).toBe("TakenUsername");
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
it("should throw error for unknown error selector", () => {
|
|
70
|
+
const decoder = new AbiDecoder(ContractAbiType.USERNAMES);
|
|
71
|
+
|
|
72
|
+
const errorData = "0x12345678";
|
|
73
|
+
|
|
74
|
+
expect(() => decoder.decodeError(errorData)).toThrow("Error selector not found in ABI: 0x12345678");
|
|
75
|
+
});
|