Skip to content

Commit

Permalink
🐛 fix(app): fix type
Browse files Browse the repository at this point in the history
  • Loading branch information
huynhducduy committed Dec 2, 2024
1 parent 0f25de1 commit 30efe77
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 63 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import {createMulticallRequest, multicall} from 'starknet_multicall'

const calls = [
createMulticallRequest('<contract address>', <ABI>, '<method_name>', [<method_arg1>, <method_arg2>]),
]
] as const

const [result1] = await multicall(calls, <multicall contract address>, <providerOrAccount>)
```
Expand Down
98 changes: 49 additions & 49 deletions eslint.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import pluginPromise from "eslint-plugin-promise";
import * as pluginRegexp from "eslint-plugin-regexp";
import pluginSecurity from "eslint-plugin-security";
import pluginSimpleImportSort from "eslint-plugin-simple-import-sort";
import pluginSonarjs from "eslint-plugin-sonarjs";
// import pluginSonarjs from "eslint-plugin-sonarjs";
import pluginVitest from "eslint-plugin-vitest";
import globals from "globals";
// eslint-disable-next-line import-x/no-unresolved -- import-x error
Expand Down Expand Up @@ -79,67 +79,67 @@ const applyToVitest = createApplyTo(
//------------------------------------------------------------------------------

const coreConfigs = [
...applyToAll("core/eslint-recommended", eslint.configs.recommended),
...applyToAll("core/security", pluginSecurity.configs.recommended),
...applyToAll("core/promise", pluginPromise.configs["flat/recommended"]),
...applyToAll("core/import-x", ...compat.config(pluginImportX.configs.recommended)),
...applyToAll("core/no-use-extend-native", pluginNoUseExtendNative.configs.recommended),
...applyToAll("core/eslint-comments", {
...applyToAll('core/eslint-recommended', eslint.configs.recommended),
...applyToAll('core/security', pluginSecurity.configs.recommended),
...applyToAll('core/promise', pluginPromise.configs['flat/recommended']),
...applyToAll('core/import-x', ...compat.config(pluginImportX.configs.recommended)),
...applyToAll('core/no-use-extend-native', pluginNoUseExtendNative.configs.recommended),
...applyToAll('core/eslint-comments', {
...pluginEslintComments.configs.recommended,
// workaround for https://github.com/eslint-community/eslint-plugin-eslint-comments/issues/215
plugins: {
"@eslint-community/eslint-comments": pluginEslintComments,
'@eslint-community/eslint-comments': pluginEslintComments,
},
}),
...applyToAll("core/regexp", pluginRegexp.configs["flat/recommended"]),
...applyToAll('core/regexp', pluginRegexp.configs['flat/recommended']),

...applyToAll("core/depend", pluginDepend.configs["flat/recommended"]),
...applyToAll("core/sonarjs", pluginSonarjs.configs.recommended), // drop this if using SonarQube or SonarCloud in favor of the IDE extension
...applyToAll("core/no-relative-import-paths", {
...applyToAll('core/depend', pluginDepend.configs['flat/recommended']),
// ...applyToAll("core/sonarjs", pluginSonarjs.configs.recommended), // drop this if using SonarQube or SonarCloud in favor of the IDE extension
...applyToAll('core/no-relative-import-paths', {
plugins: {
"no-relative-import-paths": pluginNoRelativeImportPaths,
'no-relative-import-paths': pluginNoRelativeImportPaths,
},
rules: {
"no-relative-import-paths/no-relative-import-paths": [
"warn",
{ allowSameFolder: true, rootDir: "src", prefix: "@" },
'no-relative-import-paths/no-relative-import-paths': [
'warn',
{allowSameFolder: true, rootDir: 'src', prefix: '@'},
],
},
}),
...applyToAll("core/simple-import-sort", {
...applyToAll('core/simple-import-sort', {
plugins: {
"simple-import-sort": pluginSimpleImportSort,
'simple-import-sort': pluginSimpleImportSort,
},
rules: {
"sort-imports": "off",
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
'sort-imports': 'off',
'simple-import-sort/imports': 'error',
'simple-import-sort/exports': 'error',
},
}),
...applyToAll("core/no-barrel-files", {
...applyToAll('core/no-barrel-files', {
plugins: {
"no-barrel-files": pluginNoBarrelFiles, // switch to eslint-plugin-barrel-files?
'no-barrel-files': pluginNoBarrelFiles, // switch to eslint-plugin-barrel-files?
},
rules: {
"no-barrel-files/no-barrel-files": "error",
'no-barrel-files/no-barrel-files': 'error',
},
}),
...applyToAll("core/no-secrets", {
...applyToAll('core/no-secrets', {
plugins: {
"no-secrets": pluginNoSecrets,
'no-secrets': pluginNoSecrets,
},
rules: {
"no-secrets/no-secrets": [
"error",
'no-secrets/no-secrets': [
'error',
{
tolerance: 4.5,
},
],
},
}),
...applyToAll("core/exception-handling", {
...applyToAll('core/exception-handling', {
plugins: {
"exception-handling": pluginExceptionHandling,
'exception-handling': pluginExceptionHandling,
},
rules: {
// 'exception-handling/no-unhandled': 'error',
Expand All @@ -148,7 +148,7 @@ const coreConfigs = [
// 'plugin:jsdoc/recommended-typescript', // TODO: To be added later
// 'plugin:unicorn/recommended', // TODO: To be added later
// 'plugin:isaacscript/recommended' // TODO: To be added later
];
]

const jsonConfigs = [
...applyToJson("json/json", pluginJsonc.configs["flat/recommended-with-json"]),
Expand Down Expand Up @@ -262,20 +262,20 @@ const testConfigs = [
const config = tsEslint.config(
pluginGitignore({
root: true,
files: [".gitignore"],
files: ['.gitignore'],
strict: false,
}),
{
ignores: ["public/*", "**/*.gen.ts", "vitest.config.ts.timestamp*", "src/abis/**/*"],
ignores: ['public/*', '**/*.gen.ts', 'vitest.config.ts.timestamp*', 'src/abis/**/*'],
},
...coreConfigs,
...jsonConfigs,
...typescriptConfigs,
...testConfigs,
...applyToAll("core", {
...applyToAll('core', {
languageOptions: {
sourceType: "module",
ecmaVersion: "latest",
sourceType: 'module',
ecmaVersion: 'latest',
parserOptions: {
ecmaFeatures: {
impliedStrict: true,
Expand All @@ -291,9 +291,9 @@ const config = tsEslint.config(
},
},
rules: {
"import-x/no-unresolved": "error",
"import-x/order": "off",
"import-x/namespace": "off",
'import-x/no-unresolved': 'error',
'import-x/order': 'off',
'import-x/namespace': 'off',
// 'unicorn/better-regex': 'warn',
// 'unicorn/filename-case': [
// 'error',
Expand All @@ -304,21 +304,21 @@ const config = tsEslint.config(
// }
// }
// ],
"@eslint-community/eslint-comments/require-description": [
"error",
{ ignore: ["eslint-enable"] },
'@eslint-community/eslint-comments/require-description': [
'error',
{ignore: ['eslint-enable']},
],
"sonarjs/no-duplicate-string": "warn",
"promise/always-return": ["warn", { ignoreLastCallback: true }],
"promise/no-callback-in-promise": [
"warn",
// "sonarjs/no-duplicate-string": "warn",
'promise/always-return': ['warn', {ignoreLastCallback: true}],
'promise/no-callback-in-promise': [
'warn',
{
exceptions: ["process.nextTick", "setImmediate", "setTimeout"],
exceptions: ['process.nextTick', 'setImmediate', 'setTimeout'],
},
],
},
}),
...applyToAll("prettier", pluginPrettierRecommended) // Always the last
);
...applyToAll('prettier', pluginPrettierRecommended), // Always the last
)

export default config;
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "starknet_multicall",
"version": "1.0.3",
"version": "1.0.4",
"type": "module",
"sideEffects": false,
"moduleSideEffects": false,
Expand Down Expand Up @@ -48,13 +48,13 @@
"packageManager": "pnpm@9.14.4",
"dependencies": {
"abi-wan-kanabi": "^2.2.3",
"starknet": "^6.20.3"
"starknet": "^6.20.3",
"tiny-invariant": "^1.3.3"
},
"peerDependencies": {
"abi-wan-kanabi": "^2.2.3"
},
"devDependencies": {
"jiti": "^2.4.1",
"@commitlint/cli": "^19.6.0",
"@eslint-community/eslint-plugin-eslint-comments": "^4.4.1",
"@eslint-react/eslint-plugin": "^1.17.2",
Expand Down Expand Up @@ -96,6 +96,7 @@
"eslint-plugin-vitest": "^0.5.4",
"globals": "^15.13.0",
"husky": "^9.1.7",
"jiti": "^2.4.1",
"lint-staged": "^15.2.10",
"prettier": "^3.4.1",
"tsup": "^8.3.5",
Expand Down
8 changes: 8 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 13 additions & 10 deletions src/multicall.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
type ProviderInterface,
type RawArgs,
} from 'starknet'
import invariant from 'tiny-invariant'

import MulticallABI from '../artifacts/MulticallABI'

Expand All @@ -26,12 +27,11 @@ export type ContractMethodArgs<
export function createMulticallRequest<
ContractAbi extends Abi,
Method extends ExtractAbiFunctionNames<ContractAbi>,
Args extends ContractMethodArgs<ContractAbi, Method>,
>(
address: string,
abi: ContractAbi,
method: Method,
args?: Args,
args?: ContractMethodArgs<ContractAbi, Method>,
): {
abi: ContractAbi
contractAddress: string
Expand All @@ -56,11 +56,11 @@ export interface CallAndAbi {
calldata: bigint[]
}

export type MulticallResult<T extends CallAndAbi, Ts extends T[]> = Promise<{
export type MulticallResult<T extends CallAndAbi, Ts extends readonly T[]> = Promise<{
[k in keyof Ts]: FunctionRet<Ts[k]['abi'], Ts[k]['entrypoint']>
}>

export async function multicall<T extends CallAndAbi, Ts extends T[]>(
export async function multicall<T extends CallAndAbi, Ts extends readonly T[]>(
calls: Ts,
multicallAddress: string,
providerOrAccount: ProviderInterface | AccountInterface,
Expand All @@ -79,12 +79,15 @@ export async function multicall<T extends CallAndAbi, Ts extends T[]>(
}),
)

const result = results[1]
invariant(Array.isArray(result), 'Multicall failed, response is not an array')

// @ts-expect-error -- too complex
// eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call -- its safe
return results[1].map((result, index) => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unsafe-member-access -- guranteed
const callData = new CallData(calls[index]!.abi)
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion, @typescript-eslint/no-unsafe-member-access -- guranteed
return callData.parse(calls[index]!.entrypoint, result as unknown as string[])
return result.map((result, index) => {
const call = calls[index]
invariant(call, 'Multicall failed, call is undefined')

const callData = new CallData(call.abi)
return callData.parse(call.entrypoint, result as string[])
})
}

0 comments on commit 30efe77

Please sign in to comment.