-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
5 changed files
with
133 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -24,28 +24,39 @@ dotnet add package Thirdweb | |
```csharp | ||
using Thirdweb; | ||
|
||
// Create a client | ||
var client = new ThirdwebClient(secretKey: secretKey); | ||
// Do not use secret keys client side, use client id/bundle id instead | ||
var secretKey = Environment.GetEnvironmentVariable("THIRDWEB_SECRET_KEY"); | ||
// Do not use private keys client side, use embedded/smart accounts instead | ||
var privateKey = Environment.GetEnvironmentVariable("PRIVATE_KEY"); | ||
|
||
// Fetch timeout options are optional, default is 60000ms | ||
var client = new ThirdwebClient(secretKey: secretKey, fetchTimeoutOptions: new TimeoutOptions(storage: 30000, rpc: 60000)); | ||
|
||
// Access RPC directly if needed, generally not recommended | ||
// var rpc = ThirdwebRPC.GetRpcInstance(client, 421614); | ||
// var blockNumber = await rpc.SendRequestAsync<string>("eth_blockNumber"); | ||
// Console.WriteLine($"Block number: {blockNumber}"); | ||
// Interact with a contract | ||
var contract = new ThirdwebContract(client: client, address: "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D", chain: 1, abi: "function name() view returns (string)"); | ||
var contract = new ThirdwebContract(client: client, address: "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D", chain: 1, abi: "MyC#EscapedContractABI"); | ||
var readResult = await ThirdwebContract.ReadContract<string>(contract, "name"); | ||
Console.WriteLine($"Contract read result: {readResult}"); | ||
|
||
// Or directly interact with the RPC | ||
var rpc = ThirdwebRPC.GetRpcInstance(client, 1); | ||
var blockNumber = await rpc.SendRequestAsync<string>("eth_blockNumber"); | ||
Console.WriteLine($"Block number: {blockNumber}"); | ||
|
||
// Create accounts | ||
var privateKeyAccount = new PrivateKeyAccount(client, privateKey); | ||
var embeddedAccount = new EmbeddedAccount(client, "[email protected]"); | ||
var smartAccount = new SmartAccount(client, embeddedAccount, "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", true, 421614); | ||
// Create accounts (this is an advanced use case, typically one account is plenty) | ||
var privateKeyAccount = new PrivateKeyAccount(client: client, privateKeyHex: privateKey); | ||
var embeddedAccount = new EmbeddedAccount(client: client, email: "[email protected]"); // or email: null, phoneNumber: "+1234567890" | ||
var smartAccount = new SmartAccount(client: client, personalAccount: embeddedAccount, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614); | ||
|
||
// Attempt to connect pk accounts | ||
await privateKeyAccount.Connect(); | ||
await embeddedAccount.Connect(); | ||
|
||
// Reset embedded account (optional step for testing login flow) | ||
if (await embeddedAccount.IsConnected()) | ||
{ | ||
await embeddedAccount.Disconnect(); | ||
} | ||
|
||
// Relog if embedded account not logged in | ||
if (!await embeddedAccount.IsConnected()) | ||
{ | ||
|
@@ -66,7 +77,7 @@ if (!await embeddedAccount.IsConnected()) | |
} | ||
} | ||
|
||
// Connect the smart account with embedded signer and grant a session key to pk account | ||
// Connect the smart account with embedded signer and grant a session key to pk account (advanced use case) | ||
await smartAccount.Connect(); | ||
_ = await smartAccount.CreateSessionKey( | ||
signerAddress: await privateKeyAccount.GetAddress(), | ||
|
@@ -78,23 +89,49 @@ _ = await smartAccount.CreateSessionKey( | |
reqValidityEndTimestamp: Utils.GetUnixTimeStampIn10Years().ToString() | ||
); | ||
|
||
// Reconnect to same smart account with pk account as signer | ||
smartAccount = new SmartAccount(client, privateKeyAccount, "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", true, 421614, await smartAccount.GetAddress()); | ||
// Reconnect to same smart account with pk account as signer (specifying account address override) | ||
smartAccount = new SmartAccount( | ||
client: client, | ||
personalAccount: privateKeyAccount, | ||
factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", | ||
gasless: true, | ||
chainId: 421614, | ||
accountAddressOverride: await smartAccount.GetAddress() | ||
); | ||
await smartAccount.Connect(); | ||
|
||
// Log addresses | ||
Console.WriteLine($"PrivateKey Account: {await privateKeyAccount.GetAddress()}"); | ||
Console.WriteLine($"Embedded Account: {await embeddedAccount.GetAddress()}"); | ||
Console.WriteLine($"Smart Account: {await smartAccount.GetAddress()}"); | ||
|
||
// Initialize wallet | ||
// Initialize wallet (a wallet can hold multiple accounts, but only one can be active at a time) | ||
var thirdwebWallet = new ThirdwebWallet(); | ||
await thirdwebWallet.Initialize(new List<IThirdwebAccount> { privateKeyAccount, embeddedAccount, smartAccount }); | ||
thirdwebWallet.SetActive(await smartAccount.GetAddress()); | ||
Console.WriteLine($"Active account: {await thirdwebWallet.GetAddress()}"); | ||
|
||
// Sign, triggering deploy as needed and 1271 verification | ||
// Sign, triggering deploy as needed and 1271 verification if it's a smart wallet | ||
var message = "Hello, Thirdweb!"; | ||
var signature = await thirdwebWallet.PersonalSign(message); | ||
Console.WriteLine($"Signed message: {signature}"); | ||
|
||
var balanceBefore = await ThirdwebContract.ReadContract<BigInteger>(contract, "balanceOf", await thirdwebWallet.GetAddress()); | ||
Console.WriteLine($"Balance before mint: {balanceBefore}"); | ||
|
||
var writeResult = await ThirdwebContract.WriteContract(thirdwebWallet, contract, "mintTo", 0, await thirdwebWallet.GetAddress(), 100); | ||
Console.WriteLine($"Contract write result: {writeResult}"); | ||
|
||
var balanceAfter = await ThirdwebContract.ReadContract<BigInteger>(contract, "balanceOf", await thirdwebWallet.GetAddress()); | ||
Console.WriteLine($"Balance after mint: {balanceAfter}"); | ||
|
||
// Storage actions | ||
// // Will download from IPFS or normal urls | ||
// var downloadResult = await ThirdwebStorage.Download<string>(client: client, uri: "AnyUrlIncludingIpfs"); | ||
// Console.WriteLine($"Download result: {downloadResult}"); | ||
// // Will upload to IPFS | ||
// var uploadResult = await ThirdwebStorage.Upload(client: client, path: "AnyPath"); | ||
// Console.WriteLine($"Upload result preview: {uploadResult.PreviewUrl}"); | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,11 +9,15 @@ private static async Task Main(string[] args) | |
{ | ||
DotEnv.Load(); | ||
|
||
// Do not use secret keys client side, use client id/bundle id instead | ||
var secretKey = Environment.GetEnvironmentVariable("THIRDWEB_SECRET_KEY"); | ||
// Do not use private keys client side, use embedded/smart accounts instead | ||
var privateKey = Environment.GetEnvironmentVariable("PRIVATE_KEY"); | ||
|
||
// Fetch timeout options are optional, default is 60000ms | ||
var client = new ThirdwebClient(secretKey: secretKey, fetchTimeoutOptions: new TimeoutOptions(storage: 30000, rpc: 60000)); | ||
|
||
// Access RPC directly if needed, generally not recommended | ||
// var rpc = ThirdwebRPC.GetRpcInstance(client, 421614); | ||
// var blockNumber = await rpc.SendRequestAsync<string>("eth_blockNumber"); | ||
// Console.WriteLine($"Block number: {blockNumber}"); | ||
|
@@ -27,18 +31,20 @@ private static async Task Main(string[] args) | |
var readResult = await ThirdwebContract.ReadContract<string>(contract, "name"); | ||
Console.WriteLine($"Contract read result: {readResult}"); | ||
|
||
// Create accounts | ||
var privateKeyAccount = new PrivateKeyAccount(client, privateKey); | ||
var embeddedAccount = new EmbeddedAccount(client, "[email protected]"); | ||
var smartAccount = new SmartAccount(client, embeddedAccount, "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", true, 421614); | ||
// Create accounts (this is an advanced use case, typically one account is plenty) | ||
var privateKeyAccount = new PrivateKeyAccount(client: client, privateKeyHex: privateKey); | ||
var embeddedAccount = new EmbeddedAccount(client: client, email: "[email protected]"); // or email: null, phoneNumber: "+1234567890" | ||
var smartAccount = new SmartAccount(client: client, personalAccount: embeddedAccount, factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", gasless: true, chainId: 421614); | ||
|
||
// Attempt to connect pk accounts | ||
await privateKeyAccount.Connect(); | ||
await embeddedAccount.Connect(); | ||
|
||
// Reset embedded account | ||
// Reset embedded account (optional step for testing login flow) | ||
if (await embeddedAccount.IsConnected()) | ||
{ | ||
await embeddedAccount.Disconnect(); | ||
} | ||
|
||
// Relog if embedded account not logged in | ||
if (!await embeddedAccount.IsConnected()) | ||
|
@@ -60,7 +66,7 @@ private static async Task Main(string[] args) | |
} | ||
} | ||
|
||
// Connect the smart account with embedded signer and grant a session key to pk account | ||
// Connect the smart account with embedded signer and grant a session key to pk account (advanced use case) | ||
await smartAccount.Connect(); | ||
_ = await smartAccount.CreateSessionKey( | ||
signerAddress: await privateKeyAccount.GetAddress(), | ||
|
@@ -72,22 +78,29 @@ private static async Task Main(string[] args) | |
reqValidityEndTimestamp: Utils.GetUnixTimeStampIn10Years().ToString() | ||
); | ||
|
||
// Reconnect to same smart account with pk account as signer | ||
smartAccount = new SmartAccount(client, privateKeyAccount, "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", true, 421614, await smartAccount.GetAddress()); | ||
// Reconnect to same smart account with pk account as signer (specifying account address override) | ||
smartAccount = new SmartAccount( | ||
client: client, | ||
personalAccount: privateKeyAccount, | ||
factoryAddress: "0xbf1C9aA4B1A085f7DA890a44E82B0A1289A40052", | ||
gasless: true, | ||
chainId: 421614, | ||
accountAddressOverride: await smartAccount.GetAddress() | ||
); | ||
await smartAccount.Connect(); | ||
|
||
// Log addresses | ||
Console.WriteLine($"PrivateKey Account: {await privateKeyAccount.GetAddress()}"); | ||
Console.WriteLine($"Embedded Account: {await embeddedAccount.GetAddress()}"); | ||
Console.WriteLine($"Smart Account: {await smartAccount.GetAddress()}"); | ||
|
||
// Initialize wallet | ||
// Initialize wallet (a wallet can hold multiple accounts, but only one can be active at a time) | ||
var thirdwebWallet = new ThirdwebWallet(); | ||
await thirdwebWallet.Initialize(new List<IThirdwebAccount> { privateKeyAccount, embeddedAccount, smartAccount }); | ||
thirdwebWallet.SetActive(await smartAccount.GetAddress()); | ||
Console.WriteLine($"Active account: {await thirdwebWallet.GetAddress()}"); | ||
|
||
// Sign, triggering deploy as needed and 1271 verification | ||
// Sign, triggering deploy as needed and 1271 verification if it's a smart wallet | ||
var message = "Hello, Thirdweb!"; | ||
var signature = await thirdwebWallet.PersonalSign(message); | ||
Console.WriteLine($"Signed message: {signature}"); | ||
|
@@ -100,5 +113,15 @@ private static async Task Main(string[] args) | |
|
||
var balanceAfter = await ThirdwebContract.ReadContract<BigInteger>(contract, "balanceOf", await thirdwebWallet.GetAddress()); | ||
Console.WriteLine($"Balance after mint: {balanceAfter}"); | ||
|
||
// Storage actions | ||
|
||
// // Will download from IPFS or normal urls | ||
// var downloadResult = await ThirdwebStorage.Download<string>(client: client, uri: "AnyUrlIncludingIpfs"); | ||
// Console.WriteLine($"Download result: {downloadResult}"); | ||
|
||
// // Will upload to IPFS | ||
// var uploadResult = await ThirdwebStorage.Upload(client: client, path: "AnyPath"); | ||
// Console.WriteLine($"Upload result preview: {uploadResult.PreviewUrl}"); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters