instructionsPage.test.ts 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. import {
  2. accountValueNode,
  3. constantPdaSeedNodeFromString,
  4. instructionAccountNode,
  5. instructionNode,
  6. pdaNode,
  7. pdaSeedValueNode,
  8. pdaValueNode,
  9. programNode,
  10. publicKeyTypeNode,
  11. variablePdaSeedNode,
  12. } from '@kinobi-so/nodes';
  13. import { visit } from '@kinobi-so/visitors-core';
  14. import { test } from 'vitest';
  15. import { getRenderMapVisitor } from '../src';
  16. import { renderMapContains, renderMapContainsImports } from './_setup';
  17. test('it renders instruction accounts with linked PDAs as default value', async () => {
  18. // Given the following program with a PDA node and an instruction account using it as default value.
  19. const node = programNode({
  20. instructions: [
  21. instructionNode({
  22. accounts: [
  23. instructionAccountNode({ isSigner: true, isWritable: false, name: 'authority' }),
  24. instructionAccountNode({
  25. defaultValue: pdaValueNode('counter', [
  26. pdaSeedValueNode('authority', accountValueNode('authority')),
  27. ]),
  28. isSigner: false,
  29. isWritable: false,
  30. name: 'counter',
  31. }),
  32. ],
  33. name: 'increment',
  34. }),
  35. ],
  36. name: 'counter',
  37. pdas: [
  38. pdaNode({
  39. name: 'counter',
  40. seeds: [
  41. constantPdaSeedNodeFromString('utf8', 'counter'),
  42. variablePdaSeedNode('authority', publicKeyTypeNode()),
  43. ],
  44. }),
  45. ],
  46. publicKey: '1111',
  47. });
  48. // When we render it.
  49. const renderMap = visit(node, getRenderMapVisitor());
  50. // Then we expect the following default value to be rendered.
  51. await renderMapContains(renderMap, 'instructions/increment.ts', [
  52. 'if (!resolvedAccounts.counter.value) { ' +
  53. 'resolvedAccounts.counter.value = findCounterPda( context, { authority: expectPublicKey ( resolvedAccounts.authority.value ) } ); ' +
  54. '}',
  55. ]);
  56. await renderMapContainsImports(renderMap, 'instructions/increment.ts', { '../accounts': ['findCounterPda'] });
  57. });
  58. test('it renders instruction accounts with inlined PDAs as default value', async () => {
  59. // Given the following instruction with an inlined PDA default value.
  60. const node = programNode({
  61. instructions: [
  62. instructionNode({
  63. accounts: [
  64. instructionAccountNode({ isSigner: true, isWritable: false, name: 'authority' }),
  65. instructionAccountNode({
  66. defaultValue: pdaValueNode(
  67. pdaNode({
  68. name: 'counter',
  69. seeds: [
  70. constantPdaSeedNodeFromString('utf8', 'counter'),
  71. variablePdaSeedNode('authority', publicKeyTypeNode()),
  72. ],
  73. }),
  74. [pdaSeedValueNode('authority', accountValueNode('authority'))],
  75. ),
  76. isSigner: false,
  77. isWritable: false,
  78. name: 'counter',
  79. }),
  80. ],
  81. name: 'increment',
  82. }),
  83. ],
  84. name: 'counter',
  85. publicKey: '1111',
  86. });
  87. // When we render it.
  88. const renderMap = visit(node, getRenderMapVisitor());
  89. // Then we expect the following default value to be rendered.
  90. await renderMapContains(renderMap, 'instructions/increment.ts', [
  91. "context: Pick<Context, 'eddsa' | 'programs'>",
  92. 'if (!resolvedAccounts.counter.value) { ' +
  93. 'resolvedAccounts.counter.value = context.eddsa.findPda( programId, [ ' +
  94. " string({ size: 'variable' }).serialize( 'counter' ), " +
  95. ' publicKeySerializer().serialize( expectPublicKey( resolvedAccounts.authority.value ) ) ' +
  96. '] ); ' +
  97. '}',
  98. ]);
  99. });
  100. test('it renders instruction accounts with inlined PDAs from another program as default value', async () => {
  101. // Given the following instruction with an inlined PDA default value from another program.
  102. const node = programNode({
  103. instructions: [
  104. instructionNode({
  105. accounts: [
  106. instructionAccountNode({ isSigner: true, isWritable: false, name: 'authority' }),
  107. instructionAccountNode({
  108. defaultValue: pdaValueNode(
  109. pdaNode({
  110. name: 'counter',
  111. programId: '2222',
  112. seeds: [
  113. constantPdaSeedNodeFromString('utf8', 'counter'),
  114. variablePdaSeedNode('authority', publicKeyTypeNode()),
  115. ],
  116. }),
  117. [pdaSeedValueNode('authority', accountValueNode('authority'))],
  118. ),
  119. isSigner: false,
  120. isWritable: false,
  121. name: 'counter',
  122. }),
  123. ],
  124. name: 'increment',
  125. }),
  126. ],
  127. name: 'counter',
  128. publicKey: '1111',
  129. });
  130. // When we render it.
  131. const renderMap = visit(node, getRenderMapVisitor());
  132. // Then we expect the following default value to be rendered.
  133. await renderMapContains(renderMap, 'instructions/increment.ts', [
  134. 'if (!resolvedAccounts.counter.value) { ' +
  135. 'resolvedAccounts.counter.value = context.eddsa.findPda( ' +
  136. " context.programs.getPublicKey('2222', '2222'), " +
  137. ' [ ' +
  138. " string({ size: 'variable' }).serialize( 'counter' ), " +
  139. ' publicKeySerializer().serialize( expectPublicKey( resolvedAccounts.authority.value ) ) ' +
  140. ' ] ' +
  141. '); ' +
  142. '}',
  143. ]);
  144. });