Skip to content

Commit 61c2225

Browse files
authored
Merge branch 'main' into yash/insight-events
2 parents 44dfacf + f618e2b commit 61c2225

File tree

9 files changed

+289
-91
lines changed

9 files changed

+289
-91
lines changed

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/hooks.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ type Options =
5555
};
5656

5757
export async function getClaimPhasesInLegacyFormat(
58-
options: BaseTransactionOptions<Options>,
58+
options: BaseTransactionOptions<Options> & { isMultiPhase: boolean },
5959
): Promise<CombinedClaimCondition[]> {
6060
const conditions = await (async () => {
6161
switch (options.type) {
@@ -64,7 +64,10 @@ export async function getClaimPhasesInLegacyFormat(
6464
case "erc721":
6565
return ERC721Ext.getClaimConditions(options);
6666
case "erc1155":
67-
return ERC1155Ext.getClaimConditions(options);
67+
return ERC1155Ext.getClaimConditions({
68+
...options,
69+
singlePhaseDrop: !options.isMultiPhase,
70+
});
6871
}
6972
})();
7073

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/_components/claim-conditions/claim-conditions-form/index.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ export const ClaimConditionsForm: React.FC<ClaimConditionsFormProps> = ({
222222

223223
const claimConditionsQuery = useReadContract(getClaimPhasesInLegacyFormat, {
224224
contract,
225+
isMultiPhase,
225226
...(isErc20
226227
? { type: "erc20", decimals: tokenDecimals.data }
227228
: isErc721

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/ContractOverviewPage.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export const ContractOverviewPage: React.FC<ContractOverviewPageProps> = ({
3939
}) => {
4040
return (
4141
<div className="flex flex-col gap-10 lg:flex-row lg:gap-8">
42-
<div className="flex grow flex-col gap-10">
42+
<div className="flex grow flex-col gap-10 overflow-hidden">
4343
<ContractChecklist
4444
isErc721={isErc721}
4545
isErc1155={isErc1155}

apps/dashboard/src/app/(dashboard)/(chain)/[chain_id]/[contractAddress]/overview/components/LatestEvents.tsx

Lines changed: 44 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ export function LatestEventsUI(props: {
4848
trackingCategory: string;
4949
}) {
5050
const { allEvents, autoUpdate, eventsHref } = props;
51-
5251
return (
5352
<div className="rounded-lg border bg-card">
5453
{/* header */}
@@ -93,37 +92,50 @@ export function LatestEventsUI(props: {
9392
</TableHeader>
9493

9594
<TableBody>
96-
{allEvents.slice(0, 3).map((transaction) => (
97-
<TableRow key={transaction.transactionHash}>
98-
<TableCell>
99-
<CopyTextButton
100-
textToShow={shortenString(transaction.transactionHash)}
101-
textToCopy={transaction.transactionHash}
102-
tooltip="Copy transaction hash"
103-
copyIconPosition="left"
104-
variant="ghost"
105-
className="-translate-x-2 font-mono"
106-
/>
107-
</TableCell>
108-
<TableCell>
109-
<div className="flex w-max flex-wrap gap-2">
110-
{transaction.events.map((e) => (
111-
<Button
112-
key={e.logIndex + e.address + e.eventName}
113-
variant="outline"
114-
size="sm"
115-
className="h-auto rounded-full py-1"
116-
asChild
117-
>
118-
<Link href={`${eventsHref}?event=${e.eventName}`}>
119-
{e.eventName}
120-
</Link>
121-
</Button>
122-
))}
123-
</div>
124-
</TableCell>
125-
</TableRow>
126-
))}
95+
{allEvents.slice(0, 3).map((transaction) => {
96+
return (
97+
<TableRow key={transaction.transactionHash}>
98+
<TableCell>
99+
<CopyTextButton
100+
textToShow={shortenString(transaction.transactionHash)}
101+
textToCopy={transaction.transactionHash}
102+
tooltip="Copy transaction hash"
103+
copyIconPosition="left"
104+
variant="ghost"
105+
className="-translate-x-2 font-mono"
106+
/>
107+
</TableCell>
108+
<TableCell>
109+
<div className="flex w-max flex-wrap gap-2">
110+
{transaction.events.slice(0, 3).map((e) => (
111+
<Button
112+
key={e.logIndex + e.address + e.eventName}
113+
variant="outline"
114+
size="sm"
115+
className="h-auto rounded-full py-1"
116+
asChild
117+
>
118+
<Link href={`${eventsHref}?event=${e.eventName}`}>
119+
{e.eventName}
120+
</Link>
121+
</Button>
122+
))}
123+
124+
{transaction.events.length > 3 && (
125+
<Button
126+
variant="outline"
127+
size="sm"
128+
className="h-auto rounded-full py-1 hover:bg-transparent"
129+
asChild
130+
>
131+
<div>+ {transaction.events.length - 3}</div>
132+
</Button>
133+
)}
134+
</div>
135+
</TableCell>
136+
</TableRow>
137+
);
138+
})}
127139
</TableBody>
128140
</Table>
129141
</TableContainer>

packages/service-utils/CHANGELOG.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,17 @@
11
# @thirdweb-dev/service-utils
22

3+
## 0.9.1
4+
5+
### Patch Changes
6+
7+
- [#6704](https://github.com/thirdweb-dev/js/pull/6704) [`3ab31c8`](https://github.com/thirdweb-dev/js/commit/3ab31c82104ceb2f6c11998555953e886f13d380) Thanks [@jnsdls](https://github.com/jnsdls)! - fix incrby
8+
9+
## 0.9.0
10+
11+
### Minor Changes
12+
13+
- [#6702](https://github.com/thirdweb-dev/js/pull/6702) [`d036b87`](https://github.com/thirdweb-dev/js/commit/d036b87ae163dd80f58224e4b507e6f4ac01ce62) Thanks [@jnsdls](https://github.com/jnsdls)! - update rateLimit function
14+
315
## 0.8.19
416

517
### Patch Changes

packages/service-utils/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@thirdweb-dev/service-utils",
3-
"version": "0.8.19",
3+
"version": "0.9.1",
44
"type": "module",
55
"main": "dist/cjs/index.js",
66
"module": "dist/esm/index.js",

packages/service-utils/src/core/rateLimit/index.ts

Lines changed: 31 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ const RATE_LIMIT_WINDOW_SECONDS = 10;
55

66
// Redis interface compatible with ioredis (Node) and upstash (Cloudflare Workers).
77
type IRedis = {
8-
incr: (key: string) => Promise<number>;
9-
expire: (key: string, ttlSeconds: number) => Promise<0 | 1>;
8+
get: (key: string) => Promise<string | null>;
9+
expire(key: string, seconds: number): Promise<number>;
10+
incrby(key: string, value: number): Promise<number>;
1011
};
1112

1213
export async function rateLimit(args: {
@@ -20,8 +21,20 @@ export async function rateLimit(args: {
2021
* @default 1.0
2122
*/
2223
sampleRate?: number;
24+
/**
25+
* The number of requests to increment by.
26+
* @default 1
27+
*/
28+
increment?: number;
2329
}): Promise<RateLimitResult> {
24-
const { team, limitPerSecond, serviceConfig, redis, sampleRate = 1.0 } = args;
30+
const {
31+
team,
32+
limitPerSecond,
33+
serviceConfig,
34+
redis,
35+
sampleRate = 1.0,
36+
increment = 1,
37+
} = args;
2538

2639
const shouldSampleRequest = Math.random() < sampleRate;
2740
if (!shouldSampleRequest) {
@@ -49,12 +62,8 @@ export async function rateLimit(args: {
4962
RATE_LIMIT_WINDOW_SECONDS;
5063
const key = `rate-limit:${serviceScope}:${team.id}:${timestampWindow}`;
5164

52-
// Increment and get the current request count in this window.
53-
const requestCount = await redis.incr(key);
54-
if (requestCount === 1) {
55-
// For the first increment, set an expiration to clean up this key.
56-
await redis.expire(key, RATE_LIMIT_WINDOW_SECONDS);
57-
}
65+
// first read the request count from redis
66+
const requestCount = Number((await redis.get(key).catch(() => "0")) || "0");
5867

5968
// Get the limit for this window accounting for the sample rate.
6069
const limitPerWindow =
@@ -71,9 +80,21 @@ export async function rateLimit(args: {
7180
};
7281
}
7382

83+
// do not await this, it just needs to execute at all
84+
(async () =>
85+
// always incrementBy the amount specified for the key
86+
await redis.incrby(key, increment).then(async () => {
87+
// if the initial request count was 0, set the key to expire in the future
88+
if (requestCount === 0) {
89+
await redis.expire(key, RATE_LIMIT_WINDOW_SECONDS);
90+
}
91+
}))().catch(() => {
92+
console.error("Error incrementing rate limit key", key);
93+
});
94+
7495
return {
7596
rateLimited: false,
76-
requestCount,
97+
requestCount: requestCount + increment,
7798
rateLimit: limitPerWindow,
7899
};
79100
}

0 commit comments

Comments
 (0)