diff --git a/.github/workflows/npmPublish.yml b/.github/workflows/npmPublish.yml index 68a1c74f2..ed192e23f 100644 --- a/.github/workflows/npmPublish.yml +++ b/.github/workflows/npmPublish.yml @@ -10,7 +10,7 @@ jobs: - name: Checkout code uses: actions/checkout@v2 with: - ref: "main" + ref: ${{ github.ref }} - name: Set up Node.js uses: actions/setup-node@v2 diff --git a/sdk/package.json b/sdk/package.json index fdf44fb8d..150f9d8ed 100644 --- a/sdk/package.json +++ b/sdk/package.json @@ -1,6 +1,6 @@ { "name": "@thirdweb-dev/engine", - "version": "0.0.12", + "version": "0.0.0-20240904-2", "main": "dist/thirdweb-dev-engine.cjs.js", "module": "dist/thirdweb-dev-engine.esm.js", "files": [ diff --git a/src/server/routes/backend-wallet/sendTransaction.ts b/src/server/routes/backend-wallet/sendTransaction.ts index d6321bd58..c649a432f 100644 --- a/src/server/routes/backend-wallet/sendTransaction.ts +++ b/src/server/routes/backend-wallet/sendTransaction.ts @@ -1,7 +1,9 @@ import { Static, Type } from "@sinclair/typebox"; import { FastifyInstance } from "fastify"; import { StatusCodes } from "http-status-codes"; +import { getAddress } from "thirdweb"; import { queueTxRaw } from "../../../db/transactions/queueTxRaw"; +import { redis } from "../../../utils/redis/redis"; import { requestQuerystringSchema, standardResponseSchema, @@ -72,9 +74,26 @@ export async function sendTransaction(fastify: FastifyInstance) { "x-backend-wallet-address": fromAddress, "x-idempotency-key": idempotencyKey, "x-account-address": accountAddress, + "x-account-factory-address": factoryAddress, } = request.headers as Static; const chainId = await getChainIdFromChain(chain); + if (accountAddress && factoryAddress) { + try { + const validatedFactoryAddress = getAddress(factoryAddress); + // Note: This is a temporary solution to cache the deployed address's factory for 7 days. + // This is needed due to a potential race condition of submitting a transaction immediately after creating an account that is not yet mined onchain + await redis.set( + `account-factory:${chainId}:${accountAddress.toLowerCase()}`, + validatedFactoryAddress, + "EX", + 7 * 24 * 60 * 60, + ); + } catch { + // incorrect factory address provided, ignore for backwards compatibility + } + } + let queueId: string; if (accountAddress) { const { id } = await queueTxRaw({ diff --git a/src/server/routes/contract/extensions/accountFactory/write/createAccount.ts b/src/server/routes/contract/extensions/accountFactory/write/createAccount.ts index 5d0c4c65f..8680f206e 100644 --- a/src/server/routes/contract/extensions/accountFactory/write/createAccount.ts +++ b/src/server/routes/contract/extensions/accountFactory/write/createAccount.ts @@ -95,7 +95,12 @@ export const createAccount = async (fastify: FastifyInstance) => { // Note: This is a temporary solution to cache the deployed address's factory for 7 days. // This is needed due to a potential race condition of submitting a transaction immediately after creating an account that is not yet mined onchain - await redis.set(`account-factory:${deployedAddress.toLowerCase()}`, contractAddress, 'EX', 7 * 24 * 60 * 60); + await redis.set( + `account-factory:${chainId}:${deployedAddress.toLowerCase()}`, + contractAddress, + "EX", + 7 * 24 * 60 * 60, + ); reply.status(StatusCodes.OK).send({ result: { diff --git a/src/server/routes/contract/write/write.ts b/src/server/routes/contract/write/write.ts index 27db0d682..297ee5c6d 100644 --- a/src/server/routes/contract/write/write.ts +++ b/src/server/routes/contract/write/write.ts @@ -1,8 +1,10 @@ import { Static, Type } from "@sinclair/typebox"; import { FastifyInstance } from "fastify"; import { StatusCodes } from "http-status-codes"; +import { getAddress } from "thirdweb"; import { queueTx } from "../../../../db/transactions/queueTx"; import { getContract } from "../../../../utils/cache/getContract"; +import { redis } from "../../../../utils/redis/redis"; import { abiSchema } from "../../../schemas/contract"; import { contractParamSchema, @@ -66,9 +68,27 @@ export async function writeToContract(fastify: FastifyInstance) { "x-backend-wallet-address": walletAddress, "x-account-address": accountAddress, "x-idempotency-key": idempotencyKey, + "x-account-factory-address": factoryAddress, } = request.headers as Static; const chainId = await getChainIdFromChain(chain); + + if (accountAddress && factoryAddress) { + try { + const validatedFactoryAddress = getAddress(factoryAddress); + // Note: This is a temporary solution to cache the deployed address's factory for 7 days. + // This is needed due to a potential race condition of submitting a transaction immediately after creating an account that is not yet mined onchain + await redis.set( + `account-factory:${chainId}:${accountAddress.toLowerCase()}`, + validatedFactoryAddress, + "EX", + 7 * 24 * 60 * 60, + ); + } catch { + // incorrect factory address provided, ignore for backwards compatibility + } + } + const contract = await getContract({ chainId, contractAddress, diff --git a/src/server/schemas/wallet/index.ts b/src/server/schemas/wallet/index.ts index 673322d5e..4c8c46221 100644 --- a/src/server/schemas/wallet/index.ts +++ b/src/server/schemas/wallet/index.ts @@ -19,6 +19,11 @@ export const walletWithAAHeaderSchema = Type.Object({ description: "Smart account address", }), ), + "x-account-factory-address": Type.Optional( + Type.String({ + description: "Smart account factory address", + }), + ), }); export const walletParamSchema = Type.Object({ diff --git a/src/server/utils/wallets/getSmartWallet.ts b/src/server/utils/wallets/getSmartWallet.ts index 3e43f83cb..51fb1bb43 100644 --- a/src/server/utils/wallets/getSmartWallet.ts +++ b/src/server/utils/wallets/getSmartWallet.ts @@ -20,8 +20,9 @@ export const getSmartWallet = async ({ // Note: This is a temporary solution to use cached deployed address's factory address from create-account // This is needed due to a potential race condition of submitting a transaction immediately after creating an account that is not yet mined onchain factoryAddress = - (await redis.get(`account-factory:${accountAddress.toLowerCase()}`)) || - ""; + (await redis.get( + `account-factory:${chainId}:${accountAddress.toLowerCase()}`, + )) || ""; } catch {} if (!factoryAddress) {