@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.
@@ -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
- return __async(this, null, function* () {
37
- if (this.transport && this.solanaApp) {
38
- return;
39
- }
40
- try {
41
- this.transport = yield this.loadTransport();
42
- const solana = new Solana(this.transport);
43
- const version = yield solana.getAppConfiguration().then((r) => r.version);
44
- const [major, minor, _patch] = version.split(".").map(Number);
45
- if (major < 1 || major === 1 && minor < 8) {
46
- throw new Error(
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
- publicKey() {
74
- return __async(this, null, function* () {
75
- yield this.connect();
76
- if (!this.solanaApp) {
77
- throw new Error("Ledger Solana app not initialized");
78
- }
79
- try {
80
- const result = yield this.solanaApp.getAddress(
81
- this.derivationPath,
82
- false
83
- );
84
- return new Uint8Array(result.address);
85
- } catch (error) {
86
- throw new Error(`Failed to get public key from Ledger: ${error}`);
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
- disconnect() {
91
- return __async(this, null, function* () {
92
- if (this.transport) {
93
- yield this.transport.close();
94
- this.transport = null;
95
- this.solanaApp = null;
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
- return __async(this, null, function* () {
104
- try {
105
- return yield TransportNodeHid.create();
106
- } catch (error) {
107
- throw new Error(
108
- `Failed to connect via Node HID transport. Make sure your Ledger is connected. Error: ${error}`
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":";;;;;;;;;;;;;;;;;;;;;;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,EAEW,UAAyB;AAAA;AACrC,UAAI,KAAK,aAAa,KAAK,WAAW;AACpC;AAAA,MACF;AAEA,UAAI;AACF,aAAK,YAAY,MAAM,KAAK,cAAc;AAE1C,cAAM,SAAS,IAAI,OAAO,KAAK,SAAS;AACxC,cAAM,UAAU,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO;AACxE,cAAM,CAAC,OAAO,OAAO,MAAM,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,MAAM;AAC5D,YAAI,QAAQ,KAAM,UAAU,KAAK,QAAQ,GAAI;AAC3C,gBAAM,IAAI;AAAA,YACR;AAAA,UACF;AAAA,QACF;AACA,aAAK,YAAY;AAAA,MACnB,SAAS,OAAO;AACd,cAAM,IAAI,MAAM,uCAAuC,KAAK,EAAE;AAAA,MAChE;AAAA,IACF;AAAA;AAAA,EAEa,KAAK,SAA0C;AAAA;AAC1D,YAAM,KAAK,QAAQ;AAEnB,UAAI,CAAC,KAAK,WAAW;AACnB,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,UAAU;AAAA,UAClC,KAAK;AAAA,UACL,OAAO,KAAK,OAAO;AAAA,QACrB;AACA,eAAO,IAAI,WAAW,OAAO,SAAS;AAAA,MACxC,SAAS,OAAO;AACd,cAAM,IAAI,MAAM,uCAAuC,KAAK,EAAE;AAAA,MAChE;AAAA,IACF;AAAA;AAAA,EAEa,YAAiC;AAAA;AAC5C,YAAM,KAAK,QAAQ;AAEnB,UAAI,CAAC,KAAK,WAAW;AACnB,cAAM,IAAI,MAAM,mCAAmC;AAAA,MACrD;AAEA,UAAI;AACF,cAAM,SAAS,MAAM,KAAK,UAAU;AAAA,UAClC,KAAK;AAAA,UACL;AAAA,QACF;AACA,eAAO,IAAI,WAAW,OAAO,OAAO;AAAA,MACtC,SAAS,OAAO;AACd,cAAM,IAAI,MAAM,yCAAyC,KAAK,EAAE;AAAA,MAClE;AAAA,IACF;AAAA;AAAA,EAEa,aAA4B;AAAA;AACvC,UAAI,KAAK,WAAW;AAClB,cAAM,KAAK,UAAU,MAAM;AAC3B,aAAK,YAAY;AACjB,aAAK,YAAY;AAAA,MACnB;AAAA,IACF;AAAA;AACF;;;AD9EA,SAAe,oBAAwC;AAAA;AACrD,QAAI;AACF,aAAO,MAAM,iBAAiB,OAAO;AAAA,IACvC,SAAS,OAAO;AACd,YAAM,IAAI;AAAA,QACR,wFAAwF,KAAK;AAAA,MAC/F;AAAA,IACF;AAAA,EACF;AAAA;AAEO,IAAM,qBAAN,cAAiC,uBAAuB;AAAA,EAC7D,YAAY,iBAAiB,YAAY;AACvC,UAAM,mBAAmB,cAAc;AAAA,EACzC;AACF;","names":[]}
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 import_ethers = require("ethers");
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
- let secpSig = secp.Signature.fromCompact(
95
- new Uint8Array([
96
- ...(0, import_utils.hexToBytes)(signature.r.slice(2)),
97
- ...(0, import_utils.hexToBytes)(signature.s.slice(2))
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
- return __async(this, null, function* () {
109
- if (!this.cachedPublicKey) {
110
- throw new SignerError(
111
- "Public key was not available, you must call sign() first",
112
- _Eip712Signer.SIGNER_ID
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
- return __async(this, null, function* () {
123
- const address = this.address;
124
- if (message.length < 32) {
125
- throw new SignerError(
126
- "Message too short, expected at least 32 bytes for chain hash",
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
- let eip712Json;
135
- try {
136
- eip712Json = this.schema.eip712Json(typeIndex, unsignedTxBytes);
137
- } catch (error) {
138
- throw new SignerError(
139
- `Failed to generate EIP-712 JSON from message: ${error}`,
140
- _Eip712Signer.SIGNER_ID
141
- );
142
- }
143
- let signingHash;
144
- try {
145
- signingHash = this.schema.eip712SigningHash(typeIndex, unsignedTxBytes);
146
- } catch (error) {
147
- throw new SignerError(
148
- `Failed to generate EIP-712 signing hash: ${error}`,
149
- _Eip712Signer.SIGNER_ID
150
- );
151
- }
152
- let signatureHex;
153
- try {
154
- signatureHex = yield this.provider.request({
155
- method: "eth_signTypedData_v4",
156
- params: [address, eip712Json]
157
- });
158
- } catch (error) {
159
- throw new SignerError(
160
- `Failed to sign with EIP-712: ${error}`,
161
- _Eip712Signer.SIGNER_ID
162
- );
163
- }
164
- const signature = import_ethers.Signature.from(signatureHex);
165
- this.cachePublicKey(signingHash, signature);
166
- return (0, import_utils.hexToBytes)(signature.compactSerialized.slice(2));
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 \"ethers\";\nimport { SignerError } from \"../errors\";\nimport type { Signer } from \"../signer\";\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 */\n private cachePublicKey(signingHash: Uint8Array, signature: Signature): void {\n if (this.cachedPublicKey) return;\n\n let secpSig = secp.Signature.fromCompact(\n new Uint8Array([\n ...hexToBytes(signature.r.slice(2)),\n ...hexToBytes(signature.s.slice(2)),\n ]),\n );\n secpSig = secpSig.addRecoveryBit(signature.yParity);\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 for public key recovery\n const signature = Signature.from(signatureHex);\n this.cachePublicKey(signingHash, signature);\n\n // Return the standard compact serialized signature (r + s, 64 bytes)\n return hexToBytes(signature.compactSerialized.slice(2));\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;;;ACCA,WAAsB;AACtB,mCAAoC;AACpC,mBAA2B;AAC3B,oBAA0B;;;ACDnB,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;;;ADHO,IAAM,gBAAN,MAAM,cAA+B;AAAA,EAO1C,YACE,UACA,YACA,SACA;AACA,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,YAAY,uBAAuB,cAAa,SAAS;AAAA,IACrE;AACA,SAAK,WAAW;AAChB,SAAK,SAAS,oCAAO,SAAS,KAAK,UAAU,UAAU,CAAC;AACxD,SAAK,UAAU;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA,EAKQ,eAAe,aAAyB,WAA4B;AAC1E,QAAI,KAAK,gBAAiB;AAE1B,QAAI,UAAe,eAAU;AAAA,MAC3B,IAAI,WAAW;AAAA,QACb,OAAG,yBAAW,UAAU,EAAE,MAAM,CAAC,CAAC;AAAA,QAClC,OAAG,yBAAW,UAAU,EAAE,MAAM,CAAC,CAAC;AAAA,MACpC,CAAC;AAAA,IACH;AACA,cAAU,QAAQ,eAAe,UAAU,OAAO;AAClD,UAAM,YAAY,QAAQ,iBAAiB,WAAW;AAEtD,SAAK,kBAAkB,UAAU,QAAQ,IAAI;AAAA,EAC/C;AAAA;AAAA;AAAA;AAAA,EAKM,YAAiC;AAAA;AACrC,UAAI,CAAC,KAAK,iBAAiB;AACzB,cAAM,IAAI;AAAA,UACR;AAAA,UACA,cAAa;AAAA,QACf;AAAA,MACF;AAEA,aAAO,KAAK;AAAA,IACd;AAAA;AAAA;AAAA;AAAA;AAAA,EAKM,KAAK,SAA0C;AAAA;AACnD,YAAM,UAAU,KAAK;AAGrB,UAAI,QAAQ,SAAS,IAAI;AACvB,cAAM,IAAI;AAAA,UACR;AAAA,UACA,cAAa;AAAA,QACf;AAAA,MACF;AACA,YAAM,kBAAkB,QAAQ,MAAM,GAAG,GAAG;AAG5C,YAAM,YAAY,KAAK,OAAO;AAAA,QAC5B,yCAAY;AAAA,MACd;AAGA,UAAI;AACJ,UAAI;AACF,qBAAa,KAAK,OAAO,WAAW,WAAW,eAAe;AAAA,MAChE,SAAS,OAAO;AACd,cAAM,IAAI;AAAA,UACR,iDAAiD,KAAK;AAAA,UACtD,cAAa;AAAA,QACf;AAAA,MACF;AAGA,UAAI;AACJ,UAAI;AACF,sBAAc,KAAK,OAAO,kBAAkB,WAAW,eAAe;AAAA,MACxE,SAAS,OAAO;AACd,cAAM,IAAI;AAAA,UACR,4CAA4C,KAAK;AAAA,UACjD,cAAa;AAAA,QACf;AAAA,MACF;AAEA,UAAI;AACJ,UAAI;AACF,uBAAgB,MAAM,KAAK,SAAS,QAAQ;AAAA,UAC1C,QAAQ;AAAA,UACR,QAAQ,CAAC,SAAS,UAAU;AAAA,QAC9B,CAAC;AAAA,MACH,SAAS,OAAO;AACd,cAAM,IAAI;AAAA,UACR,gCAAgC,KAAK;AAAA,UACrC,cAAa;AAAA,QACf;AAAA,MACF;AAGA,YAAM,YAAY,wBAAU,KAAK,YAAY;AAC7C,WAAK,eAAe,aAAa,SAAS;AAG1C,iBAAO,yBAAW,UAAU,kBAAkB,MAAM,CAAC,CAAC;AAAA,IACxD;AAAA;AACF;AAlHa,cAKa,YAAY;AAL/B,IAAM,eAAN;","names":[]}
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 { Signature as Signature2 } from "ethers";
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
- let secpSig = secp.Signature.fromCompact(
60
- new Uint8Array([
61
- ...hexToBytes(signature.r.slice(2)),
62
- ...hexToBytes(signature.s.slice(2))
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
- return __async(this, null, function* () {
74
- if (!this.cachedPublicKey) {
75
- throw new SignerError(
76
- "Public key was not available, you must call sign() first",
77
- _Eip712Signer.SIGNER_ID
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
- return __async(this, null, function* () {
88
- const address = this.address;
89
- if (message.length < 32) {
90
- throw new SignerError(
91
- "Message too short, expected at least 32 bytes for chain hash",
92
- _Eip712Signer.SIGNER_ID
93
- );
94
- }
95
- const unsignedTxBytes = message.slice(0, -32);
96
- const typeIndex = this.schema.knownTypeIndex(
97
- KnownTypeId.UnsignedTransaction
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
- let eip712Json;
100
- try {
101
- eip712Json = this.schema.eip712Json(typeIndex, unsignedTxBytes);
102
- } catch (error) {
103
- throw new SignerError(
104
- `Failed to generate EIP-712 JSON from message: ${error}`,
105
- _Eip712Signer.SIGNER_ID
106
- );
107
- }
108
- let signingHash;
109
- try {
110
- signingHash = this.schema.eip712SigningHash(typeIndex, unsignedTxBytes);
111
- } catch (error) {
112
- throw new SignerError(
113
- `Failed to generate EIP-712 signing hash: ${error}`,
114
- _Eip712Signer.SIGNER_ID
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";