@layerzerolabs/oft-adapter-starknet 0.2.9

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 (82) hide show
  1. package/Scarb.lock +190 -0
  2. package/Scarb.toml +4 -0
  3. package/contracts/oft_adapter/Scarb.toml +30 -0
  4. package/contracts/oft_adapter/src/lib.cairo +1 -0
  5. package/contracts/oft_adapter/src/oft_adapter.cairo +150 -0
  6. package/contracts/oft_adapter/tests/constants.cairo +3 -0
  7. package/contracts/oft_adapter/tests/lib.cairo +11 -0
  8. package/contracts/oft_adapter/tests/mocks/erc20/erc20.cairo +49 -0
  9. package/contracts/oft_adapter/tests/mocks/erc20/interface.cairo +8 -0
  10. package/contracts/oft_adapter/tests/mocks/message_inspector/message_inspector.cairo +17 -0
  11. package/contracts/oft_adapter/tests/test_oft_adapter.cairo +579 -0
  12. package/dist/3UUTAAI4.js +9 -0
  13. package/dist/3UUTAAI4.js.map +1 -0
  14. package/dist/4VIL37TM.cjs +14 -0
  15. package/dist/4VIL37TM.cjs.map +1 -0
  16. package/dist/5AQVVHK2.cjs +17 -0
  17. package/dist/5AQVVHK2.cjs.map +1 -0
  18. package/dist/6JUHMRLN.js +14 -0
  19. package/dist/6JUHMRLN.js.map +1 -0
  20. package/dist/B3SWU5G3.cjs +990 -0
  21. package/dist/B3SWU5G3.cjs.map +1 -0
  22. package/dist/E63KEOR5.cjs +11 -0
  23. package/dist/E63KEOR5.cjs.map +1 -0
  24. package/dist/HRRTIIZM.cjs +1282 -0
  25. package/dist/HRRTIIZM.cjs.map +1 -0
  26. package/dist/HTWTY64L.js +14 -0
  27. package/dist/HTWTY64L.js.map +1 -0
  28. package/dist/IH3YG4QY.js +12 -0
  29. package/dist/IH3YG4QY.js.map +1 -0
  30. package/dist/JFLNUTE2.js +988 -0
  31. package/dist/JFLNUTE2.js.map +1 -0
  32. package/dist/JNHB3COG.cjs +14 -0
  33. package/dist/JNHB3COG.cjs.map +1 -0
  34. package/dist/KGI5KEFS.js +1280 -0
  35. package/dist/KGI5KEFS.js.map +1 -0
  36. package/dist/KRS32YQY.cjs +17 -0
  37. package/dist/KRS32YQY.cjs.map +1 -0
  38. package/dist/RU2XCZGW.js +12 -0
  39. package/dist/RU2XCZGW.js.map +1 -0
  40. package/dist/generated/abi/o-f-t-adapter.cjs +13 -0
  41. package/dist/generated/abi/o-f-t-adapter.cjs.map +1 -0
  42. package/dist/generated/abi/o-f-t-adapter.d.ts +722 -0
  43. package/dist/generated/abi/o-f-t-adapter.d.ts.map +1 -0
  44. package/dist/generated/abi/o-f-t-adapter.js +4 -0
  45. package/dist/generated/abi/o-f-t-adapter.js.map +1 -0
  46. package/dist/generated/abi.cjs +14 -0
  47. package/dist/generated/abi.cjs.map +1 -0
  48. package/dist/generated/abi.d.ts +2 -0
  49. package/dist/generated/abi.d.ts.map +1 -0
  50. package/dist/generated/abi.js +5 -0
  51. package/dist/generated/abi.js.map +1 -0
  52. package/dist/generated/casm.cjs +13 -0
  53. package/dist/generated/casm.cjs.map +1 -0
  54. package/dist/generated/casm.d.ts +2 -0
  55. package/dist/generated/casm.d.ts.map +1 -0
  56. package/dist/generated/casm.js +4 -0
  57. package/dist/generated/casm.js.map +1 -0
  58. package/dist/generated/sierra.cjs +13 -0
  59. package/dist/generated/sierra.cjs.map +1 -0
  60. package/dist/generated/sierra.d.ts +2 -0
  61. package/dist/generated/sierra.d.ts.map +1 -0
  62. package/dist/generated/sierra.js +4 -0
  63. package/dist/generated/sierra.js.map +1 -0
  64. package/dist/generated/verification/index.cjs +14 -0
  65. package/dist/generated/verification/index.cjs.map +1 -0
  66. package/dist/generated/verification/index.d.ts +2 -0
  67. package/dist/generated/verification/index.d.ts.map +1 -0
  68. package/dist/generated/verification/index.js +5 -0
  69. package/dist/generated/verification/index.js.map +1 -0
  70. package/dist/generated/verification/oft_adapter.cjs +10 -0
  71. package/dist/generated/verification/oft_adapter.cjs.map +1 -0
  72. package/dist/generated/verification/oft_adapter.d.ts +4 -0
  73. package/dist/generated/verification/oft_adapter.d.ts.map +1 -0
  74. package/dist/generated/verification/oft_adapter.js +4 -0
  75. package/dist/generated/verification/oft_adapter.js.map +1 -0
  76. package/dist/index.cjs +30 -0
  77. package/dist/index.cjs.map +1 -0
  78. package/dist/index.d.ts +5 -0
  79. package/dist/index.d.ts.map +1 -0
  80. package/dist/index.js +9 -0
  81. package/dist/index.js.map +1 -0
  82. package/package.json +53 -0
