|
1 | 1 | import type { ProviderInterface } from "@coinbase/wallet-sdk"; |
| 2 | +import * as ox__Hex from "ox/Hex"; |
| 3 | +import * as ox__TypedData from "ox/TypedData"; |
2 | 4 | import { beforeEach, describe, expect, test, vi } from "vitest"; |
3 | | -import {} from "../../chains/utils.js"; |
4 | 5 | import { COINBASE } from "../constants.js"; |
5 | 6 | import type { Wallet } from "../interfaces/wallet.js"; |
6 | 7 | import { |
@@ -41,6 +42,21 @@ vi.mock("../../utils/normalizeChainId.js", () => ({ |
41 | 42 | normalizeChainId: vi.fn((chainId) => Number(chainId)), |
42 | 43 | })); |
43 | 44 |
|
| 45 | +vi.mock("ox/Hex", async () => { |
| 46 | + const actualModule = await vi.importActual("ox/Hex"); |
| 47 | + return { |
| 48 | + ...actualModule, |
| 49 | + validate: vi.fn(() => true), |
| 50 | + toNumber: vi.fn((hex) => Number.parseInt(hex, 16)), |
| 51 | + }; |
| 52 | +}); |
| 53 | + |
| 54 | +vi.mock("ox/TypedData", () => ({ |
| 55 | + extractEip712DomainTypes: vi.fn(() => []), |
| 56 | + validate: vi.fn(), |
| 57 | + serialize: vi.fn(() => "serializedData"), |
| 58 | +})); |
| 59 | + |
44 | 60 | describe("Coinbase Web", () => { |
45 | 61 | let provider: ProviderInterface; |
46 | 62 |
|
@@ -102,4 +118,59 @@ describe("Coinbase Web", () => { |
102 | 118 | expect(account.address).toBe("0x123"); |
103 | 119 | expect(chain.id).toBe(1); |
104 | 120 | }); |
| 121 | + |
| 122 | + test("signMessage uses ox__Hex for validation", async () => { |
| 123 | + const account = { |
| 124 | + address: "0x123", |
| 125 | + signMessage: async ({ message }: { message: string }) => { |
| 126 | + const messageToSign = `0x${ox__Hex.fromString(message)}`; |
| 127 | + const res = await provider.request({ |
| 128 | + method: "personal_sign", |
| 129 | + params: [messageToSign, account.address], |
| 130 | + }); |
| 131 | + expect(ox__Hex.validate(res)).toBe(true); |
| 132 | + return res; |
| 133 | + }, |
| 134 | + }; |
| 135 | + |
| 136 | + provider.request = vi.fn().mockResolvedValue("0xsignature"); |
| 137 | + const signature = await account.signMessage({ message: "hello" }); |
| 138 | + expect(signature).toBe("0xsignature"); |
| 139 | + }); |
| 140 | + |
| 141 | + test("signTypedData uses ox__TypedData for serialization", async () => { |
| 142 | + const account = { |
| 143 | + address: "0x123", |
| 144 | + // biome-ignore lint/suspicious/noExplicitAny: Inside tests |
| 145 | + signTypedData: async (typedData: any) => { |
| 146 | + const { domain, message, primaryType } = typedData; |
| 147 | + const types = { |
| 148 | + EIP712Domain: ox__TypedData.extractEip712DomainTypes(domain), |
| 149 | + ...typedData.types, |
| 150 | + }; |
| 151 | + ox__TypedData.validate({ domain, message, primaryType, types }); |
| 152 | + const stringifiedData = ox__TypedData.serialize({ |
| 153 | + domain: domain ?? {}, |
| 154 | + message, |
| 155 | + primaryType, |
| 156 | + types, |
| 157 | + }); |
| 158 | + const res = await provider.request({ |
| 159 | + method: "eth_signTypedData_v4", |
| 160 | + params: [account.address, stringifiedData], |
| 161 | + }); |
| 162 | + expect(ox__Hex.validate(res)).toBe(true); |
| 163 | + return res; |
| 164 | + }, |
| 165 | + }; |
| 166 | + |
| 167 | + provider.request = vi.fn().mockResolvedValue("0xsignature"); |
| 168 | + const signature = await account.signTypedData({ |
| 169 | + domain: {}, |
| 170 | + message: {}, |
| 171 | + primaryType: "EIP712Domain", |
| 172 | + types: {}, |
| 173 | + }); |
| 174 | + expect(signature).toBe("0xsignature"); |
| 175 | + }); |
105 | 176 | }); |
0 commit comments