Skip to main content

TradeHub

WebSocket hub for peer-to-peer trading. All operations verify that the caller owns one of the characters in the trade.

Endpoint: /tradeHub

Authorization: All methods require authentication ([Authorize])

Methods

JoinTradeSession

Join a trade session group to receive real-time updates.

public async Task JoinTradeSession(Guid tradeId)

Adds the connection to the SignalR group trade-{tradeId}.


LeaveTradeSession

Leave a trade session group.

public async Task LeaveTradeSession(Guid tradeId)

StartTrade

Initiate a new trade session between your character and another character.

public async Task<TradeSession> StartTrade(
Guid myCharacterId,
Guid targetCharacterId,
string seasonId)

Parameters:

NameTypeDescription
myCharacterIdGuidYour character (must own)
targetCharacterIdGuidCharacter to trade with
seasonIdstringSeason for the trade

Returns: TradeSession

{
tradeId: string;
status: TradeStatus;
initiatorCharacterId: string;
targetCharacterId: string;
seasonId: string;
initiatorItems: string[]; // Item IDs
targetItems: string[];
initiatorAccepted: boolean;
targetAccepted: boolean;
expiresAt: string;
}

GetTrade

Get trade session details.

public async Task<TradeSession> GetTrade(Guid tradeId)

AddItem

Add an item to your side of the trade.

public async Task<TradeSession> AddItem(Guid tradeId, Guid itemId)

The character is automatically determined from the trade participants.


RemoveItem

Remove an item from your side of the trade.

public async Task<TradeSession> RemoveItem(Guid tradeId, Guid itemId)

AcceptTrade

Accept the current trade offer.

public async Task<AcceptTradeResult> AcceptTrade(Guid tradeId)

Returns: AcceptTradeResult

{
status: TradeStatus;
completed: boolean; // true when both parties accepted
}

When both parties accept, items are atomically swapped.


CancelTrade

Cancel the trade.

public async Task CancelTrade(Guid tradeId)

TradeStatus Enum

enum TradeStatus {
Pending = 0, // In progress
Completed = 1, // Successfully completed
Cancelled = 2, // Cancelled by a participant
Expired = 3 // Timed out
}

Trade Flow

Real-Time Events

Subscribe to the TradeUpdate event for real-time updates:

connection.on("TradeUpdate", (update) => {
console.log(`Trade ${update.tradeId}: ${update.eventType}`);
// Handle update
});

// Join the trade session
await connection.invoke("JoinTradeSession", tradeId);

Event Types:

EventDescription
TradeStartedNew trade initiated
ItemAddedItem added by a participant
ItemRemovedItem removed by a participant
TradeAcceptedParticipant accepted (waiting for other)
TradeCompletedTrade executed successfully
TradeCancelledTrade cancelled by a participant

Trade Rules

Trades are validated against rules:

RuleDescription
SameSeasonRuleBoth characters must be in the same season
SoloSelfFoundRuleSSF characters cannot trade

If a rule fails, the trade operation throws a HubException.

Security

  • Only trade participants can access trade operations
  • Character ownership is verified on every operation
  • Items are atomically swapped using Orleans transactions