@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.
- package/README.md +110 -59
- package/dist/admin.d.ts +25 -40
- package/dist/admin.js +93 -114
- package/dist/encryption.js +1 -2
- package/dist/generated/duel/accounts/index.d.ts +10 -0
- package/dist/generated/duel/accounts/index.js +11 -0
- package/dist/generated/duel/accounts/matchTicket.d.ts +38 -0
- package/dist/generated/duel/accounts/matchTicket.js +45 -0
- package/dist/generated/duel/accounts/queue.d.ts +42 -0
- package/dist/generated/duel/accounts/queue.js +45 -0
- package/dist/generated/duel/accounts/tenant.d.ts +41 -0
- package/dist/generated/duel/accounts/tenant.js +44 -0
- package/dist/generated/duel/errors/duel.d.ts +31 -0
- package/dist/generated/duel/errors/duel.js +35 -0
- package/dist/generated/duel/errors/index.d.ts +8 -0
- package/dist/generated/duel/errors/index.js +9 -0
- package/dist/generated/duel/index.d.ts +12 -0
- package/dist/generated/duel/index.js +13 -0
- package/dist/generated/duel/instructions/cancelTicket.d.ts +45 -0
- package/dist/generated/duel/instructions/cancelTicket.js +56 -0
- package/dist/generated/duel/instructions/closeTicket.d.ts +45 -0
- package/dist/generated/duel/instructions/closeTicket.js +56 -0
- package/dist/generated/duel/instructions/commitTickets.d.ts +39 -0
- package/dist/generated/duel/instructions/commitTickets.js +50 -0
- package/dist/generated/duel/instructions/createTicket.d.ts +48 -0
- package/dist/generated/duel/instructions/createTicket.js +63 -0
- package/dist/generated/duel/instructions/delegateQueue.d.ts +69 -0
- package/dist/generated/duel/instructions/delegateQueue.js +90 -0
- package/dist/generated/duel/instructions/delegateTicket.d.ts +69 -0
- package/dist/generated/duel/instructions/delegateTicket.js +90 -0
- package/dist/generated/duel/instructions/flushMatches.d.ts +37 -0
- package/dist/generated/duel/instructions/flushMatches.js +43 -0
- package/dist/generated/duel/instructions/index.d.ts +19 -0
- package/dist/generated/duel/instructions/index.js +20 -0
- package/dist/generated/duel/instructions/initializeQueue.d.ts +48 -0
- package/dist/generated/duel/instructions/initializeQueue.js +63 -0
- package/dist/generated/duel/instructions/initializeTenant.d.ts +70 -0
- package/dist/generated/duel/instructions/initializeTenant.js +67 -0
- package/dist/generated/duel/instructions/joinQueue.d.ts +51 -0
- package/dist/generated/duel/instructions/joinQueue.js +56 -0
- package/dist/generated/duel/instructions/processUndelegation.d.ts +43 -0
- package/dist/generated/duel/instructions/processUndelegation.js +49 -0
- package/dist/generated/duel/instructions/setupTicketPermission.d.ts +54 -0
- package/dist/generated/duel/instructions/setupTicketPermission.js +63 -0
- package/dist/generated/duel/programs/duel.d.ts +92 -0
- package/dist/generated/duel/programs/duel.js +146 -0
- package/dist/generated/duel/programs/index.d.ts +8 -0
- package/dist/generated/duel/programs/index.js +9 -0
- package/dist/generated/duel/types/accountType.d.ts +25 -0
- package/dist/generated/duel/types/accountType.js +25 -0
- package/dist/generated/duel/types/index.d.ts +13 -0
- package/dist/generated/duel/types/index.js +14 -0
- package/dist/generated/duel/types/matchEntry.d.ts +23 -0
- package/dist/generated/duel/types/matchEntry.js +18 -0
- package/dist/generated/duel/types/matchFound.d.ts +23 -0
- package/dist/generated/duel/types/matchFound.js +18 -0
- package/dist/generated/duel/types/pendingMatch.d.ts +21 -0
- package/dist/generated/duel/types/pendingMatch.js +18 -0
- package/dist/generated/duel/types/queueEntry.d.ts +19 -0
- package/dist/generated/duel/types/queueEntry.js +18 -0
- package/dist/generated/duel/types/ticketStatus.d.ts +40 -0
- package/dist/generated/duel/types/ticketStatus.js +25 -0
- package/dist/generated/rps-game/accounts/gameSession.d.ts +40 -0
- package/dist/generated/rps-game/accounts/gameSession.js +45 -0
- package/dist/generated/rps-game/accounts/index.d.ts +9 -0
- package/dist/generated/rps-game/accounts/index.js +10 -0
- package/dist/generated/rps-game/accounts/playerProfile.d.ts +36 -0
- package/dist/generated/rps-game/accounts/playerProfile.js +47 -0
- package/dist/generated/rps-game/errors/index.d.ts +8 -0
- package/dist/generated/rps-game/errors/index.js +9 -0
- package/dist/generated/rps-game/errors/rpsGame.d.ts +25 -0
- package/dist/generated/rps-game/errors/rpsGame.js +29 -0
- package/dist/generated/rps-game/index.d.ts +12 -0
- package/dist/generated/rps-game/index.js +13 -0
- package/dist/generated/rps-game/instructions/closePlayer.d.ts +45 -0
- package/dist/generated/rps-game/instructions/closePlayer.js +56 -0
- package/dist/generated/rps-game/instructions/delegatePda.d.ts +69 -0
- package/dist/generated/rps-game/instructions/delegatePda.js +90 -0
- package/dist/generated/rps-game/instructions/index.d.ts +16 -0
- package/dist/generated/rps-game/instructions/index.js +17 -0
- package/dist/generated/rps-game/instructions/initializePlayer.d.ts +48 -0
- package/dist/generated/rps-game/instructions/initializePlayer.js +63 -0
- package/dist/generated/rps-game/instructions/makeChoice.d.ts +44 -0
- package/dist/generated/rps-game/instructions/makeChoice.js +46 -0
- package/dist/generated/rps-game/instructions/onMatchFound.d.ts +43 -0
- package/dist/generated/rps-game/instructions/onMatchFound.js +45 -0
- package/dist/generated/rps-game/instructions/persistResults.d.ts +43 -0
- package/dist/generated/rps-game/instructions/persistResults.js +50 -0
- package/dist/generated/rps-game/instructions/processUndelegation.d.ts +43 -0
- package/dist/generated/rps-game/instructions/processUndelegation.js +49 -0
- package/dist/generated/rps-game/instructions/startGame.d.ts +54 -0
- package/dist/generated/rps-game/instructions/startGame.js +67 -0
- package/dist/generated/rps-game/instructions/startGameWithTicket.d.ts +57 -0
- package/dist/generated/rps-game/instructions/startGameWithTicket.js +67 -0
- package/dist/generated/rps-game/programs/index.d.ts +8 -0
- package/dist/generated/rps-game/programs/index.js +9 -0
- package/dist/generated/rps-game/programs/rpsGame.d.ts +78 -0
- package/dist/generated/rps-game/programs/rpsGame.js +118 -0
- package/dist/generated/rps-game/types/accountType.d.ts +34 -0
- package/dist/generated/rps-game/types/accountType.js +25 -0
- package/dist/generated/rps-game/types/choice.d.ts +17 -0
- package/dist/generated/rps-game/types/choice.js +25 -0
- package/dist/generated/rps-game/types/gameResult.d.ts +26 -0
- package/dist/generated/rps-game/types/gameResult.js +25 -0
- package/dist/generated/rps-game/types/index.d.ts +10 -0
- package/dist/generated/rps-game/types/index.js +11 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -2
- package/dist/player.d.ts +25 -46
- package/dist/player.js +81 -140
- package/dist/tee.d.ts +14 -0
- package/dist/tee.js +62 -0
- package/dist/transaction.d.ts +11 -0
- package/dist/transaction.js +50 -0
- package/dist/utils.d.ts +4 -4
- package/dist/utils.js +23 -8
- package/package.json +3 -6
- package/src/admin.ts +151 -161
- package/src/duel.json +66 -7
- package/src/encryption.ts +0 -3
- package/src/generated/duel/accounts/index.ts +11 -0
- package/src/generated/duel/accounts/matchTicket.ts +77 -0
- package/src/generated/duel/accounts/queue.ts +77 -0
- package/src/generated/duel/accounts/tenant.ts +76 -0
- package/src/generated/duel/errors/duel.ts +46 -0
- package/src/generated/duel/errors/index.ts +9 -0
- package/src/generated/duel/index.ts +13 -0
- package/src/generated/duel/instructions/cancelTicket.ts +100 -0
- package/src/generated/duel/instructions/closeTicket.ts +100 -0
- package/src/generated/duel/instructions/commitTickets.ts +84 -0
- package/src/generated/duel/instructions/createTicket.ts +109 -0
- package/src/generated/duel/instructions/delegateQueue.ts +157 -0
- package/src/generated/duel/instructions/delegateTicket.ts +157 -0
- package/src/generated/duel/instructions/flushMatches.ts +76 -0
- package/src/generated/duel/instructions/index.ts +20 -0
- package/src/generated/duel/instructions/initializeQueue.ts +109 -0
- package/src/generated/duel/instructions/initializeTenant.ts +126 -0
- package/src/generated/duel/instructions/joinQueue.ts +106 -0
- package/src/generated/duel/instructions/processUndelegation.ts +86 -0
- package/src/generated/duel/instructions/setupTicketPermission.ts +115 -0
- package/src/generated/duel/programs/duel.ts +108 -0
- package/src/generated/duel/programs/index.ts +9 -0
- package/src/generated/duel/types/accountType.ts +36 -0
- package/src/generated/duel/types/index.ts +14 -0
- package/src/generated/duel/types/matchEntry.ts +25 -0
- package/src/generated/duel/types/matchFound.ts +25 -0
- package/src/generated/duel/types/pendingMatch.ts +25 -0
- package/src/generated/duel/types/queueEntry.ts +25 -0
- package/src/generated/duel/types/ticketStatus.ts +38 -0
- package/src/generated/rps-game/accounts/gameSession.ts +77 -0
- package/src/generated/rps-game/accounts/index.ts +10 -0
- package/src/generated/rps-game/accounts/playerProfile.ts +80 -0
- package/src/generated/rps-game/errors/index.ts +9 -0
- package/src/generated/rps-game/errors/rpsGame.ts +40 -0
- package/src/generated/rps-game/index.ts +13 -0
- package/src/generated/rps-game/instructions/closePlayer.ts +100 -0
- package/src/generated/rps-game/instructions/delegatePda.ts +157 -0
- package/src/generated/rps-game/instructions/index.ts +17 -0
- package/src/generated/rps-game/instructions/initializePlayer.ts +109 -0
- package/src/generated/rps-game/instructions/makeChoice.ts +84 -0
- package/src/generated/rps-game/instructions/onMatchFound.ts +79 -0
- package/src/generated/rps-game/instructions/persistResults.ts +88 -0
- package/src/generated/rps-game/instructions/processUndelegation.ts +86 -0
- package/src/generated/rps-game/instructions/startGame.ts +118 -0
- package/src/generated/rps-game/instructions/startGameWithTicket.ts +121 -0
- package/src/generated/rps-game/programs/index.ts +9 -0
- package/src/generated/rps-game/programs/rpsGame.ts +95 -0
- package/src/generated/rps-game/types/accountType.ts +36 -0
- package/src/generated/rps-game/types/choice.ts +25 -0
- package/src/generated/rps-game/types/gameResult.ts +37 -0
- package/src/generated/rps-game/types/index.ts +11 -0
- package/src/index.ts +2 -1
- package/src/player.ts +129 -192
- package/src/{idl/private_matchmaking.json → rps_game.json} +547 -583
- package/src/tee.ts +79 -0
- package/src/transaction.ts +90 -0
- package/src/utils.ts +35 -20
- package/tsconfig.json +2 -2
- package/dist/client.d.ts +0 -54
- package/dist/client.js +0 -265
- package/dist/duel.json +0 -1207
- package/dist/private_matchmaking.json +0 -534
- package/dist/types.d.ts +0 -635
- package/dist/types.js +0 -2
- package/src/idl/private_matchmaking.ts +0 -1033
- 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
package/src/player.ts
CHANGED
|
@@ -1,225 +1,162 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
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
|
|
9
|
-
public
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
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:
|
|
57
|
-
tenant:
|
|
58
|
-
validator
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
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:
|
|
79
|
-
tenant:
|
|
80
|
-
playerData:
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
.
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
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
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
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
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
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
|
|
105
|
+
* Poll L1 for ticket status.
|
|
106
|
+
* Returns match info when status becomes Matched.
|
|
191
107
|
*/
|
|
192
108
|
async pollForMatch(
|
|
193
|
-
ticketPda:
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
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
|
|
206
|
-
if (!
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
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
|
|
220
|
-
//
|
|
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
|
}
|