@1upmonster/duel 0.2.1 → 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 (30) hide show
  1. package/README.md +110 -59
  2. package/dist/admin.d.ts +8 -1
  3. package/dist/admin.js +21 -7
  4. package/dist/generated/duel/errors/duel.d.ts +1 -3
  5. package/dist/generated/duel/errors/duel.js +2 -4
  6. package/dist/generated/duel/instructions/delegateQueue.js +3 -3
  7. package/dist/generated/duel/instructions/delegateTicket.js +3 -3
  8. package/dist/generated/duel/instructions/index.d.ts +1 -0
  9. package/dist/generated/duel/instructions/index.js +2 -1
  10. package/dist/generated/duel/instructions/joinQueue.d.ts +1 -1
  11. package/dist/generated/duel/instructions/joinQueue.js +3 -3
  12. package/dist/generated/duel/instructions/setupTicketPermission.d.ts +54 -0
  13. package/dist/generated/duel/instructions/setupTicketPermission.js +63 -0
  14. package/dist/generated/duel/programs/duel.d.ts +7 -3
  15. package/dist/generated/duel/programs/duel.js +11 -3
  16. package/dist/player.d.ts +7 -1
  17. package/dist/player.js +23 -3
  18. package/package.json +1 -1
  19. package/src/admin.ts +31 -7
  20. package/src/duel.json +0 -5
  21. package/src/generated/duel/errors/duel.ts +2 -4
  22. package/src/generated/duel/instructions/delegateQueue.ts +2 -2
  23. package/src/generated/duel/instructions/delegateTicket.ts +2 -2
  24. package/src/generated/duel/instructions/index.ts +2 -1
  25. package/src/generated/duel/instructions/joinQueue.ts +3 -3
  26. package/src/generated/duel/instructions/setupTicketPermission.ts +115 -0
  27. package/src/generated/duel/programs/duel.ts +8 -4
  28. package/src/player.ts +34 -1
  29. package/src/idl/private_matchmaking.json +0 -1027
  30. package/src/idl/private_matchmaking.ts +0 -1033
