@1upmonster/duel 0.1.8 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +110 -59
  2. package/dist/admin.d.ts +25 -40
  3. package/dist/admin.js +93 -114
  4. package/dist/encryption.js +1 -2
  5. package/dist/generated/duel/accounts/index.d.ts +10 -0
  6. package/dist/generated/duel/accounts/index.js +11 -0
  7. package/dist/generated/duel/accounts/matchTicket.d.ts +38 -0
  8. package/dist/generated/duel/accounts/matchTicket.js +45 -0
  9. package/dist/generated/duel/accounts/queue.d.ts +42 -0
  10. package/dist/generated/duel/accounts/queue.js +45 -0
  11. package/dist/generated/duel/accounts/tenant.d.ts +41 -0
  12. package/dist/generated/duel/accounts/tenant.js +44 -0
  13. package/dist/generated/duel/errors/duel.d.ts +31 -0
  14. package/dist/generated/duel/errors/duel.js +35 -0
  15. package/dist/generated/duel/errors/index.d.ts +8 -0
  16. package/dist/generated/duel/errors/index.js +9 -0
  17. package/dist/generated/duel/index.d.ts +12 -0
  18. package/dist/generated/duel/index.js +13 -0
  19. package/dist/generated/duel/instructions/cancelTicket.d.ts +45 -0
  20. package/dist/generated/duel/instructions/cancelTicket.js +56 -0
  21. package/dist/generated/duel/instructions/closeTicket.d.ts +45 -0
  22. package/dist/generated/duel/instructions/closeTicket.js +56 -0
  23. package/dist/generated/duel/instructions/commitTickets.d.ts +39 -0
  24. package/dist/generated/duel/instructions/commitTickets.js +50 -0
  25. package/dist/generated/duel/instructions/createTicket.d.ts +48 -0
  26. package/dist/generated/duel/instructions/createTicket.js +63 -0
  27. package/dist/generated/duel/instructions/delegateQueue.d.ts +69 -0
  28. package/dist/generated/duel/instructions/delegateQueue.js +90 -0
  29. package/dist/generated/duel/instructions/delegateTicket.d.ts +69 -0
  30. package/dist/generated/duel/instructions/delegateTicket.js +90 -0
  31. package/dist/generated/duel/instructions/flushMatches.d.ts +37 -0
  32. package/dist/generated/duel/instructions/flushMatches.js +43 -0
  33. package/dist/generated/duel/instructions/index.d.ts +19 -0
  34. package/dist/generated/duel/instructions/index.js +20 -0
  35. package/dist/generated/duel/instructions/initializeQueue.d.ts +48 -0
  36. package/dist/generated/duel/instructions/initializeQueue.js +63 -0
  37. package/dist/generated/duel/instructions/initializeTenant.d.ts +70 -0
  38. package/dist/generated/duel/instructions/initializeTenant.js +67 -0
  39. package/dist/generated/duel/instructions/joinQueue.d.ts +51 -0
  40. package/dist/generated/duel/instructions/joinQueue.js +56 -0
  41. package/dist/generated/duel/instructions/processUndelegation.d.ts +43 -0
  42. package/dist/generated/duel/instructions/processUndelegation.js +49 -0
  43. package/dist/generated/duel/instructions/setupTicketPermission.d.ts +54 -0
  44. package/dist/generated/duel/instructions/setupTicketPermission.js +63 -0
  45. package/dist/generated/duel/programs/duel.d.ts +92 -0
  46. package/dist/generated/duel/programs/duel.js +146 -0
  47. package/dist/generated/duel/programs/index.d.ts +8 -0
  48. package/dist/generated/duel/programs/index.js +9 -0
  49. package/dist/generated/duel/types/accountType.d.ts +25 -0
  50. package/dist/generated/duel/types/accountType.js +25 -0
  51. package/dist/generated/duel/types/index.d.ts +13 -0
  52. package/dist/generated/duel/types/index.js +14 -0
  53. package/dist/generated/duel/types/matchEntry.d.ts +23 -0
  54. package/dist/generated/duel/types/matchEntry.js +18 -0
  55. package/dist/generated/duel/types/matchFound.d.ts +23 -0
  56. package/dist/generated/duel/types/matchFound.js +18 -0
  57. package/dist/generated/duel/types/pendingMatch.d.ts +21 -0
  58. package/dist/generated/duel/types/pendingMatch.js +18 -0
  59. package/dist/generated/duel/types/queueEntry.d.ts +19 -0
  60. package/dist/generated/duel/types/queueEntry.js +18 -0
  61. package/dist/generated/duel/types/ticketStatus.d.ts +40 -0
  62. package/dist/generated/duel/types/ticketStatus.js +25 -0
  63. package/dist/generated/rps-game/accounts/gameSession.d.ts +40 -0
  64. package/dist/generated/rps-game/accounts/gameSession.js +45 -0
  65. package/dist/generated/rps-game/accounts/index.d.ts +9 -0
  66. package/dist/generated/rps-game/accounts/index.js +10 -0
  67. package/dist/generated/rps-game/accounts/playerProfile.d.ts +36 -0
  68. package/dist/generated/rps-game/accounts/playerProfile.js +47 -0
  69. package/dist/generated/rps-game/errors/index.d.ts +8 -0
  70. package/dist/generated/rps-game/errors/index.js +9 -0
  71. package/dist/generated/rps-game/errors/rpsGame.d.ts +25 -0
  72. package/dist/generated/rps-game/errors/rpsGame.js +29 -0
  73. package/dist/generated/rps-game/index.d.ts +12 -0
  74. package/dist/generated/rps-game/index.js +13 -0
  75. package/dist/generated/rps-game/instructions/closePlayer.d.ts +45 -0
  76. package/dist/generated/rps-game/instructions/closePlayer.js +56 -0
  77. package/dist/generated/rps-game/instructions/delegatePda.d.ts +69 -0
  78. package/dist/generated/rps-game/instructions/delegatePda.js +90 -0
  79. package/dist/generated/rps-game/instructions/index.d.ts +16 -0
  80. package/dist/generated/rps-game/instructions/index.js +17 -0
  81. package/dist/generated/rps-game/instructions/initializePlayer.d.ts +48 -0
  82. package/dist/generated/rps-game/instructions/initializePlayer.js +63 -0
  83. package/dist/generated/rps-game/instructions/makeChoice.d.ts +44 -0
  84. package/dist/generated/rps-game/instructions/makeChoice.js +46 -0
  85. package/dist/generated/rps-game/instructions/onMatchFound.d.ts +43 -0
  86. package/dist/generated/rps-game/instructions/onMatchFound.js +45 -0
  87. package/dist/generated/rps-game/instructions/persistResults.d.ts +43 -0
  88. package/dist/generated/rps-game/instructions/persistResults.js +50 -0
  89. package/dist/generated/rps-game/instructions/processUndelegation.d.ts +43 -0
  90. package/dist/generated/rps-game/instructions/processUndelegation.js +49 -0
  91. package/dist/generated/rps-game/instructions/startGame.d.ts +54 -0
  92. package/dist/generated/rps-game/instructions/startGame.js +67 -0
  93. package/dist/generated/rps-game/instructions/startGameWithTicket.d.ts +57 -0
  94. package/dist/generated/rps-game/instructions/startGameWithTicket.js +67 -0
  95. package/dist/generated/rps-game/programs/index.d.ts +8 -0
  96. package/dist/generated/rps-game/programs/index.js +9 -0
  97. package/dist/generated/rps-game/programs/rpsGame.d.ts +78 -0
  98. package/dist/generated/rps-game/programs/rpsGame.js +118 -0
  99. package/dist/generated/rps-game/types/accountType.d.ts +34 -0
  100. package/dist/generated/rps-game/types/accountType.js +25 -0
  101. package/dist/generated/rps-game/types/choice.d.ts +17 -0
  102. package/dist/generated/rps-game/types/choice.js +25 -0
  103. package/dist/generated/rps-game/types/gameResult.d.ts +26 -0
  104. package/dist/generated/rps-game/types/gameResult.js +25 -0
  105. package/dist/generated/rps-game/types/index.d.ts +10 -0
  106. package/dist/generated/rps-game/types/index.js +11 -0
  107. package/dist/index.d.ts +2 -1
  108. package/dist/index.js +3 -2
  109. package/dist/player.d.ts +25 -46
  110. package/dist/player.js +81 -140
  111. package/dist/tee.d.ts +14 -0
  112. package/dist/tee.js +62 -0
  113. package/dist/transaction.d.ts +11 -0
  114. package/dist/transaction.js +50 -0
  115. package/dist/utils.d.ts +4 -4
  116. package/dist/utils.js +23 -8
  117. package/package.json +3 -6
  118. package/src/admin.ts +151 -161
  119. package/src/duel.json +66 -7
  120. package/src/encryption.ts +0 -3
  121. package/src/generated/duel/accounts/index.ts +11 -0
  122. package/src/generated/duel/accounts/matchTicket.ts +77 -0
  123. package/src/generated/duel/accounts/queue.ts +77 -0
  124. package/src/generated/duel/accounts/tenant.ts +76 -0
  125. package/src/generated/duel/errors/duel.ts +46 -0
  126. package/src/generated/duel/errors/index.ts +9 -0
  127. package/src/generated/duel/index.ts +13 -0
  128. package/src/generated/duel/instructions/cancelTicket.ts +100 -0
  129. package/src/generated/duel/instructions/closeTicket.ts +100 -0
  130. package/src/generated/duel/instructions/commitTickets.ts +84 -0
  131. package/src/generated/duel/instructions/createTicket.ts +109 -0
  132. package/src/generated/duel/instructions/delegateQueue.ts +157 -0
  133. package/src/generated/duel/instructions/delegateTicket.ts +157 -0
  134. package/src/generated/duel/instructions/flushMatches.ts +76 -0
  135. package/src/generated/duel/instructions/index.ts +20 -0
  136. package/src/generated/duel/instructions/initializeQueue.ts +109 -0
  137. package/src/generated/duel/instructions/initializeTenant.ts +126 -0
  138. package/src/generated/duel/instructions/joinQueue.ts +106 -0
  139. package/src/generated/duel/instructions/processUndelegation.ts +86 -0
  140. package/src/generated/duel/instructions/setupTicketPermission.ts +115 -0
  141. package/src/generated/duel/programs/duel.ts +108 -0
  142. package/src/generated/duel/programs/index.ts +9 -0
  143. package/src/generated/duel/types/accountType.ts +36 -0
  144. package/src/generated/duel/types/index.ts +14 -0
  145. package/src/generated/duel/types/matchEntry.ts +25 -0
  146. package/src/generated/duel/types/matchFound.ts +25 -0
  147. package/src/generated/duel/types/pendingMatch.ts +25 -0
  148. package/src/generated/duel/types/queueEntry.ts +25 -0
  149. package/src/generated/duel/types/ticketStatus.ts +38 -0
  150. package/src/generated/rps-game/accounts/gameSession.ts +77 -0
  151. package/src/generated/rps-game/accounts/index.ts +10 -0
  152. package/src/generated/rps-game/accounts/playerProfile.ts +80 -0
  153. package/src/generated/rps-game/errors/index.ts +9 -0
  154. package/src/generated/rps-game/errors/rpsGame.ts +40 -0
  155. package/src/generated/rps-game/index.ts +13 -0
  156. package/src/generated/rps-game/instructions/closePlayer.ts +100 -0
  157. package/src/generated/rps-game/instructions/delegatePda.ts +157 -0
  158. package/src/generated/rps-game/instructions/index.ts +17 -0
  159. package/src/generated/rps-game/instructions/initializePlayer.ts +109 -0
  160. package/src/generated/rps-game/instructions/makeChoice.ts +84 -0
  161. package/src/generated/rps-game/instructions/onMatchFound.ts +79 -0
  162. package/src/generated/rps-game/instructions/persistResults.ts +88 -0
  163. package/src/generated/rps-game/instructions/processUndelegation.ts +86 -0
  164. package/src/generated/rps-game/instructions/startGame.ts +118 -0
  165. package/src/generated/rps-game/instructions/startGameWithTicket.ts +121 -0
  166. package/src/generated/rps-game/programs/index.ts +9 -0
  167. package/src/generated/rps-game/programs/rpsGame.ts +95 -0
  168. package/src/generated/rps-game/types/accountType.ts +36 -0
  169. package/src/generated/rps-game/types/choice.ts +25 -0
  170. package/src/generated/rps-game/types/gameResult.ts +37 -0
  171. package/src/generated/rps-game/types/index.ts +11 -0
  172. package/src/index.ts +2 -1
  173. package/src/player.ts +129 -192
  174. package/src/{idl/private_matchmaking.json → rps_game.json} +547 -583
  175. package/src/tee.ts +79 -0
  176. package/src/transaction.ts +90 -0
  177. package/src/utils.ts +35 -20
  178. package/tsconfig.json +2 -2
  179. package/dist/client.d.ts +0 -54
  180. package/dist/client.js +0 -265
  181. package/dist/duel.json +0 -1207
  182. package/dist/private_matchmaking.json +0 -534
  183. package/dist/types.d.ts +0 -635
  184. package/dist/types.js +0 -2
  185. package/src/idl/private_matchmaking.ts +0 -1033
  186. package/src/types.ts +0 -300
