@wormhole-foundation/sdk-solana-ntt 0.5.2-beta.0 → 0.5.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 (225) hide show
  1. package/README.md +159 -0
  2. package/dist/cjs/ts/idl/1_0_0/json/dummy_transfer_hook.json +110 -0
  3. package/dist/{esm/anchor-idl → cjs/ts/idl/1_0_0/json}/example_native_token_transfers.json +48 -11
  4. package/dist/{esm/anchor-idl → cjs/ts/idl/1_0_0/json}/ntt_quoter.json +150 -7
  5. package/dist/cjs/{anchor-idl → ts/idl/1_0_0/json}/wormhole_governance.json +2 -5
  6. package/dist/cjs/ts/idl/1_0_0/ts/dummy_transfer_hook.d.ts +112 -0
  7. package/dist/cjs/ts/idl/1_0_0/ts/dummy_transfer_hook.d.ts.map +1 -0
  8. package/dist/cjs/ts/idl/1_0_0/ts/dummy_transfer_hook.js +114 -0
  9. package/dist/cjs/ts/idl/1_0_0/ts/dummy_transfer_hook.js.map +1 -0
  10. package/dist/cjs/{anchor-idl → ts/idl/1_0_0/ts}/example_native_token_transfers.d.ts +515 -565
  11. package/dist/cjs/ts/idl/1_0_0/ts/example_native_token_transfers.d.ts.map +1 -0
  12. package/dist/cjs/ts/idl/1_0_0/ts/example_native_token_transfers.js +1731 -0
  13. package/dist/cjs/ts/idl/1_0_0/ts/example_native_token_transfers.js.map +1 -0
  14. package/dist/cjs/ts/idl/1_0_0/ts/ntt_quoter.d.ts +590 -0
  15. package/dist/cjs/ts/idl/1_0_0/ts/ntt_quoter.d.ts.map +1 -0
  16. package/dist/cjs/ts/idl/1_0_0/ts/ntt_quoter.js +592 -0
  17. package/dist/cjs/ts/idl/1_0_0/ts/ntt_quoter.js.map +1 -0
  18. package/dist/cjs/ts/idl/1_0_0/ts/wormhole_governance.d.ts +70 -0
  19. package/dist/cjs/ts/idl/1_0_0/ts/wormhole_governance.d.ts.map +1 -0
  20. package/dist/cjs/ts/idl/1_0_0/ts/wormhole_governance.js +72 -0
  21. package/dist/cjs/ts/idl/1_0_0/ts/wormhole_governance.js.map +1 -0
  22. package/dist/cjs/ts/idl/2_0_0/json/dummy_transfer_hook.json +110 -0
  23. package/dist/cjs/ts/idl/2_0_0/json/example_native_token_transfers.json +1953 -0
  24. package/dist/cjs/{anchor-idl → ts/idl/2_0_0/json}/ntt_quoter.json +150 -7
  25. package/dist/cjs/ts/idl/2_0_0/json/wormhole_governance.json +76 -0
  26. package/dist/cjs/ts/idl/2_0_0/ts/dummy_transfer_hook.d.ts +112 -0
  27. package/dist/cjs/ts/idl/2_0_0/ts/dummy_transfer_hook.d.ts.map +1 -0
  28. package/dist/cjs/ts/idl/2_0_0/ts/dummy_transfer_hook.js +114 -0
  29. package/dist/cjs/ts/idl/2_0_0/ts/dummy_transfer_hook.js.map +1 -0
  30. package/dist/cjs/ts/idl/2_0_0/ts/example_native_token_transfers.d.ts +1955 -0
  31. package/dist/cjs/ts/idl/2_0_0/ts/example_native_token_transfers.d.ts.map +1 -0
  32. package/dist/cjs/ts/idl/2_0_0/ts/example_native_token_transfers.js +1957 -0
  33. package/dist/cjs/ts/idl/2_0_0/ts/example_native_token_transfers.js.map +1 -0
  34. package/dist/cjs/ts/idl/2_0_0/ts/ntt_quoter.d.ts +590 -0
  35. package/dist/cjs/ts/idl/2_0_0/ts/ntt_quoter.d.ts.map +1 -0
  36. package/dist/cjs/ts/idl/2_0_0/ts/ntt_quoter.js +592 -0
  37. package/dist/cjs/ts/idl/2_0_0/ts/ntt_quoter.js.map +1 -0
  38. package/dist/cjs/ts/idl/2_0_0/ts/wormhole_governance.d.ts +78 -0
  39. package/dist/cjs/ts/idl/2_0_0/ts/wormhole_governance.d.ts.map +1 -0
  40. package/dist/cjs/ts/idl/2_0_0/ts/wormhole_governance.js +80 -0
  41. package/dist/cjs/ts/idl/2_0_0/ts/wormhole_governance.js.map +1 -0
  42. package/dist/cjs/ts/index.d.ts +3 -0
  43. package/dist/cjs/ts/index.d.ts.map +1 -0
  44. package/dist/cjs/ts/index.js +19 -0
  45. package/dist/cjs/ts/index.js.map +1 -0
  46. package/dist/cjs/ts/lib/anchor-idl/1_0_0.d.ts +14 -0
  47. package/dist/cjs/ts/lib/anchor-idl/1_0_0.d.ts.map +1 -0
  48. package/dist/cjs/ts/lib/anchor-idl/1_0_0.js +11 -0
  49. package/dist/cjs/ts/lib/anchor-idl/1_0_0.js.map +1 -0
  50. package/dist/cjs/ts/lib/anchor-idl/2_0_0.d.ts +14 -0
  51. package/dist/cjs/ts/lib/anchor-idl/2_0_0.d.ts.map +1 -0
  52. package/dist/cjs/ts/lib/anchor-idl/2_0_0.js +11 -0
  53. package/dist/cjs/ts/lib/anchor-idl/2_0_0.js.map +1 -0
  54. package/dist/cjs/ts/lib/anchor-idl/index.d.ts +3 -0
  55. package/dist/cjs/ts/lib/anchor-idl/index.d.ts.map +1 -0
  56. package/dist/cjs/ts/lib/anchor-idl/index.js +19 -0
  57. package/dist/cjs/ts/lib/anchor-idl/index.js.map +1 -0
  58. package/dist/cjs/ts/lib/bindings.d.ts +22 -0
  59. package/dist/cjs/ts/lib/bindings.d.ts.map +1 -0
  60. package/dist/cjs/ts/lib/bindings.js +36 -0
  61. package/dist/cjs/ts/lib/bindings.js.map +1 -0
  62. package/dist/cjs/ts/lib/index.d.ts +5 -0
  63. package/dist/cjs/ts/lib/index.d.ts.map +1 -0
  64. package/dist/cjs/ts/lib/index.js +21 -0
  65. package/dist/cjs/ts/lib/index.js.map +1 -0
  66. package/dist/cjs/ts/lib/ntt.d.ts +162 -0
  67. package/dist/cjs/ts/lib/ntt.d.ts.map +1 -0
  68. package/dist/cjs/ts/lib/ntt.js +729 -0
  69. package/dist/cjs/ts/lib/ntt.js.map +1 -0
  70. package/dist/cjs/ts/lib/quoter.d.ts +54 -0
  71. package/dist/cjs/ts/lib/quoter.d.ts.map +1 -0
  72. package/dist/cjs/ts/lib/quoter.js +308 -0
  73. package/dist/cjs/ts/lib/quoter.js.map +1 -0
  74. package/dist/cjs/ts/lib/utils.d.ts +56 -0
  75. package/dist/cjs/ts/lib/utils.d.ts.map +1 -0
  76. package/dist/cjs/ts/lib/utils.js +91 -0
  77. package/dist/cjs/ts/lib/utils.js.map +1 -0
  78. package/dist/cjs/ts/sdk/index.d.ts +3 -0
  79. package/dist/cjs/ts/sdk/index.d.ts.map +1 -0
  80. package/dist/cjs/{index.js → ts/sdk/index.js} +3 -16
  81. package/dist/cjs/ts/sdk/index.js.map +1 -0
  82. package/dist/cjs/ts/sdk/ntt.d.ts +96 -0
  83. package/dist/cjs/ts/sdk/ntt.d.ts.map +1 -0
  84. package/dist/cjs/ts/sdk/ntt.js +635 -0
  85. package/dist/cjs/ts/sdk/ntt.js.map +1 -0
  86. package/dist/cjs/tsconfig.cjs.tsbuildinfo +1 -0
  87. package/dist/esm/ts/idl/1_0_0/json/dummy_transfer_hook.json +110 -0
  88. package/dist/{cjs/anchor-idl → esm/ts/idl/1_0_0/json}/example_native_token_transfers.json +48 -11
  89. package/dist/esm/ts/idl/1_0_0/json/ntt_quoter.json +588 -0
  90. package/dist/esm/{anchor-idl → ts/idl/1_0_0/json}/wormhole_governance.json +2 -5
  91. package/dist/esm/ts/idl/1_0_0/ts/dummy_transfer_hook.d.ts +112 -0
  92. package/dist/esm/ts/idl/1_0_0/ts/dummy_transfer_hook.d.ts.map +1 -0
  93. package/dist/esm/ts/idl/1_0_0/ts/dummy_transfer_hook.js +111 -0
  94. package/dist/esm/ts/idl/1_0_0/ts/dummy_transfer_hook.js.map +1 -0
  95. package/dist/esm/{anchor-idl → ts/idl/1_0_0/ts}/example_native_token_transfers.d.ts +515 -565
  96. package/dist/esm/ts/idl/1_0_0/ts/example_native_token_transfers.d.ts.map +1 -0
  97. package/dist/esm/ts/idl/1_0_0/ts/example_native_token_transfers.js +1728 -0
  98. package/dist/esm/ts/idl/1_0_0/ts/example_native_token_transfers.js.map +1 -0
  99. package/dist/esm/ts/idl/1_0_0/ts/ntt_quoter.d.ts +590 -0
  100. package/dist/esm/ts/idl/1_0_0/ts/ntt_quoter.d.ts.map +1 -0
  101. package/dist/esm/ts/idl/1_0_0/ts/ntt_quoter.js +589 -0
  102. package/dist/esm/ts/idl/1_0_0/ts/ntt_quoter.js.map +1 -0
  103. package/dist/esm/ts/idl/1_0_0/ts/wormhole_governance.d.ts +70 -0
  104. package/dist/esm/ts/idl/1_0_0/ts/wormhole_governance.d.ts.map +1 -0
  105. package/dist/esm/ts/idl/1_0_0/ts/wormhole_governance.js +69 -0
  106. package/dist/esm/ts/idl/1_0_0/ts/wormhole_governance.js.map +1 -0
  107. package/dist/esm/ts/idl/2_0_0/json/dummy_transfer_hook.json +110 -0
  108. package/dist/esm/ts/idl/2_0_0/json/example_native_token_transfers.json +1953 -0
  109. package/dist/esm/ts/idl/2_0_0/json/ntt_quoter.json +588 -0
  110. package/dist/esm/ts/idl/2_0_0/json/wormhole_governance.json +76 -0
  111. package/dist/esm/ts/idl/2_0_0/ts/dummy_transfer_hook.d.ts +112 -0
  112. package/dist/esm/ts/idl/2_0_0/ts/dummy_transfer_hook.d.ts.map +1 -0
  113. package/dist/esm/ts/idl/2_0_0/ts/dummy_transfer_hook.js +111 -0
  114. package/dist/esm/ts/idl/2_0_0/ts/dummy_transfer_hook.js.map +1 -0
  115. package/dist/esm/ts/idl/2_0_0/ts/example_native_token_transfers.d.ts +1955 -0
  116. package/dist/esm/ts/idl/2_0_0/ts/example_native_token_transfers.d.ts.map +1 -0
  117. package/dist/esm/ts/idl/2_0_0/ts/example_native_token_transfers.js +1954 -0
  118. package/dist/esm/ts/idl/2_0_0/ts/example_native_token_transfers.js.map +1 -0
  119. package/dist/esm/ts/idl/2_0_0/ts/ntt_quoter.d.ts +590 -0
  120. package/dist/esm/ts/idl/2_0_0/ts/ntt_quoter.d.ts.map +1 -0
  121. package/dist/esm/ts/idl/2_0_0/ts/ntt_quoter.js +589 -0
  122. package/dist/esm/ts/idl/2_0_0/ts/ntt_quoter.js.map +1 -0
  123. package/dist/esm/ts/idl/2_0_0/ts/wormhole_governance.d.ts +78 -0
  124. package/dist/esm/ts/idl/2_0_0/ts/wormhole_governance.d.ts.map +1 -0
  125. package/dist/esm/ts/idl/2_0_0/ts/wormhole_governance.js +77 -0
  126. package/dist/esm/ts/idl/2_0_0/ts/wormhole_governance.js.map +1 -0
  127. package/dist/esm/ts/index.d.ts +3 -0
  128. package/dist/esm/ts/index.d.ts.map +1 -0
  129. package/dist/esm/ts/index.js +3 -0
  130. package/dist/esm/ts/index.js.map +1 -0
  131. package/dist/esm/ts/lib/anchor-idl/1_0_0.d.ts +14 -0
  132. package/dist/esm/ts/lib/anchor-idl/1_0_0.d.ts.map +1 -0
  133. package/dist/esm/ts/lib/anchor-idl/1_0_0.js +8 -0
  134. package/dist/esm/ts/lib/anchor-idl/1_0_0.js.map +1 -0
  135. package/dist/esm/ts/lib/anchor-idl/2_0_0.d.ts +14 -0
  136. package/dist/esm/ts/lib/anchor-idl/2_0_0.d.ts.map +1 -0
  137. package/dist/esm/ts/lib/anchor-idl/2_0_0.js +8 -0
  138. package/dist/esm/ts/lib/anchor-idl/2_0_0.js.map +1 -0
  139. package/dist/esm/ts/lib/anchor-idl/index.d.ts +3 -0
  140. package/dist/esm/ts/lib/anchor-idl/index.d.ts.map +1 -0
  141. package/dist/esm/ts/lib/anchor-idl/index.js +3 -0
  142. package/dist/esm/ts/lib/anchor-idl/index.js.map +1 -0
  143. package/dist/esm/ts/lib/bindings.d.ts +22 -0
  144. package/dist/esm/ts/lib/bindings.d.ts.map +1 -0
  145. package/dist/esm/ts/lib/bindings.js +31 -0
  146. package/dist/esm/ts/lib/bindings.js.map +1 -0
  147. package/dist/esm/ts/lib/index.d.ts +5 -0
  148. package/dist/esm/ts/lib/index.d.ts.map +1 -0
  149. package/dist/esm/ts/lib/index.js +5 -0
  150. package/dist/esm/ts/lib/index.js.map +1 -0
  151. package/dist/esm/ts/lib/ntt.d.ts +162 -0
  152. package/dist/esm/ts/lib/ntt.d.ts.map +1 -0
  153. package/dist/esm/ts/lib/ntt.js +703 -0
  154. package/dist/esm/ts/lib/ntt.js.map +1 -0
  155. package/dist/esm/ts/lib/quoter.d.ts +54 -0
  156. package/dist/esm/ts/lib/quoter.d.ts.map +1 -0
  157. package/dist/esm/ts/lib/quoter.js +301 -0
  158. package/dist/esm/ts/lib/quoter.js.map +1 -0
  159. package/dist/esm/ts/lib/utils.d.ts +56 -0
  160. package/dist/esm/ts/lib/utils.d.ts.map +1 -0
  161. package/dist/esm/ts/lib/utils.js +83 -0
  162. package/dist/esm/ts/lib/utils.js.map +1 -0
  163. package/dist/esm/ts/sdk/index.d.ts +3 -0
  164. package/dist/esm/ts/sdk/index.d.ts.map +1 -0
  165. package/dist/esm/ts/sdk/index.js +7 -0
  166. package/dist/esm/ts/sdk/index.js.map +1 -0
  167. package/dist/esm/ts/sdk/ntt.d.ts +96 -0
  168. package/dist/esm/ts/sdk/ntt.d.ts.map +1 -0
  169. package/dist/esm/ts/sdk/ntt.js +604 -0
  170. package/dist/esm/ts/sdk/ntt.js.map +1 -0
  171. package/dist/esm/tsconfig.esm.tsbuildinfo +1 -0
  172. package/package.json +32 -24
  173. package/dist/cjs/anchor-idl/example_native_token_transfers.d.ts.map +0 -1
  174. package/dist/cjs/anchor-idl/example_native_token_transfers.js +0 -3
  175. package/dist/cjs/anchor-idl/example_native_token_transfers.js.map +0 -1
  176. package/dist/cjs/anchor-idl/index.d.ts +0 -327
  177. package/dist/cjs/anchor-idl/index.d.ts.map +0 -1
  178. package/dist/cjs/anchor-idl/index.js +0 -14
  179. package/dist/cjs/anchor-idl/index.js.map +0 -1
  180. package/dist/cjs/anchor-idl/ntt_quoter.d.ts +0 -443
  181. package/dist/cjs/anchor-idl/ntt_quoter.d.ts.map +0 -1
  182. package/dist/cjs/anchor-idl/ntt_quoter.js +0 -3
  183. package/dist/cjs/anchor-idl/ntt_quoter.js.map +0 -1
  184. package/dist/cjs/anchor-idl/wormhole_governance.d.ts +0 -69
  185. package/dist/cjs/anchor-idl/wormhole_governance.d.ts.map +0 -1
  186. package/dist/cjs/anchor-idl/wormhole_governance.js +0 -3
  187. package/dist/cjs/anchor-idl/wormhole_governance.js.map +0 -1
  188. package/dist/cjs/index.d.ts +0 -3
  189. package/dist/cjs/index.d.ts.map +0 -1
  190. package/dist/cjs/index.js.map +0 -1
  191. package/dist/cjs/ntt.d.ts +0 -82
  192. package/dist/cjs/ntt.d.ts.map +0 -1
  193. package/dist/cjs/ntt.js +0 -385
  194. package/dist/cjs/ntt.js.map +0 -1
  195. package/dist/cjs/utils.d.ts +0 -29
  196. package/dist/cjs/utils.d.ts.map +0 -1
  197. package/dist/cjs/utils.js +0 -46
  198. package/dist/cjs/utils.js.map +0 -1
  199. package/dist/esm/anchor-idl/example_native_token_transfers.d.ts.map +0 -1
  200. package/dist/esm/anchor-idl/example_native_token_transfers.js +0 -2
  201. package/dist/esm/anchor-idl/example_native_token_transfers.js.map +0 -1
  202. package/dist/esm/anchor-idl/index.d.ts +0 -327
  203. package/dist/esm/anchor-idl/index.d.ts.map +0 -1
  204. package/dist/esm/anchor-idl/index.js +0 -8
  205. package/dist/esm/anchor-idl/index.js.map +0 -1
  206. package/dist/esm/anchor-idl/ntt_quoter.d.ts +0 -443
  207. package/dist/esm/anchor-idl/ntt_quoter.d.ts.map +0 -1
  208. package/dist/esm/anchor-idl/ntt_quoter.js +0 -2
  209. package/dist/esm/anchor-idl/ntt_quoter.js.map +0 -1
  210. package/dist/esm/anchor-idl/wormhole_governance.d.ts +0 -69
  211. package/dist/esm/anchor-idl/wormhole_governance.d.ts.map +0 -1
  212. package/dist/esm/anchor-idl/wormhole_governance.js +0 -2
  213. package/dist/esm/anchor-idl/wormhole_governance.js.map +0 -1
  214. package/dist/esm/index.d.ts +0 -3
  215. package/dist/esm/index.d.ts.map +0 -1
  216. package/dist/esm/index.js +0 -7
  217. package/dist/esm/index.js.map +0 -1
  218. package/dist/esm/ntt.d.ts +0 -82
  219. package/dist/esm/ntt.d.ts.map +0 -1
  220. package/dist/esm/ntt.js +0 -353
  221. package/dist/esm/ntt.js.map +0 -1
  222. package/dist/esm/utils.d.ts +0 -29
  223. package/dist/esm/utils.d.ts.map +0 -1
  224. package/dist/esm/utils.js +0 -41
  225. package/dist/esm/utils.js.map +0 -1
