1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
use crate::types::{
AssignRecipientParams, CloseGameAccountParams, CreateGameAccountParams,
CreatePlayerProfileParams, CreateRecipientParams, CreateRegistrationParams, DepositParams,
GameAccount, GameBundle, JoinParams, PlayerProfile, PublishGameParams, QueryMode,
RecipientAccount, RecipientClaimParams, RegisterGameParams, RegisterServerParams,
RegistrationAccount, ServeParams, ServerAccount, SettleParams, UnregisterGameParams,
VoteParams,
};
use async_trait::async_trait;
use race_api::error::Result;
#[async_trait]
pub trait TransportT: Send + Sync {
/// Create an on-chain game account which represents a game room
/// and holds basic game properties. Check [`GameAccount`] for
/// description of the layout. The implementation should contain
/// the check for transaction signature, make sure that Ok is
/// returned only when the transaction succeeds and finalized.
///
/// # Arguments
/// * `max_players` - The maximum number of players in this game. Please note,
/// not all games require a full room to start.
/// * `bundle_addr` - The address of game bundle NFT.
/// * `data` - The borsh serialization of game specific data. The layout should be
/// game independent. It is used to describe the basic game properties,
/// and is considered to be immutable.
///
/// # Returns
/// * [`Error::InvalidMaxPlayers`] when invalid `max_players` is provided.
/// * [`Error::GameBundleNotFound`] when invalid `bundle_addr` is provided.
/// * [`Error::RpcError`] when the RPC invocation failed.
async fn create_game_account(&self, params: CreateGameAccountParams) -> Result<String>;
/// Close the game account. A game can be closed when it's empty
/// (no players). To close the game, the signer must be the owner
/// of the account.
///
/// # Arguments
/// * `addr` - The address of game to be closed.
///
/// # Returns
/// * [`Error::GameAccountNotFound`] when invalid `addr` is provided.
/// * [`Error::RpcError`] when the RPC invocation failed.
async fn close_game_account(&self, params: CloseGameAccountParams) -> Result<()>;
/// Create an on-chain account for server which can serve game
/// accounts. Check [`ServerAccount`] for the description of the
/// layout. The owner is limited to have only one server.
///
/// # Arguments
/// * `owner_addr` - The account of the server owner, should be the same to the signer.
/// * `endpoint` - The accessible endpoint to public. The format shouldn't contain the protocol.
/// e.g. 127.0.0.1:8000, example.org
///
/// # Returns
/// * [`Error::ServerAccountExists`] when the account has been created already.
/// * [`Error::MalformedEndpoint`] when the `endpoint` is invalid.
/// * [`Error::RpcError`] when the RPC invocation failed.
async fn register_server(&self, params: RegisterServerParams) -> Result<()>;
/// Join the game.
///
/// # Arguments
/// * `player_addr` - The address of player, should the same with signer.
/// * `game_addr` - The game to join.
/// * `amount` - The amount of token to bring to the game.
/// * `access_version` - The current access version.
/// * `position` - The position to be at in the game, should be an index,
/// must be less than the `max_players` of the game account.
///
/// # Returns
/// * [`Error::GameAccountNotFound`] when invalid `game_addr` is provided.
/// * [`Error::RpcError`] when the RPC invocation failed.
async fn join(&self, params: JoinParams) -> Result<()>;
/// Deposit tokens into game.
///
/// # Arguments
/// * `player_addr` - The address of player, should be the same with signer.
/// * `game_addr` - The game to deposit.
/// * `amount` - The amount of token to deposit.
/// * `access_version` - The current access version.
async fn deposit(&self, params: DepositParams) -> Result<()>;
/// Serve a game. To serve a game, server will write its address into game account.
///
/// # Arguments
/// * `game_addr` - The address of game to serve.
/// * `server_addr` - The address of server, should be the same with signer.
///
/// # Returns
/// * [`Error::RpcError`] when the RPC invocation failed.
async fn serve(&self, params: ServeParams) -> Result<()>;
/// Send a vote to game account. For example, vote for a server disconnecting.
///
/// # Arguments:
/// * `vote_type` - The type of vote, currently only `ServerDropOff` and `ServerIsOnline` are supported.
/// * `sender_addr` - The sender of the vote, must be the same with signer.
/// * `receiver_addr` - The receiver of the vote. Generally, it should be the server address.
async fn vote(&self, params: VoteParams) -> Result<()>;
/// Create a player profile on chain. A profile is required to join any games.
/// The player profile address is derived from the player wallet address.
///
/// # Arguments
/// * `addr` - The address of the wallet, should be the same with signer.
/// * `nick` - The display name in the game, can't be empty.
/// * `pfp` - The address of the NFT token to be used. `None` means using default pfp.
///
/// # Returns
/// * [`Error::PlayerProfileAccountNotFound`] when invalid `addr` is provided.
/// * [`Error::RpcError`] when the RPC invocation failed.
async fn create_player_profile(&self, params: CreatePlayerProfileParams) -> Result<()>;
/// Create a recipient account on chain. A recipient account is a
/// intermediate account to handle a multi-destination payment.
/// When receiving the payment, the assets are stored in
/// different slots respectively. And later the real recipients can claim
/// their assets based on their shares.
///
/// # Arguments
/// * `addr` - The address of the wallet, should be the same with signer.
/// * `slots` - The initial slots for recipient account.
/// * `cap_addrs` - The addresses with the capibility to approve others' applications.
async fn create_recipient(&self, params: CreateRecipientParams) -> Result<String>;
/// Claim tokens from recipient account.
async fn recipient_claim(&self, params: RecipientClaimParams) -> Result<()>;
/// Grant an address with a share to a recipient slot.
async fn assign_recipient(&self, params: AssignRecipientParams) -> Result<()>;
async fn publish_game(&self, params: PublishGameParams) -> Result<String>;
async fn settle_game(&self, params: SettleParams) -> Result<()>;
async fn create_registration(&self, params: CreateRegistrationParams) -> Result<String>;
async fn register_game(&self, params: RegisterGameParams) -> Result<()>;
async fn unregister_game(&self, params: UnregisterGameParams) -> Result<()>;
/// Get game account by its address.
async fn get_game_account(&self, addr: &str, mode: QueryMode) -> Result<Option<GameAccount>>;
/// Get game bundle account by its address.
async fn get_game_bundle(&self, addr: &str) -> Result<Option<GameBundle>>;
/// Get player profile account by its address.
async fn get_player_profile(&self, addr: &str) -> Result<Option<PlayerProfile>>;
/// Get server account by its address.
async fn get_server_account(&self, addr: &str) -> Result<Option<ServerAccount>>;
/// Get registration account by its address.
async fn get_registration(&self, addr: &str) -> Result<Option<RegistrationAccount>>;
/// Get recipient account by its address.
async fn get_recipient(&self, addr: &str) -> Result<Option<RecipientAccount>>;
}