Skip to content
Merged
21 changes: 15 additions & 6 deletions packages/thirdweb/src/utils/signatures/sign-message.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as ox__Hex from "ox/Hex";
import * as ox__PersonalMessage from "ox/PersonalMessage";
import * as ox__Secp256k1 from "ox/Secp256k1";
import * as ox__Signature from "ox/Signature";
import type { Account } from "../../wallets/interfaces/wallet.js";
import type { Hex } from "../encoding/hex.js";
import { hashMessage } from "../hashing/hashMessage.js";
import type { Prettify } from "../type-utils.js";
import { sign } from "./sign.js";
import { signatureToHex } from "./signature-to-hex.js";

type Message = Prettify<
| string
Expand Down Expand Up @@ -59,9 +60,17 @@ export function signMessage(
options: SignMessageOptions | { message: Message; account: Account },
): Hex | Promise<Hex> {
if ("privateKey" in options) {
const { message, privateKey } = options;
const signature = sign({ hash: hashMessage(message), privateKey });
return signatureToHex(signature);
const payload = ox__PersonalMessage.getSignPayload(
typeof options.message === "object"
? options.message.raw
: ox__Hex.fromString(options.message),
);

const signature = ox__Secp256k1.sign({
payload,
privateKey: options.privateKey,
});
return ox__Signature.toHex(signature);
}
if ("account" in options) {
const { message, account } = options;
Expand Down
28 changes: 15 additions & 13 deletions packages/thirdweb/src/utils/signatures/sign-typed-data.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import type { TypedData } from "abitype";
import { type TypedDataDefinition, hashTypedData } from "viem";
import type { Hex } from "../encoding/hex.js";
import { parseTypedData } from "./helpers/parseTypedData.js";
import { sign } from "./sign.js";
import { signatureToHex } from "./signature-to-hex.js";
import * as ox__TypedData from "ox/TypedData";
import * as ox__Secp256k1 from "ox/Secp256k1";
import * as ox__Hex from "ox/Hex";
import * as ox__Signature from "ox/Signature";

export type SignTypedDataOptions<
typedData extends TypedData | Record<string, unknown> = TypedData,
typedData extends
| ox__TypedData.TypedData
| Record<string, unknown> = ox__TypedData.TypedData,
primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
> = TypedDataDefinition<typedData, primaryType> & {
> = ox__TypedData.Definition<typedData, primaryType> & {
privateKey: Hex;
};

Expand All @@ -28,17 +29,18 @@ export type SignTypedDataOptions<
* @utils
*/
export function signTypedData<
const typedData extends TypedData | Record<string, unknown>,
const typedData extends ox__TypedData.TypedData | Record<string, unknown>,
primaryType extends keyof typedData | "EIP712Domain",
>(options: SignTypedDataOptions<typedData, primaryType>): Hex {
const { privateKey, ...typedData } =
options as unknown as SignTypedDataOptions;

const parsedTypeData = parseTypedData(typedData);
const payload = ox__TypedData.getSignPayload(typedData);

const signature = sign({
hash: hashTypedData(parsedTypeData), // TODO: Implement native hashTypedData
privateKey,
const signature = ox__Secp256k1.sign({
payload,
privateKey: ox__Hex.fromString(privateKey),
});
return signatureToHex(signature);

return ox__Signature.toHex(signature);
}
11 changes: 5 additions & 6 deletions packages/thirdweb/src/utils/signatures/sign.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { secp256k1 } from "@noble/curves/secp256k1";
import type { Signature } from "viem";
import * as ox__Secp256k1 from "ox/Secp256k1";

import { type Hex, toHex } from "../encoding/hex.js";

Expand Down Expand Up @@ -28,12 +27,12 @@ export type SignOptions = {
* ```
* @utils
*/
export function sign({ hash, privateKey }: SignOptions): Signature {
const { r, s, recovery } = secp256k1.sign(hash.slice(2), privateKey.slice(2));
export function sign({ hash, privateKey }: SignOptions) {
const { r, s, yParity } = ox__Secp256k1.sign({ payload: hash, privateKey });
return {
r: toHex(r, { size: 32 }),
s: toHex(s, { size: 32 }),
v: recovery ? 28n : 27n,
yParity: recovery,
v: yParity === 1 ? 28n : 27n,
yParity,
};
}
10 changes: 8 additions & 2 deletions packages/thirdweb/src/utils/signatures/signature-to-hex.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { secp256k1 } from "@noble/curves/secp256k1";
import type { Signature } from "viem";
import { type Hex, hexToBigInt } from "../encoding/hex.js";

// We can't migrate this to Ox without breaking changes since Ox does not support pre-EIP1559 signatures

/**
* Converts a signature to a hex string.
* @param signature The signature to convert.
Expand All @@ -25,7 +26,12 @@ import { type Hex, hexToBigInt } from "../encoding/hex.js";
* ```
* @utils
*/
export function signatureToHex(signature: Signature): Hex {
export function signatureToHex(signature: {
r: Hex;
s: Hex;
v?: bigint;
yParity?: number;
}): Hex {
const { r, s, v, yParity } = signature;
const yParity_ = (() => {
if (yParity === 0 || yParity === 1) return yParity;
Expand Down
Loading