Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into ph/folderReorg2
Browse files Browse the repository at this point in the history
  • Loading branch information
arcoraven committed Dec 10, 2024
2 parents 13a5a27 + d3d9a2a commit d17d103
Show file tree
Hide file tree
Showing 15 changed files with 395 additions and 330 deletions.
2 changes: 0 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import { env } from "./shared/utils/env";
import { logger } from "./shared/utils/logger";
import { initWorker } from "./worker";
import { CancelRecycledNoncesQueue } from "./worker/queues/cancelRecycledNoncesQueue";
import { MigratePostgresTransactionsQueue } from "./worker/queues/migratePostgresTransactionsQueue";
import { MineTransactionQueue } from "./worker/queues/mineTransactionQueue";
import { NonceResyncQueue } from "./worker/queues/nonceResyncQueue";
import { ProcessEventsLogQueue } from "./worker/queues/processEventLogsQueue";
Expand Down Expand Up @@ -70,7 +69,6 @@ const gracefulShutdown = async (signal: NodeJS.Signals) => {
await MineTransactionQueue.q.close();
await CancelRecycledNoncesQueue.q.close();
await PruneTransactionsQueue.q.close();
await MigratePostgresTransactionsQueue.q.close();
await NonceResyncQueue.q.close();

process.exit(0);
Expand Down
2 changes: 0 additions & 2 deletions src/server/middleware/adminRoutes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { StatusCodes } from "http-status-codes";
import { timingSafeEqual } from "node:crypto";
import { env } from "../../shared/utils/env";
import { CancelRecycledNoncesQueue } from "../../worker/queues/cancelRecycledNoncesQueue";
import { MigratePostgresTransactionsQueue } from "../../worker/queues/migratePostgresTransactionsQueue";
import { MineTransactionQueue } from "../../worker/queues/mineTransactionQueue";
import { NonceHealthCheckQueue } from "../../worker/queues/nonceHealthCheckQueue";
import { NonceResyncQueue } from "../../worker/queues/nonceResyncQueue";
Expand All @@ -30,7 +29,6 @@ const QUEUES: Queue[] = [
MineTransactionQueue.q,
CancelRecycledNoncesQueue.q,
PruneTransactionsQueue.q,
MigratePostgresTransactionsQueue.q,
NonceResyncQueue.q,
NonceHealthCheckQueue.q,
];
Expand Down
79 changes: 57 additions & 22 deletions src/server/routes/contract/extensions/erc1155/write/mintTo.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { Type, type Static } from "@sinclair/typebox";
import type { FastifyInstance } from "fastify";
import { StatusCodes } from "http-status-codes";
import { queueTx } from "../../../../../../shared/db/transactions/queueTx";
import { getContract } from "../../../../../../shared/utils/cache/getContract";
import { getContract } from "thirdweb";
import { mintTo } from "thirdweb/extensions/erc1155";
import type { NFTInput } from "thirdweb/utils";
import { getChain } from "../../../../../../shared/utils/chain";
import { thirdwebClient } from "../../../../../../shared/utils/sdk";
import { queueTransaction } from "../../../../../../shared/utils/transaction/queueTransation";
import { AddressSchema } from "../../../../../schemas/address";
import { nftAndSupplySchema } from "../../../../../schemas/nft";
import {
Expand All @@ -12,10 +16,13 @@ import {
transactionWritesResponseSchema,
} from "../../../../../schemas/sharedApiSchemas";
import { txOverridesWithValueSchema } from "../../../../../schemas/txOverrides";
import { walletWithAAHeaderSchema } from "../../../../../schemas/wallet";
import {
maybeAddress,
requiredAddress,
walletWithAAHeaderSchema,
} from "../../../../../schemas/wallet";
import { getChainIdFromChain } from "../../../../../utils/chain";

// INPUTS
const requestSchema = erc1155ContractParamSchema;
const requestBodySchema = Type.Object({
receiver: {
Expand Down Expand Up @@ -66,34 +73,62 @@ export async function erc1155mintTo(fastify: FastifyInstance) {
},
},
handler: async (request, reply) => {
const { chain, contractAddress } = request.params;
const { chain: _chain, contractAddress } = request.params;
const { simulateTx } = request.query;
const { receiver, metadataWithSupply, txOverrides } = request.body;
const {
"x-backend-wallet-address": walletAddress,
"x-backend-wallet-address": fromAddress,
"x-account-address": accountAddress,
"x-idempotency-key": idempotencyKey,
"x-account-factory-address": accountFactoryAddress,
"x-account-salt": accountSalt,
} = request.headers as Static<typeof walletWithAAHeaderSchema>;

const chainId = await getChainIdFromChain(chain);
const contract = await getContract({
chainId,
contractAddress,
walletAddress,
accountAddress,
const chainId = await getChainIdFromChain(_chain);
const chain = await getChain(chainId);

const contract = getContract({
chain,
client: thirdwebClient,
address: contractAddress,
});
const tx = await contract.erc1155.mintTo.prepare(
receiver,
metadataWithSupply,
);

const queueId = await queueTx({
tx,
chainId,
simulateTx,
extension: "erc1155",
idempotencyKey,
// Backward compatibility: Transform the request body's v4 shape to v5.
const { metadata, supply } = metadataWithSupply;
const nft: NFTInput | string =
typeof metadata === "string"
? metadata
: {
name: metadata.name?.toString() ?? undefined,
description: metadata.description ?? undefined,
image: metadata.image ?? undefined,
animation_url: metadata.animation_url ?? undefined,
external_url: metadata.external_url ?? undefined,
background_color: metadata.background_color ?? undefined,
properties: metadata.properties,
};
const transaction = mintTo({
contract,
to: receiver,
nft,
supply: BigInt(supply),
});

const queueId = await queueTransaction({
transaction,
fromAddress: requiredAddress(fromAddress, "x-backend-wallet-address"),
toAddress: maybeAddress(contractAddress, "to"),
accountAddress: maybeAddress(accountAddress, "x-account-address"),
accountFactoryAddress: maybeAddress(
accountFactoryAddress,
"x-account-factory-address",
),
accountSalt,
txOverrides,
idempotencyKey,
extension: "erc1155",
functionName: "mintTo",
shouldSimulate: simulateTx,
});

reply.status(StatusCodes.OK).send({
Expand Down
58 changes: 40 additions & 18 deletions src/server/routes/contract/extensions/erc20/write/mintTo.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
import { Type, type Static } from "@sinclair/typebox";
import type { FastifyInstance } from "fastify";
import { StatusCodes } from "http-status-codes";
import { queueTx } from "../../../../../../shared/db/transactions/queueTx";
import { getContract } from "../../../../../../shared/utils/cache/getContract";
import { getContract } from "thirdweb";
import { mintTo } from "thirdweb/extensions/erc20";
import { getChain } from "../../../../../../shared/utils/chain";
import { thirdwebClient } from "../../../../../../shared/utils/sdk";
import { queueTransaction } from "../../../../../../shared/utils/transaction/queueTransation";
import { AddressSchema } from "../../../../../schemas/address";
import {
erc20ContractParamSchema,
Expand All @@ -11,7 +14,11 @@ import {
transactionWritesResponseSchema,
} from "../../../../../schemas/sharedApiSchemas";
import { txOverridesWithValueSchema } from "../../../../../schemas/txOverrides";
import { walletWithAAHeaderSchema } from "../../../../../schemas/wallet";
import {
maybeAddress,
requiredAddress,
walletWithAAHeaderSchema,
} from "../../../../../schemas/wallet";
import { getChainIdFromChain } from "../../../../../utils/chain";

// INPUTS
Expand Down Expand Up @@ -59,31 +66,46 @@ export async function erc20mintTo(fastify: FastifyInstance) {
},
},
handler: async (request, reply) => {
const { chain, contractAddress } = request.params;
const { chain: _chain, contractAddress } = request.params;
const { simulateTx } = request.query;
const { toAddress, amount, txOverrides } = request.body;
const {
"x-backend-wallet-address": walletAddress,
"x-backend-wallet-address": fromAddress,
"x-account-address": accountAddress,
"x-idempotency-key": idempotencyKey,
"x-account-factory-address": accountFactoryAddress,
"x-account-salt": accountSalt,
} = request.headers as Static<typeof walletWithAAHeaderSchema>;

const chainId = await getChainIdFromChain(chain);
const contract = await getContract({
chainId,
contractAddress,
walletAddress,
accountAddress,
const chainId = await getChainIdFromChain(_chain);
const chain = await getChain(chainId);

const contract = getContract({
chain,
client: thirdwebClient,
address: contractAddress,
});
const transaction = mintTo({
contract,
to: toAddress,
amount,
});
const tx = await contract.erc20.mintTo.prepare(toAddress, amount);

const queueId = await queueTx({
tx,
chainId,
simulateTx,
extension: "erc20",
idempotencyKey,
const queueId = await queueTransaction({
transaction,
fromAddress: requiredAddress(fromAddress, "x-backend-wallet-address"),
toAddress: maybeAddress(contractAddress, "to"),
accountAddress: maybeAddress(accountAddress, "x-account-address"),
accountFactoryAddress: maybeAddress(
accountFactoryAddress,
"x-account-factory-address",
),
accountSalt,
txOverrides,
idempotencyKey,
extension: "erc20",
functionName: "mintTo",
shouldSimulate: simulateTx,
});

reply.status(StatusCodes.OK).send({
Expand Down
75 changes: 56 additions & 19 deletions src/server/routes/contract/extensions/erc721/write/mintTo.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
import { type Static, Type } from "@sinclair/typebox";
import { Type, type Static } from "@sinclair/typebox";
import type { FastifyInstance } from "fastify";
import { StatusCodes } from "http-status-codes";
import { queueTx } from "../../../../../../shared/db/transactions/queueTx";
import { getContract } from "../../../../../../shared/utils/cache/getContract";
import { getContract } from "thirdweb";
import { mintTo } from "thirdweb/extensions/erc721";
import type { NFTInput } from "thirdweb/utils";
import { getChain } from "../../../../../../shared/utils/chain";
import { thirdwebClient } from "../../../../../../shared/utils/sdk";
import { queueTransaction } from "../../../../../../shared/utils/transaction/queueTransation";
import { AddressSchema } from "../../../../../schemas/address";
import { nftOrInputSchema } from "../../../../../schemas/nft";
import {
Expand All @@ -12,7 +16,11 @@ import {
transactionWritesResponseSchema,
} from "../../../../../schemas/sharedApiSchemas";
import { txOverridesWithValueSchema } from "../../../../../schemas/txOverrides";
import { walletWithAAHeaderSchema } from "../../../../../schemas/wallet";
import {
maybeAddress,
requiredAddress,
walletWithAAHeaderSchema,
} from "../../../../../schemas/wallet";
import { getChainIdFromChain } from "../../../../../utils/chain";

// INPUTS
Expand Down Expand Up @@ -61,31 +69,60 @@ export async function erc721mintTo(fastify: FastifyInstance) {
},
},
handler: async (request, reply) => {
const { chain, contractAddress } = request.params;
const { chain: _chain, contractAddress } = request.params;
const { simulateTx } = request.query;
const { receiver, metadata, txOverrides } = request.body;
const {
"x-backend-wallet-address": walletAddress,
"x-backend-wallet-address": fromAddress,
"x-account-address": accountAddress,
"x-idempotency-key": idempotencyKey,
"x-account-factory-address": accountFactoryAddress,
"x-account-salt": accountSalt,
} = request.headers as Static<typeof walletWithAAHeaderSchema>;

const chainId = await getChainIdFromChain(chain);
const contract = await getContract({
chainId,
contractAddress,
walletAddress,
accountAddress,
const chainId = await getChainIdFromChain(_chain);
const chain = await getChain(chainId);

const contract = getContract({
chain,
client: thirdwebClient,
address: contractAddress,
});
const tx = await contract.erc721.mintTo.prepare(receiver, metadata);

const queueId = await queueTx({
tx,
chainId,
simulateTx,
extension: "erc721",
idempotencyKey,
// Backward compatibility: Transform the request body's v4 shape to v5.
const nft: NFTInput | string =
typeof metadata === "string"
? metadata
: {
name: metadata.name?.toString() ?? undefined,
description: metadata.description ?? undefined,
image: metadata.image ?? undefined,
animation_url: metadata.animation_url ?? undefined,
external_url: metadata.external_url ?? undefined,
background_color: metadata.background_color ?? undefined,
properties: metadata.properties,
};
const transaction = mintTo({
contract,
to: receiver,
nft,
});

const queueId = await queueTransaction({
transaction,
fromAddress: requiredAddress(fromAddress, "x-backend-wallet-address"),
toAddress: maybeAddress(contractAddress, "to"),
accountAddress: maybeAddress(accountAddress, "x-account-address"),
accountFactoryAddress: maybeAddress(
accountFactoryAddress,
"x-account-factory-address",
),
accountSalt,
txOverrides,
idempotencyKey,
extension: "erc721",
functionName: "mintTo",
shouldSimulate: simulateTx,
});

reply.status(StatusCodes.OK).send({
Expand Down
14 changes: 14 additions & 0 deletions src/shared/utils/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ export const env = createEnv({
QUEUE_FAIL_HISTORY_COUNT: z.coerce.number().default(10_000),
// Sets the number of recent nonces to map to queue IDs.
NONCE_MAP_COUNT: z.coerce.number().default(10_000),

/**
* Experimental env vars. These may be renamed or removed in future non-major releases.
*/
// Sets how long the mine worker waits for a transaction receipt before considering the transaction dropped. Default: 30 minutes
EXPERIMENTAL__MINE_WORKER_TIMEOUT_SECONDS: z.coerce
.number()
.default(30 * 60),
// Sets the max gas price for a transaction attempt. Most RPCs reject transactions above a certain gas price. Default: 10^18 wei.
EXPERIMENTAL__MAX_GAS_PRICE_WEI: z.coerce.number().default(10 ** 18),
},
clientPrefix: "NEVER_USED",
client: {},
Expand Down Expand Up @@ -134,6 +144,10 @@ export const env = createEnv({
QUEUE_COMPLETE_HISTORY_COUNT: process.env.QUEUE_COMPLETE_HISTORY_COUNT,
QUEUE_FAIL_HISTORY_COUNT: process.env.QUEUE_FAIL_HISTORY_COUNT,
NONCE_MAP_COUNT: process.env.NONCE_MAP_COUNT,
EXPERIMENTAL__MINE_WORKER_TIMEOUT_SECONDS:
process.env.EXPERIMENTAL__MINE_WORKER_TIMEOUT_SECONDS,
EXPERIMENTAL__MAX_GAS_PRICE_WEI:
process.env.EXPERIMENTAL__MAX_GAS_PRICE_WEI,
METRICS_PORT: process.env.METRICS_PORT,
METRICS_ENABLED: process.env.METRICS_ENABLED,
},
Expand Down
5 changes: 5 additions & 0 deletions src/shared/utils/math.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ export const getPercentile = (arr: number[], percentile: number): number => {
const index = Math.floor((percentile / 100) * (arr.length - 1));
return arr[index];
};

export const BigIntMath = {
min: (a: bigint, b: bigint) => (a < b ? a : b),
max: (a: bigint, b: bigint) => (a > b ? a : b),
};
3 changes: 0 additions & 3 deletions src/worker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import {
updatedWebhooksListener,
} from "./listeners/webhookListener";
import { initCancelRecycledNoncesWorker } from "./tasks/cancelRecycledNoncesWorker";
import { initMigratePostgresTransactionsWorker } from "./tasks/migratePostgresTransactionsWorker";
import { initMineTransactionWorker } from "./tasks/mineTransactionWorker";
import { initNonceHealthCheckWorker } from "./tasks/nonceHealthCheckWorker";
import { initNonceResyncWorker } from "./tasks/nonceResyncWorker";
Expand All @@ -29,8 +28,6 @@ export const initWorker = async () => {

initNonceHealthCheckWorker();

await initMigratePostgresTransactionsWorker();

await initNonceResyncWorker();

// Listen for new & updated configuration data.
Expand Down
Loading

0 comments on commit d17d103

Please sign in to comment.