package/README.md ADDED
@@ -0,0 +1,159 @@
1
+ # Solana
2
+
3
+ ## Prequisities
4
+
5
+ Ensure that you are using the correct version of the Solana and Anchor CLI tools by consulting `Anchor.toml`.
6
+
7
+ ```toml
8
+ [toolchain]
9
+ anchor_version = "0.29.0" # CLI
10
+ solana_version = "1.18.10"
11
+ ```
12
+
13
+ You will also need to install the toolchain listed in `rust-toolchain`. You can verify this by running:
14
+
15
+ ```sh
16
+ rustup show
17
+ ```
18
+
19
+ ## Design Overview
20
+
21
+ ### Message Lifecycle (Solana)
22
+
23
+ 1. **Transfer**
24
+
25
+ A client calls the [transfer_lock] or [transfer_burn] instruction based on whether the program is in "locking" or "burning" mode. The program mode is set during initialization. When transferring, the client must specify the amount of the transfer, the recipient chain, the recipient address on the recipient chain, and the boolean flag `should_queue` to specify whether the transfer should be queued if it hits the outbound rate limit. If `should_queue` is set to false, the transfer reverts instead of queuing if the rate limit were to be hit.
26
+
27
+ > Using the wrong transfer instruction, i.e. [`transfer_lock`] for a program that is in "burning" mode, will result in `InvalidMode` error.
28
+
29
+ Depending on the mode and instruction, the following will be produced in the program logs:
30
+
31
+ ```
32
+ Program log: Instruction: TransferLock
33
+ Program log: Instruction: TransferBurn
34
+ ```
35
+
36
+ Outbound transfers are always added into an Outbox via the `insert_into_outbox` method. This method checks the transfer against the configured outbound rate limit amount to determine whether the transfer should be rate limited. An `OutboxItem` is a Solana Account which holds details of the outbound transfer. If no rate limit is hit, the transfer can be released from the Outbox immediately. If a rate limit is hit, the transfer can only be released from the Outbox after the rate limit delay duration has expired.
37
+
38
+ 2. **Rate Limit**
39
+
40
+ The program checks rate limits via the `consume_or_delay` function during the transfer process. The Solana rate limiting logic is equivalent to the EVM rate limiting logic.
41
+
42
+ If the transfer amount fits within the current capacity:
43
+
44
+ - Reduce the current capacity
45
+ - Refill the inbound capacity for the destination chain
46
+ - Add the transfer to the outbox with `release_timestamp` set to the current timestamp, so it can be released immediately.
47
+
48
+ If the transfer amount does not fit within the current capacity:
49
+
50
+ - If `shouldQueue = true`, add the transfer to the outbox with `release_timestamp` set to the current timestamp plus the configured `RATE_LIMIT_DURATION`.
51
+ - If `shouldQueue = false`, revert with a `TransferExceedsRateLimit` error
52
+
53
+ 3. **Send**
54
+
55
+ The caller then needs to request each Transceiver to send messages via the [`release_outbound`] instruction. To execute this instruction, the caller needs to pass the account of the Outbox item to be released. The instruction will then verify that the Transceiver is one of the specified senders for the message. Transceivers then send the messages based on the verification backend they are using.
56
+
57
+ For example, the Wormhole Transceiver will send by calling [`post_message`] on the Wormhole program, so that the Wormhole Guardians can observe and verify the message.
58
+
59
+ > When `revert_on_delay` is true, the transaction will revert if the release timestamp has not been reached. When `revert_on_delay` is false, the transaction succeeds, but the outbound release is not performed.
60
+
61
+ The following will be produced in the program logs:
62
+
63
+ ```
64
+ Program log: Instruction: ReleaseOutbound
65
+ ```
66
+
67
+ 4. **Receive**
68
+
69
+ Similar to EVM, Transceivers vary in how they receive messages, since message relaying and verification methods may differ between implementations.
70
+
71
+ The Wormhole Transceiver receives a verified Wormhole message on Solana via the [`receive_message`] entrypoint instruction. Callers can use the [`receive_wormhole_message`] Anchor library function to execute this instruction. The instruction verifies the Wormhole VAA and stores it in a `VerifiedTransceiverMessage` account.
72
+
73
+ The following will be produced in the program logs:
74
+
75
+ ```
76
+ Program log: Instruction: ReceiveMessage
77
+ ```
78
+
79
+ [`redeem`] checks the inbound rate limit and places the message in an Inbox. Logic works the same as the outbound rate limit we mentioned previously.
80
+
81
+ The following will be produced in the program logs:
82
+
83
+ ```
84
+ Program log: Instruction: Redeem
85
+ ```
86
+
87
+ 5. **Mint or Unlock**
88
+
89
+ The inbound transfer is released and the tokens are unlocked or minted to the recipient (depending on the mode) through either [`release_inbound_mint`] (if the mode is `burning`) or [`release_inbound_unlock`] (if the mode is `locking`). Similar to transfer, using the wrong transfer instruction, i.e. [`release_inbound_mint`] for a program that is in "locking" mode, will result in `InvalidMode` error.
90
+
91
+ > When `revert_on_delay` is true, the transaction will revert if the release timestamp has not been reached. When `revert_on_delay` is false, the transaction succeeds, but the minting/unlocking is not performed.
92
+
93
+ Depending on the mode and instruction, the following will be produced in the program logs:
94
+
95
+ ```
96
+ Program log: Instruction: ReleaseInboundMint
97
+ Program log: Instruction: ReleaseInboundUnlock
98
+ ```
99
+
100
+ ## Message Customization
101
+
102
+ See the [NttManager](../docs/NttManager.md) doc for wire format details.
103
+
104
+ ### NativeTokenTransfer Additional Payload
105
+
106
+ Modify [transfer.rs](./programs/example-native-token-transfers/src/transfer.rs) and replace the `EmptyPayload` with your own custom struct. See [ntt.rs](./modules/ntt-messages/src/ntt.rs) for an example. It is highly encouraged to use a 4-byte prefix for your payload.
107
+
108
+ The additional payload field should then have your custom struct available everywhere `NativeTokenTransfer<Payload>` is used. Due to typing, parsing, and account allocation restrictions, this implementation expects that _all_ `NativeTokenTransfer` payloads for your contract adhere to your custom struct definition.
109
+
110
+ You can then modify [release_outbound](./programs/example-native-token-transfers/src/transceivers/wormhole/instructions/release_outbound.rs) and [redeem](./programs/example-native-token-transfers/src/instructions/redeem.rs) to generate and process the additional payload.
111
+
112
+ ## Testing
113
+
114
+ The test files are loacated in the `sdk/solana/__tests__/` directory
115
+
116
+ In order to run them, the Solana programs must be built and their IDL made available to the SDK.
117
+
118
+ To ensure the SDK has the generated IDL, run the tests with the make command:
119
+
120
+ ```sh
121
+ make test
122
+ ```
123
+
124
+ ### Troubleshooting
125
+
126
+ <details>
127
+ <summary><code>make: *** No rule to make target `test'. Stop.</code></summary>
128
+
129
+ - Ensure `Makefile` has target `test`
130
+ </details>
131
+
132
+ <details>
133
+ <summary><code>tsx: command not found</code></summary>
134
+
135
+ - Screenshot:
136
+ <img src="images/tsx-command-not-found.png" alt="tsx command not found screenshot">
137
+ - Update `Makefile` ([line #29](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/solana/Makefile#L29)) from:
138
+
139
+ ```sh
140
+ tsx scripts/regenerateIdl.ts $$jsonfile > $$tsfile; \
141
+ ```
142
+
143
+ to:
144
+
145
+ ```sh
146
+ npx tsx scripts/regenerateIdl.ts $$jsonfile > $$tsfile; \
147
+ ```
148
+
149
+ </details>
150
+
151
+ <details>
152
+ <summary><code>Lifecycle script `build:esm` failed with error</code></summary>
153
+
154
+ - Screenshot:
155
+ <img src="images/lifecycle-script.png" alt="lifecycle script screenshot">
156
+ - This occurs due to Typescript files failing compilation.
157
+ - [`patch-idl` script](https://github.com/wormhole-foundation/example-native-token-transfers/blob/main/solana/scripts/patch-idl) requires [`jq`](https://jqlang.github.io/jq/) to be installed. Install `jq` and retry.
158
+
159
+ </details>
@@ -0,0 +1,110 @@
1
+ {
2
+ "version": "2.0.0",
3
+ "name": "dummy_transfer_hook",
4
+ "instructions": [
5
+ {
6
+ "name": "initializeExtraAccountMetaList",
7
+ "accounts": [
8
+ {
9
+ "name": "payer",
10
+ "isMut": true,
11
+ "isSigner": true
12
+ },
13
+ {
14
+ "name": "extraAccountMetaList",
15
+ "isMut": true,
16
+ "isSigner": false
17
+ },
18
+ {
19
+ "name": "mint",
20
+ "isMut": false,
21
+ "isSigner": false
22
+ },
23
+ {
24
+ "name": "tokenProgram",
25
+ "isMut": false,
26
+ "isSigner": false
27
+ },
28
+ {
29
+ "name": "associatedTokenProgram",
30
+ "isMut": false,
31
+ "isSigner": false
32
+ },
33
+ {
34
+ "name": "counter",
35
+ "isMut": true,
36
+ "isSigner": false
37
+ },
38
+ {
39
+ "name": "systemProgram",
40
+ "isMut": false,
41
+ "isSigner": false
42
+ }
43
+ ],
44
+ "args": []
45
+ },
46
+ {
47
+ "name": "transferHook",
48
+ "accounts": [
49
+ {
50
+ "name": "sourceToken",
51
+ "isMut": false,
52
+ "isSigner": false
53
+ },
54
+ {
55
+ "name": "mint",
56
+ "isMut": false,
57
+ "isSigner": false
58
+ },
59
+ {
60
+ "name": "destinationToken",
61
+ "isMut": false,
62
+ "isSigner": false
63
+ },
64
+ {
65
+ "name": "authority",
66
+ "isMut": false,
67
+ "isSigner": false
68
+ },
69
+ {
70
+ "name": "extraAccountMetaList",
71
+ "isMut": false,
72
+ "isSigner": false
73
+ },
74
+ {
75
+ "name": "dummyAccount",
76
+ "isMut": false,
77
+ "isSigner": false,
78
+ "docs": [
79
+ "computes and the on-chain code correctly passes on the PDA."
80
+ ]
81
+ },
82
+ {
83
+ "name": "counter",
84
+ "isMut": true,
85
+ "isSigner": false
86
+ }
87
+ ],
88
+ "args": [
89
+ {
90
+ "name": "amount",
91
+ "type": "u64"
92
+ }
93
+ ]
94
+ }
95
+ ],
96
+ "accounts": [
97
+ {
98
+ "name": "Counter",
99
+ "type": {
100
+ "kind": "struct",
101
+ "fields": [
102
+ {
103
+ "name": "count",
104
+ "type": "u64"
105
+ }
106
+ ]
107
+ }
108
+ }
109
+ ]
110
+ }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.0",
2
+ "version": "1.0.0",
3
3
  "name": "example_native_token_transfers",
4
4
  "instructions": [
5
5
  {
@@ -47,7 +47,8 @@
47
47
  "docs": [
48
48
  "The custody account that holds tokens in locking mode.",
49
49
  "NOTE: the account is unconditionally initialized, but not used in",
50
- "burning mode."
50
+ "burning mode.",
51
+ "function if the token account has already been created."
51
52
  ]
52
53
  },
53
54
  {
@@ -83,6 +84,12 @@
83
84
  }
84
85
  ]
85
86
  },
87
+ {
88
+ "name": "version",
89
+ "accounts": [],
90
+ "args": [],
91
+ "returns": "string"
92
+ },
86
93
  {
87
94
  "name": "transferBurn",
88
95
  "accounts": [
@@ -292,7 +299,13 @@
292
299
  "This is because in a multi-transceiver configuration, the different",
293
300
  "transceivers \"vote\" on messages (by delivering them). By making the inbox",
294
301
  "items content-addressed, we can ensure that disagreeing votes don't",
295
- "interfere with each other."
302
+ "interfere with each other.",
303
+ "On the first call to [`redeem()`], [`InboxItem`] will be allocated and initialized with",
304
+ "default values.",
305
+ "On subsequent calls, we want to modify the `InboxItem` by \"voting\" on it. Therefore the",
306
+ "program should not fail which would occur when using the `init` constraint.",
307
+ "The [`InboxItem::init`] field is used to guard against malicious or accidental modification",
308
+ "InboxItem fields that should remain constant."
296
309
  ]
297
310
  },
298
311
  {
@@ -778,7 +791,7 @@
778
791
  },
779
792
  {
780
793
  "name": "emitter",
781
- "isMut": true,
794
+ "isMut": false,
782
795
  "isSigner": false
783
796
  },
784
797
  {
@@ -856,7 +869,7 @@
856
869
  },
857
870
  {
858
871
  "name": "emitter",
859
- "isMut": true,
872
+ "isMut": false,
860
873
  "isSigner": false
861
874
  },
862
875
  {
@@ -927,7 +940,7 @@
927
940
  },
928
941
  {
929
942
  "name": "emitter",
930
- "isMut": true,
943
+ "isMut": false,
931
944
  "isSigner": false
932
945
  },
933
946
  {
@@ -1062,7 +1075,8 @@
1062
1075
  {
1063
1076
  "name": "enabledTransceivers",
1064
1077
  "docs": [
1065
- "Bitmap of enabled transceivers"
1078
+ "Bitmap of enabled transceivers.",
1079
+ "The maximum number of transceivers is equal to [`Bitmap::BITS`]."
1066
1080
  ],
1067
1081
  "type": {
1068
1082
  "defined": "Bitmap"
@@ -1464,6 +1478,12 @@
1464
1478
  },
1465
1479
  {
1466
1480
  "name": "ReleaseStatus",
1481
+ "docs": [
1482
+ "The status of an InboxItem. This determines whether the tokens are minted/unlocked to the recipient. As",
1483
+ "such, this must be used as a state machine that moves forward in a linear manner. A state",
1484
+ "should never \"move backward\" to a previous state (e.g. should never move from `Released` to",
1485
+ "`ReleaseAfter`)."
1486
+ ],
1467
1487
  "type": {
1468
1488
  "kind": "enum",
1469
1489
  "variants": [
@@ -1725,9 +1745,26 @@
1725
1745
  "code": 6018,
1726
1746
  "name": "BadAmountAfterBurn",
1727
1747
  "msg": "BadAmountAfterBurn"
1748
+ },
1749
+ {
1750
+ "code": 6019,
1751
+ "name": "ZeroThreshold",
1752
+ "msg": "ZeroThreshold"
1753
+ },
1754
+ {
1755
+ "code": 6020,
1756
+ "name": "OverflowExponent",
1757
+ "msg": "OverflowExponent"
1758
+ },
1759
+ {
1760
+ "code": 6021,
1761
+ "name": "OverflowScaledAmount",
1762
+ "msg": "OverflowScaledAmount"
1763
+ },
1764
+ {
1765
+ "code": 6022,
1766
+ "name": "BitmapIndexOutOfBounds",
1767
+ "msg": "BitmapIndexOutOfBounds"
1728
1768
  }
1729
- ],
1730
- "metadata": {
1731
- "address": "nttiK1SepaQt6sZ4WGW5whvc9tEnGXGxuKeptcQPCcS"
1732
- }
1769
+ ]
1733
1770
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.0",
2
+ "version": "2.0.0",
3
3
  "name": "ntt_quoter",
4
4
  "instructions": [
5
5
  {
@@ -21,10 +21,18 @@
21
21
  "isSigner": false
22
22
  },
23
23
  {
24
- "name": "outboxItem",
24
+ "name": "registeredNtt",
25
25
  "isMut": false,
26
26
  "isSigner": false
27
27
  },
28
+ {
29
+ "name": "outboxItem",
30
+ "isMut": false,
31
+ "isSigner": false,
32
+ "docs": [
33
+ "and checking the release constraint into a single function"
34
+ ]
35
+ },
28
36
  {
29
37
  "name": "relayRequest",
30
38
  "isMut": true,
@@ -188,17 +196,83 @@
188
196
  ]
189
197
  },
190
198
  {
191
- "name": "updateSolPrice",
199
+ "name": "registerNtt",
192
200
  "accounts": [
193
201
  {
194
202
  "name": "authority",
203
+ "isMut": true,
204
+ "isSigner": true
205
+ },
206
+ {
207
+ "name": "instance",
195
208
  "isMut": false,
209
+ "isSigner": false
210
+ },
211
+ {
212
+ "name": "registeredNtt",
213
+ "isMut": true,
214
+ "isSigner": false
215
+ },
216
+ {
217
+ "name": "systemProgram",
218
+ "isMut": false,
219
+ "isSigner": false
220
+ }
221
+ ],
222
+ "args": [
223
+ {
224
+ "name": "args",
225
+ "type": {
226
+ "defined": "RegisterNttArgs"
227
+ }
228
+ }
229
+ ]
230
+ },
231
+ {
232
+ "name": "deregisterNtt",
233
+ "accounts": [
234
+ {
235
+ "name": "authority",
236
+ "isMut": true,
196
237
  "isSigner": true
197
238
  },
198
239
  {
199
240
  "name": "instance",
200
241
  "isMut": false,
201
242
  "isSigner": false
243
+ },
244
+ {
245
+ "name": "registeredNtt",
246
+ "isMut": true,
247
+ "isSigner": false
248
+ },
249
+ {
250
+ "name": "systemProgram",
251
+ "isMut": false,
252
+ "isSigner": false
253
+ }
254
+ ],
255
+ "args": [
256
+ {
257
+ "name": "args",
258
+ "type": {
259
+ "defined": "DeregisterNttArgs"
260
+ }
261
+ }
262
+ ]
263
+ },
264
+ {
265
+ "name": "updateSolPrice",
266
+ "accounts": [
267
+ {
268
+ "name": "authority",
269
+ "isMut": false,
270
+ "isSigner": true
271
+ },
272
+ {
273
+ "name": "instance",
274
+ "isMut": true,
275
+ "isSigner": false
202
276
  }
203
277
  ],
204
278
  "args": [
@@ -320,6 +394,26 @@
320
394
  ]
321
395
  }
322
396
  },
397
+ {
398
+ "name": "RegisteredNtt",
399
+ "type": {
400
+ "kind": "struct",
401
+ "fields": [
402
+ {
403
+ "name": "bump",
404
+ "type": "u8"
405
+ },
406
+ {
407
+ "name": "wormholeTransceiverIndex",
408
+ "type": "u8"
409
+ },
410
+ {
411
+ "name": "gasCost",
412
+ "type": "u32"
413
+ }
414
+ ]
415
+ }
416
+ },
323
417
  {
324
418
  "name": "RelayRequest",
325
419
  "type": {
@@ -346,6 +440,38 @@
346
440
  ]
347
441
  }
348
442
  },
443
+ {
444
+ "name": "RegisterNttArgs",
445
+ "type": {
446
+ "kind": "struct",
447
+ "fields": [
448
+ {
449
+ "name": "nttProgramId",
450
+ "type": "publicKey"
451
+ },
452
+ {
453
+ "name": "wormholeTransceiverIndex",
454
+ "type": "u8"
455
+ },
456
+ {
457
+ "name": "gasCost",
458
+ "type": "u32"
459
+ }
460
+ ]
461
+ }
462
+ },
463
+ {
464
+ "name": "DeregisterNttArgs",
465
+ "type": {
466
+ "kind": "struct",
467
+ "fields": [
468
+ {
469
+ "name": "nttProgramId",
470
+ "type": "publicKey"
471
+ }
472
+ ]
473
+ }
474
+ },
349
475
  {
350
476
  "name": "RequestRelayArgs",
351
477
  "type": {
@@ -428,6 +554,21 @@
428
554
  "name": "RelayingToChainDisabled",
429
555
  "msg": "Relaying to the specified chain is disabled"
430
556
  },
557
+ {
558
+ "code": 6005,
559
+ "name": "OutboxItemNotReleased",
560
+ "msg": "Relaying to the specified chain is disabled"
561
+ },
562
+ {
563
+ "code": 6006,
564
+ "name": "ScalingOverflow",
565
+ "msg": "Scaled value exceeds u64::MAX"
566
+ },
567
+ {
568
+ "code": 6007,
569
+ "name": "DivByZero",
570
+ "msg": "Cannot divide by zero"
571
+ },
431
572
  {
432
573
  "code": 6257,
433
574
  "name": "FeeRecipientCannotBeDefault",
@@ -437,9 +578,11 @@
437
578
  "code": 6258,
438
579
  "name": "NotAuthorized",
439
580
  "msg": "Must be owner or assistant"
581
+ },
582
+ {
583
+ "code": 6259,
584
+ "name": "PriceCannotBeZero",
585
+ "msg": "The price cannot be zero"
440
586
  }
441
- ],
442
- "metadata": {
443
- "address": "9jFBLvMZZERVmeY4tbq5MejbXRE18paGEuoB6xVJZgGe"
444
- }
587
+ ]
445
588
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.0",
2
+ "version": "1.0.0",
3
3
  "name": "wormhole_governance",
4
4
  "instructions": [
5
5
  {
@@ -64,8 +64,5 @@
64
64
  "name": "InvalidGovernanceEmitter",
65
65
  "msg": "InvalidGovernanceEmitter"
66
66
  }
67
- ],
68
- "metadata": {
69
- "address": "wgvEiKVzX9yyEoh41jZAdC6JqGUTS4CFXbFGBV5TKdZ"
70
- }
67
+ ]
71
68
  }