Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions SDK/Runtime/Auth/Models/IPrivyUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,29 @@ public interface IPrivyUser
/// Creates a new Solana embedded wallet for the user.
/// </summary>
Task<IEmbeddedSolanaWallet> CreateSolanaWallet(bool allowAdditional = false);

/// <summary>
/// Generates a cryptographic signature for an API request payload using the
/// authenticated user's signing key.
///
/// This method canonicalizes the payload to JSON (RFC 8785) and signs the
/// canonical bytes. The returned base64-encoded signature can be included as
/// the <c>privy-authorization-signature</c> header to authorize Privy API requests.
/// </summary>
/// <param name="payload">The <see cref="WalletApiPayload"/> containing the API request details to be signed.</param>
/// <returns>A task whose result is the base64-encoded signature string.</returns>
Task<string> GenerateAuthorizationSignature(WalletApiPayload payload);

/// <summary>
/// Generates a cryptographic signature for a pre-serialized binary payload using the
/// authenticated user's signing key.
///
/// Unlike the typed payload variant, this method skips JSON canonicalization and signs the
/// raw bytes directly. Use this when you have already serialized and canonicalized your
/// payload outside the SDK.
/// </summary>
/// <param name="payload">The pre-serialized payload bytes to sign.</param>
/// <returns>A task whose result is the base64-encoded signature string.</returns>
Task<string> GenerateAuthorizationSignature(byte[] payload);
}
}
17 changes: 16 additions & 1 deletion SDK/Runtime/Auth/Models/PrivyUser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,20 +98,22 @@ public Dictionary<string, string> CustomMetadata
private AppConfigRepository _appConfigRepository;
private WalletApiWalletCreator _walletApiWalletCreator;
private WalletApiRepository _walletApiRepository;
private IAuthorizationKey _authorizationKey;

private EmbeddedWalletManager _embeddedWalletManager;

//Constructor is internal, but the object is public facing
//TODO: Create Interface class for this
internal PrivyUser(AuthDelegator authDelegator, EmbeddedWalletManager embeddedWalletManager,
AppConfigRepository appConfigRepository, WalletApiWalletCreator walletApiWalletCreator,
WalletApiRepository walletApiRepository)
WalletApiRepository walletApiRepository, IAuthorizationKey authorizationKey)
{
_authDelegator = authDelegator;
_embeddedWalletManager = embeddedWalletManager;
_appConfigRepository = appConfigRepository;
_walletApiWalletCreator = walletApiWalletCreator;
_walletApiRepository = walletApiRepository;
_authorizationKey = authorizationKey;
}

public async Task<string> GetAccessToken()
Expand All @@ -124,6 +126,19 @@ public async Task<string> GetIdentityToken()
return await _authDelegator.GetIdentityToken();
}

public async Task<string> GenerateAuthorizationSignature(WalletApiPayload payload)
{
byte[] encodedPayload = payload.EncodePayload();
byte[] signature = await _authorizationKey.Signature(encodedPayload);
return Convert.ToBase64String(signature);
}

public async Task<string> GenerateAuthorizationSignature(byte[] payload)
{
byte[] signature = await _authorizationKey.Signature(payload);
return Convert.ToBase64String(signature);
}

// Public Methods
public async Task<IEmbeddedEthereumWallet> CreateEthereumWallet(bool allowAdditional = false)
{
Expand Down
2 changes: 1 addition & 1 deletion SDK/Runtime/Core/PrivyImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ public PrivyImpl(PrivyConfig config)
OAuth = new LoginWithOAuth(_authDelegator);
Sms = new LoginWithSms(_authDelegator);
_user = new PrivyUser(_authDelegator, _embeddedWalletManager, _appConfigRepository, walletApiWalletCreator,
walletApiRepository);
walletApiRepository, authorizationKey);
}

internal async Task InitializeAsync()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,26 @@

namespace Privy.Wallets
{
internal struct WalletApiPayload
/// <summary>
/// Represents an API request payload to be signed for authorization.
/// The signature can be included as the <c>privy-authorization-signature</c> header.
/// </summary>
public struct WalletApiPayload
{
[JsonProperty("version")]
internal int Version;
public int Version;

[JsonProperty("url")]
internal string Url;
public string Url;

[JsonProperty("method")]
internal string Method;
public string Method;

[JsonProperty("headers")]
internal Dictionary<string, string> Headers;
public Dictionary<string, string> Headers;

[JsonProperty("body")]
internal object Body;
public object Body;

internal byte[] EncodePayload()
{
Expand Down
Loading
Loading