From d8d1432ade1b02957a9ceff968c069319adac21b Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Tue, 17 Dec 2024 13:07:17 +0700 Subject: [PATCH 1/4] Account Unlinking --- Thirdweb.Console/Program.cs | 20 ++++++++-- Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs | 10 +++++ .../EcosystemWallet/EcosystemWallet.cs | 38 +++++++++++++++++++ .../EmbeddedWallet.Authentication/Server.cs | 16 ++++++++ .../EmbeddedWallet.AccountLinking.cs | 5 +++ .../InAppWallet/InAppWallet.Types.cs | 22 +++++++++++ .../PrivateKeyWallet/PrivateKeyWallet.cs | 5 +++ .../SmartWallet/SmartWallet.cs | 10 +++++ 8 files changed, 123 insertions(+), 3 deletions(-) diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs index c3f195de..d65ea601 100644 --- a/Thirdweb.Console/Program.cs +++ b/Thirdweb.Console/Program.cs @@ -241,7 +241,7 @@ #region Account Linking -// var inAppWalletMain = await InAppWallet.Create(client: client, authProvider: AuthProvider.Google); +// var inAppWalletMain = await InAppWallet.Create(client: client, authProvider: AuthProvider.Telegram); // if (!await inAppWalletMain.IsConnected()) // { // _ = await inAppWalletMain.LoginWithOauth( @@ -260,12 +260,26 @@ // var oldLinkedAccounts = await inAppWalletMain.GetLinkedAccounts(); // Console.WriteLine($"Old linked accounts: {JsonConvert.SerializeObject(oldLinkedAccounts, Formatting.Indented)}"); -// var inAppWalletToLink = await InAppWallet.Create(client: client, authProvider: AuthProvider.Guest); -// _ = await inAppWalletMain.LinkAccount(walletToLink: inAppWalletToLink); +// External wallet variant +// var externalWallet = await PrivateKeyWallet.Generate(client: client); +// var externalWalletAddress = await externalWallet.GetAddress(); +// var inAppWalletToLink = await InAppWallet.Create(client: client, authProvider: AuthProvider.Siwe, siweSigner: externalWallet); +// _ = await inAppWalletMain.LinkAccount(walletToLink: inAppWalletToLink, chainId: 421614); + +// Email variant +// var linkedEmail = "firekeeper+unlinkingtest@thirdweb.com"; +// var inAppWalletToLink = await InAppWallet.Create(client: client, email: linkedEmail); +// await inAppWalletToLink.SendOTP(); +// Console.WriteLine("Enter OTP:"); +// var otp = Console.ReadLine(); +// _ = await inAppWalletMain.LinkAccount(walletToLink: inAppWalletToLink, otp: otp); // var linkedAccounts = await inAppWalletMain.GetLinkedAccounts(); // Console.WriteLine($"Linked accounts: {JsonConvert.SerializeObject(linkedAccounts, Formatting.Indented)}"); +// var unlinkingResult = await inAppWalletMain.UnlinkAccount(authProviderToUnlink: UnlinkingType.email, email: linkedEmail); +// Console.WriteLine($"Unlinking result: {JsonConvert.SerializeObject(unlinkingResult, Formatting.Indented)}"); + #endregion #region Smart Wallet - Authenticate diff --git a/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs b/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs index 3c5879bd..0f87f20d 100644 --- a/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs @@ -155,6 +155,16 @@ Task> LinkAccount( string payload = null ); + /// + /// Unlinks an account (auth method) from the current wallet. Must pass corresponding parameter to unlink. + /// + /// The auth provider to unlink. + /// The related wallet address to unlink (if applicable). + /// The related email to unlink (if applicable). + /// The related phone number to unlink (if applicable). + /// The related user ID to unlink (if applicable). + Task> UnlinkAccount(UnlinkingType authProviderToUnlink, string address = null, string email = null, string phone = null, string id = null); + /// /// Returns a list of linked accounts to the current wallet. /// diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs index d970763a..666f831c 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs @@ -332,6 +332,44 @@ public string GenerateExternalLoginLink(string redirectUrl) #region Account Linking + public async Task> UnlinkAccount(UnlinkingType authProviderToUnlink, string address = null, string email = null, string phone = null, string id = null) + { + if (!await this.IsConnected().ConfigureAwait(false)) + { + throw new InvalidOperationException("Cannot unlink account with a wallet that is not connected. Please login to the wallet before unlinking other wallets."); + } + + var currentAccountToken = this.EmbeddedWallet.GetSessionData()?.AuthToken; + var linkedType = authProviderToUnlink.ToString(); + var linkedDetails = new + { + address, + email, + phone, + id + }; + + var serverLinkedAccounts = await this.EmbeddedWallet.UnlinkAccountAsync(currentAccountToken, linkedType, linkedDetails).ConfigureAwait(false); + var linkedAccounts = new List(); + foreach (var linkedAccount in serverLinkedAccounts) + { + linkedAccounts.Add( + new LinkedAccount + { + Type = linkedAccount.Type, + Details = new LinkedAccount.LinkedAccountDetails + { + Email = linkedAccount.Details?.Email, + Address = linkedAccount.Details?.Address, + Phone = linkedAccount.Details?.Phone, + Id = linkedAccount.Details?.Id + } + } + ); + } + return linkedAccounts; + } + public async Task> LinkAccount( IThirdwebWallet walletToLink, string otp = null, diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/Server.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/Server.cs index 680c9141..6a2e7699 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/Server.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/Server.cs @@ -6,6 +6,7 @@ namespace Thirdweb.EWS; internal abstract class ServerBase { + internal abstract Task> UnlinkAccountAsync(string currentAccountToken, string linkedType, object linkedDetails); internal abstract Task> LinkAccountAsync(string currentAccountToken, string authTokenToConnect); internal abstract Task> GetLinkedAccountsAsync(string currentAccountToken); @@ -50,6 +51,21 @@ internal Server(ThirdwebClient client, IThirdwebHttpClient httpClient) this._httpClient = httpClient; } + // account/disconnect + internal override async Task> UnlinkAccountAsync(string currentAccountToken, string linkedType, object linkedDetails) + { + var uri = MakeUri2024("/account/disconnect"); + var request = new HttpRequestMessage(HttpMethod.Post, uri) + { + Content = MakeHttpContent(new { type = linkedType, details = linkedDetails }) + }; + var response = await this.SendHttpWithAuthAsync(request, currentAccountToken).ConfigureAwait(false); + await CheckStatusCodeAsync(response).ConfigureAwait(false); + + var res = await DeserializeAsync(response).ConfigureAwait(false); + return res == null || res.LinkedAccounts == null || res.LinkedAccounts.Count == 0 ? throw new InvalidOperationException("No linked accounts returned") : res.LinkedAccounts; + } + // account/connect internal override async Task> LinkAccountAsync(string currentAccountToken, string authTokenToConnect) { diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.AccountLinking.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.AccountLinking.cs index 2990bb9d..fe207fe8 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.AccountLinking.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.AccountLinking.cs @@ -2,6 +2,11 @@ internal partial class EmbeddedWallet { + public async Task> UnlinkAccountAsync(string currentAccountToken, string linkedType, object linkedDetails) + { + return await this._server.UnlinkAccountAsync(currentAccountToken, linkedType, linkedDetails).ConfigureAwait(false); + } + public async Task> LinkAccountAsync(string currentAccountToken, string authTokenToConnect) { return await this._server.LinkAccountAsync(currentAccountToken, authTokenToConnect).ConfigureAwait(false); diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs index ca022877..2079c044 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs @@ -26,6 +26,28 @@ public enum AuthProvider Steam } +public enum UnlinkingType +{ + apple, + coinbase, + discord, + email, + facebook, + farcaster, + github, + google, + guest, + line, + passkey, + phone, + siwe, + steam, + telegram, + twitch, + x, + wallet +} + /// /// Represents a linked account. /// diff --git a/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs b/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs index e671eb35..c9161472 100644 --- a/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs @@ -380,5 +380,10 @@ public virtual Task> GetLinkedAccounts() throw new InvalidOperationException("GetLinkedAccounts is not supported for private key wallets."); } + public Task> UnlinkAccount(UnlinkingType authProviderToUnlink, string address = null, string email = null, string phone = null, string id = null) + { + throw new InvalidOperationException("UnlinkAccount is not supported for private key wallets."); + } + #endregion } diff --git a/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs b/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs index 6e52b157..f2b49904 100644 --- a/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs @@ -1167,6 +1167,16 @@ public Task Disconnect() return Task.CompletedTask; } + public async Task> UnlinkAccount(UnlinkingType authProviderToUnlink, string address = null, string email = null, string phone = null, string id = null) + { + var personalWallet = await this.GetPersonalWallet().ConfigureAwait(false); + if (personalWallet is not InAppWallet and not EcosystemWallet) + { + throw new Exception("SmartWallet.UnlinkAccount is only supported if the signer is an InAppWallet or EcosystemWallet"); + } + return await personalWallet.UnlinkAccount(authProviderToUnlink, address, email, phone, id).ConfigureAwait(false); + } + public async Task> LinkAccount( IThirdwebWallet walletToLink, string otp = null, From 95673ad0b3e7d47ef1393857d40430909713de45 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Tue, 17 Dec 2024 13:18:35 +0700 Subject: [PATCH 2/4] drop the enum, match type from GetLinkedAccounts --- Thirdweb.Console/Program.cs | 12 ++-------- Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs | 4 ++-- .../EcosystemWallet/EcosystemWallet.cs | 3 +-- .../InAppWallet/InAppWallet.Types.cs | 22 ------------------- .../PrivateKeyWallet/PrivateKeyWallet.cs | 2 +- .../SmartWallet/SmartWallet.cs | 4 ++-- 6 files changed, 8 insertions(+), 39 deletions(-) diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs index d65ea601..b6b9eef0 100644 --- a/Thirdweb.Console/Program.cs +++ b/Thirdweb.Console/Program.cs @@ -260,24 +260,16 @@ // var oldLinkedAccounts = await inAppWalletMain.GetLinkedAccounts(); // Console.WriteLine($"Old linked accounts: {JsonConvert.SerializeObject(oldLinkedAccounts, Formatting.Indented)}"); -// External wallet variant +// // External wallet variant // var externalWallet = await PrivateKeyWallet.Generate(client: client); // var externalWalletAddress = await externalWallet.GetAddress(); // var inAppWalletToLink = await InAppWallet.Create(client: client, authProvider: AuthProvider.Siwe, siweSigner: externalWallet); // _ = await inAppWalletMain.LinkAccount(walletToLink: inAppWalletToLink, chainId: 421614); -// Email variant -// var linkedEmail = "firekeeper+unlinkingtest@thirdweb.com"; -// var inAppWalletToLink = await InAppWallet.Create(client: client, email: linkedEmail); -// await inAppWalletToLink.SendOTP(); -// Console.WriteLine("Enter OTP:"); -// var otp = Console.ReadLine(); -// _ = await inAppWalletMain.LinkAccount(walletToLink: inAppWalletToLink, otp: otp); - // var linkedAccounts = await inAppWalletMain.GetLinkedAccounts(); // Console.WriteLine($"Linked accounts: {JsonConvert.SerializeObject(linkedAccounts, Formatting.Indented)}"); -// var unlinkingResult = await inAppWalletMain.UnlinkAccount(authProviderToUnlink: UnlinkingType.email, email: linkedEmail); +// var unlinkingResult = await inAppWalletMain.UnlinkAccount(linkedType: "siwe", address: externalWalletAddress); // Console.WriteLine($"Unlinking result: {JsonConvert.SerializeObject(unlinkingResult, Formatting.Indented)}"); #endregion diff --git a/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs b/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs index 0f87f20d..16f62fbe 100644 --- a/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs @@ -158,12 +158,12 @@ Task> LinkAccount( /// /// Unlinks an account (auth method) from the current wallet. Must pass corresponding parameter to unlink. /// - /// The auth provider to unlink. + /// The auth provider to unlink, use the type you get from GetLinkedAccounts. /// The related wallet address to unlink (if applicable). /// The related email to unlink (if applicable). /// The related phone number to unlink (if applicable). /// The related user ID to unlink (if applicable). - Task> UnlinkAccount(UnlinkingType authProviderToUnlink, string address = null, string email = null, string phone = null, string id = null); + Task> UnlinkAccount(string linkedType, string address = null, string email = null, string phone = null, string id = null); /// /// Returns a list of linked accounts to the current wallet. diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs index 666f831c..5b9c73e1 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs @@ -332,7 +332,7 @@ public string GenerateExternalLoginLink(string redirectUrl) #region Account Linking - public async Task> UnlinkAccount(UnlinkingType authProviderToUnlink, string address = null, string email = null, string phone = null, string id = null) + public async Task> UnlinkAccount(string linkedType, string address = null, string email = null, string phone = null, string id = null) { if (!await this.IsConnected().ConfigureAwait(false)) { @@ -340,7 +340,6 @@ public async Task> UnlinkAccount(UnlinkingType authProviderT } var currentAccountToken = this.EmbeddedWallet.GetSessionData()?.AuthToken; - var linkedType = authProviderToUnlink.ToString(); var linkedDetails = new { address, diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs index 2079c044..ca022877 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs @@ -26,28 +26,6 @@ public enum AuthProvider Steam } -public enum UnlinkingType -{ - apple, - coinbase, - discord, - email, - facebook, - farcaster, - github, - google, - guest, - line, - passkey, - phone, - siwe, - steam, - telegram, - twitch, - x, - wallet -} - /// /// Represents a linked account. /// diff --git a/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs b/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs index c9161472..b2746654 100644 --- a/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs @@ -380,7 +380,7 @@ public virtual Task> GetLinkedAccounts() throw new InvalidOperationException("GetLinkedAccounts is not supported for private key wallets."); } - public Task> UnlinkAccount(UnlinkingType authProviderToUnlink, string address = null, string email = null, string phone = null, string id = null) + public Task> UnlinkAccount(string linkedType, string address = null, string email = null, string phone = null, string id = null) { throw new InvalidOperationException("UnlinkAccount is not supported for private key wallets."); } diff --git a/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs b/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs index f2b49904..44feb3c3 100644 --- a/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs @@ -1167,14 +1167,14 @@ public Task Disconnect() return Task.CompletedTask; } - public async Task> UnlinkAccount(UnlinkingType authProviderToUnlink, string address = null, string email = null, string phone = null, string id = null) + public async Task> UnlinkAccount(string linkedType, string address = null, string email = null, string phone = null, string id = null) { var personalWallet = await this.GetPersonalWallet().ConfigureAwait(false); if (personalWallet is not InAppWallet and not EcosystemWallet) { throw new Exception("SmartWallet.UnlinkAccount is only supported if the signer is an InAppWallet or EcosystemWallet"); } - return await personalWallet.UnlinkAccount(authProviderToUnlink, address, email, phone, id).ConfigureAwait(false); + return await personalWallet.UnlinkAccount(linkedType, address, email, phone, id).ConfigureAwait(false); } public async Task> LinkAccount( From 16f1e150bbbe732ae7fa21b8e246831eefbe26f1 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Tue, 17 Dec 2024 13:39:37 +0700 Subject: [PATCH 3/4] Better dx, LinkedAccount type across the board --- Thirdweb.Console/Program.cs | 58 +++++++++---------- Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs | 12 ++-- .../EcosystemWallet/EcosystemWallet.cs | 11 +--- .../EmbeddedWallet.Authentication/Server.cs | 6 +- .../EmbeddedWallet.AccountLinking.cs | 15 ++++- .../InAppWallet/InAppWallet.Types.cs | 10 ++++ .../PrivateKeyWallet/PrivateKeyWallet.cs | 2 +- .../SmartWallet/SmartWallet.cs | 4 +- 8 files changed, 63 insertions(+), 55 deletions(-) diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs index b6b9eef0..7582df7c 100644 --- a/Thirdweb.Console/Program.cs +++ b/Thirdweb.Console/Program.cs @@ -241,36 +241,34 @@ #region Account Linking -// var inAppWalletMain = await InAppWallet.Create(client: client, authProvider: AuthProvider.Telegram); -// if (!await inAppWalletMain.IsConnected()) -// { -// _ = await inAppWalletMain.LoginWithOauth( -// isMobile: false, -// (url) => -// { -// var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true }; -// _ = Process.Start(psi); -// }, -// "thirdweb://", -// new InAppWalletBrowser() -// ); -// } -// Console.WriteLine($"Main InAppWallet address: {await inAppWalletMain.GetAddress()}"); - -// var oldLinkedAccounts = await inAppWalletMain.GetLinkedAccounts(); -// Console.WriteLine($"Old linked accounts: {JsonConvert.SerializeObject(oldLinkedAccounts, Formatting.Indented)}"); - -// // External wallet variant -// var externalWallet = await PrivateKeyWallet.Generate(client: client); -// var externalWalletAddress = await externalWallet.GetAddress(); -// var inAppWalletToLink = await InAppWallet.Create(client: client, authProvider: AuthProvider.Siwe, siweSigner: externalWallet); -// _ = await inAppWalletMain.LinkAccount(walletToLink: inAppWalletToLink, chainId: 421614); - -// var linkedAccounts = await inAppWalletMain.GetLinkedAccounts(); -// Console.WriteLine($"Linked accounts: {JsonConvert.SerializeObject(linkedAccounts, Formatting.Indented)}"); - -// var unlinkingResult = await inAppWalletMain.UnlinkAccount(linkedType: "siwe", address: externalWalletAddress); -// Console.WriteLine($"Unlinking result: {JsonConvert.SerializeObject(unlinkingResult, Formatting.Indented)}"); +var inAppWalletMain = await InAppWallet.Create(client: client, authProvider: AuthProvider.Telegram); +if (!await inAppWalletMain.IsConnected()) +{ + _ = await inAppWalletMain.LoginWithOauth( + isMobile: false, + (url) => + { + var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true }; + _ = Process.Start(psi); + }, + "thirdweb://", + new InAppWalletBrowser() + ); +} +Console.WriteLine($"Main InAppWallet address: {await inAppWalletMain.GetAddress()}"); + +var oldLinkedAccounts = await inAppWalletMain.GetLinkedAccounts(); +Console.WriteLine($"Old linked accounts: {JsonConvert.SerializeObject(oldLinkedAccounts, Formatting.Indented)}"); + +// External wallet variant +var externalWallet = await PrivateKeyWallet.Generate(client: client); +var externalWalletAddress = await externalWallet.GetAddress(); +var inAppWalletToLink = await InAppWallet.Create(client: client, authProvider: AuthProvider.Siwe, siweSigner: externalWallet); +var linkedAccounts = await inAppWalletMain.LinkAccount(walletToLink: inAppWalletToLink, chainId: 421614); +Console.WriteLine($"Linked accounts: {JsonConvert.SerializeObject(linkedAccounts, Formatting.Indented)}"); + +var unlinkingResult = await inAppWalletMain.UnlinkAccount(linkedAccounts.First(linkedAccounts => linkedAccounts.Type == "siwe")); +Console.WriteLine($"Unlinking result: {JsonConvert.SerializeObject(unlinkingResult, Formatting.Indented)}"); #endregion diff --git a/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs b/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs index 16f62fbe..164d4b1d 100644 --- a/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/IThirdwebWallet.cs @@ -156,14 +156,10 @@ Task> LinkAccount( ); /// - /// Unlinks an account (auth method) from the current wallet. Must pass corresponding parameter to unlink. - /// - /// The auth provider to unlink, use the type you get from GetLinkedAccounts. - /// The related wallet address to unlink (if applicable). - /// The related email to unlink (if applicable). - /// The related phone number to unlink (if applicable). - /// The related user ID to unlink (if applicable). - Task> UnlinkAccount(string linkedType, string address = null, string email = null, string phone = null, string id = null); + /// Unlinks an account (auth method) from the current wallet. + /// + /// The linked account to unlink. Same type returned by . + Task> UnlinkAccount(LinkedAccount accountToUnlink); /// /// Returns a list of linked accounts to the current wallet. diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs index 5b9c73e1..8a2231e4 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EcosystemWallet/EcosystemWallet.cs @@ -332,7 +332,7 @@ public string GenerateExternalLoginLink(string redirectUrl) #region Account Linking - public async Task> UnlinkAccount(string linkedType, string address = null, string email = null, string phone = null, string id = null) + public async Task> UnlinkAccount(LinkedAccount accountToUnlink) { if (!await this.IsConnected().ConfigureAwait(false)) { @@ -340,15 +340,8 @@ public async Task> UnlinkAccount(string linkedType, string a } var currentAccountToken = this.EmbeddedWallet.GetSessionData()?.AuthToken; - var linkedDetails = new - { - address, - email, - phone, - id - }; - var serverLinkedAccounts = await this.EmbeddedWallet.UnlinkAccountAsync(currentAccountToken, linkedType, linkedDetails).ConfigureAwait(false); + var serverLinkedAccounts = await this.EmbeddedWallet.UnlinkAccountAsync(currentAccountToken, accountToUnlink).ConfigureAwait(false); var linkedAccounts = new List(); foreach (var linkedAccount in serverLinkedAccounts) { diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/Server.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/Server.cs index 6a2e7699..a396ff15 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/Server.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet.Authentication/Server.cs @@ -6,7 +6,7 @@ namespace Thirdweb.EWS; internal abstract class ServerBase { - internal abstract Task> UnlinkAccountAsync(string currentAccountToken, string linkedType, object linkedDetails); + internal abstract Task> UnlinkAccountAsync(string currentAccountToken, Server.LinkedAccount linkedAccount); internal abstract Task> LinkAccountAsync(string currentAccountToken, string authTokenToConnect); internal abstract Task> GetLinkedAccountsAsync(string currentAccountToken); @@ -52,12 +52,12 @@ internal Server(ThirdwebClient client, IThirdwebHttpClient httpClient) } // account/disconnect - internal override async Task> UnlinkAccountAsync(string currentAccountToken, string linkedType, object linkedDetails) + internal override async Task> UnlinkAccountAsync(string currentAccountToken, LinkedAccount linkedAccount) { var uri = MakeUri2024("/account/disconnect"); var request = new HttpRequestMessage(HttpMethod.Post, uri) { - Content = MakeHttpContent(new { type = linkedType, details = linkedDetails }) + Content = MakeHttpContent(linkedAccount) }; var response = await this.SendHttpWithAuthAsync(request, currentAccountToken).ConfigureAwait(false); await CheckStatusCodeAsync(response).ConfigureAwait(false); diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.AccountLinking.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.AccountLinking.cs index fe207fe8..0e1335aa 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.AccountLinking.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/EmbeddedWallet/EmbeddedWallet.AccountLinking.cs @@ -2,9 +2,20 @@ internal partial class EmbeddedWallet { - public async Task> UnlinkAccountAsync(string currentAccountToken, string linkedType, object linkedDetails) + public async Task> UnlinkAccountAsync(string currentAccountToken, LinkedAccount linkedAccount) { - return await this._server.UnlinkAccountAsync(currentAccountToken, linkedType, linkedDetails).ConfigureAwait(false); + var serverLinkedAccount = new Server.LinkedAccount + { + Type = linkedAccount.Type, + Details = new Server.LinkedAccount.LinkedAccountDetails + { + Email = linkedAccount.Details.Email, + Address = linkedAccount.Details.Address, + Phone = linkedAccount.Details.Phone, + Id = linkedAccount.Details.Id + } + }; + return await this._server.UnlinkAccountAsync(currentAccountToken, serverLinkedAccount).ConfigureAwait(false); } public async Task> LinkAccountAsync(string currentAccountToken, string authTokenToConnect) diff --git a/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs b/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs index ca022877..4b4056b2 100644 --- a/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs +++ b/Thirdweb/Thirdweb.Wallets/InAppWallet/InAppWallet.Types.cs @@ -31,14 +31,24 @@ public enum AuthProvider /// public struct LinkedAccount { + [JsonProperty("type")] public string Type { get; set; } + + [JsonProperty("details")] public LinkedAccountDetails Details { get; set; } public struct LinkedAccountDetails { + [JsonProperty("email")] public string Email { get; set; } + + [JsonProperty("name")] public string Address { get; set; } + + [JsonProperty("phone")] public string Phone { get; set; } + + [JsonProperty("id")] public string Id { get; set; } } diff --git a/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs b/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs index b2746654..26d90a48 100644 --- a/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/PrivateKeyWallet/PrivateKeyWallet.cs @@ -380,7 +380,7 @@ public virtual Task> GetLinkedAccounts() throw new InvalidOperationException("GetLinkedAccounts is not supported for private key wallets."); } - public Task> UnlinkAccount(string linkedType, string address = null, string email = null, string phone = null, string id = null) + public Task> UnlinkAccount(LinkedAccount accountToUnlink) { throw new InvalidOperationException("UnlinkAccount is not supported for private key wallets."); } diff --git a/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs b/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs index 44feb3c3..68548c8f 100644 --- a/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs +++ b/Thirdweb/Thirdweb.Wallets/SmartWallet/SmartWallet.cs @@ -1167,14 +1167,14 @@ public Task Disconnect() return Task.CompletedTask; } - public async Task> UnlinkAccount(string linkedType, string address = null, string email = null, string phone = null, string id = null) + public async Task> UnlinkAccount(LinkedAccount accountToUnlink) { var personalWallet = await this.GetPersonalWallet().ConfigureAwait(false); if (personalWallet is not InAppWallet and not EcosystemWallet) { throw new Exception("SmartWallet.UnlinkAccount is only supported if the signer is an InAppWallet or EcosystemWallet"); } - return await personalWallet.UnlinkAccount(linkedType, address, email, phone, id).ConfigureAwait(false); + return await personalWallet.UnlinkAccount(accountToUnlink).ConfigureAwait(false); } public async Task> LinkAccount( From de8b8ad52e46f8f672dbe0301612ec25dc6e16b0 Mon Sep 17 00:00:00 2001 From: 0xFirekeeper <0xFirekeeper@gmail.com> Date: Tue, 17 Dec 2024 13:40:20 +0700 Subject: [PATCH 4/4] Update Program.cs --- Thirdweb.Console/Program.cs | 55 ++++++++++++++++++------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/Thirdweb.Console/Program.cs b/Thirdweb.Console/Program.cs index 7582df7c..e8d52ab8 100644 --- a/Thirdweb.Console/Program.cs +++ b/Thirdweb.Console/Program.cs @@ -241,34 +241,33 @@ #region Account Linking -var inAppWalletMain = await InAppWallet.Create(client: client, authProvider: AuthProvider.Telegram); -if (!await inAppWalletMain.IsConnected()) -{ - _ = await inAppWalletMain.LoginWithOauth( - isMobile: false, - (url) => - { - var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true }; - _ = Process.Start(psi); - }, - "thirdweb://", - new InAppWalletBrowser() - ); -} -Console.WriteLine($"Main InAppWallet address: {await inAppWalletMain.GetAddress()}"); - -var oldLinkedAccounts = await inAppWalletMain.GetLinkedAccounts(); -Console.WriteLine($"Old linked accounts: {JsonConvert.SerializeObject(oldLinkedAccounts, Formatting.Indented)}"); - -// External wallet variant -var externalWallet = await PrivateKeyWallet.Generate(client: client); -var externalWalletAddress = await externalWallet.GetAddress(); -var inAppWalletToLink = await InAppWallet.Create(client: client, authProvider: AuthProvider.Siwe, siweSigner: externalWallet); -var linkedAccounts = await inAppWalletMain.LinkAccount(walletToLink: inAppWalletToLink, chainId: 421614); -Console.WriteLine($"Linked accounts: {JsonConvert.SerializeObject(linkedAccounts, Formatting.Indented)}"); - -var unlinkingResult = await inAppWalletMain.UnlinkAccount(linkedAccounts.First(linkedAccounts => linkedAccounts.Type == "siwe")); -Console.WriteLine($"Unlinking result: {JsonConvert.SerializeObject(unlinkingResult, Formatting.Indented)}"); +// var inAppWalletMain = await InAppWallet.Create(client: client, authProvider: AuthProvider.Telegram); +// if (!await inAppWalletMain.IsConnected()) +// { +// _ = await inAppWalletMain.LoginWithOauth( +// isMobile: false, +// (url) => +// { +// var psi = new ProcessStartInfo { FileName = url, UseShellExecute = true }; +// _ = Process.Start(psi); +// }, +// "thirdweb://", +// new InAppWalletBrowser() +// ); +// } +// Console.WriteLine($"Main InAppWallet address: {await inAppWalletMain.GetAddress()}"); + +// var oldLinkedAccounts = await inAppWalletMain.GetLinkedAccounts(); +// Console.WriteLine($"Old linked accounts: {JsonConvert.SerializeObject(oldLinkedAccounts, Formatting.Indented)}"); + +// // External wallet variant +// var externalWallet = await PrivateKeyWallet.Generate(client: client); +// var inAppWalletToLink = await InAppWallet.Create(client: client, authProvider: AuthProvider.Siwe, siweSigner: externalWallet); +// var linkedAccounts = await inAppWalletMain.LinkAccount(walletToLink: inAppWalletToLink, chainId: 421614); +// Console.WriteLine($"Linked accounts: {JsonConvert.SerializeObject(linkedAccounts, Formatting.Indented)}"); + +// var unlinkingResult = await inAppWalletMain.UnlinkAccount(linkedAccounts.First(linkedAccounts => linkedAccounts.Type == "siwe")); +// Console.WriteLine($"Unlinking result: {JsonConvert.SerializeObject(unlinkingResult, Formatting.Indented)}"); #endregion