diff --git a/Assets/Samples/Stream Video & Audio Chat SDK/0.9.0/Video & Audio Chat Example Project/Scripts/StreamVideoManager.cs b/Assets/Samples/Stream Video & Audio Chat SDK/0.9.0/Video & Audio Chat Example Project/Scripts/StreamVideoManager.cs
index 8cec7b3a..ce016658 100644
--- a/Assets/Samples/Stream Video & Audio Chat SDK/0.9.0/Video & Audio Chat Example Project/Scripts/StreamVideoManager.cs
+++ b/Assets/Samples/Stream Video & Audio Chat SDK/0.9.0/Video & Audio Chat Example Project/Scripts/StreamVideoManager.cs
@@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
-using System.Net.Http;
using System.Threading.Tasks;
using StreamVideo.Core;
using StreamVideo.Core.Configs;
using StreamVideo.Core.Exceptions;
using StreamVideo.Core.StatefulModels;
using StreamVideo.Core.StatefulModels.Tracks;
+using StreamVideo.Libs;
using StreamVideo.Libs.Auth;
-using StreamVideo.Libs.Serialization;
using StreamVideo.Libs.Utils;
using UnityEngine;
#if STREAM_DEBUG_ENABLED
@@ -244,24 +243,6 @@ protected void OnApplicationPause(bool pauseStatus)
}
#endif
- ///
- /// API success response template when using Stream's Demo Credentials
- ///
- private class DemoCredentialsApiResponse
- {
- public string UserId;
- public string Token;
- public string APIKey;
- }
-
- ///
- /// API error response template when using Stream's Demo Credentials
- ///
- private class DemoCredentialsApiError
- {
- public string Error;
- }
-
#pragma warning disable CS0414 //Disable warning that _info is unused. It's purpose is to display info box in the Unity Inspector only
[SerializeField]
@@ -281,6 +262,10 @@ private string _info
[SerializeField]
private string _userToken = "";
+ [Header("Demo Credentials")]
+ [SerializeField]
+ private StreamEnvironment _environment = StreamEnvironment.Demo;
+
[Header("Background Music in a call")]
[SerializeField]
private AudioClip _musicClip = null;
@@ -312,46 +297,16 @@ private async Task ConnectToStreamAsync(AuthCredentials credentials)
if (credentialsEmpty)
{
- // If custom credentials are not defined - use Stream's Demo Credentials
Debug.Log("Authorization credentials were not provided. Using Stream's Demo Credentials.");
- var demoCredentials = await GetStreamDemoTokenAsync();
- credentials = new AuthCredentials(demoCredentials.APIKey, demoCredentials.UserId,
- demoCredentials.Token);
+ var factory = new StreamDependenciesFactory();
+ var provider = factory.CreateDemoCredentialsProvider();
+ credentials = await provider.GetDemoCredentialsAsync("DemoUser", _environment);
}
await Client.ConnectUserAsync(credentials);
}
- ///
- /// This method will fetch Stream's demo credentials. These credentials are not usable in a real production due to limited rates.
- /// Customer accounts do have a FREE tier so please register at https://getstream.io/ to get your own app ID and credentials.
- ///
- private static async Task GetStreamDemoTokenAsync()
- {
- var serializer = new NewtonsoftJsonSerializer();
- var httpClient = new HttpClient();
- var uriBuilder = new UriBuilder
- {
- Host = "pronto.getstream.io",
- Path = "/api/auth/create-token",
- Query = $"user_id=DemoUser",
- Scheme = "https",
- };
-
- var uri = uriBuilder.Uri;
- var response = await httpClient.GetAsync(uri);
- var result = await response.Content.ReadAsStringAsync();
- if (!response.IsSuccessStatusCode)
- {
- var apiError = serializer.Deserialize(result);
- throw new Exception(
- $"Failed to get demo credentials. Error status code: `{response.StatusCode}`, Error message: `{apiError.Error}`");
- }
-
- return serializer.Deserialize(result);
- }
-
private void OnCallStarted(IStreamCall call)
{
_activeCall = call;
diff --git a/Packages/StreamVideo/Runtime/Libs/Auth/StreamDemoCredentialsProvider.cs b/Packages/StreamVideo/Runtime/Libs/Auth/StreamDemoCredentialsProvider.cs
new file mode 100644
index 00000000..7e15209c
--- /dev/null
+++ b/Packages/StreamVideo/Runtime/Libs/Auth/StreamDemoCredentialsProvider.cs
@@ -0,0 +1,98 @@
+using System;
+using System.Threading;
+using System.Threading.Tasks;
+using StreamVideo.Libs.Http;
+using StreamVideo.Libs.Serialization;
+
+namespace StreamVideo.Libs.Auth
+{
+ ///
+ /// Fetches demo/test credentials (API key + user token) from the Pronto endpoint.
+ /// DO NOT USE IN PRODUCTION. These credentials are rate-limited and meant only for internal testing and demo apps.
+ /// Customer accounts have a FREE tier for testing — please register at https://getstream.io/ to get your own app ID and credentials.
+ ///
+ public class StreamDemoCredentialsProvider
+ {
+ public StreamDemoCredentialsProvider(IHttpClient httpClient, ISerializer serializer)
+ {
+ _httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
+ _serializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
+ }
+
+ ///
+ /// Fetch demo credentials from https://pronto.getstream.io/api/auth/create-token.
+ /// The returned contains the API key, user ID, and signed token.
+ /// DO NOT USE IN PRODUCTION. Customer accounts have a FREE tier for testing —
+ /// please register at https://getstream.io/ to get your own app ID and credentials.
+ ///
+ public async Task GetDemoCredentialsAsync(
+ string userId,
+ StreamEnvironment environment = StreamEnvironment.Demo,
+ CancellationToken cancellationToken = default)
+ {
+ if (string.IsNullOrEmpty(userId))
+ {
+ throw new ArgumentException("User ID must not be null or empty.", nameof(userId));
+ }
+
+ var uri = new UriBuilder
+ {
+ Scheme = "https",
+ Host = Host,
+ Path = Path,
+ Query = $"user_id={Uri.EscapeDataString(userId)}&environment={ToQueryValue(environment)}",
+ }.Uri;
+
+ var response = await _httpClient.GetAsync(uri, cancellationToken);
+ if (!response.IsSuccessStatusCode)
+ {
+ string errorMessage = null;
+ try
+ {
+ var error = _serializer.Deserialize(response.Result);
+ errorMessage = error?.Error;
+ }
+ catch
+ {
+ // ignored — use raw response below
+ }
+
+ throw new Exception(
+ $"Failed to get demo credentials. Status code: {response.StatusCode}, " +
+ $"Error: {errorMessage ?? response.Result}");
+ }
+
+ var result = _serializer.Deserialize(response.Result);
+ return new AuthCredentials(result.ApiKey, result.UserId, result.Token);
+ }
+
+ private const string Host = "pronto.getstream.io";
+ private const string Path = "/api/auth/create-token";
+
+ private static string ToQueryValue(StreamEnvironment environment)
+ {
+ switch (environment)
+ {
+ case StreamEnvironment.Demo: return "demo";
+ case StreamEnvironment.Pronto: return "pronto";
+ default: throw new ArgumentOutOfRangeException(nameof(environment), environment,
+ $"Unsupported environment: {environment}");
+ }
+ }
+
+ private class CredentialsResponse
+ {
+ public string UserId;
+ public string ApiKey;
+ public string Token;
+ }
+
+ private class ErrorResponse
+ {
+ public string Error;
+ }
+
+ private readonly IHttpClient _httpClient;
+ private readonly ISerializer _serializer;
+ }
+}
diff --git a/Packages/StreamVideo/Runtime/Libs/Auth/StreamDemoCredentialsProvider.cs.meta b/Packages/StreamVideo/Runtime/Libs/Auth/StreamDemoCredentialsProvider.cs.meta
new file mode 100644
index 00000000..3b44088a
--- /dev/null
+++ b/Packages/StreamVideo/Runtime/Libs/Auth/StreamDemoCredentialsProvider.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: 917a3ed83d7d6aa4aa5399a3dbd41523
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/StreamVideo/Runtime/Libs/Auth/StreamEnvironment.cs b/Packages/StreamVideo/Runtime/Libs/Auth/StreamEnvironment.cs
new file mode 100644
index 00000000..03121531
--- /dev/null
+++ b/Packages/StreamVideo/Runtime/Libs/Auth/StreamEnvironment.cs
@@ -0,0 +1,11 @@
+namespace StreamVideo.Libs.Auth
+{
+ ///
+ /// Stream backend environment used when fetching demo credentials from Pronto.
+ ///
+ public enum StreamEnvironment
+ {
+ Demo,
+ Pronto,
+ }
+}
diff --git a/Packages/StreamVideo/Runtime/Libs/Auth/StreamEnvironment.cs.meta b/Packages/StreamVideo/Runtime/Libs/Auth/StreamEnvironment.cs.meta
new file mode 100644
index 00000000..cdb12e01
--- /dev/null
+++ b/Packages/StreamVideo/Runtime/Libs/Auth/StreamEnvironment.cs.meta
@@ -0,0 +1,11 @@
+fileFormatVersion: 2
+guid: dfe7d5c118486ee4db1147a3f818d80a
+MonoImporter:
+ externalObjects: {}
+ serializedVersion: 2
+ defaultReferences: []
+ executionOrder: 0
+ icon: {instanceID: 0}
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/Packages/StreamVideo/Runtime/Libs/StreamDependenciesFactory.cs b/Packages/StreamVideo/Runtime/Libs/StreamDependenciesFactory.cs
index 027926db..dea9b7b0 100644
--- a/Packages/StreamVideo/Runtime/Libs/StreamDependenciesFactory.cs
+++ b/Packages/StreamVideo/Runtime/Libs/StreamDependenciesFactory.cs
@@ -1,4 +1,4 @@
-using StreamVideo.Libs.AppInfo;
+using StreamVideo.Libs.AppInfo;
using StreamVideo.Libs.Auth;
using StreamVideo.Libs.VideoClientInstanceRunner;
using StreamVideo.Libs.Http;
@@ -48,6 +48,9 @@ public virtual IHttpClient CreateHttpClient()
public virtual ITokenProvider CreateTokenProvider(TokenProvider.TokenUriHandler urlFactory) => new TokenProvider(CreateHttpClient(), urlFactory);
+ public virtual StreamDemoCredentialsProvider CreateDemoCredentialsProvider()
+ => new StreamDemoCredentialsProvider(CreateHttpClient(), CreateSerializer());
+
public virtual IStreamVideoClientRunner CreateClientRunner()
{
var go = new GameObject
diff --git a/Packages/StreamVideo/Samples~/VideoChat/Scripts/StreamVideoManager.cs b/Packages/StreamVideo/Samples~/VideoChat/Scripts/StreamVideoManager.cs
index 8cec7b3a..ce016658 100644
--- a/Packages/StreamVideo/Samples~/VideoChat/Scripts/StreamVideoManager.cs
+++ b/Packages/StreamVideo/Samples~/VideoChat/Scripts/StreamVideoManager.cs
@@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
-using System.Net.Http;
using System.Threading.Tasks;
using StreamVideo.Core;
using StreamVideo.Core.Configs;
using StreamVideo.Core.Exceptions;
using StreamVideo.Core.StatefulModels;
using StreamVideo.Core.StatefulModels.Tracks;
+using StreamVideo.Libs;
using StreamVideo.Libs.Auth;
-using StreamVideo.Libs.Serialization;
using StreamVideo.Libs.Utils;
using UnityEngine;
#if STREAM_DEBUG_ENABLED
@@ -244,24 +243,6 @@ protected void OnApplicationPause(bool pauseStatus)
}
#endif
- ///
- /// API success response template when using Stream's Demo Credentials
- ///
- private class DemoCredentialsApiResponse
- {
- public string UserId;
- public string Token;
- public string APIKey;
- }
-
- ///
- /// API error response template when using Stream's Demo Credentials
- ///
- private class DemoCredentialsApiError
- {
- public string Error;
- }
-
#pragma warning disable CS0414 //Disable warning that _info is unused. It's purpose is to display info box in the Unity Inspector only
[SerializeField]
@@ -281,6 +262,10 @@ private string _info
[SerializeField]
private string _userToken = "";
+ [Header("Demo Credentials")]
+ [SerializeField]
+ private StreamEnvironment _environment = StreamEnvironment.Demo;
+
[Header("Background Music in a call")]
[SerializeField]
private AudioClip _musicClip = null;
@@ -312,46 +297,16 @@ private async Task ConnectToStreamAsync(AuthCredentials credentials)
if (credentialsEmpty)
{
- // If custom credentials are not defined - use Stream's Demo Credentials
Debug.Log("Authorization credentials were not provided. Using Stream's Demo Credentials.");
- var demoCredentials = await GetStreamDemoTokenAsync();
- credentials = new AuthCredentials(demoCredentials.APIKey, demoCredentials.UserId,
- demoCredentials.Token);
+ var factory = new StreamDependenciesFactory();
+ var provider = factory.CreateDemoCredentialsProvider();
+ credentials = await provider.GetDemoCredentialsAsync("DemoUser", _environment);
}
await Client.ConnectUserAsync(credentials);
}
- ///
- /// This method will fetch Stream's demo credentials. These credentials are not usable in a real production due to limited rates.
- /// Customer accounts do have a FREE tier so please register at https://getstream.io/ to get your own app ID and credentials.
- ///
- private static async Task GetStreamDemoTokenAsync()
- {
- var serializer = new NewtonsoftJsonSerializer();
- var httpClient = new HttpClient();
- var uriBuilder = new UriBuilder
- {
- Host = "pronto.getstream.io",
- Path = "/api/auth/create-token",
- Query = $"user_id=DemoUser",
- Scheme = "https",
- };
-
- var uri = uriBuilder.Uri;
- var response = await httpClient.GetAsync(uri);
- var result = await response.Content.ReadAsStringAsync();
- if (!response.IsSuccessStatusCode)
- {
- var apiError = serializer.Deserialize(result);
- throw new Exception(
- $"Failed to get demo credentials. Error status code: `{response.StatusCode}`, Error message: `{apiError.Error}`");
- }
-
- return serializer.Deserialize(result);
- }
-
private void OnCallStarted(IStreamCall call)
{
_activeCall = call;
diff --git a/Packages/StreamVideo/Tests/Shared/TestClient.cs b/Packages/StreamVideo/Tests/Shared/TestClient.cs
index 9816146d..7613cf58 100644
--- a/Packages/StreamVideo/Tests/Shared/TestClient.cs
+++ b/Packages/StreamVideo/Tests/Shared/TestClient.cs
@@ -1,12 +1,11 @@
-#if STREAM_TESTS_ENABLED
+#if STREAM_TESTS_ENABLED
using System;
using System.Diagnostics;
-using System.Net.Http;
using System.Threading.Tasks;
using StreamVideo.Core;
using StreamVideo.Core.StatefulModels;
+using StreamVideo.Libs;
using StreamVideo.Libs.Auth;
-using StreamVideo.Libs.Serialization;
using UnityEngine;
using Debug = UnityEngine.Debug;
@@ -52,7 +51,10 @@ public async Task ConnectAsync()
var timer = new Stopwatch();
timer.Start();
- var getCredentialsTask = GetStreamDemoCredentialsAsync();
+ var factory = new StreamDependenciesFactory();
+ var provider = factory.CreateDemoCredentialsProvider();
+
+ var getCredentialsTask = provider.GetDemoCredentialsAsync("DemoUser", StreamEnvironment.Demo);
while (!getCredentialsTask.IsCompleted)
{
await Task.Delay(1);
@@ -64,9 +66,7 @@ public async Task ConnectAsync()
}
}
- var demoCredentials = getCredentialsTask.Result;
- var credentials
- = new AuthCredentials(demoCredentials.APIKey, demoCredentials.UserId, demoCredentials.Token);
+ var credentials = getCredentialsTask.Result;
var connectTask = Client.ConnectUserAsync(credentials);
@@ -89,45 +89,6 @@ var credentials
Debug.Log($"Client connected in {timer.Elapsed.TotalSeconds:F2} seconds");
}
- private class DemoCredentialsApiResponse
- {
- public string UserId;
- public string Token;
- public string APIKey;
- }
-
- private class DemoCredentialsApiError
- {
- public string Error;
- }
-
- private static async Task GetStreamDemoCredentialsAsync()
- {
- Debug.Log("Get demo credentials " + Time.time);
- var serializer = new NewtonsoftJsonSerializer();
- var httpClient = new HttpClient();
- var uriBuilder = new UriBuilder
- {
- Host = "pronto.getstream.io",
- Path = "/api/auth/create-token",
- Query = $"user_id=DemoUser",
- Scheme = "https",
- };
-
- var uri = uriBuilder.Uri;
- var response = await httpClient.GetAsync(uri);
- var result = await response.Content.ReadAsStringAsync();
- if (!response.IsSuccessStatusCode)
- {
- var apiError = serializer.Deserialize(result);
- throw new Exception(
- $"Failed to get demo credentials. Error status code: `{response.StatusCode}`, Error message: `{apiError.Error}`");
- }
-
- Debug.Log("Demo credentials received: " + Time.time);
-
- return serializer.Deserialize(result);
- }
}
}
#endif
\ No newline at end of file