@@ -0,0 +1,37 @@
1
+ /**
2
+ * This code was AUTOGENERATED using the Codama library.
3
+ * Please DO NOT EDIT THIS FILE, instead use visitors
4
+ * to add features, then rerun Codama to update it.
5
+ *
6
+ * @see https://github.com/codama-idl/codama
7
+ */
8
+
9
+ import { combineCodec, getAddressDecoder, getAddressEncoder, getDiscriminatedUnionDecoder, getDiscriminatedUnionEncoder, getStructDecoder, getStructEncoder, getTupleDecoder, getTupleEncoder, getUnitDecoder, getUnitEncoder, type Address, type Codec, type Decoder, type Encoder, type GetDiscriminatedUnionVariant, type GetDiscriminatedUnionVariantContent } from '@solana/kit';
10
+
11
+ export type GameResult = { __kind: "Winner", fields: readonly [Address]; } | { __kind: "Tie" } | { __kind: "None" };
12
+
13
+ export type GameResultArgs = GameResult;
14
+
15
+ export function getGameResultEncoder(): Encoder<GameResultArgs> {
16
+ return getDiscriminatedUnionEncoder([['Winner', getStructEncoder([['fields', getTupleEncoder([getAddressEncoder()])]])], ['Tie', getUnitEncoder()], ['None', getUnitEncoder()]]);
17
+ }
18
+
19
+ export function getGameResultDecoder(): Decoder<GameResult> {
20
+ return getDiscriminatedUnionDecoder([['Winner', getStructDecoder([['fields', getTupleDecoder([getAddressDecoder()])]])], ['Tie', getUnitDecoder()], ['None', getUnitDecoder()]]);
21
+ }
22
+
23
+ export function getGameResultCodec(): Codec<GameResultArgs, GameResult> {
24
+ return combineCodec(getGameResultEncoder(), getGameResultDecoder());
25
+ }
26
+
27
+ // Data Enum Helpers.
28
+ export function gameResult(kind: 'Winner', data: GetDiscriminatedUnionVariantContent<GameResultArgs, '__kind', 'Winner'>['fields']): GetDiscriminatedUnionVariant<GameResultArgs, '__kind', 'Winner'>;
29
+ export function gameResult(kind: 'Tie'): GetDiscriminatedUnionVariant<GameResultArgs, '__kind', 'Tie'>;
30
+ export function gameResult(kind: 'None'): GetDiscriminatedUnionVariant<GameResultArgs, '__kind', 'None'>;
31
+ export function gameResult<K extends GameResultArgs['__kind'], Data>(kind: K, data?: Data) {
32
+ return Array.isArray(data) ? { __kind: kind, fields: data } : { __kind: kind, ...(data ?? {}) };
33
+ }
34
+
35
+ export function isGameResult<K extends GameResult['__kind']>(kind: K, value: GameResult): value is GameResult & { __kind: K } {
36
+ return value.__kind === kind;
37
+ };
@@ -0,0 +1,11 @@
1
+ /**
2
+ * This code was AUTOGENERATED using the Codama library.
3
+ * Please DO NOT EDIT THIS FILE, instead use visitors
4
+ * to add features, then rerun Codama to update it.
5
+ *
6
+ * @see https://github.com/codama-idl/codama
7
+ */
8
+
9
+ export * from './accountType';
10
+ export * from './choice';
11
+ export * from './gameResult';
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export * from "./admin.js";
2
2
  export * from "./player.js";
