Skip to content

Commit

Permalink
Use input as data in eth_sendTransaction
Browse files Browse the repository at this point in the history
  • Loading branch information
jiexi committed Apr 10, 2024
1 parent 7604ffb commit 90baaf9
Show file tree
Hide file tree
Showing 2 changed files with 115 additions and 4 deletions.
99 changes: 99 additions & 0 deletions src/wallet.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ describe('wallet', () => {
engine.push(createWalletMiddleware({ getAccounts, processTransaction }));
const txParams = {
from: testAddresses[0],
data: '0x0',
};

const payload = { method: 'eth_sendTransaction', params: [txParams] };
Expand Down Expand Up @@ -117,6 +118,103 @@ describe('wallet', () => {
);
});

it('processes transaction with data field but without input field', async () => {
const { engine } = createTestSetup();
const getAccounts = async () => testAddresses.slice(0, 2);
const witnessedTxParams: TransactionParams[] = [];
const processTransaction = async (_txParams: TransactionParams) => {
witnessedTxParams.push(_txParams);
return testTxHash;
};
engine.push(createWalletMiddleware({ getAccounts, processTransaction }));
const txParams = {
from: testAddresses[0],
data: '0x0',
};

const payload = { method: 'eth_sendTransaction', params: [txParams] };
const sendTxResponse = await pify(engine.handle).call(engine, payload);
const sendTxResult = sendTxResponse.result;
expect(sendTxResult).toBeDefined();
expect(sendTxResult).toStrictEqual(testTxHash);
expect(witnessedTxParams).toHaveLength(1);
expect(witnessedTxParams[0]).toStrictEqual(txParams);
});

it('processes transaction with input field but without data field', async () => {
const { engine } = createTestSetup();
const getAccounts = async () => testAddresses.slice(0, 2);
const witnessedTxParams: TransactionParams[] = [];
const processTransaction = async (_txParams: TransactionParams) => {
witnessedTxParams.push(_txParams);
return testTxHash;
};
engine.push(createWalletMiddleware({ getAccounts, processTransaction }));
const txParams = {
from: testAddresses[0],
input: '0x0',
};

const payload = { method: 'eth_sendTransaction', params: [txParams] };
const sendTxResponse = await pify(engine.handle).call(engine, payload);
const sendTxResult = sendTxResponse.result;
expect(sendTxResult).toBeDefined();
expect(sendTxResult).toStrictEqual(testTxHash);
expect(witnessedTxParams).toHaveLength(1);
expect(witnessedTxParams[0]).toStrictEqual({
from: txParams.from,
data: txParams.input,
});
});

it('processes transaction with matching input and data field', async () => {
const { engine } = createTestSetup();
const getAccounts = async () => testAddresses.slice(0, 2);
const witnessedTxParams: TransactionParams[] = [];
const processTransaction = async (_txParams: TransactionParams) => {
witnessedTxParams.push(_txParams);
return testTxHash;
};
engine.push(createWalletMiddleware({ getAccounts, processTransaction }));
const txParams = {
from: testAddresses[0],
data: '0x0',
input: '0x0',
};

const payload = { method: 'eth_sendTransaction', params: [txParams] };
const sendTxResponse = await pify(engine.handle).call(engine, payload);
const sendTxResult = sendTxResponse.result;
expect(sendTxResult).toBeDefined();
expect(sendTxResult).toStrictEqual(testTxHash);
expect(witnessedTxParams).toHaveLength(1);
expect(witnessedTxParams[0]).toStrictEqual({
from: txParams.from,
data: txParams.data,
});
});

it('throws when input and data fields are both defined but do not match', async () => {
const { engine } = createTestSetup();
const getAccounts = async () => testAddresses.slice(0, 2);
const witnessedTxParams: TransactionParams[] = [];
const processTransaction = async (_txParams: TransactionParams) => {
witnessedTxParams.push(_txParams);
return testTxHash;
};
engine.push(createWalletMiddleware({ getAccounts, processTransaction }));
const txParams = {
from: testAddresses[0],
data: '0x0',
input: '0x1',
};

const payload = { method: 'eth_sendTransaction', params: [txParams] };
await expect(pify(engine.handle).call(engine, payload)).rejects.toThrow(
new Error('Invalid input.'),
);
});

it('should not override other request params', async () => {
const { engine } = createTestSetup();
const getAccounts = async () => testAddresses.slice(0, 2);
Expand All @@ -129,6 +227,7 @@ describe('wallet', () => {
const txParams = {
from: testAddresses[0],
to: testAddresses[1],
data: '0x0',
};

const payload = { method: 'eth_sendTransaction', params: [txParams] };
Expand Down
20 changes: 16 additions & 4 deletions src/wallet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -159,10 +159,22 @@ WalletMiddlewareOptions): JsonRpcMiddleware<any, Block> {
throw rpcErrors.invalidInput();
}

const params = req.params[0] as TransactionParams | undefined;
const txParams: TransactionParams = {
...params,
from: await validateAndNormalizeKeyholder(params?.from || '', req),
const params = req.params[0] as
| (TransactionParams & {
input?: string;
data?: string;
})
| undefined;

const { from, data, input, ...restParams } = params || {};
if (data && input && data !== input) {
throw rpcErrors.invalidInput();
}

const txParams: TransactionParams & { data?: string } = {
...restParams,
data: data || input,
from: await validateAndNormalizeKeyholder(from || '', req),
};
res.result = await processTransaction(txParams, req);
}
Expand Down

0 comments on commit 90baaf9

Please sign in to comment.