From 774cfb1d5b979ae75a3cfa86fa9b44fa112ddf59 Mon Sep 17 00:00:00 2001 From: khanti42 Date: Wed, 23 Oct 2024 15:40:38 +0200 Subject: [PATCH] fix(get-starknet): fix undefined params handling in `formatters` utils (#403) * chore: fix missing access to requestParams in call to revamped rpc * chore: fix on off event should not throw * chore: fix formatter when undefined input * chore: handle comments * chore: fix comments * chore: fix comments * chore: fix comments * chore: fix comments * chore: remove dep from starknet-types-07 * Update packages/get-starknet/src/utils/formatter.test.ts Co-authored-by: Stanley Yuen <102275989+stanleyyconsensys@users.noreply.github.com> * Update packages/get-starknet/src/utils/formatter.test.ts Co-authored-by: Stanley Yuen <102275989+stanleyyconsensys@users.noreply.github.com> * Update packages/get-starknet/src/utils/formatter.test.ts Co-authored-by: Stanley Yuen <102275989+stanleyyconsensys@users.noreply.github.com> * Update packages/get-starknet/src/utils/formatter.test.ts Co-authored-by: Stanley Yuen <102275989+stanleyyconsensys@users.noreply.github.com> --------- Co-authored-by: Stanley Yuen <102275989+stanleyyconsensys@users.noreply.github.com> --- packages/get-starknet/src/rpcs/add-declare.ts | 4 +- packages/get-starknet/src/rpcs/add-invoke.ts | 4 +- .../get-starknet/src/utils/formatter.test.ts | 51 +++++++++++++++++-- packages/get-starknet/src/utils/formatter.ts | 40 +++++++-------- 4 files changed, 68 insertions(+), 31 deletions(-) diff --git a/packages/get-starknet/src/rpcs/add-declare.ts b/packages/get-starknet/src/rpcs/add-declare.ts index af2ce2e7..06d7fd96 100644 --- a/packages/get-starknet/src/rpcs/add-declare.ts +++ b/packages/get-starknet/src/rpcs/add-declare.ts @@ -4,11 +4,11 @@ import { formatDeclareTransaction } from '../utils/formatter'; import { StarknetWalletRpc } from '../utils/rpc'; export type WalletAddDeclareTransactionMethod = 'wallet_addDeclareTransaction'; -type Params = RpcTypeToMessageMap[WalletAddDeclareTransactionMethod]['params']; +export type AddDeclareParams = RpcTypeToMessageMap[WalletAddDeclareTransactionMethod]['params']; type Result = RpcTypeToMessageMap[WalletAddDeclareTransactionMethod]['result']; export class WalletAddDeclareTransaction extends StarknetWalletRpc { - async handleRequest(params: Params): Promise { + async handleRequest(params: AddDeclareParams): Promise { return await this.snap.declare({ senderAddress: this.wallet.selectedAddress, contractPayload: formatDeclareTransaction(params), diff --git a/packages/get-starknet/src/rpcs/add-invoke.ts b/packages/get-starknet/src/rpcs/add-invoke.ts index 585dc676..ca415203 100644 --- a/packages/get-starknet/src/rpcs/add-invoke.ts +++ b/packages/get-starknet/src/rpcs/add-invoke.ts @@ -4,11 +4,11 @@ import { formatCalls } from '../utils/formatter'; import { StarknetWalletRpc } from '../utils/rpc'; export type WalletAddInvokeTransactionMethod = 'wallet_addInvokeTransaction'; -type Params = RpcTypeToMessageMap[WalletAddInvokeTransactionMethod]['params']; +export type AddInvokeTransactionParams = RpcTypeToMessageMap[WalletAddInvokeTransactionMethod]['params']; type Result = RpcTypeToMessageMap[WalletAddInvokeTransactionMethod]['result']; export class WalletAddInvokeTransaction extends StarknetWalletRpc { - async handleRequest(params: Params): Promise { + async handleRequest(params: AddInvokeTransactionParams): Promise { const { calls } = params; return await this.snap.execute({ address: this.wallet.selectedAddress, diff --git a/packages/get-starknet/src/utils/formatter.test.ts b/packages/get-starknet/src/utils/formatter.test.ts index a63bf1ff..16829ab5 100644 --- a/packages/get-starknet/src/utils/formatter.test.ts +++ b/packages/get-starknet/src/utils/formatter.test.ts @@ -60,6 +60,12 @@ describe('formatCalls', () => { expect(result).toStrictEqual(expected); }); + + it('returns undefined if the `calls` is undefined', () => { + const result = formatCalls(undefined as unknown as any); + + expect(result).toBeUndefined(); + }); }); /* eslint-disable @typescript-eslint/naming-convention */ @@ -119,11 +125,48 @@ describe('formatDeclareTransaction', () => { expect(result).toStrictEqual(expected); }); - it('remains `class_hash` undefined if it is undefined', () => { - const params = generateDeclareTransactionParams({ classHash: undefined }); - const expected = generateExpectedDeclareTransactionPayload({ classHash: undefined }); + it('returns undefined if the `AddDeclareParams` is undefined', () => { + const result = formatDeclareTransaction(undefined as any); - const result = formatDeclareTransaction(params); + expect(result).toBeUndefined(); + }); + + it.each([ + { + fieldName: 'compiled_class_hash', + paramKey: 'compiledClassHash', + }, + { + fieldName: 'class_hash', + paramKey: 'classHash', + }, + { + fieldName: 'contract_class', + paramKey: 'contract', + }, + ])('remains undefined if the field - $fieldName is undefined', ({ fieldName, paramKey }) => { + const params = generateDeclareTransactionParams(); + + // Dynamically set the field to undefined + params[fieldName] = undefined as any; + const expected = generateExpectedDeclareTransactionPayload(); + + // Dynamically set the expected field to undefined + expected[paramKey] = undefined as any; + + const result = formatDeclareTransaction(params as unknown as any); + + expect(result).toStrictEqual(expected); + }); + + it('returns undefined if the `AddDeclareParams` is {}', () => { + const expected = { + classHash: undefined, + compiledClassHash: undefined, + contract: undefined, + }; + + const result = formatDeclareTransaction({} as unknown as any); expect(result).toStrictEqual(expected); }); diff --git a/packages/get-starknet/src/utils/formatter.ts b/packages/get-starknet/src/utils/formatter.ts index 8f0a9195..bdf15b01 100644 --- a/packages/get-starknet/src/utils/formatter.ts +++ b/packages/get-starknet/src/utils/formatter.ts @@ -1,7 +1,9 @@ /* eslint-disable @typescript-eslint/naming-convention, camelcase */ -import type { Abi, Call, DeclareContractPayload } from 'starknet'; -import type { AddDeclareTransactionParameters, Call as CallGetStarknetV4 } from 'starknet-types-07'; +import type { Call, DeclareContractPayload } from 'starknet'; +import type { AddDeclareParams, AddInvokeTransactionParams } from '../rpcs'; + +type CallGetStarknetV4 = AddInvokeTransactionParams['calls'][number]; /** * Converts an array of calls from either the `CallGetStarknetV4[]` format * or the standard `Call[]` format into the standard `Call[]` format. If the input @@ -16,6 +18,9 @@ import type { AddDeclareTransactionParameters, Call as CallGetStarknetV4 } from * @returns The array of formatted calls in the `Call[]` format. */ export const formatCalls = (calls: Call[] | CallGetStarknetV4[]): Call[] => { + if (calls === undefined || !Array.isArray(calls)) { + return undefined as unknown as Call[]; + } return calls.map((call) => { const contractAddress = 'contract_address' in call ? call.contract_address : call.contractAddress; const entrypoint = 'entry_point' in call ? call.entry_point : call.entrypoint; @@ -40,30 +45,19 @@ export const formatCalls = (calls: Call[] | CallGetStarknetV4[]): Call[] => { * @param params - The object of `AddDeclareTransactionParameters`. * @returns The object in `DeclareContractPayload` format. */ -export const formatDeclareTransaction = (params: AddDeclareTransactionParameters): DeclareContractPayload => { - const { compiled_class_hash, class_hash, contract_class } = params; +export const formatDeclareTransaction = (params: AddDeclareParams): DeclareContractPayload => { + if (params === undefined) { + return undefined as unknown as DeclareContractPayload; + } + const { + compiled_class_hash = undefined, + class_hash = undefined, + contract_class = undefined as unknown as any, + } = params; return { compiledClassHash: compiled_class_hash, classHash: class_hash, - contract: { - sierra_program: contract_class.sierra_program, - contract_class_version: contract_class.contract_class_version, - entry_points_by_type: { - CONSTRUCTOR: contract_class?.entry_points_by_type?.CONSTRUCTOR.map((ep) => ({ - selector: ep.selector, - function_idx: ep.function_idx, - })), - EXTERNAL: contract_class?.entry_points_by_type?.EXTERNAL.map((ep) => ({ - selector: ep.selector, - function_idx: ep.function_idx, - })), - L1_HANDLER: contract_class?.entry_points_by_type?.L1_HANDLER.map((ep) => ({ - selector: ep.selector, - function_idx: ep.function_idx, - })), - }, - abi: contract_class.abi as unknown as Abi, // Directly passing the string as `any` - }, + contract: contract_class, }; };