Skip to content

Commit 44fa557

Browse files
committed
Merge branch 'main' of https://github.com/thirdweb-dev/js into gi/portal-translation-crowdinai
2 parents cbf48f5 + ca22e46 commit 44fa557

File tree

13 files changed

+100
-86
lines changed

13 files changed

+100
-86
lines changed

apps/portal/src/app/nebula/faqs/page.mdx

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,20 @@
44

55
Estamos aprobando el acceso a Nebula en lotes diariamente. ¡Mantente atento!
66

7-
### ¿Nebula será de código abierto?
7+
### ¿Qué contratos soporta Nebula?
8+
Nebula soporta el contexto de lectura y escritura de cualquier contrato verificado o cualquier contrato en el panel de control de thirdweb. Para desplegar a través de Nebula, los contratos soportados incluyen [Token - ERC20](https://thirdweb.com/thirdweb.eth/TokenERC20), [Colección NFT - ERC721](https://thirdweb.com/thirdweb.eth/TokenERC721), [Edición - ERC1155](https://thirdweb.com/thirdweb.eth/TokenERC1155), y [Split](https://thirdweb.com/thirdweb.eth/Split).
9+
10+
Si tienes un contrato publicado que te gustaría habilitar para su despliegue a través de Nebula, por favor [contáctanos](https://thirdweb.com/contact-us).
11+
12+
### ¿Nebula tiene memoria de conversaciones pasadas?
13+
Nebula retiene memoria dentro de los límites de una sesión.
814

915
Nebula no es actualmente de código abierto. Estamos explorando la posibilidad de hacer Nebula de código abierto en el futuro.
1016

1117
### ¿Cuándo estará disponible la información sobre precios para Nebula?
1218

13-
Las opciones de precios estarán disponibles en la versión beta (estimada para mediados de enero de 2025).
19+
Nebula no es actualmente de código abierto. Estamos explorando la posibilidad de hacerlo en el futuro.
20+
21+
### ¿Cuándo estará disponible la información de precios para Nebula?
22+
23+
Las opciones de precios estarán disponibles en la versión beta. Nebula aún está siendo probada en su versión alfa.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
# OpenAI
2+
3+
### Chat Completions API
4+
5+
Compatible with OpenAI’s Chat Completion API to process chat history and generate context-aware responses.
6+
7+
```python
8+
from openai import OpenAI
9+
10+
client = OpenAI(
11+
base_url="https://nebula-api.thirdweb.com",
12+
api_key="{{THIRDWEB_SECRET_KEY}}",
13+
)
14+
chat_completion = client.chat.completions.create(
15+
model="t0",
16+
messages=[{"role": "user", "content": "Hello Nebula!"}],
17+
stream=False,
18+
extra_body={ "context": { "wallet_address": "0x..." }}
19+
)
20+
21+
print(chat_completion)
22+
```
23+
24+
### Models API
25+
26+
Compatible with OpenAI’s Models API to list out models used.
27+
28+
```python
29+
from openai import OpenAI
30+
31+
# https://nebula-api.thirdweb.com/models
32+
33+
client = OpenAI(
34+
base_url="https://nebula-api.thirdweb.com/",
35+
api_key="",
36+
)
37+
38+
models = client.models.list()
39+
print(models)
40+
```

apps/portal/src/app/nebula/plugins/page.mdx

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@ import { Callout } from '@doc'
22

33
# Plugins
44

5+
- [OpenAI](/nebula/plugins/openai)
6+
- [Eliza](/nebula/plugins/eliza)
57

6-
<Callout variant='info' title='Coming Soon'>
7-
8-
We are actively developing plugins to develop with other frameworks and languages.
9-
10-
If you have a specific request, please [contact us](https://thirdweb.com/contact).
11-
12-
</Callout>
8+
We are actively adding more integrations, for any specific requests please [contact us](https://thirdweb.com/contact).

apps/portal/src/app/nebula/sidebar.tsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,10 +110,14 @@ export const sidebar: SideBar = {
110110
],
111111
},
112112
{
113-
name: "Plugins",
113+
name: "Plugins & Integrations",
114114
href: "/nebula/plugins",
115115
icon: <Blocks />,
116116
links: [
117+
{
118+
name: "OpenAI",
119+
href: "/nebula/plugins/openai",
120+
},
117121
{
118122
name: "Eliza",
119123
href: "/nebula/plugins/eliza",

packages/service-utils/CHANGELOG.md

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

3+
## 0.8.0
4+
5+
### Minor Changes
6+
7+
- [#6101](https://github.com/thirdweb-dev/js/pull/6101) [`e8892b1`](https://github.com/thirdweb-dev/js/commit/e8892b152f70d3024dfbefcddcfa74a69a12bdd0) Thanks [@jnsdls](https://github.com/jnsdls)! - pass `team` instead of `project` to `rateLimit`
8+
39
## 0.7.3
410

511
### Patch Changes

packages/service-utils/package.json

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@thirdweb-dev/service-utils",
3-
"version": "0.7.3",
3+
"version": "0.8.0",
44
"type": "module",
55
"main": "dist/cjs/index.js",
66
"module": "dist/esm/index.js",
@@ -26,12 +26,8 @@
2626
},
2727
"typesVersions": {
2828
"*": {
29-
"node": [
30-
"./dist/types/node/index.d.ts"
31-
],
32-
"cf-worker": [
33-
"./dist/types/cf-worker/index.d.ts"
34-
]
29+
"node": ["./dist/types/node/index.d.ts"],
30+
"cf-worker": ["./dist/types/cf-worker/index.d.ts"]
3531
}
3632
},
3733
"repository": "https://github.com/thirdweb-dev/js/tree/main/packages/pay",
@@ -40,9 +36,7 @@
4036
"url": "https://github.com/thirdweb-dev/js/issues"
4137
},
4238
"author": "thirdweb eng <[email protected]>",
43-
"files": [
44-
"dist/"
45-
],
39+
"files": ["dist/"],
4640
"sideEffects": false,
4741
"dependencies": {
4842
"aws4fetch": "1.0.20",

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

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -164,24 +164,3 @@ export async function fetchTeamAndProject(
164164
);
165165
}
166166
}
167-
168-
export async function updateRateLimitedAt(
169-
projectId: string,
170-
config: CoreServiceConfig,
171-
): Promise<void> {
172-
const { apiUrl, serviceScope: scope, serviceApiKey } = config;
173-
174-
const url = `${apiUrl}/usage/rateLimit`;
175-
176-
await fetch(url, {
177-
method: "PUT",
178-
headers: {
179-
"x-service-api-key": serviceApiKey,
180-
"content-type": "application/json",
181-
},
182-
body: JSON.stringify({
183-
apiKeyId: projectId, // projectId is the apiKeyId
184-
scope,
185-
}),
186-
});
187-
}

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

Lines changed: 4 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
type CoreServiceConfig,
3-
type ProjectResponse,
4-
updateRateLimitedAt,
5-
} from "../api.js";
1+
import type { CoreServiceConfig, TeamResponse } from "../api.js";
62
import type { RateLimitResult } from "./types.js";
73

84
const RATE_LIMIT_WINDOW_SECONDS = 10;
@@ -14,7 +10,7 @@ type IRedis = {
1410
};
1511

1612
export async function rateLimit(args: {
17-
project?: ProjectResponse;
13+
team: TeamResponse;
1814
limitPerSecond: number;
1915
serviceConfig: CoreServiceConfig;
2016
redis: IRedis;
@@ -25,13 +21,7 @@ export async function rateLimit(args: {
2521
*/
2622
sampleRate?: number;
2723
}): Promise<RateLimitResult> {
28-
const {
29-
project,
30-
limitPerSecond,
31-
serviceConfig,
32-
redis,
33-
sampleRate = 1.0,
34-
} = args;
24+
const { team, limitPerSecond, serviceConfig, redis, sampleRate = 1.0 } = args;
3525

3626
const shouldSampleRequest = Math.random() < sampleRate;
3727
if (!shouldSampleRequest) {
@@ -57,7 +47,7 @@ export async function rateLimit(args: {
5747
const timestampWindow =
5848
Math.floor(Date.now() / (1000 * RATE_LIMIT_WINDOW_SECONDS)) *
5949
RATE_LIMIT_WINDOW_SECONDS;
60-
const key = `rate-limit:${serviceScope}:${project?.id}:${timestampWindow}`;
50+
const key = `rate-limit:${serviceScope}:${team.id}:${timestampWindow}`;
6151

6252
// Increment and get the current request count in this window.
6353
const requestCount = await redis.incr(key);
@@ -71,17 +61,6 @@ export async function rateLimit(args: {
7161
limitPerSecond * sampleRate * RATE_LIMIT_WINDOW_SECONDS;
7262

7363
if (requestCount > limitPerWindow) {
74-
/**
75-
* Report rate limit hits.
76-
* Only track rate limit when its hit for the first time.
77-
* Not waiting for tracking to complete as user doesn't need to wait.
78-
*/
79-
if (requestCount === limitPerWindow + 1 && project?.id) {
80-
updateRateLimitedAt(project.id, serviceConfig).catch(() => {
81-
// no-op
82-
});
83-
}
84-
8564
return {
8665
rateLimited: true,
8766
requestCount,

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

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
2-
import { validProjectResponse, validServiceConfig } from "../../mocks.js";
3-
import { updateRateLimitedAt } from "../api.js";
2+
import { validServiceConfig, validTeamResponse } from "../../mocks.js";
43
import { rateLimit } from "./index.js";
54

65
const mockRedis = {
76
incr: vi.fn(),
87
expire: vi.fn(),
98
};
109

11-
// Mocking the updateRateLimitedAt function
12-
vi.mock("../../../src/core/api", () => ({
13-
updateRateLimitedAt: vi.fn().mockResolvedValue({}),
14-
}));
15-
1610
describe("rateLimit", () => {
1711
beforeEach(() => {
1812
// Clear mock function calls and reset any necessary state.
@@ -27,7 +21,7 @@ describe("rateLimit", () => {
2721

2822
it("should not rate limit if service scope is not in rate limits", async () => {
2923
const result = await rateLimit({
30-
project: validProjectResponse,
24+
team: validTeamResponse,
3125
limitPerSecond: 0,
3226
serviceConfig: validServiceConfig,
3327
redis: mockRedis,
@@ -44,7 +38,7 @@ describe("rateLimit", () => {
4438
mockRedis.incr.mockResolvedValue(50); // Current count is 50 requests in 10 seconds.
4539

4640
const result = await rateLimit({
47-
project: validProjectResponse,
41+
team: validTeamResponse,
4842
limitPerSecond: 5,
4943
serviceConfig: validServiceConfig,
5044
redis: mockRedis,
@@ -55,15 +49,15 @@ describe("rateLimit", () => {
5549
requestCount: 50,
5650
rateLimit: 50,
5751
});
58-
expect(updateRateLimitedAt).not.toHaveBeenCalled();
52+
5953
expect(mockRedis.expire).not.toHaveBeenCalled();
6054
});
6155

6256
it("should rate limit if exceeded hard limit", async () => {
6357
mockRedis.incr.mockResolvedValue(51);
6458

6559
const result = await rateLimit({
66-
project: validProjectResponse,
60+
team: validTeamResponse,
6761
limitPerSecond: 5,
6862
serviceConfig: validServiceConfig,
6963
redis: mockRedis,
@@ -77,15 +71,15 @@ describe("rateLimit", () => {
7771
errorMessage: `You've exceeded your storage rate limit at 5 reqs/sec. To get higher rate limits, contact us at https://thirdweb.com/contact-us.`,
7872
errorCode: "RATE_LIMIT_EXCEEDED",
7973
});
80-
expect(updateRateLimitedAt).toHaveBeenCalled();
74+
8175
expect(mockRedis.expire).not.toHaveBeenCalled();
8276
});
8377

8478
it("expires on the first incr request only", async () => {
8579
mockRedis.incr.mockResolvedValue(1);
8680

8781
const result = await rateLimit({
88-
project: validProjectResponse,
82+
team: validTeamResponse,
8983
limitPerSecond: 5,
9084
serviceConfig: validServiceConfig,
9185
redis: mockRedis,
@@ -104,7 +98,7 @@ describe("rateLimit", () => {
10498
vi.spyOn(global.Math, "random").mockReturnValue(0.08);
10599

106100
const result = await rateLimit({
107-
project: validProjectResponse,
101+
team: validTeamResponse,
108102
limitPerSecond: 5,
109103
serviceConfig: validServiceConfig,
110104
redis: mockRedis,
@@ -127,7 +121,7 @@ describe("rateLimit", () => {
127121
vi.spyOn(global.Math, "random").mockReturnValue(0.15);
128122

129123
const result = await rateLimit({
130-
project: validProjectResponse,
124+
team: validTeamResponse,
131125
limitPerSecond: 5,
132126
serviceConfig: validServiceConfig,
133127
redis: mockRedis,

packages/service-utils/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export type {
1010
TeamResponse,
1111
} from "./core/api.js";
1212

13-
export { fetchTeamAndProject, updateRateLimitedAt } from "./core/api.js";
13+
export { fetchTeamAndProject } from "./core/api.js";
1414

1515
export {
1616
authorizeBundleId,

0 commit comments

Comments
 (0)