diff --git a/.changeset/rude-vans-decide.md b/.changeset/rude-vans-decide.md new file mode 100644 index 0000000000..1e6ec80750 --- /dev/null +++ b/.changeset/rude-vans-decide.md @@ -0,0 +1,7 @@ +--- +"viem": minor +--- + +Removed CIP-42 support. + +Any transactions with feeCurrency field will be treated as CIP-64. diff --git a/src/celo/formatters.test.ts b/src/celo/formatters.test.ts index 90e83d3845..d7f5f2389c 100644 --- a/src/celo/formatters.test.ts +++ b/src/celo/formatters.test.ts @@ -568,12 +568,13 @@ describe('transaction', () => { describe('transactionRequest', () => { const { transactionRequest } = celo.formatters! - test('formatter cip42', () => { + test('formatter CIP-42 (removed, should produce CIP-64 when feeCurrency specified, EIP-1559 otherwise)', () => { expect( transactionRequest.format({ feeCurrency: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', from: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', gas: 1n, + // @ts-ignore gatewayFee: 4n, gatewayFeeRecipient: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', maxFeePerGas: 2n, @@ -586,12 +587,10 @@ describe('transactionRequest', () => { "feeCurrency": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "gas": "0x1", - "gatewayFee": "0x4", - "gatewayFeeRecipient": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "maxFeePerGas": "0x2", "maxPriorityFeePerGas": "0x1", "nonce": "0x1", - "type": "0x7c", + "type": "0x7b", "value": "0x1", } `) @@ -601,6 +600,7 @@ describe('transactionRequest', () => { feeCurrency: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', from: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', gas: 1n, + // @ts-ignore gatewayFeeRecipient: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', maxFeePerGas: 2n, maxPriorityFeePerGas: 1n, @@ -612,12 +612,10 @@ describe('transactionRequest', () => { "feeCurrency": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "gas": "0x1", - "gatewayFee": undefined, - "gatewayFeeRecipient": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "maxFeePerGas": "0x2", "maxPriorityFeePerGas": "0x1", "nonce": "0x1", - "type": "0x7c", + "type": "0x7b", "value": "0x1", } `) @@ -627,6 +625,7 @@ describe('transactionRequest', () => { feeCurrency: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', from: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', gas: 1n, + // @ts-ignore gatewayFee: 4n, gatewayFeeRecipient: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', maxFeePerGas: 2n, @@ -639,12 +638,10 @@ describe('transactionRequest', () => { "feeCurrency": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "gas": "0x1", - "gatewayFee": "0x4", - "gatewayFeeRecipient": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "maxFeePerGas": "0x2", "maxPriorityFeePerGas": "0x1", "nonce": "0x1", - "type": "0x7c", + "type": "0x7b", "value": "0x1", } `) @@ -654,6 +651,7 @@ describe('transactionRequest', () => { feeCurrency: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', from: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', gas: 1n, + // @ts-ignore gatewayFee: 4n, gatewayFeeRecipient: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', maxFeePerGas: 2n, @@ -666,12 +664,10 @@ describe('transactionRequest', () => { "feeCurrency": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "gas": "0x1", - "gatewayFee": "0x4", - "gatewayFeeRecipient": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "maxFeePerGas": "0x2", "maxPriorityFeePerGas": "0x1", "nonce": "0x1", - "type": "0x7c", + "type": "0x7b", "value": "0x1", } `) @@ -681,6 +677,7 @@ describe('transactionRequest', () => { feeCurrency: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', from: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', gas: 1n, + // @ts-ignore gatewayFee: 4n, gatewayFeeRecipient: '0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9', maxFeePerGas: 2n, @@ -693,12 +690,10 @@ describe('transactionRequest', () => { "feeCurrency": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "from": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "gas": "0x1", - "gatewayFee": "0x4", - "gatewayFeeRecipient": "0x0f16e9b0d03470827a95cdfd0cb8a8a3b46969b9", "maxFeePerGas": "0x2", "maxPriorityFeePerGas": "0x4", "nonce": "0x1", - "type": "0x7c", + "type": "0x7b", "value": "0x1", } `) diff --git a/src/celo/formatters.ts b/src/celo/formatters.ts index baaf3395e4..7f7c913842 100644 --- a/src/celo/formatters.ts +++ b/src/celo/formatters.ts @@ -2,7 +2,6 @@ import { type ChainFormatters } from '../types/chain.js' import type { Hash } from '../types/misc.js' import type { RpcTransaction } from '../types/rpc.js' import { hexToBigInt } from '../utils/encoding/fromHex.js' -import { numberToHex } from '../utils/encoding/toHex.js' import { defineBlock } from '../utils/formatters/block.js' import { defineTransaction, @@ -16,7 +15,7 @@ import type { CeloTransaction, CeloTransactionRequest, } from './types.js' -import { isCIP42, isCIP64 } from './utils.js' +import { isCIP64 } from './utils.js' export const formatters = { block: /*#__PURE__*/ defineBlock({ @@ -73,15 +72,8 @@ export const formatters = { feeCurrency: args.feeCurrency, } as CeloRpcTransactionRequest - if (isCIP64(args)) request.type = '0x7b' - else { - if (isCIP42(args)) request.type = '0x7c' - - request.gatewayFee = - typeof args.gatewayFee !== 'undefined' - ? numberToHex(args.gatewayFee) - : undefined - request.gatewayFeeRecipient = args.gatewayFeeRecipient + if (isCIP64(args)) { + request.type = '0x7b' } return request diff --git a/src/celo/getTransaction.test.ts b/src/celo/getTransaction.test.ts new file mode 100644 index 0000000000..2eedda059b --- /dev/null +++ b/src/celo/getTransaction.test.ts @@ -0,0 +1,94 @@ +import { describe, expect, test, vi } from 'vitest' +import { celo } from '../chains/index.js' +import { + type EIP1193RequestFn, + type PublicRpcSchema, + type WalletRpcSchema, + createPublicClient, + createTransport, +} from '../index.js' + +describe('getTransaction()', () => { + const transportRequestMock = vi.fn(async (request) => { + if (request.method === 'eth_getTransactionByHash') { + return { + hash: '0xb733188a557d376b29bd8fd7bbd9cbefea6beaa90b993bd967c3eab9826b1e59', + nonce: '0x23cb', + blockHash: + '0x81d734d38a2c62726a0ce029e3f0291c7c54cac35db7b1f60e558133c6f44d18', + blockNumber: '0xefa8eb', + transactionIndex: '0x2', + from: '0xeb350f3c0d8519ff63540c6f26950935f5b93efa', + to: '0x4aad04d41fd7fd495503731c5a2579e19054c432', + value: '0x0', + gas: '0x1d3c9', + maxFeePerGas: '0x83215600', + maxPriorityFeePerGas: '0x77359400', + input: + '0xa020c8de0000000000000000000000007550d8d538bc883c965dfac89a8c76de4a2672e3000000000000000000000000c8a81d473992c7c6d3f469a8263f24914625709d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005', + r: '0x198e15feb6f615c3ae9ba42e1721b518d391aa6b098005b03c6c4051f694bf0c', + s: '0x584546ab557daf99b3118f3efb0583d57cc9d3136bce0d436d0acc821eddddf1', + v: '0x1', + chainId: '0xa4ec', + accessList: [], + type: '0x7c', + ethCompatible: false, + feeCurrency: null, + gatewayFee: '0x0', + gatewayFeeRecipient: '0x7a41b0e608a6bcf8c8ad78671e175d6df7f71f95', + gasPrice: null, + } + } + return null + }) as EIP1193RequestFn + + const mockTransport = () => + createTransport({ + key: 'mock', + name: 'Mock Transport', + request: transportRequestMock, + type: 'mock', + }) + + const client = createPublicClient({ + transport: mockTransport, + chain: celo, + }) + + test('returns CIP-42 transaction', async () => { + expect( + await client.getTransaction({ + hash: '0xb733188a557d376b29bd8fd7bbd9cbefea6beaa90b993bd967c3eab9826b1e59', + }), + ).toMatchInlineSnapshot(` + { + "accessList": [], + "blockHash": "0x81d734d38a2c62726a0ce029e3f0291c7c54cac35db7b1f60e558133c6f44d18", + "blockNumber": 15706347n, + "chainId": 42220, + "ethCompatible": false, + "feeCurrency": null, + "from": "0xeb350f3c0d8519ff63540c6f26950935f5b93efa", + "gas": 119753n, + "gasPrice": undefined, + "gatewayFee": 0n, + "gatewayFeeRecipient": "0x7a41b0e608a6bcf8c8ad78671e175d6df7f71f95", + "hash": "0xb733188a557d376b29bd8fd7bbd9cbefea6beaa90b993bd967c3eab9826b1e59", + "input": "0xa020c8de0000000000000000000000007550d8d538bc883c965dfac89a8c76de4a2672e3000000000000000000000000c8a81d473992c7c6d3f469a8263f24914625709d00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005", + "maxFeePerBlobGas": undefined, + "maxFeePerGas": 2200000000n, + "maxPriorityFeePerGas": 2000000000n, + "nonce": 9163, + "r": "0x198e15feb6f615c3ae9ba42e1721b518d391aa6b098005b03c6c4051f694bf0c", + "s": "0x584546ab557daf99b3118f3efb0583d57cc9d3136bce0d436d0acc821eddddf1", + "to": "0x4aad04d41fd7fd495503731c5a2579e19054c432", + "transactionIndex": 2, + "type": "cip42", + "typeHex": "0x7c", + "v": 1n, + "value": 0n, + "yParity": 1, + } + `) + }) +}) diff --git a/src/celo/index.ts b/src/celo/index.ts index 82df65eddb..f79590c4d9 100644 --- a/src/celo/index.ts +++ b/src/celo/index.ts @@ -18,11 +18,9 @@ export type { CeloTransactionType, RpcTransactionCIP42, RpcTransactionCIP64, - RpcTransactionRequestCIP42, RpcTransactionRequestCIP64, TransactionCIP42, TransactionCIP64, - TransactionRequestCIP42, TransactionRequestCIP64, TransactionSerializableCIP42, TransactionSerializableCIP64, diff --git a/src/celo/parsers.test.ts b/src/celo/parsers.test.ts index c9fface4ed..c9f48cbe3e 100644 --- a/src/celo/parsers.test.ts +++ b/src/celo/parsers.test.ts @@ -10,10 +10,7 @@ import { } from '../index.js' import { parseTransaction } from './parsers.js' import { serializeTransaction } from './serializers.js' -import type { - TransactionSerializableCIP42, - TransactionSerializableCIP64, -} from './types.js' +import type { TransactionSerializableCIP64 } from './types.js' test('should be able to parse a cip42 transaction', () => { const signedTransaction = @@ -49,17 +46,12 @@ test('should return same result as standard parser when not CIP42 or CIP64', () }) describe('should parse a CIP42 transaction', () => { - const transactionWithGatewayFee = { - ...transaction, - chainId: 42270, - gatewayFee: parseEther('0.1'), - gatewayFeeRecipient: accounts[1].address, - } - test('with gatewayFee', () => { - const serialized = serializeTransaction(transactionWithGatewayFee) - - expect(parseTransaction(serialized)).toMatchInlineSnapshot(` + expect( + parseTransaction( + '0x7cf85282a51e82031184773594008477359400825209809470997970c51812dc3a010c7d01b50e0d17dc79c888016345785d8a00009490f79bf6eb2c4f870365e785982e1f101e93b906880de0b6b3a764000080c0', + ), + ).toMatchInlineSnapshot(` { "chainId": 42270, "gas": 21001n, @@ -74,23 +66,13 @@ describe('should parse a CIP42 transaction', () => { } `) }) - test('with access list', () => { - const transactionWithAccessList: TransactionSerializableCIP42 = { - ...transactionWithGatewayFee, - accessList: [ - { - address: '0x0000000000000000000000000000000000000000', - storageKeys: [ - '0x0000000000000000000000000000000000000000000000000000000000000001', - '0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe', - ], - }, - ], - } - const serialized = serializeTransaction(transactionWithAccessList) - - expect(parseTransaction(serialized)).toMatchInlineSnapshot(` + test('with access list', () => { + expect( + parseTransaction( + '0x7cf8ae82a51e82031184773594008477359400825209809470997970c51812dc3a010c7d01b50e0d17dc79c888016345785d8a00009490f79bf6eb2c4f870365e785982e1f101e93b906880de0b6b3a764000080f85bf859940000000000000000000000000000000000000000f842a00000000000000000000000000000000000000000000000000000000000000001a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe', + ), + ).toMatchInlineSnapshot(` { "accessList": [ { @@ -114,15 +96,13 @@ describe('should parse a CIP42 transaction', () => { } `) }) - test('with data as 0x', () => { - const transactionWithData: TransactionSerializableCIP42 = { - ...transactionWithGatewayFee, - data: '0x', - } - const serialized = serializeTransaction(transactionWithData) - - expect(parseTransaction(serialized)).toMatchInlineSnapshot(` + test('with data as 0x', () => { + expect( + parseTransaction( + '0x7cf85282a51e82031184773594008477359400825209809470997970c51812dc3a010c7d01b50e0d17dc79c888016345785d8a00009490f79bf6eb2c4f870365e785982e1f101e93b906880de0b6b3a764000080c0', + ), + ).toMatchInlineSnapshot(` { "chainId": 42270, "gas": 21001n, @@ -137,15 +117,13 @@ describe('should parse a CIP42 transaction', () => { } `) }) - test('with data', () => { - const transactionWithData: TransactionSerializableCIP42 = { - ...transactionWithGatewayFee, - data: '0x1234', - } - - const serialized = serializeTransaction(transactionWithData) - expect(parseTransaction(serialized)).toMatchInlineSnapshot(` + test('with data', () => { + expect( + parseTransaction( + '0x7cf85482a51e82031184773594008477359400825209809470997970c51812dc3a010c7d01b50e0d17dc79c888016345785d8a00009490f79bf6eb2c4f870365e785982e1f101e93b906880de0b6b3a7640000821234c0', + ), + ).toMatchInlineSnapshot(` { "chainId": 42270, "data": "0x1234", diff --git a/src/celo/sendTransaction.test.ts b/src/celo/sendTransaction.test.ts index f8c09a6487..0493efa1dd 100644 --- a/src/celo/sendTransaction.test.ts +++ b/src/celo/sendTransaction.test.ts @@ -86,7 +86,7 @@ describe('sendTransaction()', () => { }) }) - test('provides valid transaction params to sign for eth_sendRawTransaction (local account) for CIP-42', async () => { + test('provides valid transaction params to sign for eth_sendRawTransaction (local account) for CIP-42 - sending as CIP-64', async () => { const hash = await client.sendTransaction({ value: 1n, to: toAddress, @@ -99,7 +99,7 @@ describe('sendTransaction()', () => { expect(transportRequestMock).toHaveBeenLastCalledWith({ method: 'eth_sendRawTransaction', params: [ - '0x7cf88d82a4ec80010201940000000000000000000000000000000000000fee9400000000000000000000000000000000000000017b94f39fd6e51aad88f6f4ce6ab8827279cfffb922660180c080a049b4b40c685a0bf9e3d1cca92a9175382bfa3a5e1bbd65610abcb0bd28b4ad90a009b40f809939683763bec0943101c7a7c79ea60239fd0d73975f555e6777ee1d', + '0x7bf87782a4ec8001020194f39fd6e51aad88f6f4ce6ab8827279cfffb922660180c0940000000000000000000000000000000000000fee80a0a3163f9ff91200f4c8000f0217d85d16c329c2f38d48a7b4b70119989e475e57a0555fd5b2a6eac95426e33cd07ca5fec121ad46194611a013001f76bbc4b33136', ], }) }) diff --git a/src/celo/serializers.test.ts b/src/celo/serializers.test.ts index 10910a5c50..16a6d9df9c 100644 --- a/src/celo/serializers.test.ts +++ b/src/celo/serializers.test.ts @@ -40,204 +40,6 @@ const baseCip64 = { maxPriorityFeePerGas: parseGwei('2'), } as TransactionSerializableCIP64 -describe('cip42', () => { - test('should be able to serialize a cip42 transaction', () => { - // sanity checks the serialized value, but then rely on the parser - const serialized = serializeTransaction(baseCip42) - const reparsed = parseTransaction(serialized) - const reserialized = serializeTransaction(reparsed) - expect(serialized).toEqual( - '0x7cf85f82a4ec01847735940084773594008094765de816845861e75a25fca122bb6898b8b1282a9414dc79964da2c08b23698b3d3cc7ca32193d995585e8d60aa46794f39fd6e51aad88f6f4ce6ab8827279cfffb92266880de0b6b3a764000080c0', - ) - expect(reparsed).toEqual({ ...baseCip42, type: 'cip42' }) - expect(serialized).toEqual(reserialized) - }) - - test('args: accessList', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - accessList: [ - { - address: '0x0000000000000000000000000000000000000000', - storageKeys: [ - '0x0000000000000000000000000000000000000000000000000000000000000001', - '0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe', - ], - }, - ], - } - - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('args: data', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - data: '0x1234', - } - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('args: feeCurrency (absent)', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - gatewayFeeRecipient: accounts[0].address, - gatewayFee: parseEther('0.1'), - feeCurrency: undefined, - } - - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('args: gas', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - gas: 69420n, - } - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('args: gas (absent)', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - gas: undefined, - } - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('args: maxFeePerGas (absent)', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - maxFeePerGas: undefined, - type: 'cip42', - } - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('args: maxPriorityFeePerGas (absent)', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - maxPriorityFeePerGas: undefined, - type: 'cip42', - } - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('args: nonce (absent)', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - nonce: undefined, - } - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('args: to (absent)', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - to: undefined, - } - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('args: value (absent)', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - value: undefined, - } - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('type is undefined but has cip42 fields', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - type: undefined, - } - - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip42', - }) - }) - - test('signed', async () => { - const signed = await signTransaction({ - privateKey: accounts[0].privateKey, - transaction: baseCip42, - serializer: serializeTransaction, - }) - - const serialized = - '0x7cf8a282a4ec01847735940084773594008094765de816845861e75a25fca122bb6898b8b1282a9414dc79964da2c08b23698b3d3cc7ca32193d995585e8d60aa46794f39fd6e51aad88f6f4ce6ab8827279cfffb92266880de0b6b3a764000080c001a0430169754e015d53ccf07816d580ea968cbf1ccec6fcf45589507c7a38c0e685a00a66965256aee1476446f293f6b7db29ddcfe09eba707612d63e3b67035671fe' - expect(signed).toEqual(serialized) - expect(parseTransaction(signed)).toEqual({ - ...baseCip42, - type: 'cip42', - }) - }) - - test('signature', () => { - const tx1 = - '0x7cf8a282a4ec01847735940084773594008094765de816845861e75a25fca122bb6898b8b1282a9414dc79964da2c08b23698b3d3cc7ca32193d995585e8d60aa46794f39fd6e51aad88f6f4ce6ab8827279cfffb92266880de0b6b3a764000080c001a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe' - const tx2 = - '0x7cf8a282a4ec01847735940084773594008094765de816845861e75a25fca122bb6898b8b1282a9414dc79964da2c08b23698b3d3cc7ca32193d995585e8d60aa46794f39fd6e51aad88f6f4ce6ab8827279cfffb92266880de0b6b3a764000080c080a060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fea060fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe' - expect( - serializeTransaction( - baseCip42, - - { - r: '0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe', - s: '0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe', - yParity: 1, - }, - ), - ).toEqual(tx1) - expect( - serializeTransaction( - baseCip42, - - { - r: '0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe', - s: '0x60fdd29ff912ce880cd3edaf9f932dc61d3dae823ea77e0323f94adb9f6a72fe', - yParity: 0, - }, - ), - ).toEqual(tx2) - - expect(parseTransaction(tx1)).toEqual(parseTransaction(tx2)) - expect(parseTransaction(tx1)).toEqual({ ...baseCip42, type: 'cip42' }) - }) -}) - describe('cip64', () => { test('should be able to serialize a cip64 transaction', () => { // sanity checks the serialized value, but then rely on the parser @@ -419,53 +221,18 @@ describe('cip64', () => { expect(parseTransaction(tx1)).toEqual({ ...baseCip64, type: 'cip64' }) }) - test('CIP-42 transaction that has all CIP-64 fields and CIP-64 takes precedence', () => { + test('CIP-42 transaction should be discarded and sent as CIP-64', () => { const transaction: TransactionSerializableCIP42 = { ...baseCip42, - gatewayFeeRecipient: undefined, - gatewayFee: undefined, type: 'cip42', } - expect(parseTransaction(serializeTransaction(transaction))).toEqual({ - ...transaction, - type: 'cip64', - }) - }) -}) -describe('invalid params specific to CIP-42', () => { - const baseCip42WithType = { - ...baseCip42, - type: 'cip42', - } as const - test('only one of the gateWayFee fields is defined', () => { - const transactionA: TransactionSerializableCIP42 = { - ...baseCip42WithType, - gatewayFee: undefined, - gatewayFeeRecipient: accounts[7].address, - } - expect(() => serializeTransaction(transactionA)).toThrowError( - '`gatewayFee` and `gatewayFeeRecipient` must be provided together.', - ) - const transactionB: TransactionSerializableCIP42 = { - ...baseCip42WithType, - gatewayFee: 1000023434343n, - gatewayFeeRecipient: undefined, - } - expect(() => serializeTransaction(transactionB)).toThrowError( - '`gatewayFee` and `gatewayFeeRecipient` must be provided together.', - ) - }) - test('transaction looks like cip42 but does not have values for either feeCurrency or gatewayFee', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42WithType, - feeCurrency: undefined, + expect(parseTransaction(serializeTransaction(transaction as any))).toEqual({ + ...transaction, gatewayFee: undefined, gatewayFeeRecipient: undefined, - } - expect(() => serializeTransaction(transaction)).toThrowError( - 'Either `feeCurrency` or `gatewayFeeRecipient` must be provided for CIP-42 transactions.', - ) + type: 'cip64', + }) }) }) @@ -482,86 +249,6 @@ describe('invalid params specific to CIP-64', () => { }) }) -describe('Common invalid params (for CIP-42)', () => { - test('invalid to', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - to: '0xdeadbeef', - } - expect(() => serializeTransaction(transaction)).toThrowError( - InvalidAddressError, - ) - }) - - test('gatewayFeeRecipient is not an address', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - type: 'cip42', - // @ts-expect-error - (Type '"example"' is not assignable to type "`0x${string}"' - gatewayFeeRecipient: 'example', - } - expect(() => serializeTransaction(transaction)).toThrowError( - InvalidAddressError, - ) - }) - - test('maxFeePerGas is too high', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - maxFeePerGas: 2n ** 257n, - } - expect(() => serializeTransaction(transaction)).toThrowError( - FeeCapTooHighError, - ) - }) - - test('feeCurrency is not an address', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - // @ts-expect-error - (Type '"CUSD"' is not assignable to type "`0x${string}"' - feeCurrency: 'CUSD', - } - - expect(() => serializeTransaction(transaction)).toThrowError( - '`feeCurrency` MUST be a token address for CIP-42 transactions.', - ) - }) - - test('gasPrice is defined', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - // @ts-expect-error - gasPrice: BigInt(1), - } - - expect(() => serializeTransaction(transaction)).toThrowError( - '`gasPrice` is not a valid CIP-42 Transaction attribute.', - ) - }) - - test('chainID is invalid', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - chainId: -1, - } - - expect(() => serializeTransaction(transaction)).toThrowError( - `Chain ID "${-1}" is invalid.`, - ) - }) - - test('maxPriorityFeePerGas is higher than maxPriorityFee', () => { - const transaction: TransactionSerializableCIP42 = { - ...baseCip42, - maxPriorityFeePerGas: parseGwei('5000000000'), - maxFeePerGas: parseGwei('1'), - } - expect(() => serializeTransaction(transaction)).toThrowError( - TipAboveFeeCapError, - ) - }) -}) - describe('Common invalid params (for CIP-64)', () => { test('invalid to', () => { const transaction: TransactionSerializableCIP64 = { diff --git a/src/celo/serializers.ts b/src/celo/serializers.ts index 52db6c4ed0..243403557b 100644 --- a/src/celo/serializers.ts +++ b/src/celo/serializers.ts @@ -17,10 +17,9 @@ import type { CeloTransactionSerializable, TransactionSerializableCIP42, TransactionSerializableCIP64, - TransactionSerializedCIP42, TransactionSerializedCIP64, } from './types.js' -import { isCIP42, isCIP64, isEmpty, isPresent } from './utils.js' +import { isCIP64, isEmpty, isPresent } from './utils.js' export function serializeTransaction( transaction: CeloTransactionSerializable, @@ -28,8 +27,7 @@ export function serializeTransaction( ) { if (isCIP64(transaction)) return serializeTransactionCIP64(transaction, signature) - if (isCIP42(transaction)) - return serializeTransactionCIP42(transaction, signature) + return serializeTransaction_(transaction, signature) } @@ -40,54 +38,8 @@ export const serializers = { ////////////////////////////////////////////////////////////////////////////// // Serializers -export type SerializeTransactionCIP42ReturnType = TransactionSerializedCIP42 export type SerializeTransactionCIP64ReturnType = TransactionSerializedCIP64 -// There shall be a typed transaction with the code 0x7c that has the following format: -// 0x7c || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, feecurrency, gatewayFeeRecipient, gatewayfee, destination, amount, data, access_list, signature_y_parity, signature_r, signature_s]). -// This will be in addition to the type 0x02 transaction as specified in EIP-1559. -function serializeTransactionCIP42( - transaction: TransactionSerializableCIP42, - signature?: Signature | undefined, -): SerializeTransactionCIP42ReturnType { - assertTransactionCIP42(transaction) - const { - chainId, - gas, - nonce, - to, - value, - maxFeePerGas, - maxPriorityFeePerGas, - accessList, - feeCurrency, - gatewayFeeRecipient, - gatewayFee, - data, - } = transaction - - const serializedTransaction = [ - toHex(chainId), - nonce ? toHex(nonce) : '0x', - maxPriorityFeePerGas ? toHex(maxPriorityFeePerGas) : '0x', - maxFeePerGas ? toHex(maxFeePerGas) : '0x', - gas ? toHex(gas) : '0x', - feeCurrency ?? '0x', - gatewayFeeRecipient ?? '0x', - gatewayFee ? toHex(gatewayFee) : '0x', - to ?? '0x', - value ? toHex(value) : '0x', - data ?? '0x', - serializeAccessList(accessList), - ...toYParitySignatureArray(transaction, signature), - ] - - return concatHex([ - '0x7c', - toRlp(serializedTransaction), - ]) as SerializeTransactionCIP42ReturnType -} - function serializeTransactionCIP64( transaction: TransactionSerializableCIP64, signature?: Signature | undefined, diff --git a/src/celo/types.ts b/src/celo/types.ts index 65dd3d47e5..eba8a882f6 100644 --- a/src/celo/types.ts +++ b/src/celo/types.ts @@ -76,7 +76,6 @@ export type CeloRpcTransaction = export type CeloRpcTransactionRequest = | RpcTransactionRequest - | RpcTransactionRequestCIP42 | RpcTransactionRequestCIP64 export type CeloTransaction = @@ -86,13 +85,10 @@ export type CeloTransaction = export type CeloTransactionRequest = | TransactionRequest - | TransactionRequestCIP42 | TransactionRequestCIP64 export type CeloTransactionSerializable = OneOf< - | TransactionSerializable - | TransactionSerializableCIP42 - | TransactionSerializableCIP64 + TransactionSerializable | TransactionSerializableCIP64 > export type CeloTransactionSerialized< @@ -113,8 +109,6 @@ type RpcTransaction = type RpcTransactionRequest = RpcTransactionRequest_ & { feeCurrency?: Address | undefined - gatewayFee?: Hex | undefined - gatewayFeeRecipient?: Address | undefined } export type RpcTransactionCIP42 = Omit< @@ -139,18 +133,6 @@ export type RpcTransactionCIP64 = Omit< type: '0x7b' } -export type RpcTransactionRequestCIP42 = TransactionRequestBase< - Quantity, - Index -> & - ExactPartial> & { - accessList?: AccessList | undefined - feeCurrency?: Address | undefined - gatewayFee?: Hex | undefined - gatewayFeeRecipient?: Address | undefined - type?: '0x7c' | undefined - } - export type RpcTransactionRequestCIP64 = TransactionRequestBase< Quantity, Index @@ -158,8 +140,6 @@ export type RpcTransactionRequestCIP64 = TransactionRequestBase< ExactPartial> & { accessList?: AccessList | undefined feeCurrency?: Address | undefined - gatewayFee?: undefined - gatewayFeeRecipient?: undefined type?: '0x7b' | undefined } @@ -169,8 +149,8 @@ type Transaction = Transaction_< TPending > & { feeCurrency: Address | null - gatewayFee: bigint | null - gatewayFeeRecipient: Address | null + gatewayFee?: undefined + gatewayFeeRecipient?: undefined } export type TransactionCIP42 = @@ -193,25 +173,12 @@ export type TransactionCIP64 = type TransactionRequest = TransactionRequest_ & { feeCurrency?: Address | undefined - gatewayFee?: bigint | undefined - gatewayFeeRecipient?: Address | undefined } -export type TransactionRequestCIP42 = TransactionRequestBase & - ExactPartial & { - accessList?: AccessList | undefined - feeCurrency?: Address | undefined - gatewayFee?: bigint | undefined - gatewayFeeRecipient?: Address | undefined - type?: 'cip42' | undefined - } - export type TransactionRequestCIP64 = TransactionRequestBase & ExactPartial & { accessList?: AccessList | undefined feeCurrency?: Address | undefined - gatewayFee?: undefined - gatewayFeeRecipient?: undefined type?: 'cip64' | undefined } @@ -235,8 +202,6 @@ export type TransactionSerializableCIP64< ExactPartial> & { accessList?: AccessList | undefined feeCurrency?: Address | undefined - gatewayFee?: undefined - gatewayFeeRecipient?: undefined chainId: number type?: 'cip64' | undefined } diff --git a/src/celo/utils.test.ts b/src/celo/utils.test.ts index 76c2452114..64cf855d72 100644 --- a/src/celo/utils.test.ts +++ b/src/celo/utils.test.ts @@ -1,7 +1,7 @@ import { randomBytes } from 'crypto' import type { Address } from 'abitype' import { beforeEach, describe, expect, test } from 'vitest' -import { isCIP42, isCIP64, isEIP1559, isEmpty, isPresent } from './utils.js' +import { isCIP64, isEIP1559, isEmpty, isPresent } from './utils.js' let mockAddress: Address @@ -117,91 +117,6 @@ describe('isEIP1559', () => { }) }) -describe('isCIP42', () => { - test('it allows forcing the type even if transaction is not EIP-1559', () => { - expect( - isCIP42({ - type: 'cip42', - maxFeePerGas: 0n, - maxPriorityFeePerGas: 0n, - from: mockAddress, - }), - ).toBe(true) - }) - - test('it recognizes valid CIP-42 without forced type', () => { - expect( - isCIP42({ - feeCurrency: mockAddress, - gatewayFeeRecipient: mockAddress, - gatewayFee: 789n, - maxFeePerGas: 123n, - maxPriorityFeePerGas: 456n, - from: mockAddress, - }), - ).toBe(true) - - expect( - isCIP42({ - feeCurrency: mockAddress, - maxFeePerGas: 123n, - maxPriorityFeePerGas: 456n, - from: mockAddress, - }), - ).toBe(true) - - expect( - isCIP42({ - gatewayFeeRecipient: mockAddress, - maxFeePerGas: 123n, - maxPriorityFeePerGas: 456n, - from: mockAddress, - }), - ).toBe(true) - - expect( - isCIP42({ - gatewayFee: 789n, - maxFeePerGas: 123n, - maxPriorityFeePerGas: 456n, - from: mockAddress, - }), - ).toBe(true) - }) - - test('it does not recognize valid CIP-42', () => { - expect(isCIP42({})).toBe(false) - - expect( - isCIP42({ - feeCurrency: '0x', - gatewayFeeRecipient: '0x', - gatewayFee: 0n, - maxFeePerGas: 123n, - maxPriorityFeePerGas: 456n, - from: mockAddress, - }), - ).toBe(false) - - expect( - isCIP42({ - maxFeePerGas: 123n, - maxPriorityFeePerGas: 456n, - from: mockAddress, - }), - ).toBe(false) - - expect( - isCIP42({ - feeCurrency: mockAddress, - gatewayFeeRecipient: mockAddress, - gatewayFee: 789n, - from: mockAddress, - }), - ).toBe(false) - }) -}) - describe('isCIP64', () => { test('it allows forcing the type even if transaction is not EIP-1559', () => { expect( @@ -218,8 +133,6 @@ describe('isCIP64', () => { expect( isCIP64({ feeCurrency: mockAddress, - gatewayFeeRecipient: '0x', - gatewayFee: 0n, maxFeePerGas: 123n, maxPriorityFeePerGas: 456n, from: mockAddress, @@ -241,8 +154,6 @@ describe('isCIP64', () => { isCIP64({ type: 'eip1559', feeCurrency: mockAddress, - gatewayFeeRecipient: '0x', - gatewayFee: 0n, maxFeePerGas: 123n, maxPriorityFeePerGas: 456n, from: mockAddress, diff --git a/src/celo/utils.ts b/src/celo/utils.ts index ccc7204188..d16552b7a0 100644 --- a/src/celo/utils.ts +++ b/src/celo/utils.ts @@ -3,7 +3,6 @@ import { trim } from '../utils/data/trim.js' import type { CeloTransactionRequest, CeloTransactionSerializable, - TransactionSerializableCIP42, TransactionSerializableCIP64, } from './types.js' @@ -38,23 +37,6 @@ export function isEIP1559( ) } -// process as CIP42 if any of these fields are present. realistically gatewayfee is not used but is part of spec -export function isCIP42( - transaction: CeloTransactionSerializable | CeloTransactionRequest, -): transaction is TransactionSerializableCIP42 { - // Enable end-user to force the tx to be considered as a cip42 - if (transaction.type === 'cip42') { - return true - } - - return ( - isEIP1559(transaction) && - (isPresent(transaction.feeCurrency) || - isPresent(transaction.gatewayFeeRecipient) || - isPresent(transaction.gatewayFee)) - ) -} - export function isCIP64( transaction: CeloTransactionSerializable | CeloTransactionRequest, ): transaction is TransactionSerializableCIP64 { @@ -72,10 +54,5 @@ export function isCIP64( return true } - return ( - isEIP1559(transaction) && - isPresent(transaction.feeCurrency) && - isEmpty(transaction.gatewayFee) && - isEmpty(transaction.gatewayFeeRecipient) - ) + return isEIP1559(transaction) && isPresent(transaction.feeCurrency) } diff --git a/src/chains/index.ts b/src/chains/index.ts index 20f08b9e78..6f60619dea 100644 --- a/src/chains/index.ts +++ b/src/chains/index.ts @@ -289,11 +289,9 @@ export type { CeloTransactionSerialized, RpcTransactionCIP42, RpcTransactionCIP64, - RpcTransactionRequestCIP42, RpcTransactionRequestCIP64, TransactionCIP42, TransactionCIP64, - TransactionRequestCIP42, TransactionRequestCIP64, TransactionSerializableCIP42, TransactionSerializableCIP64,