Skip to content

Commit bb90430

Browse files
committed
Add team capabilities to service-utils
1 parent 4691343 commit bb90430

File tree

4 files changed

+113
-0
lines changed

4 files changed

+113
-0
lines changed

.changeset/loose-comics-serve.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@thirdweb-dev/service-utils": patch
3+
---
4+
5+
add team capabilities

packages/service-utils/src/core/api.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,41 @@ export type ApiResponse = {
4343
};
4444
};
4545

46+
// needs to be kept in sync with the capabilities from the backend
47+
type TeamCapabilities = {
48+
rpc: {
49+
enabled: boolean;
50+
rateLimit: number;
51+
};
52+
insight: {
53+
enabled: boolean;
54+
rateLimit: number;
55+
};
56+
storage: {
57+
enabled: boolean;
58+
download: {
59+
rateLimit: number;
60+
};
61+
upload: {
62+
rateLimit: number;
63+
};
64+
};
65+
nebula: {
66+
enabled: boolean;
67+
rateLimit: number;
68+
};
69+
bundler: {
70+
enabled: true;
71+
mainnetEnabled: boolean;
72+
rateLimit: number;
73+
};
74+
embeddedWallets: {
75+
enabled: boolean;
76+
customAuth: boolean;
77+
customBranding: boolean;
78+
};
79+
};
80+
4681
export type TeamResponse = {
4782
id: string;
4883
name: string;
@@ -68,6 +103,7 @@ export type TeamResponse = {
68103
canCreatePublicChains: boolean | null;
69104
enabledScopes: ServiceName[];
70105
isOnboarded: boolean;
106+
capabilities: TeamCapabilities;
71107
};
72108

73109
export type ProjectSecretKey = {

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

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {
22
type CoreServiceConfig,
33
type TeamAndProjectResponse,
4+
type TeamResponse,
45
fetchTeamAndProject,
56
} from "../api.js";
67
import { authorizeClient } from "./client.js";
@@ -129,6 +130,21 @@ export async function authorize(
129130
errorCode: "INVALID_KEY",
130131
};
131132
}
133+
// check if the service is maybe disabled for the team (usually due to a billing issue / exceeding the free plan limit)
134+
if (
135+
!isServiceEnabledForTeam(
136+
serviceConfig.serviceScope,
137+
teamAndProjectResponse.team.capabilities,
138+
)
139+
) {
140+
return {
141+
authorized: false,
142+
status: 403,
143+
errorMessage:
144+
"You currently do not have access to this service. Please check if your subscription includes this service and is active.",
145+
errorCode: "SERVICE_TEMPOARILY_DISABLED",
146+
};
147+
}
132148
// now we can validate the key itself
133149
const clientAuth = authorizeClient(authData, teamAndProjectResponse);
134150

@@ -161,3 +177,26 @@ export async function authorize(
161177
authMethod: clientAuth.authMethod,
162178
};
163179
}
180+
181+
function isServiceEnabledForTeam(
182+
scope: CoreServiceConfig["serviceScope"],
183+
teamCapabilities: TeamResponse["capabilities"],
184+
): boolean {
185+
switch (scope) {
186+
case "rpc":
187+
return teamCapabilities.rpc.enabled;
188+
case "bundler":
189+
return teamCapabilities.bundler.enabled;
190+
case "storage":
191+
return teamCapabilities.storage.enabled;
192+
case "insight":
193+
return teamCapabilities.insight.enabled;
194+
case "nebula":
195+
return teamCapabilities.nebula.enabled;
196+
case "embeddedWallets":
197+
return teamCapabilities.embeddedWallets.enabled;
198+
default:
199+
// always return true for any legacy / un-named services
200+
return true;
201+
}
202+
}

packages/service-utils/src/mocks.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,39 @@ export const validTeamResponse: TeamResponse = {
5959
canCreatePublicChains: false,
6060
enabledScopes: ["storage", "rpc", "bundler"],
6161
isOnboarded: true,
62+
capabilities: {
63+
rpc: {
64+
enabled: true,
65+
rateLimit: 1000,
66+
},
67+
insight: {
68+
enabled: true,
69+
rateLimit: 1000,
70+
},
71+
storage: {
72+
enabled: true,
73+
download: {
74+
rateLimit: 1000,
75+
},
76+
upload: {
77+
rateLimit: 1000,
78+
},
79+
},
80+
nebula: {
81+
enabled: true,
82+
rateLimit: 1000,
83+
},
84+
bundler: {
85+
enabled: true,
86+
mainnetEnabled: true,
87+
rateLimit: 1000,
88+
},
89+
embeddedWallets: {
90+
enabled: true,
91+
customAuth: true,
92+
customBranding: true,
93+
},
94+
},
6295
};
6396

6497
export const validTeamAndProjectResponse: TeamAndProjectResponse = {

0 commit comments

Comments
 (0)