@@ -0,0 +1,115 @@
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, fixDecoderSize, fixEncoderSize, getAddressEncoder, getBytesDecoder, getBytesEncoder, getProgramDerivedAddress, getStructDecoder, getStructEncoder, SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, SolanaError, transformEncoder, type AccountMeta, type AccountSignerMeta, type Address, type FixedSizeCodec, type FixedSizeDecoder, type FixedSizeEncoder, type Instruction, type InstructionWithAccounts, type InstructionWithData, type ReadonlyAccount, type ReadonlyUint8Array, type TransactionSigner, type WritableAccount, type WritableSignerAccount } from '@solana/kit';
10
+ import { getAccountMetaFactory, getAddressFromResolvedInstructionAccount, type ResolvedInstructionAccount } from '@solana/program-client-core';
11
+ import { DUEL_PROGRAM_ADDRESS } from '../programs';
12
+
13
+ export const SETUP_TICKET_PERMISSION_DISCRIMINATOR = new Uint8Array([164, 29, 7, 235, 183, 223, 11, 85]);
14
+
15
+ export function getSetupTicketPermissionDiscriminatorBytes() { return fixEncoderSize(getBytesEncoder(), 8).encode(SETUP_TICKET_PERMISSION_DISCRIMINATOR); }
16
+
17
+ export type SetupTicketPermissionInstruction<TProgram extends string = typeof DUEL_PROGRAM_ADDRESS, TAccountTicket extends string | AccountMeta<string> = string, TAccountTenant extends string | AccountMeta<string> = string, TAccountPlayer extends string | AccountMeta<string> = string, TAccountPermission extends string | AccountMeta<string> = string, TAccountPermissionProgram extends string | AccountMeta<string> = string, TAccountSystemProgram extends string | AccountMeta<string> = "11111111111111111111111111111111", TRemainingAccounts extends readonly AccountMeta<string>[] = []> =
18
+ Instruction<TProgram> & InstructionWithData<ReadonlyUint8Array> & InstructionWithAccounts<[TAccountTicket extends string ? ReadonlyAccount<TAccountTicket> : TAccountTicket, TAccountTenant extends string ? ReadonlyAccount<TAccountTenant> : TAccountTenant, TAccountPlayer extends string ? WritableSignerAccount<TAccountPlayer> & AccountSignerMeta<TAccountPlayer> : TAccountPlayer, TAccountPermission extends string ? WritableAccount<TAccountPermission> : TAccountPermission, TAccountPermissionProgram extends string ? ReadonlyAccount<TAccountPermissionProgram> : TAccountPermissionProgram, TAccountSystemProgram extends string ? ReadonlyAccount<TAccountSystemProgram> : TAccountSystemProgram, ...TRemainingAccounts]>;
19
+
20
+ export type SetupTicketPermissionInstructionData = { discriminator: ReadonlyUint8Array; };
21
+
22
+ export type SetupTicketPermissionInstructionDataArgs = { };
23
+
24
+ export function getSetupTicketPermissionInstructionDataEncoder(): FixedSizeEncoder<SetupTicketPermissionInstructionDataArgs> {
25
+ return transformEncoder(getStructEncoder([['discriminator', fixEncoderSize(getBytesEncoder(), 8)]]), (value) => ({ ...value, discriminator: SETUP_TICKET_PERMISSION_DISCRIMINATOR }));
26
+ }
27
+
28
+ export function getSetupTicketPermissionInstructionDataDecoder(): FixedSizeDecoder<SetupTicketPermissionInstructionData> {
29
+ return getStructDecoder([['discriminator', fixDecoderSize(getBytesDecoder(), 8)]]);
30
+ }
31
+
32
+ export function getSetupTicketPermissionInstructionDataCodec(): FixedSizeCodec<SetupTicketPermissionInstructionDataArgs, SetupTicketPermissionInstructionData> {
33
+ return combineCodec(getSetupTicketPermissionInstructionDataEncoder(), getSetupTicketPermissionInstructionDataDecoder());
34
+ }
35
+
36
+ export type SetupTicketPermissionAsyncInput<TAccountTicket extends string = string, TAccountTenant extends string = string, TAccountPlayer extends string = string, TAccountPermission extends string = string, TAccountPermissionProgram extends string = string, TAccountSystemProgram extends string = string> = {
37
+ ticket?: Address<TAccountTicket>;
38
+ tenant: Address<TAccountTenant>;
39
+ player: TransactionSigner<TAccountPlayer>;
40
+ permission: Address<TAccountPermission>;
41
+ permissionProgram: Address<TAccountPermissionProgram>;
42
+ systemProgram?: Address<TAccountSystemProgram>;
43
+ }
44
+
45
+ export async function getSetupTicketPermissionInstructionAsync<TAccountTicket extends string, TAccountTenant extends string, TAccountPlayer extends string, TAccountPermission extends string, TAccountPermissionProgram extends string, TAccountSystemProgram extends string, TProgramAddress extends Address = typeof DUEL_PROGRAM_ADDRESS>(input: SetupTicketPermissionAsyncInput<TAccountTicket, TAccountTenant, TAccountPlayer, TAccountPermission, TAccountPermissionProgram, TAccountSystemProgram>, config?: { programAddress?: TProgramAddress } ): Promise<SetupTicketPermissionInstruction<TProgramAddress, TAccountTicket, TAccountTenant, TAccountPlayer, TAccountPermission, TAccountPermissionProgram, TAccountSystemProgram>> {
46
+ // Program address.
47
+ const programAddress = config?.programAddress ?? DUEL_PROGRAM_ADDRESS;
48
+
49
+ // Original accounts.
50
+ const originalAccounts = { ticket: { value: input.ticket ?? null, isWritable: false }, tenant: { value: input.tenant ?? null, isWritable: false }, player: { value: input.player ?? null, isWritable: true }, permission: { value: input.permission ?? null, isWritable: true }, permissionProgram: { value: input.permissionProgram ?? null, isWritable: false }, systemProgram: { value: input.systemProgram ?? null, isWritable: false } }
51
+ const accounts = originalAccounts as Record<keyof typeof originalAccounts, ResolvedInstructionAccount>;
52
+
53
+
54
+ // Resolve default values.
55
+ if (!accounts.ticket.value) {
56
+ accounts.ticket.value = await getProgramDerivedAddress({ programAddress, seeds: [getBytesEncoder().encode(new Uint8Array([116, 105, 99, 107, 101, 116])), getAddressEncoder().encode(getAddressFromResolvedInstructionAccount("player", accounts.player.value)), getAddressEncoder().encode(getAddressFromResolvedInstructionAccount("tenant", accounts.tenant.value))] });
57
+ }
58
+ if (!accounts.systemProgram.value) {
59
+ accounts.systemProgram.value = '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>;
60
+ }
61
+
62
+ const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
63
+ return Object.freeze({ accounts: [getAccountMeta("ticket", accounts.ticket), getAccountMeta("tenant", accounts.tenant), getAccountMeta("player", accounts.player), getAccountMeta("permission", accounts.permission), getAccountMeta("permissionProgram", accounts.permissionProgram), getAccountMeta("systemProgram", accounts.systemProgram)], data: getSetupTicketPermissionInstructionDataEncoder().encode({}), programAddress } as SetupTicketPermissionInstruction<TProgramAddress, TAccountTicket, TAccountTenant, TAccountPlayer, TAccountPermission, TAccountPermissionProgram, TAccountSystemProgram>);
64
+ }
65
+
66
+ export type SetupTicketPermissionInput<TAccountTicket extends string = string, TAccountTenant extends string = string, TAccountPlayer extends string = string, TAccountPermission extends string = string, TAccountPermissionProgram extends string = string, TAccountSystemProgram extends string = string> = {
67
+ ticket: Address<TAccountTicket>;
68
+ tenant: Address<TAccountTenant>;
69
+ player: TransactionSigner<TAccountPlayer>;
70
+ permission: Address<TAccountPermission>;
71
+ permissionProgram: Address<TAccountPermissionProgram>;
72
+ systemProgram?: Address<TAccountSystemProgram>;
73
+ }
74
+
75
+ export function getSetupTicketPermissionInstruction<TAccountTicket extends string, TAccountTenant extends string, TAccountPlayer extends string, TAccountPermission extends string, TAccountPermissionProgram extends string, TAccountSystemProgram extends string, TProgramAddress extends Address = typeof DUEL_PROGRAM_ADDRESS>(input: SetupTicketPermissionInput<TAccountTicket, TAccountTenant, TAccountPlayer, TAccountPermission, TAccountPermissionProgram, TAccountSystemProgram>, config?: { programAddress?: TProgramAddress } ): SetupTicketPermissionInstruction<TProgramAddress, TAccountTicket, TAccountTenant, TAccountPlayer, TAccountPermission, TAccountPermissionProgram, TAccountSystemProgram> {
76
+ // Program address.
77
+ const programAddress = config?.programAddress ?? DUEL_PROGRAM_ADDRESS;
78
+
79
+ // Original accounts.
80
+ const originalAccounts = { ticket: { value: input.ticket ?? null, isWritable: false }, tenant: { value: input.tenant ?? null, isWritable: false }, player: { value: input.player ?? null, isWritable: true }, permission: { value: input.permission ?? null, isWritable: true }, permissionProgram: { value: input.permissionProgram ?? null, isWritable: false }, systemProgram: { value: input.systemProgram ?? null, isWritable: false } }
81
+ const accounts = originalAccounts as Record<keyof typeof originalAccounts, ResolvedInstructionAccount>;
82
+
83
+
84
+ // Resolve default values.
85
+ if (!accounts.systemProgram.value) {
86
+ accounts.systemProgram.value = '11111111111111111111111111111111' as Address<'11111111111111111111111111111111'>;
87
+ }
88
+
89
+ const getAccountMeta = getAccountMetaFactory(programAddress, 'programId');
90
+ return Object.freeze({ accounts: [getAccountMeta("ticket", accounts.ticket), getAccountMeta("tenant", accounts.tenant), getAccountMeta("player", accounts.player), getAccountMeta("permission", accounts.permission), getAccountMeta("permissionProgram", accounts.permissionProgram), getAccountMeta("systemProgram", accounts.systemProgram)], data: getSetupTicketPermissionInstructionDataEncoder().encode({}), programAddress } as SetupTicketPermissionInstruction<TProgramAddress, TAccountTicket, TAccountTenant, TAccountPlayer, TAccountPermission, TAccountPermissionProgram, TAccountSystemProgram>);
91
+ }
92
+
93
+ export type ParsedSetupTicketPermissionInstruction<TProgram extends string = typeof DUEL_PROGRAM_ADDRESS, TAccountMetas extends readonly AccountMeta[] = readonly AccountMeta[]> = { programAddress: Address<TProgram>;
94
+ accounts: {
95
+ ticket: TAccountMetas[0];
96
+ tenant: TAccountMetas[1];
97
+ player: TAccountMetas[2];
98
+ permission: TAccountMetas[3];
99
+ permissionProgram: TAccountMetas[4];
100
+ systemProgram: TAccountMetas[5];
101
+ };
102
+ data: SetupTicketPermissionInstructionData; };
103
+
104
+ export function parseSetupTicketPermissionInstruction<TProgram extends string, TAccountMetas extends readonly AccountMeta[]>(instruction: Instruction<TProgram> & InstructionWithAccounts<TAccountMetas> & InstructionWithData<ReadonlyUint8Array>): ParsedSetupTicketPermissionInstruction<TProgram, TAccountMetas> {
105
+ if (instruction.accounts.length < 6) {
106
+ throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__INSUFFICIENT_ACCOUNT_METAS, { actualAccountMetas: instruction.accounts.length, expectedAccountMetas: 6 });
107
+ }
108
+ let accountIndex = 0;
109
+ const getNextAccount = () => {
110
+ const accountMeta = (instruction.accounts as TAccountMetas)[accountIndex]!;
111
+ accountIndex += 1;
112
+ return accountMeta;
113
+ }
114
+ return { programAddress: instruction.programAddress, accounts: { ticket: getNextAccount(), tenant: getNextAccount(), player: getNextAccount(), permission: getNextAccount(), permissionProgram: getNextAccount(), systemProgram: getNextAccount() }, data: getSetupTicketPermissionInstructionDataDecoder().decode(instruction.data) };
115
+ }
@@ -9,7 +9,7 @@
9
9
  import { assertIsInstructionWithAccounts, containsBytes, fixEncoderSize, getBytesEncoder, SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT, SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION, SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE, SolanaError, type Address, type ClientWithPayer, type ClientWithRpc, type ClientWithTransactionPlanning, type ClientWithTransactionSending, type GetAccountInfoApi, type GetMultipleAccountsApi, type Instruction, type InstructionWithData, type ReadonlyUint8Array } from '@solana/kit';