3
- export * from "./types.js";
3
+ export * from "./tee.js";
4
4
  export * as utils from "./utils.js";
5
+ export { fetchMaybeTenant, fetchTenant, fetchMaybeQueue, fetchQueue } from "./generated/duel/index.js";
package/src/player.ts CHANGED
@@ -1,225 +1,162 @@
1
- import * as anchor from "@coral-xyz/anchor";
2
- import * as web3 from "@solana/web3.js";
3
- import type { Duel } from "./types.js";
4
- import IDL from "./duel.json" with { type: "json" };
1
+ import {
2
+ createSolanaRpc,
3
+ type Address,
4
+ type TransactionSigner,
5
+ type Rpc,
6
+ type SolanaRpcApi,
7
+ } from "@solana/kit";
8
+ import {
9
+ getCreateTicketInstructionAsync,
10
+ getDelegateTicketInstructionAsync,
11
+ getJoinQueueInstructionAsync,
12
+ getCancelTicketInstructionAsync,
13
+ getCloseTicketInstructionAsync,
14
+ fetchMaybeMatchTicket,
15
+ accountType,
16
+ } from "./generated/duel/index.js";
17
+ import { sendInstruction } from "./transaction.js";
18
+ import { waitUntilPermissionActive } from "./tee.js";
5
19
  import * as utils from "./utils.js";
