FrontierSharp.SuiClient provides access to EVE Frontier data exposed through Sui GraphQL, including:
- killmails
- characters
- assemblies
- polling-based assembly update subscriptions
The assembly watcher API is designed for the common flow of loading a snapshot with GetAllAssembliesAsync() and then
subscribing to incremental changes.
dotnet add package FrontierSharp.SuiClient
dotnet add package ZiggyCreatures.FusionCachevar services = new ServiceCollection();
const string HTTP_CLIENT_NAME = "SuiGraphQl";
services.AddLogging();
services.AddHttpClient(HTTP_CLIENT_NAME);
services.AddFusionCache().AsHybridCache();
services.Configure<SuiClientOptions>(options => {
options.HttpClientName = HTTP_CLIENT_NAME;
options.WithNetwork(SuiNetwork.Testnet);
options.WithDefaultWorldPackageAddress("0x28b497559d65ab320d9da4613bf2498d5946b2c0ae3597ccfda3072ce127448c");
});
services.AddSingleton<ISuiGraphQlClient, SuiGraphQlClient>();
services.AddSingleton<IWorldClient, WorldClient>();
var serviceProvider = services.BuildServiceProvider();
var client = serviceProvider.GetRequiredService<IWorldClient>();
var initialAssembliesResult = await client.GetAllAssembliesAsync(first: 50);
if (initialAssembliesResult.IsFailed) {
foreach (var error in initialAssembliesResult.Errors) {
Console.WriteLine($"Failed to load assemblies: {error.Message}");
}
return;
}
Console.WriteLine($"Loaded {initialAssembliesResult.Value.Count()} Assemblies from initial batch");
var subscriptionResult = await client.SubscribeToAssemblyUpdatesAsync(
initialAssembliesResult.Value,
async (batch, cancellationToken) => {
foreach (var change in batch.Changes) {
var assembly = change.Current ?? change.Previous;
Console.WriteLine($"{change.ChangeType}: {assembly!.Key.Tenant}/{assembly.Key.ItemId}");
}
await Task.CompletedTask;
},
new AssemblySubscriptionOptions {
PollInterval = TimeSpan.FromSeconds(5),
PageSize = 50
});
if (subscriptionResult.IsFailed) {
foreach (var error in subscriptionResult.Errors) {
Console.WriteLine($"Failed to start subscription: {error.Message}");
}
return;
}
using var subscription = subscriptionResult.Value;
await Task.Delay(-1);
subscription.Dispose();
await subscription.Completion;To query a different world package without creating another client, pass worldPackageAddress on the call:
var result = await client.GetAllAssembliesAsync(
first: 100,
worldPackageAddress: "0xanotherworldpackage");Each callback receives an AssemblyUpdateBatch:
IsInitialSnapshotistrueonly whenEmitInitialSnapshotis enabled and the watcher is sending the baseline load.CurrentAssembliescontains the latest full snapshot known to the watcher.Changescontains only the delta for that poll cycle.
Each AssemblyChange contains:
ChangeType—Added,Updated, orRemovedPrevious— the prior assembly state for updates and removalsCurrent— the new assembly state for additions and updatesKey— a shortcut to the assembly'sTenantItemId
- The watcher polls on a timer; it is not a websocket subscription.
- Polling queries bypass the GraphQL cache so updates are not delayed by
GraphQlCacheDuration. - Dispose the returned
IAssemblyUpdateSubscriptionto stop polling, then awaitCompletionfor shutdown.
- Compiled example project: examples/AssemblyWatcherExample/Program.cs
- Script-style sample: examples/assembly-watcher.cs