10
10
  import { addSelfFetchFunctions, addSelfPlanAndSendFunctions, type SelfFetchFunctions, type SelfPlanAndSendFunctions } from '@solana/program-client-core';
11
11
  import { getMatchTicketCodec, getQueueCodec, getTenantCodec, type MatchTicket, type MatchTicketArgs, type Queue, type QueueArgs, type Tenant, type TenantArgs } from '../accounts';
12
- import { getCancelTicketInstructionAsync, getCloseTicketInstructionAsync, getCommitTicketsInstruction, getCreateTicketInstructionAsync, getDelegateQueueInstructionAsync, getDelegateTicketInstructionAsync, getFlushMatchesInstruction, getInitializeQueueInstructionAsync, getInitializeTenantInstructionAsync, getJoinQueueInstructionAsync, getProcessUndelegationInstruction, parseCancelTicketInstruction, parseCloseTicketInstruction, parseCommitTicketsInstruction, parseCreateTicketInstruction, parseDelegateQueueInstruction, parseDelegateTicketInstruction, parseFlushMatchesInstruction, parseInitializeQueueInstruction, parseInitializeTenantInstruction, parseJoinQueueInstruction, parseProcessUndelegationInstruction, type CancelTicketAsyncInput, type CloseTicketAsyncInput, type CommitTicketsInput, type CreateTicketAsyncInput, type DelegateQueueAsyncInput, type DelegateTicketAsyncInput, type FlushMatchesInput, type InitializeQueueAsyncInput, type InitializeTenantAsyncInput, type JoinQueueAsyncInput, type ParsedCancelTicketInstruction, type ParsedCloseTicketInstruction, type ParsedCommitTicketsInstruction, type ParsedCreateTicketInstruction, type ParsedDelegateQueueInstruction, type ParsedDelegateTicketInstruction, type ParsedFlushMatchesInstruction, type ParsedInitializeQueueInstruction, type ParsedInitializeTenantInstruction, type ParsedJoinQueueInstruction, type ParsedProcessUndelegationInstruction, type ProcessUndelegationInput } from '../instructions';
12
+ import { getCancelTicketInstructionAsync, getCloseTicketInstructionAsync, getCommitTicketsInstruction, getCreateTicketInstructionAsync, getDelegateQueueInstructionAsync, getDelegateTicketInstructionAsync, getFlushMatchesInstruction, getInitializeQueueInstructionAsync, getInitializeTenantInstructionAsync, getJoinQueueInstructionAsync, getProcessUndelegationInstruction, getSetupTicketPermissionInstructionAsync, parseCancelTicketInstruction, parseCloseTicketInstruction, parseCommitTicketsInstruction, parseCreateTicketInstruction, parseDelegateQueueInstruction, parseDelegateTicketInstruction, parseFlushMatchesInstruction, parseInitializeQueueInstruction, parseInitializeTenantInstruction, parseJoinQueueInstruction, parseProcessUndelegationInstruction, parseSetupTicketPermissionInstruction, type CancelTicketAsyncInput, type CloseTicketAsyncInput, type CommitTicketsInput, type CreateTicketAsyncInput, type DelegateQueueAsyncInput, type DelegateTicketAsyncInput, type FlushMatchesInput, type InitializeQueueAsyncInput, type InitializeTenantAsyncInput, type JoinQueueAsyncInput, type ParsedCancelTicketInstruction, type ParsedCloseTicketInstruction, type ParsedCommitTicketsInstruction, type ParsedCreateTicketInstruction, type ParsedDelegateQueueInstruction, type ParsedDelegateTicketInstruction, type ParsedFlushMatchesInstruction, type ParsedInitializeQueueInstruction, type ParsedInitializeTenantInstruction, type ParsedJoinQueueInstruction, type ParsedProcessUndelegationInstruction, type ParsedSetupTicketPermissionInstruction, type ProcessUndelegationInput, type SetupTicketPermissionAsyncInput } from '../instructions';
13
13
 
