Skip to content

Commit e50d77d

Browse files
committed
Docs up to .NET 2.17.1 / Unity 5.17.1 (#6200)
Closes TOOL-2991 <!-- ## title your PR with this format: "[SDK/Dashboard/Portal] Feature/Fix: Concise title for the changes" If you did not copy the branch name from Linear, paste the issue tag here (format is TEAM-0000): ## Notes for the reviewer Anything important to call out? Be sure to also clarify these in your comments. ## How to test Unit tests, playground, etc. --> <!-- start pr-codex --> --- ## PR-Codex overview This PR introduces enhancements to the `sidebar` structure and API documentation, adds new wallet authentication options, and refines existing content for clarity. It also includes new RPC overrides and updates to the `InAppWallet` and `EcosystemWallet` functionalities. ### Detailed summary - Added `rpcOverrides` example to `page.mdx`. - Updated `sidebar.tsx` to include "API Reference" and "Blockchain API" sections. - Replaced "Blockchain API" with "Nebula AI" in `sidebar.tsx`. - Enhanced `EcosystemWallet` and `InAppWallet` functionalities with new login options. - Clarified documentation on wallet connections and authentication methods. - Added examples for `SiweExternal` login process. - Updated various sections in `page.mdx` for better clarity and detail. > ✨ Ask PR-Codex anything about this PR by commenting with `/codex {your question}` <!-- end pr-codex -->
1 parent 7f3b91d commit e50d77d

File tree

11 files changed

+374
-230
lines changed

11 files changed

+374
-230
lines changed

apps/portal/src/app/dotnet/client/page.mdx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,4 +64,19 @@ Options for configuring timeouts for fetching data. Useful for fine-tuning reque
6464
TimeoutOptions(int? storage = null, int? rpc = null, int? other = null)
6565
```
6666

67+
### rpcOverrides (optional)
68+
69+
Overrides for the default RPC endpoints. Will use your custom endpoints instead of thirdweb RPC endpoints.
70+
71+
```csharp
72+
var client = ThirdwebClient.Create(
73+
...,
74+
rpcOverrides: new()
75+
{
76+
{ 1, "https://eth.llamarpc.com" },
77+
{ 42161, "https://arbitrum.llamarpc.com" }
78+
}
79+
);
80+
```
81+
6782
</Details>
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
import { Details, createMetadata } from "@doc";
2+
3+
export const metadata = createMetadata({
4+
title: "ThirdwebContract.Create | Thirdweb .NET SDK",
5+
description:
6+
"Instantiate a ThirdwebContract to interact with smart contracts.",
7+
});
8+
9+
# [Nebula AI](https://thirdweb.com/nebula) .NET Integration
10+
The last piece of the puzzle required to create .NET apps and games leveraging a blockchain-powered AI assistant or NPC that also has the power to fully execute transactions.
11+
12+
## Read, Write, Reason.
13+
The best way to understand is to look at examples.
14+
15+
We'll prepare some context for the AI - here, we'll generate a basic `PrivateKeyWallet` and upgrade it to a `SmartWallet` on Sepolia.
16+
```csharp
17+
// Prepare some context
18+
var myChain = 11155111; // Sepolia
19+
var mySigner = await PrivateKeyWallet.Generate(client);
20+
var myWallet = await SmartWallet.Create(mySigner, myChain);
21+
var myContractAddress = "0xe2cb0eb5147b42095c2FfA6F7ec953bb0bE347D8"; // DropERC1155
22+
var usdcAddress = "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238"; // Sepolia USDC
23+
```
24+
25+
A one liner creates a Nebula session.
26+
```csharp
27+
// Create a Nebula session
28+
var nebula = await ThirdwebNebula.Create(client);
29+
```
30+
31+
You can **Chat** with Nebula. The Chat method accepts any `IThirdwebWallet` as an optional parameter, context will automatically be updated.
32+
```csharp
33+
// Chat, passing wallet context
34+
var response1 = await nebula.Chat(message: "What is my wallet address?", wallet: myWallet);
35+
Console.WriteLine($"Response 1: {response1.Message}");
36+
```
37+
38+
You may also pass it smart contract context.
39+
```csharp
40+
// Chat, passing contract context
41+
var response2 = await nebula.Chat(
42+
message: "What's the total supply of token id 0 for this contract?",
43+
context: new NebulaContext(contractAddresses: new List<string> { myContractAddress }, chainIds: new List<BigInteger> { myChain })
44+
);
45+
Console.WriteLine($"Response 2: {response2.Message}");
46+
```
47+
48+
You can have a full on conversation with it with our **Chat** override accepting multiple messages.
49+
```csharp
50+
// Chat, passing multiple messages and context
51+
var response3 = await nebula.Chat(
52+
messages: new List<NebulaChatMessage>
53+
{
54+
new($"Tell me the name of this contract: {myContractAddress}", NebulaChatRole.User),
55+
new("The name of the contract is CatDrop", NebulaChatRole.Assistant),
56+
new("What's the symbol of this contract?", NebulaChatRole.User),
57+
},
58+
context: new NebulaContext(contractAddresses: new List<string> { myContractAddress }, chainIds: new List<BigInteger> { myChain })
59+
);
60+
Console.WriteLine($"Response 3: {response3.Message}");
61+
```
62+
63+
Chatting is cool, but what if I just want it to _**do**_ things and stop talking so much?
64+
65+
You can **Execute** transactions directly with a simple prompt.
66+
```csharp
67+
// Execute, this directly sends transactions
68+
var executionResult = await nebula.Execute("Approve 1 USDC to vitalik.eth", wallet: myWallet, context: new NebulaContext(contractAddresses: new List<string>() { usdcAddress }));
69+
if (executionResult.TransactionReceipts != null && executionResult.TransactionReceipts.Count > 0)
70+
{
71+
Console.WriteLine($"Receipt: {executionResult.TransactionReceipts[0]}");
72+
}
73+
else
74+
{
75+
Console.WriteLine($"Message: {executionResult.Message}");
76+
}
77+
```
78+
79+
Similarly, **Execute** can take in multiple messages.
80+
```csharp
81+
// Batch execute
82+
var batchExecutionResult = await nebula.Execute(
83+
new List<NebulaChatMessage>
84+
{
85+
new("What's the address of vitalik.eth", NebulaChatRole.User),
86+
new("The address of vitalik.eth is 0xd8dA6BF26964aF8E437eEa5e3616511D7G3a3298", NebulaChatRole.Assistant),
87+
new("Approve 1 USDC to them", NebulaChatRole.User),
88+
},
89+
wallet: myWallet,
90+
context: new NebulaContext(contractAddresses: new List<string>() { usdcAddress })
91+
);
92+
if (batchExecutionResult.TransactionReceipts != null && batchExecutionResult.TransactionReceipts.Count > 0)
93+
{
94+
Console.WriteLine($"Receipts: {JsonConvert.SerializeObject(batchExecutionResult.TransactionReceipts, Formatting.Indented)}");
95+
}
96+
else
97+
{
98+
Console.WriteLine($"Message: {batchExecutionResult.Message}");
99+
}
100+
```

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

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { SideBar } from "@/components/Layouts/DocLayout";
22
import type { SidebarLink } from "@/components/others/Sidebar";
3-
import { ZapIcon } from "lucide-react";
3+
import { CodeIcon, ExternalLink, ZapIcon } from "lucide-react";
44

55
const walletProviders: SidebarLink = (() => {
66
const parentSlug = "/dotnet/wallets/providers";
@@ -261,16 +261,29 @@ export const sidebar: SideBar = {
261261
icon: <ZapIcon />,
262262
},
263263
{
264-
name: "Godot Integration",
265-
href: "/dotnet/godot",
266-
},
267-
{
268-
name: "Unity Integration",
269-
href: "/unity/v5",
264+
name: "API Reference",
265+
href: "https://thirdweb-dev.github.io/dotnet/index.html",
266+
isCollapsible: false,
267+
icon: <ExternalLink />,
270268
},
271269
{
272-
name: "MAUI Integration",
273-
href: "/dotnet/maui",
270+
name: "Integrations",
271+
isCollapsible: true,
272+
icon: <CodeIcon />,
273+
links: [
274+
{
275+
name: "Unity",
276+
href: "/unity/v5",
277+
},
278+
{
279+
name: "Godot",
280+
href: "/dotnet/godot",
281+
},
282+
{
283+
name: "MAUI",
284+
href: "/dotnet/maui",
285+
},
286+
],
274287
},
275288
{
276289
name: "Core",
@@ -291,7 +304,6 @@ export const sidebar: SideBar = {
291304
isCollapsible: false,
292305
links: [walletProviders, walletActions],
293306
},
294-
pay,
295307
{
296308
name: "Blockchain API",
297309
isCollapsible: false,
@@ -304,10 +316,20 @@ export const sidebar: SideBar = {
304316
},
305317
],
306318
},
307-
{ separator: true },
308319
{
309-
name: "Full Reference",
310-
href: "https://thirdweb-dev.github.io/dotnet/index.html",
320+
name: "Nebula AI",
321+
isCollapsible: false,
322+
links: [
323+
{
324+
name: "Quickstart",
325+
href: "/dotnet/nebula/quickstart",
326+
},
327+
{
328+
name: "Nebula Full Reference",
329+
href: "https://thirdweb-dev.github.io/dotnet/docs/Thirdweb.AI.ThirdwebNebula.html",
330+
},
331+
],
311332
},
333+
pay,
312334
],
313335
};

apps/portal/src/app/dotnet/wallets/providers/ecosystem-wallet/page.mdx

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,11 +15,13 @@ Create an instance of `EcosystemWallet` using a user's email, phone number or OA
1515
Ecosystem Wallets support a variety of login methods:
1616
- Email (OTP Login)
1717
- Phone (OTP Login)
18-
- Socials (Google, Apple, Facebook, Telegram, Farcaster, Line, Github, Twitch, Steam, etc.)
19-
- SIWE (Sign-In with Ethereum)
18+
- Socials (Google, Apple, Facebook, Telegram, Farcaster, Line, Github, Twitch, Steam etc.)
2019
- Custom Auth (OIDC Compatible)
2120
- Custom Auth (Generic Auth Endpoint)
2221
- Guest (Onboard easily, link other accounts later)
22+
- Backend (Server Wallets)
23+
- Siwe (Login with a seperate wallet supported by the SDK)
24+
- SiweExternal (Login with an external wallet that only supports web using a browser loading a static thirdweb React page temporarily)
2325

2426
## Usage
2527

@@ -32,14 +34,18 @@ var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosyste
3234
var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.my-ecosystem", phoneNumber: "+1234567890");
3335
// Google, Apple, Facebook, etc.
3436
var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.my-ecosystem", authProvider: AuthProvider.Google);
35-
// SIWE
36-
var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.my-ecosystem", authProvider: AuthProvider.Siwe, siweSigner: anyExternalWallet);
3737
// Custom Auth - JWT
3838
var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.my-ecosystem", authProvider: AuthProvider.JWT);
3939
// Custom Auth - AuthEndpoint
4040
var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.my-ecosystem", authProvider: AuthProvider.AuthEndpoint);
4141
// Guest Login
4242
var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.my-ecosystem", authProvider: AuthProvider.Guest);
43+
// Server Login
44+
var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.my-ecosystem", authProvider: AuthProvider.Backend, walletSecret: "very-secret");
45+
// Siwe
46+
var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.my-ecosystem", authProvider: AuthProvider.Siwe, siweSigner: anyExternalWallet);
47+
// SiweExternal
48+
var wallet = await EcosystemWallet.Create(client: client, ecosystemId: "ecosystem.my-ecosystem", authProvider: AuthProvider.SiweExternal);
4349

4450
// Session resuming supported for all methods
4551
var isConnected = await wallet.IsConnected();
@@ -62,9 +68,6 @@ var address = await wallet.LoginWithOauth(
6268
mobileRedirectScheme: "myBundleId://"
6369
);
6470

65-
// SIWE (Wallet)
66-
var address = await siweWallet.LoginWithSiwe(chainId: 1);
67-
6871
// Custom Auth (JWT)
6972
var address = await wallet.LoginWithCustomAuth(jwt: "myjwt");
7073

@@ -73,11 +76,26 @@ var address = await wallet.LoginWithAuthEndpoint(payload: "mypayload");
7376

7477
// Guest Login (Easy onboarding)
7578
var address = await wallet.LoginWithGuest();
79+
80+
// Backend (Server Wallets)
81+
var address = await wallet.LoginWithBackend();
82+
83+
// SIWE (Wallet)
84+
var address = await siweWallet.LoginWithSiwe(chainId: 1);
85+
86+
// SiweExternal (React-only wallet)
87+
var address = await wallet.LoginWithSiweExternal(
88+
// Windows console app example, adaptable to any runtime
89+
isMobile: false,
90+
browserOpenAction: (url) =>
91+
{
92+
var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true };
93+
_ = Process.Start(psi);
94+
},
95+
forceWalletIds: new List<string> { "io.metamask", "com.coinbase.wallet", "xyz.abs" }
96+
);
7697
```
7798

78-
<Callout variant="info" title="Client-Side Use">
79-
This wallet is designed for client-side use in applications where direct access to the user's private keys is not safe or necessary. It leverages OTP for secure authentication, allowing users to interact with blockchain applications seamlessly.
80-
</Callout>
8199
<Details summary="Parameters">
82100

83101
### client (required)
@@ -108,6 +126,18 @@ The OAuth provider to use for authentication. Supported values are `AuthProvider
108126

109127
The path to the directory where the wallet data is stored. Defaults to the application's data directory.
110128

129+
### siweSigner (optional)
130+
131+
An external wallet instance to use for SIWE authentication.
132+
133+
### legacyEncryptionKey (optional)
134+
135+
The encryption key that is no longer required but was used in the past. Only pass this if you had used custom auth before this was deprecated.
136+
137+
### walletSecret (optional)
138+
139+
The secret identifier to use when creating server-side wallets with backend authentication.
140+
111141
</Details>
112142

113143
<Details summary="Return Value">
@@ -246,6 +276,31 @@ if (!await ecosystemWallet.IsConnected())
246276

247277
**Note:** The `LoginWithOauth` API allows for custom browser handling, making it suitable for various application types and platforms.
248278

279+
## External Wallet Auth (Siwe & SiweExternal)
280+
281+
**LoginWithSiwe:** Initiate the login process by calling LoginWithSiwe on the EcosystemWallet instance. This will prompt the external wallet to sign a message instantly.
282+
283+
```csharp
284+
var address = await siweWallet.LoginWithSiwe(chainId: 1);
285+
```
286+
287+
**LoginWithSiweExternal:** Initiate the login process by calling LoginWithSiweExternal on the EcosystemWallet instance. This will initiate a browser-based login flow for external wallets that only support web platforms.
288+
289+
```csharp
290+
var address = await wallet.LoginWithSiweExternal(
291+
// Windows console app example, adaptable to any runtime
292+
isMobile: false,
293+
browserOpenAction: (url) =>
294+
{
295+
var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true };
296+
_ = Process.Start(psi);
297+
},
298+
forceWalletIds: new List<string> { "io.metamask", "com.coinbase.wallet", "xyz.abs" }
299+
);
300+
```
301+
302+
Note: The parameters are similar to the OAuth flow, with the addition of `forceWalletIds` to specify the wallet IDs to force the user to use. Using a single wallet id will skip the wallet selection screen and directly open the wallet.
303+
249304
## Unified Identity - Account Linking
250305

251306
EcosystemWallet supports linking multiple authentication methods to a single user account. This feature enables users to access their account using different authentication methods, such as email, phone, or OAuth, without creating separate accounts for each method.

0 commit comments

Comments
 (0)