ProgramNode.test.ts 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. import {
  2. accountNode,
  3. accountValueNode,
  4. argumentValueNode,
  5. arrayTypeNode,
  6. bytesTypeNode,
  7. constantPdaSeedNodeFromBytes,
  8. definedTypeLinkNode,
  9. definedTypeNode,
  10. enumEmptyVariantTypeNode,
  11. enumTupleVariantTypeNode,
  12. enumTypeNode,
  13. errorNode,
  14. fieldDiscriminatorNode,
  15. fixedCountNode,
  16. fixedSizeTypeNode,
  17. instructionAccountNode,
  18. instructionArgumentNode,
  19. instructionNode,
  20. numberTypeNode,
  21. pdaNode,
  22. pdaSeedValueNode,
  23. pdaValueNode,
  24. programNode,
  25. publicKeyTypeNode,
  26. structFieldTypeNode,
  27. structTypeNode,
  28. tupleTypeNode,
  29. variablePdaSeedNode,
  30. } from '@codama/nodes';
  31. import { expect, test } from 'vitest';
  32. import { getAnchorDiscriminatorV01, programNodeFromAnchorV01 } from '../../src';
  33. test('it creates program nodes', () => {
  34. const node = programNodeFromAnchorV01({
  35. accounts: [{ discriminator: [246, 28, 6, 87, 251, 45, 50, 42], name: 'MyAccount' }],
  36. address: '1111',
  37. errors: [{ code: 42, msg: 'my error message', name: 'myError' }],
  38. instructions: [
  39. {
  40. accounts: [
  41. {
  42. name: 'authority',
  43. pda: {
  44. seeds: [
  45. { kind: 'const', value: [42, 31, 29] },
  46. { kind: 'account', path: 'owner' },
  47. { kind: 'arg', path: 'amount' },
  48. ],
  49. },
  50. },
  51. {
  52. name: 'owner',
  53. },
  54. {
  55. name: 'some_account',
  56. },
  57. ],
  58. args: [
  59. {
  60. name: 'amount',
  61. type: 'u8',
  62. },
  63. ],
  64. discriminator: [246, 28, 6, 87, 251, 45, 50, 42],
  65. name: 'my_instruction',
  66. },
  67. ],
  68. metadata: { name: 'my_program', spec: '0.1.0', version: '1.2.3' },
  69. types: [{ name: 'MyAccount', type: { fields: [{ name: 'delegate', type: 'pubkey' }], kind: 'struct' } }],
  70. });
  71. expect(node).toEqual(
  72. programNode({
  73. accounts: [
  74. accountNode({
  75. data: structTypeNode([
  76. structFieldTypeNode({
  77. defaultValue: getAnchorDiscriminatorV01([246, 28, 6, 87, 251, 45, 50, 42]),
  78. defaultValueStrategy: 'omitted',
  79. name: 'discriminator',
  80. type: fixedSizeTypeNode(bytesTypeNode(), 8),
  81. }),
  82. structFieldTypeNode({
  83. name: 'delegate',
  84. type: publicKeyTypeNode(),
  85. }),
  86. ]),
  87. discriminators: [fieldDiscriminatorNode('discriminator')],
  88. name: 'myAccount',
  89. }),
  90. ],
  91. definedTypes: [],
  92. errors: [
  93. errorNode({
  94. code: 42,
  95. docs: ['myError: my error message'],
  96. message: 'my error message',
  97. name: 'myError',
  98. }),
  99. ],
  100. instructions: [
  101. instructionNode({
  102. accounts: [
  103. instructionAccountNode({
  104. defaultValue: pdaValueNode(
  105. pdaNode({
  106. name: 'authority',
  107. seeds: [
  108. constantPdaSeedNodeFromBytes('base58', 'F9bS'),
  109. variablePdaSeedNode('owner', publicKeyTypeNode()),
  110. variablePdaSeedNode('amount', numberTypeNode('u8')),
  111. ],
  112. }),
  113. [
  114. pdaSeedValueNode('owner', accountValueNode('owner')),
  115. pdaSeedValueNode('amount', argumentValueNode('amount')),
  116. ],
  117. ),
  118. isSigner: false,
  119. isWritable: false,
  120. name: 'authority',
  121. }),
  122. instructionAccountNode({
  123. isSigner: false,
  124. isWritable: false,
  125. name: 'owner',
  126. }),
  127. instructionAccountNode({
  128. isSigner: false,
  129. isWritable: false,
  130. name: 'someAccount',
  131. }),
  132. ],
  133. arguments: [
  134. instructionArgumentNode({
  135. defaultValue: getAnchorDiscriminatorV01([246, 28, 6, 87, 251, 45, 50, 42]),
  136. defaultValueStrategy: 'omitted',
  137. name: 'discriminator',
  138. type: fixedSizeTypeNode(bytesTypeNode(), 8),
  139. }),
  140. instructionArgumentNode({ name: 'amount', type: numberTypeNode('u8') }),
  141. ],
  142. discriminators: [fieldDiscriminatorNode('discriminator')],
  143. name: 'myInstruction',
  144. }),
  145. ],
  146. name: 'myProgram',
  147. origin: 'anchor',
  148. pdas: [],
  149. publicKey: '1111',
  150. version: '1.2.3',
  151. }),
  152. );
  153. });
  154. test('it unwraps and removes generic types', () => {
  155. const node = programNodeFromAnchorV01({
  156. address: '1111',
  157. instructions: [],
  158. metadata: { name: 'my_program', spec: '0.1.0', version: '1.2.3' },
  159. types: [
  160. {
  161. generics: [
  162. { kind: 'const', name: 'N', type: 'usize' },
  163. { kind: 'type', name: 'T' },
  164. ],
  165. name: 'SimpleAllocator',
  166. type: {
  167. fields: [
  168. {
  169. name: 'state',
  170. type: { array: [{ defined: { name: 'ItemState' } }, { generic: 'N' }] },
  171. },
  172. {
  173. name: 'data',
  174. type: { array: [{ generic: 'T' }, { generic: 'N' }] },
  175. },
  176. ],
  177. kind: 'struct',
  178. },
  179. },
  180. {
  181. name: 'AccountData',
  182. type: {
  183. kind: 'enum',
  184. variants: [
  185. { name: 'Unknown' },
  186. {
  187. fields: [
  188. {
  189. defined: {
  190. generics: [
  191. { kind: 'const', value: '1000' },
  192. { kind: 'type', type: { defined: { name: 'VirtualTimelockAccount' } } },
  193. ],
  194. name: 'SimpleAllocator',
  195. },
  196. },
  197. ],
  198. name: 'Timelock',
  199. },
  200. {
  201. fields: [
  202. {
  203. defined: {
  204. generics: [
  205. { kind: 'const', value: '500' },
  206. { kind: 'type', type: { defined: { name: 'VirtualDurableNonce' } } },
  207. ],
  208. name: 'SimpleAllocator',
  209. },
  210. },
  211. ],
  212. name: 'Nonce',
  213. },
  214. {
  215. fields: [
  216. {
  217. defined: {
  218. generics: [
  219. { kind: 'const', value: '250' },
  220. { kind: 'type', type: { defined: { name: 'VirtualRelayAccount' } } },
  221. ],
  222. name: 'SimpleAllocator',
  223. },
  224. },
  225. ],
  226. name: 'Relay',
  227. },
  228. ],
  229. },
  230. },
  231. ],
  232. });
  233. expect(node).toEqual(
  234. programNode({
  235. definedTypes: [
  236. definedTypeNode({
  237. name: 'AccountData',
  238. type: enumTypeNode([
  239. enumEmptyVariantTypeNode('unknown'),
  240. enumTupleVariantTypeNode(
  241. 'timelock',
  242. tupleTypeNode([
  243. structTypeNode([
  244. structFieldTypeNode({
  245. name: 'state',
  246. type: arrayTypeNode(definedTypeLinkNode('itemState'), fixedCountNode(1000)),
  247. }),
  248. structFieldTypeNode({
  249. name: 'data',
  250. type: arrayTypeNode(
  251. definedTypeLinkNode('virtualTimelockAccount'),
  252. fixedCountNode(1000),
  253. ),
  254. }),
  255. ]),
  256. ]),
  257. ),
  258. enumTupleVariantTypeNode(
  259. 'nonce',
  260. tupleTypeNode([
  261. structTypeNode([
  262. structFieldTypeNode({
  263. name: 'state',
  264. type: arrayTypeNode(definedTypeLinkNode('itemState'), fixedCountNode(500)),
  265. }),
  266. structFieldTypeNode({
  267. name: 'data',
  268. type: arrayTypeNode(
  269. definedTypeLinkNode('virtualDurableNonce'),
  270. fixedCountNode(500),
  271. ),
  272. }),
  273. ]),
  274. ]),
  275. ),
  276. enumTupleVariantTypeNode(
  277. 'relay',
  278. tupleTypeNode([
  279. structTypeNode([
  280. structFieldTypeNode({
  281. name: 'state',
  282. type: arrayTypeNode(definedTypeLinkNode('itemState'), fixedCountNode(250)),
  283. }),
  284. structFieldTypeNode({
  285. name: 'data',
  286. type: arrayTypeNode(
  287. definedTypeLinkNode('virtualRelayAccount'),
  288. fixedCountNode(250),
  289. ),
  290. }),
  291. ]),
  292. ]),
  293. ),
  294. ]),
  295. }),
  296. ],
  297. name: 'myProgram',
  298. origin: 'anchor',
  299. pdas: [],
  300. publicKey: '1111',
  301. version: '1.2.3',
  302. }),
  303. );
  304. });