Skip to content

Commit 34f43fa

Browse files
committed
Shared signature logic + move function defintions inside body
1 parent fa215bc commit 34f43fa

File tree

1 file changed

+79
-77
lines changed

1 file changed

+79
-77
lines changed
Lines changed: 79 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
import { type KMSClientConfig } from "@aws-sdk/client-kms";
22
import { KmsSigner } from "aws-kms-signer";
33
import type { Hex, ThirdwebClient } from "thirdweb";
4-
import { keccak256, type Address as TwAddress } from "thirdweb";
5-
import { eth_sendRawTransaction, getRpcClient } from "thirdweb/rpc";
4+
import {
5+
eth_sendRawTransaction,
6+
getRpcClient,
7+
keccak256,
8+
type Address as TwAddress,
9+
} from "thirdweb";
610
import { serializeTransaction } from "thirdweb/transaction";
711
import { toBytes } from "thirdweb/utils";
812
import { type Account } from "thirdweb/wallets";
@@ -39,82 +43,80 @@ export async function getAwsKmsAccount(
3943
const addressUnprefixed = await signer.getAddress();
4044
const address = `0x${addressUnprefixed}` as TwAddress;
4145

46+
async function signTransaction(tx: TransactionSerializable): Promise<Hex> {
47+
const serializedTx = serializeTransaction({ transaction: tx });
48+
const txHash = keccak256(serializedTx);
49+
const signature = await signer.sign(Buffer.from(txHash.slice(2), "hex"));
50+
51+
const r = `0x${signature.r.toString("hex")}` as Hex;
52+
const s = `0x${signature.s.toString("hex")}` as Hex;
53+
const v = signature.v;
54+
55+
const yParity = v % 2 === 0 ? 1 : (0 as 0 | 1);
56+
57+
const signedTx = serializeTransaction({
58+
transaction: tx,
59+
signature: {
60+
r,
61+
s,
62+
yParity,
63+
},
64+
});
65+
66+
return signedTx;
67+
}
68+
69+
async function signMessage({
70+
message,
71+
}: {
72+
message: SignableMessage;
73+
}): Promise<Hex> {
74+
let messageHash: Hex;
75+
if (typeof message === "string") {
76+
const prefixedMessage = `\x19Ethereum Signed Message:\n${message.length}${message}`;
77+
messageHash = keccak256(toBytes(prefixedMessage));
78+
} else if ("raw" in message) {
79+
messageHash = keccak256(message.raw);
80+
} else {
81+
throw new Error("Invalid message format");
82+
}
83+
84+
const signature = await signer.sign(
85+
Buffer.from(messageHash.slice(2), "hex"),
86+
);
87+
return `0x${signature.toString()}`;
88+
}
89+
90+
async function signTypedData<
91+
const typedData extends TypedData | Record<string, unknown>,
92+
primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
93+
>(_typedData: TypedDataDefinition<typedData, primaryType>): Promise<Hex> {
94+
const typedDataHash = hashTypedData(_typedData);
95+
const signature = await signer.sign(
96+
Buffer.from(typedDataHash.slice(2), "hex"),
97+
);
98+
return `0x${signature.toString()}`;
99+
}
100+
101+
async function sendTransaction(
102+
tx: SendTransactionOption,
103+
): Promise<SendTransactionResult> {
104+
const rpcRequest = getRpcClient({
105+
client: client,
106+
chain: await getChain(tx.chainId),
107+
});
108+
109+
const signedTx = await signTransaction(tx);
110+
111+
const transactionHash = await eth_sendRawTransaction(rpcRequest, signedTx);
112+
return { transactionHash };
113+
}
114+
42115
return {
43116
address,
44-
45-
sendTransaction: async (
46-
tx: SendTransactionOption,
47-
): Promise<SendTransactionResult> => {
48-
const rpcRequest = getRpcClient({
49-
client: client,
50-
chain: await getChain(tx.chainId),
51-
});
52-
53-
const serializedTx = serializeTransaction({ transaction: tx });
54-
const txHash = keccak256(serializedTx);
55-
const signature = await signer.sign(Buffer.from(txHash.slice(2), "hex"));
56-
57-
const r = `0x${signature.r.toString("hex")}` as Hex;
58-
const s = `0x${signature.s.toString("hex")}` as Hex;
59-
const v = signature.v;
60-
61-
const yParity = v % 2 === 0 ? 1 : (0 as 0 | 1);
62-
63-
const signedTx = serializeTransaction({
64-
transaction: tx,
65-
signature: {
66-
r,
67-
s,
68-
yParity,
69-
},
70-
});
71-
72-
const transactionHash = await eth_sendRawTransaction(
73-
rpcRequest,
74-
signedTx,
75-
);
76-
return { transactionHash };
77-
},
78-
79-
signMessage: async ({
80-
message,
81-
}: {
82-
message: SignableMessage;
83-
}): Promise<Hex> => {
84-
let messageHash: Hex;
85-
if (typeof message === "string") {
86-
const prefixedMessage = `\x19Ethereum Signed Message:\n${message.length}${message}`;
87-
messageHash = keccak256(toBytes(prefixedMessage));
88-
} else if ("raw" in message) {
89-
messageHash = keccak256(message.raw);
90-
} else {
91-
throw new Error("Invalid message format");
92-
}
93-
94-
const signature = await signer.sign(
95-
Buffer.from(messageHash.slice(2), "hex"),
96-
);
97-
return `0x${signature.toString()}`;
98-
},
99-
100-
signTypedData: async <
101-
const typedData extends TypedData | Record<string, unknown>,
102-
primaryType extends keyof typedData | "EIP712Domain" = keyof typedData,
103-
>(
104-
_typedData: TypedDataDefinition<typedData, primaryType>,
105-
): Promise<Hex> => {
106-
const typedDataHash = hashTypedData(_typedData);
107-
const signature = await signer.sign(
108-
Buffer.from(typedDataHash.slice(2), "hex"),
109-
);
110-
return `0x${signature.toString()}`;
111-
},
112-
113-
signTransaction: async (tx: TransactionSerializable): Promise<Hex> => {
114-
const serializedTx = serializeTransaction({ transaction: tx });
115-
const txHash = keccak256(serializedTx);
116-
const signature = await signer.sign(Buffer.from(txHash.slice(2), "hex"));
117-
return `0x${signature.toString()}`;
118-
},
117+
sendTransaction,
118+
signMessage,
119+
signTypedData,
120+
signTransaction,
119121
};
120122
}

0 commit comments

Comments
 (0)