@sovereign-sdk/signers 0.0.4 → 0.1.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/index.d.mts +56 -1
- package/dist/index.d.ts +56 -1
- package/dist/index.js +117 -0
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +103 -0
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { MetaMaskInpageProvider } from '@metamask/providers';
|
|
2
|
+
import * as ed from '@noble/ed25519';
|
|
3
|
+
import { PrivKey } from '@noble/secp256k1';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* A signer interface that can be implemented to provide custom signers for use in Sovereign SDK applications.
|
|
@@ -61,4 +63,57 @@ type MetaMaskSnapSignerOpt = {
|
|
|
61
63
|
*/
|
|
62
64
|
declare const newMetaMaskSnapSigner: ({ curve, schema, snapId, ...rest }: MetaMaskSnapSignerOpt) => Signer;
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
declare class Ed25519Signer implements Signer {
|
|
67
|
+
private readonly privateKey;
|
|
68
|
+
private readonly chainHash;
|
|
69
|
+
constructor(privateKey: ed.Hex, chainHash: Uint8Array);
|
|
70
|
+
sign(message: Uint8Array): Promise<Uint8Array>;
|
|
71
|
+
publicKey(): Promise<Uint8Array>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
declare class Secp256k1Signer implements Signer {
|
|
75
|
+
private readonly privateKey;
|
|
76
|
+
private readonly chainHash;
|
|
77
|
+
constructor(privateKey: PrivKey, chainHash: Uint8Array);
|
|
78
|
+
sign(message: Uint8Array): Promise<Uint8Array>;
|
|
79
|
+
/** Returns the public key in compressed form. */
|
|
80
|
+
publicKey(): Promise<Uint8Array>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* An error that can be thrown by a signer.
|
|
85
|
+
*/
|
|
86
|
+
declare class SignerError extends Error {
|
|
87
|
+
readonly signerId: string;
|
|
88
|
+
/**
|
|
89
|
+
* Create a new SignerError.
|
|
90
|
+
*
|
|
91
|
+
* @param message - The error message
|
|
92
|
+
* @param signerId - The ID of the signer that threw the error
|
|
93
|
+
*/
|
|
94
|
+
constructor(message: string, signerId: string);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Minimal EIP-1193 provider interface (exposed by Privy wallets). */
|
|
98
|
+
type EthereumProvider = {
|
|
99
|
+
request: (args: {
|
|
100
|
+
method: string;
|
|
101
|
+
params?: unknown[];
|
|
102
|
+
}) => Promise<unknown>;
|
|
103
|
+
};
|
|
104
|
+
declare class PrivySignerError extends SignerError {
|
|
105
|
+
constructor(message: string);
|
|
106
|
+
}
|
|
107
|
+
declare class PrivySigner implements Signer {
|
|
108
|
+
private readonly provider;
|
|
109
|
+
private readonly chainHash;
|
|
110
|
+
private cachedPublicKey?;
|
|
111
|
+
constructor(provider: EthereumProvider, chainHash: Uint8Array);
|
|
112
|
+
private signProvider;
|
|
113
|
+
sign(message: Uint8Array): Promise<Uint8Array>;
|
|
114
|
+
/** Returns the public key in compressed form. */
|
|
115
|
+
publicKey(): Promise<Uint8Array>;
|
|
116
|
+
private cachePublicKey;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export { Ed25519Signer, type EthereumProvider, type MetaMaskSnapSignerOpt, PrivySigner, PrivySignerError, Secp256k1Signer, type Signer, type SignerOpt, newMetaMaskSnapSigner };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { MetaMaskInpageProvider } from '@metamask/providers';
|
|
2
|
+
import * as ed from '@noble/ed25519';
|
|
3
|
+
import { PrivKey } from '@noble/secp256k1';
|
|
2
4
|
|
|
3
5
|
/**
|
|
4
6
|
* A signer interface that can be implemented to provide custom signers for use in Sovereign SDK applications.
|
|
@@ -61,4 +63,57 @@ type MetaMaskSnapSignerOpt = {
|
|
|
61
63
|
*/
|
|
62
64
|
declare const newMetaMaskSnapSigner: ({ curve, schema, snapId, ...rest }: MetaMaskSnapSignerOpt) => Signer;
|
|
63
65
|
|
|
64
|
-
|
|
66
|
+
declare class Ed25519Signer implements Signer {
|
|
67
|
+
private readonly privateKey;
|
|
68
|
+
private readonly chainHash;
|
|
69
|
+
constructor(privateKey: ed.Hex, chainHash: Uint8Array);
|
|
70
|
+
sign(message: Uint8Array): Promise<Uint8Array>;
|
|
71
|
+
publicKey(): Promise<Uint8Array>;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
declare class Secp256k1Signer implements Signer {
|
|
75
|
+
private readonly privateKey;
|
|
76
|
+
private readonly chainHash;
|
|
77
|
+
constructor(privateKey: PrivKey, chainHash: Uint8Array);
|
|
78
|
+
sign(message: Uint8Array): Promise<Uint8Array>;
|
|
79
|
+
/** Returns the public key in compressed form. */
|
|
80
|
+
publicKey(): Promise<Uint8Array>;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* An error that can be thrown by a signer.
|
|
85
|
+
*/
|
|
86
|
+
declare class SignerError extends Error {
|
|
87
|
+
readonly signerId: string;
|
|
88
|
+
/**
|
|
89
|
+
* Create a new SignerError.
|
|
90
|
+
*
|
|
91
|
+
* @param message - The error message
|
|
92
|
+
* @param signerId - The ID of the signer that threw the error
|
|
93
|
+
*/
|
|
94
|
+
constructor(message: string, signerId: string);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/** Minimal EIP-1193 provider interface (exposed by Privy wallets). */
|
|
98
|
+
type EthereumProvider = {
|
|
99
|
+
request: (args: {
|
|
100
|
+
method: string;
|
|
101
|
+
params?: unknown[];
|
|
102
|
+
}) => Promise<unknown>;
|
|
103
|
+
};
|
|
104
|
+
declare class PrivySignerError extends SignerError {
|
|
105
|
+
constructor(message: string);
|
|
106
|
+
}
|
|
107
|
+
declare class PrivySigner implements Signer {
|
|
108
|
+
private readonly provider;
|
|
109
|
+
private readonly chainHash;
|
|
110
|
+
private cachedPublicKey?;
|
|
111
|
+
constructor(provider: EthereumProvider, chainHash: Uint8Array);
|
|
112
|
+
private signProvider;
|
|
113
|
+
sign(message: Uint8Array): Promise<Uint8Array>;
|
|
114
|
+
/** Returns the public key in compressed form. */
|
|
115
|
+
publicKey(): Promise<Uint8Array>;
|
|
116
|
+
private cachePublicKey;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
export { Ed25519Signer, type EthereumProvider, type MetaMaskSnapSignerOpt, PrivySigner, PrivySignerError, Secp256k1Signer, type Signer, type SignerOpt, newMetaMaskSnapSigner };
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
2
3
|
var __defProp = Object.defineProperty;
|
|
3
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
6
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
6
8
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
9
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
10
|
var __objRest = (source, exclude) => {
|
|
@@ -29,6 +31,14 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
29
31
|
}
|
|
30
32
|
return to;
|
|
31
33
|
};
|
|
34
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
35
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
36
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
37
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
38
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
39
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
40
|
+
mod
|
|
41
|
+
));
|
|
32
42
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
33
43
|
var __async = (__this, __arguments, generator) => {
|
|
34
44
|
return new Promise((resolve, reject) => {
|
|
@@ -54,6 +64,10 @@ var __async = (__this, __arguments, generator) => {
|
|
|
54
64
|
// src/index.ts
|
|
55
65
|
var src_exports = {};
|
|
56
66
|
__export(src_exports, {
|
|
67
|
+
Ed25519Signer: () => Ed25519Signer,
|
|
68
|
+
PrivySigner: () => PrivySigner,
|
|
69
|
+
PrivySignerError: () => PrivySignerError,
|
|
70
|
+
Secp256k1Signer: () => Secp256k1Signer,
|
|
57
71
|
newMetaMaskSnapSigner: () => newMetaMaskSnapSigner
|
|
58
72
|
});
|
|
59
73
|
module.exports = __toCommonJS(src_exports);
|
|
@@ -144,8 +158,111 @@ var newMetaMaskSnapSigner = (_a) => {
|
|
|
144
158
|
}
|
|
145
159
|
};
|
|
146
160
|
};
|
|
161
|
+
|
|
162
|
+
// src/ed25519.ts
|
|
163
|
+
var ed = __toESM(require("@noble/ed25519"));
|
|
164
|
+
var Ed25519Signer = class {
|
|
165
|
+
constructor(privateKey, chainHash) {
|
|
166
|
+
this.privateKey = privateKey;
|
|
167
|
+
this.chainHash = chainHash;
|
|
168
|
+
}
|
|
169
|
+
sign(message) {
|
|
170
|
+
return __async(this, null, function* () {
|
|
171
|
+
return ed.signAsync(
|
|
172
|
+
new Uint8Array([...message, ...this.chainHash]),
|
|
173
|
+
this.privateKey
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
publicKey() {
|
|
178
|
+
return __async(this, null, function* () {
|
|
179
|
+
return ed.getPublicKeyAsync(this.privateKey);
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
// src/secp256k1.ts
|
|
185
|
+
var import_sha3 = require("@noble/hashes/sha3");
|
|
186
|
+
var import_secp256k1 = require("@noble/secp256k1");
|
|
187
|
+
var Secp256k1Signer = class {
|
|
188
|
+
constructor(privateKey, chainHash) {
|
|
189
|
+
this.privateKey = privateKey;
|
|
190
|
+
this.chainHash = chainHash;
|
|
191
|
+
}
|
|
192
|
+
sign(message) {
|
|
193
|
+
return __async(this, null, function* () {
|
|
194
|
+
const msgHash = (0, import_sha3.keccak_256)(new Uint8Array([...message, ...this.chainHash]));
|
|
195
|
+
const signature = yield (0, import_secp256k1.signAsync)(msgHash, this.privateKey);
|
|
196
|
+
return signature.toCompactRawBytes();
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
/** Returns the public key in compressed form. */
|
|
200
|
+
publicKey() {
|
|
201
|
+
return __async(this, null, function* () {
|
|
202
|
+
return (0, import_secp256k1.getPublicKey)(this.privateKey, true);
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
};
|
|
206
|
+
|
|
207
|
+
// src/privy.ts
|
|
208
|
+
var secp = __toESM(require("@noble/secp256k1"));
|
|
209
|
+
var import_ethers = require("ethers");
|
|
210
|
+
var PrivySignerError = class extends SignerError {
|
|
211
|
+
constructor(message) {
|
|
212
|
+
super(message, "Privy");
|
|
213
|
+
}
|
|
214
|
+
};
|
|
215
|
+
var PrivySigner = class {
|
|
216
|
+
constructor(provider, chainHash) {
|
|
217
|
+
this.provider = provider;
|
|
218
|
+
this.chainHash = chainHash;
|
|
219
|
+
}
|
|
220
|
+
signProvider(messageHash) {
|
|
221
|
+
return __async(this, null, function* () {
|
|
222
|
+
const signatureHex = yield this.provider.request({
|
|
223
|
+
method: "secp256k1_sign",
|
|
224
|
+
params: [messageHash]
|
|
225
|
+
});
|
|
226
|
+
return signatureHex;
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
sign(message) {
|
|
230
|
+
return __async(this, null, function* () {
|
|
231
|
+
const data = new Uint8Array([...message, ...this.chainHash]);
|
|
232
|
+
const digest = import_ethers.ethers.keccak256(data);
|
|
233
|
+
const signatureBytes = yield this.signProvider(digest);
|
|
234
|
+
const signature = import_ethers.Signature.from(signatureBytes);
|
|
235
|
+
this.cachePublicKey(digest, signature);
|
|
236
|
+
return import_ethers.ethers.getBytes(import_ethers.ethers.concat([signature.r, signature.s]));
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
/** Returns the public key in compressed form. */
|
|
240
|
+
publicKey() {
|
|
241
|
+
return __async(this, null, function* () {
|
|
242
|
+
if (!this.cachedPublicKey) {
|
|
243
|
+
throw new PrivySignerError(
|
|
244
|
+
"Public key was not available, you must call sign() first"
|
|
245
|
+
);
|
|
246
|
+
}
|
|
247
|
+
return this.cachedPublicKey;
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
cachePublicKey(msgHash, signature) {
|
|
251
|
+
if (this.cachedPublicKey) return;
|
|
252
|
+
let secpSig = secp.Signature.fromCompact(
|
|
253
|
+
import_ethers.ethers.getBytesCopy(import_ethers.ethers.concat([signature.r, signature.s]))
|
|
254
|
+
);
|
|
255
|
+
secpSig = secpSig.addRecoveryBit(signature.yParity);
|
|
256
|
+
const publicKey = secpSig.recoverPublicKey(import_ethers.ethers.getBytes(msgHash));
|
|
257
|
+
this.cachedPublicKey = publicKey.toBytes(true);
|
|
258
|
+
}
|
|
259
|
+
};
|
|
147
260
|
// Annotate the CommonJS export names for ESM import in node:
|
|
148
261
|
0 && (module.exports = {
|
|
262
|
+
Ed25519Signer,
|
|
263
|
+
PrivySigner,
|
|
264
|
+
PrivySignerError,
|
|
265
|
+
Secp256k1Signer,
|
|
149
266
|
newMetaMaskSnapSigner
|
|
150
267
|
});
|
|
151
268
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/snap.ts","../src/errors.ts"],"sourcesContent":["export * from \"./signer\";\nexport * from \"./snap\";\n","/// <reference path=\"./snap-env.d.ts\" />\n\nimport type { MetaMaskInpageProvider } from \"@metamask/providers\";\nimport { bytesToHex, hexToBytes } from \"@sovereign-sdk/utils\";\nimport { SignerError } from \"./errors\";\nimport type { Signer, SignerOpt } from \"./signer\";\n\n/**\n * Options for initializing a MetaMask Snap signer.\n */\nexport type MetaMaskSnapSignerOpt = {\n /**\n * The {@link MetaMaskInpageProvider} to use for the signer.\n *\n * If not provided, the signer will attempt to use the global `window.ethereum` provider.\n */\n provider?: MetaMaskInpageProvider;\n /**\n * The snap ID to use for the signer.\n *\n * Defaults to `npm:@sovereign-sdk/metamask-snap`.\n * Can be changed to `local:localhost:8080` for local development.\n */\n snapId?: string;\n} & SignerOpt;\n\n/**\n * Create a new MetaMask Snap signer.\n *\n * @param options - The {@link MetaMaskSnapSignerOpt} options.\n * @returns A {@link Signer} implementation utilizing Sovereign's MetaMask Snap.\n */\nexport const newMetaMaskSnapSigner = ({\n curve,\n schema,\n snapId = \"npm:@sovereign-sdk/metamask-snap\",\n ...rest\n}: MetaMaskSnapSignerOpt): Signer => {\n const signerId = \"MetaMaskSnap\";\n const provider = rest.provider ?? window.ethereum;\n\n if (!provider) {\n throw new SignerError(\"Failed to find provider for signer\", signerId);\n }\n\n const assertSupported = async () => {\n try {\n await provider.request({\n method: \"wallet_getSnaps\",\n });\n } catch {\n throw new SignerError(\n \"Provider does not support MetaMask snaps\",\n signerId,\n );\n }\n };\n\n const path = 0;\n\n return {\n async publicKey() {\n await assertSupported();\n\n const args = {\n method: \"wallet_invokeSnap\",\n params: {\n snapId,\n request: {\n method: \"getPublicKey\",\n params: { path, curve },\n },\n },\n };\n // biome-ignore lint/suspicious/noExplicitAny: todo\n const { publicKey } = (await provider.request(args)) as any;\n\n return hexToBytes(publicKey);\n },\n async sign(message: Uint8Array) {\n await assertSupported();\n\n const args = {\n method: \"wallet_invokeSnap\",\n params: {\n snapId,\n request: {\n method: \"signTransaction\",\n params: { unsignedTxHex: bytesToHex(message), schema, curve, path },\n },\n },\n };\n // biome-ignore lint/suspicious/noExplicitAny: todo\n const { signature } = (await provider.request(args)) as any;\n\n return hexToBytes(signature);\n },\n };\n};\n","/**\n * An error that can be thrown by a signer.\n */\nexport class SignerError extends Error {\n public readonly signerId: string;\n\n /**\n * Create a new SignerError.\n *\n * @param message - The error message\n * @param signerId - The ID of the signer that threw the error\n */\n constructor(message: string, signerId: string) {\n super(`[${signerId}] ${message}`);\n\n this.signerId = signerId;\n this.name = this.constructor.name;\n this.stack = new Error().stack;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACGA,mBAAuC;;;ACAhC,IAAM,cAAN,cAA0B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASrC,YAAY,SAAiB,UAAkB;AAC7C,UAAM,IAAI,QAAQ,KAAK,OAAO,EAAE;AAEhC,SAAK,WAAW;AAChB,SAAK,OAAO,KAAK,YAAY;AAC7B,SAAK,QAAQ,IAAI,MAAM,EAAE;AAAA,EAC3B;AACF;;;ADaO,IAAM,wBAAwB,CAAC,OAKD;AALC,eACpC;AAAA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,EAnCX,IAgCsC,IAIjC,iBAJiC,IAIjC;AAAA,IAHH;AAAA,IACA;AAAA,IACA;AAAA;AAnCF,MAAAA;AAsCE,QAAM,WAAW;AACjB,QAAM,YAAWA,MAAA,KAAK,aAAL,OAAAA,MAAiB,OAAO;AAEzC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,YAAY,sCAAsC,QAAQ;AAAA,EACtE;AAEA,QAAM,kBAAkB,MAAY;AAClC,QAAI;AACF,YAAM,SAAS,QAAQ;AAAA,QACrB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,SAAQ;AACN,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO;AAEb,SAAO;AAAA,IACC,YAAY;AAAA;AAChB,cAAM,gBAAgB;AAEtB,cAAM,OAAO;AAAA,UACX,QAAQ;AAAA,UACR,QAAQ;AAAA,YACN;AAAA,YACA,SAAS;AAAA,cACP,QAAQ;AAAA,cACR,QAAQ,EAAE,MAAM,MAAM;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AAEA,cAAM,EAAE,UAAU,IAAK,MAAM,SAAS,QAAQ,IAAI;AAElD,mBAAO,yBAAW,SAAS;AAAA,MAC7B;AAAA;AAAA,IACM,KAAK,SAAqB;AAAA;AAC9B,cAAM,gBAAgB;AAEtB,cAAM,OAAO;AAAA,UACX,QAAQ;AAAA,UACR,QAAQ;AAAA,YACN;AAAA,YACA,SAAS;AAAA,cACP,QAAQ;AAAA,cACR,QAAQ,EAAE,mBAAe,yBAAW,OAAO,GAAG,QAAQ,OAAO,KAAK;AAAA,YACpE;AAAA,UACF;AAAA,QACF;AAEA,cAAM,EAAE,UAAU,IAAK,MAAM,SAAS,QAAQ,IAAI;AAElD,mBAAO,yBAAW,SAAS;AAAA,MAC7B;AAAA;AAAA,EACF;AACF;","names":["_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/snap.ts","../src/errors.ts","../src/ed25519.ts","../src/secp256k1.ts","../src/privy.ts"],"sourcesContent":["export * from \"./signer\";\nexport * from \"./snap\";\nexport * from \"./ed25519\";\nexport * from \"./secp256k1\";\nexport * from \"./privy\";\n","/// <reference path=\"./snap-env.d.ts\" />\n\nimport type { MetaMaskInpageProvider } from \"@metamask/providers\";\nimport { bytesToHex, hexToBytes } from \"@sovereign-sdk/utils\";\nimport { SignerError } from \"./errors\";\nimport type { Signer, SignerOpt } from \"./signer\";\n\n/**\n * Options for initializing a MetaMask Snap signer.\n */\nexport type MetaMaskSnapSignerOpt = {\n /**\n * The {@link MetaMaskInpageProvider} to use for the signer.\n *\n * If not provided, the signer will attempt to use the global `window.ethereum` provider.\n */\n provider?: MetaMaskInpageProvider;\n /**\n * The snap ID to use for the signer.\n *\n * Defaults to `npm:@sovereign-sdk/metamask-snap`.\n * Can be changed to `local:localhost:8080` for local development.\n */\n snapId?: string;\n} & SignerOpt;\n\n/**\n * Create a new MetaMask Snap signer.\n *\n * @param options - The {@link MetaMaskSnapSignerOpt} options.\n * @returns A {@link Signer} implementation utilizing Sovereign's MetaMask Snap.\n */\nexport const newMetaMaskSnapSigner = ({\n curve,\n schema,\n snapId = \"npm:@sovereign-sdk/metamask-snap\",\n ...rest\n}: MetaMaskSnapSignerOpt): Signer => {\n const signerId = \"MetaMaskSnap\";\n const provider = rest.provider ?? window.ethereum;\n\n if (!provider) {\n throw new SignerError(\"Failed to find provider for signer\", signerId);\n }\n\n const assertSupported = async () => {\n try {\n await provider.request({\n method: \"wallet_getSnaps\",\n });\n } catch {\n throw new SignerError(\n \"Provider does not support MetaMask snaps\",\n signerId,\n );\n }\n };\n\n const path = 0;\n\n return {\n async publicKey() {\n await assertSupported();\n\n const args = {\n method: \"wallet_invokeSnap\",\n params: {\n snapId,\n request: {\n method: \"getPublicKey\",\n params: { path, curve },\n },\n },\n };\n // biome-ignore lint/suspicious/noExplicitAny: todo\n const { publicKey } = (await provider.request(args)) as any;\n\n return hexToBytes(publicKey);\n },\n async sign(message: Uint8Array) {\n await assertSupported();\n\n const args = {\n method: \"wallet_invokeSnap\",\n params: {\n snapId,\n request: {\n method: \"signTransaction\",\n params: { unsignedTxHex: bytesToHex(message), schema, curve, path },\n },\n },\n };\n // biome-ignore lint/suspicious/noExplicitAny: todo\n const { signature } = (await provider.request(args)) as any;\n\n return hexToBytes(signature);\n },\n };\n};\n","/**\n * An error that can be thrown by a signer.\n */\nexport class SignerError extends Error {\n public readonly signerId: string;\n\n /**\n * Create a new SignerError.\n *\n * @param message - The error message\n * @param signerId - The ID of the signer that threw the error\n */\n constructor(message: string, signerId: string) {\n super(`[${signerId}] ${message}`);\n\n this.signerId = signerId;\n this.name = this.constructor.name;\n this.stack = new Error().stack;\n }\n}\n","import * as ed from \"@noble/ed25519\";\nimport type { Signer } from \"./signer\";\n\nexport class Ed25519Signer implements Signer {\n private readonly privateKey: ed.Hex;\n private readonly chainHash: Uint8Array;\n\n constructor(privateKey: ed.Hex, chainHash: Uint8Array) {\n this.privateKey = privateKey;\n this.chainHash = chainHash;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n return ed.signAsync(\n new Uint8Array([...message, ...this.chainHash]),\n this.privateKey,\n );\n }\n\n async publicKey() {\n return ed.getPublicKeyAsync(this.privateKey);\n }\n}\n","import { keccak_256 } from \"@noble/hashes/sha3\";\nimport { type PrivKey, getPublicKey, signAsync } from \"@noble/secp256k1\";\nimport type { Signer } from \"./signer\";\n\nexport class Secp256k1Signer implements Signer {\n private readonly privateKey: PrivKey;\n private readonly chainHash: Uint8Array;\n\n constructor(privateKey: PrivKey, chainHash: Uint8Array) {\n this.privateKey = privateKey;\n this.chainHash = chainHash;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n const msgHash = keccak_256(new Uint8Array([...message, ...this.chainHash]));\n const signature = await signAsync(msgHash, this.privateKey);\n\n return signature.toCompactRawBytes();\n }\n\n /** Returns the public key in compressed form. */\n public async publicKey(): Promise<Uint8Array> {\n return getPublicKey(this.privateKey, true);\n }\n}\n","import * as secp from \"@noble/secp256k1\";\nimport { Signature, ethers } from \"ethers\";\nimport { SignerError } from \"./errors\";\nimport type { Signer } from \"./signer\";\n\n/** Minimal EIP-1193 provider interface (exposed by Privy wallets). */\nexport type EthereumProvider = {\n request: (args: { method: string; params?: unknown[] }) => Promise<unknown>;\n};\n\nexport class PrivySignerError extends SignerError {\n constructor(message: string) {\n super(message, \"Privy\");\n }\n}\n\nexport class PrivySigner implements Signer {\n private readonly provider: EthereumProvider;\n private readonly chainHash: Uint8Array;\n private cachedPublicKey?: Uint8Array;\n\n constructor(provider: EthereumProvider, chainHash: Uint8Array) {\n this.provider = provider;\n this.chainHash = chainHash;\n }\n\n private async signProvider(messageHash: string): Promise<string> {\n const signatureHex = await this.provider.request({\n method: \"secp256k1_sign\",\n params: [messageHash],\n });\n return signatureHex as string;\n }\n\n async sign(message: Uint8Array): Promise<Uint8Array> {\n const data = new Uint8Array([...message, ...this.chainHash]);\n const digest = ethers.keccak256(data);\n const signatureBytes = await this.signProvider(digest);\n const signature = Signature.from(signatureBytes);\n this.cachePublicKey(digest, signature);\n return ethers.getBytes(ethers.concat([signature.r, signature.s]));\n }\n\n /** Returns the public key in compressed form. */\n async publicKey(): Promise<Uint8Array> {\n if (!this.cachedPublicKey) {\n throw new PrivySignerError(\n \"Public key was not available, you must call sign() first\",\n );\n }\n\n return this.cachedPublicKey;\n }\n\n private cachePublicKey(msgHash: string, signature: Signature) {\n if (this.cachedPublicKey) return;\n\n let secpSig = secp.Signature.fromCompact(\n ethers.getBytesCopy(ethers.concat([signature.r, signature.s])),\n );\n secpSig = secpSig.addRecoveryBit(signature.yParity);\n const publicKey = secpSig.recoverPublicKey(ethers.getBytes(msgHash));\n\n this.cachedPublicKey = publicKey.toBytes(true);\n }\n}\n"],"mappings":"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","names":["_a"]}
|
package/dist/index.mjs
CHANGED
|
@@ -120,7 +120,110 @@ var newMetaMaskSnapSigner = (_a) => {
|
|
|
120
120
|
}
|
|
121
121
|
};
|
|
122
122
|
};
|
|
123
|
+
|
|
124
|
+
// src/ed25519.ts
|
|
125
|
+
import * as ed from "@noble/ed25519";
|
|
126
|
+
var Ed25519Signer = class {
|
|
127
|
+
constructor(privateKey, chainHash) {
|
|
128
|
+
this.privateKey = privateKey;
|
|
129
|
+
this.chainHash = chainHash;
|
|
130
|
+
}
|
|
131
|
+
sign(message) {
|
|
132
|
+
return __async(this, null, function* () {
|
|
133
|
+
return ed.signAsync(
|
|
134
|
+
new Uint8Array([...message, ...this.chainHash]),
|
|
135
|
+
this.privateKey
|
|
136
|
+
);
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
publicKey() {
|
|
140
|
+
return __async(this, null, function* () {
|
|
141
|
+
return ed.getPublicKeyAsync(this.privateKey);
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
// src/secp256k1.ts
|
|
147
|
+
import { keccak_256 } from "@noble/hashes/sha3";
|
|
148
|
+
import { getPublicKey, signAsync as signAsync2 } from "@noble/secp256k1";
|
|
149
|
+
var Secp256k1Signer = class {
|
|
150
|
+
constructor(privateKey, chainHash) {
|
|
151
|
+
this.privateKey = privateKey;
|
|
152
|
+
this.chainHash = chainHash;
|
|
153
|
+
}
|
|
154
|
+
sign(message) {
|
|
155
|
+
return __async(this, null, function* () {
|
|
156
|
+
const msgHash = keccak_256(new Uint8Array([...message, ...this.chainHash]));
|
|
157
|
+
const signature = yield signAsync2(msgHash, this.privateKey);
|
|
158
|
+
return signature.toCompactRawBytes();
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
/** Returns the public key in compressed form. */
|
|
162
|
+
publicKey() {
|
|
163
|
+
return __async(this, null, function* () {
|
|
164
|
+
return getPublicKey(this.privateKey, true);
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
// src/privy.ts
|
|
170
|
+
import * as secp from "@noble/secp256k1";
|
|
171
|
+
import { Signature as Signature2, ethers } from "ethers";
|
|
172
|
+
var PrivySignerError = class extends SignerError {
|
|
173
|
+
constructor(message) {
|
|
174
|
+
super(message, "Privy");
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
var PrivySigner = class {
|
|
178
|
+
constructor(provider, chainHash) {
|
|
179
|
+
this.provider = provider;
|
|
180
|
+
this.chainHash = chainHash;
|
|
181
|
+
}
|
|
182
|
+
signProvider(messageHash) {
|
|
183
|
+
return __async(this, null, function* () {
|
|
184
|
+
const signatureHex = yield this.provider.request({
|
|
185
|
+
method: "secp256k1_sign",
|
|
186
|
+
params: [messageHash]
|
|
187
|
+
});
|
|
188
|
+
return signatureHex;
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
sign(message) {
|
|
192
|
+
return __async(this, null, function* () {
|
|
193
|
+
const data = new Uint8Array([...message, ...this.chainHash]);
|
|
194
|
+
const digest = ethers.keccak256(data);
|
|
195
|
+
const signatureBytes = yield this.signProvider(digest);
|
|
196
|
+
const signature = Signature2.from(signatureBytes);
|
|
197
|
+
this.cachePublicKey(digest, signature);
|
|
198
|
+
return ethers.getBytes(ethers.concat([signature.r, signature.s]));
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
/** Returns the public key in compressed form. */
|
|
202
|
+
publicKey() {
|
|
203
|
+
return __async(this, null, function* () {
|
|
204
|
+
if (!this.cachedPublicKey) {
|
|
205
|
+
throw new PrivySignerError(
|
|
206
|
+
"Public key was not available, you must call sign() first"
|
|
207
|
+
);
|
|
208
|
+
}
|
|
209
|
+
return this.cachedPublicKey;
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
cachePublicKey(msgHash, signature) {
|
|
213
|
+
if (this.cachedPublicKey) return;
|
|
214
|
+
let secpSig = secp.Signature.fromCompact(
|
|
215
|
+
ethers.getBytesCopy(ethers.concat([signature.r, signature.s]))
|
|
216
|
+
);
|
|
217
|
+
secpSig = secpSig.addRecoveryBit(signature.yParity);
|
|
218
|
+
const publicKey = secpSig.recoverPublicKey(ethers.getBytes(msgHash));
|
|
219
|
+
this.cachedPublicKey = publicKey.toBytes(true);
|
|
220
|
+
}
|
|
221
|
+
};
|
|
123
222
|
export {
|
|
223
|
+
Ed25519Signer,
|
|
224
|
+
PrivySigner,
|
|
225
|
+
PrivySignerError,
|
|
226
|
+
Secp256k1Signer,
|
|
124
227
|
newMetaMaskSnapSigner
|
|
125
228
|
};
|
|
126
229
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/snap.ts","../src/errors.ts"],"sourcesContent":["/// <reference path=\"./snap-env.d.ts\" />\n\nimport type { MetaMaskInpageProvider } from \"@metamask/providers\";\nimport { bytesToHex, hexToBytes } from \"@sovereign-sdk/utils\";\nimport { SignerError } from \"./errors\";\nimport type { Signer, SignerOpt } from \"./signer\";\n\n/**\n * Options for initializing a MetaMask Snap signer.\n */\nexport type MetaMaskSnapSignerOpt = {\n /**\n * The {@link MetaMaskInpageProvider} to use for the signer.\n *\n * If not provided, the signer will attempt to use the global `window.ethereum` provider.\n */\n provider?: MetaMaskInpageProvider;\n /**\n * The snap ID to use for the signer.\n *\n * Defaults to `npm:@sovereign-sdk/metamask-snap`.\n * Can be changed to `local:localhost:8080` for local development.\n */\n snapId?: string;\n} & SignerOpt;\n\n/**\n * Create a new MetaMask Snap signer.\n *\n * @param options - The {@link MetaMaskSnapSignerOpt} options.\n * @returns A {@link Signer} implementation utilizing Sovereign's MetaMask Snap.\n */\nexport const newMetaMaskSnapSigner = ({\n curve,\n schema,\n snapId = \"npm:@sovereign-sdk/metamask-snap\",\n ...rest\n}: MetaMaskSnapSignerOpt): Signer => {\n const signerId = \"MetaMaskSnap\";\n const provider = rest.provider ?? window.ethereum;\n\n if (!provider) {\n throw new SignerError(\"Failed to find provider for signer\", signerId);\n }\n\n const assertSupported = async () => {\n try {\n await provider.request({\n method: \"wallet_getSnaps\",\n });\n } catch {\n throw new SignerError(\n \"Provider does not support MetaMask snaps\",\n signerId,\n );\n }\n };\n\n const path = 0;\n\n return {\n async publicKey() {\n await assertSupported();\n\n const args = {\n method: \"wallet_invokeSnap\",\n params: {\n snapId,\n request: {\n method: \"getPublicKey\",\n params: { path, curve },\n },\n },\n };\n // biome-ignore lint/suspicious/noExplicitAny: todo\n const { publicKey } = (await provider.request(args)) as any;\n\n return hexToBytes(publicKey);\n },\n async sign(message: Uint8Array) {\n await assertSupported();\n\n const args = {\n method: \"wallet_invokeSnap\",\n params: {\n snapId,\n request: {\n method: \"signTransaction\",\n params: { unsignedTxHex: bytesToHex(message), schema, curve, path },\n },\n },\n };\n // biome-ignore lint/suspicious/noExplicitAny: todo\n const { signature } = (await provider.request(args)) as any;\n\n return hexToBytes(signature);\n },\n };\n};\n","/**\n * An error that can be thrown by a signer.\n */\nexport class SignerError extends Error {\n public readonly signerId: string;\n\n /**\n * Create a new SignerError.\n *\n * @param message - The error message\n * @param signerId - The ID of the signer that threw the error\n */\n constructor(message: string, signerId: string) {\n super(`[${signerId}] ${message}`);\n\n this.signerId = signerId;\n this.name = this.constructor.name;\n this.stack = new Error().stack;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGA,SAAS,YAAY,kBAAkB;;;ACAhC,IAAM,cAAN,cAA0B,MAAM;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASrC,YAAY,SAAiB,UAAkB;AAC7C,UAAM,IAAI,QAAQ,KAAK,OAAO,EAAE;AAEhC,SAAK,WAAW;AAChB,SAAK,OAAO,KAAK,YAAY;AAC7B,SAAK,QAAQ,IAAI,MAAM,EAAE;AAAA,EAC3B;AACF;;;ADaO,IAAM,wBAAwB,CAAC,OAKD;AALC,eACpC;AAAA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,EAnCX,IAgCsC,IAIjC,iBAJiC,IAIjC;AAAA,IAHH;AAAA,IACA;AAAA,IACA;AAAA;AAnCF,MAAAA;AAsCE,QAAM,WAAW;AACjB,QAAM,YAAWA,MAAA,KAAK,aAAL,OAAAA,MAAiB,OAAO;AAEzC,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,YAAY,sCAAsC,QAAQ;AAAA,EACtE;AAEA,QAAM,kBAAkB,MAAY;AAClC,QAAI;AACF,YAAM,SAAS,QAAQ;AAAA,QACrB,QAAQ;AAAA,MACV,CAAC;AAAA,IACH,SAAQ;AACN,YAAM,IAAI;AAAA,QACR;AAAA,QACA;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,QAAM,OAAO;AAEb,SAAO;AAAA,IACC,YAAY;AAAA;AAChB,cAAM,gBAAgB;AAEtB,cAAM,OAAO;AAAA,UACX,QAAQ;AAAA,UACR,QAAQ;AAAA,YACN;AAAA,YACA,SAAS;AAAA,cACP,QAAQ;AAAA,cACR,QAAQ,EAAE,MAAM,MAAM;AAAA,YACxB;AAAA,UACF;AAAA,QACF;AAEA,cAAM,EAAE,UAAU,IAAK,MAAM,SAAS,QAAQ,IAAI;AAElD,eAAO,WAAW,SAAS;AAAA,MAC7B;AAAA;AAAA,IACM,KAAK,SAAqB;AAAA;AAC9B,cAAM,gBAAgB;AAEtB,cAAM,OAAO;AAAA,UACX,QAAQ;AAAA,UACR,QAAQ;AAAA,YACN;AAAA,YACA,SAAS;AAAA,cACP,QAAQ;AAAA,cACR,QAAQ,EAAE,eAAe,WAAW,OAAO,GAAG,QAAQ,OAAO,KAAK;AAAA,YACpE;AAAA,UACF;AAAA,QACF;AAEA,cAAM,EAAE,UAAU,IAAK,MAAM,SAAS,QAAQ,IAAI;AAElD,eAAO,WAAW,SAAS;AAAA,MAC7B;AAAA;AAAA,EACF;AACF;","names":["_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/snap.ts","../src/errors.ts","../src/ed25519.ts","../src/secp256k1.ts","../src/privy.ts"],"sourcesContent":["/// <reference path=\"./snap-env.d.ts\" />\n\nimport type { MetaMaskInpageProvider } from \"@metamask/providers\";\nimport { bytesToHex, hexToBytes } from \"@sovereign-sdk/utils\";\nimport { SignerError } from \"./errors\";\nimport type { Signer, SignerOpt } from \"./signer\";\n\n/**\n * Options for initializing a MetaMask Snap signer.\n */\nexport type MetaMaskSnapSignerOpt = {\n /**\n * The {@link MetaMaskInpageProvider} to use for the signer.\n *\n * If not provided, the signer will attempt to use the global `window.ethereum` provider.\n */\n provider?: MetaMaskInpageProvider;\n /**\n * The snap ID to use for the signer.\n *\n * Defaults to `npm:@sovereign-sdk/metamask-snap`.\n * Can be changed to `local:localhost:8080` for local development.\n */\n snapId?: string;\n} & SignerOpt;\n\n/**\n * Create a new MetaMask Snap signer.\n *\n * @param options - The {@link MetaMaskSnapSignerOpt} options.\n * @returns A {@link Signer} implementation utilizing Sovereign's MetaMask Snap.\n */\nexport const newMetaMaskSnapSigner = ({\n curve,\n schema,\n snapId = \"npm:@sovereign-sdk/metamask-snap\",\n ...rest\n}: MetaMaskSnapSignerOpt): Signer => {\n const signerId = \"MetaMaskSnap\";\n const provider = rest.provider ?? window.ethereum;\n\n if (!provider) {\n throw new SignerError(\"Failed to find provider for signer\", signerId);\n }\n\n const assertSupported = async () => {\n try {\n await provider.request({\n method: \"wallet_getSnaps\",\n });\n } catch {\n throw new SignerError(\n \"Provider does not support MetaMask snaps\",\n signerId,\n );\n }\n };\n\n const path = 0;\n\n return {\n async publicKey() {\n await assertSupported();\n\n const args = {\n method: \"wallet_invokeSnap\",\n params: {\n snapId,\n request: {\n method: \"getPublicKey\",\n params: { path, curve },\n },\n },\n };\n // biome-ignore lint/suspicious/noExplicitAny: todo\n const { publicKey } = (await provider.request(args)) as any;\n\n return hexToBytes(publicKey);\n },\n async sign(message: Uint8Array) {\n await assertSupported();\n\n const args = {\n method: \"wallet_invokeSnap\",\n params: {\n snapId,\n request: {\n method: \"signTransaction\",\n params: { unsignedTxHex: bytesToHex(message), schema, curve, path },\n },\n },\n };\n // biome-ignore lint/suspicious/noExplicitAny: todo\n const { signature } = (await provider.request(args)) as any;\n\n return hexToBytes(signature);\n },\n };\n};\n","/**\n * An error that can be thrown by a signer.\n */\nexport class SignerError extends Error {\n public readonly signerId: string;\n\n /**\n * Create a new SignerError.\n *\n * @param message - The error message\n * @param signerId - The ID of the signer that threw the error\n */\n constructor(message: string, signerId: string) {\n super(`[${signerId}] ${message}`);\n\n this.signerId = signerId;\n this.name = this.constructor.name;\n this.stack = new Error().stack;\n }\n}\n","import * as ed from \"@noble/ed25519\";\nimport type { Signer } from \"./signer\";\n\nexport class Ed25519Signer implements Signer {\n private readonly privateKey: ed.Hex;\n private readonly chainHash: Uint8Array;\n\n constructor(privateKey: ed.Hex, chainHash: Uint8Array) {\n this.privateKey = privateKey;\n this.chainHash = chainHash;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n return ed.signAsync(\n new Uint8Array([...message, ...this.chainHash]),\n this.privateKey,\n );\n }\n\n async publicKey() {\n return ed.getPublicKeyAsync(this.privateKey);\n }\n}\n","import { keccak_256 } from \"@noble/hashes/sha3\";\nimport { type PrivKey, getPublicKey, signAsync } from \"@noble/secp256k1\";\nimport type { Signer } from \"./signer\";\n\nexport class Secp256k1Signer implements Signer {\n private readonly privateKey: PrivKey;\n private readonly chainHash: Uint8Array;\n\n constructor(privateKey: PrivKey, chainHash: Uint8Array) {\n this.privateKey = privateKey;\n this.chainHash = chainHash;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n const msgHash = keccak_256(new Uint8Array([...message, ...this.chainHash]));\n const signature = await signAsync(msgHash, this.privateKey);\n\n return signature.toCompactRawBytes();\n }\n\n /** Returns the public key in compressed form. */\n public async publicKey(): Promise<Uint8Array> {\n return getPublicKey(this.privateKey, true);\n }\n}\n","import * as secp from \"@noble/secp256k1\";\nimport { Signature, ethers } from \"ethers\";\nimport { SignerError } from \"./errors\";\nimport type { Signer } from \"./signer\";\n\n/** Minimal EIP-1193 provider interface (exposed by Privy wallets). */\nexport type EthereumProvider = {\n request: (args: { method: string; params?: unknown[] }) => Promise<unknown>;\n};\n\nexport class PrivySignerError extends SignerError {\n constructor(message: string) {\n super(message, \"Privy\");\n }\n}\n\nexport class PrivySigner implements Signer {\n private readonly provider: EthereumProvider;\n private readonly chainHash: Uint8Array;\n private cachedPublicKey?: Uint8Array;\n\n constructor(provider: EthereumProvider, chainHash: Uint8Array) {\n this.provider = provider;\n this.chainHash = chainHash;\n }\n\n private async signProvider(messageHash: string): Promise<string> {\n const signatureHex = await this.provider.request({\n method: \"secp256k1_sign\",\n params: [messageHash],\n });\n return signatureHex as string;\n }\n\n async sign(message: Uint8Array): Promise<Uint8Array> {\n const data = new Uint8Array([...message, ...this.chainHash]);\n const digest = ethers.keccak256(data);\n const signatureBytes = await this.signProvider(digest);\n const signature = Signature.from(signatureBytes);\n this.cachePublicKey(digest, signature);\n return ethers.getBytes(ethers.concat([signature.r, signature.s]));\n }\n\n /** Returns the public key in compressed form. */\n async publicKey(): Promise<Uint8Array> {\n if (!this.cachedPublicKey) {\n throw new PrivySignerError(\n \"Public key was not available, you must call sign() first\",\n );\n }\n\n return this.cachedPublicKey;\n }\n\n private cachePublicKey(msgHash: string, signature: Signature) {\n if (this.cachedPublicKey) return;\n\n let secpSig = secp.Signature.fromCompact(\n ethers.getBytesCopy(ethers.concat([signature.r, signature.s])),\n );\n secpSig = secpSig.addRecoveryBit(signature.yParity);\n const publicKey = secpSig.recoverPublicKey(ethers.getBytes(msgHash));\n\n this.cachedPublicKey = publicKey.toBytes(true);\n }\n}\n"],"mappings":"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","names":["_a","signAsync","signAsync","Signature","Signature"]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sovereign-sdk/signers",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "Signer interface and default implementations for use with Sovereign SDK applications",
|
|
5
|
+
"repository": "github:Sovereign-Labs/sovereign-sdk-web3-js",
|
|
5
6
|
"files": [
|
|
6
7
|
"dist",
|
|
7
8
|
"README.md",
|
|
@@ -31,6 +32,10 @@
|
|
|
31
32
|
"access": "public"
|
|
32
33
|
},
|
|
33
34
|
"dependencies": {
|
|
35
|
+
"@noble/ed25519": "^2.1.0",
|
|
36
|
+
"@noble/hashes": "^1.5.0",
|
|
37
|
+
"@noble/secp256k1": "^2.3.0",
|
|
38
|
+
"ethers": "^6.15.0",
|
|
34
39
|
"@sovereign-sdk/utils": "^0.0.3"
|
|
35
40
|
},
|
|
36
41
|
"scripts": {
|