@layerzerolabs/lz-iotal1-sdk-v2 3.0.143

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 (279) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +19 -0
  3. package/deployments/iotal1-mainnet/blocked_message_lib.json +58 -0
  4. package/deployments/iotal1-mainnet/blocked_msglib_ptb_builder.json +58 -0
  5. package/deployments/iotal1-mainnet/call.json +46 -0
  6. package/deployments/iotal1-mainnet/counter.json +85 -0
  7. package/deployments/iotal1-mainnet/dvn.json +49 -0
  8. package/deployments/iotal1-mainnet/dvn_call_type.json +45 -0
  9. package/deployments/iotal1-mainnet/dvn_fee_lib.json +59 -0
  10. package/deployments/iotal1-mainnet/dvn_layerzero.json +56 -0
  11. package/deployments/iotal1-mainnet/dvn_ptb_builder.json +45 -0
  12. package/deployments/iotal1-mainnet/endpoint_ptb_builder.json +70 -0
  13. package/deployments/iotal1-mainnet/endpoint_v2.json +86 -0
  14. package/deployments/iotal1-mainnet/executor.json +49 -0
  15. package/deployments/iotal1-mainnet/executor_call_type.json +45 -0
  16. package/deployments/iotal1-mainnet/executor_fee_lib.json +60 -0
  17. package/deployments/iotal1-mainnet/executor_layerzero.json +56 -0
  18. package/deployments/iotal1-mainnet/executor_ptb_builder.json +45 -0
  19. package/deployments/iotal1-mainnet/layerzero_views.json +46 -0
  20. package/deployments/iotal1-mainnet/message_lib_common.json +47 -0
  21. package/deployments/iotal1-mainnet/msglib_ptb_builder_call_types.json +45 -0
  22. package/deployments/iotal1-mainnet/multi_call.json +45 -0
  23. package/deployments/iotal1-mainnet/oapp.json +50 -0
  24. package/deployments/iotal1-mainnet/object-BlockedMessageLib.json +9 -0
  25. package/deployments/iotal1-mainnet/object-BlockedMsglibPtbBuilder.json +9 -0
  26. package/deployments/iotal1-mainnet/object-Counter.json +9 -0
  27. package/deployments/iotal1-mainnet/object-CounterAdminCap.json +9 -0
  28. package/deployments/iotal1-mainnet/object-CounterOApp.json +9 -0
  29. package/deployments/iotal1-mainnet/object-DVN.json +5 -0
  30. package/deployments/iotal1-mainnet/object-DVNCap.json +9 -0
  31. package/deployments/iotal1-mainnet/object-DVNFeeLib.json +9 -0
  32. package/deployments/iotal1-mainnet/object-EndpointPtbBuilder.json +9 -0
  33. package/deployments/iotal1-mainnet/object-EndpointPtbBuilderAdminCap.json +9 -0
  34. package/deployments/iotal1-mainnet/object-EndpointV2.json +9 -0
  35. package/deployments/iotal1-mainnet/object-EndpointV2AdminCap.json +9 -0
  36. package/deployments/iotal1-mainnet/object-Executor.json +5 -0
  37. package/deployments/iotal1-mainnet/object-ExecutorCap.json +9 -0
  38. package/deployments/iotal1-mainnet/object-ExecutorFeeLib.json +9 -0
  39. package/deployments/iotal1-mainnet/object-ExecutorOwnerCap.json +5 -0
  40. package/deployments/iotal1-mainnet/object-OFTComposerManager.json +9 -0
  41. package/deployments/iotal1-mainnet/object-PackageWhitelistValidator.json +9 -0
  42. package/deployments/iotal1-mainnet/object-PriceFeed.json +9 -0
  43. package/deployments/iotal1-mainnet/object-PriceFeedOwnerCap.json +9 -0
  44. package/deployments/iotal1-mainnet/object-SimpleMessageLib.json +9 -0
  45. package/deployments/iotal1-mainnet/object-SimpleMessageLibAdminCap.json +9 -0
  46. package/deployments/iotal1-mainnet/object-SmlPtbBuilder.json +9 -0
  47. package/deployments/iotal1-mainnet/object-Treasury.json +9 -0
  48. package/deployments/iotal1-mainnet/object-TreasuryAdminCap.json +9 -0
  49. package/deployments/iotal1-mainnet/object-ULN302.json +9 -0
  50. package/deployments/iotal1-mainnet/object-ULN302AdminCap.json +9 -0
  51. package/deployments/iotal1-mainnet/object-Uln302PtbBuilder.json +9 -0
  52. package/deployments/iotal1-mainnet/object-Uln302Verification.json +9 -0
  53. package/deployments/iotal1-mainnet/object-WorkerRegistry.json +9 -0
  54. package/deployments/iotal1-mainnet/object-ZroCoinMetadata.json +9 -0
  55. package/deployments/iotal1-mainnet/object-ZroTreasuryCap.json +9 -0
  56. package/deployments/iotal1-mainnet/oft_common.json +61 -0
  57. package/deployments/iotal1-mainnet/package_whitelist_validator.json +113 -0
  58. package/deployments/iotal1-mainnet/price_feed.json +70 -0
  59. package/deployments/iotal1-mainnet/price_feed_call_types.json +45 -0
  60. package/deployments/iotal1-mainnet/ptb_move_call.json +48 -0
  61. package/deployments/iotal1-mainnet/simple_message_lib.json +69 -0
  62. package/deployments/iotal1-mainnet/simple_msglib_ptb_builder.json +58 -0
  63. package/deployments/iotal1-mainnet/treasury.json +69 -0
  64. package/deployments/iotal1-mainnet/uln_302.json +87 -0
  65. package/deployments/iotal1-mainnet/uln_302_ptb_builder.json +58 -0
  66. package/deployments/iotal1-mainnet/uln_common.json +49 -0
  67. package/deployments/iotal1-mainnet/utils.json +57 -0
  68. package/deployments/iotal1-mainnet/worker_common.json +46 -0
  69. package/deployments/iotal1-mainnet/worker_registry.json +58 -0
  70. package/deployments/iotal1-mainnet/zro.json +67 -0
  71. package/deployments/iotal1-sandbox-local/blocked_message_lib.json +58 -0
  72. package/deployments/iotal1-sandbox-local/blocked_msglib_ptb_builder.json +58 -0
  73. package/deployments/iotal1-sandbox-local/call.json +46 -0
  74. package/deployments/iotal1-sandbox-local/counter.json +148 -0
  75. package/deployments/iotal1-sandbox-local/dvn.json +49 -0
  76. package/deployments/iotal1-sandbox-local/dvn_call_type.json +73 -0
  77. package/deployments/iotal1-sandbox-local/dvn_fee_lib.json +59 -0
  78. package/deployments/iotal1-sandbox-local/dvn_layerzero.json +56 -0
  79. package/deployments/iotal1-sandbox-local/dvn_ptb_builder.json +45 -0
  80. package/deployments/iotal1-sandbox-local/endpoint_ptb_builder.json +70 -0
  81. package/deployments/iotal1-sandbox-local/endpoint_v2.json +86 -0
  82. package/deployments/iotal1-sandbox-local/executor.json +49 -0
  83. package/deployments/iotal1-sandbox-local/executor_call_type.json +73 -0
  84. package/deployments/iotal1-sandbox-local/executor_fee_lib.json +60 -0
  85. package/deployments/iotal1-sandbox-local/executor_layerzero.json +56 -0
  86. package/deployments/iotal1-sandbox-local/executor_ptb_builder.json +45 -0
  87. package/deployments/iotal1-sandbox-local/layerzero_views.json +46 -0
  88. package/deployments/iotal1-sandbox-local/message_lib_common.json +47 -0
  89. package/deployments/iotal1-sandbox-local/msglib_ptb_builder_call_types.json +45 -0
  90. package/deployments/iotal1-sandbox-local/multi_call.json +45 -0
  91. package/deployments/iotal1-sandbox-local/oapp.json +50 -0
  92. package/deployments/iotal1-sandbox-local/object-BlockedMessageLib.json +9 -0
  93. package/deployments/iotal1-sandbox-local/object-BlockedMsglibPtbBuilder.json +9 -0
  94. package/deployments/iotal1-sandbox-local/object-Counter.json +9 -0
  95. package/deployments/iotal1-sandbox-local/object-CounterAdminCap.json +9 -0
  96. package/deployments/iotal1-sandbox-local/object-CounterOApp.json +9 -0
  97. package/deployments/iotal1-sandbox-local/object-DVN.json +5 -0
  98. package/deployments/iotal1-sandbox-local/object-DVNCap.json +9 -0
  99. package/deployments/iotal1-sandbox-local/object-DVNFeeLib.json +9 -0
  100. package/deployments/iotal1-sandbox-local/object-EndpointPtbBuilder.json +9 -0
  101. package/deployments/iotal1-sandbox-local/object-EndpointPtbBuilderAdminCap.json +9 -0
  102. package/deployments/iotal1-sandbox-local/object-EndpointV2.json +9 -0
  103. package/deployments/iotal1-sandbox-local/object-EndpointV2AdminCap.json +9 -0
  104. package/deployments/iotal1-sandbox-local/object-Executor.json +5 -0
  105. package/deployments/iotal1-sandbox-local/object-ExecutorCap.json +9 -0
  106. package/deployments/iotal1-sandbox-local/object-ExecutorFeeLib.json +9 -0
  107. package/deployments/iotal1-sandbox-local/object-ExecutorOwnerCap.json +5 -0
  108. package/deployments/iotal1-sandbox-local/object-PackageWhitelistValidator.json +9 -0
  109. package/deployments/iotal1-sandbox-local/object-PriceFeed.json +9 -0
  110. package/deployments/iotal1-sandbox-local/object-PriceFeedOwnerCap.json +9 -0
  111. package/deployments/iotal1-sandbox-local/object-SimpleMessageLib.json +9 -0
  112. package/deployments/iotal1-sandbox-local/object-SimpleMessageLibAdminCap.json +9 -0
  113. package/deployments/iotal1-sandbox-local/object-SmlPtbBuilder.json +9 -0
  114. package/deployments/iotal1-sandbox-local/object-Treasury.json +9 -0
  115. package/deployments/iotal1-sandbox-local/object-TreasuryAdminCap.json +9 -0
  116. package/deployments/iotal1-sandbox-local/object-ULN302.json +9 -0
  117. package/deployments/iotal1-sandbox-local/object-ULN302AdminCap.json +9 -0
  118. package/deployments/iotal1-sandbox-local/object-Uln302PtbBuilder.json +9 -0
  119. package/deployments/iotal1-sandbox-local/object-Uln302Verification.json +9 -0
  120. package/deployments/iotal1-sandbox-local/object-WorkerRegistry.json +9 -0
  121. package/deployments/iotal1-sandbox-local/object-ZroCoinMetadata.json +9 -0
  122. package/deployments/iotal1-sandbox-local/object-ZroTreasuryCap.json +9 -0
  123. package/deployments/iotal1-sandbox-local/package_whitelist_validator.json +113 -0
  124. package/deployments/iotal1-sandbox-local/price_feed.json +98 -0
  125. package/deployments/iotal1-sandbox-local/price_feed_call_types.json +45 -0
  126. package/deployments/iotal1-sandbox-local/ptb_move_call.json +48 -0
  127. package/deployments/iotal1-sandbox-local/simple_message_lib.json +69 -0
  128. package/deployments/iotal1-sandbox-local/simple_msglib_ptb_builder.json +58 -0
  129. package/deployments/iotal1-sandbox-local/treasury.json +97 -0
  130. package/deployments/iotal1-sandbox-local/uln_302.json +87 -0
  131. package/deployments/iotal1-sandbox-local/uln_302_ptb_builder.json +58 -0
  132. package/deployments/iotal1-sandbox-local/uln_common.json +49 -0
  133. package/deployments/iotal1-sandbox-local/utils.json +78 -0
  134. package/deployments/iotal1-sandbox-local/worker_common.json +46 -0
  135. package/deployments/iotal1-sandbox-local/worker_registry.json +58 -0
  136. package/deployments/iotal1-sandbox-local/zro.json +67 -0
  137. package/deployments/iotal1-testnet/blocked_message_lib.json +58 -0
  138. package/deployments/iotal1-testnet/blocked_msglib_ptb_builder.json +58 -0
  139. package/deployments/iotal1-testnet/call.json +46 -0
  140. package/deployments/iotal1-testnet/counter.json +85 -0
  141. package/deployments/iotal1-testnet/dvn.json +49 -0
  142. package/deployments/iotal1-testnet/dvn_call_type.json +45 -0
  143. package/deployments/iotal1-testnet/dvn_fee_lib.json +59 -0
  144. package/deployments/iotal1-testnet/dvn_layerzero.json +56 -0
  145. package/deployments/iotal1-testnet/dvn_ptb_builder.json +45 -0
  146. package/deployments/iotal1-testnet/endpoint_ptb_builder.json +70 -0
  147. package/deployments/iotal1-testnet/endpoint_v2.json +86 -0
  148. package/deployments/iotal1-testnet/executor.json +49 -0
  149. package/deployments/iotal1-testnet/executor_call_type.json +45 -0
  150. package/deployments/iotal1-testnet/executor_fee_lib.json +60 -0
  151. package/deployments/iotal1-testnet/executor_layerzero.json +56 -0
  152. package/deployments/iotal1-testnet/executor_ptb_builder.json +45 -0
  153. package/deployments/iotal1-testnet/layerzero_views.json +46 -0
  154. package/deployments/iotal1-testnet/message_lib_common.json +47 -0
  155. package/deployments/iotal1-testnet/msglib_ptb_builder_call_types.json +45 -0
  156. package/deployments/iotal1-testnet/multi_call.json +45 -0
  157. package/deployments/iotal1-testnet/oapp.json +50 -0
  158. package/deployments/iotal1-testnet/object-BlockedMessageLib.json +9 -0
  159. package/deployments/iotal1-testnet/object-BlockedMsglibPtbBuilder.json +9 -0
  160. package/deployments/iotal1-testnet/object-Counter.json +9 -0
  161. package/deployments/iotal1-testnet/object-CounterAdminCap.json +9 -0
  162. package/deployments/iotal1-testnet/object-CounterOApp.json +9 -0
  163. package/deployments/iotal1-testnet/object-DVN.json +5 -0
  164. package/deployments/iotal1-testnet/object-DVNCap.json +9 -0
  165. package/deployments/iotal1-testnet/object-DVNFeeLib.json +9 -0
  166. package/deployments/iotal1-testnet/object-EndpointPtbBuilder.json +9 -0
  167. package/deployments/iotal1-testnet/object-EndpointPtbBuilderAdminCap.json +9 -0
  168. package/deployments/iotal1-testnet/object-EndpointV2.json +9 -0
  169. package/deployments/iotal1-testnet/object-EndpointV2AdminCap.json +9 -0
  170. package/deployments/iotal1-testnet/object-Executor.json +5 -0
  171. package/deployments/iotal1-testnet/object-ExecutorCap.json +9 -0
  172. package/deployments/iotal1-testnet/object-ExecutorFeeLib.json +9 -0
  173. package/deployments/iotal1-testnet/object-ExecutorOwnerCap.json +5 -0
  174. package/deployments/iotal1-testnet/object-PackageWhitelistValidator.json +9 -0
  175. package/deployments/iotal1-testnet/object-PriceFeed.json +9 -0
  176. package/deployments/iotal1-testnet/object-PriceFeedOwnerCap.json +9 -0
  177. package/deployments/iotal1-testnet/object-SimpleMessageLib.json +9 -0
  178. package/deployments/iotal1-testnet/object-SimpleMessageLibAdminCap.json +9 -0
  179. package/deployments/iotal1-testnet/object-SmlPtbBuilder.json +9 -0
  180. package/deployments/iotal1-testnet/object-Treasury.json +9 -0
  181. package/deployments/iotal1-testnet/object-TreasuryAdminCap.json +9 -0
  182. package/deployments/iotal1-testnet/object-ULN302.json +9 -0
  183. package/deployments/iotal1-testnet/object-ULN302AdminCap.json +9 -0
  184. package/deployments/iotal1-testnet/object-Uln302PtbBuilder.json +9 -0
  185. package/deployments/iotal1-testnet/object-Uln302Verification.json +9 -0
  186. package/deployments/iotal1-testnet/object-WorkerRegistry.json +9 -0
  187. package/deployments/iotal1-testnet/object-ZroCoinMetadata.json +9 -0
  188. package/deployments/iotal1-testnet/object-ZroTreasuryCap.json +9 -0
  189. package/deployments/iotal1-testnet/package_whitelist_validator.json +113 -0
  190. package/deployments/iotal1-testnet/price_feed.json +70 -0
  191. package/deployments/iotal1-testnet/price_feed_call_types.json +45 -0
  192. package/deployments/iotal1-testnet/ptb_move_call.json +48 -0
  193. package/deployments/iotal1-testnet/simple_message_lib.json +69 -0
  194. package/deployments/iotal1-testnet/simple_msglib_ptb_builder.json +58 -0
  195. package/deployments/iotal1-testnet/treasury.json +69 -0
  196. package/deployments/iotal1-testnet/uln_302.json +87 -0
  197. package/deployments/iotal1-testnet/uln_302_ptb_builder.json +58 -0
  198. package/deployments/iotal1-testnet/uln_common.json +49 -0
  199. package/deployments/iotal1-testnet/utils.json +57 -0
  200. package/deployments/iotal1-testnet/worker_common.json +46 -0
  201. package/deployments/iotal1-testnet/worker_registry.json +58 -0
  202. package/deployments/iotal1-testnet/zro.json +67 -0
  203. package/dist/index.cjs +11279 -0
  204. package/dist/index.cjs.map +1 -0
  205. package/dist/index.d.mts +5824 -0
  206. package/dist/index.d.ts +5824 -0
  207. package/dist/index.mjs +11107 -0
  208. package/dist/index.mjs.map +1 -0
  209. package/package.json +68 -0
  210. package/src/bcs/dvn.ts +7 -0
  211. package/src/bcs/endpoint.ts +7 -0
  212. package/src/bcs/executor.ts +27 -0
  213. package/src/bcs/index.ts +8 -0
  214. package/src/bcs/messaging-fee.ts +6 -0
  215. package/src/bcs/move-call.ts +28 -0
  216. package/src/bcs/oapp.ts +14 -0
  217. package/src/bcs/price-feed.ts +21 -0
  218. package/src/bcs/uln.ts +15 -0
  219. package/src/generated/addresses.ts +344 -0
  220. package/src/index.ts +5 -0
  221. package/src/module-manager.ts +360 -0
  222. package/src/modules/call.ts +245 -0
  223. package/src/modules/endpoint.ts +2417 -0
  224. package/src/modules/index.ts +10 -0
  225. package/src/modules/layerzero-views.ts +205 -0
  226. package/src/modules/message-libs/blocked-message-lib.ts +112 -0
  227. package/src/modules/message-libs/index.ts +4 -0
  228. package/src/modules/message-libs/simple-message-lib.ts +270 -0
  229. package/src/modules/message-libs/uln302.ts +827 -0
  230. package/src/modules/oapps/counter.ts +458 -0
  231. package/src/modules/oapps/index.ts +3 -0
  232. package/src/modules/oapps/oapp.ts +744 -0
  233. package/src/modules/ptb-builders/blocked-message-lib-ptb-builder.ts +49 -0
  234. package/src/modules/ptb-builders/dvn-ptb-builder.ts +58 -0
  235. package/src/modules/ptb-builders/endpoint-ptb-builder.ts +520 -0
  236. package/src/modules/ptb-builders/executor-ptb-builder.ts +58 -0
  237. package/src/modules/ptb-builders/index.ts +9 -0
  238. package/src/modules/ptb-builders/package-whitelist-validator.ts +142 -0
  239. package/src/modules/ptb-builders/ptb-builder.ts +357 -0
  240. package/src/modules/ptb-builders/simple-message-lib-ptb-builder.ts +53 -0
  241. package/src/modules/ptb-builders/uln302-ptb-builder.ts +222 -0
  242. package/src/modules/utils.ts +902 -0
  243. package/src/modules/workers/dvn-fee-lib.ts +89 -0
  244. package/src/modules/workers/dvn-layerzero.ts +85 -0
  245. package/src/modules/workers/dvn.ts +1727 -0
  246. package/src/modules/workers/executor-fee-lib.ts +94 -0
  247. package/src/modules/workers/executor-layerzero.ts +79 -0
  248. package/src/modules/workers/executor.ts +1170 -0
  249. package/src/modules/workers/index.ts +10 -0
  250. package/src/modules/workers/price-feed.ts +575 -0
  251. package/src/modules/workers/treasury.ts +295 -0
  252. package/src/modules/workers/worker-registry.ts +110 -0
  253. package/src/modules/zro.ts +94 -0
  254. package/src/resource.ts +104 -0
  255. package/src/sdk.ts +183 -0
  256. package/src/types/dvn.ts +20 -0
  257. package/src/types/endpoint.ts +16 -0
  258. package/src/types/errors.ts +10 -0
  259. package/src/types/executor.ts +23 -0
  260. package/src/types/index.ts +13 -0
  261. package/src/types/layerzero-views.ts +59 -0
  262. package/src/types/message-lib.ts +38 -0
  263. package/src/types/modules.ts +36 -0
  264. package/src/types/move-types.ts +24 -0
  265. package/src/types/oapp.ts +6 -0
  266. package/src/types/options.ts +333 -0
  267. package/src/types/price-feed.ts +21 -0
  268. package/src/types/ptb-builder.ts +29 -0
  269. package/src/types/simulation.ts +8 -0
  270. package/src/utils/argument.ts +198 -0
  271. package/src/utils/index.ts +8 -0
  272. package/src/utils/move-call-object-fetcher.ts +105 -0
  273. package/src/utils/non-sender-object-validator.ts +102 -0
  274. package/src/utils/package-allowlist-validator.ts +134 -0
  275. package/src/utils/ptb-validator.ts +14 -0
  276. package/src/utils/share-object-validator.ts +37 -0
  277. package/src/utils/transaction.ts +157 -0
  278. package/src/utils/type-name.ts +99 -0
  279. package/src/utils/validate-with-details.ts +50 -0