package/Scarb.lock ADDED
@@ -0,0 +1,190 @@
1
+ # Code generated by scarb DO NOT EDIT.
2
+ version = 1
3
+
4
+ [[package]]
5
+ name = "enumerable_set"
6
+ version = "0.1.0"
7
+
8
+ [[package]]
9
+ name = "layerzero"
10
+ version = "0.1.0"
11
+ dependencies = [
12
+ "enumerable_set",
13
+ "lz_utils",
14
+ "multisig",
15
+ "openzeppelin",
16
+ ]
17
+
18
+ [[package]]
19
+ name = "lz_utils"
20
+ version = "0.1.0"
21
+
22
+ [[package]]
23
+ name = "multisig"
24
+ version = "0.1.0"
25
+ dependencies = [
26
+ "enumerable_set",
27
+ "lz_utils",
28
+ ]
29
+
30
+ [[package]]
31
+ name = "oft_adapter"
32
+ version = "0.1.0"
33
+ dependencies = [
34
+ "layerzero",
35
+ "lz_utils",
36
+ "openzeppelin",
37
+ "snforge_std",
38
+ "starkware_utils_testing",
39
+ ]
40
+
41
+ [[package]]
42
+ name = "openzeppelin"
43
+ version = "2.0.0"
44
+ source = "registry+https://scarbs.xyz/"
45
+ checksum = "sha256:5e4fdecc957cfca7854d95912dc72d9f725517c063b116512900900add29fd77"
46
+ dependencies = [
47
+ "openzeppelin_access",
48
+ "openzeppelin_account",
49
+ "openzeppelin_finance",
50
+ "openzeppelin_governance",
51
+ "openzeppelin_introspection",
52
+ "openzeppelin_merkle_tree",
53
+ "openzeppelin_presets",
54
+ "openzeppelin_security",
55
+ "openzeppelin_token",
56
+ "openzeppelin_upgrades",
57
+ "openzeppelin_utils",
58
+ ]
59
+
60
+ [[package]]
61
+ name = "openzeppelin_access"
62
+ version = "2.0.0"
63
+ source = "registry+https://scarbs.xyz/"
64
+ checksum = "sha256:511681dd26d814ee2bc996d44ff8cb4aaa5ae9d14272130def7eb901cf004850"
65
+ dependencies = [
66
+ "openzeppelin_introspection",
67
+ ]
68
+
69
+ [[package]]
70
+ name = "openzeppelin_account"
71
+ version = "2.0.0"
72
+ source = "registry+https://scarbs.xyz/"
73
+ checksum = "sha256:fb3381c50d68b028d3801feb43df378e2bd62137b6884844f8f60aefe796188b"
74
+ dependencies = [
75
+ "openzeppelin_introspection",
76
+ "openzeppelin_utils",
77
+ ]
78
+
79
+ [[package]]
80
+ name = "openzeppelin_finance"
81
+ version = "2.0.0"
82
+ source = "registry+https://scarbs.xyz/"
83
+ checksum = "sha256:e9456ef69502a87c4c99bf50145351b50950f8b11244847d92935c466c4ba787"
84
+ dependencies = [
85
+ "openzeppelin_access",
86
+ "openzeppelin_token",
87
+ ]
88
+
89
+ [[package]]
90
+ name = "openzeppelin_governance"
91
+ version = "2.0.0"
92
+ source = "registry+https://scarbs.xyz/"
93
+ checksum = "sha256:056e6d6f3d48193b53f06283884f8a9675f986fc85425f6a40e8c1aeb3b3ecfa"
94
+ dependencies = [
95
+ "openzeppelin_access",
96
+ "openzeppelin_account",
97
+ "openzeppelin_introspection",
98
+ "openzeppelin_token",
99
+ "openzeppelin_utils",
100
+ ]
101
+
102
+ [[package]]
103
+ name = "openzeppelin_introspection"
104
+ version = "2.0.0"
105
+ source = "registry+https://scarbs.xyz/"
106
+ checksum = "sha256:87773ed6cd2318f169283ecbbb161890d1996260a80302d81ec45b70ee5e54c1"
107
+
108
+ [[package]]
109
+ name = "openzeppelin_merkle_tree"
110
+ version = "2.0.0"
111
+ source = "registry+https://scarbs.xyz/"
112
+ checksum = "sha256:47f80c9ce59557774243214f8e75c5e866f30f3d8daa755855f6ffd01c89ca89"
113
+
114
+ [[package]]
115
+ name = "openzeppelin_presets"
116
+ version = "2.0.0"
117
+ source = "registry+https://scarbs.xyz/"
118
+ checksum = "sha256:36c761ee923f1dc0887c0eab8c224b49ac242dbfe9163fbb0b08562042ab3d98"
119
+ dependencies = [
120
+ "openzeppelin_access",
121
+ "openzeppelin_account",
122
+ "openzeppelin_finance",
123
+ "openzeppelin_introspection",
124
+ "openzeppelin_token",
125
+ "openzeppelin_upgrades",
126
+ "openzeppelin_utils",
127
+ ]
128
+
129
+ [[package]]
130
+ name = "openzeppelin_security"
131
+ version = "2.0.0"
132
+ source = "registry+https://scarbs.xyz/"
133
+ checksum = "sha256:902932ec296c2f400e0ac7c579edeaafd6067b6ce6d9854c1191de28e396ffe3"
134
+
135
+ [[package]]
136
+ name = "openzeppelin_token"
137
+ version = "2.0.0"
138
+ source = "registry+https://scarbs.xyz/"
139
+ checksum = "sha256:6fe61f63b5a6706018265fb7373b6e5bd3ff829bdc760b2b90296b1e708d180c"
140
+ dependencies = [
141
+ "openzeppelin_access",
142
+ "openzeppelin_account",
143
+ "openzeppelin_introspection",
144
+ "openzeppelin_utils",
145
+ ]
146
+
147
+ [[package]]
148
+ name = "openzeppelin_upgrades"
149
+ version = "2.0.0"
150
+ source = "registry+https://scarbs.xyz/"
151
+ checksum = "sha256:560d57a9c3f3ec5a476e82fec8963c93c8df63a4ff9ff134f64ab8383bde3c61"
152
+
153
+ [[package]]
154
+ name = "openzeppelin_utils"
155
+ version = "2.0.0"
156
+ source = "registry+https://scarbs.xyz/"
157
+ checksum = "sha256:bf799c794139837f397975ffdf6a7ed5032d198bbf70e87a8f44f144a9dfc505"
158
+
159
+ [[package]]
160
+ name = "snforge_scarb_plugin"
161
+ version = "0.49.0"
162
+ source = "registry+https://scarbs.xyz/"
163
+ checksum = "sha256:903150f0e9542e4277d417029eea4c03af0db398b581f9f7ae3ebbdac9afc657"
164
+
165
+ [[package]]
166
+ name = "snforge_std"
167
+ version = "0.49.0"
168
+ source = "registry+https://scarbs.xyz/"
169
+ checksum = "sha256:73d73653cc4356ec51b92a6bec9d8385b20318170c2f2ade7891e5185a0e7e64"
170
+ dependencies = [
171
+ "snforge_scarb_plugin",
172
+ ]
173
+
174
+ [[package]]
175
+ name = "starkware_utils"
176
+ version = "1.0.0"
177
+ source = "git+https://github.com/starkware-libs/starkware-starknet-utils?rev=e1955423808045de868987b8fb0b43f5cbdf5699#e1955423808045de868987b8fb0b43f5cbdf5699"
178
+ dependencies = [
179
+ "openzeppelin",
180
+ ]
181
+
182
+ [[package]]
183
+ name = "starkware_utils_testing"
184
+ version = "1.0.0"
185
+ source = "git+https://github.com/starkware-libs/starkware-starknet-utils?rev=e1955423808045de868987b8fb0b43f5cbdf5699#e1955423808045de868987b8fb0b43f5cbdf5699"
186
+ dependencies = [
187
+ "openzeppelin",
188
+ "snforge_std",
189
+ "starkware_utils",
190
+ ]
package/Scarb.toml ADDED
@@ -0,0 +1,4 @@
1
+ [workspace]
2
+ members = ["contracts/*"]
3
+
4
+
@@ -0,0 +1,30 @@
1
+ [package]
2
+ name = "oft_adapter"
3
+ version = "0.1.0"
4
+ edition = "2024_07"
5
+
6
+ # See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html
7
+
8
+ [dependencies]
9
+ starknet = "2.14.0"
10
+ openzeppelin = "2.0.0"
11
+ lz_utils = { path = "../../node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils" }
12
+ layerzero = { path = "../../node_modules/@layerzerolabs/protocol-starknet-v2/layerzero" }
13
+
14
+ [dev-dependencies]
15
+ snforge_std = "0.49.0"
16
+ assert_macros = "2.12.0"
17
+ starkware_utils_testing = { git = "https://github.com/starkware-libs/starkware-starknet-utils", rev = "e1955423808045de868987b8fb0b43f5cbdf5699" }
18
+
19
+ [[target.starknet-contract]]
20
+ sierra = true
21
+ casm = true
22
+
23
+
24
+ [scripts]
25
+ test = "snforge test"
26
+
27
+ [tool.scarb]
28
+ allow-prebuilt-plugins = ["snforge_scarb_plugin", "snforge_std"]
29
+
30
+
@@ -0,0 +1 @@
1
+ pub mod oft_adapter;
@@ -0,0 +1,150 @@
1
+ /// OFT Adapter Contract
2
+ /// Wraps an existing ERC20 token for cross-chain transfers using lock/unlock mechanism
3
+ #[starknet::contract]
4
+ pub mod OFTAdapter {
5
+ use layerzero::oapps::common::oapp_options_type_3::oapp_options_type_3::OAppOptionsType3Component;
6
+ use layerzero::oapps::oapp::oapp_core::OAppCoreComponent;
7
+ use layerzero::oapps::oft::errors::err_oft_transfer_failed;
8
+ use layerzero::oapps::oft::oft_core::default_oapp_hooks::OFTCoreOAppHooksDefaultImpl;
9
+ use layerzero::oapps::oft::oft_core::oft_core::OFTCoreComponent;
10
+ use layerzero::oapps::oft::structs::OFTDebit;
11
+ use lz_utils::error::assert_with_byte_array;
12
+ use openzeppelin::access::ownable::OwnableComponent;
13
+ use openzeppelin::token::erc20::interface::{
14
+ IERC20Dispatcher, IERC20DispatcherTrait, IERC20MetadataDispatcher,
15
+ IERC20MetadataDispatcherTrait,
16
+ };
17
+ use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};
18
+ use starknet::{ContractAddress, get_contract_address};
19
+
20
+ // Component declarations
21
+ component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
22
+ component!(path: OAppCoreComponent, storage: oapp_core, event: OAppCoreEvent);
23
+ component!(path: OFTCoreComponent, storage: oft_core, event: OFTCoreEvent);
24
+ component!(
25
+ path: OAppOptionsType3Component, storage: oapp_options_type_3, event: OAppOptionsType3Event,
26
+ );
27
+
28
+ // Ownable Mixin
29
+ #[abi(embed_v0)]
30
+ impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;
31
+ impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;
32
+
33
+ // OApp Core
34
+ #[abi(embed_v0)]
35
+ impl OAppCoreImpl = OAppCoreComponent::OAppCoreImpl<ContractState>;
36
+ impl OAppCoreInternalImpl = OAppCoreComponent::InternalImpl<ContractState>;
37
+
38
+
39
+ // OApp Receiver
40
+ #[abi(embed_v0)]
41
+ impl IOAppReceiverImpl = OAppCoreComponent::OAppReceiverImpl<ContractState>;
42
+ #[abi(embed_v0)]
43
+ impl ILayerZeroReceiverImpl =
44
+ OAppCoreComponent::LayerZeroReceiverImpl<ContractState>;
45
+
46
+ // OFT Core - embed the implementation
47
+ #[abi(embed_v0)]
48
+ impl OFTCoreImpl = OFTCoreComponent::OFTCoreImpl<ContractState>;
49
+ impl OFTCoreInternalImpl = OFTCoreComponent::InternalImpl<ContractState>;
50
+
51
+ const SHARED_DECIMALS: u8 = 6;
52
+
53
+ // OApp Options Type 3
54
+ #[abi(embed_v0)]
55
+ impl OAppOptionsType3Impl =
56
+ OAppOptionsType3Component::OAppOptionsType3Impl<ContractState>;
57
+ impl OAppOptionsType3InternalImpl = OAppOptionsType3Component::InternalImpl<ContractState>;
58
+
59
+ #[storage]
60
+ struct Storage {
61
+ #[substorage(v0)]
62
+ ownable: OwnableComponent::Storage,
63
+ #[substorage(v0)]
64
+ oapp_core: OAppCoreComponent::Storage,
65
+ #[substorage(v0)]
66
+ oft_core: OFTCoreComponent::Storage,
67
+ #[substorage(v0)]
68
+ oapp_options_type_3: OAppOptionsType3Component::Storage,
69
+ erc20_token: ContractAddress,
70
+ }
71
+
72
+ #[event]
73
+ #[derive(Drop, starknet::Event)]
74
+ enum Event {
75
+ #[flat]
76
+ OwnableEvent: OwnableComponent::Event,
77
+ #[flat]
78
+ OAppCoreEvent: OAppCoreComponent::Event,
79
+ #[flat]
80
+ OFTCoreEvent: OFTCoreComponent::Event,
81
+ #[flat]
82
+ OAppOptionsType3Event: OAppOptionsType3Component::Event,
83
+ }
84
+
85
+ #[constructor]
86
+ fn constructor(
87
+ ref self: ContractState,
88
+ erc20_token: ContractAddress,
89
+ lz_endpoint: ContractAddress,
90
+ owner: ContractAddress,
91
+ native_token: ContractAddress,
92
+ ) {
93
+ // Initialize Ownable
94
+ self.ownable.initializer(owner);
95
+
96
+ // Initialize OApp Core
97
+ self.oapp_core.initializer(lz_endpoint, owner, native_token);
98
+
99
+ // Initialize token address
100
+ self.erc20_token.write(erc20_token);
101
+
102
+ // OFT Core needs to read local decimals from already deployed ERC20 token
103
+ let token_dispatcher = IERC20MetadataDispatcher { contract_address: erc20_token };
104
+
105
+ // Initialize OFT Core with local decimals
106
+ self.oft_core.initializer(token_dispatcher.decimals(), SHARED_DECIMALS);
107
+ }
108
+
109
+ // Implement OFTHooks to provide the specific token operations
110
+ impl OFTHooks of OFTCoreComponent::OFTHooks<ContractState> {
111
+ fn _debit(
112
+ ref self: OFTCoreComponent::ComponentState<ContractState>,
113
+ from: ContractAddress,
114
+ amount: u256,
115
+ min_amount: u256,
116
+ dst_eid: u32,
117
+ ) -> OFTDebit {
118
+ let oft_debit = self._debit_view(amount, min_amount, dst_eid);
119
+
120
+ // Lock tokens by transferring them from the caller to this contract
121
+ let success = IERC20Dispatcher { contract_address: self._token() }
122
+ .transfer_from(from, get_contract_address(), oft_debit.amount_sent_ld);
123
+ assert_with_byte_array(success, err_oft_transfer_failed());
124
+
125
+ oft_debit
126
+ }
127
+
128
+ fn _credit(
129
+ ref self: OFTCoreComponent::ComponentState<ContractState>,
130
+ to: ContractAddress,
131
+ amount: u256,
132
+ src_eid: u32,
133
+ ) -> u256 {
134
+ // Unlock tokens by transferring them from this contract to the recipient
135
+ let success = IERC20Dispatcher { contract_address: self._token() }.transfer(to, amount);
136
+ assert_with_byte_array(success, err_oft_transfer_failed());
137
+
138
+ // Return the actual amount received (same as input in default implementation)
139
+ amount
140
+ }
141
+
142
+ fn _token(self: @OFTCoreComponent::ComponentState<ContractState>) -> ContractAddress {
143
+ self.get_contract().erc20_token.read()
144
+ }
145
+
146
+ fn _approval_required(self: @OFTCoreComponent::ComponentState<ContractState>) -> bool {
147
+ true
148
+ }
149
+ }
150
+ }
@@ -0,0 +1,3 @@
1
+ pub fn assert_eq<T, +PartialEq<T>, +Drop<T>>(a: T, b: T) {
2
+ assert(a == b, 'Should be equal');
3
+ }
@@ -0,0 +1,11 @@
1
+ pub mod constants;
2
+ pub mod test_oft_adapter;
3
+ pub mod mocks {
4
+ pub mod erc20 {
5
+ pub mod erc20;
6
+ pub mod interface;
7
+ }
8
+ pub mod message_inspector {
9
+ pub mod message_inspector;
10
+ }
11
+ }
@@ -0,0 +1,49 @@
1
+ //! Mock ERC20 component for testing
2
+
3
+ #[starknet::contract]
4
+ pub mod MockERC20 {
5
+ use openzeppelin::token::erc20::{ERC20Component, ERC20HooksEmptyImpl};
6
+ use starknet::ContractAddress;
7
+ use crate::mocks::erc20::interface::IMockERC20;
8
+
9
+ component!(path: ERC20Component, storage: erc20, event: ERC20Event);
10
+
11
+ impl ERC20ImmutableConfig of ERC20Component::ImmutableConfig {
12
+ const DECIMALS: u8 = 18;
13
+ }
14
+
15
+ #[abi(embed_v0)]
16
+ impl ERC20MixinImpl = ERC20Component::ERC20MixinImpl<ContractState>;
17
+ impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;
18
+
19
+ #[storage]
20
+ struct Storage {
21
+ #[substorage(v0)]
22
+ erc20: ERC20Component::Storage,
23
+ }
24
+
25
+ #[event]
26
+ #[derive(Drop, starknet::Event)]
27
+ enum Event {
28
+ #[flat]
29
+ ERC20Event: ERC20Component::Event,
30
+ }
31
+
32
+ #[constructor]
33
+ fn constructor(ref self: ContractState, initial_supply: u256, recipient: ContractAddress) {
34
+ let name = "MyToken";
35
+ let symbol = "MTK";
36
+
37
+ self.erc20.initializer(name, symbol);
38
+ self.erc20.mint(recipient, initial_supply);
39
+ }
40
+
41
+ #[abi(embed_v0)]
42
+ impl MockERC20Impl of IMockERC20<ContractState> {
43
+ fn mint(ref self: ContractState, recipient: ContractAddress, amount: u256) {
44
+ // This function is NOT protected which means
45
+ // ANYONE can mint tokens
46
+ self.erc20.mint(recipient, amount);
47
+ }
48
+ }
49
+ }
@@ -0,0 +1,8 @@
1
+ //! Mock ERC20 interface for testing
2
+
3
+ use starknet::ContractAddress;
4
+
5
+ #[starknet::interface]
6
+ pub trait IMockERC20<TContractState> {
7
+ fn mint(ref self: TContractState, recipient: ContractAddress, amount: u256);
8
+ }
@@ -0,0 +1,17 @@
1
+ //! Mock Message Inspector component for testing
2
+
3
+ #[starknet::contract]
4
+ pub mod MockMessageInspector {
5
+ use core::panics::panic_with_byte_array;
6
+ use layerzero::oapps::message_inspector::interface::IMessageInspector;
7
+
8
+ #[storage]
9
+ struct Storage {}
10
+
11
+ #[abi(embed_v0)]
12
+ impl MockMessageInspectorImpl of IMessageInspector<ContractState> {
13
+ fn inspect_msg(self: @ContractState, message: ByteArray, options: ByteArray) -> bool {
14
+ panic_with_byte_array(@"Invalid message or options")
15
+ }
16
+ }
17
+ }