@sovereign-sdk/signers 0.5.1 → 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 +3 -3
|
@@ -1,24 +1,3 @@
|
|
|
1
|
-
var __async = (__this, __arguments, generator) => {
|
|
2
|
-
return new Promise((resolve, reject) => {
|
|
3
|
-
var fulfilled = (value) => {
|
|
4
|
-
try {
|
|
5
|
-
step(generator.next(value));
|
|
6
|
-
} catch (e) {
|
|
7
|
-
reject(e);
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
var rejected = (value) => {
|
|
11
|
-
try {
|
|
12
|
-
step(generator.throw(value));
|
|
13
|
-
} catch (e) {
|
|
14
|
-
reject(e);
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
18
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
|
|
22
1
|
// src/ledger-solana/node.ts
|
|
23
2
|
import TransportNodeHid from "@ledgerhq/hw-transport-node-hid";
|
|
24
3
|
|
|
@@ -32,83 +11,73 @@ var LedgerSolanaSignerBase = class {
|
|
|
32
11
|
this.transport = null;
|
|
33
12
|
this.solanaApp = null;
|
|
34
13
|
}
|
|
35
|
-
connect() {
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"Signing off-chain messages requires Solana Ledger App 1.8.0 or later"
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
this.solanaApp = solana;
|
|
51
|
-
} catch (error) {
|
|
52
|
-
throw new Error(`Failed to connect to Ledger device: ${error}`);
|
|
53
|
-
}
|
|
54
|
-
});
|
|
55
|
-
}
|
|
56
|
-
sign(message) {
|
|
57
|
-
return __async(this, null, function* () {
|
|
58
|
-
yield this.connect();
|
|
59
|
-
if (!this.solanaApp) {
|
|
60
|
-
throw new Error("Ledger Solana app not initialized");
|
|
61
|
-
}
|
|
62
|
-
try {
|
|
63
|
-
const result = yield this.solanaApp.signOffchainMessage(
|
|
64
|
-
this.derivationPath,
|
|
65
|
-
Buffer.from(message)
|
|
14
|
+
async connect() {
|
|
15
|
+
if (this.transport && this.solanaApp) {
|
|
16
|
+
return;
|
|
17
|
+
}
|
|
18
|
+
try {
|
|
19
|
+
this.transport = await this.loadTransport();
|
|
20
|
+
const solana = new Solana(this.transport);
|
|
21
|
+
const version = await solana.getAppConfiguration().then((r) => r.version);
|
|
22
|
+
const [major, minor, _patch] = version.split(".").map(Number);
|
|
23
|
+
if (major < 1 || major === 1 && minor < 8) {
|
|
24
|
+
throw new Error(
|
|
25
|
+
"Signing off-chain messages requires Solana Ledger App 1.8.0 or later"
|
|
66
26
|
);
|
|
67
|
-
return new Uint8Array(result.signature);
|
|
68
|
-
} catch (error) {
|
|
69
|
-
throw new Error(`Failed to sign message with Ledger: ${error}`);
|
|
70
27
|
}
|
|
71
|
-
|
|
28
|
+
this.solanaApp = solana;
|
|
29
|
+
} catch (error) {
|
|
30
|
+
throw new Error(`Failed to connect to Ledger device: ${error}`);
|
|
31
|
+
}
|
|
72
32
|
}
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
}
|
|
88
|
-
});
|
|
33
|
+
async sign(message) {
|
|
34
|
+
await this.connect();
|
|
35
|
+
if (!this.solanaApp) {
|
|
36
|
+
throw new Error("Ledger Solana app not initialized");
|
|
37
|
+
}
|
|
38
|
+
try {
|
|
39
|
+
const result = await this.solanaApp.signOffchainMessage(
|
|
40
|
+
this.derivationPath,
|
|
41
|
+
Buffer.from(message)
|
|
42
|
+
);
|
|
43
|
+
return new Uint8Array(result.signature);
|
|
44
|
+
} catch (error) {
|
|
45
|
+
throw new Error(`Failed to sign message with Ledger: ${error}`);
|
|
46
|
+
}
|
|
89
47
|
}
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
48
|
+
async publicKey() {
|
|
49
|
+
await this.connect();
|
|
50
|
+
if (!this.solanaApp) {
|
|
51
|
+
throw new Error("Ledger Solana app not initialized");
|
|
52
|
+
}
|
|
53
|
+
try {
|
|
54
|
+
const result = await this.solanaApp.getAddress(
|
|
55
|
+
this.derivationPath,
|
|
56
|
+
false
|
|
57
|
+
);
|
|
58
|
+
return new Uint8Array(result.address);
|
|
59
|
+
} catch (error) {
|
|
60
|
+
throw new Error(`Failed to get public key from Ledger: ${error}`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
async disconnect() {
|
|
64
|
+
if (this.transport) {
|
|
65
|
+
await this.transport.close();
|
|
66
|
+
this.transport = null;
|
|
67
|
+
this.solanaApp = null;
|
|
68
|
+
}
|
|
98
69
|
}
|
|
99
70
|
};
|
|
100
71
|
|
|
101
72
|
// src/ledger-solana/node.ts
|
|
102
|
-
function loadNodeTransport() {
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
}
|
|
111
|
-
});
|
|
73
|
+
async function loadNodeTransport() {
|
|
74
|
+
try {
|
|
75
|
+
return await TransportNodeHid.create();
|
|
76
|
+
} catch (error) {
|
|
77
|
+
throw new Error(
|
|
78
|
+
`Failed to connect via Node HID transport. Make sure your Ledger is connected. Error: ${error}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
112
81
|
}
|
|
113
82
|
var LedgerSolanaSigner = class extends LedgerSolanaSignerBase {
|
|
114
83
|
constructor(derivationPath = "44'/501'") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ledger-solana/node.ts","../../src/ledger-solana/common.ts"],"sourcesContent":["import type Transport from \"@ledgerhq/hw-transport\";\nimport TransportNodeHid from \"@ledgerhq/hw-transport-node-hid\";\nimport { LedgerSolanaSignerBase } from \"./common\";\n\nasync function loadNodeTransport(): Promise<Transport> {\n try {\n return await TransportNodeHid.create();\n } catch (error) {\n throw new Error(\n `Failed to connect via Node HID transport. Make sure your Ledger is connected. Error: ${error}`,\n );\n }\n}\n\nexport class LedgerSolanaSigner extends LedgerSolanaSignerBase {\n constructor(derivationPath = \"44'/501'\") {\n super(loadNodeTransport, derivationPath);\n }\n}\n","import Solana from \"@ledgerhq/hw-app-solana\";\nimport type Transport from \"@ledgerhq/hw-transport\";\nimport type { Signer } from \"../signer\";\n\nexport type TransportLoader = () => Promise<Transport>;\n\nexport class LedgerSolanaSignerBase implements Signer {\n readonly __ledgerSolanaSigner = true as const;\n\n private transport: Transport | null = null;\n private solanaApp: Solana | null = null;\n\n constructor(\n private loadTransport: TransportLoader,\n private derivationPath = \"44'/501'\",\n ) {}\n\n private async connect(): Promise<void> {\n if (this.transport && this.solanaApp) {\n return;\n }\n\n try {\n this.transport = await this.loadTransport();\n\n const solana = new Solana(this.transport);\n const version = await solana.getAppConfiguration().then((r) => r.version);\n const [major, minor, _patch] = version.split(\".\").map(Number);\n if (major < 1 || (major === 1 && minor < 8)) {\n throw new Error(\n \"Signing off-chain messages requires Solana Ledger App 1.8.0 or later\",\n );\n }\n this.solanaApp = solana;\n } catch (error) {\n throw new Error(`Failed to connect to Ledger device: ${error}`);\n }\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n await this.connect();\n\n if (!this.solanaApp) {\n throw new Error(\"Ledger Solana app not initialized\");\n }\n\n try {\n const result = await this.solanaApp.signOffchainMessage(\n this.derivationPath,\n Buffer.from(message),\n );\n return new Uint8Array(result.signature);\n } catch (error) {\n throw new Error(`Failed to sign message with Ledger: ${error}`);\n }\n }\n\n public async publicKey(): Promise<Uint8Array> {\n await this.connect();\n\n if (!this.solanaApp) {\n throw new Error(\"Ledger Solana app not initialized\");\n }\n\n try {\n const result = await this.solanaApp.getAddress(\n this.derivationPath,\n false,\n );\n return new Uint8Array(result.address);\n } catch (error) {\n throw new Error(`Failed to get public key from Ledger: ${error}`);\n }\n }\n\n public async disconnect(): Promise<void> {\n if (this.transport) {\n await this.transport.close();\n this.transport = null;\n this.solanaApp = null;\n }\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../src/ledger-solana/node.ts","../../src/ledger-solana/common.ts"],"sourcesContent":["import type Transport from \"@ledgerhq/hw-transport\";\nimport TransportNodeHid from \"@ledgerhq/hw-transport-node-hid\";\nimport { LedgerSolanaSignerBase } from \"./common\";\n\nasync function loadNodeTransport(): Promise<Transport> {\n try {\n return await TransportNodeHid.create();\n } catch (error) {\n throw new Error(\n `Failed to connect via Node HID transport. Make sure your Ledger is connected. Error: ${error}`,\n );\n }\n}\n\nexport class LedgerSolanaSigner extends LedgerSolanaSignerBase {\n constructor(derivationPath = \"44'/501'\") {\n super(loadNodeTransport, derivationPath);\n }\n}\n","import Solana from \"@ledgerhq/hw-app-solana\";\nimport type Transport from \"@ledgerhq/hw-transport\";\nimport type { Signer } from \"../signer\";\n\nexport type TransportLoader = () => Promise<Transport>;\n\nexport class LedgerSolanaSignerBase implements Signer {\n readonly __ledgerSolanaSigner = true as const;\n\n private transport: Transport | null = null;\n private solanaApp: Solana | null = null;\n\n constructor(\n private loadTransport: TransportLoader,\n private derivationPath = \"44'/501'\",\n ) {}\n\n private async connect(): Promise<void> {\n if (this.transport && this.solanaApp) {\n return;\n }\n\n try {\n this.transport = await this.loadTransport();\n\n const solana = new Solana(this.transport);\n const version = await solana.getAppConfiguration().then((r) => r.version);\n const [major, minor, _patch] = version.split(\".\").map(Number);\n if (major < 1 || (major === 1 && minor < 8)) {\n throw new Error(\n \"Signing off-chain messages requires Solana Ledger App 1.8.0 or later\",\n );\n }\n this.solanaApp = solana;\n } catch (error) {\n throw new Error(`Failed to connect to Ledger device: ${error}`);\n }\n }\n\n public async sign(message: Uint8Array): Promise<Uint8Array> {\n await this.connect();\n\n if (!this.solanaApp) {\n throw new Error(\"Ledger Solana app not initialized\");\n }\n\n try {\n const result = await this.solanaApp.signOffchainMessage(\n this.derivationPath,\n Buffer.from(message),\n );\n return new Uint8Array(result.signature);\n } catch (error) {\n throw new Error(`Failed to sign message with Ledger: ${error}`);\n }\n }\n\n public async publicKey(): Promise<Uint8Array> {\n await this.connect();\n\n if (!this.solanaApp) {\n throw new Error(\"Ledger Solana app not initialized\");\n }\n\n try {\n const result = await this.solanaApp.getAddress(\n this.derivationPath,\n false,\n );\n return new Uint8Array(result.address);\n } catch (error) {\n throw new Error(`Failed to get public key from Ledger: ${error}`);\n }\n }\n\n public async disconnect(): Promise<void> {\n if (this.transport) {\n await this.transport.close();\n this.transport = null;\n this.solanaApp = null;\n }\n }\n}\n"],"mappings":";AACA,OAAO,sBAAsB;;;ACD7B,OAAO,YAAY;AAMZ,IAAM,yBAAN,MAA+C;AAAA,EAMpD,YACU,eACA,iBAAiB,YACzB;AAFQ;AACA;AAPV,SAAS,uBAAuB;AAEhC,SAAQ,YAA8B;AACtC,SAAQ,YAA2B;AAAA,EAKhC;AAAA,EAEH,MAAc,UAAyB;AACrC,QAAI,KAAK,aAAa,KAAK,WAAW;AACpC;AAAA,IACF;AAEA,QAAI;AACF,WAAK,YAAY,MAAM,KAAK,cAAc;AAE1C,YAAM,SAAS,IAAI,OAAO,KAAK,SAAS;AACxC,YAAM,UAAU,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AACxE,YAAM,CAAC,OAAO,OAAO,MAAM,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AAC5D,UAAI,QAAQ,KAAM,UAAU,KAAK,QAAQ,GAAI;AAC3C,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AACA,WAAK,YAAY;AAAA,IACnB,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,uCAAuC,KAAK,EAAE;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,MAAa,KAAK,SAA0C;AAC1D,UAAM,KAAK,QAAQ;AAEnB,QAAI,CAAC,KAAK,WAAW;AACnB,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,UAAU;AAAA,QAClC,KAAK;AAAA,QACL,OAAO,KAAK,OAAO;AAAA,MACrB;AACA,aAAO,IAAI,WAAW,OAAO,SAAS;AAAA,IACxC,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,uCAAuC,KAAK,EAAE;AAAA,IAChE;AAAA,EACF;AAAA,EAEA,MAAa,YAAiC;AAC5C,UAAM,KAAK,QAAQ;AAEnB,QAAI,CAAC,KAAK,WAAW;AACnB,YAAM,IAAI,MAAM,mCAAmC;AAAA,IACrD;AAEA,QAAI;AACF,YAAM,SAAS,MAAM,KAAK,UAAU;AAAA,QAClC,KAAK;AAAA,QACL;AAAA,MACF;AACA,aAAO,IAAI,WAAW,OAAO,OAAO;AAAA,IACtC,SAAS,OAAO;AACd,YAAM,IAAI,MAAM,yCAAyC,KAAK,EAAE;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,MAAa,aAA4B;AACvC,QAAI,KAAK,WAAW;AAClB,YAAM,KAAK,UAAU,MAAM;AAC3B,WAAK,YAAY;AACjB,WAAK,YAAY;AAAA,IACnB;AAAA,EACF;AACF;;;AD9EA,eAAe,oBAAwC;AACrD,MAAI;AACF,WAAO,MAAM,iBAAiB,OAAO;AAAA,EACvC,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,wFAAwF,KAAK;AAAA,IAC/F;AAAA,EACF;AACF;AAEO,IAAM,qBAAN,cAAiC,uBAAuB;AAAA,EAC7D,YAAY,iBAAiB,YAAY;AACvC,UAAM,mBAAmB,cAAc;AAAA,EACzC;AACF;","names":[]}
|
package/dist/wasm.d.mts
CHANGED
|
@@ -18,6 +18,7 @@ declare class Eip712Signer implements Signer {
|
|
|
18
18
|
constructor(provider: MetaMaskInpageProvider, schemaJson: Record<string, unknown>, address: string);
|
|
19
19
|
/**
|
|
20
20
|
* Cache the public key recovered from a signature.
|
|
21
|
+
* Uses viem's parseSignature which accepts high-s signatures (unlike ethers).
|
|
21
22
|
*/
|
|
22
23
|
private cachePublicKey;
|
|
23
24
|
/**
|
package/dist/wasm.d.ts
CHANGED
|
@@ -18,6 +18,7 @@ declare class Eip712Signer implements Signer {
|
|
|
18
18
|
constructor(provider: MetaMaskInpageProvider, schemaJson: Record<string, unknown>, address: string);
|
|
19
19
|
/**
|
|
20
20
|
* Cache the public key recovered from a signature.
|
|
21
|
+
* Uses viem's parseSignature which accepts high-s signatures (unlike ethers).
|
|
21
22
|
*/
|
|
22
23
|
private cachePublicKey;
|
|
23
24
|
/**
|
package/dist/wasm.js
CHANGED
|
@@ -26,26 +26,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
|
|
|
26
26
|
mod
|
|
27
27
|
));
|
|
28
28
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
-
var __async = (__this, __arguments, generator) => {
|
|
30
|
-
return new Promise((resolve, reject) => {
|
|
31
|
-
var fulfilled = (value) => {
|
|
32
|
-
try {
|
|
33
|
-
step(generator.next(value));
|
|
34
|
-
} catch (e) {
|
|
35
|
-
reject(e);
|
|
36
|
-
}
|
|
37
|
-
};
|
|
38
|
-
var rejected = (value) => {
|
|
39
|
-
try {
|
|
40
|
-
step(generator.throw(value));
|
|
41
|
-
} catch (e) {
|
|
42
|
-
reject(e);
|
|
43
|
-
}
|
|
44
|
-
};
|
|
45
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
46
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
47
|
-
});
|
|
48
|
-
};
|
|
49
29
|
|
|
50
30
|
// src/wasm.ts
|
|
51
31
|
var wasm_exports = {};
|
|
@@ -58,7 +38,7 @@ module.exports = __toCommonJS(wasm_exports);
|
|
|
58
38
|
var secp = __toESM(require("@noble/secp256k1"));
|
|
59
39
|
var import_universal_wallet_wasm = require("@sovereign-sdk/universal-wallet-wasm");
|
|
60
40
|
var import_utils = require("@sovereign-sdk/utils");
|
|
61
|
-
var
|
|
41
|
+
var import_viem = require("viem");
|
|
62
42
|
|
|
63
43
|
// src/errors.ts
|
|
64
44
|
var SignerError = class extends Error {
|
|
@@ -77,6 +57,15 @@ var SignerError = class extends Error {
|
|
|
77
57
|
};
|
|
78
58
|
|
|
79
59
|
// src/wasm/eip712.ts
|
|
60
|
+
function normalizeSignature(signature) {
|
|
61
|
+
const r = (0, import_utils.hexToBytes)(signature.r.slice(2));
|
|
62
|
+
const s = (0, import_utils.hexToBytes)(signature.s.slice(2));
|
|
63
|
+
let secpSig = secp.Signature.fromCompact(new Uint8Array([...r, ...s]));
|
|
64
|
+
if (secpSig.hasHighS()) {
|
|
65
|
+
secpSig = secpSig.normalizeS();
|
|
66
|
+
}
|
|
67
|
+
return secpSig.toCompactRawBytes();
|
|
68
|
+
}
|
|
80
69
|
var _Eip712Signer = class _Eip712Signer {
|
|
81
70
|
constructor(provider, schemaJson, address) {
|
|
82
71
|
if (!address) {
|
|
@@ -88,83 +77,78 @@ var _Eip712Signer = class _Eip712Signer {
|
|
|
88
77
|
}
|
|
89
78
|
/**
|
|
90
79
|
* Cache the public key recovered from a signature.
|
|
80
|
+
* Uses viem's parseSignature which accepts high-s signatures (unlike ethers).
|
|
91
81
|
*/
|
|
92
82
|
cachePublicKey(signingHash, signature) {
|
|
93
83
|
if (this.cachedPublicKey) return;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
])
|
|
99
|
-
);
|
|
100
|
-
secpSig = secpSig.addRecoveryBit(signature.yParity);
|
|
84
|
+
const r = (0, import_utils.hexToBytes)(signature.r.slice(2));
|
|
85
|
+
const s = (0, import_utils.hexToBytes)(signature.s.slice(2));
|
|
86
|
+
let secpSig = secp.Signature.fromCompact(new Uint8Array([...r, ...s]));
|
|
87
|
+
secpSig = secpSig.addRecoveryBit(signature.yParity ?? 0);
|
|
101
88
|
const publicKey = secpSig.recoverPublicKey(signingHash);
|
|
102
89
|
this.cachedPublicKey = publicKey.toBytes(true);
|
|
103
90
|
}
|
|
104
91
|
/**
|
|
105
92
|
* Get the public key. Requires sign() to be called first to recover the key from a signature.
|
|
106
93
|
*/
|
|
107
|
-
publicKey() {
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
return this.cachedPublicKey;
|
|
116
|
-
});
|
|
94
|
+
async publicKey() {
|
|
95
|
+
if (!this.cachedPublicKey) {
|
|
96
|
+
throw new SignerError(
|
|
97
|
+
"Public key was not available, you must call sign() first",
|
|
98
|
+
_Eip712Signer.SIGNER_ID
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
return this.cachedPublicKey;
|
|
117
102
|
}
|
|
118
103
|
/**
|
|
119
104
|
* Sign an UnsignedTransaction using EIP-712 typed data signing.
|
|
120
105
|
*/
|
|
121
|
-
sign(message) {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
_Eip712Signer.SIGNER_ID
|
|
128
|
-
);
|
|
129
|
-
}
|
|
130
|
-
const unsignedTxBytes = message.slice(0, -32);
|
|
131
|
-
const typeIndex = this.schema.knownTypeIndex(
|
|
132
|
-
import_universal_wallet_wasm.KnownTypeId.UnsignedTransaction
|
|
106
|
+
async sign(message) {
|
|
107
|
+
const address = this.address;
|
|
108
|
+
if (message.length < 32) {
|
|
109
|
+
throw new SignerError(
|
|
110
|
+
"Message too short, expected at least 32 bytes for chain hash",
|
|
111
|
+
_Eip712Signer.SIGNER_ID
|
|
133
112
|
);
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
113
|
+
}
|
|
114
|
+
const unsignedTxBytes = message.slice(0, -32);
|
|
115
|
+
const typeIndex = this.schema.knownTypeIndex(
|
|
116
|
+
import_universal_wallet_wasm.KnownTypeId.UnsignedTransaction
|
|
117
|
+
);
|
|
118
|
+
let eip712Json;
|
|
119
|
+
try {
|
|
120
|
+
eip712Json = this.schema.eip712Json(typeIndex, unsignedTxBytes);
|
|
121
|
+
} catch (error) {
|
|
122
|
+
throw new SignerError(
|
|
123
|
+
`Failed to generate EIP-712 JSON from message: ${error}`,
|
|
124
|
+
_Eip712Signer.SIGNER_ID
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
let signingHash;
|
|
128
|
+
try {
|
|
129
|
+
signingHash = this.schema.eip712SigningHash(typeIndex, unsignedTxBytes);
|
|
130
|
+
} catch (error) {
|
|
131
|
+
throw new SignerError(
|
|
132
|
+
`Failed to generate EIP-712 signing hash: ${error}`,
|
|
133
|
+
_Eip712Signer.SIGNER_ID
|
|
134
|
+
);
|
|
135
|
+
}
|
|
136
|
+
let signatureHex;
|
|
137
|
+
try {
|
|
138
|
+
signatureHex = await this.provider.request({
|
|
139
|
+
method: "eth_signTypedData_v4",
|
|
140
|
+
params: [address, eip712Json]
|
|
141
|
+
});
|
|
142
|
+
} catch (error) {
|
|
143
|
+
throw new SignerError(
|
|
144
|
+
`Failed to sign with EIP-712: ${error}`,
|
|
145
|
+
_Eip712Signer.SIGNER_ID
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
const normalizedHex = signatureHex.startsWith("0x") ? signatureHex : `0x${signatureHex}`;
|
|
149
|
+
const signature = (0, import_viem.parseSignature)(normalizedHex);
|
|
150
|
+
this.cachePublicKey(signingHash, signature);
|
|
151
|
+
return normalizeSignature(signature);
|
|
168
152
|
}
|
|
169
153
|
};
|
|
170
154
|
_Eip712Signer.SIGNER_ID = "Eip712";
|
package/dist/wasm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/wasm.ts","../src/wasm/eip712.ts","../src/errors.ts"],"sourcesContent":["export { type Signer } from \"./signer\";\nexport * from \"./wasm/eip712\";\n","import type { MetaMaskInpageProvider } from \"@metamask/providers\";\nimport * as secp from \"@noble/secp256k1\";\nimport { KnownTypeId, Schema } from \"@sovereign-sdk/universal-wallet-wasm\";\nimport { hexToBytes } from \"@sovereign-sdk/utils\";\nimport { Signature } from \"
|
|
1
|
+
{"version":3,"sources":["../src/wasm.ts","../src/wasm/eip712.ts","../src/errors.ts"],"sourcesContent":["export { type Signer } from \"./signer\";\nexport * from \"./wasm/eip712\";\n","import type { MetaMaskInpageProvider } from \"@metamask/providers\";\nimport * as secp from \"@noble/secp256k1\";\nimport { KnownTypeId, Schema } from \"@sovereign-sdk/universal-wallet-wasm\";\nimport { hexToBytes } from \"@sovereign-sdk/utils\";\nimport { type Signature, parseSignature } from \"viem\";\nimport { SignerError } from \"../errors\";\nimport type { Signer } from \"../signer\";\n\n/**\n * Normalize a signature to low-s form if needed.\n * MetaMask's eth_signTypedData_v4 may return high-s signatures (~50% of the time).\n * The rollup server requires low-s signatures.\n */\nfunction normalizeSignature(signature: Signature): Uint8Array {\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\n // Normalize s if it's > n/2 (convert high-s to low-s)\n if (secpSig.hasHighS()) {\n secpSig = secpSig.normalizeS();\n }\n\n return secpSig.toCompactRawBytes();\n}\n\n/**\n * EIP-712 signer implementation that uses MetaMask's eth_signTypedData_v4 method.\n *\n * This signer expects the message to be a valid UnsignedTransaction that can be\n * parsed by the schema's eip712Json() method.\n *\n * The signer uses the provided address for signing operations.\n */\nexport class Eip712Signer implements Signer {\n private readonly provider: MetaMaskInpageProvider;\n private readonly schema: Schema;\n private readonly address: string;\n private cachedPublicKey?: Uint8Array;\n private static readonly SIGNER_ID = \"Eip712\";\n\n constructor(\n provider: MetaMaskInpageProvider,\n schemaJson: Record<string, unknown>,\n address: string,\n ) {\n if (!address) {\n throw new SignerError(\"Address is required\", Eip712Signer.SIGNER_ID);\n }\n this.provider = provider;\n this.schema = Schema.fromJSON(JSON.stringify(schemaJson));\n this.address = address;\n }\n\n /**\n * Cache the public key recovered from a signature.\n * Uses viem's parseSignature which accepts high-s signatures (unlike ethers).\n */\n private cachePublicKey(signingHash: Uint8Array, signature: Signature): void {\n if (this.cachedPublicKey) return;\n\n const r = hexToBytes(signature.r.slice(2));\n const s = hexToBytes(signature.s.slice(2));\n\n let secpSig = secp.Signature.fromCompact(new Uint8Array([...r, ...s]));\n secpSig = secpSig.addRecoveryBit(signature.yParity ?? 0);\n const publicKey = secpSig.recoverPublicKey(signingHash);\n\n this.cachedPublicKey = publicKey.toBytes(true); // compressed form\n }\n\n /**\n * Get the public key. Requires sign() to be called first to recover the key from a signature.\n */\n async publicKey(): Promise<Uint8Array> {\n if (!this.cachedPublicKey) {\n throw new SignerError(\n \"Public key was not available, you must call sign() first\",\n Eip712Signer.SIGNER_ID,\n );\n }\n\n return this.cachedPublicKey;\n }\n\n /**\n * Sign an UnsignedTransaction using EIP-712 typed data signing.\n */\n async sign(message: Uint8Array): Promise<Uint8Array> {\n const address = this.address;\n\n // Rollups invoke the signer with the chain hash appended, so drop the last 32 bytes of the message\n if (message.length < 32) {\n throw new SignerError(\n \"Message too short, expected at least 32 bytes for chain hash\",\n Eip712Signer.SIGNER_ID,\n );\n }\n const unsignedTxBytes = message.slice(0, -32);\n\n // Get the UnsignedTransaction type index\n const typeIndex = this.schema.knownTypeIndex(\n KnownTypeId.UnsignedTransaction,\n );\n\n // Generate the EIP-712 JSON from the message bytes\n let eip712Json: string;\n try {\n eip712Json = this.schema.eip712Json(typeIndex, unsignedTxBytes);\n } catch (error) {\n throw new SignerError(\n `Failed to generate EIP-712 JSON from message: ${error}`,\n Eip712Signer.SIGNER_ID,\n );\n }\n\n // Get the EIP-712 signing hash for public key recovery\n let signingHash: Uint8Array;\n try {\n signingHash = this.schema.eip712SigningHash(typeIndex, unsignedTxBytes);\n } catch (error) {\n throw new SignerError(\n `Failed to generate EIP-712 signing hash: ${error}`,\n Eip712Signer.SIGNER_ID,\n );\n }\n\n let signatureHex: string;\n try {\n signatureHex = (await this.provider.request({\n method: \"eth_signTypedData_v4\",\n params: [address, eip712Json],\n })) as string;\n } catch (error) {\n throw new SignerError(\n `Failed to sign with EIP-712: ${error}`,\n Eip712Signer.SIGNER_ID,\n );\n }\n\n // Parse the signature using viem (accepts high-s signatures unlike ethers)\n // Normalize to ensure 0x prefix\n const normalizedHex = signatureHex.startsWith(\"0x\")\n ? signatureHex\n : `0x${signatureHex}`;\n const signature = parseSignature(normalizedHex as `0x${string}`);\n this.cachePublicKey(signingHash, signature);\n\n // Normalize to low-s form\n // (EIP-2 low-s requirement only applies to transactions, not off-chain message signing,\n // but the rollup server expects low-s signatures)\n return normalizeSignature(signature);\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":"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","names":[]}
|
package/dist/wasm.mjs
CHANGED
|
@@ -1,29 +1,8 @@
|
|
|
1
|
-
var __async = (__this, __arguments, generator) => {
|
|
2
|
-
return new Promise((resolve, reject) => {
|
|
3
|
-
var fulfilled = (value) => {
|
|
4
|
-
try {
|
|
5
|
-
step(generator.next(value));
|
|
6
|
-
} catch (e) {
|
|
7
|
-
reject(e);
|
|
8
|
-
}
|
|
9
|
-
};
|
|
10
|
-
var rejected = (value) => {
|
|
11
|
-
try {
|
|
12
|
-
step(generator.throw(value));
|
|
13
|
-
} catch (e) {
|
|
14
|
-
reject(e);
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
|
|
18
|
-
step((generator = generator.apply(__this, __arguments)).next());
|
|
19
|
-
});
|
|
20
|
-
};
|
|
21
|
-
|
|
22
1
|
// src/wasm/eip712.ts
|
|
23
2
|
import * as secp from "@noble/secp256k1";
|
|
24
3
|
import { KnownTypeId, Schema } from "@sovereign-sdk/universal-wallet-wasm";
|
|
25
4
|
import { hexToBytes } from "@sovereign-sdk/utils";
|
|
26
|
-
import {
|
|
5
|
+
import { parseSignature } from "viem";
|
|
27
6
|
|
|
28
7
|
// src/errors.ts
|
|
29
8
|
var SignerError = class extends Error {
|
|
@@ -42,6 +21,15 @@ var SignerError = class extends Error {
|
|
|
42
21
|
};
|
|
43
22
|
|
|
44
23
|
// src/wasm/eip712.ts
|
|
24
|
+
function normalizeSignature(signature) {
|
|
25
|
+
const r = hexToBytes(signature.r.slice(2));
|
|
26
|
+
const s = hexToBytes(signature.s.slice(2));
|
|
27
|
+
let secpSig = secp.Signature.fromCompact(new Uint8Array([...r, ...s]));
|
|
28
|
+
if (secpSig.hasHighS()) {
|
|
29
|
+
secpSig = secpSig.normalizeS();
|
|
30
|
+
}
|
|
31
|
+
return secpSig.toCompactRawBytes();
|
|
32
|
+
}
|
|
45
33
|
var _Eip712Signer = class _Eip712Signer {
|
|
46
34
|
constructor(provider, schemaJson, address) {
|
|
47
35
|
if (!address) {
|
|
@@ -53,83 +41,78 @@ var _Eip712Signer = class _Eip712Signer {
|
|
|
53
41
|
}
|
|
54
42
|
/**
|
|
55
43
|
* Cache the public key recovered from a signature.
|
|
44
|
+
* Uses viem's parseSignature which accepts high-s signatures (unlike ethers).
|
|
56
45
|
*/
|
|
57
46
|
cachePublicKey(signingHash, signature) {
|
|
58
47
|
if (this.cachedPublicKey) return;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
])
|
|
64
|
-
);
|
|
65
|
-
secpSig = secpSig.addRecoveryBit(signature.yParity);
|
|
48
|
+
const r = hexToBytes(signature.r.slice(2));
|
|
49
|
+
const s = hexToBytes(signature.s.slice(2));
|
|
50
|
+
let secpSig = secp.Signature.fromCompact(new Uint8Array([...r, ...s]));
|
|
51
|
+
secpSig = secpSig.addRecoveryBit(signature.yParity ?? 0);
|
|
66
52
|
const publicKey = secpSig.recoverPublicKey(signingHash);
|
|
67
53
|
this.cachedPublicKey = publicKey.toBytes(true);
|
|
68
54
|
}
|
|
69
55
|
/**
|
|
70
56
|
* Get the public key. Requires sign() to be called first to recover the key from a signature.
|
|
71
57
|
*/
|
|
72
|
-
publicKey() {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
return this.cachedPublicKey;
|
|
81
|
-
});
|
|
58
|
+
async publicKey() {
|
|
59
|
+
if (!this.cachedPublicKey) {
|
|
60
|
+
throw new SignerError(
|
|
61
|
+
"Public key was not available, you must call sign() first",
|
|
62
|
+
_Eip712Signer.SIGNER_ID
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
return this.cachedPublicKey;
|
|
82
66
|
}
|
|
83
67
|
/**
|
|
84
68
|
* Sign an UnsignedTransaction using EIP-712 typed data signing.
|
|
85
69
|
*/
|
|
86
|
-
sign(message) {
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
70
|
+
async sign(message) {
|
|
71
|
+
const address = this.address;
|
|
72
|
+
if (message.length < 32) {
|
|
73
|
+
throw new SignerError(
|
|
74
|
+
"Message too short, expected at least 32 bytes for chain hash",
|
|
75
|
+
_Eip712Signer.SIGNER_ID
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
const unsignedTxBytes = message.slice(0, -32);
|
|
79
|
+
const typeIndex = this.schema.knownTypeIndex(
|
|
80
|
+
KnownTypeId.UnsignedTransaction
|
|
81
|
+
);
|
|
82
|
+
let eip712Json;
|
|
83
|
+
try {
|
|
84
|
+
eip712Json = this.schema.eip712Json(typeIndex, unsignedTxBytes);
|
|
85
|
+
} catch (error) {
|
|
86
|
+
throw new SignerError(
|
|
87
|
+
`Failed to generate EIP-712 JSON from message: ${error}`,
|
|
88
|
+
_Eip712Signer.SIGNER_ID
|
|
89
|
+
);
|
|
90
|
+
}
|
|
91
|
+
let signingHash;
|
|
92
|
+
try {
|
|
93
|
+
signingHash = this.schema.eip712SigningHash(typeIndex, unsignedTxBytes);
|
|
94
|
+
} catch (error) {
|
|
95
|
+
throw new SignerError(
|
|
96
|
+
`Failed to generate EIP-712 signing hash: ${error}`,
|
|
97
|
+
_Eip712Signer.SIGNER_ID
|
|
98
98
|
);
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
}
|
|
117
|
-
let signatureHex;
|
|
118
|
-
try {
|
|
119
|
-
signatureHex = yield this.provider.request({
|
|
120
|
-
method: "eth_signTypedData_v4",
|
|
121
|
-
params: [address, eip712Json]
|
|
122
|
-
});
|
|
123
|
-
} catch (error) {
|
|
124
|
-
throw new SignerError(
|
|
125
|
-
`Failed to sign with EIP-712: ${error}`,
|
|
126
|
-
_Eip712Signer.SIGNER_ID
|
|
127
|
-
);
|
|
128
|
-
}
|
|
129
|
-
const signature = Signature2.from(signatureHex);
|
|
130
|
-
this.cachePublicKey(signingHash, signature);
|
|
131
|
-
return hexToBytes(signature.compactSerialized.slice(2));
|
|
132
|
-
});
|
|
99
|
+
}
|
|
100
|
+
let signatureHex;
|
|
101
|
+
try {
|
|
102
|
+
signatureHex = await this.provider.request({
|
|
103
|
+
method: "eth_signTypedData_v4",
|
|
104
|
+
params: [address, eip712Json]
|
|
105
|
+
});
|
|
106
|
+
} catch (error) {
|
|
107
|
+
throw new SignerError(
|
|
108
|
+
`Failed to sign with EIP-712: ${error}`,
|
|
109
|
+
_Eip712Signer.SIGNER_ID
|
|
110
|
+
);
|
|
111
|
+
}
|
|
112
|
+
const normalizedHex = signatureHex.startsWith("0x") ? signatureHex : `0x${signatureHex}`;
|
|
113
|
+
const signature = parseSignature(normalizedHex);
|
|
114
|
+
this.cachePublicKey(signingHash, signature);
|
|
115
|
+
return normalizeSignature(signature);
|
|
133
116
|
}
|
|
134
117
|
};
|
|
135
118
|
_Eip712Signer.SIGNER_ID = "Eip712";
|