delegate.ts 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186
  1. import * as beet from "@metaplex-foundation/beet";
  2. import * as web3 from "@solana/web3.js";
  3. import {
  4. DelegateAccounts,
  5. DELEGATION_PROGRAM_ID,
  6. } from "@magicblock-labs/delegation-program";
  7. import { FindComponentPda } from "../index";
  8. import {
  9. type PublicKey,
  10. Transaction,
  11. type TransactionInstruction,
  12. } from "@solana/web3.js";
  13. export interface DelegateInstructionArgs {
  14. validUntil: beet.bignum;
  15. commitFrequencyMs: number;
  16. }
  17. export const delegateStruct = new beet.FixableBeetArgsStruct<
  18. DelegateInstructionArgs & {
  19. instructionDiscriminator: number[] /* size: 8 */;
  20. }
  21. >(
  22. [
  23. ["instructionDiscriminator", beet.uniformFixedSizeArray(beet.u8, 8)],
  24. ["validUntil", beet.i64],
  25. ["commitFrequencyMs", beet.u32],
  26. ],
  27. "DelegateInstructionArgs"
  28. );
  29. /**
  30. * Accounts required by the _delegate_ instruction
  31. *
  32. */
  33. export interface DelegateInstructionAccounts {
  34. payer: web3.PublicKey;
  35. entity: web3.PublicKey;
  36. account: web3.PublicKey;
  37. ownerProgram: web3.PublicKey;
  38. buffer?: web3.PublicKey;
  39. delegationRecord?: web3.PublicKey;
  40. delegationMetadata?: web3.PublicKey;
  41. delegationProgram?: web3.PublicKey;
  42. systemProgram?: web3.PublicKey;
  43. }
  44. export const delegateInstructionDiscriminator = [
  45. 90, 147, 75, 178, 85, 88, 4, 137,
  46. ];
  47. /**
  48. * Creates a Delegate instruction.
  49. */
  50. export function createDelegateInstruction(
  51. accounts: DelegateInstructionAccounts,
  52. validUntil: beet.bignum = 0,
  53. commitFrequencyMs: number = 30000,
  54. programId = accounts.ownerProgram
  55. ) {
  56. const [data] = delegateStruct.serialize({
  57. instructionDiscriminator: delegateInstructionDiscriminator,
  58. validUntil,
  59. commitFrequencyMs,
  60. });
  61. const { delegationPda, delegationMetadata, bufferPda } = DelegateAccounts(
  62. accounts.account,
  63. accounts.ownerProgram
  64. );
  65. const keys: web3.AccountMeta[] = [
  66. {
  67. pubkey: accounts.payer,
  68. isWritable: false,
  69. isSigner: true,
  70. },
  71. {
  72. pubkey: accounts.entity,
  73. isWritable: false,
  74. isSigner: false,
  75. },
  76. {
  77. pubkey: accounts.account,
  78. isWritable: true,
  79. isSigner: false,
  80. },
  81. {
  82. pubkey: accounts.ownerProgram,
  83. isWritable: false,
  84. isSigner: false,
  85. },
  86. {
  87. pubkey: accounts.buffer ?? bufferPda,
  88. isWritable: true,
  89. isSigner: false,
  90. },
  91. {
  92. pubkey: accounts.delegationRecord ?? delegationPda,
  93. isWritable: true,
  94. isSigner: false,
  95. },
  96. {
  97. pubkey: accounts.delegationMetadata ?? delegationMetadata,
  98. isWritable: true,
  99. isSigner: false,
  100. },
  101. {
  102. pubkey:
  103. accounts.delegationProgram ?? new web3.PublicKey(DELEGATION_PROGRAM_ID),
  104. isWritable: false,
  105. isSigner: false,
  106. },
  107. {
  108. pubkey: accounts.systemProgram ?? web3.SystemProgram.programId,
  109. isWritable: false,
  110. isSigner: false,
  111. },
  112. ];
  113. return new web3.TransactionInstruction({
  114. programId,
  115. keys,
  116. data,
  117. });
  118. }
  119. /**
  120. * Create the transaction to Delegate a component
  121. * @param payer
  122. * @param entityPda
  123. * @param componentId
  124. * @param seeds
  125. * @param buffer
  126. * @param delegationRecord
  127. * @param delegationMetadata
  128. * @param delegationProgram
  129. * @param systemProgram
  130. * @constructor
  131. */
  132. export async function DelegateComponent({
  133. payer,
  134. entity,
  135. componentId,
  136. seed = "",
  137. buffer,
  138. delegationRecord,
  139. delegationMetadata,
  140. delegationProgram,
  141. systemProgram,
  142. }: {
  143. payer: PublicKey;
  144. entity: PublicKey;
  145. componentId: PublicKey;
  146. seed?: string;
  147. buffer?: web3.PublicKey;
  148. delegationRecord?: web3.PublicKey;
  149. delegationMetadata?: web3.PublicKey;
  150. delegationProgram?: web3.PublicKey;
  151. systemProgram?: web3.PublicKey;
  152. }): Promise<{
  153. instruction: TransactionInstruction;
  154. transaction: Transaction;
  155. componentPda: PublicKey;
  156. }> {
  157. const componentPda = FindComponentPda({ componentId, entity, seed });
  158. const delegateComponentIx = createDelegateInstruction({
  159. payer,
  160. entity,
  161. account: componentPda,
  162. ownerProgram: componentId,
  163. buffer,
  164. delegationRecord,
  165. delegationMetadata,
  166. delegationProgram,
  167. systemProgram,
  168. });
  169. return {
  170. instruction: delegateComponentIx,
  171. transaction: new Transaction().add(delegateComponentIx),
  172. componentPda,
  173. };
  174. }