@@ -0,0 +1,102 @@
1
+ import { ObjectOwner } from '@iota/iota-sdk/client'
2
+
3
+ import { MoveCallWithObjectDetails } from './move-call-object-fetcher'
4
+ import { IPTBValidator } from './ptb-validator'
5
+
6
+ /**
7
+ * NonSenderObjectValidator ensures objects are not owned by the transaction sender
8
+ *
9
+ * In Iota, this validator checks that objects are:
10
+ * - Shared: globally accessible, mutations require consensus
11
+ * - Immutable: can't change after creation
12
+ * - Owned by another address (not the sender)
13
+ *
14
+ * This prevents the sender from using their own owned objects in the transaction
15
+ */
16
+ export class NonSenderObjectValidator implements IPTBValidator {
17
+ private sender: string
18
+
19
+ constructor(sender: string) {
20
+ this.sender = sender
21
+ }
22
+
23
+ /**
24
+ * Validates that objects are not owned by the sender
25
+ * @param moveCallsWithDetails - Array of move calls with object details
26
+ * @throws Error if any object is owned by the sender
27
+ */
28
+ validate(moveCallsWithDetails: MoveCallWithObjectDetails[]): void {
29
+ for (const { objectDetails } of moveCallsWithDetails) {
30
+ for (const [objectId, objectResponse] of objectDetails) {
31
+ const owner = objectResponse.data?.owner
32
+ if (owner == null) {
33
+ throw new Error(`Object ${objectId} has no owner`)
34
+ }
35
+ // Validate that object is not owned by the sender
36
+ if (!this.isValidOwnership(owner)) {
37
+ const ownerType = this.getOwnershipType(owner)
38
+ throw new Error(
39
+ `Object ${objectId} is owned by the sender (${this.sender}). ` +
40
+ `Only Shared, Immutable, or objects owned by other addresses are allowed. ` +
41
+ `Current ownership: ${ownerType}`
42
+ )
43
+ }
44
+ }
45
+ }
46
+ }
47
+
48
+ /**
49
+ * Checks if the ownership is valid (not owned by sender)
50
+ * @param owner - The object owner to check
51
+ * @returns true if ownership is valid (Shared, Immutable, or owned by another address)
52
+ */
53
+ private isValidOwnership(owner: ObjectOwner): boolean {
54
+ // Shared objects are valid
55
+ if (typeof owner === 'object' && 'Shared' in owner) {
56
+ return true
57
+ }
58
+
59
+ // Immutable objects are valid
60
+ if (owner === 'Immutable') {
61
+ return true
62
+ }
63
+
64
+ // Objects owned by another address are valid
65
+ if (typeof owner === 'object' && 'AddressOwner' in owner && owner.AddressOwner !== this.sender) {
66
+ return true
67
+ }
68
+
69
+ // Objects owned by another object are valid
70
+ if (typeof owner === 'object' && 'ObjectOwner' in owner) {
71
+ return true
72
+ }
73
+
74
+ // If owned by sender, it's invalid
75
+ return false
76
+ }
77
+
78
+ /**
79
+ * Gets a human-readable description of the ownership type
80
+ * @param owner - The object owner
81
+ * @returns String description of ownership type
82
+ */
83
+ private getOwnershipType(owner: ObjectOwner): string {
84
+ if (typeof owner === 'object' && 'Shared' in owner) {
85
+ return `Shared (initial_shared_version: ${owner.Shared.initial_shared_version})`
86
+ }
87
+
88
+ if (owner === 'Immutable') {
89
+ return 'Immutable'
90
+ }
91
+
92
+ if (typeof owner === 'object' && 'AddressOwner' in owner) {
93
+ return `AddressOwner: ${owner.AddressOwner}`
94
+ }
95
+
96
+ if (typeof owner === 'object' && 'ObjectOwner' in owner) {
97
+ return `ObjectOwner: ${owner.ObjectOwner}`
98
+ }
99
+
100
+ return 'Unknown ownership type'
101
+ }
102
+ }
@@ -0,0 +1,134 @@
1
+ import { MoveCallWithObjectDetails } from './move-call-object-fetcher'
2
+ import { IPTBValidator } from './ptb-validator'
3
+ import { PackageWhitelistValidator as PackageWhitelistSDK } from '../modules/ptb-builders/package-whitelist-validator'
4
+
5
+ /**
6
+ * PackageAllowlistValidator ensures all function calls and objects belong to allowlisted packages
7
+ * This validator checks that:
8
+ * 1. All function calls target approved packages
9
+ * 2. All object arguments come from approved packages
10
+ *
11
+ * If local packageWhitelist is empty, it will use the PTB whitelist contract for validation
12
+ * If local packageWhitelist is provided, it will use only the local whitelist (contract is ignored)
13
+ */
14
+ export class PackageAllowlistValidator implements IPTBValidator {
15
+ private packageWhitelist: Set<string>
16
+ private validator?: PackageWhitelistSDK
17
+
18
+ constructor(packageWhitelist: string[] = [], validator?: PackageWhitelistSDK) {
19
+ if (packageWhitelist.length == 0 && validator == null) {
20
+ throw new Error('PackageAllowlistValidator requires either a packageWhitelist or a validator')
21
+ }
22
+ this.packageWhitelist = new Set(packageWhitelist)
23
+ this.validator = validator
24
+ }
25
+
26
+ /**
27
+ * Validates that all function calls and object arguments belong to whitelisted packages
28
+ * @param moveCallsWithDetails - Array of move calls with object details
29
+ * @throws Error if any function call or object belongs to a non-whitelisted package
30
+ */
31
+ async validate(moveCallsWithDetails: MoveCallWithObjectDetails[]): Promise<void> {
32
+ const allPackages = new Set<string>()
33
+
34
+ // Collect packages from function calls
35
+ for (const { moveCall } of moveCallsWithDetails) {
36
+ const packageId = moveCall.function.package
37
+ if (packageId === '') {
38
+ throw new Error('Move call package is missing')
39
+ }
40
+ allPackages.add(packageId)
41
+ }
42
+
43
+ // Collect packages from objects
44
+ for (const { objectDetails } of moveCallsWithDetails) {
45
+ for (const [objectId, objectResponse] of objectDetails) {
46
+ if (!objectResponse.data) {
47
+ throw new Error(`Object ${objectId} not found`)
48
+ }
49
+
50
+ const packageId = this.extractPackageIdFromType(objectResponse.data.type)
51
+ if (packageId == null) {
52
+ throw new Error(`Could not extract package ID from object ${objectId}`)
53
+ }
54
+ allPackages.add(packageId)
55
+ }
56
+ }
57
+
58
+ // Validate all packages at once
59
+ const isAllValid = await this.validatePackages(Array.from(allPackages))
60
+ // Check result - if any package failed, throw error
61
+ if (!isAllValid) {
62
+ throw new Error(
63
+ `One or more packages are not allowlisted. Packages: [${Array.from(allPackages).join(', ')}]`
64
+ )
65
+ }
66
+ }
67
+
68
+ /**
69
+ * Validate multiple packages at once
70
+ * @param packages - Array of package IDs to validate
71
+ * @returns Object mapping package ID to validation result
72
+ */
73
+ private async validatePackages(packages: string[]): Promise<boolean> {
74
+ if (packages.length === 0) {
75
+ return true
76
+ }
77
+ // If custom whitelist is provided, use it first
78
+ if (this.packageWhitelist.size > 0) {
79
+ // Check if ALL packages are in whitelist - if any fails, return false
80
+ for (const packageId of packages) {
81
+ if (!this.packageWhitelist.has(packageId)) {
82
+ return false
83
+ }
84
+ }
85
+ return true
86
+ } else {
87
+ // Use the contract's validate function to validate all packages at once
88
+ try {
89
+ return await this.validator!.validate(packages)
90
+ } catch (error) {
91
+ console.warn(`Failed to check whitelist:`, error)
92
+ return false
93
+ }
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Extracts package ID from object type string
99
+ * Object types are in format: "packageId::module::struct<generics>"
100
+ * @param objectType - The object type string
101
+ * @returns The package ID or null if extraction fails
102
+ */
103
+ private extractPackageIdFromType(objectType: string | null | undefined): string | null {
104
+ if (objectType == null) {
105
+ return null
106
+ }
107
+
108
+ // Object type format: "0x123abc::module_name::struct_name<T1, T2>"
109
+ // We want to extract the package ID (0x123abc)
110
+ const parts = objectType.split('::')
111
+ if (parts.length < 2) {
112
+ return null
113
+ }
114
+
115
+ const packageId = parts[0]
116
+
117
+ // Validate that it looks like a package ID (starts with 0x and has hex characters)
118
+ if (!packageId.startsWith('0x') || packageId.length < 3) {
119
+ return null
120
+ }
121
+
122
+ return packageId
123
+ }
124
+
125
+ /**
126
+ * Get available packages for error messages
127
+ */
128
+ private getAvailablePackagesList(): string {
129
+ if (this.packageWhitelist.size > 0) {
130
+ return Array.from(this.packageWhitelist).join(', ')
131
+ }
132
+ return 'contract whitelist'
133
+ }
134
+ }
@@ -0,0 +1,14 @@
1
+ import { MoveCallWithObjectDetails } from './move-call-object-fetcher'
2
+
3
+ export interface ObjectFetchOptions {
4
+ showOwner?: boolean
5
+ showType?: boolean
6
+ showContent?: boolean
7
+ showBcs?: boolean
8
+ showDisplay?: boolean
9
+ showStorageRebate?: boolean
10
+ }
11
+
12
+ export interface IPTBValidator {
13
+ validate(moveCallsWithDetails: MoveCallWithObjectDetails[], sender?: string): void | Promise<void>
14
+ }
@@ -0,0 +1,37 @@
1
+ import { ObjectOwner } from '@iota/iota-sdk/client'
2
+
3
+ import { MoveCallWithObjectDetails } from './move-call-object-fetcher'
4
+ import { IPTBValidator } from './ptb-validator'
5
+
6
+ /**
7
+ * ShareObjectValidator ensures all object arguments are Shared or Immutable
8
+ * This is the default validator for PTB operations
9
+ */
10
+ export class ShareObjectValidator implements IPTBValidator {
11
+ /**
12
+ * Validates move calls with pre-fetched object details
13
+ * @param moveCallsWithDetails - Array of move calls with object details
14
+ * @throws Error if any object is not Shared/Immutable
15
+ */
16
+ validate(moveCallsWithDetails: MoveCallWithObjectDetails[]): void {
17
+ for (const { objectDetails } of moveCallsWithDetails) {
18
+ for (const [objectId, objectResponse] of objectDetails) {
19
+ if (objectResponse.data?.owner == null) {
20
+ throw new Error(`Object ${objectId} does not have owner`)
21
+ }
22
+ if (!this.isSharedOrImmutable(objectResponse.data.owner)) {
23
+ throw new Error(`Object ${objectId} is not Shared/Immutable`)
24
+ }
25
+ }
26
+ }
27
+ }
28
+
29
+ /**
30
+ * Checks if an object owner is Shared or Immutable
31
+ * @param owner - The object owner to check
32
+ * @returns true if the owner is Shared or Immutable, false otherwise
33
+ */
34
+ protected isSharedOrImmutable(owner: ObjectOwner): boolean {
35
+ return (typeof owner === 'object' && 'Shared' in owner) || owner === 'Immutable'
36
+ }
37
+ }
@@ -0,0 +1,157 @@
1
+ import { IotaClient, IotaExecutionResult, IotaTransactionBlockResponse } from '@iota/iota-sdk/client'
2
+ import { Keypair } from '@iota/iota-sdk/cryptography'
3
+ import { Ed25519Keypair } from '@iota/iota-sdk/keypairs/ed25519'
4
+ import { Transaction } from '@iota/iota-sdk/transactions'
5
+ import { fromBase64 } from '@iota/iota-sdk/utils'
6
+
7
+ import { MoveAbortError, SimulateResult, UnclassifiedError } from '../types'
8
+
9
+ export async function simulateTransaction(
10
+ iotaClient: IotaClient,
11
+ tx: Transaction,
12
+ sender?: string
13
+ ): Promise<SimulateResult[]> {
14
+ const resolvedSender = determineSenderAddress(tx, sender)
15
+ const { results, error } = await iotaClient.devInspectTransactionBlock({
16
+ transactionBlock: tx,
17
+ sender: resolvedSender,
18
+ })
19
+
20
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
21
+ if (error != undefined && error != null) {
22
+ throw handleError(error)
23
+ }
24
+ if (results === undefined || results === null) {
25
+ throw new Error('No results found')
26
+ }
27
+ const lastCommandResults: IotaExecutionResult = results[results.length - 1]
28
+
29
+ if (lastCommandResults.returnValues === undefined) {
30
+ throw new Error('No return values found')
31
+ }
32
+ return lastCommandResults.returnValues.map((result) => {
33
+ return {
34
+ value: typeof result[0] === 'string' ? fromBase64(result[0]) : new Uint8Array(result[0]),
35
+ type: result[1],
36
+ }
37
+ })
38
+ }
39
+
40
+ export async function simulateTransactionMultiResult(
41
+ iotaClient: IotaClient,
42
+ tx: Transaction,
43
+ resultIndex: number[],
44
+ sender?: string
45
+ ): Promise<SimulateResult[][]> {
46
+ const resolvedSender = determineSenderAddress(tx, sender)
47
+ const { results, error } = await iotaClient.devInspectTransactionBlock({
48
+ transactionBlock: tx,
49
+ sender: resolvedSender,
50
+ })
51
+
52
+ // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
53
+ if (error != undefined && error != null) {
54
+ throw handleError(error)
55
+ }
56
+ if (results === undefined || results === null) {
57
+ throw new Error('No results found')
58
+ }
59
+
60
+ const selectedResults: IotaExecutionResult[] = resultIndex.map((idx) => {
61
+ return results[idx]
62
+ })
63
+
64
+ return selectedResults.map((result) => {
65
+ if (result.returnValues === undefined) {
66
+ throw new Error('No return values found')
67
+ }
68
+ return result.returnValues.map((result) => {
69
+ return {
70
+ value: typeof result[0] === 'string' ? fromBase64(result[0]) : new Uint8Array(result[0]),
71
+ type: result[1],
72
+ }
73
+ })
74
+ })
75
+ }
76
+
77
+ export async function validateTransaction(
78
+ client: IotaClient,
79
+ signer: Keypair,
80
+ tx: Transaction
81
+ ): Promise<IotaTransactionBlockResponse> {
82
+ tx.setSenderIfNotSet(signer.getPublicKey().toIotaAddress())
83
+ const result = await client.signAndExecuteTransaction({
84
+ signer,
85
+ transaction: tx,
86
+ options: {
87
+ showEffects: true,
88
+ showObjectChanges: true,
89
+ showEvents: true,
90
+ },
91
+ })
92
+
93
+ if (result.effects?.status.status !== 'success') {
94
+ throw new Error(result.effects?.status.error)
95
+ }
96
+
97
+ await client.waitForTransaction({ digest: result.digest })
98
+ return result
99
+ }
100
+
101
+ /**
102
+ * Execute simulate using a moveCall function
103
+ * @param client - The Iota client
104
+ * @param moveCallFn - Function that adds moveCall to the transaction (supports both sync and async, any return type)
105
+ * @param parser - Function to parse the result
106
+ * @returns The parsed result
107
+ */
108
+ export async function executeSimulate<T>(
109
+ client: IotaClient,
110
+ moveCallFn: (tx: Transaction) => unknown,
111
+ parser: (result: { value: Uint8Array }[]) => T
112
+ ): Promise<T> {
113
+ const tx = new Transaction()
114
+ await moveCallFn(tx)
115
+ const result = await simulateTransaction(client, tx)
116
+ return parser(result)
117
+ }
118
+
119
+ /**
120
+ * Determines the appropriate sender address using fallback hierarchy:
121
+ * 1. Use provided sender if available
122
+ * 2. Use transaction's existing sender if valid
123
+ * 3. Generate a random sender as last resort
124
+ *
125
+ * @param tx - The transaction to get sender from
126
+ * @param preferredSender - Optional sender address to prioritize
127
+ * @returns The determined sender address
128
+ */
129
+ function determineSenderAddress(tx: Transaction, preferredSender?: string): string {
130
+ //eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
131
+ if (preferredSender) return preferredSender
132
+
133
+ const existingSender = tx.getData().sender
134
+ if (typeof existingSender === 'string') return existingSender
135
+
136
+ return Ed25519Keypair.generate().toIotaAddress()
137
+ }
138
+
139
+ export function handleError(e: string): unknown {
140
+ if (e.includes('ExecutionError')) {
141
+ const majorStatusMatch = e.match(/major_status:\s([A-Z_]+)/)
142
+ if (majorStatusMatch !== null) {
143
+ const major_status = majorStatusMatch[1]
144
+ if (major_status === 'ABORTED') {
145
+ const subStatusMatch = e.match(/sub_status:\sSome\((\d+)\)/)
146
+ if (subStatusMatch === null) {
147
+ return new MoveAbortError(Number.NEGATIVE_INFINITY, e)
148
+ } else {
149
+ return new MoveAbortError(Number(subStatusMatch[1]), e)
150
+ }
151
+ }
152
+ } else {
153
+ return new UnclassifiedError(e)
154
+ }
155
+ }
156
+ return new Error(e)
157
+ }
@@ -0,0 +1,99 @@
1
+ import sha3 from 'js-sha3'
2
+
3
+ import { ModuleManager } from '../module-manager'
4
+ import { CallTypeName, LzTypeName, Modules } from '../types'
5
+
6
+ // Predefined type names
7
+ const TYPE_CONFIG = {
8
+ [LzTypeName.EndpointQuoteParam]: { pkg: Modules.Endpoint, module: 'endpoint_quote', type: 'QuoteParam' },
9
+ [LzTypeName.EndpointSendParam]: { pkg: Modules.Endpoint, module: 'endpoint_send', type: 'SendParam' },
10
+ [LzTypeName.MessageLibQuoteParam]: { pkg: Modules.Endpoint, module: 'message_lib_quote', type: 'QuoteParam' },
11
+ [LzTypeName.MessageLibSendParam]: { pkg: Modules.Endpoint, module: 'message_lib_send', type: 'SendParam' },
12
+ [LzTypeName.MessageLibSendResult]: { pkg: Modules.Endpoint, module: 'message_lib_send', type: 'SendResult' },
13
+ [LzTypeName.MessageLibSetConfigParam]: {
14
+ pkg: Modules.Endpoint,
15
+ module: 'message_lib_set_config',
16
+ type: 'SetConfigParam',
17
+ },
18
+ [LzTypeName.MessagingFee]: { pkg: Modules.Endpoint, module: 'messaging_fee', type: 'MessagingFee' },
19
+ [LzTypeName.MessagingReceipt]: { pkg: Modules.Endpoint, module: 'messaging_receipt', type: 'MessagingReceipt' },
20
+ [LzTypeName.EndpointLzReceiveParam]: { pkg: Modules.Endpoint, module: 'lz_receive', type: 'LzReceiveParam' },
21
+ [LzTypeName.EndpointLzComposeParam]: { pkg: Modules.Endpoint, module: 'lz_compose', type: 'LzComposeParam' },
22
+ [LzTypeName.MoveCall]: { pkg: Modules.Call, module: 'move_call', type: 'MoveCall' },
23
+ [LzTypeName.CallVoid]: { pkg: Modules.Call, module: 'call', type: 'Void' },
24
+ } as const
25
+
26
+ // Call type configuration
27
+ const CALL_TYPE_CONFIG = {
28
+ [CallTypeName.EndpointQuoteCall]: { param: LzTypeName.EndpointQuoteParam, result: LzTypeName.MessagingFee },
29
+ [CallTypeName.EndpointSendCall]: { param: LzTypeName.EndpointSendParam, result: LzTypeName.MessagingReceipt },
30
+ [CallTypeName.MessageLibQuoteCall]: { param: LzTypeName.MessageLibQuoteParam, result: LzTypeName.MessagingFee },
31
+ [CallTypeName.MessageLibSendCall]: {
32
+ param: LzTypeName.MessageLibSendParam,
33
+ result: LzTypeName.MessageLibSendResult,
34
+ },
35
+ [CallTypeName.MessageLibSetConfigCall]: { param: LzTypeName.MessageLibSetConfigParam, result: LzTypeName.CallVoid },
36
+ [CallTypeName.EndpointLzReceiveCall]: { param: LzTypeName.EndpointLzReceiveParam, result: LzTypeName.CallVoid },
37
+ [CallTypeName.EndpointLzComposeCall]: { param: LzTypeName.EndpointLzComposeParam, result: LzTypeName.CallVoid },
38
+ } as const
39
+
40
+ export function getTypeName(moduleManager: ModuleManager, type: LzTypeName | CallTypeName): string {
41
+ // Handle simple types
42
+ if (type in TYPE_CONFIG) {
43
+ const config = TYPE_CONFIG[type as keyof typeof TYPE_CONFIG]
44
+ const { packageId } = moduleManager.getModule<{ packageId: string }>(config.pkg)
45
+ return buildTypeName(packageId, config.module, config.type)
46
+ }
47
+
48
+ // Handle Call types
49
+ if (type in CALL_TYPE_CONFIG) {
50
+ const callConfig = CALL_TYPE_CONFIG[type as keyof typeof CALL_TYPE_CONFIG]
51
+ const paramType = getTypeName(moduleManager, callConfig.param)
52
+ const resultType = getTypeName(moduleManager, callConfig.result)
53
+ return buildCallTypeName(moduleManager.getCall().packageId, paramType, resultType)
54
+ }
55
+
56
+ throw new Error(`Unknown type name: ${JSON.stringify(type)}`)
57
+ }
58
+
59
+ /**
60
+ * Normalizes a Iota package ID with configurable formatting options
61
+ * @param packageId - The package ID to normalize (with or without 0x prefix)
62
+ * @param includePrefix - Whether to include the '0x' prefix in the result (default: false)
63
+ * @param trimLeadingZeros - Whether to remove leading zeros (default: true)
64
+ * @returns The normalized package ID
65
+ *
66
+ * @example
67
+ * normalizeIotaPackageId('0x0001abc', false, true) // '1abc'
68
+ * normalizeIotaPackageId('0x0001abc', true, true) // '0x1abc'
69
+ * normalizeIotaPackageId('0x0001abc', true, false) // '0x0001abc'
70
+ */
71
+ export function normalizeIotaPackageId(packageId: string, includePrefix = false, trimLeadingZeros = false): string {
72
+ // Remove 0x prefix if present
73
+ let normalized = packageId.startsWith('0x') ? packageId.slice(2) : packageId
74
+
75
+ // Trim leading zeros if requested
76
+ if (trimLeadingZeros) {
77
+ // eslint-disable-next-line @typescript-eslint/strict-boolean-expressions
78
+ normalized = normalized.replace(/^0+/, '') || '0'
79
+ }
80
+
81
+ // Add prefix back if requested
82
+ return includePrefix ? `0x${normalized}` : normalized
83
+ }
84
+
85
+ export function callId(moduleManager: ModuleManager, type: CallTypeName): string {
86
+ return sha3.keccak_256(Buffer.from(getTypeName(moduleManager, type)))
87
+ }
88
+
89
+ // === Internal Functions ===
90
+
91
+ // Helper function: build basic type name
92
+ function buildTypeName(packageId: string, module: string, type: string): string {
93
+ return `${normalizeIotaPackageId(packageId)}::${module}::${type}`
94
+ }
95
+
96
+ // Helper function: build Call type name
97
+ function buildCallTypeName(packageId: string, paramType: string, resultType: string): string {
98
+ return `${normalizeIotaPackageId(packageId)}::call::Call<${paramType},${resultType}>`
99
+ }
@@ -0,0 +1,50 @@
1
+ import { IotaClient } from '@iota/iota-sdk/client'
2
+
3
+ import { MoveCallObjectFetcher } from './move-call-object-fetcher'
4
+ import { IPTBValidator, ObjectFetchOptions } from './ptb-validator'
5
+ import { MAX_BATCH_SIZE, MoveCall } from '../types'
6
+
7
+ /**
8
+ * Validates move calls using multiple validators with a single object fetch
9
+ * @param client - IotaClient instance
10
+ * @param moveCalls - Array of move calls to validate
11
+ * @param validators - Array of validators to run
12
+ * @param options - Options for what object data to fetch
13
+ * @param batchSize - Batch size for object fetching
14
+ */
15
+ export async function validateWithDetails(
16
+ client: IotaClient,
17
+ moveCalls: MoveCall[],
18
+ validators: IPTBValidator[],
19
+ sender?: string,
20
+ userOptions: ObjectFetchOptions = {},
21
+ batchSize: number = MAX_BATCH_SIZE
22
+ ): Promise<void> {
23
+ if (validators.length === 0) {
24
+ return // No validators to run
25
+ }
26
+
27
+ // Default to fetching all common options, user can override
28
+ const defaultOptions: ObjectFetchOptions = {
29
+ showOwner: true,
30
+ showType: true,
31
+ showContent: false,
32
+ showBcs: false,
33
+ showDisplay: false,
34
+ showStorageRebate: false,
35
+ }
36
+
37
+ // Merge user options with defaults (user options take precedence)
38
+ const finalOptions = { ...defaultOptions, ...userOptions }
39
+
40
+ // Fetch object details once
41
+ const objectFetcher = new MoveCallObjectFetcher(client, batchSize)
42
+ const moveCallsWithDetails = await objectFetcher.fetchObjectDetails(moveCalls, finalOptions)
43
+ // Run all validators with the same object details
44
+ for (const validator of validators) {
45
+ const result = validator.validate(moveCallsWithDetails, sender)
46
+ if (result instanceof Promise) {
47
+ await result
48
+ }
49
+ }
50
+ }