diff --git a/.changeset/thick-bees-deny.md b/.changeset/thick-bees-deny.md new file mode 100644 index 00000000000..5c7e343d675 --- /dev/null +++ b/.changeset/thick-bees-deny.md @@ -0,0 +1,5 @@ +--- +"thirdweb": patch +--- + +Change caching strategy for contract ABI diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 2dd47e3dcac..eca21aac999 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -20,7 +20,7 @@ env: jobs: optimize_ci: - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8 outputs: skip: ${{ steps.check_skip.outputs.skip }} steps: @@ -34,7 +34,7 @@ jobs: build: needs: optimize_ci if: needs.optimize_ci.outputs.skip == 'false' - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8 name: Build Packages steps: - name: Check out the code @@ -51,7 +51,7 @@ jobs: if: needs.optimize_ci.outputs.skip == 'false' timeout-minutes: 15 name: Lint Packages - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8 steps: - name: Check out the code uses: actions/checkout@v4 @@ -71,7 +71,7 @@ jobs: if: needs.optimize_ci.outputs.skip == 'false' timeout-minutes: 15 name: Unit Tests - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8 steps: - name: Check out the code uses: actions/checkout@v4 @@ -99,7 +99,7 @@ jobs: if: needs.optimize_ci.outputs.skip == 'false' timeout-minutes: 15 name: E2E Tests - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8 strategy: matrix: package_manager: [npm, yarn, pnpm, bun] @@ -169,7 +169,7 @@ jobs: if: github.event_name == 'pull_request' && needs.optimize_ci.outputs.skip == 'false' timeout-minutes: 15 name: "Size" - runs-on: ubuntu-latest + runs-on: ubuntu-latest-8 steps: - name: Check out the code uses: actions/checkout@v4 diff --git a/packages/thirdweb/src/contract/actions/resolve-abi.ts b/packages/thirdweb/src/contract/actions/resolve-abi.ts index 333fa4a2117..2c53edff16e 100644 --- a/packages/thirdweb/src/contract/actions/resolve-abi.ts +++ b/packages/thirdweb/src/contract/actions/resolve-abi.ts @@ -1,10 +1,9 @@ import { type Abi, formatAbi, parseAbi } from "abitype"; import { download } from "../../storage/download.js"; import { getClientFetch } from "../../utils/fetch.js"; +import { withCache } from "../../utils/promise/withCache.js"; import { type ThirdwebContract, getContract } from "../contract.js"; -const ABI_RESOLUTION_CACHE = new WeakMap, Promise>(); - /** * Resolves the ABI (Application Binary Interface) for a given contract. * If the ABI is already cached, it returns the cached value. @@ -32,31 +31,34 @@ export function resolveContractAbi( contract: ThirdwebContract, contractApiBaseUrl = "https://contract.thirdweb.com/abi", ): Promise { - if (ABI_RESOLUTION_CACHE.has(contract)) { - return ABI_RESOLUTION_CACHE.get(contract) as Promise; - } - - const prom = (async () => { - // if the contract already HAS a user defined we always use that! - if (contract.abi) { - return contract.abi as abi; - } + return withCache( + async () => { + // if the contract already HAS a user defined we always use that! + if (contract.abi) { + return contract.abi as abi; + } - // for local chains, we need to resolve the composite abi from bytecode - if (contract.chain.id === 31337 || contract.chain.id === 1337) { - return await resolveCompositeAbi(contract as ThirdwebContract); - } + // for local chains, we need to resolve the composite abi from bytecode + if (contract.chain.id === 31337 || contract.chain.id === 1337) { + return (await resolveCompositeAbi(contract as ThirdwebContract)) as abi; + } - // try to get it from the api - try { - return await resolveAbiFromContractApi(contract, contractApiBaseUrl); - } catch { - // if that fails, try to resolve it from the bytecode - return await resolveCompositeAbi(contract as ThirdwebContract); - } - })(); - ABI_RESOLUTION_CACHE.set(contract, prom); - return prom as Promise; + // try to get it from the api + try { + return (await resolveAbiFromContractApi( + contract, + contractApiBaseUrl, + )) as abi; + } catch { + // if that fails, try to resolve it from the bytecode + return (await resolveCompositeAbi(contract as ThirdwebContract)) as abi; + } + }, + { + cacheKey: `${contract.chain.id}-${contract.address}`, + cacheTime: 1000 * 60 * 60 * 1, // 1 hour + }, + ); } /**