@sovereign-sdk/signers 0.5.0 → 0.5.2
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 +76 -128
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +76 -130
- package/dist/index.mjs.map +1 -1
- package/dist/ledger-solana/default.js +59 -89
- package/dist/ledger-solana/default.js.map +1 -1
- package/dist/ledger-solana/default.mjs +59 -90
- package/dist/ledger-solana/default.mjs.map +1 -1
- package/dist/ledger-solana/node.js +59 -89
- package/dist/ledger-solana/node.js.map +1 -1
- package/dist/ledger-solana/node.mjs +59 -90
- package/dist/ledger-solana/node.mjs.map +1 -1
- package/dist/wasm.d.mts +1 -0
- package/dist/wasm.d.ts +1 -0
- package/dist/wasm.js +68 -84
- package/dist/wasm.js.map +1 -1
- package/dist/wasm.mjs +68 -85
- package/dist/wasm.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -3,22 +3,8 @@ var __create = Object.create;
|
|
|
3
3
|
var __defProp = Object.defineProperty;
|
|
4
4
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
5
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
7
6
|
var __getProtoOf = Object.getPrototypeOf;
|
|
8
7
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
10
|
-
var __objRest = (source, exclude) => {
|
|
11
|
-
var target = {};
|
|
12
|
-
for (var prop in source)
|
|
13
|
-
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
14
|
-
target[prop] = source[prop];
|
|
15
|
-
if (source != null && __getOwnPropSymbols)
|
|
16
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
17
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
18
|
-
target[prop] = source[prop];
|
|
19
|
-
}
|
|
20
|
-
return target;
|
|
21
|
-
};
|
|
22
8
|
var __export = (target, all) => {
|
|
23
9
|
for (var name in all)
|
|
24
10
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -40,26 +26,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
40
26
|
mod
|
|
41
27
|
));
|
|
42
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
43
|
-
var __async = (__this, __arguments, generator) => {
|
|
44
|
-
return new Promise((resolve, reject) => {
|
|
45
|
-
var fulfilled = (value) => {
|
|
46
|
-
try {
|
|
47
|
-
step(generator.next(value));
|
|
48
|
-
} catch (e) {
|
|
49
|
-
reject(e);
|
|
50
|
-
}
|
|
51
|
-
};
|
|
52
|
-
var rejected = (value) => {
|
|
53
|
-
try {
|
|
54
|
-
step(generator.throw(value));
|
|
55
|
-
} catch (e) {
|
|
56
|
-
reject(e);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
60
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
61
|
-
});
|
|
62
|
-
};
|
|
63
29
|
|
|
64
30
|
// src/index.ts
|
|
65
31
|
var src_exports = {};
|
|
@@ -93,69 +59,60 @@ var SignerError = class extends Error {
|
|
|
93
59
|
};
|
|
94
60
|
|
|
95
61
|
// src/snap.ts
|
|
96
|
-
var newMetaMaskSnapSigner = (
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
"curve",
|
|
103
|
-
"schema",
|
|
104
|
-
"snapId"
|
|
105
|
-
]);
|
|
106
|
-
var _a2;
|
|
62
|
+
var newMetaMaskSnapSigner = ({
|
|
63
|
+
curve,
|
|
64
|
+
schema,
|
|
65
|
+
snapId = "npm:@sovereign-sdk/metamask-snap",
|
|
66
|
+
...rest
|
|
67
|
+
}) => {
|
|
107
68
|
const signerId = "MetaMaskSnap";
|
|
108
|
-
const provider =
|
|
69
|
+
const provider = rest.provider ?? window.ethereum;
|
|
109
70
|
if (!provider) {
|
|
110
71
|
throw new SignerError("Failed to find provider for signer", signerId);
|
|
111
72
|
}
|
|
112
|
-
const assertSupported = () =>
|
|
73
|
+
const assertSupported = async () => {
|
|
113
74
|
try {
|
|
114
|
-
|
|
75
|
+
await provider.request({
|
|
115
76
|
method: "wallet_getSnaps"
|
|
116
77
|
});
|
|
117
|
-
} catch
|
|
78
|
+
} catch {
|
|
118
79
|
throw new SignerError(
|
|
119
80
|
"Provider does not support MetaMask snaps",
|
|
120
81
|
signerId
|
|
121
82
|
);
|
|
122
83
|
}
|
|
123
|
-
}
|
|
84
|
+
};
|
|
124
85
|
const path = 0;
|
|
125
86
|
return {
|
|
126
|
-
publicKey() {
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
params: { path, curve }
|
|
136
|
-
}
|
|
87
|
+
async publicKey() {
|
|
88
|
+
await assertSupported();
|
|
89
|
+
const args = {
|
|
90
|
+
method: "wallet_invokeSnap",
|
|
91
|
+
params: {
|
|
92
|
+
snapId,
|
|
93
|
+
request: {
|
|
94
|
+
method: "getPublicKey",
|
|
95
|
+
params: { path, curve }
|
|
137
96
|
}
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
const { publicKey } = await provider.request(args);
|
|
100
|
+
return (0, import_utils.hexToBytes)(publicKey);
|
|
142
101
|
},
|
|
143
|
-
sign(message) {
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
params: { unsignedTxHex: (0, import_utils.bytesToHex)(message), schema, curve, path }
|
|
153
|
-
}
|
|
102
|
+
async sign(message) {
|
|
103
|
+
await assertSupported();
|
|
104
|
+
const args = {
|
|
105
|
+
method: "wallet_invokeSnap",
|
|
106
|
+
params: {
|
|
107
|
+
snapId,
|
|
108
|
+
request: {
|
|
109
|
+
method: "signTransaction",
|
|
110
|
+
params: { unsignedTxHex: (0, import_utils.bytesToHex)(message), schema, curve, path }
|
|
154
111
|
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
const { signature } = await provider.request(args);
|
|
115
|
+
return (0, import_utils.hexToBytes)(signature);
|
|
159
116
|
}
|
|
160
117
|
};
|
|
161
118
|
};
|
|
@@ -166,15 +123,11 @@ var Ed25519Signer = class {
|
|
|
166
123
|
constructor(privateKey) {
|
|
167
124
|
this.privateKey = privateKey;
|
|
168
125
|
}
|
|
169
|
-
sign(message) {
|
|
170
|
-
return
|
|
171
|
-
return ed.signAsync(message, this.privateKey);
|
|
172
|
-
});
|
|
126
|
+
async sign(message) {
|
|
127
|
+
return ed.signAsync(message, this.privateKey);
|
|
173
128
|
}
|
|
174
|
-
publicKey() {
|
|
175
|
-
return
|
|
176
|
-
return ed.getPublicKeyAsync(this.privateKey);
|
|
177
|
-
});
|
|
129
|
+
async publicKey() {
|
|
130
|
+
return ed.getPublicKeyAsync(this.privateKey);
|
|
178
131
|
}
|
|
179
132
|
};
|
|
180
133
|
|
|
@@ -185,24 +138,21 @@ var Secp256k1Signer = class {
|
|
|
185
138
|
constructor(privateKey) {
|
|
186
139
|
this.privateKey = privateKey;
|
|
187
140
|
}
|
|
188
|
-
sign(message) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
return signature.toCompactRawBytes();
|
|
193
|
-
});
|
|
141
|
+
async sign(message) {
|
|
142
|
+
const msgHash = (0, import_sha3.keccak_256)(message);
|
|
143
|
+
const signature = await (0, import_secp256k1.signAsync)(msgHash, this.privateKey);
|
|
144
|
+
return signature.toCompactRawBytes();
|
|
194
145
|
}
|
|
195
146
|
/** Returns the public key in compressed form. */
|
|
196
|
-
publicKey() {
|
|
197
|
-
return
|
|
198
|
-
return (0, import_secp256k1.getPublicKey)(this.privateKey, true);
|
|
199
|
-
});
|
|
147
|
+
async publicKey() {
|
|
148
|
+
return (0, import_secp256k1.getPublicKey)(this.privateKey, true);
|
|
200
149
|
}
|
|
201
150
|
};
|
|
202
151
|
|
|
203
152
|
// src/privy.ts
|
|
204
153
|
var secp = __toESM(require("@noble/secp256k1"));
|
|
205
|
-
var
|
|
154
|
+
var import_utils2 = require("@sovereign-sdk/utils");
|
|
155
|
+
var import_viem = require("viem");
|
|
206
156
|
var PrivySignerError = class extends SignerError {
|
|
207
157
|
constructor(message) {
|
|
208
158
|
super(message, "Privy");
|
|
@@ -212,42 +162,40 @@ var PrivySigner = class {
|
|
|
212
162
|
constructor(provider) {
|
|
213
163
|
this.provider = provider;
|
|
214
164
|
}
|
|
215
|
-
signProvider(messageHash) {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
params: [messageHash]
|
|
220
|
-
});
|
|
221
|
-
return signatureHex;
|
|
165
|
+
async signProvider(messageHash) {
|
|
166
|
+
const signatureHex = await this.provider.request({
|
|
167
|
+
method: "secp256k1_sign",
|
|
168
|
+
params: [messageHash]
|
|
222
169
|
});
|
|
170
|
+
return signatureHex;
|
|
223
171
|
}
|
|
224
|
-
sign(message) {
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
172
|
+
async sign(message) {
|
|
173
|
+
const digest = (0, import_viem.keccak256)(message);
|
|
174
|
+
const signatureBytes = await this.signProvider(digest);
|
|
175
|
+
const normalizedHex = signatureBytes.startsWith("0x") ? signatureBytes : `0x${signatureBytes}`;
|
|
176
|
+
const signature = (0, import_viem.parseSignature)(normalizedHex);
|
|
177
|
+
this.cachePublicKey(digest, signature);
|
|
178
|
+
const r = (0, import_utils2.hexToBytes)(signature.r.slice(2));
|
|
179
|
+
const s = (0, import_utils2.hexToBytes)(signature.s.slice(2));
|
|
180
|
+
return new Uint8Array([...r, ...s]);
|
|
232
181
|
}
|
|
233
182
|
/** Returns the public key in compressed form. */
|
|
234
|
-
publicKey() {
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
return this.cachedPublicKey;
|
|
242
|
-
});
|
|
183
|
+
async publicKey() {
|
|
184
|
+
if (!this.cachedPublicKey) {
|
|
185
|
+
throw new PrivySignerError(
|
|
186
|
+
"Public key was not available, you must call sign() first"
|
|
187
|
+
);
|
|
188
|
+
}
|
|
189
|
+
return this.cachedPublicKey;
|
|
243
190
|
}
|
|
244
191
|
cachePublicKey(msgHash, signature) {
|
|
245
192
|
if (this.cachedPublicKey) return;
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
);
|
|
249
|
-
secpSig = secpSig.addRecoveryBit(signature.yParity);
|
|
250
|
-
const
|
|
193
|
+
const r = (0, import_utils2.hexToBytes)(signature.r.slice(2));
|
|
194
|
+
const s = (0, import_utils2.hexToBytes)(signature.s.slice(2));
|
|
195
|
+
let secpSig = secp.Signature.fromCompact(new Uint8Array([...r, ...s]));
|
|
196
|
+
secpSig = secpSig.addRecoveryBit(signature.yParity ?? 0);
|
|
197
|
+
const msgHashBytes = (0, import_utils2.hexToBytes)(msgHash.slice(2));
|
|
198
|
+
const publicKey = secpSig.recoverPublicKey(msgHashBytes);
|
|
251
199
|
this.cachedPublicKey = publicKey.toBytes(true);
|
|
252
200
|
}
|
|
253
201
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/snap.ts","../src/errors.ts","../src/ed25519.ts","../src/secp256k1.ts","../src/privy.ts","../src/ledger-solana/types.ts"],"sourcesContent":["export * from \"./signer\";\nexport * from \"./snap\";\nexport * from \"./ed25519\";\nexport * from \"./secp256k1\";\nexport * from \"./privy\";\nexport * from \"./ledger-solana/types\";\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\n constructor(privateKey: ed.Hex) {\n this.privateKey = privateKey;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n return ed.signAsync(message, this.privateKey);\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\n constructor(privateKey: PrivKey) {\n this.privateKey = privateKey;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n const msgHash = keccak_256(message);\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 cachedPublicKey?: Uint8Array;\n\n constructor(provider: EthereumProvider) {\n this.provider = provider;\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 digest = ethers.keccak256(message);\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","import type { Signer } from \"../signer\";\n\n/**\n * Type guard to check if a signer is a Ledger Solana signer.\n * This allows checking the signer type without importing Ledger-specific dependencies.\n */\nexport function isLedgerSolanaSigner(\n signer: Signer,\n): signer is Signer & { readonly __ledgerSolanaSigner: true } {\n return (\n \"__ledgerSolanaSigner\" in signer && signer.__ledgerSolanaSigner === true\n );\n}\n"],"mappings":"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","names":["_a"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/snap.ts","../src/errors.ts","../src/ed25519.ts","../src/secp256k1.ts","../src/privy.ts","../src/ledger-solana/types.ts"],"sourcesContent":["export * from \"./signer\";\nexport * from \"./snap\";\nexport * from \"./ed25519\";\nexport * from \"./secp256k1\";\nexport * from \"./privy\";\nexport * from \"./ledger-solana/types\";\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\n constructor(privateKey: ed.Hex) {\n this.privateKey = privateKey;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n return ed.signAsync(message, this.privateKey);\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\n constructor(privateKey: PrivKey) {\n this.privateKey = privateKey;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n const msgHash = keccak_256(message);\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 { hexToBytes } from \"@sovereign-sdk/utils\";\nimport { type Signature, keccak256, parseSignature } from \"viem\";\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 cachedPublicKey?: Uint8Array;\n\n constructor(provider: EthereumProvider) {\n this.provider = provider;\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 digest = keccak256(message);\n const signatureBytes = await this.signProvider(digest);\n // Normalize to ensure 0x prefix\n const normalizedHex = signatureBytes.startsWith(\"0x\")\n ? signatureBytes\n : `0x${signatureBytes}`;\n const signature = parseSignature(normalizedHex as `0x${string}`);\n this.cachePublicKey(digest, signature);\n\n // Return compact signature (r + s, 64 bytes)\n const r = hexToBytes(signature.r.slice(2));\n const s = hexToBytes(signature.s.slice(2));\n return new Uint8Array([...r, ...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 const r = hexToBytes(signature.r.slice(2));\n const s = hexToBytes(signature.s.slice(2));\n let secpSig = secp.Signature.fromCompact(new Uint8Array([...r, ...s]));\n secpSig = secpSig.addRecoveryBit(signature.yParity ?? 0);\n\n const msgHashBytes = hexToBytes(msgHash.slice(2));\n const publicKey = secpSig.recoverPublicKey(msgHashBytes);\n\n this.cachedPublicKey = publicKey.toBytes(true);\n }\n}\n","import type { Signer } from \"../signer\";\n\n/**\n * Type guard to check if a signer is a Ledger Solana signer.\n * This allows checking the signer type without importing Ledger-specific dependencies.\n */\nexport function isLedgerSolanaSigner(\n signer: Signer,\n): signer is Signer & { readonly __ledgerSolanaSigner: true } {\n return (\n \"__ledgerSolanaSigner\" in signer && signer.__ledgerSolanaSigner === true\n );\n}\n"],"mappings":"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","names":["import_utils"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,39 +1,3 @@
|
|
|
1
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
2
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
3
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
4
|
-
var __objRest = (source, exclude) => {
|
|
5
|
-
var target = {};
|
|
6
|
-
for (var prop in source)
|
|
7
|
-
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
8
|
-
target[prop] = source[prop];
|
|
9
|
-
if (source != null && __getOwnPropSymbols)
|
|
10
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
11
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
12
|
-
target[prop] = source[prop];
|
|
13
|
-
}
|
|
14
|
-
return target;
|
|
15
|
-
};
|
|
16
|
-
var __async = (__this, __arguments, generator) => {
|
|
17
|
-
return new Promise((resolve, reject) => {
|
|
18
|
-
var fulfilled = (value) => {
|
|
19
|
-
try {
|
|
20
|
-
step(generator.next(value));
|
|
21
|
-
} catch (e) {
|
|
22
|
-
reject(e);
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
var rejected = (value) => {
|
|
26
|
-
try {
|
|
27
|
-
step(generator.throw(value));
|
|
28
|
-
} catch (e) {
|
|
29
|
-
reject(e);
|
|
30
|
-
}
|
|
31
|
-
};
|
|
32
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
33
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
34
|
-
});
|
|
35
|
-
};
|
|
36
|
-
|
|
37
1
|
// src/snap.ts
|
|
38
2
|
import { bytesToHex, hexToBytes } from "@sovereign-sdk/utils";
|
|
39
3
|
|
|
@@ -54,69 +18,60 @@ var SignerError = class extends Error {
|
|
|
54
18
|
};
|
|
55
19
|
|
|
56
20
|
// src/snap.ts
|
|
57
|
-
var newMetaMaskSnapSigner = (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"curve",
|
|
64
|
-
"schema",
|
|
65
|
-
"snapId"
|
|
66
|
-
]);
|
|
67
|
-
var _a2;
|
|
21
|
+
var newMetaMaskSnapSigner = ({
|
|
22
|
+
curve,
|
|
23
|
+
schema,
|
|
24
|
+
snapId = "npm:@sovereign-sdk/metamask-snap",
|
|
25
|
+
...rest
|
|
26
|
+
}) => {
|
|
68
27
|
const signerId = "MetaMaskSnap";
|
|
69
|
-
const provider =
|
|
28
|
+
const provider = rest.provider ?? window.ethereum;
|
|
70
29
|
if (!provider) {
|
|
71
30
|
throw new SignerError("Failed to find provider for signer", signerId);
|
|
72
31
|
}
|
|
73
|
-
const assertSupported = () =>
|
|
32
|
+
const assertSupported = async () => {
|
|
74
33
|
try {
|
|
75
|
-
|
|
34
|
+
await provider.request({
|
|
76
35
|
method: "wallet_getSnaps"
|
|
77
36
|
});
|
|
78
|
-
} catch
|
|
37
|
+
} catch {
|
|
79
38
|
throw new SignerError(
|
|
80
39
|
"Provider does not support MetaMask snaps",
|
|
81
40
|
signerId
|
|
82
41
|
);
|
|
83
42
|
}
|
|
84
|
-
}
|
|
43
|
+
};
|
|
85
44
|
const path = 0;
|
|
86
45
|
return {
|
|
87
|
-
publicKey() {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
params: { path, curve }
|
|
97
|
-
}
|
|
46
|
+
async publicKey() {
|
|
47
|
+
await assertSupported();
|
|
48
|
+
const args = {
|
|
49
|
+
method: "wallet_invokeSnap",
|
|
50
|
+
params: {
|
|
51
|
+
snapId,
|
|
52
|
+
request: {
|
|
53
|
+
method: "getPublicKey",
|
|
54
|
+
params: { path, curve }
|
|
98
55
|
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
const { publicKey } = await provider.request(args);
|
|
59
|
+
return hexToBytes(publicKey);
|
|
103
60
|
},
|
|
104
|
-
sign(message) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
params: { unsignedTxHex: bytesToHex(message), schema, curve, path }
|
|
114
|
-
}
|
|
61
|
+
async sign(message) {
|
|
62
|
+
await assertSupported();
|
|
63
|
+
const args = {
|
|
64
|
+
method: "wallet_invokeSnap",
|
|
65
|
+
params: {
|
|
66
|
+
snapId,
|
|
67
|
+
request: {
|
|
68
|
+
method: "signTransaction",
|
|
69
|
+
params: { unsignedTxHex: bytesToHex(message), schema, curve, path }
|
|
115
70
|
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
71
|
+
}
|
|
72
|
+
};
|
|
73
|
+
const { signature } = await provider.request(args);
|
|
74
|
+
return hexToBytes(signature);
|
|
120
75
|
}
|
|
121
76
|
};
|
|
122
77
|
};
|
|
@@ -127,15 +82,11 @@ var Ed25519Signer = class {
|
|
|
127
82
|
constructor(privateKey) {
|
|
128
83
|
this.privateKey = privateKey;
|
|
129
84
|
}
|
|
130
|
-
sign(message) {
|
|
131
|
-
return
|
|
132
|
-
return ed.signAsync(message, this.privateKey);
|
|
133
|
-
});
|
|
85
|
+
async sign(message) {
|
|
86
|
+
return ed.signAsync(message, this.privateKey);
|
|
134
87
|
}
|
|
135
|
-
publicKey() {
|
|
136
|
-
return
|
|
137
|
-
return ed.getPublicKeyAsync(this.privateKey);
|
|
138
|
-
});
|
|
88
|
+
async publicKey() {
|
|
89
|
+
return ed.getPublicKeyAsync(this.privateKey);
|
|
139
90
|
}
|
|
140
91
|
};
|
|
141
92
|
|
|
@@ -146,24 +97,21 @@ var Secp256k1Signer = class {
|
|
|
146
97
|
constructor(privateKey) {
|
|
147
98
|
this.privateKey = privateKey;
|
|
148
99
|
}
|
|
149
|
-
sign(message) {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return signature.toCompactRawBytes();
|
|
154
|
-
});
|
|
100
|
+
async sign(message) {
|
|
101
|
+
const msgHash = keccak_256(message);
|
|
102
|
+
const signature = await signAsync2(msgHash, this.privateKey);
|
|
103
|
+
return signature.toCompactRawBytes();
|
|
155
104
|
}
|
|
156
105
|
/** Returns the public key in compressed form. */
|
|
157
|
-
publicKey() {
|
|
158
|
-
return
|
|
159
|
-
return getPublicKey(this.privateKey, true);
|
|
160
|
-
});
|
|
106
|
+
async publicKey() {
|
|
107
|
+
return getPublicKey(this.privateKey, true);
|
|
161
108
|
}
|
|
162
109
|
};
|
|
163
110
|
|
|
164
111
|
// src/privy.ts
|
|
165
112
|
import * as secp from "@noble/secp256k1";
|
|
166
|
-
import {
|
|
113
|
+
import { hexToBytes as hexToBytes2 } from "@sovereign-sdk/utils";
|
|
114
|
+
import { keccak256, parseSignature } from "viem";
|
|
167
115
|
var PrivySignerError = class extends SignerError {
|
|
168
116
|
constructor(message) {
|
|
169
117
|
super(message, "Privy");
|
|
@@ -173,42 +121,40 @@ var PrivySigner = class {
|
|
|
173
121
|
constructor(provider) {
|
|
174
122
|
this.provider = provider;
|
|
175
123
|
}
|
|
176
|
-
signProvider(messageHash) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
params: [messageHash]
|
|
181
|
-
});
|
|
182
|
-
return signatureHex;
|
|
124
|
+
async signProvider(messageHash) {
|
|
125
|
+
const signatureHex = await this.provider.request({
|
|
126
|
+
method: "secp256k1_sign",
|
|
127
|
+
params: [messageHash]
|
|
183
128
|
});
|
|
129
|
+
return signatureHex;
|
|
184
130
|
}
|
|
185
|
-
sign(message) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
131
|
+
async sign(message) {
|
|
132
|
+
const digest = keccak256(message);
|
|
133
|
+
const signatureBytes = await this.signProvider(digest);
|
|
134
|
+
const normalizedHex = signatureBytes.startsWith("0x") ? signatureBytes : `0x${signatureBytes}`;
|
|
135
|
+
const signature = parseSignature(normalizedHex);
|
|
136
|
+
this.cachePublicKey(digest, signature);
|
|
137
|
+
const r = hexToBytes2(signature.r.slice(2));
|
|
138
|
+
const s = hexToBytes2(signature.s.slice(2));
|
|
139
|
+
return new Uint8Array([...r, ...s]);
|
|
193
140
|
}
|
|
194
141
|
/** Returns the public key in compressed form. */
|
|
195
|
-
publicKey() {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return this.cachedPublicKey;
|
|
203
|
-
});
|
|
142
|
+
async publicKey() {
|
|
143
|
+
if (!this.cachedPublicKey) {
|
|
144
|
+
throw new PrivySignerError(
|
|
145
|
+
"Public key was not available, you must call sign() first"
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
return this.cachedPublicKey;
|
|
204
149
|
}
|
|
205
150
|
cachePublicKey(msgHash, signature) {
|
|
206
151
|
if (this.cachedPublicKey) return;
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
);
|
|
210
|
-
secpSig = secpSig.addRecoveryBit(signature.yParity);
|
|
211
|
-
const
|
|
152
|
+
const r = hexToBytes2(signature.r.slice(2));
|
|
153
|
+
const s = hexToBytes2(signature.s.slice(2));
|
|
154
|
+
let secpSig = secp.Signature.fromCompact(new Uint8Array([...r, ...s]));
|
|
155
|
+
secpSig = secpSig.addRecoveryBit(signature.yParity ?? 0);
|
|
156
|
+
const msgHashBytes = hexToBytes2(msgHash.slice(2));
|
|
157
|
+
const publicKey = secpSig.recoverPublicKey(msgHashBytes);
|
|
212
158
|
this.cachedPublicKey = publicKey.toBytes(true);
|
|
213
159
|
}
|
|
214
160
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/snap.ts","../src/errors.ts","../src/ed25519.ts","../src/secp256k1.ts","../src/privy.ts","../src/ledger-solana/types.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\n constructor(privateKey: ed.Hex) {\n this.privateKey = privateKey;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n return ed.signAsync(message, this.privateKey);\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\n constructor(privateKey: PrivKey) {\n this.privateKey = privateKey;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n const msgHash = keccak_256(message);\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 cachedPublicKey?: Uint8Array;\n\n constructor(provider: EthereumProvider) {\n this.provider = provider;\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 digest = ethers.keccak256(message);\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","import type { Signer } from \"../signer\";\n\n/**\n * Type guard to check if a signer is a Ledger Solana signer.\n * This allows checking the signer type without importing Ledger-specific dependencies.\n */\nexport function isLedgerSolanaSigner(\n signer: Signer,\n): signer is Signer & { readonly __ledgerSolanaSigner: true } {\n return (\n \"__ledgerSolanaSigner\" in signer && signer.__ledgerSolanaSigner === true\n );\n}\n"],"mappings":"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","names":["_a","signAsync","signAsync","Signature","Signature"]}
|
|
1
|
+
{"version":3,"sources":["../src/snap.ts","../src/errors.ts","../src/ed25519.ts","../src/secp256k1.ts","../src/privy.ts","../src/ledger-solana/types.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\n constructor(privateKey: ed.Hex) {\n this.privateKey = privateKey;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n return ed.signAsync(message, this.privateKey);\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\n constructor(privateKey: PrivKey) {\n this.privateKey = privateKey;\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n const msgHash = keccak_256(message);\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 { hexToBytes } from \"@sovereign-sdk/utils\";\nimport { type Signature, keccak256, parseSignature } from \"viem\";\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 cachedPublicKey?: Uint8Array;\n\n constructor(provider: EthereumProvider) {\n this.provider = provider;\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 digest = keccak256(message);\n const signatureBytes = await this.signProvider(digest);\n // Normalize to ensure 0x prefix\n const normalizedHex = signatureBytes.startsWith(\"0x\")\n ? signatureBytes\n : `0x${signatureBytes}`;\n const signature = parseSignature(normalizedHex as `0x${string}`);\n this.cachePublicKey(digest, signature);\n\n // Return compact signature (r + s, 64 bytes)\n const r = hexToBytes(signature.r.slice(2));\n const s = hexToBytes(signature.s.slice(2));\n return new Uint8Array([...r, ...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 const r = hexToBytes(signature.r.slice(2));\n const s = hexToBytes(signature.s.slice(2));\n let secpSig = secp.Signature.fromCompact(new Uint8Array([...r, ...s]));\n secpSig = secpSig.addRecoveryBit(signature.yParity ?? 0);\n\n const msgHashBytes = hexToBytes(msgHash.slice(2));\n const publicKey = secpSig.recoverPublicKey(msgHashBytes);\n\n this.cachedPublicKey = publicKey.toBytes(true);\n }\n}\n","import type { Signer } from \"../signer\";\n\n/**\n * Type guard to check if a signer is a Ledger Solana signer.\n * This allows checking the signer type without importing Ledger-specific dependencies.\n */\nexport function isLedgerSolanaSigner(\n signer: Signer,\n): signer is Signer & { readonly __ledgerSolanaSigner: true } {\n return (\n \"__ledgerSolanaSigner\" in signer && signer.__ledgerSolanaSigner === true\n );\n}\n"],"mappings":"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","names":["signAsync","hexToBytes","hexToBytes"]}
|