14
14
  export const DUEL_PROGRAM_ADDRESS = 'EdZzUwKd1X2ZWjxLPpz1cpEzMF7RUZC43Pq64v1VcK5X' as Address<'EdZzUwKd1X2ZWjxLPpz1cpEzMF7RUZC43Pq64v1VcK5X'>;
15
15
 
@@ -23,7 +23,7 @@ if (containsBytes(data, fixEncoderSize(getBytesEncoder(), 8).encode(new Uint8Arr
23
23
  throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_ACCOUNT, { accountData: data, programName: "duel" });
24
24
  }
25
25
 
26
- export enum DuelInstruction { CancelTicket, CloseTicket, CommitTickets, CreateTicket, DelegateQueue, DelegateTicket, FlushMatches, InitializeQueue, InitializeTenant, JoinQueue, ProcessUndelegation }
26
+ export enum DuelInstruction { CancelTicket, CloseTicket, CommitTickets, CreateTicket, DelegateQueue, DelegateTicket, FlushMatches, InitializeQueue, InitializeTenant, JoinQueue, ProcessUndelegation, SetupTicketPermission }
27
27
 
28
28
  export function identifyDuelInstruction(instruction: { data: ReadonlyUint8Array } | ReadonlyUint8Array): DuelInstruction {
29
29
  const data = 'data' in instruction ? instruction.data : instruction;
@@ -38,6 +38,7 @@ if (containsBytes(data, fixEncoderSize(getBytesEncoder(), 8).encode(new Uint8Arr
38
38
  if (containsBytes(data, fixEncoderSize(getBytesEncoder(), 8).encode(new Uint8Array([94, 120, 34, 186, 57, 167, 241, 206])), 0)) { return DuelInstruction.InitializeTenant; }
39
39
  if (containsBytes(data, fixEncoderSize(getBytesEncoder(), 8).encode(new Uint8Array([157, 115, 48, 109, 65, 86, 203, 238])), 0)) { return DuelInstruction.JoinQueue; }
40
40
  if (containsBytes(data, fixEncoderSize(getBytesEncoder(), 8).encode(new Uint8Array([196, 28, 41, 206, 48, 37, 51, 167])), 0)) { return DuelInstruction.ProcessUndelegation; }
41
+ if (containsBytes(data, fixEncoderSize(getBytesEncoder(), 8).encode(new Uint8Array([164, 29, 7, 235, 183, 223, 11, 85])), 0)) { return DuelInstruction.SetupTicketPermission; }
41
42
  throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__FAILED_TO_IDENTIFY_INSTRUCTION, { instructionData: data, programName: "duel" });
42
43
  }
43
44
 
@@ -53,6 +54,7 @@ export type ParsedDuelInstruction<TProgram extends string = 'EdZzUwKd1X2ZWjxLPpz
53
54
  | { instructionType: DuelInstruction.InitializeTenant } & ParsedInitializeTenantInstruction<TProgram>
54
55
  | { instructionType: DuelInstruction.JoinQueue } & ParsedJoinQueueInstruction<TProgram>
55
56
  | { instructionType: DuelInstruction.ProcessUndelegation } & ParsedProcessUndelegationInstruction<TProgram>
57
+ | { instructionType: DuelInstruction.SetupTicketPermission } & ParsedSetupTicketPermissionInstruction<TProgram>
56
58
 
57
59
 
58
60
  export function parseDuelInstruction<TProgram extends string>(
@@ -83,6 +85,8 @@ case DuelInstruction.JoinQueue: { assertIsInstructionWithAccounts(instruction);
83
85
  return { instructionType: DuelInstruction.JoinQueue, ...parseJoinQueueInstruction(instruction) }; }
84
86
  case DuelInstruction.ProcessUndelegation: { assertIsInstructionWithAccounts(instruction);
85
87
  return { instructionType: DuelInstruction.ProcessUndelegation, ...parseProcessUndelegationInstruction(instruction) }; }
88
+ case DuelInstruction.SetupTicketPermission: { assertIsInstructionWithAccounts(instruction);
89
+ return { instructionType: DuelInstruction.SetupTicketPermission, ...parseSetupTicketPermissionInstruction(instruction) }; }
86
90
  default: throw new SolanaError(SOLANA_ERROR__PROGRAM_CLIENTS__UNRECOGNIZED_INSTRUCTION_TYPE, { instructionType: instructionType as string, programName: "duel" });
87
91
  }
88
92
  }
@@ -91,13 +95,13 @@ export type DuelPlugin = { accounts: DuelPluginAccounts; instructions: DuelPlugi
91
95
 
92
96
  export type DuelPluginAccounts = { matchTicket: ReturnType<typeof getMatchTicketCodec> & SelfFetchFunctions<MatchTicketArgs, MatchTicket>; queue: ReturnType<typeof getQueueCodec> & SelfFetchFunctions<QueueArgs, Queue>; tenant: ReturnType<typeof getTenantCodec> & SelfFetchFunctions<TenantArgs, Tenant>; }
93
97
 
94
- export type DuelPluginInstructions = { cancelTicket: (input: CancelTicketAsyncInput) => ReturnType<typeof getCancelTicketInstructionAsync> & SelfPlanAndSendFunctions; closeTicket: (input: CloseTicketAsyncInput) => ReturnType<typeof getCloseTicketInstructionAsync> & SelfPlanAndSendFunctions; commitTickets: (input: MakeOptional<CommitTicketsInput, "payer">) => ReturnType<typeof getCommitTicketsInstruction> & SelfPlanAndSendFunctions; createTicket: (input: CreateTicketAsyncInput) => ReturnType<typeof getCreateTicketInstructionAsync> & SelfPlanAndSendFunctions; delegateQueue: (input: MakeOptional<DelegateQueueAsyncInput, "payer">) => ReturnType<typeof getDelegateQueueInstructionAsync> & SelfPlanAndSendFunctions; delegateTicket: (input: MakeOptional<DelegateTicketAsyncInput, "payer">) => ReturnType<typeof getDelegateTicketInstructionAsync> & SelfPlanAndSendFunctions; flushMatches: (input: FlushMatchesInput) => ReturnType<typeof getFlushMatchesInstruction> & SelfPlanAndSendFunctions; initializeQueue: (input: InitializeQueueAsyncInput) => ReturnType<typeof getInitializeQueueInstructionAsync> & SelfPlanAndSendFunctions; initializeTenant: (input: InitializeTenantAsyncInput) => ReturnType<typeof getInitializeTenantInstructionAsync> & SelfPlanAndSendFunctions; joinQueue: (input: JoinQueueAsyncInput) => ReturnType<typeof getJoinQueueInstructionAsync> & SelfPlanAndSendFunctions; processUndelegation: (input: MakeOptional<ProcessUndelegationInput, "payer">) => ReturnType<typeof getProcessUndelegationInstruction> & SelfPlanAndSendFunctions; }
98
+ export type DuelPluginInstructions = { cancelTicket: (input: CancelTicketAsyncInput) => ReturnType<typeof getCancelTicketInstructionAsync> & SelfPlanAndSendFunctions; closeTicket: (input: CloseTicketAsyncInput) => ReturnType<typeof getCloseTicketInstructionAsync> & SelfPlanAndSendFunctions; commitTickets: (input: MakeOptional<CommitTicketsInput, "payer">) => ReturnType<typeof getCommitTicketsInstruction> & SelfPlanAndSendFunctions; createTicket: (input: CreateTicketAsyncInput) => ReturnType<typeof getCreateTicketInstructionAsync> & SelfPlanAndSendFunctions; delegateQueue: (input: MakeOptional<DelegateQueueAsyncInput, "payer">) => ReturnType<typeof getDelegateQueueInstructionAsync> & SelfPlanAndSendFunctions; delegateTicket: (input: MakeOptional<DelegateTicketAsyncInput, "payer">) => ReturnType<typeof getDelegateTicketInstructionAsync> & SelfPlanAndSendFunctions; flushMatches: (input: FlushMatchesInput) => ReturnType<typeof getFlushMatchesInstruction> & SelfPlanAndSendFunctions; initializeQueue: (input: InitializeQueueAsyncInput) => ReturnType<typeof getInitializeQueueInstructionAsync> & SelfPlanAndSendFunctions; initializeTenant: (input: InitializeTenantAsyncInput) => ReturnType<typeof getInitializeTenantInstructionAsync> & SelfPlanAndSendFunctions; joinQueue: (input: JoinQueueAsyncInput) => ReturnType<typeof getJoinQueueInstructionAsync> & SelfPlanAndSendFunctions; processUndelegation: (input: MakeOptional<ProcessUndelegationInput, "payer">) => ReturnType<typeof getProcessUndelegationInstruction> & SelfPlanAndSendFunctions; setupTicketPermission: (input: SetupTicketPermissionAsyncInput) => ReturnType<typeof getSetupTicketPermissionInstructionAsync> & SelfPlanAndSendFunctions; }
95
99
 
96
100
  export type DuelPluginRequirements = ClientWithRpc<GetAccountInfoApi & GetMultipleAccountsApi> & ClientWithPayer & ClientWithTransactionPlanning & ClientWithTransactionSending
97
101
 
98
102
  export function duelProgram() {
99
103
  return <T extends DuelPluginRequirements>(client: T) => {
100
- return { ...client, duel: <DuelPlugin>{ accounts: { matchTicket: addSelfFetchFunctions(client, getMatchTicketCodec()), queue: addSelfFetchFunctions(client, getQueueCodec()), tenant: addSelfFetchFunctions(client, getTenantCodec()) }, instructions: { cancelTicket: input => addSelfPlanAndSendFunctions(client, getCancelTicketInstructionAsync(input)), closeTicket: input => addSelfPlanAndSendFunctions(client, getCloseTicketInstructionAsync(input)), commitTickets: input => addSelfPlanAndSendFunctions(client, getCommitTicketsInstruction({ ...input, payer: input.payer ?? client.payer })), createTicket: input => addSelfPlanAndSendFunctions(client, getCreateTicketInstructionAsync(input)), delegateQueue: input => addSelfPlanAndSendFunctions(client, getDelegateQueueInstructionAsync({ ...input, payer: input.payer ?? client.payer })), delegateTicket: input => addSelfPlanAndSendFunctions(client, getDelegateTicketInstructionAsync({ ...input, payer: input.payer ?? client.payer })), flushMatches: input => addSelfPlanAndSendFunctions(client, getFlushMatchesInstruction(input)), initializeQueue: input => addSelfPlanAndSendFunctions(client, getInitializeQueueInstructionAsync(input)), initializeTenant: input => addSelfPlanAndSendFunctions(client, getInitializeTenantInstructionAsync(input)), joinQueue: input => addSelfPlanAndSendFunctions(client, getJoinQueueInstructionAsync(input)), processUndelegation: input => addSelfPlanAndSendFunctions(client, getProcessUndelegationInstruction({ ...input, payer: input.payer ?? client.payer.address })) } } };
104
+ return { ...client, duel: <DuelPlugin>{ accounts: { matchTicket: addSelfFetchFunctions(client, getMatchTicketCodec()), queue: addSelfFetchFunctions(client, getQueueCodec()), tenant: addSelfFetchFunctions(client, getTenantCodec()) }, instructions: { cancelTicket: input => addSelfPlanAndSendFunctions(client, getCancelTicketInstructionAsync(input)), closeTicket: input => addSelfPlanAndSendFunctions(client, getCloseTicketInstructionAsync(input)), commitTickets: input => addSelfPlanAndSendFunctions(client, getCommitTicketsInstruction({ ...input, payer: input.payer ?? client.payer })), createTicket: input => addSelfPlanAndSendFunctions(client, getCreateTicketInstructionAsync(input)), delegateQueue: input => addSelfPlanAndSendFunctions(client, getDelegateQueueInstructionAsync({ ...input, payer: input.payer ?? client.payer })), delegateTicket: input => addSelfPlanAndSendFunctions(client, getDelegateTicketInstructionAsync({ ...input, payer: input.payer ?? client.payer })), flushMatches: input => addSelfPlanAndSendFunctions(client, getFlushMatchesInstruction(input)), initializeQueue: input => addSelfPlanAndSendFunctions(client, getInitializeQueueInstructionAsync(input)), initializeTenant: input => addSelfPlanAndSendFunctions(client, getInitializeTenantInstructionAsync(input)), joinQueue: input => addSelfPlanAndSendFunctions(client, getJoinQueueInstructionAsync(input)), processUndelegation: input => addSelfPlanAndSendFunctions(client, getProcessUndelegationInstruction({ ...input, payer: input.payer ?? client.payer.address })), setupTicketPermission: input => addSelfPlanAndSendFunctions(client, getSetupTicketPermissionInstructionAsync(input)) } } };
101
105
  };
102
106
  }
103
107
 
package/src/player.ts CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  accountType,
16
16
  } from "./generated/duel/index.js";
17
17
  import { sendInstruction } from "./transaction.js";
18
+ import { waitUntilPermissionActive } from "./tee.js";
18
19
  import * as utils from "./utils.js";
19
20
 
20
21
  const DUEL_PROGRAM_ID = "EdZzUwKd1X2ZWjxLPpz1cpEzMF7RUZC43Pq64v1VcK5X" as Address;
@@ -69,6 +70,7 @@ export class MatchmakingPlayer {
69
70
  queue: Address,
70
71
  tenant: Address,
71
72
  playerData: Address,
73
+ callbackProgram?: Address,
72
74
  ): Promise<string> {
73
75
  const ix = await getJoinQueueInstructionAsync({
74
76
  queue,
@@ -76,7 +78,11 @@ export class MatchmakingPlayer {
76
78
  playerData,
77
79
  signer: this.signer,
78
80
  }, { programAddress: this.programId });
79
- return sendInstruction(this.rpc, ix, this.signer);
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);
80
86
  }
81
87
 
82
88
  async cancelTicket(tenant: Address): Promise<string> {
@@ -122,6 +128,33 @@ export class MatchmakingPlayer {
122
128
  return null;
123
129
  }
124
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
+
125
158
  /** Create a new MatchmakingPlayer pointing at a TEE RPC endpoint. */
126
159
  withRpc(teeUrl: string): MatchmakingPlayer {
127
160
  return new MatchmakingPlayer(createSolanaRpc(teeUrl), this.signer, this.programId);