6
20
 
21
+ const DUEL_PROGRAM_ID = "EdZzUwKd1X2ZWjxLPpz1cpEzMF7RUZC43Pq64v1VcK5X" as Address;
22
+
7
23
  export class MatchmakingPlayer {
8
- public program: anchor.Program<Duel>;
9
- public provider: anchor.AnchorProvider;
10
-
11
- constructor(provider: anchor.AnchorProvider, programId: web3.PublicKey | string) {
12
- const address = typeof programId === "string" ? programId : programId.toBase58();
13
- const idl = { ...IDL, address };
14
- this.program = new anchor.Program(idl as any, provider);
15
- this.provider = provider;
24
+ public rpc: Rpc<SolanaRpcApi>;
25
+ public signer: TransactionSigner;
26
+ public programId: Address;
27
+
28
+ constructor(
29
+ rpc: Rpc<SolanaRpcApi>,
30
+ signer: TransactionSigner,
31
+ programId: Address = DUEL_PROGRAM_ID,
32
+ ) {
33
+ this.rpc = rpc;
34
+ this.signer = signer;
35
+ this.programId = programId;
16
36
  }
17
37
 
18
- /**
19
- * Derive MatchTicket PDA
20
- */
21
- getTicketPda(player: web3.PublicKey, tenant: web3.PublicKey): web3.PublicKey {
22
- return utils.deriveTicketPda(this.program.programId, player, tenant);
38
+ async getTicketPda(player: Address, tenant: Address): Promise<Address> {
39
+ return utils.deriveTicketPda(this.programId, player, tenant);
23
40
  }
24
41
 
25
- /**
26
- * Fetch MatchTicket account data
27
- */
28
- async getTicket(ticketPda: web3.PublicKey): Promise<any> {
29
- return await this.program.account.matchTicket.fetch(ticketPda);
42
+ async getTicket(ticketPda: Address) {
43
+ return fetchMaybeMatchTicket(this.rpc, ticketPda);
30
44
  }
31
45
 
32
- /**
33
- * Create MatchTicket PDA on L1
34
- */
35
- async createTicket(
36
- tenant: web3.PublicKey,
37
- confirmOptions?: web3.ConfirmOptions,
38
- signers: web3.Keypair[] = []
39
- ): Promise<web3.TransactionSignature> {
40
- const ticketPda = this.getTicketPda(this.provider.publicKey, tenant);
41
- return await this.program.methods
42
- .createTicket()
43
- .accountsPartial({
44
- ticket: ticketPda,
45
- tenant: tenant,
46
- player: this.provider.publicKey,
47
- })
48
- .signers(signers)
49
- .rpc(confirmOptions);
46
+ async createTicket(tenant: Address): Promise<string> {
47
+ const ix = await getCreateTicketInstructionAsync({
48
+ player: this.signer,
49
+ tenant,
50
+ }, { programAddress: this.programId });
51
+ return sendInstruction(this.rpc, ix, this.signer);
50
52
  }
51
53
 
52
- /**
53
- * Delegate ticket into TEE (becomes invisible on L1)
54
- */
55
54
  async delegateTicket(
56
- player: web3.PublicKey,
57
- tenant: web3.PublicKey,
58
- validator: web3.PublicKey = new web3.PublicKey("FnE6VJT5QNZdedZPnCoLsARgBwoE6DeJNjBs2H1gySXA"),
59
- confirmOptions?: web3.ConfirmOptions,
60
- signers: web3.Keypair[] = []
61
- ): Promise<web3.TransactionSignature> {
62
- const ticketPda = this.getTicketPda(player, tenant);
63
- return await this.program.methods
64
- .delegateTicket({ ticket: { player, tenant } } as any)
65
- .accounts({
66
- pda: ticketPda,
67
- payer: this.provider.publicKey,
68
- validator: validator,
69
- } as any)
70
- .signers(signers)
71
- .rpc(confirmOptions);
55
+ player: Address,
56
+ tenant: Address,
57
+ validator?: Address,
58
+ ): Promise<string> {
59
+ const ticketPda = await this.getTicketPda(player, tenant);
60
+ const ix = await getDelegateTicketInstructionAsync({
61
+ pda: ticketPda,
62
+ payer: this.signer,
63
+ validator,
64
+ accountType: accountType("Ticket", { player, tenant }),
65
+ }, { programAddress: this.programId });
66
+ return sendInstruction(this.rpc, ix, this.signer);
72
67
  }
73
68
 
74
- /**
75
- * Join Queue (TEE Aware) - now requires ticket
76
- */
77
69
  async joinQueue(
78
- queue: web3.PublicKey,
79
- tenant: web3.PublicKey,
80
- playerData: web3.PublicKey,
81
- confirmOptions?: web3.ConfirmOptions,
82
- signers: web3.Keypair[] = []
83
- ): Promise<web3.TransactionSignature> {
84
- const ticketPda = this.getTicketPda(this.provider.publicKey, tenant);
85
- return await this.program.methods
86
- .joinQueue()
87
- .accountsPartial({
88
- queue: queue,
89
- tenant: tenant,
90
- playerData: playerData,
91
- playerTicket: ticketPda,
92
- signer: this.provider.publicKey,
93
- })
94
- .signers(signers)
95
- .rpc(confirmOptions);
96
- }
97
-
98
- /**
99
- * Cancel search, marks ticket as Cancelled (runs in TEE)
100
- */
101
- async cancelTicket(
102
- tenant: web3.PublicKey,
103
- confirmOptions?: web3.ConfirmOptions,
104
- signers: web3.Keypair[] = []
105
- ): Promise<web3.TransactionSignature> {
106
- const ticketPda = this.getTicketPda(this.provider.publicKey, tenant);
107
- return await this.program.methods
108
- .cancelTicket()
109
- .accountsPartial({
110
- ticket: ticketPda,
111
- tenant: tenant,
112
- player: this.provider.publicKey,
113
- })
114
- .signers(signers)
115
- .rpc(confirmOptions);
70
+ queue: Address,
71
+ tenant: Address,
72
+ playerData: Address,
73
+ callbackProgram?: Address,
74
+ ): Promise<string> {
75
+ const ix = await getJoinQueueInstructionAsync({
76
+ queue,
77
+ tenant,
78
+ playerData,
79
+ signer: this.signer,
80
+ }, { programAddress: this.programId });
81
+ const ixFinal = callbackProgram
82
+ ? { ...ix, accounts: [...ix.accounts, { address: callbackProgram, role: 0 as const }] }
83
+ : ix;
84
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
85
+ return sendInstruction(this.rpc, ixFinal as any, this.signer);
116
86
  }
117
87
 
118
- /**
119
- * Close ticket and reclaim rent (L1, after match consumed or cancelled)
120
- */
121
- async closeTicket(
122
- tenant: web3.PublicKey,
123
- confirmOptions?: web3.ConfirmOptions,
124
- signers: web3.Keypair[] = []
125
- ): Promise<web3.TransactionSignature> {
126
- const ticketPda = this.getTicketPda(this.provider.publicKey, tenant);
127
- return await this.program.methods
128
- .closeTicket()
129
- .accountsPartial({
130
- ticket: ticketPda,
131
- tenant: tenant,
132
- player: this.provider.publicKey,
133
- })
134
- .signers(signers)
135
- .rpc(confirmOptions);
88
+ async cancelTicket(tenant: Address): Promise<string> {
89
+ const ix = await getCancelTicketInstructionAsync({
90
+ player: this.signer,
91
+ tenant,
92
+ }, { programAddress: this.programId });
93
+ return sendInstruction(this.rpc, ix, this.signer);
136
94
  }
137
95
 
138
- /**
139
- * Wait for match by subscribing to ticket PDA changes on L1.
140
- * Returns match info when ticket status changes to Matched.
141
- */
142
- async waitForMatch(
143
- ticketPda: web3.PublicKey,
144
- connection: web3.Connection,
145
- timeoutMs: number = 120000
146
- ): Promise<{ opponent: web3.PublicKey; matchId: anchor.BN } | null> {
147
- return new Promise((resolve, reject) => {
148
- let subscriptionId: number | null = null;
149
- let timeoutId: ReturnType<typeof setTimeout> | null = null;
150
-
151
- const cleanup = () => {
152
- if (timeoutId) clearTimeout(timeoutId);
153
- if (subscriptionId !== null) {
154
- connection.removeAccountChangeListener(subscriptionId);
155
- }
156
- };
157
-
158
- // Set timeout
159
- timeoutId = setTimeout(() => {
160
- cleanup();
161
- resolve(null);
162
- }, timeoutMs);
163
-
164
- // Subscribe to account changes on L1
165
- subscriptionId = connection.onAccountChange(
166
- ticketPda,
167
- (accountInfo: web3.AccountInfo<Buffer>) => {
168
- try {
169
- const decoded = this.program.coder.accounts.decode(
170
- "matchTicket",
171
- accountInfo.data
172
- );
173
- if (decoded.status.matched) {
174
- cleanup();
175
- resolve({
176
- opponent: decoded.status.matched.opponent,
177
- matchId: decoded.status.matched.matchId,
178
- });
179
- }
180
- } catch (e) {
181
- // Ignore decode errors (account may be in transition)
182
- }
183
- },
184
- "confirmed"
185
- );
186
- });
96
+ async closeTicket(tenant: Address): Promise<string> {
97
+ const ix = await getCloseTicketInstructionAsync({
98
+ player: this.signer,
99
+ tenant,
100
+ }, { programAddress: this.programId });
101
+ return sendInstruction(this.rpc, ix, this.signer);
187
102
  }
188
103
 
189
104
  /**
190
- * Poll L1 for ticket status (fallback for environments without websocket)
105
+ * Poll L1 for ticket status.
106
+ * Returns match info when status becomes Matched.
191
107
  */
192
108
  async pollForMatch(
193
- ticketPda: web3.PublicKey,
194
- connection: web3.Connection,
195
- maxAttempts: number = 60,
196
- pollInterval: number = 2000,
197
- signal?: AbortSignal
198
- ): Promise<{ opponent: web3.PublicKey; matchId: anchor.BN } | null> {
109
+ ticketPda: Address,
110
+ maxAttempts = 60,
111
+ pollInterval = 2000,
112
+ signal?: AbortSignal,
113
+ ): Promise<{ opponent: Address; matchId: bigint } | null> {
199
114
  for (let i = 0; i < maxAttempts; i++) {
200
115
  if (signal?.aborted) return null;
201
-
202
- await new Promise(resolve => setTimeout(resolve, pollInterval));
203
-
116
+ await new Promise((r) => setTimeout(r, pollInterval));
204
117
  try {
205
- const accountInfo = await connection.getAccountInfo(ticketPda);
206
- if (!accountInfo) continue;
207
-
208
- const decoded = this.program.coder.accounts.decode(
209
- "matchTicket",
210
- accountInfo.data
211
- );
212
-
213
- if (decoded.status.matched) {
214
- return {
215
- opponent: decoded.status.matched.opponent,
216
- matchId: decoded.status.matched.matchId,
217
- };
118
+ const maybeTicket = await fetchMaybeMatchTicket(this.rpc, ticketPda);
119
+ if (!maybeTicket.exists) continue;
120
+ const status = maybeTicket.data.status;
121
+ if (status.__kind === "Matched") {
122
+ return { opponent: status.opponent, matchId: status.matchId };
218
123
  }
219
- } catch (e) {
220
- // Account may not exist yet or be in transition
124
+ } catch {
125
+ // Ignore decode errors during transition
221
126
  }
222
127
  }
223
128
  return null;
224
129
  }
130
+
131
+ /**
132
+ * High-level: full matchmaking TEE entry flow.
133
+ * Creates ticket on L1, delegates it to TEE, waits for activation, then joins the queue.
134
+ * Use individual methods (createTicket, delegateTicket, joinQueue) as escape hatches if needed.
135
+ */
136
+ async enterQueue(
137
+ tenant: Address,
138
+ queue: Address,
139
+ playerData: Address,
140
+ teeRpc: Rpc<SolanaRpcApi>,
141
+ teeUrlWithToken: string,
142
+ validator?: Address,
143
+ callbackProgram?: Address,
144
+ ): Promise<Address> {
145
+ const player = this.signer.address as Address;
146
+ const ticketPda = await this.getTicketPda(player, tenant);
147
+
148
+ await this.createTicket(tenant);
149
+ await this.delegateTicket(player, tenant, validator);
150
+ await waitUntilPermissionActive(teeUrlWithToken, ticketPda);
151
+
152
+ const teeClient = new MatchmakingPlayer(teeRpc, this.signer, this.programId);
153
+ await teeClient.joinQueue(queue, tenant, playerData, callbackProgram);
154
+
155
+ return ticketPda;
156
+ }
157
+
158
+ /** Create a new MatchmakingPlayer pointing at a TEE RPC endpoint. */
159
+ withRpc(teeUrl: string): MatchmakingPlayer {
160
+ return new MatchmakingPlayer(createSolanaRpc(teeUrl), this.signer, this.programId);
161
+ }
225
162
  }