@thirdweb-dev/service-utils 0.4.4-nightly-2088de1c-20230901183809 → 0.4.5-nightly-903145a4-20230918223433
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.dev.js +19 -5
- package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.cjs.prod.js +19 -5
- package/cf-worker/dist/thirdweb-dev-service-utils-cf-worker.esm.js +18 -6
- package/dist/declarations/src/cf-worker/index.d.ts +6 -2
- package/dist/declarations/src/cf-worker/index.d.ts.map +1 -1
- package/dist/declarations/src/cf-worker/usage.d.ts +14 -11
- package/dist/declarations/src/cf-worker/usage.d.ts.map +1 -1
- package/dist/declarations/src/core/api.d.ts +17 -1
- package/dist/declarations/src/core/api.d.ts.map +1 -1
- package/dist/declarations/src/core/authorize/client.d.ts.map +1 -1
- package/dist/declarations/src/core/authorize/index.d.ts.map +1 -1
- package/dist/declarations/src/core/authorize/service.d.ts.map +1 -1
- package/dist/declarations/src/core/rateLimit/index.d.ts +10 -0
- package/dist/declarations/src/core/rateLimit/index.d.ts.map +1 -0
- package/dist/declarations/src/core/rateLimit/types.d.ts +9 -0
- package/dist/declarations/src/core/rateLimit/types.d.ts.map +1 -0
- package/dist/declarations/src/core/usageLimit/index.d.ts +5 -0
- package/dist/declarations/src/core/usageLimit/index.d.ts.map +1 -0
- package/dist/declarations/src/core/usageLimit/types.d.ts +9 -0
- package/dist/declarations/src/core/usageLimit/types.d.ts.map +1 -0
- package/dist/declarations/src/node/index.d.ts +2 -0
- package/dist/declarations/src/node/index.d.ts.map +1 -1
- package/dist/{index-6e0ecc5f.cjs.prod.js → index-807f6a60.cjs.dev.js} +132 -6
- package/dist/{index-ffddf746.esm.js → index-bcf68113.esm.js} +131 -7
- package/dist/{index-cd4f96ef.cjs.dev.js → index-cfc8027b.cjs.prod.js} +132 -6
- package/node/dist/thirdweb-dev-service-utils-node.cjs.dev.js +3 -1
- package/node/dist/thirdweb-dev-service-utils-node.cjs.prod.js +3 -1
- package/node/dist/thirdweb-dev-service-utils-node.esm.js +2 -1
- package/package.json +2 -1
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
4
4
|
|
5
|
-
var index = require('../../dist/index-
|
6
|
-
var services = require('../../dist/services-a3f36057.cjs.dev.js');
|
5
|
+
var index = require('../../dist/index-807f6a60.cjs.dev.js');
|
7
6
|
var aws4fetch = require('aws4fetch');
|
8
7
|
var zod = require('zod');
|
8
|
+
var services = require('../../dist/services-a3f36057.cjs.dev.js');
|
9
9
|
|
10
10
|
// Initialize a singleton for aws usage.
|
11
11
|
let _aws;
|
@@ -20,7 +20,7 @@ function getAws(options) {
|
|
20
20
|
* Types
|
21
21
|
*/
|
22
22
|
const usageEventSchema = zod.z.object({
|
23
|
-
source: zod.z.enum(["
|
23
|
+
source: zod.z.enum(["embeddedWallets", "rpc", "storage", "bundler", "paymaster", "relayer"]),
|
24
24
|
action: zod.z.string(),
|
25
25
|
accountId: zod.z.string(),
|
26
26
|
// Optional
|
@@ -33,10 +33,11 @@ const usageEventSchema = zod.z.object({
|
|
33
33
|
mimeType: zod.z.string().optional(),
|
34
34
|
fileSize: zod.z.number().int().nonnegative().optional(),
|
35
35
|
fileCid: zod.z.string().optional(),
|
36
|
-
|
36
|
+
evmMethod: zod.z.string().optional(),
|
37
|
+
userOpHash: zod.z.string().optional(),
|
37
38
|
gasLimit: zod.z.number().nonnegative().optional(),
|
38
39
|
gasPricePerUnit: zod.z.string().optional(),
|
39
|
-
|
40
|
+
transactionHash: zod.z.string().optional()
|
40
41
|
});
|
41
42
|
/**
|
42
43
|
* Publish usage events. Provide the relevant fields for your application.
|
@@ -86,6 +87,8 @@ async function publishUsageEvents(usageEvents, config) {
|
|
86
87
|
}
|
87
88
|
|
88
89
|
const DEFAULT_CACHE_TTL_SECONDS = 60;
|
90
|
+
// must be > DEFAULT_RATE_LIMIT_WINDOW_SECONDS
|
91
|
+
const DEFAULT_RATE_LIMIT_CACHE_TTL_SECONDS = 60;
|
89
92
|
async function authorizeWorker(authInput, serviceConfig) {
|
90
93
|
let authData;
|
91
94
|
try {
|
@@ -117,6 +120,14 @@ async function authorizeWorker(authInput, serviceConfig) {
|
|
117
120
|
cacheTtlSeconds: serviceConfig.cacheTtlSeconds ?? DEFAULT_CACHE_TTL_SECONDS
|
118
121
|
});
|
119
122
|
}
|
123
|
+
async function rateLimitWorker(authzResult, serviceConfig) {
|
124
|
+
return await index.rateLimit(authzResult, serviceConfig, {
|
125
|
+
get: async bucketId => serviceConfig.kvStore.get(bucketId),
|
126
|
+
put: (bucketId, count) => serviceConfig.kvStore.put(bucketId, count, {
|
127
|
+
expirationTtl: DEFAULT_RATE_LIMIT_CACHE_TTL_SECONDS
|
128
|
+
})
|
129
|
+
});
|
130
|
+
}
|
120
131
|
async function extractAuthorizationData(authInput) {
|
121
132
|
const requestUrl = new URL(authInput.req.url);
|
122
133
|
const headers = authInput.req.headers;
|
@@ -228,6 +239,8 @@ async function logHttpRequest(_ref) {
|
|
228
239
|
console.log(`statusMessage=${statusMessage ?? res.statusText}`);
|
229
240
|
}
|
230
241
|
|
242
|
+
exports.rateLimit = index.rateLimit;
|
243
|
+
exports.usageLimit = index.usageLimit;
|
231
244
|
exports.SERVICES = services.SERVICES;
|
232
245
|
exports.SERVICE_DEFINITIONS = services.SERVICE_DEFINITIONS;
|
233
246
|
exports.SERVICE_NAMES = services.SERVICE_NAMES;
|
@@ -238,3 +251,4 @@ exports.extractAuthorizationData = extractAuthorizationData;
|
|
238
251
|
exports.hashSecretKey = hashSecretKey;
|
239
252
|
exports.logHttpRequest = logHttpRequest;
|
240
253
|
exports.publishUsageEvents = publishUsageEvents;
|
254
|
+
exports.rateLimitWorker = rateLimitWorker;
|
@@ -2,10 +2,10 @@
|
|
2
2
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
4
4
|
|
5
|
-
var index = require('../../dist/index-
|
6
|
-
var services = require('../../dist/services-9e185105.cjs.prod.js');
|
5
|
+
var index = require('../../dist/index-cfc8027b.cjs.prod.js');
|
7
6
|
var aws4fetch = require('aws4fetch');
|
8
7
|
var zod = require('zod');
|
8
|
+
var services = require('../../dist/services-9e185105.cjs.prod.js');
|
9
9
|
|
10
10
|
// Initialize a singleton for aws usage.
|
11
11
|
let _aws;
|
@@ -20,7 +20,7 @@ function getAws(options) {
|
|
20
20
|
* Types
|
21
21
|
*/
|
22
22
|
const usageEventSchema = zod.z.object({
|
23
|
-
source: zod.z.enum(["
|
23
|
+
source: zod.z.enum(["embeddedWallets", "rpc", "storage", "bundler", "paymaster", "relayer"]),
|
24
24
|
action: zod.z.string(),
|
25
25
|
accountId: zod.z.string(),
|
26
26
|
// Optional
|
@@ -33,10 +33,11 @@ const usageEventSchema = zod.z.object({
|
|
33
33
|
mimeType: zod.z.string().optional(),
|
34
34
|
fileSize: zod.z.number().int().nonnegative().optional(),
|
35
35
|
fileCid: zod.z.string().optional(),
|
36
|
-
|
36
|
+
evmMethod: zod.z.string().optional(),
|
37
|
+
userOpHash: zod.z.string().optional(),
|
37
38
|
gasLimit: zod.z.number().nonnegative().optional(),
|
38
39
|
gasPricePerUnit: zod.z.string().optional(),
|
39
|
-
|
40
|
+
transactionHash: zod.z.string().optional()
|
40
41
|
});
|
41
42
|
/**
|
42
43
|
* Publish usage events. Provide the relevant fields for your application.
|
@@ -86,6 +87,8 @@ async function publishUsageEvents(usageEvents, config) {
|
|
86
87
|
}
|
87
88
|
|
88
89
|
const DEFAULT_CACHE_TTL_SECONDS = 60;
|
90
|
+
// must be > DEFAULT_RATE_LIMIT_WINDOW_SECONDS
|
91
|
+
const DEFAULT_RATE_LIMIT_CACHE_TTL_SECONDS = 60;
|
89
92
|
async function authorizeWorker(authInput, serviceConfig) {
|
90
93
|
let authData;
|
91
94
|
try {
|
@@ -117,6 +120,14 @@ async function authorizeWorker(authInput, serviceConfig) {
|
|
117
120
|
cacheTtlSeconds: serviceConfig.cacheTtlSeconds ?? DEFAULT_CACHE_TTL_SECONDS
|
118
121
|
});
|
119
122
|
}
|
123
|
+
async function rateLimitWorker(authzResult, serviceConfig) {
|
124
|
+
return await index.rateLimit(authzResult, serviceConfig, {
|
125
|
+
get: async bucketId => serviceConfig.kvStore.get(bucketId),
|
126
|
+
put: (bucketId, count) => serviceConfig.kvStore.put(bucketId, count, {
|
127
|
+
expirationTtl: DEFAULT_RATE_LIMIT_CACHE_TTL_SECONDS
|
128
|
+
})
|
129
|
+
});
|
130
|
+
}
|
120
131
|
async function extractAuthorizationData(authInput) {
|
121
132
|
const requestUrl = new URL(authInput.req.url);
|
122
133
|
const headers = authInput.req.headers;
|
@@ -228,6 +239,8 @@ async function logHttpRequest(_ref) {
|
|
228
239
|
console.log(`statusMessage=${statusMessage ?? res.statusText}`);
|
229
240
|
}
|
230
241
|
|
242
|
+
exports.rateLimit = index.rateLimit;
|
243
|
+
exports.usageLimit = index.usageLimit;
|
231
244
|
exports.SERVICES = services.SERVICES;
|
232
245
|
exports.SERVICE_DEFINITIONS = services.SERVICE_DEFINITIONS;
|
233
246
|
exports.SERVICE_NAMES = services.SERVICE_NAMES;
|
@@ -238,3 +251,4 @@ exports.extractAuthorizationData = extractAuthorizationData;
|
|
238
251
|
exports.hashSecretKey = hashSecretKey;
|
239
252
|
exports.logHttpRequest = logHttpRequest;
|
240
253
|
exports.publishUsageEvents = publishUsageEvents;
|
254
|
+
exports.rateLimitWorker = rateLimitWorker;
|
@@ -1,7 +1,8 @@
|
|
1
|
-
import { a as authorize } from '../../dist/index-
|
2
|
-
export {
|
1
|
+
import { a as authorize, r as rateLimit } from '../../dist/index-bcf68113.esm.js';
|
2
|
+
export { r as rateLimit, u as usageLimit } from '../../dist/index-bcf68113.esm.js';
|
3
3
|
import { AwsClient } from 'aws4fetch';
|
4
4
|
import { z } from 'zod';
|
5
|
+
export { b as SERVICES, S as SERVICE_DEFINITIONS, a as SERVICE_NAMES, g as getServiceByName } from '../../dist/services-86283509.esm.js';
|
5
6
|
|
6
7
|
// Initialize a singleton for aws usage.
|
7
8
|
let _aws;
|
@@ -16,7 +17,7 @@ function getAws(options) {
|
|
16
17
|
* Types
|
17
18
|
*/
|
18
19
|
const usageEventSchema = z.object({
|
19
|
-
source: z.enum(["
|
20
|
+
source: z.enum(["embeddedWallets", "rpc", "storage", "bundler", "paymaster", "relayer"]),
|
20
21
|
action: z.string(),
|
21
22
|
accountId: z.string(),
|
22
23
|
// Optional
|
@@ -29,10 +30,11 @@ const usageEventSchema = z.object({
|
|
29
30
|
mimeType: z.string().optional(),
|
30
31
|
fileSize: z.number().int().nonnegative().optional(),
|
31
32
|
fileCid: z.string().optional(),
|
32
|
-
|
33
|
+
evmMethod: z.string().optional(),
|
34
|
+
userOpHash: z.string().optional(),
|
33
35
|
gasLimit: z.number().nonnegative().optional(),
|
34
36
|
gasPricePerUnit: z.string().optional(),
|
35
|
-
|
37
|
+
transactionHash: z.string().optional()
|
36
38
|
});
|
37
39
|
/**
|
38
40
|
* Publish usage events. Provide the relevant fields for your application.
|
@@ -82,6 +84,8 @@ async function publishUsageEvents(usageEvents, config) {
|
|
82
84
|
}
|
83
85
|
|
84
86
|
const DEFAULT_CACHE_TTL_SECONDS = 60;
|
87
|
+
// must be > DEFAULT_RATE_LIMIT_WINDOW_SECONDS
|
88
|
+
const DEFAULT_RATE_LIMIT_CACHE_TTL_SECONDS = 60;
|
85
89
|
async function authorizeWorker(authInput, serviceConfig) {
|
86
90
|
let authData;
|
87
91
|
try {
|
@@ -113,6 +117,14 @@ async function authorizeWorker(authInput, serviceConfig) {
|
|
113
117
|
cacheTtlSeconds: serviceConfig.cacheTtlSeconds ?? DEFAULT_CACHE_TTL_SECONDS
|
114
118
|
});
|
115
119
|
}
|
120
|
+
async function rateLimitWorker(authzResult, serviceConfig) {
|
121
|
+
return await rateLimit(authzResult, serviceConfig, {
|
122
|
+
get: async bucketId => serviceConfig.kvStore.get(bucketId),
|
123
|
+
put: (bucketId, count) => serviceConfig.kvStore.put(bucketId, count, {
|
124
|
+
expirationTtl: DEFAULT_RATE_LIMIT_CACHE_TTL_SECONDS
|
125
|
+
})
|
126
|
+
});
|
127
|
+
}
|
116
128
|
async function extractAuthorizationData(authInput) {
|
117
129
|
const requestUrl = new URL(authInput.req.url);
|
118
130
|
const headers = authInput.req.headers;
|
@@ -224,4 +236,4 @@ async function logHttpRequest(_ref) {
|
|
224
236
|
console.log(`statusMessage=${statusMessage ?? res.statusText}`);
|
225
237
|
}
|
226
238
|
|
227
|
-
export { authorizeWorker, deriveClientIdFromSecretKeyHash, extractAuthorizationData, hashSecretKey, logHttpRequest, publishUsageEvents };
|
239
|
+
export { authorizeWorker, deriveClientIdFromSecretKeyHash, extractAuthorizationData, hashSecretKey, logHttpRequest, publishUsageEvents, rateLimitWorker };
|
@@ -3,10 +3,13 @@ import type { CoreServiceConfig } from "../core/api";
|
|
3
3
|
import type { Request } from "@cloudflare/workers-types";
|
4
4
|
import type { AuthorizationInput } from "../core/authorize";
|
5
5
|
import type { AuthorizationResult } from "../core/authorize/types";
|
6
|
+
import type { RateLimitResult } from "../core/rateLimit/types";
|
6
7
|
import type { CoreAuthInput } from "../core/types";
|
7
|
-
export * from "../core/services";
|
8
8
|
export * from "./usage";
|
9
|
-
|
9
|
+
export * from "../core/services";
|
10
|
+
export * from "../core/rateLimit";
|
11
|
+
export * from "../core/usageLimit";
|
12
|
+
export type WorkerServiceConfig = CoreServiceConfig & {
|
10
13
|
kvStore: KVNamespace;
|
11
14
|
ctx: ExecutionContext;
|
12
15
|
cacheTtlSeconds?: number;
|
@@ -15,6 +18,7 @@ type AuthInput = CoreAuthInput & {
|
|
15
18
|
req: Request;
|
16
19
|
};
|
17
20
|
export declare function authorizeWorker(authInput: AuthInput, serviceConfig: WorkerServiceConfig): Promise<AuthorizationResult>;
|
21
|
+
export declare function rateLimitWorker(authzResult: AuthorizationResult, serviceConfig: WorkerServiceConfig): Promise<RateLimitResult>;
|
18
22
|
export declare function extractAuthorizationData(authInput: AuthInput): Promise<AuthorizationInput>;
|
19
23
|
export declare function hashSecretKey(secretKey: string): Promise<string>;
|
20
24
|
export declare function deriveClientIdFromSecretKeyHash(secretKeyHash: string): string;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"../../../../src/cf-worker","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,WAAW,EACX,QAAQ,EACT,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAGV,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"../../../../src/cf-worker","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,gBAAgB,EAChB,WAAW,EACX,QAAQ,EACT,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAGV,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAGrB,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAGnD,cAAc,SAAS,CAAC;AACxB,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AAEnC,MAAM,MAAM,mBAAmB,GAAG,iBAAiB,GAAG;IACpD,OAAO,EAAE,WAAW,CAAC;IACrB,GAAG,EAAE,gBAAgB,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B,CAAC;AAMF,KAAK,SAAS,GAAG,aAAa,GAAG;IAC/B,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF,wBAAsB,eAAe,CACnC,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,mBAAmB,GACjC,OAAO,CAAC,mBAAmB,CAAC,CA0C9B;AAED,wBAAsB,eAAe,CACnC,WAAW,EAAE,mBAAmB,EAChC,aAAa,EAAE,mBAAmB,GACjC,OAAO,CAAC,eAAe,CAAC,CAQ1B;AAED,wBAAsB,wBAAwB,CAC5C,SAAS,EAAE,SAAS,GACnB,OAAO,CAAC,kBAAkB,CAAC,CA2E7B;AAED,wBAAsB,aAAa,CAAC,SAAS,EAAE,MAAM,mBAIpD;AAED,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,MAAM,UAEpE;AAQD,wBAAsB,cAAc,CAAC,EACnC,MAAM,EACN,QAAQ,EACR,GAAG,EACH,GAAG,EACH,QAAQ,EACR,aAAa,GACd,EAAE,SAAS,GAAG;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,QAAQ,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAChC,iBAoBA"}
|
@@ -3,7 +3,7 @@ import { z } from "zod";
|
|
3
3
|
* Types
|
4
4
|
*/
|
5
5
|
declare const usageEventSchema: z.ZodObject<{
|
6
|
-
source: z.ZodEnum<["
|
6
|
+
source: z.ZodEnum<["embeddedWallets", "rpc", "storage", "bundler", "paymaster", "relayer"]>;
|
7
7
|
action: z.ZodString;
|
8
8
|
accountId: z.ZodString;
|
9
9
|
apiKeyId: z.ZodOptional<z.ZodString>;
|
@@ -15,14 +15,15 @@ declare const usageEventSchema: z.ZodObject<{
|
|
15
15
|
mimeType: z.ZodOptional<z.ZodString>;
|
16
16
|
fileSize: z.ZodOptional<z.ZodNumber>;
|
17
17
|
fileCid: z.ZodOptional<z.ZodString>;
|
18
|
-
|
18
|
+
evmMethod: z.ZodOptional<z.ZodString>;
|
19
|
+
userOpHash: z.ZodOptional<z.ZodString>;
|
19
20
|
gasLimit: z.ZodOptional<z.ZodNumber>;
|
20
21
|
gasPricePerUnit: z.ZodOptional<z.ZodString>;
|
21
|
-
|
22
|
+
transactionHash: z.ZodOptional<z.ZodString>;
|
22
23
|
}, "strip", z.ZodTypeAny, {
|
23
|
-
source: "storage" | "rpc" | "bundler" | "relayer" | "
|
24
|
-
action: string;
|
24
|
+
source: "storage" | "rpc" | "bundler" | "relayer" | "embeddedWallets" | "paymaster";
|
25
25
|
accountId: string;
|
26
|
+
action: string;
|
26
27
|
apiKeyId?: string | undefined;
|
27
28
|
creatorWalletAddress?: string | undefined;
|
28
29
|
clientId?: string | undefined;
|
@@ -32,14 +33,15 @@ declare const usageEventSchema: z.ZodObject<{
|
|
32
33
|
mimeType?: string | undefined;
|
33
34
|
fileSize?: number | undefined;
|
34
35
|
fileCid?: string | undefined;
|
35
|
-
|
36
|
+
evmMethod?: string | undefined;
|
37
|
+
userOpHash?: string | undefined;
|
36
38
|
gasLimit?: number | undefined;
|
37
39
|
gasPricePerUnit?: string | undefined;
|
38
|
-
|
40
|
+
transactionHash?: string | undefined;
|
39
41
|
}, {
|
40
|
-
source: "storage" | "rpc" | "bundler" | "relayer" | "
|
41
|
-
action: string;
|
42
|
+
source: "storage" | "rpc" | "bundler" | "relayer" | "embeddedWallets" | "paymaster";
|
42
43
|
accountId: string;
|
44
|
+
action: string;
|
43
45
|
apiKeyId?: string | undefined;
|
44
46
|
creatorWalletAddress?: string | undefined;
|
45
47
|
clientId?: string | undefined;
|
@@ -49,10 +51,11 @@ declare const usageEventSchema: z.ZodObject<{
|
|
49
51
|
mimeType?: string | undefined;
|
50
52
|
fileSize?: number | undefined;
|
51
53
|
fileCid?: string | undefined;
|
52
|
-
|
54
|
+
evmMethod?: string | undefined;
|
55
|
+
userOpHash?: string | undefined;
|
53
56
|
gasLimit?: number | undefined;
|
54
57
|
gasPricePerUnit?: string | undefined;
|
55
|
-
|
58
|
+
transactionHash?: string | undefined;
|
56
59
|
}>;
|
57
60
|
export type UsageEvent = z.infer<typeof usageEventSchema>;
|
58
61
|
/**
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"usage.d.ts","sourceRoot":"../../../../src/cf-worker","sources":["usage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB;;GAEG;AACH,QAAA,MAAM,gBAAgB
|
1
|
+
{"version":3,"file":"usage.d.ts","sourceRoot":"../../../../src/cf-worker","sources":["usage.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAWxB;;GAEG;AACH,QAAA,MAAM,gBAAgB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2BpB,CAAC;AACH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gBAAgB,CAAC,CAAC;AAE1D;;;;;;;;;;;;;GAaG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,UAAU,EAAE,EACzB,MAAM,EAAE;IACN,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,GACA,OAAO,CAAC,IAAI,CAAC,CAiCf"}
|
@@ -1,12 +1,20 @@
|
|
1
1
|
import type { ServiceName } from "./services";
|
2
2
|
export type CoreServiceConfig = {
|
3
|
-
enforceAuth
|
3
|
+
enforceAuth?: boolean;
|
4
4
|
apiUrl: string;
|
5
5
|
serviceScope: ServiceName;
|
6
6
|
serviceApiKey: string;
|
7
7
|
serviceAction?: string;
|
8
8
|
useWalletAuth?: boolean;
|
9
9
|
};
|
10
|
+
type Usage = {
|
11
|
+
storage?: {
|
12
|
+
sumFileSizeBytes: number;
|
13
|
+
};
|
14
|
+
embeddedWallets?: {
|
15
|
+
countWalletAddresses: number;
|
16
|
+
};
|
17
|
+
};
|
10
18
|
export type ApiKeyMetadata = {
|
11
19
|
id: string;
|
12
20
|
key: string;
|
@@ -23,11 +31,17 @@ export type ApiKeyMetadata = {
|
|
23
31
|
targetAddresses: string[];
|
24
32
|
actions: string[];
|
25
33
|
}[];
|
34
|
+
usage?: Usage;
|
35
|
+
limits: Partial<Record<ServiceName, number>>;
|
36
|
+
rateLimits: Partial<Record<ServiceName, number>>;
|
26
37
|
};
|
27
38
|
export type AccountMetadata = {
|
28
39
|
id: string;
|
29
40
|
name: string;
|
30
41
|
creatorWalletAddress: string;
|
42
|
+
usage?: Usage;
|
43
|
+
limits: Partial<Record<ServiceName, number>>;
|
44
|
+
rateLimits: Partial<Record<ServiceName, number>>;
|
31
45
|
};
|
32
46
|
export type ApiResponse = {
|
33
47
|
data: ApiKeyMetadata | null;
|
@@ -47,4 +61,6 @@ export type ApiAccountResponse = {
|
|
47
61
|
};
|
48
62
|
export declare function fetchKeyMetadataFromApi(clientId: string, config: CoreServiceConfig): Promise<ApiResponse>;
|
49
63
|
export declare function fetchAccountFromApi(jwt: string, config: CoreServiceConfig, useWalletAuth: boolean): Promise<ApiAccountResponse>;
|
64
|
+
export declare function updateRateLimitedAt(apiKeyId: string, config: CoreServiceConfig): Promise<void>;
|
65
|
+
export {};
|
50
66
|
//# sourceMappingURL=api.d.ts.map
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"api.d.ts","sourceRoot":"../../../../src/core","sources":["api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
1
|
+
{"version":3,"file":"api.d.ts","sourceRoot":"../../../../src/core","sources":["api.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,WAAW,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,KAAK,KAAK,GAAG;IACX,OAAO,CAAC,EAAE;QACR,gBAAgB,EAAE,MAAM,CAAC;KAC1B,CAAC;IACF,eAAe,CAAC,EAAE;QAChB,oBAAoB,EAAE,MAAM,CAAC;KAC9B,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,cAAc,GAAG;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,YAAY,GAAG,WAAW,GAAG,cAAc,GAAG,gBAAgB,CAAC;IAC9E,WAAW,EAAE,MAAM,GAAG,YAAY,CAAC;IACnC,oBAAoB,EAAE,MAAM,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,OAAO,EAAE,MAAM,EAAE,CAAC;KACnB,EAAE,CAAC;IACJ,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,MAAM,CAAC;IAC7B,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;IAC7C,UAAU,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC;CAClD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACxB,IAAI,EAAE,cAAc,GAAG,IAAI,CAAC;IAC5B,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,eAAe,GAAG,IAAI,CAAC;IAC7B,KAAK,EAAE;QACL,IAAI,EAAE,MAAM,CAAC;QACb,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH,CAAC;AAEF,wBAAsB,uBAAuB,CAC3C,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,WAAW,CAAC,CAqBtB;AAED,wBAAsB,mBAAmB,CACvC,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,iBAAiB,EACzB,aAAa,EAAE,OAAO,GACrB,OAAO,CAAC,kBAAkB,CAAC,CAwB7B;AAED,wBAAsB,mBAAmB,CACvC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,iBAAiB,GACxB,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"../../../../../src/core/authorize","sources":["client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,MAAM,0BAA0B,GAAG;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,wBAAgB,eAAe,CAC7B,WAAW,EAAE,0BAA0B,EACvC,UAAU,EAAE,cAAc,GACzB,mBAAmB,
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"../../../../../src/core/authorize","sources":["client.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAC;AAC7C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAEnD,MAAM,MAAM,0BAA0B,GAAG;IACvC,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AAEF,wBAAgB,eAAe,CAC7B,WAAW,EAAE,0BAA0B,EACvC,UAAU,EAAE,cAAc,GACzB,mBAAmB,CA2GrB"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"../../../../../src/core/authorize","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,cAAc,EACd,iBAAiB,EAGlB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAElC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClD,GAAG,EAAE,CACH,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,GAAG,eAAe,KACnC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAgBF,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,kBAAkB,EAC5B,aAAa,EAAE,iBAAiB,EAChC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,mBAAmB,CAAC,
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"../../../../../src/core/authorize","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,eAAe,EACf,cAAc,EACd,iBAAiB,EAGlB,MAAM,QAAQ,CAAC;AAGhB,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,kBAAkB,GAAG;IAC/B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAElC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClD,GAAG,EAAE,CACH,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,cAAc,GAAG,eAAe,KACnC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,eAAe,EAAE,MAAM,CAAC;CACzB,CAAC;AAgBF,wBAAsB,SAAS,CAC7B,QAAQ,EAAE,kBAAkB,EAC5B,aAAa,EAAE,iBAAiB,EAChC,YAAY,CAAC,EAAE,YAAY,GAC1B,OAAO,CAAC,mBAAmB,CAAC,CAsN9B"}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"service.d.ts","sourceRoot":"../../../../../src/core/authorize","sources":["service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,2BAA2B,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,CAAC;AAEhF,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,iBAAiB,EAChC,oBAAoB,CAAC,EAAE,2BAA2B,GACjD,mBAAmB,
|
1
|
+
{"version":3,"file":"service.d.ts","sourceRoot":"../../../../../src/core/authorize","sources":["service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3D,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAE9C,MAAM,MAAM,2BAA2B,GAAG;IAAE,aAAa,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAA;CAAE,CAAC;AAEhF,wBAAgB,gBAAgB,CAC9B,cAAc,EAAE,cAAc,EAC9B,aAAa,EAAE,iBAAiB,EAChC,oBAAoB,CAAC,EAAE,2BAA2B,GACjD,mBAAmB,CAgErB"}
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { CoreServiceConfig } from "../api";
|
2
|
+
import { AuthorizationResult } from "../authorize/types";
|
3
|
+
import { RateLimitResult } from "./types";
|
4
|
+
type CacheOptions = {
|
5
|
+
get: (bucketId: string) => Promise<string | null>;
|
6
|
+
put: (bucketId: string, count: string) => Promise<void> | void;
|
7
|
+
};
|
8
|
+
export declare function rateLimit(authzResult: AuthorizationResult, serviceConfig: CoreServiceConfig, cacheOptions: CacheOptions): Promise<RateLimitResult>;
|
9
|
+
export {};
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"../../../../../src/core/rateLimit","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAuB,MAAM,QAAQ,CAAC;AAChE,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAK1C,KAAK,YAAY,GAAG;IAClB,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IAClD,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;CAChE,CAAC;AAEF,wBAAsB,SAAS,CAC7B,WAAW,EAAE,mBAAmB,EAChC,aAAa,EAAE,iBAAiB,EAChC,YAAY,EAAE,YAAY,GACzB,OAAO,CAAC,eAAe,CAAC,CAuD1B"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"../../../../../src/core/rateLimit","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GACvB;IACE,WAAW,EAAE,KAAK,CAAC;CACpB,GACD;IACE,WAAW,EAAE,IAAI,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
@@ -0,0 +1,5 @@
|
|
1
|
+
import { CoreServiceConfig } from "../api";
|
2
|
+
import { AuthorizationResult } from "../authorize/types";
|
3
|
+
import { UsageLimitResult } from "./types";
|
4
|
+
export declare function usageLimit(authzResult: AuthorizationResult, serviceConfig: CoreServiceConfig): Promise<UsageLimitResult>;
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"../../../../../src/core/usageLimit","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AAE3C,wBAAsB,UAAU,CAC9B,WAAW,EAAE,mBAAmB,EAChC,aAAa,EAAE,iBAAiB,GAC/B,OAAO,CAAC,gBAAgB,CAAC,CAwC3B"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"../../../../../src/core/usageLimit","sources":["types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,gBAAgB,GACxB;IACE,YAAY,EAAE,KAAK,CAAC;CACrB,GACD;IACE,YAAY,EAAE,IAAI,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
@@ -6,6 +6,8 @@ import type { AuthorizationInput } from "../core/authorize";
|
|
6
6
|
import type { AuthorizationResult } from "../core/authorize/types";
|
7
7
|
import type { CoreAuthInput } from "../core/types";
|
8
8
|
export * from "../core/services";
|
9
|
+
export * from "../core/rateLimit";
|
10
|
+
export * from "../core/usageLimit";
|
9
11
|
type NodeServiceConfig = CoreServiceConfig;
|
10
12
|
export type AuthInput = CoreAuthInput & {
|
11
13
|
req: IncomingMessage;
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"../../../../src/node","sources":["index.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,KAAK,EAAuB,eAAe,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,cAAc,kBAAkB,CAAC;
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"../../../../src/node","sources":["index.ts"],"names":[],"mappings":";AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,MAAM,CAAC;AAC3C,OAAO,KAAK,EAAuB,eAAe,EAAE,MAAM,WAAW,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AACnE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAEnD,cAAc,kBAAkB,CAAC;AACjC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AAEnC,KAAK,iBAAiB,GAAG,iBAAiB,CAAC;AAE3C,MAAM,MAAM,SAAS,GAAG,aAAa,GAAG;IACtC,GAAG,EAAE,eAAe,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,SAAS,EACpB,aAAa,EAAE,iBAAiB,GAC/B,OAAO,CAAC,mBAAmB,CAAC,CAsB9B;AAaD,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,SAAS,GACnB,kBAAkB,CA2FpB;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,UAE9C;AAED,wBAAgB,+BAA+B,CAAC,aAAa,EAAE,MAAM,UAEpE;AAED,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,QAAQ,EACR,GAAG,EACH,GAAG,EACH,QAAQ,EACR,aAAa,GACd,EAAE,SAAS,GAAG;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,cAAc,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;CAChC,QAsBA"}
|
@@ -6,7 +6,7 @@ async function fetchKeyMetadataFromApi(clientId, config) {
|
|
6
6
|
serviceScope,
|
7
7
|
serviceApiKey
|
8
8
|
} = config;
|
9
|
-
const url = `${apiUrl}/v1/keys/use?clientId=${clientId}&scope=${serviceScope}`;
|
9
|
+
const url = `${apiUrl}/v1/keys/use?clientId=${clientId}&scope=${serviceScope}&includeUsage=true`;
|
10
10
|
const response = await fetch(url, {
|
11
11
|
method: "GET",
|
12
12
|
headers: {
|
@@ -27,7 +27,7 @@ async function fetchAccountFromApi(jwt, config, useWalletAuth) {
|
|
27
27
|
apiUrl,
|
28
28
|
serviceApiKey
|
29
29
|
} = config;
|
30
|
-
const url = useWalletAuth ? `${apiUrl}/v1/wallet/me` : `${apiUrl}/v1/account/me`;
|
30
|
+
const url = useWalletAuth ? `${apiUrl}/v1/wallet/me?includeUsage=true` : `${apiUrl}/v1/account/me?includeUsage=true`;
|
31
31
|
const response = await fetch(url, {
|
32
32
|
method: "GET",
|
33
33
|
headers: {
|
@@ -44,6 +44,25 @@ async function fetchAccountFromApi(jwt, config, useWalletAuth) {
|
|
44
44
|
}
|
45
45
|
return json;
|
46
46
|
}
|
47
|
+
async function updateRateLimitedAt(apiKeyId, config) {
|
48
|
+
const {
|
49
|
+
apiUrl,
|
50
|
+
serviceScope: scope,
|
51
|
+
serviceApiKey
|
52
|
+
} = config;
|
53
|
+
const url = `${apiUrl}/usage/rateLimit`;
|
54
|
+
await fetch(url, {
|
55
|
+
method: "PUT",
|
56
|
+
headers: {
|
57
|
+
"x-service-api-key": serviceApiKey,
|
58
|
+
"content-type": "application/json"
|
59
|
+
},
|
60
|
+
body: JSON.stringify({
|
61
|
+
apiKeyId,
|
62
|
+
scope
|
63
|
+
})
|
64
|
+
});
|
65
|
+
}
|
47
66
|
|
48
67
|
function authorizeClient(authOptions, apiKeyMeta) {
|
49
68
|
const {
|
@@ -63,7 +82,10 @@ function authorizeClient(authOptions, apiKeyMeta) {
|
|
63
82
|
id: apiKeyMeta.accountId,
|
64
83
|
// TODO update this later
|
65
84
|
name: "",
|
66
|
-
creatorWalletAddress: apiKeyMeta.creatorWalletAddress
|
85
|
+
creatorWalletAddress: apiKeyMeta.creatorWalletAddress,
|
86
|
+
limits: apiKeyMeta.limits,
|
87
|
+
rateLimits: apiKeyMeta.rateLimits,
|
88
|
+
usage: apiKeyMeta.usage
|
67
89
|
}
|
68
90
|
};
|
69
91
|
|
@@ -193,12 +215,15 @@ function authorizeService(apiKeyMetadata, serviceConfig, authorizationPayload) {
|
|
193
215
|
}
|
194
216
|
return {
|
195
217
|
authorized: true,
|
218
|
+
apiKeyMeta: apiKeyMetadata,
|
196
219
|
accountMeta: {
|
197
220
|
id: apiKeyMetadata.accountId,
|
198
221
|
name: "",
|
199
|
-
creatorWalletAddress: apiKeyMetadata.creatorWalletAddress
|
200
|
-
|
201
|
-
|
222
|
+
creatorWalletAddress: apiKeyMetadata.creatorWalletAddress,
|
223
|
+
limits: apiKeyMetadata.limits,
|
224
|
+
rateLimits: apiKeyMetadata.rateLimits,
|
225
|
+
usage: apiKeyMetadata.usage
|
226
|
+
}
|
202
227
|
};
|
203
228
|
}
|
204
229
|
|
@@ -416,9 +441,110 @@ async function authorize(authData, serviceConfig, cacheOptions) {
|
|
416
441
|
id: apiKeyMeta.accountId,
|
417
442
|
// TODO update this later
|
418
443
|
name: "",
|
444
|
+
limits: apiKeyMeta.limits,
|
445
|
+
rateLimits: apiKeyMeta.rateLimits,
|
446
|
+
usage: apiKeyMeta.usage,
|
419
447
|
creatorWalletAddress: apiKeyMeta.creatorWalletAddress
|
420
448
|
}
|
421
449
|
};
|
422
450
|
}
|
423
451
|
|
452
|
+
const DEFAULT_RATE_LIMIT_WINDOW_SECONDS = 10;
|
453
|
+
const HARD_LIMIT_MULTIPLE = 2; // 2x of allowed limit
|
454
|
+
|
455
|
+
async function rateLimit(authzResult, serviceConfig, cacheOptions) {
|
456
|
+
if (!authzResult.authorized) {
|
457
|
+
return {
|
458
|
+
rateLimited: false
|
459
|
+
};
|
460
|
+
}
|
461
|
+
const {
|
462
|
+
apiKeyMeta,
|
463
|
+
accountMeta
|
464
|
+
} = authzResult;
|
465
|
+
const {
|
466
|
+
rateLimits
|
467
|
+
} = apiKeyMeta || accountMeta || {};
|
468
|
+
const accountId = apiKeyMeta?.accountId || accountMeta?.id;
|
469
|
+
const {
|
470
|
+
serviceScope
|
471
|
+
} = serviceConfig;
|
472
|
+
if (!rateLimits || !(serviceScope in rateLimits)) {
|
473
|
+
// No rate limit is provided. Assume the request is not rate limited.
|
474
|
+
return {
|
475
|
+
rateLimited: false
|
476
|
+
};
|
477
|
+
}
|
478
|
+
const limit = rateLimits[serviceScope];
|
479
|
+
|
480
|
+
// Floors the current time to the nearest DEFAULT_RATE_LIMIT_WINDOW_SECONDS.
|
481
|
+
const bucketId = Math.floor(Date.now() / (1000 * DEFAULT_RATE_LIMIT_WINDOW_SECONDS)) * DEFAULT_RATE_LIMIT_WINDOW_SECONDS;
|
482
|
+
const key = [serviceScope, accountId, bucketId].join(":");
|
483
|
+
const value = parseInt((await cacheOptions.get(key)) || "0");
|
484
|
+
const current = value + 1;
|
485
|
+
|
486
|
+
// limit is in seconds, but we need in DEFAULT_RATE_LIMIT_WINDOW_SECONDS
|
487
|
+
const limitWindow = limit * DEFAULT_RATE_LIMIT_WINDOW_SECONDS;
|
488
|
+
if (current > limitWindow) {
|
489
|
+
// report rate limit hits
|
490
|
+
if (apiKeyMeta?.id) {
|
491
|
+
await updateRateLimitedAt(apiKeyMeta.id, serviceConfig);
|
492
|
+
}
|
493
|
+
|
494
|
+
// actually rate limit only when reached hard limit
|
495
|
+
if (current > limitWindow * HARD_LIMIT_MULTIPLE) {
|
496
|
+
return {
|
497
|
+
rateLimited: true,
|
498
|
+
status: 429,
|
499
|
+
errorMessage: `You've exceeded your ${serviceScope} rate limit at ${limit} reqs/sec. To get higher rate limits, contact us at https://thirdweb.com/contact-us.`,
|
500
|
+
errorCode: "RATE_LIMIT_EXCEEDED"
|
501
|
+
};
|
502
|
+
}
|
503
|
+
} else {
|
504
|
+
await cacheOptions.put(key, current.toString());
|
505
|
+
}
|
506
|
+
return {
|
507
|
+
rateLimited: false
|
508
|
+
};
|
509
|
+
}
|
510
|
+
|
511
|
+
async function usageLimit(authzResult, serviceConfig) {
|
512
|
+
if (!authzResult.authorized) {
|
513
|
+
return {
|
514
|
+
usageLimited: false
|
515
|
+
};
|
516
|
+
}
|
517
|
+
const {
|
518
|
+
apiKeyMeta,
|
519
|
+
accountMeta
|
520
|
+
} = authzResult;
|
521
|
+
const {
|
522
|
+
limits,
|
523
|
+
usage
|
524
|
+
} = apiKeyMeta || accountMeta || {};
|
525
|
+
const {
|
526
|
+
serviceScope
|
527
|
+
} = serviceConfig;
|
528
|
+
if (!usage || !(serviceScope in usage) || !limits || !(serviceScope in limits)) {
|
529
|
+
// No usage limit is provided. Assume the request is not limited.
|
530
|
+
return {
|
531
|
+
usageLimited: false
|
532
|
+
};
|
533
|
+
}
|
534
|
+
const limit = limits.storage;
|
535
|
+
if (serviceScope === "storage" && (usage.storage?.sumFileSizeBytes || 0) > limit) {
|
536
|
+
return {
|
537
|
+
usageLimited: true,
|
538
|
+
status: 403,
|
539
|
+
errorMessage: `You've used all of your total usage limit for Storage Pinning. Please add your payment method at https://thirdweb.com/dashboard/settings/billing.`,
|
540
|
+
errorCode: "PAYMENT_METHOD_REQUIRED"
|
541
|
+
};
|
542
|
+
}
|
543
|
+
return {
|
544
|
+
usageLimited: false
|
545
|
+
};
|
546
|
+
}
|
547
|
+
|
424
548
|
exports.authorize = authorize;
|
549
|
+
exports.rateLimit = rateLimit;
|
550
|
+
exports.usageLimit = usageLimit;
|
@@ -4,7 +4,7 @@ async function fetchKeyMetadataFromApi(clientId, config) {
|
|
4
4
|
serviceScope,
|
5
5
|
serviceApiKey
|
6
6
|
} = config;
|
7
|
-
const url = `${apiUrl}/v1/keys/use?clientId=${clientId}&scope=${serviceScope}`;
|
7
|
+
const url = `${apiUrl}/v1/keys/use?clientId=${clientId}&scope=${serviceScope}&includeUsage=true`;
|
8
8
|
const response = await fetch(url, {
|
9
9
|
method: "GET",
|
10
10
|
headers: {
|
@@ -25,7 +25,7 @@ async function fetchAccountFromApi(jwt, config, useWalletAuth) {
|
|
25
25
|
apiUrl,
|
26
26
|
serviceApiKey
|
27
27
|
} = config;
|
28
|
-
const url = useWalletAuth ? `${apiUrl}/v1/wallet/me` : `${apiUrl}/v1/account/me`;
|
28
|
+
const url = useWalletAuth ? `${apiUrl}/v1/wallet/me?includeUsage=true` : `${apiUrl}/v1/account/me?includeUsage=true`;
|
29
29
|
const response = await fetch(url, {
|
30
30
|
method: "GET",
|
31
31
|
headers: {
|
@@ -42,6 +42,25 @@ async function fetchAccountFromApi(jwt, config, useWalletAuth) {
|
|
42
42
|
}
|
43
43
|
return json;
|
44
44
|
}
|
45
|
+
async function updateRateLimitedAt(apiKeyId, config) {
|
46
|
+
const {
|
47
|
+
apiUrl,
|
48
|
+
serviceScope: scope,
|
49
|
+
serviceApiKey
|
50
|
+
} = config;
|
51
|
+
const url = `${apiUrl}/usage/rateLimit`;
|
52
|
+
await fetch(url, {
|
53
|
+
method: "PUT",
|
54
|
+
headers: {
|
55
|
+
"x-service-api-key": serviceApiKey,
|
56
|
+
"content-type": "application/json"
|
57
|
+
},
|
58
|
+
body: JSON.stringify({
|
59
|
+
apiKeyId,
|
60
|
+
scope
|
61
|
+
})
|
62
|
+
});
|
63
|
+
}
|
45
64
|
|
46
65
|
function authorizeClient(authOptions, apiKeyMeta) {
|
47
66
|
const {
|
@@ -61,7 +80,10 @@ function authorizeClient(authOptions, apiKeyMeta) {
|
|
61
80
|
id: apiKeyMeta.accountId,
|
62
81
|
// TODO update this later
|
63
82
|
name: "",
|
64
|
-
creatorWalletAddress: apiKeyMeta.creatorWalletAddress
|
83
|
+
creatorWalletAddress: apiKeyMeta.creatorWalletAddress,
|
84
|
+
limits: apiKeyMeta.limits,
|
85
|
+
rateLimits: apiKeyMeta.rateLimits,
|
86
|
+
usage: apiKeyMeta.usage
|
65
87
|
}
|
66
88
|
};
|
67
89
|
|
@@ -191,12 +213,15 @@ function authorizeService(apiKeyMetadata, serviceConfig, authorizationPayload) {
|
|
191
213
|
}
|
192
214
|
return {
|
193
215
|
authorized: true,
|
216
|
+
apiKeyMeta: apiKeyMetadata,
|
194
217
|
accountMeta: {
|
195
218
|
id: apiKeyMetadata.accountId,
|
196
219
|
name: "",
|
197
|
-
creatorWalletAddress: apiKeyMetadata.creatorWalletAddress
|
198
|
-
|
199
|
-
|
220
|
+
creatorWalletAddress: apiKeyMetadata.creatorWalletAddress,
|
221
|
+
limits: apiKeyMetadata.limits,
|
222
|
+
rateLimits: apiKeyMetadata.rateLimits,
|
223
|
+
usage: apiKeyMetadata.usage
|
224
|
+
}
|
200
225
|
};
|
201
226
|
}
|
202
227
|
|
@@ -414,9 +439,108 @@ async function authorize(authData, serviceConfig, cacheOptions) {
|
|
414
439
|
id: apiKeyMeta.accountId,
|
415
440
|
// TODO update this later
|
416
441
|
name: "",
|
442
|
+
limits: apiKeyMeta.limits,
|
443
|
+
rateLimits: apiKeyMeta.rateLimits,
|
444
|
+
usage: apiKeyMeta.usage,
|
417
445
|
creatorWalletAddress: apiKeyMeta.creatorWalletAddress
|
418
446
|
}
|
419
447
|
};
|
420
448
|
}
|
421
449
|
|
422
|
-
|
450
|
+
const DEFAULT_RATE_LIMIT_WINDOW_SECONDS = 10;
|
451
|
+
const HARD_LIMIT_MULTIPLE = 2; // 2x of allowed limit
|
452
|
+
|
453
|
+
async function rateLimit(authzResult, serviceConfig, cacheOptions) {
|
454
|
+
if (!authzResult.authorized) {
|
455
|
+
return {
|
456
|
+
rateLimited: false
|
457
|
+
};
|
458
|
+
}
|
459
|
+
const {
|
460
|
+
apiKeyMeta,
|
461
|
+
accountMeta
|
462
|
+
} = authzResult;
|
463
|
+
const {
|
464
|
+
rateLimits
|
465
|
+
} = apiKeyMeta || accountMeta || {};
|
466
|
+
const accountId = apiKeyMeta?.accountId || accountMeta?.id;
|
467
|
+
const {
|
468
|
+
serviceScope
|
469
|
+
} = serviceConfig;
|
470
|
+
if (!rateLimits || !(serviceScope in rateLimits)) {
|
471
|
+
// No rate limit is provided. Assume the request is not rate limited.
|
472
|
+
return {
|
473
|
+
rateLimited: false
|
474
|
+
};
|
475
|
+
}
|
476
|
+
const limit = rateLimits[serviceScope];
|
477
|
+
|
478
|
+
// Floors the current time to the nearest DEFAULT_RATE_LIMIT_WINDOW_SECONDS.
|
479
|
+
const bucketId = Math.floor(Date.now() / (1000 * DEFAULT_RATE_LIMIT_WINDOW_SECONDS)) * DEFAULT_RATE_LIMIT_WINDOW_SECONDS;
|
480
|
+
const key = [serviceScope, accountId, bucketId].join(":");
|
481
|
+
const value = parseInt((await cacheOptions.get(key)) || "0");
|
482
|
+
const current = value + 1;
|
483
|
+
|
484
|
+
// limit is in seconds, but we need in DEFAULT_RATE_LIMIT_WINDOW_SECONDS
|
485
|
+
const limitWindow = limit * DEFAULT_RATE_LIMIT_WINDOW_SECONDS;
|
486
|
+
if (current > limitWindow) {
|
487
|
+
// report rate limit hits
|
488
|
+
if (apiKeyMeta?.id) {
|
489
|
+
await updateRateLimitedAt(apiKeyMeta.id, serviceConfig);
|
490
|
+
}
|
491
|
+
|
492
|
+
// actually rate limit only when reached hard limit
|
493
|
+
if (current > limitWindow * HARD_LIMIT_MULTIPLE) {
|
494
|
+
return {
|
495
|
+
rateLimited: true,
|
496
|
+
status: 429,
|
497
|
+
errorMessage: `You've exceeded your ${serviceScope} rate limit at ${limit} reqs/sec. To get higher rate limits, contact us at https://thirdweb.com/contact-us.`,
|
498
|
+
errorCode: "RATE_LIMIT_EXCEEDED"
|
499
|
+
};
|
500
|
+
}
|
501
|
+
} else {
|
502
|
+
await cacheOptions.put(key, current.toString());
|
503
|
+
}
|
504
|
+
return {
|
505
|
+
rateLimited: false
|
506
|
+
};
|
507
|
+
}
|
508
|
+
|
509
|
+
async function usageLimit(authzResult, serviceConfig) {
|
510
|
+
if (!authzResult.authorized) {
|
511
|
+
return {
|
512
|
+
usageLimited: false
|
513
|
+
};
|
514
|
+
}
|
515
|
+
const {
|
516
|
+
apiKeyMeta,
|
517
|
+
accountMeta
|
518
|
+
} = authzResult;
|
519
|
+
const {
|
520
|
+
limits,
|
521
|
+
usage
|
522
|
+
} = apiKeyMeta || accountMeta || {};
|
523
|
+
const {
|
524
|
+
serviceScope
|
525
|
+
} = serviceConfig;
|
526
|
+
if (!usage || !(serviceScope in usage) || !limits || !(serviceScope in limits)) {
|
527
|
+
// No usage limit is provided. Assume the request is not limited.
|
528
|
+
return {
|
529
|
+
usageLimited: false
|
530
|
+
};
|
531
|
+
}
|
532
|
+
const limit = limits.storage;
|
533
|
+
if (serviceScope === "storage" && (usage.storage?.sumFileSizeBytes || 0) > limit) {
|
534
|
+
return {
|
535
|
+
usageLimited: true,
|
536
|
+
status: 403,
|
537
|
+
errorMessage: `You've used all of your total usage limit for Storage Pinning. Please add your payment method at https://thirdweb.com/dashboard/settings/billing.`,
|
538
|
+
errorCode: "PAYMENT_METHOD_REQUIRED"
|
539
|
+
};
|
540
|
+
}
|
541
|
+
return {
|
542
|
+
usageLimited: false
|
543
|
+
};
|
544
|
+
}
|
545
|
+
|
546
|
+
export { authorize as a, rateLimit as r, usageLimit as u };
|
@@ -6,7 +6,7 @@ async function fetchKeyMetadataFromApi(clientId, config) {
|
|
6
6
|
serviceScope,
|
7
7
|
serviceApiKey
|
8
8
|
} = config;
|
9
|
-
const url = `${apiUrl}/v1/keys/use?clientId=${clientId}&scope=${serviceScope}`;
|
9
|
+
const url = `${apiUrl}/v1/keys/use?clientId=${clientId}&scope=${serviceScope}&includeUsage=true`;
|
10
10
|
const response = await fetch(url, {
|
11
11
|
method: "GET",
|
12
12
|
headers: {
|
@@ -27,7 +27,7 @@ async function fetchAccountFromApi(jwt, config, useWalletAuth) {
|
|
27
27
|
apiUrl,
|
28
28
|
serviceApiKey
|
29
29
|
} = config;
|
30
|
-
const url = useWalletAuth ? `${apiUrl}/v1/wallet/me` : `${apiUrl}/v1/account/me`;
|
30
|
+
const url = useWalletAuth ? `${apiUrl}/v1/wallet/me?includeUsage=true` : `${apiUrl}/v1/account/me?includeUsage=true`;
|
31
31
|
const response = await fetch(url, {
|
32
32
|
method: "GET",
|
33
33
|
headers: {
|
@@ -44,6 +44,25 @@ async function fetchAccountFromApi(jwt, config, useWalletAuth) {
|
|
44
44
|
}
|
45
45
|
return json;
|
46
46
|
}
|
47
|
+
async function updateRateLimitedAt(apiKeyId, config) {
|
48
|
+
const {
|
49
|
+
apiUrl,
|
50
|
+
serviceScope: scope,
|
51
|
+
serviceApiKey
|
52
|
+
} = config;
|
53
|
+
const url = `${apiUrl}/usage/rateLimit`;
|
54
|
+
await fetch(url, {
|
55
|
+
method: "PUT",
|
56
|
+
headers: {
|
57
|
+
"x-service-api-key": serviceApiKey,
|
58
|
+
"content-type": "application/json"
|
59
|
+
},
|
60
|
+
body: JSON.stringify({
|
61
|
+
apiKeyId,
|
62
|
+
scope
|
63
|
+
})
|
64
|
+
});
|
65
|
+
}
|
47
66
|
|
48
67
|
function authorizeClient(authOptions, apiKeyMeta) {
|
49
68
|
const {
|
@@ -63,7 +82,10 @@ function authorizeClient(authOptions, apiKeyMeta) {
|
|
63
82
|
id: apiKeyMeta.accountId,
|
64
83
|
// TODO update this later
|
65
84
|
name: "",
|
66
|
-
creatorWalletAddress: apiKeyMeta.creatorWalletAddress
|
85
|
+
creatorWalletAddress: apiKeyMeta.creatorWalletAddress,
|
86
|
+
limits: apiKeyMeta.limits,
|
87
|
+
rateLimits: apiKeyMeta.rateLimits,
|
88
|
+
usage: apiKeyMeta.usage
|
67
89
|
}
|
68
90
|
};
|
69
91
|
|
@@ -193,12 +215,15 @@ function authorizeService(apiKeyMetadata, serviceConfig, authorizationPayload) {
|
|
193
215
|
}
|
194
216
|
return {
|
195
217
|
authorized: true,
|
218
|
+
apiKeyMeta: apiKeyMetadata,
|
196
219
|
accountMeta: {
|
197
220
|
id: apiKeyMetadata.accountId,
|
198
221
|
name: "",
|
199
|
-
creatorWalletAddress: apiKeyMetadata.creatorWalletAddress
|
200
|
-
|
201
|
-
|
222
|
+
creatorWalletAddress: apiKeyMetadata.creatorWalletAddress,
|
223
|
+
limits: apiKeyMetadata.limits,
|
224
|
+
rateLimits: apiKeyMetadata.rateLimits,
|
225
|
+
usage: apiKeyMetadata.usage
|
226
|
+
}
|
202
227
|
};
|
203
228
|
}
|
204
229
|
|
@@ -416,9 +441,110 @@ async function authorize(authData, serviceConfig, cacheOptions) {
|
|
416
441
|
id: apiKeyMeta.accountId,
|
417
442
|
// TODO update this later
|
418
443
|
name: "",
|
444
|
+
limits: apiKeyMeta.limits,
|
445
|
+
rateLimits: apiKeyMeta.rateLimits,
|
446
|
+
usage: apiKeyMeta.usage,
|
419
447
|
creatorWalletAddress: apiKeyMeta.creatorWalletAddress
|
420
448
|
}
|
421
449
|
};
|
422
450
|
}
|
423
451
|
|
452
|
+
const DEFAULT_RATE_LIMIT_WINDOW_SECONDS = 10;
|
453
|
+
const HARD_LIMIT_MULTIPLE = 2; // 2x of allowed limit
|
454
|
+
|
455
|
+
async function rateLimit(authzResult, serviceConfig, cacheOptions) {
|
456
|
+
if (!authzResult.authorized) {
|
457
|
+
return {
|
458
|
+
rateLimited: false
|
459
|
+
};
|
460
|
+
}
|
461
|
+
const {
|
462
|
+
apiKeyMeta,
|
463
|
+
accountMeta
|
464
|
+
} = authzResult;
|
465
|
+
const {
|
466
|
+
rateLimits
|
467
|
+
} = apiKeyMeta || accountMeta || {};
|
468
|
+
const accountId = apiKeyMeta?.accountId || accountMeta?.id;
|
469
|
+
const {
|
470
|
+
serviceScope
|
471
|
+
} = serviceConfig;
|
472
|
+
if (!rateLimits || !(serviceScope in rateLimits)) {
|
473
|
+
// No rate limit is provided. Assume the request is not rate limited.
|
474
|
+
return {
|
475
|
+
rateLimited: false
|
476
|
+
};
|
477
|
+
}
|
478
|
+
const limit = rateLimits[serviceScope];
|
479
|
+
|
480
|
+
// Floors the current time to the nearest DEFAULT_RATE_LIMIT_WINDOW_SECONDS.
|
481
|
+
const bucketId = Math.floor(Date.now() / (1000 * DEFAULT_RATE_LIMIT_WINDOW_SECONDS)) * DEFAULT_RATE_LIMIT_WINDOW_SECONDS;
|
482
|
+
const key = [serviceScope, accountId, bucketId].join(":");
|
483
|
+
const value = parseInt((await cacheOptions.get(key)) || "0");
|
484
|
+
const current = value + 1;
|
485
|
+
|
486
|
+
// limit is in seconds, but we need in DEFAULT_RATE_LIMIT_WINDOW_SECONDS
|
487
|
+
const limitWindow = limit * DEFAULT_RATE_LIMIT_WINDOW_SECONDS;
|
488
|
+
if (current > limitWindow) {
|
489
|
+
// report rate limit hits
|
490
|
+
if (apiKeyMeta?.id) {
|
491
|
+
await updateRateLimitedAt(apiKeyMeta.id, serviceConfig);
|
492
|
+
}
|
493
|
+
|
494
|
+
// actually rate limit only when reached hard limit
|
495
|
+
if (current > limitWindow * HARD_LIMIT_MULTIPLE) {
|
496
|
+
return {
|
497
|
+
rateLimited: true,
|
498
|
+
status: 429,
|
499
|
+
errorMessage: `You've exceeded your ${serviceScope} rate limit at ${limit} reqs/sec. To get higher rate limits, contact us at https://thirdweb.com/contact-us.`,
|
500
|
+
errorCode: "RATE_LIMIT_EXCEEDED"
|
501
|
+
};
|
502
|
+
}
|
503
|
+
} else {
|
504
|
+
await cacheOptions.put(key, current.toString());
|
505
|
+
}
|
506
|
+
return {
|
507
|
+
rateLimited: false
|
508
|
+
};
|
509
|
+
}
|
510
|
+
|
511
|
+
async function usageLimit(authzResult, serviceConfig) {
|
512
|
+
if (!authzResult.authorized) {
|
513
|
+
return {
|
514
|
+
usageLimited: false
|
515
|
+
};
|
516
|
+
}
|
517
|
+
const {
|
518
|
+
apiKeyMeta,
|
519
|
+
accountMeta
|
520
|
+
} = authzResult;
|
521
|
+
const {
|
522
|
+
limits,
|
523
|
+
usage
|
524
|
+
} = apiKeyMeta || accountMeta || {};
|
525
|
+
const {
|
526
|
+
serviceScope
|
527
|
+
} = serviceConfig;
|
528
|
+
if (!usage || !(serviceScope in usage) || !limits || !(serviceScope in limits)) {
|
529
|
+
// No usage limit is provided. Assume the request is not limited.
|
530
|
+
return {
|
531
|
+
usageLimited: false
|
532
|
+
};
|
533
|
+
}
|
534
|
+
const limit = limits.storage;
|
535
|
+
if (serviceScope === "storage" && (usage.storage?.sumFileSizeBytes || 0) > limit) {
|
536
|
+
return {
|
537
|
+
usageLimited: true,
|
538
|
+
status: 403,
|
539
|
+
errorMessage: `You've used all of your total usage limit for Storage Pinning. Please add your payment method at https://thirdweb.com/dashboard/settings/billing.`,
|
540
|
+
errorCode: "PAYMENT_METHOD_REQUIRED"
|
541
|
+
};
|
542
|
+
}
|
543
|
+
return {
|
544
|
+
usageLimited: false
|
545
|
+
};
|
546
|
+
}
|
547
|
+
|
424
548
|
exports.authorize = authorize;
|
549
|
+
exports.rateLimit = rateLimit;
|
550
|
+
exports.usageLimit = usageLimit;
|
@@ -3,7 +3,7 @@
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
4
4
|
|
5
5
|
var node_crypto = require('node:crypto');
|
6
|
-
var index = require('../../dist/index-
|
6
|
+
var index = require('../../dist/index-807f6a60.cjs.dev.js');
|
7
7
|
var services = require('../../dist/services-a3f36057.cjs.dev.js');
|
8
8
|
|
9
9
|
/**
|
@@ -173,6 +173,8 @@ function logHttpRequest(_ref) {
|
|
173
173
|
console.log(`statusMessage=${_statusMessage}`);
|
174
174
|
}
|
175
175
|
|
176
|
+
exports.rateLimit = index.rateLimit;
|
177
|
+
exports.usageLimit = index.usageLimit;
|
176
178
|
exports.SERVICES = services.SERVICES;
|
177
179
|
exports.SERVICE_DEFINITIONS = services.SERVICE_DEFINITIONS;
|
178
180
|
exports.SERVICE_NAMES = services.SERVICE_NAMES;
|
@@ -3,7 +3,7 @@
|
|
3
3
|
Object.defineProperty(exports, '__esModule', { value: true });
|
4
4
|
|
5
5
|
var node_crypto = require('node:crypto');
|
6
|
-
var index = require('../../dist/index-
|
6
|
+
var index = require('../../dist/index-cfc8027b.cjs.prod.js');
|
7
7
|
var services = require('../../dist/services-9e185105.cjs.prod.js');
|
8
8
|
|
9
9
|
/**
|
@@ -173,6 +173,8 @@ function logHttpRequest(_ref) {
|
|
173
173
|
console.log(`statusMessage=${_statusMessage}`);
|
174
174
|
}
|
175
175
|
|
176
|
+
exports.rateLimit = index.rateLimit;
|
177
|
+
exports.usageLimit = index.usageLimit;
|
176
178
|
exports.SERVICES = services.SERVICES;
|
177
179
|
exports.SERVICE_DEFINITIONS = services.SERVICE_DEFINITIONS;
|
178
180
|
exports.SERVICE_NAMES = services.SERVICE_NAMES;
|
@@ -1,5 +1,6 @@
|
|
1
1
|
import { createHash } from 'node:crypto';
|
2
|
-
import { a as authorize } from '../../dist/index-
|
2
|
+
import { a as authorize } from '../../dist/index-bcf68113.esm.js';
|
3
|
+
export { r as rateLimit, u as usageLimit } from '../../dist/index-bcf68113.esm.js';
|
3
4
|
export { b as SERVICES, S as SERVICE_DEFINITIONS, a as SERVICE_NAMES, g as getServiceByName } from '../../dist/services-86283509.esm.js';
|
4
5
|
|
5
6
|
/**
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@thirdweb-dev/service-utils",
|
3
|
-
"version": "0.4.
|
3
|
+
"version": "0.4.5-nightly-903145a4-20230918223433",
|
4
4
|
"main": "dist/thirdweb-dev-service-utils.cjs.js",
|
5
5
|
"module": "dist/thirdweb-dev-service-utils.esm.js",
|
6
6
|
"exports": {
|
@@ -52,6 +52,7 @@
|
|
52
52
|
"eslint-config-thirdweb": "^0.1.6",
|
53
53
|
"jest": "^29.6.2",
|
54
54
|
"prettier": "^3.0.0",
|
55
|
+
"ts-jest": "^29.1.1",
|
55
56
|
"typescript": "^5.1.6"
|
56
57
|
},
|
57
58
|
"dependencies": {
|