Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SDK] Refactor: More Viem to Ox migration #5790

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/auto-assign.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Auto Author Assign

on:
pull_request:
types: [opened, reopened]
types: [opened, reopened, ready_for_review, draft]

permissions:
pull-requests: write
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,12 @@ export const AbiSelector: React.FC<AbiSelectorProps> = ({
options={options}
defaultValue={options.find((o) => o.value === defaultValue)}
chakraStyles={{
// @ts-expect-error - this works fine
container: (provided) => ({
...provided,
width: "full",
}),
}}
value={options.find((o) => o.value === value)}
// @ts-expect-error - this works fine
onChange={(selectedFn) => {
if (selectedFn) {
onChange((selectedFn as { label: string; value: string }).value);
Expand Down
4 changes: 2 additions & 2 deletions packages/thirdweb/src/auth/is-erc6492-signature.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { sliceHex } from "viem";
import * as ox__Hex from "ox/Hex";
import type { Hex } from "../utils/encoding/hex.js";
import { ERC_6492_MAGIC_VALUE } from "./constants.js";

Expand All @@ -19,5 +19,5 @@ import { ERC_6492_MAGIC_VALUE } from "./constants.js";
* @auth
*/
export function isErc6492Signature(signature: Hex): boolean {
return sliceHex(signature, -32) === ERC_6492_MAGIC_VALUE;
return ox__Hex.slice(signature, -32) === ERC_6492_MAGIC_VALUE;
}
14 changes: 10 additions & 4 deletions packages/thirdweb/src/auth/parse-erc6492-signature.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { decodeAbiParameters, isErc6492Signature } from "viem";
import * as ox__AbiParameters from "ox/AbiParameters";
import * as ox__Address from "ox/Address";
import { WrappedSignature as ox__WrappedSignature } from "ox/erc6492";
import type { Hex } from "../utils/encoding/hex.js";
import type { OneOf } from "../utils/type-utils.js";
import type { Erc6492Signature } from "./types.js";
Expand Down Expand Up @@ -29,13 +31,17 @@ export type ParseErc6492SignatureReturnType = OneOf<
export function parseErc6492Signature(
signature: Hex,
): ParseErc6492SignatureReturnType {
if (!isErc6492Signature(signature)) {
if (!ox__WrappedSignature.validate(signature)) {
return { signature };
}

const [address, data, originalSignature] = decodeAbiParameters(
const [address, data, originalSignature] = ox__AbiParameters.decode(
[{ type: "address" }, { type: "bytes" }, { type: "bytes" }],
signature,
);
return { address: address, data, signature: originalSignature };
return {
address: ox__Address.checksum(address),
data,
signature: originalSignature,
};
}
36 changes: 16 additions & 20 deletions packages/thirdweb/src/auth/verify-hash.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
import {
type Signature,
encodeDeployData,
encodeFunctionData,
isErc6492Signature,
serializeSignature,
universalSignatureValidatorAbi,
universalSignatureValidatorByteCode,
} from "viem";
import * as ox__Abi from "ox/Abi";
import * as ox__AbiConstructor from "ox/AbiConstructor";
import * as ox__AbiFunction from "ox/AbiFunction";
import * as ox__Signature from "ox/Signature";
import { WrappedSignature as ox__WrappedSignature } from "ox/erc6492";
import type { Chain } from "../chains/types.js";
import type { ThirdwebClient } from "../client/client.js";
import { type ThirdwebContract, getContract } from "../contract/contract.js";
Expand All @@ -20,7 +16,7 @@

export type VerifyHashParams = {
hash: Hex;
signature: string | Uint8Array | Signature;
signature: string | Uint8Array | ox__Signature.Signature;
address: string;
client: ThirdwebClient;
chain: Chain;
Expand Down Expand Up @@ -71,7 +67,7 @@
const signatureHex = (() => {
if (isHex(signature)) return signature;
if (typeof signature === "object" && "r" in signature && "s" in signature)
return serializeSignature(signature);
return ox__Signature.toHex(signature);
if (signature instanceof Uint8Array) return fromBytes(signature, "hex");
// We should never hit this but TS doesn't know that
throw new Error(
Expand All @@ -85,7 +81,7 @@
if (!accountFactory) return signatureHex;

// If this sigature was already wrapped for ERC-6492, carry on
if (isErc6492Signature(signatureHex)) return signatureHex;
if (ox__WrappedSignature.validate(signatureHex)) return signatureHex;

Check warning on line 84 in packages/thirdweb/src/auth/verify-hash.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/auth/verify-hash.ts#L84

Added line #L84 was not covered by tests

// Otherwise, serialize the signature for ERC-6492 validation
return serializeErc6492Signature({
Expand All @@ -100,23 +96,23 @@
data: Hex;
};
const zkSyncChain = await isZkSyncChain(chain);
const abi = ox__Abi.from(ox__WrappedSignature.universalSignatureValidatorAbi);
if (zkSyncChain) {
// zksync chains dont support deploying code with eth_call
// need to call a deployed contract instead
verificationData = {
to: ZKSYNC_VALIDATOR_ADDRESS,
data: encodeFunctionData({
abi: universalSignatureValidatorAbi,
functionName: "isValidSig",
args: [address, hash, wrappedSignature],
}),
data: ox__AbiFunction.encodeData(
ox__AbiFunction.fromAbi(abi, "isValidSig"),
[address, hash, wrappedSignature],
),

Check warning on line 108 in packages/thirdweb/src/auth/verify-hash.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/auth/verify-hash.ts#L105-L108

Added lines #L105 - L108 were not covered by tests
};
} else {
const validatorConstructor = ox__AbiConstructor.fromAbi(abi);
verificationData = {
data: encodeDeployData({
abi: universalSignatureValidatorAbi,
data: ox__AbiConstructor.encode(validatorConstructor, {
args: [address, hash, wrappedSignature],
bytecode: universalSignatureValidatorByteCode,
bytecode: ox__WrappedSignature.universalSignatureValidatorBytecode,
}),
};
}
Expand Down
50 changes: 43 additions & 7 deletions packages/thirdweb/src/auth/verify-signature.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,27 @@
import { type SignableMessage, type Signature, recoverAddress } from "viem";
import * as ox__Bytes from "ox/Bytes";
import * as ox__Hex from "ox/Hex";
import * as ox__Secp256k1 from "ox/Secp256k1";
import * as ox__Signature from "ox/Signature";
import type { Chain } from "../chains/types.js";
import type { ThirdwebClient } from "../client/client.js";
import { type Hex, isHex } from "../utils/encoding/hex.js";
import { hashMessage } from "../utils/hashing/hashMessage.js";
import type { Prettify } from "../utils/type-utils.js";
import { verifyHash } from "./verify-hash.js";

type Message = Prettify<
| string
| {
raw: Hex | Uint8Array;
}
>;

/**
* @auth
*/
export type VerifyEOASignatureParams = {
message: string | SignableMessage;
signature: string | Uint8Array | Signature;
message: string | Message;
signature: string | Uint8Array | ox__Signature.Signature;
address: string;
};

Expand Down Expand Up @@ -39,9 +49,9 @@
return false;
}

const recoveredAddress = await recoverAddress({
hash: messageHash,
signature: options.signature,
const recoveredAddress = ox__Secp256k1.recoverAddress({
payload: messageHash,
signature: ox__Signature.fromHex(options.signature),
});

if (recoveredAddress.toLowerCase() === options.address.toLowerCase()) {
Expand Down Expand Up @@ -103,9 +113,35 @@
accountFactory,
}: VerifyContractWalletSignatureParams) {
const messageHash = hashMessage(message);

const parsedSignature = (() => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this seems a bit scary? maybe add tests for these sub cases?

if (ox__Bytes.validate(signature)) {
const sig = ox__Signature.fromBytes(signature);
return {
r: ox__Hex.fromNumber(sig.r),
s: ox__Hex.fromNumber(sig.s),
yParity: sig.yParity,
};

Check warning on line 124 in packages/thirdweb/src/auth/verify-signature.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/auth/verify-signature.ts#L119-L124

Added lines #L119 - L124 were not covered by tests
} else if (typeof signature === "object") {
return {
r: ox__Hex.fromNumber(signature.r),
s: ox__Hex.fromNumber(signature.s),
yParity: signature.yParity,
};
}

Check warning on line 131 in packages/thirdweb/src/auth/verify-signature.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/auth/verify-signature.ts#L126-L131

Added lines #L126 - L131 were not covered by tests
return signature;
})();

return verifyHash({
hash: messageHash,
signature,
signature:
typeof parsedSignature === "string"
? parsedSignature
: {
r: ox__Hex.toBigInt(parsedSignature.r),
s: ox__Hex.toBigInt(parsedSignature.s),
yParity: parsedSignature.yParity,
},

Check warning on line 144 in packages/thirdweb/src/auth/verify-signature.ts

View check run for this annotation

Codecov / codecov/patch

packages/thirdweb/src/auth/verify-signature.ts#L140-L144

Added lines #L140 - L144 were not covered by tests
address,
client,
chain,
Expand Down
16 changes: 9 additions & 7 deletions packages/thirdweb/src/auth/verify-typed-data.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import type { Signature, TypedData, TypedDataDefinition } from "viem";
import { hashTypedData } from "viem";
import type * as ox__Signature from "ox/Signature";
import * as ox__TypedData from "ox/TypedData";
import type { Chain } from "../chains/types.js";
import type { ThirdwebClient } from "../client/client.js";
import type { Hex } from "../utils/encoding/hex.js";
import type { HashTypedDataParams } from "../utils/hashing/hashTypedData.js";
import { type VerifyHashParams, verifyHash } from "./verify-hash.js";

export type VerifyTypedDataParams<
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,
> = Omit<VerifyHashParams, "hash"> &
TypedDataDefinition<typedData, primaryType> & {
ox__TypedData.Definition<typedData, primaryType> & {
address: string;
signature: string | Uint8Array | Signature;
signature: string | Uint8Array | ox__Signature.Signature;
client: ThirdwebClient;
chain: Chain;
accountFactory?: {
Expand Down Expand Up @@ -80,7 +82,7 @@ export type VerifyTypedDataParams<
* @auth
*/
export async function verifyTypedData<
typedData extends TypedData | Record<string, unknown>,
typedData extends ox__TypedData.TypedData | Record<string, unknown>,
primaryType extends keyof typedData | "EIP712Domain",
>({
address,
Expand All @@ -93,7 +95,7 @@ export async function verifyTypedData<
primaryType,
types,
}: VerifyTypedDataParams<typedData, primaryType>): Promise<boolean> {
const messageHash = hashTypedData({
const messageHash = ox__TypedData.getSignPayload({
message,
domain,
primaryType,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getContractAddress } from "viem";
import * as ox__ContractAddress from "ox/ContractAddress";
import { getGasPrice } from "../../../gas/get-gas-price.js";
import { eth_getBalance } from "../../../rpc/actions/eth_getBalance.js";
import { eth_sendRawTransaction } from "../../../rpc/actions/eth_sendRawTransaction.js";
Expand Down Expand Up @@ -208,7 +208,7 @@ async function _getCreate2FactoryDeploymentInfo(
},
signature: SIGNATURE,
});
const create2FactoryAddress = getContractAddress({
const create2FactoryAddress = ox__ContractAddress.from({
from: deploymentTransaction.signerAddress,
nonce: 0n,
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { Abi } from "abitype";
import { decodeAbiParameters } from "viem";
import type * as ox__Abi from "ox/Abi";
import * as ox__AbiConstructor from "ox/AbiConstructor";
import * as ox__AbiParameters from "ox/AbiParameters";
import { eth_getTransactionByHash } from "../../rpc/actions/eth_getTransactionByHash.js";
import { getRpcClient } from "../../rpc/rpc.js";
import type { ThirdwebContract } from "../contract.js";
Expand All @@ -10,19 +11,9 @@ type FetchConstructorParamsOptions = {
contract: ThirdwebContract;
explorerApiUrl: string;
explorerApiKey: string;
abi: Abi;
abi: ox__Abi.Abi;
};

// TODO: move to abi helpers (?)
function extractConstructorParamsFromAbi(abi: Abi) {
for (const input of abi) {
if (input.type === "constructor") {
return input.inputs || [];
}
}
return [];
}

const RequestStatus = {
OK: "1",
NOTOK: "0",
Expand All @@ -37,7 +28,8 @@ const RequestStatus = {
export async function fetchConstructorParams(
options: FetchConstructorParamsOptions,
): Promise<string> {
const constructorParamTypes = extractConstructorParamsFromAbi(options.abi);
const abiConstructor = ox__AbiConstructor.fromAbi(options.abi);
const constructorParamTypes = ox__AbiParameters.from(abiConstructor.inputs);
if (constructorParamTypes.length === 0) {
return "";
}
Expand Down Expand Up @@ -114,7 +106,8 @@ export async function fetchConstructorParams(
try {
// sanity check that the constructor params are valid
// TODO: should we sanity check after each attempt?
decodeAbiParameters(constructorParamTypes, `0x${constructorArgs}`);

ox__AbiParameters.decode(constructorParamTypes, `0x${constructorArgs}`);
} catch {
throw new Error(
"Verifying this contract requires it to be published. Run `npx thirdweb publish` to publish this contract, then try again.",
Expand Down
11 changes: 6 additions & 5 deletions packages/thirdweb/src/event/types.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { AbiParameter, AbiParameterToPrimitiveType } from "abitype";
import type { Hex, LogTopic } from "viem";
import type * as ox__Hex from "ox/Hex";
import type { Log as ox__Log } from "ox/Log";
import type { Filter, MaybeRequired, Prettify } from "../utils/type-utils.js";

//////////////////////////////////////////////////////////////////////
Expand Down Expand Up @@ -83,11 +84,11 @@ type _HasUnnamedAbiParameter<TAbiParameters extends readonly AbiParameter[]> =
* @internal
*/
type LogTopicType<
TPrimitiveType = Hex,
TTopic extends LogTopic = LogTopic,
> = TTopic extends Hex
TPrimitiveType = ox__Hex.Hex,
TTopic extends ox__Log["topics"][0] = ox__Log["topics"][0],
> = TTopic extends ox__Hex.Hex
? TPrimitiveType
: TTopic extends Hex[]
: TTopic extends ox__Hex.Hex[]
? TPrimitiveType[]
: TTopic extends null
? null
Expand Down
2 changes: 1 addition & 1 deletion packages/thirdweb/src/exports/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ export { stringify } from "../utils/json.js";
// ------------------------------------------------
// values
// ------------------------------------------------
export { maxUint256 } from "viem";
export { maxUint256 } from "ox/Solidity";

// ------------------------------------------------
// jwt
Expand Down
Loading
Loading