Skip to content

Commit 07e6d35

Browse files
committed
fix: accept chainId parameter for EIP-712 signing
1 parent ba6e3a9 commit 07e6d35

File tree

2 files changed

+26
-13
lines changed

2 files changed

+26
-13
lines changed

src/core/signer.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,15 @@
11
import { secp256k1 } from "@noble/curves/secp256k1.js";
22
import { bytesToHex, hexToBytes } from "@noble/hashes/utils.js";
33
import {
4+
type Chain,
45
createWalletClient,
56
custom,
67
type EIP1193Provider,
78
type SignTypedDataParameters,
89
type WalletClient,
910
} from "viem";
1011
import { mainnet } from "viem/chains";
11-
import {
12-
NUC_EIP712_DOMAIN,
13-
type NucHeader,
14-
NucHeaderSchema,
15-
NucHeaders,
16-
} from "#/nuc/header";
12+
import { type NucHeader, NucHeaderSchema, NucHeaders } from "#/nuc/header";
1713
import { Payload } from "#/nuc/payload";
1814
import { Did } from "./did/did";
1915
import * as ethr from "./did/ethr";
@@ -106,12 +102,21 @@ export namespace Signer {
106102
/**
107103
* Creates an EIP-712 Signer for Ethereum wallet signing.
108104
* @param signer The EIP-712 compatible signer (e.g., ethers Wallet)
105+
* @param options.chainId Optional chainId for the EIP-712 domain. Defaults to 1 (mainnet).
109106
* @returns A Signer instance that uses EIP-712 signing
110107
*/
111-
export function fromWeb3(signer: Eip712Signer): Signer {
108+
export function fromWeb3(
109+
signer: Eip712Signer,
110+
options?: { chainId?: number },
111+
): Signer {
112+
const domain = {
113+
name: "NUC",
114+
version: "1",
115+
chainId: options?.chainId ?? 1,
116+
};
112117
return {
113118
// The Builder constructs the correct header and passes it into `sign`, so here we return a placeholder header
114-
header: NucHeaders.v1_eip712_delegation(NUC_EIP712_DOMAIN),
119+
header: NucHeaders.v1_eip712_delegation(domain),
115120
getDid: async () => ethr.fromAddress(await signer.getAddress()),
116121
sign: async (data: Uint8Array): Promise<Uint8Array> => {
117122
// The `data` is `rawHeader.rawPayload`. We must parse the header from it.
@@ -170,16 +175,17 @@ export namespace Signer {
170175
* it to the Signer interface.
171176
*
172177
* @param provider The Eip-1193 compatible provider, typically `window.ethereum`.
173-
* @param options Optional account address to use. If not provided, it will be requested from the wallet.
178+
* @param options.account Optional account address to use. If not provided, it will be requested from the wallet.
179+
* @param options.chain Optional chain to use. Defaults to mainnet. Must match the wallet's active chain.
174180
* @returns A Promise that resolves to a new `Signer` instance.
175181
* @throws If the provider is not available or the user rejects the connection request.
176182
*/
177183
export async function fromEip1193Provider(
178184
provider: EIP1193Provider,
179-
options?: { account?: `0x${string}` },
185+
options?: { account?: `0x${string}`; chain?: Chain },
180186
): Promise<Signer> {
181187
const client: WalletClient = createWalletClient({
182-
chain: mainnet, // Nuc Eip-712 signatures are chain-agnostic but viem requires one. Mainnet is a safe default.
188+
chain: options?.chain ?? mainnet,
183189
transport: custom(provider),
184190
});
185191

@@ -203,7 +209,9 @@ export namespace Signer {
203209
},
204210
};
205211

206-
return Signer.fromWeb3(eip712SignerAdapter);
212+
// Use the chain's ID from the options, or default to mainnet (1)
213+
const chainId = options?.chain?.id ?? 1;
214+
return Signer.fromWeb3(eip712SignerAdapter, { chainId });
207215
}
208216
}
209217

src/nuc/builder.ts

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { bytesToHex, randomBytes } from "@noble/hashes/utils.js";
2+
import type { TypedDataDomain } from "abitype";
23
import { DEFAULT_MAX_LIFETIME_MS, DEFAULT_NONCE_LENGTH } from "#/constants";
34
import type { Did } from "#/core/did/types";
45
import { base64UrlEncode } from "#/core/encoding";
@@ -256,9 +257,13 @@ abstract class AbstractBuilder {
256257
const payloadData = this._getPayloadData(issuer);
257258

258259
// Generate the correct EIP-712 header based on payload type.
260+
// Use the domain from the signer's header to preserve chainId.
259261
const header =
260262
signer.header.typ === NucHeaderType.EIP712
261-
? getEip712Header(payloadData)
263+
? getEip712Header(
264+
payloadData,
265+
signer.header.meta?.domain as TypedDataDomain | undefined,
266+
)
262267
: signer.header;
263268

264269
const rawHeader = base64UrlEncode(

0 commit comments

Comments
 (0)