@layerzerolabs/oft-mint-burn-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.
- package/Scarb.lock +190 -0
- package/Scarb.toml +3 -0
- package/contracts/oft_mint_burn/Scarb.toml +29 -0
- package/contracts/oft_mint_burn/src/constants.cairo +11 -0
- package/contracts/oft_mint_burn/src/erc20_mint_burn_upgradeable/constants.cairo +17 -0
- package/contracts/oft_mint_burn/src/erc20_mint_burn_upgradeable/erc20_mint_burn_upgradeable.cairo +309 -0
- package/contracts/oft_mint_burn/src/erc20_mint_burn_upgradeable/interface.cairo +86 -0
- package/contracts/oft_mint_burn/src/errors.cairo +39 -0
- package/contracts/oft_mint_burn/src/interface.cairo +95 -0
- package/contracts/oft_mint_burn/src/lib.cairo +10 -0
- package/contracts/oft_mint_burn/src/oft_mint_burn_adapter.cairo +382 -0
- package/contracts/oft_mint_burn/tests/fuzzable/contract_address.cairo +21 -0
- package/contracts/oft_mint_burn/tests/lib.cairo +8 -0
- package/contracts/oft_mint_burn/tests/test_erc20_mint_burn_upgradeable.cairo +621 -0
- package/contracts/oft_mint_burn/tests/test_mint_burn_adapter.cairo +194 -0
- package/contracts/oft_mint_burn/tests/test_mint_burn_adapter_advanced.cairo +746 -0
- package/contracts/oft_mint_burn/tests/utils.cairo +84 -0
- package/dist/3UUTAAI4.js +9 -0
- package/dist/3UUTAAI4.js.map +1 -0
- package/dist/4EGWSIX7.js +18 -0
- package/dist/4EGWSIX7.js.map +1 -0
- package/dist/54KHZH3Y.cjs +22 -0
- package/dist/54KHZH3Y.cjs.map +1 -0
- package/dist/5KFUKPR2.js +1033 -0
- package/dist/5KFUKPR2.js.map +1 -0
- package/dist/5R6WMZVR.cjs +22 -0
- package/dist/5R6WMZVR.cjs.map +1 -0
- package/dist/CCHLUK5E.cjs +1035 -0
- package/dist/CCHLUK5E.cjs.map +1 -0
- package/dist/CGU4EJTF.cjs +14 -0
- package/dist/CGU4EJTF.cjs.map +1 -0
- package/dist/DJIRVXJ3.cjs +1914 -0
- package/dist/DJIRVXJ3.cjs.map +1 -0
- package/dist/E63KEOR5.cjs +11 -0
- package/dist/E63KEOR5.cjs.map +1 -0
- package/dist/FL52ASKH.cjs +16 -0
- package/dist/FL52ASKH.cjs.map +1 -0
- package/dist/GZXOKWQY.js +1303 -0
- package/dist/GZXOKWQY.js.map +1 -0
- package/dist/IQR2DIUY.cjs +1305 -0
- package/dist/IQR2DIUY.cjs.map +1 -0
- package/dist/MNNO3GDF.js +14 -0
- package/dist/MNNO3GDF.js.map +1 -0
- package/dist/NZRVZWHQ.js +1912 -0
- package/dist/NZRVZWHQ.js.map +1 -0
- package/dist/QYG4SI7W.js +18 -0
- package/dist/QYG4SI7W.js.map +1 -0
- package/dist/UE6XWQTX.js +12 -0
- package/dist/UE6XWQTX.js.map +1 -0
- package/dist/generated/abi/e-r-c20-mint-burn-upgradeable.cjs +13 -0
- package/dist/generated/abi/e-r-c20-mint-burn-upgradeable.cjs.map +1 -0
- package/dist/generated/abi/e-r-c20-mint-burn-upgradeable.d.ts +760 -0
- package/dist/generated/abi/e-r-c20-mint-burn-upgradeable.d.ts.map +1 -0
- package/dist/generated/abi/e-r-c20-mint-burn-upgradeable.js +4 -0
- package/dist/generated/abi/e-r-c20-mint-burn-upgradeable.js.map +1 -0
- package/dist/generated/abi/o-f-t-mint-burn-adapter.cjs +13 -0
- package/dist/generated/abi/o-f-t-mint-burn-adapter.cjs.map +1 -0
- package/dist/generated/abi/o-f-t-mint-burn-adapter.d.ts +1408 -0
- package/dist/generated/abi/o-f-t-mint-burn-adapter.d.ts.map +1 -0
- package/dist/generated/abi/o-f-t-mint-burn-adapter.js +4 -0
- package/dist/generated/abi/o-f-t-mint-burn-adapter.js.map +1 -0
- package/dist/generated/abi.cjs +19 -0
- package/dist/generated/abi.cjs.map +1 -0
- package/dist/generated/abi.d.ts +3 -0
- package/dist/generated/abi.d.ts.map +1 -0
- package/dist/generated/abi.js +6 -0
- package/dist/generated/abi.js.map +1 -0
- package/dist/generated/casm.cjs +17 -0
- package/dist/generated/casm.cjs.map +1 -0
- package/dist/generated/casm.d.ts +3 -0
- package/dist/generated/casm.d.ts.map +1 -0
- package/dist/generated/casm.js +4 -0
- package/dist/generated/casm.js.map +1 -0
- package/dist/generated/sierra.cjs +17 -0
- package/dist/generated/sierra.cjs.map +1 -0
- package/dist/generated/sierra.d.ts +3 -0
- package/dist/generated/sierra.d.ts.map +1 -0
- package/dist/generated/sierra.js +4 -0
- package/dist/generated/sierra.js.map +1 -0
- package/dist/generated/verification/index.cjs +14 -0
- package/dist/generated/verification/index.cjs.map +1 -0
- package/dist/generated/verification/index.d.ts +2 -0
- package/dist/generated/verification/index.d.ts.map +1 -0
- package/dist/generated/verification/index.js +5 -0
- package/dist/generated/verification/index.js.map +1 -0
- package/dist/generated/verification/oft_mint_burn.cjs +10 -0
- package/dist/generated/verification/oft_mint_burn.cjs.map +1 -0
- package/dist/generated/verification/oft_mint_burn.d.ts +4 -0
- package/dist/generated/verification/oft_mint_burn.d.ts.map +1 -0
- package/dist/generated/verification/oft_mint_burn.js +4 -0
- package/dist/generated/verification/oft_mint_burn.js.map +1 -0
- package/dist/index.cjs +31 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/generated/verification/oft_mint_burn.ts"],"names":["verificationInfo"],"mappings":";;;AAEA,IAAMA,gBAAAA,GAA2C;EAC/C,SAAA,EAAW;IACT,6CAAA,EAA+C,ygBAAA;IAC/C,yEAAA,EAA2E,CAAA;;;;;;;;;;;;;;;;;;IAC3E,2FAAA,EAA6F,ulYAAA;IAC7F,yEAAA,EAA2E,s/FAAA;IAC3E,0CAAA,EAA4C,kvCAAA;IAC5C,6CAAA,EAA+C,ylGAAA;IAC/C,uCAAA,EAAyC,iOAAA;IACzC,yDAAA,EAA2D,85dAAA;IAC3D,oCAAA,EAAsC,i0BAAA;IACtC,mGAAA,EAAqG,+kxBAAA;IACrG,uGAAA,EAAyG,kuUAAA;IACzG,wGAAA,EAA0G,218BAAA;IAC1G,+FAAA,EAAiG,ikBAAA;IACjG,gFAAA,EAAkF,s7BAAA;IAClF,gFAAA,EAAkF,mwBAAA;IAClF,iFAAA,EAAmF,ofAAA;IACnF,8EAAA,EAAgF,uLAAA;IAChF,2EAAA,EAA6E,6SAAA;IAC7E,uFAAA,EAAyF,o7BAAA;IACzF,yFAAA,EAA2F,+cAAA;IAC3F,kFAAA,EAAoF,gmBAAA;IACpF,6FAAA,EAA+F,onWAAA;IAC/F,+FAAA,EAAiG,mgCAAA;IACjG,4FAAA,EAA8F,wrBAAA;IAC9F,yFAAA,EAA2F,snBAAA;IAC3F,2FAAA,EAA6F,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAC7F,sFAAA,EAAwF,qlKAAA;IACxF,sFAAA,EAAwF,s/EAAA;IACxF,sGAAA,EAAwG,2wXAAA;IACxG,6GAAA,EAA+G,+2FAAA;IAC/G,6GAAA,EAA+G,ukFAAA;IAC/G,0GAAA,EAA4G,oqHAAA;IAC5G,0GAAA,EAA4G,shFAAA;IAC5G,6GAAA,EAA+G,0imBAAA;IAC/G,uHAAA,EAAyH,4pgCAAA;IACzH,2GAAA,EAA6G,isCAAA;IAC7G,wGAAA,EAA0G,yoCAAA;IAC1G,wGAAA,EAA0G,i8CAAA;IAC1G,2GAAA,EAA6G,06NAAA;IAC7G,mHAAA,EAAqH,upkBAAA;IACrH,yGAAA,EAA2G,y2DAAA;IAC3G,yGAAA,EAA2G,+2DAAA;IAC3G,4GAAA,EAA8G,kyJAAA;IAC9G,qHAAA,EAAuH,0oTAAA;IACvH,0EAAA,EAA4E,wxLAAA;IAC5E,sGAAA,EAAwG,w+HAAA;IACxG,4FAAA,EAA8F,o/DAAA;IAC9F,6FAAA,EAA+F,wlBAAA;IAC/F,6FAAA,EAA+F,6oBAAA;IAC/F,yGAAA,EAA2G,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAC3G,0FAAA,EAA4F,irBAAA;IAC5F,iGAAA,EAAmG,61JAAA;IACnG,iGAAA,EAAmG,4zEAAA;IACnG,oGAAA,EAAsG,ihHAAA;IACtG,kGAAA,EAAoG,+pFAAA;IACpG,kHAAA,EAAoH,49CAAA;IACpH,+GAAA,EAAiH,oMAAA;IACjH,6GAAA,EAA+G,yqMAAA;IAC/G,0HAAA,EAA4H,i3HAAA;IAC5H,+GAAA,EAAiH,0LAAA;IACjH,+GAAA,EAAiH,q0tCAAA;IACjH,yGAAA,EAA2G,0jKAAA;IAC3G,qGAAA,EAAuG,i1BAAA;IACvG,qGAAA,EAAuG,+pBAAA;IACvG,wGAAA,EAA0G,2gCAAA;IAC1G,8FAAA,EAAgG,kpBAAA;IAChG,8FAAA,EAAgG,kOAAA;IAChG,2FAAA,EAA6F,mzJAAA;IAC7F,iGAAA,EAAmG,yxDAAA;IACnG,+FAAA,EAAiG,gJAAA;IACjG,8GAAA,EAAgH,0kBAAA;IAChH,8GAAA,EAAgH,qMAAA;IAChH,iHAAA,EAAmH,82CAAA;IACnH,2HAAA,EAA6H,0rJAAA;IAC7H,+GAAA,EAAiH,8IAAA;IACjH,uGAAA,EAAyG,8kBAAA;IACzG,uGAAA,EAAyG,2wBAAA;IACzG,0GAAA,EAA4G,ktDAAA;IAC5G,6GAAA,EAA+G,w/jBAAA;IAC/G,wGAAA,EAA0G,ovDAAA;IAC1G,8FAAA,EAAgG,uLAAA;IAChG,4FAAA,EAA8F,+igBAAA;IAC9F,2FAAA,EAA6F,CAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAC7F,8FAAA,EAAgG,6qDAAA;IAChG,8FAAA,EAAgG,gjCAAA;IAChG,4FAAA,EAA8F,4xBAAA;IAC9F,4FAAA,EAA8F,oaAAA;IAC9F,wGAAA,EAA0G,80BAAA;IAC1G,wFAAA,EAA0F,w8FAAA;IAC1F,wFAAA,EAA0F,iKAAA;IAC1F,2FAAA,EAA6F,8qEAAA;IAC7F,sFAAA,EAAwF,o6EAAA;IACxF,2FAAA,EAA6F,mzmBAAA;IAC7F,uFAAA,EAAyF,q9CAAA;IACzF,uFAAA,EAAyF,opBAAA;IACzF,0FAAA,EAA4F,20GAAA;IAC5F,sGAAA,EAAwG,ghIAAA;IACxG,4GAAA,EAA8G,2uCAAA;IAC9G,2GAAA,EAA6G,2xEAAA;IAC7G,kGAAA,EAAoG,41uBAAA;IACpG,8FAAA,EAAgG,q1IAAA;IAChG,wFAAA,EAA0F,k8FAAA;IAC1F,sFAAA,EAAwF,urBAAA;IACxF,sFAAA,EAAwF,sHAAA;IACxF,6GAAA,EAA+G,i2DAAA;IAC/G,2GAAA,EAA6G,27CAAA;IAC7G,yGAAA,EAA2G,syCAAA;IAC3G,wFAAA,EAA0F,4sJAAA;IAC1F,6FAAA,EAA+F,sdAAA;IAC/F,wFAAA,EAA0F,+7SAAA;IAC1F,0FAAA,EAA4F,s+BAAA;IAC5F,0FAAA,EAA4F,+kCAAA;IAC5F,6FAAA,EAA+F,+vGAAA;IAC/F,2FAAA,EAA6F,gPAAA;IAC7F,qFAAA,EAAuF,gsDAAA;IACvF,4FAAA,EAA8F,yYAAA;IAC9F,sFAAA,EAAwF,q1gBAAA;IACxF,yFAAA,EAA2F,u+FAAA;IAC3F,yFAAA,EAA2F,2xBAAA;IAC3F,sGAAA,EAAwG,ijLAAA;IACxG,oGAAA,EAAsG,68CAAA;IACtG,4FAAA,EAA8F,k8IAAA;IAC9F,0FAAA,EAA4F,q0IAAA;IAC5F,0FAAA,EAA4F,uzCAAA;IAC5F,8FAAA,EAAgG,26LAAA;IAChG,8FAAA,EAAgG,ujCAAA;IAChG,gGAAA,EAAkG,snjBAAA;IAClG,gHAAA,EAAkH,ysLAAA;IAClH,yGAAA,EAA2G,4xGAAA;IAC3G,iGAAA,EAAmG,urKAAA;IACnG,+FAAA,EAAiG,orTAAA;IACjG,+FAAA,EAAiG,64GAAA;IACjG,wFAAA,EAA0F,y/BAAA;IAC1F,mGAAA,EAAqG,uOAAA;IACrG,gGAAA,EAAkG,woCAAA;IAClG,gGAAA,EAAkG,8RAAA;IAClG,mGAAA,EAAqG,4mQAAA;IACrG,oGAAA,EAAsG,ujfAAA;IACtG,iGAAA,EAAmG,m1EAAA;IACnG,uEAAA,EAAyE,+3BAAA;IACzE,+FAAA,EAAiG,u+HAAA;IACjG,oFAAA,EAAsF,yKAAA;IACtF,iFAAA,EAAmF,mTAAA;IACnF,iFAAA,EAAmF,qyFAAA;IACnF,iFAAA,EAAmF,2RAAA;IACnF,oFAAA,EAAsF,yhFAAA;IACtF,8EAAA,EAAgF,8KAAA;IAChF,mFAAA,EAAqF,2qSAAA;IACrF,2EAAA,EAA6E,ioBAAA;IAC7E,YAAA,EAAc;AAChB,GAAA;EACA,iBAAA,EAAmB,QAAA;EACnB,aAAA,EAAe,eAAA;EACf,gBAAA,EAAkB,GAAA;EAClB,kBAAA,EAAoB;AACtB,CAAA;AAEA,IAAA,qBAAA,GAAeA","file":"IQR2DIUY.cjs","sourcesContent":["import type { StarknetSourceSnapshot } from '@layerzerolabs/build-utils-starknet';\n\nconst verificationInfo: StarknetSourceSnapshot = {\n \"sources\": {\n \"contracts/oft_mint_burn/src/constants.cairo\": \"/// Role identifier for addresses that can manage fees\\npub const FEE_MANAGER_ROLE: felt252 = 'FEE_MANAGER_ROLE';\\n\\n/// Role identifier for addresses that can manage rate limits\\npub const RATE_LIMITER_MANAGER_ROLE: felt252 = 'RATE_LIMITER_MANAGER_ROLE';\\n\\n/// Role identifier for addresses that can upgrade the contract\\npub const UPGRADE_MANAGER_ROLE: felt252 = 'UPGRADE_MANAGER_ROLE';\\n\\n/// Role identifier for addresses that can pause the contract\\npub const PAUSE_MANAGER_ROLE: felt252 = 'PAUSE_MANAGER_ROLE';\\n\",\n \"contracts/oft_mint_burn/src/erc20_mint_burn_upgradeable/constants.cairo\": \"/// Role identifier for addresses that can mint new tokens\\n/// In Solidity, this would be: bytes32 public constant MINTER_ROLE = keccak256(\\\"MINTER_ROLE\\\")\\npub const MINTER_ROLE: felt252 = 'MINTER_ROLE';\\n\\n/// Role identifier for addresses that can burn tokens without approval\\n/// In Solidity, this would be: bytes32 public constant BURNER_ROLE = keccak256(\\\"BURNER_ROLE\\\")\\npub const BURNER_ROLE: felt252 = 'BURNER_ROLE';\\n\\n/// Role identifier for addresses that can pause the contract\\n/// In Solidity, this would be: bytes32 public constant PAUSE_MANAGER_ROLE =\\n/// keccak256(\\\"PAUSE_MANAGER_ROLE\\\")\\npub const PAUSE_MANAGER_ROLE: felt252 = 'PAUSE_MANAGER_ROLE';\\n\\n/// Role identifier for addresses that can manage the allowlist\\n/// In Solidity, this would be: bytes32 public constant ALLOWLIST_MANAGER_ROLE =\\n/// keccak256(\\\"ALLOWLIST_MANAGER_ROLE\\\")\\npub const ALLOWLIST_MANAGER_ROLE: felt252 = 'ALLOWLIST_MANAGER_ROLE';\\n\",\n \"contracts/oft_mint_burn/src/erc20_mint_burn_upgradeable/erc20_mint_burn_upgradeable.cairo\": \"/// ERC20MintBurnUpgradeable\\n///\\n/// Upgradeable ERC20 token with permissioned mint/burn functionality\\n/// This contract provides a standard ERC20 token that allows permissioned minters and burners\\n/// to mint and burn tokens through the IMintableToken interface.\\n///\\n/// Key features:\\n/// - MINTER_ROLE: Addresses with this role can mint tokens via permissioned_mint\\n/// - BURNER_ROLE: Addresses with this role can burn tokens via permissioned_burn\\n/// - ALLOWLIST_MANAGER_ROLE: Addresses with this role can manage the allowlist\\n/// - DEFAULT_ADMIN_ROLE: Can grant/revoke roles\\n/// - Upgradeable for future improvements\\n/// - Allowlist support with Open/Blacklist/Whitelist modes\\n#[starknet::contract]\\npub mod ERC20MintBurnUpgradeable {\\n use AccessControlComponent::DEFAULT_ADMIN_ROLE;\\n use layerzero::common::constants::ZERO_ADDRESS;\\n use layerzero::oapps::common::allow_list::allow_list::AllowlistComponent;\\n use layerzero::oapps::common::allow_list::errors::err_not_allowed;\\n use layerzero::oapps::common::allow_list::interface::AllowlistMode;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::accesscontrol::AccessControlComponent;\\n use openzeppelin::introspection::src5::SRC5Component;\\n use openzeppelin::security::pausable::PausableComponent;\\n use openzeppelin::token::erc20::ERC20Component;\\n use openzeppelin::token::erc20::interface::IERC20Metadata;\\n use openzeppelin::upgrades::UpgradeableComponent;\\n use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};\\n use starknet::{ClassHash, ContractAddress, get_caller_address};\\n use crate::erc20_mint_burn_upgradeable::constants::{\\n ALLOWLIST_MANAGER_ROLE, BURNER_ROLE, MINTER_ROLE, PAUSE_MANAGER_ROLE,\\n };\\n use crate::erc20_mint_burn_upgradeable::interface::IERC20MintBurnUpgradeable;\\n use crate::interface::IMintableToken;\\n\\n // =============================== Components ===============================\\n\\n component!(path: ERC20Component, storage: erc20, event: ERC20Event);\\n component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);\\n component!(path: PausableComponent, storage: pausable, event: PausableEvent);\\n component!(path: AccessControlComponent, storage: access_control, event: AccessControlEvent);\\n component!(path: SRC5Component, storage: src5, event: SRC5Event);\\n component!(path: AllowlistComponent, storage: allowlist, event: AllowlistEvent);\\n\\n\\n // Use individual embeds instead of Mixin to allow custom decimals override\\n #[abi(embed_v0)]\\n impl ERC20Impl = ERC20Component::ERC20Impl<ContractState>;\\n #[abi(embed_v0)]\\n impl ERC20CamelOnlyImpl = ERC20Component::ERC20CamelOnlyImpl<ContractState>;\\n impl ERC20InternalImpl = ERC20Component::InternalImpl<ContractState>;\\n\\n impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl AccessControlImpl =\\n AccessControlComponent::AccessControlImpl<ContractState>;\\n impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl PausableImpl = PausableComponent::PausableImpl<ContractState>;\\n impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl AllowlistImpl = AllowlistComponent::AllowlistImpl<ContractState>;\\n impl AllowlistInternalImpl = AllowlistComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n #[substorage(v0)]\\n erc20: ERC20Component::Storage,\\n #[substorage(v0)]\\n upgradeable: UpgradeableComponent::Storage,\\n #[substorage(v0)]\\n access_control: AccessControlComponent::Storage,\\n #[substorage(v0)]\\n src5: SRC5Component::Storage,\\n #[substorage(v0)]\\n pausable: PausableComponent::Storage,\\n #[substorage(v0)]\\n allowlist: AllowlistComponent::Storage,\\n /// Token decimals (configurable via constructor)\\n decimals: u8,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n enum Event {\\n #[flat]\\n ERC20Event: ERC20Component::Event,\\n #[flat]\\n UpgradeableEvent: UpgradeableComponent::Event,\\n #[flat]\\n AccessControlEvent: AccessControlComponent::Event,\\n #[flat]\\n SRC5Event: SRC5Component::Event,\\n #[flat]\\n PausableEvent: PausableComponent::Event,\\n #[flat]\\n AllowlistEvent: AllowlistComponent::Event,\\n }\\n\\n /// Initializes the ERC20 token with mint/burn capabilities\\n ///\\n /// # Arguments\\n /// * `name` - Token name\\n /// * `symbol` - Token symbol\\n /// * `decimals` - Token decimals\\n /// * `default_admin` - Address that will receive DEFAULT_ADMIN_ROLE\\n ///\\n /// # Notes\\n /// The default admin can grant MINTER_ROLE, BURNER_ROLE, and ALLOWLIST_MANAGER_ROLE to other\\n /// addresses. The allowlist is initialized in Open mode (all users allowed).\\n #[constructor]\\n fn constructor(\\n ref self: ContractState,\\n name: ByteArray,\\n symbol: ByteArray,\\n decimals: u8,\\n default_admin: ContractAddress,\\n ) {\\n assert(default_admin != ZERO_ADDRESS, 'Invalid admin: zero address');\\n\\n // Initialize ERC20 with name and symbol\\n self.erc20.initializer(name, symbol);\\n\\n // Store decimals in contract storage\\n self.decimals.write(decimals);\\n\\n // Initialize access control\\n self.access_control.initializer();\\n\\n // Initialize allowlist in Open mode (all users allowed by default)\\n self.allowlist.initializer(AllowlistMode::Open);\\n\\n // Grant admin role to the specified address\\n // Admin can then grant MINTER_ROLE, BURNER_ROLE, and ALLOWLIST_MANAGER_ROLE as needed\\n self.access_control._grant_role(DEFAULT_ADMIN_ROLE, default_admin);\\n }\\n\\n // Override ERC20Metadata to read decimals from storage\\n #[abi(embed_v0)]\\n impl ERC20MetadataImpl of IERC20Metadata<ContractState> {\\n fn name(self: @ContractState) -> ByteArray {\\n self.erc20.ERC20_name.read()\\n }\\n\\n fn symbol(self: @ContractState) -> ByteArray {\\n self.erc20.ERC20_symbol.read()\\n }\\n\\n fn decimals(self: @ContractState) -> u8 {\\n self.decimals.read()\\n }\\n }\\n\\n #[abi(embed_v0)]\\n impl MintableTokenImpl of IMintableToken<ContractState> {\\n /// Mints tokens to address using permitted minter pattern\\n ///\\n /// # Arguments\\n /// * `account` - Address to mint tokens to\\n /// * `amount` - Amount of tokens to mint\\n ///\\n /// # Access Control\\n /// Only callable by accounts with MINTER_ROLE\\n fn permissioned_mint(ref self: ContractState, account: ContractAddress, amount: u256) {\\n self._assert_only_minter();\\n self.erc20.mint(account, amount);\\n }\\n\\n /// Burns tokens from address using permitted burner pattern\\n ///\\n /// # Arguments\\n /// * `account` - Address to burn tokens from\\n /// * `amount` - Amount of tokens to burn\\n ///\\n /// # Access Control\\n /// Only callable by accounts with BURNER_ROLE\\n ///\\n /// # Notes\\n /// Unlike standard burn, this doesn't require approval from token holder\\n fn permissioned_burn(ref self: ContractState, account: ContractAddress, amount: u256) {\\n self._assert_only_burner();\\n self.erc20.burn(account, amount);\\n }\\n }\\n\\n #[abi(embed_v0)]\\n impl ERC20MintBurnUpgradeableImpl of IERC20MintBurnUpgradeable<ContractState> {\\n fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {\\n self._assert_only_default_admin();\\n self.upgradeable.upgrade(new_class_hash);\\n }\\n\\n fn upgrade_and_call(\\n ref self: ContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252> {\\n self._assert_only_default_admin();\\n self.upgradeable.upgrade_and_call(new_class_hash, selector, calldata)\\n }\\n\\n fn pause(ref self: ContractState) {\\n self._assert_only_pause_manager();\\n self.pausable.pause();\\n }\\n\\n fn unpause(ref self: ContractState) {\\n self._assert_only_pause_manager();\\n self.pausable.unpause();\\n }\\n\\n fn set_allowlist_mode(ref self: ContractState, mode: AllowlistMode) {\\n self._assert_only_allowlist_manager();\\n self.allowlist._set_allowlist_mode(mode);\\n }\\n\\n fn set_whitelisted(ref self: ContractState, users: Span<ContractAddress>, status: bool) {\\n self._assert_only_allowlist_manager();\\n self.allowlist._set_whitelisted(users, status);\\n }\\n\\n fn set_blacklisted(ref self: ContractState, users: Span<ContractAddress>, status: bool) {\\n self._assert_only_allowlist_manager();\\n self.allowlist._set_blacklisted(users, status);\\n }\\n }\\n\\n // =============================== ERC20 Hooks ===============================\\n\\n // Overrides the default implementation of `ERC20Component::InternalTrait::update`\\n // - Mint (from == zero): NO pause check, NO allowlist check - can always mint\\n // - Burn (to == zero): Check pause AND allowlist on `from`\\n // - Transfer (both non-zero): Check pause AND allowlist on `from`, `to`,\\n // - Transfer from: caller if caller != from\\n impl ERC20Hooks of ERC20Component::ERC20HooksTrait<ContractState> {\\n fn before_update(\\n ref self: ERC20Component::ComponentState<ContractState>,\\n from: ContractAddress,\\n recipient: ContractAddress,\\n amount: u256,\\n ) {\\n // Mint: from == ZERO_ADDRESS - no checks, can always mint\\n if from == ZERO_ADDRESS {\\n return;\\n }\\n\\n let contract = self.get_contract();\\n\\n // For burn and transfer: check pause\\n contract.pausable.assert_not_paused();\\n\\n // For burn (to == ZERO_ADDRESS): check allowlist on `from` only\\n if recipient == ZERO_ADDRESS {\\n assert_with_byte_array(\\n contract.allowlist.is_user_allowlisted(from), err_not_allowed(),\\n );\\n return;\\n }\\n\\n // For transfer: check allowlist on `from`, `recipient`, AND caller\\n assert_with_byte_array(\\n contract.allowlist.is_user_allowlisted(from)\\n && contract.allowlist.is_user_allowlisted(recipient),\\n err_not_allowed(),\\n );\\n\\n // handle transfer_from where caller != from\\n let caller = get_caller_address();\\n if caller != from {\\n assert_with_byte_array(\\n contract.allowlist.is_user_allowlisted(caller), err_not_allowed(),\\n );\\n }\\n }\\n }\\n\\n /// Internal functions for role validation\\n #[generate_trait]\\n impl InternalImpl of InternalTrait {\\n /// Validates caller has DEFAULT_ADMIN_ROLE\\n fn _assert_only_default_admin(self: @ContractState) {\\n self.access_control.assert_only_role(DEFAULT_ADMIN_ROLE);\\n }\\n\\n /// Validates caller has MINTER_ROLE\\n fn _assert_only_minter(self: @ContractState) {\\n self.access_control.assert_only_role(MINTER_ROLE);\\n }\\n\\n /// Validates caller has BURNER_ROLE\\n fn _assert_only_burner(self: @ContractState) {\\n self.access_control.assert_only_role(BURNER_ROLE);\\n }\\n\\n /// Validates caller has PAUSE_MANAGER_ROLE\\n fn _assert_only_pause_manager(self: @ContractState) {\\n self.access_control.assert_only_role(PAUSE_MANAGER_ROLE);\\n }\\n\\n /// Validates caller has ALLOWLIST_MANAGER_ROLE\\n fn _assert_only_allowlist_manager(self: @ContractState) {\\n self.access_control.assert_only_role(ALLOWLIST_MANAGER_ROLE);\\n }\\n }\\n}\\n\",\n \"contracts/oft_mint_burn/src/erc20_mint_burn_upgradeable/interface.cairo\": \"use layerzero::oapps::common::allow_list::interface::AllowlistMode;\\nuse starknet::{ClassHash, ContractAddress};\\n\\n#[starknet::interface]\\npub trait IERC20MintBurnUpgradeable<TContractState> {\\n /// Upgrades the contract\\n ///\\n /// # Arguments\\n /// * `new_class_hash` - The new class hash to upgrade to\\n ///\\n /// # Events\\n /// * `Upgraded` - Emitted when the contract is upgraded (from OpenZeppelin's\\n /// [`UpgradeableComponent`])\\n ///\\n /// @dev This function is only callable by the default admin.\\n fn upgrade(ref self: TContractState, new_class_hash: ClassHash);\\n\\n /// Upgrades the contract and calls a function\\n ///\\n /// # Arguments\\n /// * `new_class_hash` - The new class hash to upgrade to\\n /// * `selector` - The selector to call\\n /// * `data` - The data to pass to the function\\n ///\\n /// # Returns\\n /// * `Span<felt252>` - The response data from the function call\\n ///\\n /// # Events\\n /// * `Upgraded` - Emitted when the contract is upgraded (from OpenZeppelin's\\n /// [`UpgradeableComponent`])\\n ///\\n /// @dev This function is only callable by the default admin.\\n fn upgrade_and_call(\\n ref self: TContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252>;\\n\\n // =============================== Pause ===============================\\n\\n /// Pauses the contract\\n ///\\n /// # Events\\n /// * `Paused` - Emitted when the contract is paused (from OpenZeppelin's\\n /// [`PausableComponent`])\\n fn pause(ref self: TContractState);\\n\\n /// Unpauses the contract\\n ///\\n /// # Events\\n /// * `Unpaused` - Emitted when the contract is unpaused (from OpenZeppelin's\\n /// [`PausableComponent`])\\n fn unpause(ref self: TContractState);\\n\\n // =============================== Allowlist ===============================\\n\\n /// Sets the allowlist mode\\n ///\\n /// # Arguments\\n /// * `mode` - The new allowlist mode (Open, Blacklist, or Whitelist)\\n ///\\n /// # Access Control\\n /// Only callable by accounts with ALLOWLIST_MANAGER_ROLE\\n fn set_allowlist_mode(ref self: TContractState, mode: AllowlistMode);\\n\\n /// Sets the whitelist status for multiple users\\n ///\\n /// # Arguments\\n /// * `users` - Array of user addresses\\n /// * `status` - Whether to whitelist (true) or unwhitelist (false)\\n ///\\n /// # Access Control\\n /// Only callable by accounts with ALLOWLIST_MANAGER_ROLE\\n fn set_whitelisted(ref self: TContractState, users: Span<ContractAddress>, status: bool);\\n\\n /// Sets the blacklist status for multiple users\\n ///\\n /// # Arguments\\n /// * `users` - Array of user addresses\\n /// * `status` - Whether to blacklist (true) or unblacklist (false)\\n ///\\n /// # Access Control\\n /// Only callable by accounts with ALLOWLIST_MANAGER_ROLE\\n fn set_blacklisted(ref self: TContractState, users: Span<ContractAddress>, status: bool);\\n}\\n\",\n \"contracts/oft_mint_burn/src/errors.cairo\": \"//! OFT Mint Burn Adapter errors\\n\\nuse lz_utils::error::{Error, format_error};\\nuse starknet::ContractAddress;\\n\\n#[derive(Drop)]\\npub enum OFTMintBurnAdapterError {\\n NoFeesToWithdraw,\\n TransferFailed,\\n CallerNotOwnerOrMissingRole,\\n}\\n\\nimpl OFTMintBurnAdapterErrorImpl of Error<OFTMintBurnAdapterError> {\\n fn prefix() -> ByteArray {\\n \\\"OFT_MINT_BURN_ADAPTER\\\"\\n }\\n\\n fn name(self: OFTMintBurnAdapterError) -> ByteArray {\\n match self {\\n OFTMintBurnAdapterError::NoFeesToWithdraw => \\\"NO_FEES_TO_WITHDRAW\\\",\\n OFTMintBurnAdapterError::TransferFailed => \\\"TRANSFER_FAILED\\\",\\n OFTMintBurnAdapterError::CallerNotOwnerOrMissingRole => \\\"CALLER_NOT_OWNER_OR_MISSING_ROLE\\\",\\n }\\n }\\n}\\n\\npub fn err_no_fees_to_withdraw() -> ByteArray {\\n format_error(OFTMintBurnAdapterError::NoFeesToWithdraw, \\\"\\\")\\n}\\n\\npub fn err_transfer_failed(to: ContractAddress, amount: u256) -> ByteArray {\\n format_error(\\n OFTMintBurnAdapterError::TransferFailed, format!(\\\"to: {:?}, amount: {:?}\\\", to, amount),\\n )\\n}\\n\\npub fn err_caller_not_owner_or_missing_role(role: felt252) -> ByteArray {\\n format_error(OFTMintBurnAdapterError::CallerNotOwnerOrMissingRole, format!(\\\"role: {:?}\\\", role))\\n}\\n\",\n \"contracts/oft_mint_burn/src/interface.cairo\": \"use layerzero::oapps::common::rate_limiter::structs::{\\n RateLimitConfig, RateLimitDirection, RateLimitEnabled,\\n};\\nuse starknet::{ClassHash, ContractAddress};\\n\\n#[starknet::interface]\\npub trait IMintableToken<TContractState> {\\n fn permissioned_mint(ref self: TContractState, account: ContractAddress, amount: u256);\\n fn permissioned_burn(ref self: TContractState, account: ContractAddress, amount: u256);\\n}\\n\\n#[starknet::interface]\\npub trait IOFTMintBurnAdapter<TContractState> {\\n // =============================== View ===============================\\n\\n /// Gets the fee balance\\n ///\\n /// # Returns\\n ///\\n /// * `u256` - The fee balance\\n fn fee_balance(self: @TContractState) -> u256;\\n\\n /// Gets the minter burner contract address\\n ///\\n /// # Returns\\n ///\\n /// * `ContractAddress` - The minter burner contract address\\n fn get_minter_burner(self: @TContractState) -> ContractAddress;\\n\\n // =============================== Only Owner or Role ===============================\\n\\n /// Sets the rate limits\\n ///\\n /// # Arguments\\n /// * `rate_limits` - The rate limits\\n /// * `direction` - The rate limit direction\\n fn set_rate_limits(\\n ref self: TContractState,\\n rate_limits: Array<RateLimitConfig>,\\n direction: RateLimitDirection,\\n );\\n\\n /// Sets the rate limits enabled\\n ///\\n /// # Arguments\\n /// * `enabled` - The rate limits enabled\\n fn set_rate_limits_enabled(ref self: TContractState, enabled: RateLimitEnabled);\\n\\n /// Resets the rate limits for the given endpoint IDs.\\n ///\\n /// This sets `amount_in_flight` to zero for both outbound and inbound directions.\\n /// Useful when limit thresholds are reduced below current amount in flight, or for\\n /// emergency recovery.\\n ///\\n /// # Arguments\\n /// * `eids` - The endpoint IDs to reset rate limits for\\n fn reset_rate_limits(ref self: TContractState, eids: Array<u32>);\\n\\n /// Withdraws the fees\\n ///\\n /// # Arguments\\n /// * `to` - The address to withdraw the fees to\\n fn withdraw_fees(ref self: TContractState, to: ContractAddress);\\n\\n // =============================== Upgrade ===============================\\n\\n /// Upgrades the contract\\n ///\\n /// # Arguments\\n /// * `new_class_hash` - The new class hash to upgrade to\\n fn upgrade(ref self: TContractState, new_class_hash: ClassHash);\\n\\n /// Upgrades the contract and calls a function\\n ///\\n /// # Arguments\\n /// * `new_class_hash` - The new class hash to upgrade to\\n /// * `selector` - The selector to call\\n /// * `calldata` - The calldata to pass to the function\\n ///\\n /// # Returns\\n fn upgrade_and_call(\\n ref self: TContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252>;\\n\\n // =============================== Pause ===============================\\n\\n /// Pauses the contract\\n fn pause(ref self: TContractState);\\n\\n /// Unpauses the contract\\n fn unpause(ref self: TContractState);\\n}\\n\",\n \"contracts/oft_mint_burn/src/lib.cairo\": \"pub mod constants;\\npub mod errors;\\npub mod interface;\\npub mod oft_mint_burn_adapter;\\n\\npub mod erc20_mint_burn_upgradeable {\\n pub mod constants;\\n pub mod erc20_mint_burn_upgradeable;\\n pub mod interface;\\n}\\n\",\n \"contracts/oft_mint_burn/src/oft_mint_burn_adapter.cairo\": \"/// A mint/burn OFT adapter with fees, rate limiting, and role-based access control.\\n///\\n/// This contract should be used to mint and burn tokens for ERC-20 token contracts\\n/// that implement the IMintableBurnable interface.\\n#[starknet::contract]\\npub mod OFTMintBurnAdapter {\\n use core::num::traits::Zero;\\n use layerzero::common::constants::DEAD_ADDRESS;\\n use layerzero::oapps::common::fee::fee::{FeeComponent, FeeHooksDefaultImpl};\\n use layerzero::oapps::common::oapp_options_type_3::oapp_options_type_3::OAppOptionsType3Component;\\n use layerzero::oapps::common::rate_limiter::rate_limiter::{\\n RateLimiterComponent, RateLimiterHooksDefaultImpl,\\n };\\n use layerzero::oapps::common::rate_limiter::structs::{\\n RateLimitConfig, RateLimitDirection, RateLimitEnabled,\\n };\\n use layerzero::oapps::oapp::oapp_core::OAppCoreComponent;\\n use layerzero::oapps::oft::errors::err_slippage_exceeded;\\n use layerzero::oapps::oft::oft_core::default_oapp_hooks::OFTCoreOAppHooksDefaultImpl;\\n use layerzero::oapps::oft::oft_core::oft_core::OFTCoreComponent;\\n use layerzero::oapps::oft::structs::OFTDebit;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::accesscontrol::AccessControlComponent;\\n\\n // Access control roles\\n pub use openzeppelin::access::accesscontrol::AccessControlComponent::DEFAULT_ADMIN_ROLE;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::introspection::src5::SRC5Component;\\n use openzeppelin::security::pausable::PausableComponent;\\n use openzeppelin::token::erc20::interface::{\\n IERC20Dispatcher, IERC20DispatcherTrait, IERC20MetadataDispatcher,\\n IERC20MetadataDispatcherTrait,\\n };\\n use openzeppelin::upgrades::UpgradeableComponent;\\n use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};\\n use starknet::{ClassHash, ContractAddress, get_contract_address};\\n use crate::constants::{\\n FEE_MANAGER_ROLE, PAUSE_MANAGER_ROLE, RATE_LIMITER_MANAGER_ROLE, UPGRADE_MANAGER_ROLE,\\n };\\n use crate::errors::{\\n err_caller_not_owner_or_missing_role, err_no_fees_to_withdraw, err_transfer_failed,\\n };\\n use crate::interface::{\\n IMintableTokenDispatcher, IMintableTokenDispatcherTrait, IOFTMintBurnAdapter,\\n };\\n\\n\\n // =============================== Components ===============================\\n\\n component!(path: AccessControlComponent, storage: access_control, event: AccessControlEvent);\\n component!(path: SRC5Component, storage: src5, event: SRC5Event);\\n component!(path: PausableComponent, storage: pausable, event: PausableEvent);\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n component!(path: OAppCoreComponent, storage: oapp_core, event: OAppCoreEvent);\\n component!(path: OFTCoreComponent, storage: oft_core, event: OFTCoreEvent);\\n component!(\\n path: OAppOptionsType3Component, storage: oapp_options_type_3, event: OAppOptionsType3Event,\\n );\\n component!(path: FeeComponent, storage: fee, event: FeeEvent);\\n component!(path: RateLimiterComponent, storage: rate_limiter, event: RateLimiterEvent);\\n component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);\\n\\n // =============================== Impls ===============================\\n\\n #[abi(embed_v0)]\\n impl AccessControlImpl =\\n AccessControlComponent::AccessControlImpl<ContractState>;\\n impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl PausableImpl = PausableComponent::PausableImpl<ContractState>;\\n impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;\\n impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl OAppCoreImpl = OAppCoreComponent::OAppCoreImpl<ContractState>;\\n impl OAppCoreInternalImpl = OAppCoreComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl IOAppReceiverImpl = OAppCoreComponent::OAppReceiverImpl<ContractState>;\\n #[abi(embed_v0)]\\n impl ILayerZeroReceiverImpl =\\n OAppCoreComponent::LayerZeroReceiverImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl OFTCoreImpl = OFTCoreComponent::OFTCoreImpl<ContractState>;\\n impl OFTCoreInternalImpl = OFTCoreComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl OAppOptionsType3Impl =\\n OAppOptionsType3Component::OAppOptionsType3Impl<ContractState>;\\n impl OAppOptionsType3InternalImpl = OAppOptionsType3Component::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl FeeImpl = FeeComponent::FeeImpl<ContractState>;\\n impl FeeInternalImpl = FeeComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl RateLimiterImpl = RateLimiterComponent::RateLimiterImpl<ContractState>;\\n\\n impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;\\n\\n // =============================== Storage ===============================\\n\\n #[storage]\\n struct Storage {\\n erc20_token: ContractAddress,\\n minter_burner: ContractAddress,\\n fee_balance: u256,\\n #[substorage(v0)]\\n access_control: AccessControlComponent::Storage,\\n #[substorage(v0)]\\n src5: SRC5Component::Storage,\\n #[substorage(v0)]\\n pausable: PausableComponent::Storage,\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n #[substorage(v0)]\\n oapp_core: OAppCoreComponent::Storage,\\n #[substorage(v0)]\\n oft_core: OFTCoreComponent::Storage,\\n #[substorage(v0)]\\n oapp_options_type_3: OAppOptionsType3Component::Storage,\\n #[substorage(v0)]\\n fee: FeeComponent::Storage,\\n #[substorage(v0)]\\n rate_limiter: RateLimiterComponent::Storage,\\n #[substorage(v0)]\\n upgradeable: UpgradeableComponent::Storage,\\n }\\n\\n // =============================== Events ===============================\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n FeeWithdrawn: FeeWithdrawn,\\n #[flat]\\n AccessControlEvent: AccessControlComponent::Event,\\n #[flat]\\n SRC5Event: SRC5Component::Event,\\n #[flat]\\n PausableEvent: PausableComponent::Event,\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n #[flat]\\n OAppCoreEvent: OAppCoreComponent::Event,\\n #[flat]\\n OFTCoreEvent: OFTCoreComponent::Event,\\n #[flat]\\n OAppOptionsType3Event: OAppOptionsType3Component::Event,\\n #[flat]\\n FeeEvent: FeeComponent::Event,\\n #[flat]\\n RateLimiterEvent: RateLimiterComponent::Event,\\n #[flat]\\n UpgradeableEvent: UpgradeableComponent::Event,\\n }\\n\\n #[derive(Drop, starknet::Event)]\\n pub struct FeeWithdrawn {\\n pub to: ContractAddress,\\n pub amount_ld: u256,\\n }\\n\\n // =============================== Constructor ===============================\\n\\n #[constructor]\\n fn constructor(\\n ref self: ContractState,\\n erc20_token: ContractAddress,\\n minter_burner: ContractAddress,\\n lz_endpoint: ContractAddress,\\n owner: ContractAddress,\\n native_token: ContractAddress,\\n shared_decimals: u8,\\n ) {\\n self.erc20_token.write(erc20_token);\\n self.minter_burner.write(minter_burner);\\n\\n self.ownable.initializer(owner);\\n self.oapp_core.initializer(lz_endpoint, owner, native_token);\\n\\n // Get local decimals from the ERC20 token using ERC20Metadata interface\\n let token = IERC20MetadataDispatcher { contract_address: erc20_token };\\n let local_decimals = token.decimals();\\n self.oft_core.initializer(local_decimals, shared_decimals);\\n\\n // Initialize access control roles - only grant DEFAULT_ADMIN_ROLE to owner\\n // Other roles should be granted explicitly after deployment\\n self.access_control._grant_role(DEFAULT_ADMIN_ROLE, owner);\\n }\\n\\n #[abi(embed_v0)]\\n impl OFTMintBurnAdapterImpl of IOFTMintBurnAdapter<ContractState> {\\n // =============================== View ===============================\\n\\n fn get_minter_burner(self: @ContractState) -> ContractAddress {\\n self.minter_burner.read()\\n }\\n\\n fn fee_balance(self: @ContractState) -> u256 {\\n self.fee_balance.read()\\n }\\n\\n // =============================== Rate Limiter Manager ===============================\\n\\n fn set_rate_limits(\\n ref self: ContractState,\\n rate_limits: Array<RateLimitConfig>,\\n direction: RateLimitDirection,\\n ) {\\n self._assert_owner_or_role(RATE_LIMITER_MANAGER_ROLE);\\n self.rate_limiter._set_rate_limits(rate_limits, direction);\\n }\\n\\n fn set_rate_limits_enabled(ref self: ContractState, enabled: RateLimitEnabled) {\\n self._assert_owner_or_role(RATE_LIMITER_MANAGER_ROLE);\\n self.rate_limiter._set_rate_limit_enabled(enabled);\\n }\\n\\n fn reset_rate_limits(ref self: ContractState, eids: Array<u32>) {\\n self._assert_owner_or_role(RATE_LIMITER_MANAGER_ROLE);\\n self.rate_limiter._reset_rate_limits(eids);\\n }\\n\\n // =============================== Fee Manager ===============================\\n\\n fn withdraw_fees(ref self: ContractState, to: ContractAddress) {\\n self._assert_owner_or_role(FEE_MANAGER_ROLE);\\n\\n let fee_balance = self.fee_balance.read();\\n assert_with_byte_array(fee_balance > 0, err_no_fees_to_withdraw());\\n\\n self.fee_balance.write(0);\\n let token = IERC20Dispatcher { contract_address: self.erc20_token.read() };\\n let result = token.transfer(to, fee_balance);\\n assert_with_byte_array(result, err_transfer_failed(to, fee_balance));\\n\\n self.emit(FeeWithdrawn { to, amount_ld: fee_balance });\\n }\\n\\n // =============================== Upgrade Manager ===============================\\n\\n fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {\\n self._assert_owner_or_role(UPGRADE_MANAGER_ROLE);\\n self.upgradeable.upgrade(new_class_hash);\\n }\\n\\n fn upgrade_and_call(\\n ref self: ContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252> {\\n self._assert_owner_or_role(UPGRADE_MANAGER_ROLE);\\n self.upgradeable.upgrade_and_call(new_class_hash, selector, calldata)\\n }\\n\\n // =============================== Pausable ===============================\\n\\n fn pause(ref self: ContractState) {\\n self._assert_owner_or_role(PAUSE_MANAGER_ROLE);\\n self.pausable.pause();\\n }\\n\\n fn unpause(ref self: ContractState) {\\n self._assert_owner_or_role(PAUSE_MANAGER_ROLE);\\n self.pausable.unpause();\\n }\\n }\\n\\n // =============================== Internal Access Control ===============================\\n\\n #[generate_trait]\\n pub impl InternalAccessControlImpl of InternalAccessControlTrait {\\n fn _assert_owner_or_role(self: @ContractState, role: felt252) {\\n let caller = starknet::get_caller_address();\\n let is_owner = caller == self.ownable.owner();\\n let has_role = self.access_control.has_role(role, caller);\\n\\n assert_with_byte_array(\\n is_owner || has_role, err_caller_not_owner_or_missing_role(role),\\n );\\n }\\n }\\n\\n // =============================== OFT Hooks ===============================\\n\\n impl OFTHooksImpl of OFTCoreComponent::OFTHooks<ContractState> {\\n fn _debit(\\n ref self: OFTCoreComponent::ComponentState<ContractState>,\\n from: ContractAddress,\\n amount: u256,\\n min_amount: u256,\\n dst_eid: u32,\\n ) -> OFTDebit {\\n // Check contract is not paused\\n let contract = self.get_contract();\\n contract.pausable.assert_not_paused();\\n\\n let oft_debit = self._debit_view(amount, min_amount, dst_eid);\\n let fee = oft_debit.amount_sent_ld - oft_debit.amount_received_ld;\\n\\n let mut contract = self.get_contract_mut();\\n contract.rate_limiter._outflow(dst_eid, oft_debit.amount_received_ld);\\n\\n let minter_burner = IMintableTokenDispatcher {\\n contract_address: contract.minter_burner.read(),\\n };\\n\\n if fee > 0 {\\n contract.fee_balance.write(contract.fee_balance.read() + fee);\\n minter_burner.permissioned_mint(get_contract_address(), fee);\\n }\\n\\n minter_burner.permissioned_burn(from, oft_debit.amount_sent_ld);\\n\\n oft_debit\\n }\\n\\n fn _debit_view(\\n self: @OFTCoreComponent::ComponentState<ContractState>,\\n amount_ld: u256,\\n min_amount_ld: u256,\\n dst_eid: u32,\\n ) -> OFTDebit {\\n // Calculate a fee based on the amount BEFORE the dust is deducted.\\n let fee = self.get_contract().fee.get_fee(dst_eid, amount_ld);\\n let amount_received_ld = self._remove_dust(amount_ld - fee);\\n\\n assert_with_byte_array(\\n amount_received_ld >= min_amount_ld,\\n err_slippage_exceeded(amount_received_ld, min_amount_ld),\\n );\\n\\n let amount_sent_ld = amount_received_ld + fee;\\n\\n OFTDebit { amount_sent_ld, amount_received_ld }\\n }\\n\\n fn _credit(\\n ref self: OFTCoreComponent::ComponentState<ContractState>,\\n to: ContractAddress,\\n amount: u256,\\n src_eid: u32,\\n ) -> u256 {\\n // Check contract is not paused\\n let contract = self.get_contract();\\n contract.pausable.assert_not_paused();\\n\\n // Handle the zero address case\\n let to = if to.is_zero() {\\n DEAD_ADDRESS\\n } else {\\n to\\n };\\n\\n let mut contract = self.get_contract_mut();\\n contract.rate_limiter._inflow(src_eid, amount);\\n\\n let minter_burner = IMintableTokenDispatcher {\\n contract_address: contract.minter_burner.read(),\\n };\\n minter_burner.permissioned_mint(to, amount);\\n\\n amount\\n }\\n\\n fn _token(self: @OFTCoreComponent::ComponentState<ContractState>) -> ContractAddress {\\n self.get_contract().erc20_token.read()\\n }\\n\\n fn _approval_required(self: @OFTCoreComponent::ComponentState<ContractState>) -> bool {\\n // No approval since we mint/burn.\\n false\\n }\\n }\\n}\\n\",\n \"contracts/oft_mint_burn/Scarb.toml\": \"[package]\\nname = \\\"oft_mint_burn\\\"\\nversion = \\\"0.1.0\\\"\\nedition = \\\"2024_07\\\"\\n\\n# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html\\n\\n[dependencies]\\nstarknet = \\\"2.14.0\\\"\\nopenzeppelin = \\\"2.0.0\\\"\\nlz_utils = { path = \\\"../../node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils\\\" }\\nlayerzero = { path = \\\"../../node_modules/@layerzerolabs/protocol-starknet-v2/layerzero\\\" }\\n\\n[dev-dependencies]\\nsnforge_std = \\\"0.49.0\\\"\\nassert_macros = \\\"2.12.0\\\"\\nstarkware_utils_testing = { git = \\\"https://github.com/starkware-libs/starkware-starknet-utils\\\", rev = \\\"e1955423808045de868987b8fb0b43f5cbdf5699\\\" }\\n\\n[[target.starknet-contract]]\\nsierra = true\\ncasm = true\\n\\n\\n[scripts]\\ntest = \\\"snforge test\\\"\\n\\n[tool.scarb]\\nallow-prebuilt-plugins = [\\\"snforge_scarb_plugin\\\", \\\"snforge_std\\\"]\\n\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils/src/byte_array_ext/bit_array.cairo\": \"// SPDX-License-Identifier: MIT\\n// Based on code from Alexandria (https://github.com/keep-starknet-strange/alexandria)\\n// Copyright (c) 2023 Alexandria Contributors\\n\\nuse core::bytes_31::bytes31;\\nuse core::integer::u512;\\nuse core::ops::index::IndexView;\\nuse core::serde::Serde;\\nuse core::serde::into_felt252_based::SerdeImpl;\\n\\nconst SELECT_BIT: u128 = 0b10;\\nconst POW_2_128: felt252 = 0x100000000000000000000000000000000;\\nconst BYTES_IN_U128: usize = 16;\\nconst BYTES_IN_BYTES31: usize = 31;\\nconst BYTES_IN_BYTES31_MINUS_ONE: usize = BYTES_IN_BYTES31 - 1;\\n\\n#[derive(Clone, Drop)]\\npub struct BitArray {\\n data: Array<bytes31>,\\n current: felt252,\\n read_pos: usize,\\n write_pos: usize,\\n}\\n\\nimpl BitArrayDefaultImpl of Default<BitArray> {\\n fn default() -> BitArray {\\n BitArray { data: array![], current: 0, read_pos: 0, write_pos: 0 }\\n }\\n}\\n\\npub trait BitArrayTrait {\\n /// Creates a new BitArray instance.\\n /// #### Arguments\\n /// * `data` - Array of bytes31 data\\n /// * `current` - Current working felt252 value\\n /// * `read_pos` - Current read position\\n /// * `write_pos` - Current write position\\n fn new(data: Array<bytes31>, current: felt252, read_pos: usize, write_pos: usize) -> BitArray;\\n /// Gets the current working felt252 value.\\n /// #### Arguments\\n /// * `self` - The BitArray to get the current value from\\n fn current(self: @BitArray) -> felt252;\\n /// Gets the underlying data array.\\n /// #### Arguments\\n /// * `self` - The BitArray to get the data from\\n fn data(self: BitArray) -> Array<bytes31>;\\n /// Appends a single bit to the BitArray\\n /// #### Arguments\\n /// * `self` - The BitArray to append to\\n /// * `bit` - either true or false, representing a single bit to be appended\\n fn append_bit(ref self: BitArray, bit: bool);\\n /// Reads a single bit from the array\\n /// #### Arguments\\n /// * `self` - The BitArray to read from\\n /// * `index` - the index into the array to read\\n /// #### Returns\\n /// `Option<bool>` - if the index is found, the stored bool is returned\\n fn at(self: @BitArray, index: usize) -> Option<bool>;\\n /// The current length of the BitArray\\n /// #### Arguments\\n /// * `self` - The BitArray to get the length of\\n /// #### Returns\\n /// `usize` - length in bits of the BitArray\\n fn len(self: @BitArray) -> usize;\\n /// Returns and removes the first element of the BitArray\\n /// #### Arguments\\n /// * `self` - The BitArray to pop from\\n /// #### Returns\\n /// `Option<bool>` - If the array is non-empty, a `bool` is removed from the front and returned\\n fn pop_front(ref self: BitArray) -> Option<bool>;\\n /// Reads a single word of the specified length up to 248 bits in big endian bit representation\\n /// #### Arguments\\n /// * `self` - The BitArray to read from\\n /// * `length` - The bit length of the word to read, max 248\\n /// #### Returns\\n /// `Option<felt252>` - If there are `length` bits remaining, the word is returned as felt252\\n fn read_word_be(ref self: BitArray, length: usize) -> Option<felt252>;\\n /// Reads a single word of the specified length up to 256 bits in big endian representation.\\n /// For words shorter than (or equal to) 248 bits use `read_word_be(...)` instead.\\n /// #### Arguments\\n /// * `self` - The BitArray to read from\\n /// * `length` - The bit length of the word to read, max 256\\n /// #### Returns\\n /// `Option<u256>` - If there are `length` bits remaining, the word is returned as u256\\n fn read_word_be_u256(ref self: BitArray, length: usize) -> Option<u256>;\\n /// Reads a single word of the specified length up to 512 bits in big endian representation.\\n /// For words shorter than (or equal to) 256 bits consider the other read calls instead.\\n /// #### Arguments\\n /// * `self` - The BitArray to read from\\n /// * `length` - The bit length of the word to read, max 512\\n /// #### Returns\\n /// `Option<u512>` - If there are `length` bits remaining, the word is returned as u512\\n fn read_word_be_u512(ref self: BitArray, length: usize) -> Option<u512>;\\n /// Writes the bits of the specified length from `word` onto the BitArray\\n /// in big endian representation\\n /// #### Arguments\\n /// * `self` - The BitArray to write to\\n /// * `word` - The value to store onto the bit array of type `felt252`\\n /// * `length` - The length of the word in bits, maximum 248\\n fn write_word_be(ref self: BitArray, word: felt252, length: usize);\\n /// Writes the bits of the specified length from `word` onto the BitArray\\n /// in big endian representation\\n /// #### Arguments\\n /// * `self` - The BitArray to write to\\n /// * `word` - The value to store onto the bit array of type `u256`\\n /// * `length` - The length of the word in bits, maximum 256\\n fn write_word_be_u256(ref self: BitArray, word: u256, length: usize);\\n /// Writes the bits of the specified length from `word` onto the BitArray\\n /// in big endian representation\\n /// #### Arguments\\n /// * `self` - The BitArray to write to\\n /// * `word` - The value to store onto the bit array of type `u512`\\n /// * `length` - The length of the word in bits, maximum 512\\n fn write_word_be_u512(ref self: BitArray, word: u512, length: usize);\\n /// Reads a single word of the specified length up to 248 bits in little endian bit\\n /// representation\\n /// #### Arguments\\n /// * `self` - The BitArray to read from\\n /// * `length` - The bit length of the word to read, max 248\\n /// #### Returns\\n /// `Option<felt252>` - If there are `length` bits remaining, the word is returned as felt252\\n fn read_word_le(ref self: BitArray, length: usize) -> Option<felt252>;\\n /// Reads a single word of the specified length up to 256 bits in little endian representation.\\n /// For words shorter than (or equal to) 248 bits use `read_word_be(...)` instead.\\n /// #### Arguments\\n /// * `self` - The BitArray to read from\\n /// * `length` - The bit length of the word to read, max 256\\n /// #### Returns\\n /// `Option<u256>` - If there are `length` bits remaining, the word is returned as u256\\n fn read_word_le_u256(ref self: BitArray, length: usize) -> Option<u256>;\\n /// Reads a single word of the specified length up to 512 bits in little endian representation.\\n /// For words shorter than (or equal to) 256 bits consider the other read calls instead.\\n /// #### Arguments\\n /// * `self` - The BitArray to read from\\n /// * `length` - The bit length of the word to read, max 512\\n /// #### Returns\\n /// `Option<u512>` - If there are `length` bits remaining, the word is returned as u512\\n fn read_word_le_u512(ref self: BitArray, length: usize) -> Option<u512>;\\n /// Writes the bits of the specified length from `word` onto the BitArray\\n /// in little endian representation\\n /// #### Arguments\\n /// * `self` - The BitArray to write to\\n /// * `word` - The value to store onto the bit array of type `felt252`\\n /// * `length` - The length of the word in bits, maximum 248\\n fn write_word_le(ref self: BitArray, word: felt252, length: usize);\\n /// Writes the bits of the specified length from `word` onto the BitArray\\n /// in little endian representation\\n /// #### Arguments\\n /// * `self` - The BitArray to write to\\n /// * `word` - The value to store onto the bit array of type `u256`\\n /// * `length` - The length of the word in bits, maximum 256\\n fn write_word_le_u256(ref self: BitArray, word: u256, length: usize);\\n /// Writes the bits of the specified length from `word` onto the BitArray\\n /// in little endian representation\\n /// #### Arguments\\n /// * `self` - The BitArray to write to\\n /// * `word` - The value to store onto the bit array of type `u512`\\n /// * `length` - The length of the word in bits, maximum 512\\n fn write_word_le_u512(ref self: BitArray, word: u512, length: usize);\\n}\\n\\nimpl BitArrayImpl of BitArrayTrait {\\n fn new(data: Array<bytes31>, current: felt252, read_pos: usize, write_pos: usize) -> BitArray {\\n BitArray { data, current, read_pos, write_pos }\\n }\\n\\n fn current(self: @BitArray) -> felt252 {\\n *self.current\\n }\\n\\n fn data(self: BitArray) -> Array<bytes31> {\\n self.data\\n }\\n\\n fn append_bit(ref self: BitArray, bit: bool) {\\n let (byte_number, bit_offset) = DivRem::div_rem(\\n self.write_pos, 8_usize.try_into().unwrap(),\\n );\\n let byte_offset = BYTES_IN_BYTES31_MINUS_ONE - (byte_number % BYTES_IN_BYTES31);\\n let bit_offset = 7 - bit_offset;\\n self.write_pos += 1;\\n if bit {\\n self.current += one_shift_left_bytes_felt252(byte_offset).into()\\n * shift_bit(bit_offset).into();\\n }\\n if byte_offset + bit_offset == 0 {\\n self.data.append(self.current.try_into().unwrap());\\n self.current = 0;\\n }\\n }\\n\\n fn at(self: @BitArray, index: usize) -> Option<bool> {\\n if index >= self.len() {\\n Option::None\\n } else {\\n let (word, byte_offset, bit_offset) = self.word_and_offset(index + *self.read_pos);\\n Option::Some(select(word, byte_offset, bit_offset))\\n }\\n }\\n\\n #[inline]\\n fn len(self: @BitArray) -> usize {\\n *self.write_pos - *self.read_pos\\n }\\n\\n fn pop_front(ref self: BitArray) -> Option<bool> {\\n let result = self.at(0)?;\\n self.read_pos += 1;\\n Option::Some(result)\\n }\\n\\n fn read_word_be(ref self: BitArray, length: usize) -> Option<felt252> {\\n assert(length <= 248, 'illegal length');\\n self._read_word_be_recursive(0, length)\\n }\\n\\n fn read_word_be_u256(ref self: BitArray, length: usize) -> Option<u256> {\\n assert(length <= 256, 'illegal length');\\n Option::Some(\\n if length > 128 {\\n let high = self._read_word_be_recursive(0, length - 128)?.try_into().unwrap();\\n let low = self._read_word_be_recursive(0, 128)?.try_into().unwrap();\\n u256 { low, high }\\n } else {\\n let high = 0;\\n let low = self._read_word_be_recursive(0, length)?.try_into().unwrap();\\n u256 { low, high }\\n },\\n )\\n }\\n\\n fn read_word_be_u512(ref self: BitArray, length: usize) -> Option<u512> {\\n assert(length <= 512, 'illegal length');\\n Option::Some(\\n if length > 384 {\\n let limb3 = self._read_word_be_recursive(0, length - 384)?.try_into().unwrap();\\n let limb2 = self._read_word_be_recursive(0, 128)?.try_into().unwrap();\\n let limb1 = self._read_word_be_recursive(0, 128)?.try_into().unwrap();\\n let limb0 = self._read_word_be_recursive(0, 128)?.try_into().unwrap();\\n u512 { limb0, limb1, limb2, limb3 }\\n } else if length > 256 {\\n let limb3 = 0;\\n let limb2 = self._read_word_be_recursive(0, length - 256)?.try_into().unwrap();\\n let limb1 = self._read_word_be_recursive(0, 128)?.try_into().unwrap();\\n let limb0 = self._read_word_be_recursive(0, 128)?.try_into().unwrap();\\n u512 { limb0, limb1, limb2, limb3 }\\n } else if length > 128 {\\n let limb3 = 0;\\n let limb2 = 0;\\n let limb1 = self._read_word_be_recursive(0, length - 128)?.try_into().unwrap();\\n let limb0 = self._read_word_be_recursive(0, 128)?.try_into().unwrap();\\n u512 { limb0, limb1, limb2, limb3 }\\n } else {\\n let limb3 = 0;\\n let limb2 = 0;\\n let limb1 = 0;\\n let limb0 = self._read_word_be_recursive(0, length)?.try_into().unwrap();\\n u512 { limb0, limb1, limb2, limb3 }\\n },\\n )\\n }\\n\\n fn write_word_be(ref self: BitArray, word: felt252, length: usize) {\\n assert(length <= 248, 'illegal length');\\n if length == 0 {\\n return;\\n }\\n let (mut byte_offset, mut bit_offset) = DivRem::div_rem(\\n length - 1, 8_usize.try_into().unwrap(),\\n );\\n loop {\\n self.append_bit(select(word, byte_offset, bit_offset));\\n if bit_offset == 0 {\\n if byte_offset == 0 {\\n break;\\n } else {\\n bit_offset = 8;\\n byte_offset -= 1;\\n }\\n }\\n bit_offset -= 1;\\n };\\n }\\n\\n fn write_word_be_u256(ref self: BitArray, word: u256, length: usize) {\\n assert(length <= 256, 'illegal length');\\n let u256 { low, high } = word;\\n if length > 128 {\\n self.write_word_be(high.into(), length - 128);\\n self.write_word_be(low.into(), 128);\\n } else {\\n self.write_word_be(low.into(), length);\\n }\\n }\\n\\n fn write_word_be_u512(ref self: BitArray, word: u512, length: usize) {\\n assert(length <= 512, 'illegal length');\\n let u512 { limb0, limb1, limb2, limb3 } = word;\\n\\n if length > 384 {\\n self.write_word_be(limb3.into(), length - 384);\\n self.write_word_be(limb2.into(), 128);\\n self.write_word_be(limb1.into(), 128);\\n self.write_word_be(limb0.into(), 128);\\n } else if length > 256 {\\n self.write_word_be(limb2.into(), length - 256);\\n self.write_word_be(limb1.into(), 128);\\n self.write_word_be(limb0.into(), 128);\\n } else if length > 128 {\\n self.write_word_be(limb1.into(), length - 128);\\n self.write_word_be(limb0.into(), 128);\\n } else {\\n self.write_word_be(limb0.into(), length);\\n }\\n }\\n\\n fn read_word_le(ref self: BitArray, length: usize) -> Option<felt252> {\\n assert(length <= 248, 'illegal length');\\n if length == 0 {\\n return Option::None;\\n }\\n let (byte_limit, bit_limit) = DivRem::div_rem(length, 8_usize.try_into().unwrap());\\n let mut bit_offset = 0_usize;\\n let mut byte_offset = 0_usize;\\n let mut result: Option<felt252> = Option::Some(0);\\n while (bit_offset != bit_limit || byte_offset != byte_limit) {\\n match self.pop_front() {\\n Option::Some(bit) => {\\n if bit {\\n let shifted = one_shift_left_bytes_felt252(byte_offset);\\n let value = (shifted * shift_bit(bit_offset).into()) + result.unwrap();\\n result = Option::Some(value);\\n }\\n },\\n Option::None => {\\n result = Option::None;\\n break;\\n },\\n }\\n if bit_offset == 7 {\\n byte_offset += 1;\\n bit_offset = 0;\\n } else {\\n bit_offset += 1;\\n }\\n }\\n result\\n }\\n\\n fn read_word_le_u256(ref self: BitArray, length: usize) -> Option<u256> {\\n assert(length <= 256, 'illegal length');\\n Option::Some(\\n if length > 128 {\\n let low = self.read_word_le(128)?.try_into().unwrap();\\n let high = self.read_word_le(length - 128)?.try_into().unwrap();\\n u256 { low, high }\\n } else {\\n let low = self.read_word_le(length)?.try_into().unwrap();\\n let high = 0;\\n u256 { low, high }\\n },\\n )\\n }\\n\\n fn read_word_le_u512(ref self: BitArray, length: usize) -> Option<u512> {\\n assert(length <= 512, 'illegal length');\\n Option::Some(\\n if length > 384 {\\n let limb0 = self.read_word_le(128)?;\\n let limb1 = self.read_word_le(128)?;\\n let limb2 = self.read_word_le(128)?;\\n let limb3 = self.read_word_le(length - 384)?;\\n u512 {\\n limb0: limb0.try_into().unwrap(),\\n limb1: limb1.try_into().unwrap(),\\n limb2: limb2.try_into().unwrap(),\\n limb3: limb3.try_into().unwrap(),\\n }\\n } else if length > 256 {\\n let limb0 = self.read_word_le(128)?;\\n let limb1 = self.read_word_le(128)?;\\n let limb2 = self.read_word_le(length - 256)?;\\n let limb3 = 0;\\n u512 {\\n limb0: limb0.try_into().unwrap(),\\n limb1: limb1.try_into().unwrap(),\\n limb2: limb2.try_into().unwrap(),\\n limb3,\\n }\\n } else if length > 128 {\\n let limb0 = self.read_word_le(128)?;\\n let limb1 = self.read_word_le(length - 128)?;\\n let limb2 = 0;\\n let limb3 = 0;\\n u512 {\\n limb0: limb0.try_into().unwrap(),\\n limb1: limb1.try_into().unwrap(),\\n limb2,\\n limb3,\\n }\\n } else {\\n let limb0 = self.read_word_le(length)?;\\n let limb1 = 0;\\n let limb2 = 0;\\n let limb3 = 0;\\n u512 { limb0: limb0.try_into().unwrap(), limb1, limb2, limb3 }\\n },\\n )\\n }\\n\\n fn write_word_le(ref self: BitArray, word: felt252, length: usize) {\\n assert(length <= 248, 'illegal length');\\n let u256 { low, high } = word.into();\\n if length > 128 {\\n self._write_word_le_recursive(low, 128);\\n self._write_word_le_recursive(high, length - 128);\\n } else {\\n self._write_word_le_recursive(low, length);\\n }\\n }\\n\\n fn write_word_le_u256(ref self: BitArray, word: u256, length: usize) {\\n assert(length <= 256, 'illegal length');\\n let u256 { low, high } = word;\\n if length > 128 {\\n self.write_word_le(low.into(), 128);\\n self.write_word_le(high.into(), length - 128);\\n } else {\\n self.write_word_le(low.into(), length);\\n }\\n }\\n\\n fn write_word_le_u512(ref self: BitArray, word: u512, length: usize) {\\n assert(length <= 512, 'illegal length');\\n let u512 { limb0, limb1, limb2, limb3 } = word;\\n if length > 384 {\\n self.write_word_le(limb0.into(), 128);\\n self.write_word_le(limb1.into(), 128);\\n self.write_word_le(limb2.into(), 128);\\n self.write_word_le(limb3.into(), length - 384);\\n } else if length > 256 {\\n self.write_word_le(limb0.into(), 128);\\n self.write_word_le(limb1.into(), 128);\\n self.write_word_le(limb2.into(), length - 256);\\n } else if length > 128 {\\n self.write_word_le(limb0.into(), 128);\\n self.write_word_le(limb1.into(), length - 128);\\n } else {\\n self.write_word_le(limb0.into(), length);\\n }\\n }\\n}\\n\\n#[generate_trait]\\nimpl BitArrayInternalImpl of BitArrayInternalTrait {\\n #[inline]\\n fn word_and_offset(self: @BitArray, index: usize) -> (felt252, usize, usize) {\\n let (byte_number, bit_offset) = DivRem::div_rem(index, 8_usize.try_into().unwrap());\\n let (word_index, byte_offset) = DivRem::div_rem(\\n byte_number, BYTES_IN_BYTES31.try_into().unwrap(),\\n );\\n let bit_offset = 7_usize - bit_offset;\\n let byte_offset = BYTES_IN_BYTES31_MINUS_ONE - byte_offset;\\n let word = if word_index == self.data.len() {\\n *self.current\\n } else {\\n let w = *self.data.at(word_index);\\n w.into()\\n };\\n (word, byte_offset, bit_offset)\\n }\\n\\n fn _write_word_le_recursive(ref self: BitArray, word: u128, length: usize) {\\n assert(length <= 128, 'illegal length');\\n if length == 0 {\\n return;\\n }\\n let bit = word % SELECT_BIT;\\n self.append_bit(bit == 1);\\n self._write_word_le_recursive(word / SELECT_BIT, length - 1);\\n }\\n\\n fn _read_word_be_recursive(\\n ref self: BitArray, current: felt252, length: usize,\\n ) -> Option<felt252> {\\n if length == 0 {\\n return Option::Some(current);\\n }\\n\\n let bit = self.pop_front()?;\\n let next = if bit {\\n 1\\n } else {\\n 0\\n };\\n self._read_word_be_recursive(current * 2 + next, length - 1)\\n }\\n}\\n\\nimpl BitArrayIndexView of IndexView<BitArray, usize> {\\n type Target = bool;\\n fn index(self: @BitArray, index: usize) -> bool {\\n self.at(index).expect('Index out of bounds')\\n }\\n}\\n\\nimpl BitArraySerde of Serde<BitArray> {\\n fn serialize(self: @BitArray, ref output: Array<felt252>) {\\n self.len().serialize(ref output);\\n self.data.serialize(ref output);\\n output.append(*self.current);\\n }\\n\\n fn deserialize(ref serialized: Span<felt252>) -> Option<BitArray> {\\n let write_pos = Serde::<u32>::deserialize(ref serialized)?;\\n let bytes31_arr = Serde::<Array<bytes31>>::deserialize(ref serialized)?;\\n let current = *serialized.pop_front()?;\\n Option::Some(BitArray { data: bytes31_arr, current, read_pos: 0, write_pos })\\n }\\n}\\n\\n/// Computes 2^number for bit positions 0-7 within a byte\\n///\\n/// This helper function returns the value of 2 raised to the given power,\\n/// specifically designed for bit manipulation within a single byte (0-7 bit positions).\\n/// It provides fast lookup for common bit shift operations.\\n///\\n/// #### Arguments\\n/// * `number` - The bit position (0-7) to compute 2^number for\\n///\\n/// #### Returns\\n/// * `u8` - The value 2^number as a u8, panics if number > 7\\n#[inline(always)]\\npub fn shift_bit(number: usize) -> u8 {\\n if number == 0 {\\n 1_u8\\n } else if number == 1 {\\n 0b10_u8\\n } else if number == 2 {\\n 0b100_u8\\n } else if number == 3 {\\n 0b1000_u8\\n } else if number == 4 {\\n 0b10000_u8\\n } else if number == 5 {\\n 0b100000_u8\\n } else if number == 6 {\\n 0b1000000_u8\\n } else if number == 7 {\\n 0b10000000_u8\\n } else {\\n panic!(\\\"invalid shift\\\")\\n }\\n}\\n\\n#[inline(always)]\\nfn select(word: felt252, byte_index: usize, bit_index: usize) -> bool {\\n let u256 { low, high } = word.into();\\n let shifted_bytes = if byte_index >= BYTES_IN_U128 {\\n high / one_shift_left_bytes_u128(byte_index - BYTES_IN_U128)\\n } else {\\n low / one_shift_left_bytes_u128(byte_index)\\n };\\n (shifted_bytes / shift_bit(bit_index).into()) % SELECT_BIT == 1\\n}\\n\\n/// Computes 256^n_bytes for felt252 byte shifting operations\\n///\\n/// This function calculates the value needed to shift bytes within a felt252 value.\\n/// Since felt252 can hold up to 31 bytes, this function handles the full range\\n/// by splitting calculations between the low and high 128-bit parts when necessary.\\n///\\n/// #### Arguments\\n/// * `n_bytes` - The number of byte positions to shift (0-30)\\n///\\n/// #### Returns\\n/// * `felt252` - The value 256^n_bytes for byte shifting operations\\npub fn one_shift_left_bytes_felt252(n_bytes: usize) -> felt252 {\\n if n_bytes < BYTES_IN_U128 {\\n one_shift_left_bytes_u128(n_bytes).into()\\n } else {\\n one_shift_left_bytes_u128(n_bytes - BYTES_IN_U128).into() * POW_2_128\\n }\\n}\\n\\n/// Computes 256^n_bytes for u128 byte shifting operations\\n///\\n/// This function provides a lookup table for powers of 256 up to 256^15,\\n/// which covers the full range of byte positions within a u128 value.\\n/// Each position represents shifting by one byte (8 bits) to the left.\\n///\\n/// #### Arguments\\n/// * `n_bytes` - The number of byte positions to shift (0-15)\\n///\\n/// #### Returns\\n/// * `u128` - The value 256^n_bytes, panics if n_bytes > 15\\npub fn one_shift_left_bytes_u128(n_bytes: usize) -> u128 {\\n match n_bytes {\\n 0 => 0x1,\\n 1 => 0x100,\\n 2 => 0x10000,\\n 3 => 0x1000000,\\n 4 => 0x100000000,\\n 5 => 0x10000000000,\\n 6 => 0x1000000000000,\\n 7 => 0x100000000000000,\\n 8 => 0x10000000000000000,\\n 9 => 0x1000000000000000000,\\n 10 => 0x100000000000000000000,\\n 11 => 0x10000000000000000000000,\\n 12 => 0x1000000000000000000000000,\\n 13 => 0x100000000000000000000000000,\\n 14 => 0x10000000000000000000000000000,\\n 15 => 0x1000000000000000000000000000000,\\n _ => core::panic_with_felt252(\\n 'n_bytes too big',\\n ) // For some reason we can't use panic!(\\\"\\\") macro here... (running out of gas)\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils/src/byte_array_ext/byte_appender.cairo\": \"// SPDX-License-Identifier: MIT\\n// Based on code from Alexandria (https://github.com/keep-starknet-strange/alexandria)\\n// Copyright (c) 2023 Alexandria Contributors\\n\\nuse core::integer::u512;\\nuse super::bit_array::{one_shift_left_bytes_felt252, one_shift_left_bytes_u128};\\n\\n/// Generic support trait for appending signed and unsigned integers onto byte storage.\\n/// There are two functions, one for each of big and little endian byte order due to\\n/// performance considerations. The byte reversal could be used in the naïve case when\\n/// only one implementation is worthwhile.\\npub trait ByteAppenderSupportTrait<T> {\\n /// Appends `bytes` data of size `count` ordered in big endian\\n /// #### Arguments\\n /// * `bytes` - big endian ordered bytes to append\\n /// * `count` - number of bytes from input to append\\n fn append_bytes_be(ref self: T, bytes: felt252, count: usize);\\n /// Appends `bytes` data of size `count` ordered in little endian\\n /// #### Arguments\\n /// * `bytes` - little endian ordered bytes to append\\n /// * `count` - number of bytes from input to append\\n fn append_bytes_le(ref self: T, bytes: felt252, count: usize);\\n}\\n\\nimpl ByteAppenderSupportArrayU8Impl of ByteAppenderSupportTrait<Array<u8>> {\\n fn append_bytes_be(ref self: Array<u8>, bytes: felt252, mut count: usize) {\\n assert(count <= 16, 'count too big');\\n let u256 { low, high: _high } = bytes.into();\\n while (count != 0) {\\n let next = (low / one_shift_left_bytes_u128(count - 1)) % 0x100;\\n // Unwrap safe by definition of modulus operation 0x100\\n self.append(next.try_into().unwrap());\\n count -= 1;\\n };\\n }\\n\\n fn append_bytes_le(ref self: Array<u8>, bytes: felt252, count: usize) {\\n assert(count <= 16, 'count too big');\\n let u256 { mut low, high: _high } = bytes.into();\\n let mut index = 0;\\n while (index != count) {\\n let (remaining_bytes, next) = DivRem::div_rem(low, 0x100_u128.try_into().unwrap());\\n low = remaining_bytes;\\n // Unwrap safe by definition of remainder from division by 0x100\\n self.append(next.try_into().unwrap());\\n index += 1;\\n };\\n }\\n}\\n\\npub trait ByteAppender<T> {\\n /// Appends an unsigned 16 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 16 bit unsigned integer typed as u16\\n fn append_u16(ref self: T, word: u16);\\n /// Appends an unsigned 16 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 16 bit unsigned integer typed as u16\\n fn append_u16_le(ref self: T, word: u16);\\n /// Appends an unsigned 32 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 32 bit unsigned integer typed as u32\\n fn append_u32(ref self: T, word: u32);\\n /// Appends an unsigned 32 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 32 bit unsigned integer typed as u32\\n fn append_u32_le(ref self: T, word: u32);\\n /// Appends an unsigned 64 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 64 bit unsigned integer typed as u64\\n fn append_u64(ref self: T, word: u64);\\n /// Appends an unsigned 64 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 64 bit unsigned integer typed as u64\\n fn append_u64_le(ref self: T, word: u64);\\n /// Appends an unsigned 128 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 128 bit unsigned integer typed as u128\\n fn append_u128(ref self: T, word: u128);\\n /// Appends an unsigned 128 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 128 bit unsigned integer typed as u128\\n fn append_u128_le(ref self: T, word: u128);\\n /// Appends an unsigned 256 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 256 bit unsigned integer typed as u256\\n fn append_u256(ref self: T, word: u256);\\n /// Appends an unsigned 256 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 256 bit unsigned integer typed as u256\\n fn append_u256_le(ref self: T, word: u256);\\n /// Appends an unsigned 512 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 512 bit unsigned integer typed as u512\\n fn append_u512(ref self: T, word: u512);\\n /// Appends an unsigned 512 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 512 bit unsigned integer typed as u512\\n fn append_u512_le(ref self: T, word: u512);\\n /// Appends a signed 8 bit integer\\n /// #### Arguments\\n /// * `word` - an 8 bit signed integer typed as i8\\n fn append_i8(ref self: T, word: i8);\\n /// Appends a signed 16 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 16 bit signed integer typed as i16\\n fn append_i16(ref self: T, word: i16);\\n /// Appends a signed 16 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 16 bit signed integer typed as i16\\n fn append_i16_le(ref self: T, word: i16);\\n /// Appends a signed 32 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 32 bit signed integer typed as i32\\n fn append_i32(ref self: T, word: i32);\\n /// Appends a signed 32 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 32 bit signed integer typed as i32\\n fn append_i32_le(ref self: T, word: i32);\\n /// Appends a signed 64 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 64 bit signed integer typed as i64\\n fn append_i64(ref self: T, word: i64);\\n /// Appends a signed 64 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 64 bit signed integer typed as i64\\n fn append_i64_le(ref self: T, word: i64);\\n /// Appends a signed 128 bit integer encoded in big endian\\n /// #### Arguments\\n /// * `word` - a 128 bit signed integer typed as i128\\n fn append_i128(ref self: T, word: i128);\\n /// Appends a signed 128 bit integer encoded in little endian\\n /// #### Arguments\\n /// * `word` - a 128 bit signed integer typed as i128\\n fn append_i128_le(ref self: T, word: i128);\\n}\\n\\nimpl ByteAppenderImpl<T, +Drop<T>, +ByteAppenderSupportTrait<T>> of ByteAppender<T> {\\n fn append_u16(ref self: T, word: u16) {\\n self.append_bytes_be(word.into(), 2);\\n }\\n\\n fn append_u16_le(ref self: T, word: u16) {\\n self.append_bytes_le(word.into(), 2);\\n }\\n\\n fn append_u32(ref self: T, word: u32) {\\n self.append_bytes_be(word.into(), 4);\\n }\\n\\n fn append_u32_le(ref self: T, word: u32) {\\n self.append_bytes_le(word.into(), 4);\\n }\\n\\n fn append_u64(ref self: T, word: u64) {\\n self.append_bytes_be(word.into(), 8);\\n }\\n\\n fn append_u64_le(ref self: T, word: u64) {\\n self.append_bytes_le(word.into(), 8);\\n }\\n\\n fn append_u128(ref self: T, word: u128) {\\n self.append_bytes_be(word.into(), 16);\\n }\\n\\n fn append_u128_le(ref self: T, word: u128) {\\n self.append_bytes_le(word.into(), 16);\\n }\\n\\n fn append_u256(ref self: T, word: u256) {\\n let u256 { low, high } = word;\\n self.append_u128(high);\\n self.append_u128(low);\\n }\\n\\n fn append_u256_le(ref self: T, word: u256) {\\n let u256 { low, high } = word;\\n self.append_u128_le(low);\\n self.append_u128_le(high);\\n }\\n\\n fn append_u512(ref self: T, word: u512) {\\n let u512 { limb0, limb1, limb2, limb3 } = word;\\n self.append_u128(limb3);\\n self.append_u128(limb2);\\n self.append_u128(limb1);\\n self.append_u128(limb0);\\n }\\n\\n fn append_u512_le(ref self: T, word: u512) {\\n let u512 { limb0, limb1, limb2, limb3 } = word;\\n self.append_u128_le(limb0);\\n self.append_u128_le(limb1);\\n self.append_u128_le(limb2);\\n self.append_u128_le(limb3);\\n }\\n\\n fn append_i8(ref self: T, word: i8) {\\n if word >= 0_i8 {\\n self.append_bytes_be(word.into(), 1);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(1), 1);\\n }\\n }\\n\\n fn append_i16(ref self: T, word: i16) {\\n if word >= 0_i16 {\\n self.append_bytes_be(word.into(), 2);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(2), 2);\\n }\\n }\\n\\n fn append_i16_le(ref self: T, word: i16) {\\n if word >= 0_i16 {\\n self.append_bytes_le(word.into(), 2);\\n } else {\\n self.append_bytes_le(word.into() + one_shift_left_bytes_felt252(2), 2);\\n }\\n }\\n\\n fn append_i32(ref self: T, word: i32) {\\n if word >= 0_i32 {\\n self.append_bytes_be(word.into(), 4);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(4), 4);\\n }\\n }\\n\\n fn append_i32_le(ref self: T, word: i32) {\\n if word >= 0_i32 {\\n self.append_bytes_le(word.into(), 4);\\n } else {\\n self.append_bytes_le(word.into() + one_shift_left_bytes_felt252(4), 4);\\n }\\n }\\n\\n fn append_i64(ref self: T, word: i64) {\\n if word >= 0_i64 {\\n self.append_bytes_be(word.into(), 8);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(8), 8);\\n }\\n }\\n\\n fn append_i64_le(ref self: T, word: i64) {\\n if word >= 0_i64 {\\n self.append_bytes_le(word.into(), 8);\\n } else {\\n self.append_bytes_le(word.into() + one_shift_left_bytes_felt252(8), 8);\\n }\\n }\\n\\n fn append_i128(ref self: T, word: i128) {\\n if word >= 0_i128 {\\n self.append_bytes_be(word.into(), 16);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(16), 16);\\n }\\n }\\n\\n fn append_i128_le(ref self: T, word: i128) {\\n if word >= 0_i128 {\\n self.append_bytes_le(word.into(), 16);\\n } else {\\n self.append_bytes_le(word.into() + one_shift_left_bytes_felt252(16), 16);\\n }\\n }\\n}\\n\\nimpl ArrayU8ByteAppenderImpl = ByteAppenderImpl<Array<u8>>;\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils/src/byte_array_ext/byte_array_ext.cairo\": \"// SPDX-License-Identifier: MIT\\n// Based on code from Alexandria (https://github.com/keep-starknet-strange/alexandria)\\n// Copyright (c) 2023 Alexandria Contributors\\n\\nuse core::integer::u512;\\nuse core::num::traits::Zero;\\nuse starknet::ContractAddress;\\nuse crate::byte_array_ext::bit_array::one_shift_left_bytes_felt252;\\nuse crate::byte_array_ext::byte_appender::{ByteAppender, ByteAppenderSupportTrait};\\n\\n\\n/// Implementation for converting a Span<u8> to a ByteArray\\n///\\n/// This conversion creates a new ByteArray by iterating through each byte\\n/// in the span and appending it to the ByteArray. This is useful for converting\\n/// byte spans to the more efficient ByteArray representation.\\n///\\n/// #### Arguments\\n/// * `self` - The Span<u8> to convert to ByteArray\\n///\\n/// #### Returns\\n/// * `ByteArray` - A new ByteArray containing all bytes from the input span\\npub impl SpanU8IntoByteArray of Into<Span<u8>, ByteArray> {\\n #[inline]\\n fn into(self: Span<u8>) -> ByteArray {\\n let mut reader: u32 = 0;\\n let mut result: ByteArray = Default::default();\\n while reader != self.len() {\\n result.append_byte(*self.at(reader));\\n reader = reader + 1;\\n }\\n result\\n }\\n}\\n\\n/// Implementation for converting an Array<u8> to a ByteArray\\n///\\n/// This conversion creates a new ByteArray from an Array<u8> by first converting\\n/// the array to a span and then using the SpanU8IntoByteArray implementation.\\n/// This provides a convenient way to convert byte arrays to ByteArray format.\\n///\\n/// #### Arguments\\n/// * `self` - The Array<u8> to convert to ByteArray\\n///\\n/// #### Returns\\n/// * `ByteArray` - A new ByteArray containing all bytes from the input array\\nimpl ArrayU8IntoByteArray of Into<Array<u8>, ByteArray> {\\n fn into(self: Array<u8>) -> ByteArray {\\n self.span().into()\\n }\\n}\\n\\n/// Implementation for converting a ByteArray to an Array<u8>\\n///\\n/// This conversion creates a new Array<u8> by iterating through each byte\\n/// in the ByteArray and appending it to the array. This is useful when you need\\n/// to work with individual bytes or interface with functions that expect Array<u8>.\\n///\\n/// #### Arguments\\n/// * `self` - The ByteArray to convert to Array<u8>\\n///\\n/// #### Returns\\n/// * `Array<u8>` - A new Array<u8> containing all bytes from the input ByteArray\\npub impl ByteArrayIntoArrayU8 of Into<ByteArray, Array<u8>> {\\n fn into(self: ByteArray) -> Array<u8> {\\n let mut reader: u32 = 0;\\n let mut result = array![];\\n while reader != self.len() {\\n let (_, byte) = self.read_u8(reader);\\n result.append(byte);\\n reader = reader + 1;\\n }\\n result\\n }\\n}\\n\\n/// Extension trait for reading and writing different data types to `ByteArray`\\npub trait ByteArrayTraitExt {\\n /// Create a ByteArray from an array of u128\\n /// #### Arguments\\n /// * `data` - Array of u128 values to create ByteArray from\\n /// #### Returns\\n /// * `ByteArray` - A new ByteArray created from the input data\\n fn new(data: Array<u128>) -> ByteArray;\\n /// instantiate a new ByteArray\\n /// #### Returns\\n /// * `ByteArray` - A new empty ByteArray\\n fn new_empty() -> ByteArray;\\n // get size. Same as len()\\n /// #### Arguments\\n /// * `self` - The ByteArray to get the size of\\n /// #### Returns\\n /// * `usize` - The size of the ByteArray\\n fn size(self: @ByteArray) -> usize;\\n /// Reads a 8-bit unsigned integer from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// #### Returns\\n /// * `(usize, u8)` - The new offset and the u8 value read\\n fn read_u8(self: @ByteArray, offset: usize) -> (usize, u8);\\n /// Reads a 16-bit unsigned integer from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// #### Returns\\n /// * `(usize, u16)` - The new offset and the u16 value read\\n fn read_u16(self: @ByteArray, offset: usize) -> (usize, u16);\\n /// Reads a 32-bit unsigned integer from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// #### Returns\\n /// * `(usize, u32)` - The new offset and the u32 value read\\n fn read_u32(self: @ByteArray, offset: usize) -> (usize, u32);\\n /// Reads a `usize` from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// #### Returns\\n /// * `(usize, usize)` - The new offset and the usize value read\\n fn read_usize(self: @ByteArray, offset: usize) -> (usize, usize);\\n /// Reads a 64-bit unsigned integer from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// #### Returns\\n /// * `(usize, u64)` - The new offset and the u64 value read\\n fn read_u64(self: @ByteArray, offset: usize) -> (usize, u64);\\n /// Reads a 128-bit unsigned integer from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// #### Returns\\n /// * `(usize, u128)` - The new offset and the u128 value read\\n fn read_u128(self: @ByteArray, offset: usize) -> (usize, u128);\\n /// Read value with size bytes from ByteArray, and packed into u128\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// * `size` - The number of bytes to read\\n /// #### Returns\\n /// * `(usize, u128)` - The new offset and the packed u128 value\\n fn read_u128_packed(self: @ByteArray, offset: usize, size: usize) -> (usize, u128);\\n /// Reads a packed array of `u128` values from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// * `array_length` - The length of the array to read\\n /// * `element_size` - The size of each element in bytes\\n /// #### Returns\\n /// * `(usize, Array<u128>)` - The new offset and the array of u128 values\\n fn read_u128_array_packed(\\n self: @ByteArray, offset: usize, array_length: usize, element_size: usize,\\n ) -> (usize, Array<u128>);\\n /// Reads a 256-bit unsigned integer from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// #### Returns\\n /// * `(usize, u256)` - The new offset and the u256 value read\\n fn read_u256(self: @ByteArray, offset: usize) -> (usize, u256);\\n /// Reads an array of `u256` values from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// * `array_length` - The length of the array to read\\n /// #### Returns\\n /// * `(usize, Array<u256>)` - The new offset and the array of u256 values\\n fn read_u256_array(\\n self: @ByteArray, offset: usize, array_length: usize,\\n ) -> (usize, Array<u256>);\\n /// Reads a `felt252` (Starknet field element) from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// #### Returns\\n /// * `(usize, felt252)` - The new offset and the felt252 value read\\n fn read_felt252(self: @ByteArray, offset: usize) -> (usize, felt252);\\n /// Read value with size bytes from Bytes, and packed into felt252\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// * `size` - The number of bytes to read\\n /// #### Returns\\n /// * `(usize, felt252)` - The new offset and the packed felt252 value\\n fn read_felt252_packed(self: @ByteArray, offset: usize, size: usize) -> (usize, felt252);\\n /// Reads a Starknet contract address from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// #### Returns\\n /// * `(usize, ContractAddress)` - The new offset and the contract address\\n fn read_address(self: @ByteArray, offset: usize) -> (usize, ContractAddress);\\n /// Reads a raw sequence of bytes of given `size` from the given offset.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// * `size` - The number of bytes to read\\n /// #### Returns\\n /// * `(usize, ByteArray)` - The new offset and the read bytes as ByteArray\\n fn read_bytes(self: @ByteArray, offset: usize, size: usize) -> (usize, ByteArray);\\n /// Appends a 8-bit unsigned integer to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u8(ref self: ByteArray, value: u8);\\n /// Appends a 16-bit unsigned integer to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u16(ref self: ByteArray, value: u16);\\n /// Appends a 16-bit unsigned integer to the `ByteArray` in little-endian format.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u16_le(ref self: ByteArray, value: u16);\\n /// Appends a 32-bit unsigned integer to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u32(ref self: ByteArray, value: u32);\\n /// Appends a 32-bit unsigned integer to the `ByteArray` in little-endian format.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u32_le(ref self: ByteArray, value: u32);\\n /// Appends usize to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_usize(ref self: ByteArray, value: usize);\\n /// Appends a 64-bit unsigned integer to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u64(ref self: ByteArray, value: u64);\\n /// Appends a 64-bit unsigned integer to the `ByteArray` in little-endian format.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u64_le(ref self: ByteArray, value: u64);\\n /// Appends a 128-bit unsigned integer to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u128(ref self: ByteArray, value: u128);\\n /// Appends a 128-bit unsigned integer to the `ByteArray` in little-endian format.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u128_le(ref self: ByteArray, value: u128);\\n /// Appends a 256-bit unsigned integer to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u256(ref self: ByteArray, value: u256);\\n /// Appends a 256-bit unsigned integer to the `ByteArray` in little-endian format.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u256_le(ref self: ByteArray, value: u256);\\n /// Appends a 512-bit unsigned integer to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_u512(ref self: ByteArray, value: u512);\\n /// Appends a `felt252` to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_felt252(ref self: ByteArray, value: felt252);\\n /// Appends bytes data of size `count` ordered in little endian\\n /// #### Arguments\\n /// * `bytes` - little endian ordered bytes to append\\n /// * `count` - number of bytes from input to append\\n fn append_bytes_le(ref self: ByteArray, bytes: felt252, count: usize);\\n /// Appends a Starknet contract address to the `ByteArray`.\\n /// #### Arguments\\n /// * `self` - The ByteArray to append to\\n /// * `value` - The value to append\\n fn append_address(ref self: ByteArray, value: ContractAddress);\\n /// Updates a byte at the given `offset` with a new value.\\n /// #### Arguments\\n /// * `self` - The ByteArray to update\\n /// * `offset` - The offset to update at\\n /// * `value` - The new value\\n fn update_at(ref self: ByteArray, offset: usize, value: u8);\\n /// Reads an unsigned integer of type T from the ByteArray starting at a given offset,\\n /// with a specified size.\\n /// #### Arguments\\n /// * `self` - The ByteArray to read from\\n /// * `offset` - The offset to read from\\n /// * `size` - The number of bytes to read\\n fn read_uint_within_size<\\n T, +Add<T>, +Mul<T>, +Zero<T>, +TryInto<felt252, T>, +Drop<T>, +Into<u8, T>,\\n >(\\n self: @ByteArray, offset: usize, size: usize,\\n ) -> (usize, T);\\n}\\n\\n\\npub impl ByteArrayTraitExtImpl of ByteArrayTraitExt {\\n /// Create a ByteArray from an array of u128\\n #[inline(always)]\\n fn new(mut data: Array<u128>) -> ByteArray {\\n if data.len() == 0 {\\n return Default::default();\\n }\\n let mut index = 0;\\n let mut ba: ByteArray = Default::default();\\n while index != data.len() {\\n Self::append_u128(ref ba, *data[index]);\\n index += 1;\\n }\\n ba\\n }\\n\\n /// instantiate a new ByteArray\\n #[inline(always)]\\n fn new_empty() -> ByteArray {\\n Default::default()\\n }\\n\\n /// get size. Same as len()\\n #[inline(always)]\\n fn size(self: @ByteArray) -> usize {\\n self.len()\\n }\\n\\n /// Read a u8 from ByteArray\\n #[inline(always)]\\n fn read_u8(self: @ByteArray, offset: usize) -> (usize, u8) {\\n assert(offset < self.len(), 'out of bound');\\n (offset + 1, self.at(offset).unwrap())\\n }\\n\\n /// Read a u16 from ByteArray\\n #[inline(always)]\\n fn read_u16(self: @ByteArray, offset: usize) -> (usize, u16) {\\n read_uint::<u16>(self, offset, 2)\\n }\\n\\n /// Read a u32 from ByteArray\\n #[inline(always)]\\n fn read_u32(self: @ByteArray, offset: usize) -> (usize, u32) {\\n read_uint::<u32>(self, offset, 4)\\n }\\n\\n /// Read a usize from ByteArray\\n #[inline(always)]\\n fn read_usize(self: @ByteArray, offset: usize) -> (usize, usize) {\\n read_uint::<usize>(self, offset, 4)\\n }\\n\\n /// Read a u64 from ByteArray\\n #[inline(always)]\\n fn read_u64(self: @ByteArray, offset: usize) -> (usize, u64) {\\n read_uint::<u64>(self, offset, 8)\\n }\\n\\n /// Read a u128 from ByteArray\\n #[inline(always)]\\n fn read_u128(self: @ByteArray, offset: usize) -> (usize, u128) {\\n read_uint::<u128>(self, offset, 16)\\n }\\n\\n /// Read value with size bytes from ByteArray, and packed into u128\\n /// #### Arguments:\\n /// - offset: the offset in Bytes\\n /// - size: the number of bytes to read\\n /// #### Returns:\\n /// - new_offset: next value offset in Bytes\\n /// - value: the value packed into u128\\n #[inline(always)]\\n fn read_u128_packed(self: @ByteArray, offset: usize, size: usize) -> (usize, u128) {\\n // check\\n assert(offset + size <= self.len(), 'out of bound');\\n assert(size <= 16, 'too large');\\n\\n self.read_uint_within_size::<u128>(offset, size)\\n }\\n\\n /// Read a u256 from ByteArray\\n #[inline(always)]\\n fn read_u256(self: @ByteArray, offset: usize) -> (usize, u256) {\\n read_uint::<u256>(self, offset, 32)\\n }\\n\\n /// Read value with size bytes from ByteArray, and packed into felt252\\n /// #### Arguments:\\n /// - offset: the offset in Bytes\\n /// - size: the number of bytes to read\\n /// #### Returns:\\n /// - new_offset: next value offset in Bytes\\n /// - value: the value packed into felt252\\n #[inline(always)]\\n fn read_felt252_packed(self: @ByteArray, offset: usize, size: usize) -> (usize, felt252) {\\n // check\\n assert(offset + size <= self.size(), 'out of bound');\\n // Bytes unit is one byte\\n // felt252 can hold 31 bytes max\\n assert(size <= 31, 'too large');\\n self.read_uint_within_size::<felt252>(offset, size)\\n }\\n\\n\\n #[inline(always)]\\n fn read_felt252(self: @ByteArray, offset: usize) -> (usize, felt252) {\\n let (new_offset, value) = read_uint::<felt252>(self, offset, 32);\\n (new_offset, value.try_into().expect('Couldn\\\\'t convert to felt252'))\\n }\\n\\n /// Read Contract Address from Bytes\\n #[inline(always)]\\n fn read_address(self: @ByteArray, offset: usize) -> (usize, ContractAddress) {\\n let (new_offset, value) = self.read_u256(offset);\\n let address: felt252 = value.try_into().expect('Couldn\\\\'t convert to felt252');\\n (new_offset, address.try_into().expect('Couldn\\\\'t convert to address'))\\n }\\n\\n /// Read bytes from ByteArray\\n #[inline(always)]\\n fn read_bytes(self: @ByteArray, offset: usize, size: usize) -> (usize, ByteArray) {\\n assert(offset + size <= self.len(), 'out of bound');\\n\\n if size == 0 {\\n return (offset, Default::default());\\n }\\n\\n let mut ba: ByteArray = Default::default();\\n\\n // read full array element for sub_bytes\\n let mut offset = offset;\\n //read per block of u32\\n let mut sub_bytes_full_array_len = size / 4;\\n\\n while sub_bytes_full_array_len != 0 {\\n let (new_offset, value) = self.read_u32(offset);\\n Self::append_u32(ref ba, value);\\n offset = new_offset;\\n sub_bytes_full_array_len -= 1;\\n }\\n\\n // process last array element for sub_bytes\\n // 1. read last element real value;\\n // 2. make last element full with padding 0;\\n let mut sub_bytes_last_element_size = size % 4;\\n while sub_bytes_last_element_size != 0 {\\n let value = self.at(offset).unwrap();\\n ba.append_byte(value);\\n sub_bytes_last_element_size -= 1;\\n offset += 1;\\n }\\n\\n return (offset, ba);\\n }\\n\\n /// Read an array of u128 values from ByteArray\\n #[inline(always)]\\n fn read_u128_array_packed(\\n self: @ByteArray, offset: usize, array_length: usize, element_size: usize,\\n ) -> (usize, Array<u128>) {\\n assert(offset + array_length * element_size <= self.len(), 'out of bound');\\n let mut array: Array<u128> = array![];\\n\\n if array_length == 0 {\\n return (offset, array);\\n }\\n let mut offset = offset;\\n let mut i = array_length;\\n while i != 0 {\\n let (new_offset, value) = self.read_uint_within_size::<u128>(offset, element_size);\\n array.append(value);\\n offset = new_offset;\\n i -= 1;\\n }\\n (offset, array)\\n }\\n\\n /// Read an array of u256 values from ByteArray\\n #[inline(always)]\\n fn read_u256_array(\\n self: @ByteArray, offset: usize, array_length: usize,\\n ) -> (usize, Array<u256>) {\\n assert(offset + array_length * 32 <= self.len(), 'out of bound');\\n let mut array = array![];\\n\\n if array_length == 0 {\\n return (offset, array);\\n }\\n\\n let mut offset = offset;\\n let mut i = array_length;\\n while i != 0 {\\n let (new_offset, value) = self.read_u256(offset);\\n array.append(value);\\n offset = new_offset;\\n i -= 1;\\n }\\n (offset, array)\\n }\\n\\n /// Reads an unsigned integer of type T from the ByteArray starting at a given offset,\\n /// with a specified size.\\n ///\\n /// Inputs:\\n /// - self: A reference to the ByteArray from which to read.\\n /// - offset: The starting position in the ByteArray to begin reading.\\n /// - size: The number of bytes to read.\\n ///\\n /// Outputs:\\n /// - A tuple containing:\\n /// - The new offset after reading the specified number of bytes.\\n /// - The value of type T read from the ByteArray.\\n fn read_uint_within_size<\\n T, +Add<T>, +Mul<T>, +Zero<T>, +TryInto<felt252, T>, +Drop<T>, +Into<u8, T>,\\n >(\\n self: @ByteArray, offset: usize, size: usize,\\n ) -> (usize, T) {\\n read_uint::<T>(self, offset, size)\\n }\\n\\n /// Append a u8 to ByteArray\\n fn append_u8(ref self: ByteArray, value: u8) {\\n self.append_byte(value);\\n }\\n\\n /// Append a u16 to ByteArray\\n #[inline]\\n fn append_u16(ref self: ByteArray, value: u16) {\\n self.append_word(value.into(), 2);\\n }\\n\\n /// Append a u16 to ByteArray in little-endian format\\n #[inline]\\n fn append_u16_le(ref self: ByteArray, value: u16) {\\n Self::append_bytes_le(ref self, value.into(), 2);\\n }\\n\\n /// Append a u32 to ByteArray\\n #[inline]\\n fn append_u32(ref self: ByteArray, value: u32) {\\n self.append_word(value.into(), 4);\\n }\\n\\n /// Append a u32 to ByteArray in little-endian format\\n #[inline]\\n fn append_u32_le(ref self: ByteArray, value: u32) {\\n Self::append_bytes_le(ref self, value.into(), 4);\\n }\\n\\n /// Append a usize to ByteArray\\n fn append_usize(ref self: ByteArray, value: usize) {\\n self.append_word(value.into(), 4);\\n }\\n\\n /// Append a u64 to ByteArray\\n #[inline]\\n fn append_u64(ref self: ByteArray, value: u64) {\\n self.append_word(value.into(), 8);\\n }\\n\\n /// Append a u64 to ByteArray in little-endian format\\n #[inline]\\n fn append_u64_le(ref self: ByteArray, value: u64) {\\n Self::append_bytes_le(ref self, value.into(), 8);\\n }\\n\\n /// Append a u128 to ByteArray\\n #[inline]\\n fn append_u128(ref self: ByteArray, value: u128) {\\n self.append_word(value.into(), 16);\\n }\\n\\n /// Append a u128 to ByteArray in little-endian format\\n #[inline]\\n fn append_u128_le(ref self: ByteArray, value: u128) {\\n Self::append_bytes_le(ref self, value.into(), 16);\\n }\\n\\n /// Append a u256 to ByteArray\\n fn append_u256(ref self: ByteArray, value: u256) {\\n Self::append_u128(ref self, value.high);\\n Self::append_u128(ref self, value.low);\\n }\\n\\n /// Append a u256 to ByteArray in little-endian format\\n fn append_u256_le(ref self: ByteArray, value: u256) {\\n Self::append_u128_le(ref self, value.low);\\n Self::append_u128_le(ref self, value.high);\\n }\\n\\n /// Append a u512 to ByteArray\\n fn append_u512(ref self: ByteArray, value: u512) {\\n let u512 { limb0, limb1, limb2, limb3 } = value;\\n Self::append_u128(ref self, limb3);\\n Self::append_u128(ref self, limb2);\\n Self::append_u128(ref self, limb1);\\n Self::append_u128(ref self, limb0);\\n }\\n\\n /// Append a felt252 to ByteArray\\n fn append_felt252(ref self: ByteArray, value: felt252) {\\n Self::append_u256(ref self, value.into());\\n }\\n\\n /// Append bytes data of size `count` ordered in little endian\\n fn append_bytes_le(ref self: ByteArray, bytes: felt252, count: usize) {\\n assert(count <= 16, 'count too big');\\n let u256 { mut low, high: _high } = bytes.into();\\n let mut index = 0;\\n while (index != count) {\\n let (remaining_bytes, next) = DivRem::div_rem(low, 0x100_u128.try_into().unwrap());\\n low = remaining_bytes;\\n // Unwrap safe by definition of remainder from division by 0x100\\n self.append_byte(next.try_into().unwrap());\\n index += 1;\\n };\\n }\\n\\n /// Append a ContractAddress to ByteArray\\n fn append_address(ref self: ByteArray, value: ContractAddress) {\\n let address: felt252 = value.into();\\n self.append_felt252(address);\\n }\\n\\n /// Update a byte at a specific offset in ByteArray\\n fn update_at(ref self: ByteArray, offset: usize, value: u8) {\\n assert(offset < self.len(), 'out of bound');\\n\\n let (_, temp_l) = self.read_bytes(0, offset);\\n let (_, temp_r) = self.read_bytes(offset + 1, self.len() - 1 - offset);\\n let mut new_byte_array: ByteArray = temp_l;\\n new_byte_array.append_byte(value);\\n new_byte_array.append(@temp_r);\\n self = new_byte_array;\\n }\\n}\\n\\nimpl ByteAppenderSupportByteArrayImpl of ByteAppenderSupportTrait<ByteArray> {\\n #[inline(always)]\\n fn append_bytes_be(ref self: ByteArray, bytes: felt252, count: usize) {\\n assert(count <= 16, 'count too big');\\n self.append_word(bytes.into(), count);\\n }\\n\\n #[inline(always)]\\n fn append_bytes_le(ref self: ByteArray, bytes: felt252, count: usize) {\\n // Use the same DivRem approach as ByteArrayTraitExtImpl for consistency\\n ByteArrayTraitExtImpl::append_bytes_le(ref self, bytes, count);\\n }\\n}\\n\\npub impl ByteArrayAppenderImpl of ByteAppender<T: ByteArray> {\\n fn append_u16(ref self: ByteArray, word: u16) {\\n ByteArrayTraitExtImpl::append_u16(ref self, word);\\n }\\n\\n fn append_u16_le(ref self: ByteArray, word: u16) {\\n ByteArrayTraitExtImpl::append_u16_le(ref self, word);\\n }\\n\\n fn append_u32(ref self: ByteArray, word: u32) {\\n ByteArrayTraitExtImpl::append_u32(ref self, word);\\n }\\n\\n fn append_u32_le(ref self: ByteArray, word: u32) {\\n ByteArrayTraitExtImpl::append_u32_le(ref self, word);\\n }\\n\\n fn append_u64(ref self: ByteArray, word: u64) {\\n ByteArrayTraitExtImpl::append_u64(ref self, word);\\n }\\n\\n fn append_u64_le(ref self: ByteArray, word: u64) {\\n ByteArrayTraitExtImpl::append_u64_le(ref self, word);\\n }\\n\\n fn append_u128(ref self: ByteArray, word: u128) {\\n ByteArrayTraitExtImpl::append_u128(ref self, word);\\n }\\n\\n fn append_u128_le(ref self: ByteArray, word: u128) {\\n ByteArrayTraitExtImpl::append_u128_le(ref self, word);\\n }\\n\\n fn append_u256(ref self: ByteArray, word: u256) {\\n ByteArrayTraitExtImpl::append_u256(ref self, word);\\n }\\n\\n fn append_u256_le(ref self: ByteArray, word: u256) {\\n let u256 { low, high } = word;\\n Self::append_u128_le(ref self, low);\\n Self::append_u128_le(ref self, high);\\n }\\n\\n fn append_u512(ref self: ByteArray, word: u512) {\\n ByteArrayTraitExtImpl::append_u512(ref self, word);\\n }\\n\\n fn append_u512_le(ref self: ByteArray, word: u512) {\\n let u512 { limb0, limb1, limb2, limb3 } = word;\\n Self::append_u128_le(ref self, limb0);\\n Self::append_u128_le(ref self, limb1);\\n Self::append_u128_le(ref self, limb2);\\n Self::append_u128_le(ref self, limb3);\\n }\\n\\n fn append_i8(ref self: ByteArray, word: i8) {\\n if word >= 0_i8 {\\n self.append_bytes_be(word.into(), 1);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(1), 1);\\n }\\n }\\n\\n fn append_i16(ref self: ByteArray, word: i16) {\\n if word >= 0_i16 {\\n self.append_bytes_be(word.into(), 2);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(2), 2);\\n }\\n }\\n\\n fn append_i16_le(ref self: ByteArray, word: i16) {\\n if word >= 0_i16 {\\n ByteArrayTraitExtImpl::append_bytes_le(ref self, word.into(), 2);\\n } else {\\n ByteArrayTraitExtImpl::append_bytes_le(\\n ref self, word.into() + one_shift_left_bytes_felt252(2), 2,\\n );\\n }\\n }\\n\\n fn append_i32(ref self: ByteArray, word: i32) {\\n if word >= 0_i32 {\\n self.append_bytes_be(word.into(), 4);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(4), 4);\\n }\\n }\\n\\n fn append_i32_le(ref self: ByteArray, word: i32) {\\n if word >= 0_i32 {\\n ByteArrayTraitExtImpl::append_bytes_le(ref self, word.into(), 4);\\n } else {\\n ByteArrayTraitExtImpl::append_bytes_le(\\n ref self, word.into() + one_shift_left_bytes_felt252(4), 4,\\n );\\n }\\n }\\n\\n fn append_i64(ref self: ByteArray, word: i64) {\\n if word >= 0_i64 {\\n self.append_bytes_be(word.into(), 8);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(8), 8);\\n }\\n }\\n\\n fn append_i64_le(ref self: ByteArray, word: i64) {\\n if word >= 0_i64 {\\n ByteArrayTraitExtImpl::append_bytes_le(ref self, word.into(), 8);\\n } else {\\n ByteArrayTraitExtImpl::append_bytes_le(\\n ref self, word.into() + one_shift_left_bytes_felt252(8), 8,\\n );\\n }\\n }\\n\\n fn append_i128(ref self: ByteArray, word: i128) {\\n if word >= 0_i128 {\\n self.append_bytes_be(word.into(), 16);\\n } else {\\n self.append_bytes_be(word.into() + one_shift_left_bytes_felt252(16), 16);\\n }\\n }\\n\\n fn append_i128_le(ref self: ByteArray, word: i128) {\\n if word >= 0_i128 {\\n ByteArrayTraitExtImpl::append_bytes_le(ref self, word.into(), 16);\\n } else {\\n ByteArrayTraitExtImpl::append_bytes_le(\\n ref self, word.into() + one_shift_left_bytes_felt252(16), 16,\\n );\\n }\\n }\\n}\\n\\n/// Reads an unsigned integer of type T from the ByteArray starting at a given offset,\\n/// with a specified size.\\n///\\n/// Inputs:\\n/// - self: A reference to the ByteArray from which to read.\\n/// - offset: The starting position in the ByteArray to begin reading.\\n/// - size: The number of bytes to read.\\n///\\n/// Outputs:\\n/// - A tuple containing:\\n/// - The new offset after reading the specified number of bytes.\\n/// - The value of type T read from the ByteArray.\\nfn read_uint<T, +Add<T>, +Mul<T>, +Zero<T>, +TryInto<felt252, T>, +Drop<T>, +Into<u8, T>>(\\n self: @ByteArray, offset: usize, size: usize,\\n) -> (usize, T) {\\n assert(offset + size <= self.len(), 'out of bound');\\n\\n let mut value: T = Zero::zero();\\n let mut i = 0;\\n\\n // Read bytes and accumulate the value\\n while i < size {\\n let byte: u8 = self.at(offset + i).unwrap();\\n value = (value * 256.try_into().unwrap()) + byte.into();\\n i += 1;\\n }\\n\\n (offset + size, value)\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils/src/byte_array_ext/utils.cairo\": \"// SPDX-License-Identifier: MIT\\n// Based on code from Alexandria (https://github.com/keep-starknet-strange/alexandria)\\n// Copyright (c) 2023 Alexandria Contributors\\n\\nuse core::integer::u128_byte_reverse;\\n\\n/// Reverses the endianness of a u256 value.\\n/// #### Arguments\\n/// * `input` - The u256 value to reverse endianness\\n/// #### Returns\\n/// * `u256` - The u256 value with reversed endianness\\npub fn u256_reverse_endian(input: u256) -> u256 {\\n let low = u128_byte_reverse(input.high);\\n let high = u128_byte_reverse(input.low);\\n u256 { low, high }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils/src/bytes.cairo\": \"use starknet::ContractAddress;\\n\\n// the default is u256 default = 0\\n#[derive(Drop, Serde, Default, Copy, Debug, PartialEq, Hash, starknet::Store)]\\npub struct Bytes32 {\\n pub value: u256,\\n}\\n\\npub impl ContractAddressIntoBytes32 of Into<ContractAddress, Bytes32> {\\n fn into(self: ContractAddress) -> Bytes32 {\\n let contract_address_felt: felt252 = self.into();\\n Bytes32 { value: contract_address_felt.into() }\\n }\\n}\\n\\npub impl Bytes32TryIntoContractAddress of TryInto<Bytes32, ContractAddress> {\\n fn try_into(self: Bytes32) -> Option<ContractAddress> {\\n let bytes32_felt: felt252 = self.value.try_into()?;\\n bytes32_felt.try_into()\\n }\\n}\\n\\npub impl Bytes32IntoU256 of Into<Bytes32, u256> {\\n fn into(self: Bytes32) -> u256 {\\n self.value\\n }\\n}\\n\\npub impl U256IntoBytes32 of Into<u256, Bytes32> {\\n fn into(self: u256) -> Bytes32 {\\n Bytes32 { value: self }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils/src/error.cairo\": \"/// Trait to get the error name for an error code.\\n/// This trait is intended to be implemented for enum types.\\nuse core::panics::panic_with_byte_array;\\n\\npub trait Error<T> {\\n fn name(self: T) -> ByteArray;\\n fn prefix() -> ByteArray;\\n}\\n\\n/// Generic format function that works with any type implementing Error trait\\n/// ERROR_CODE::MESSAGE\\npub fn format_error<T, +Error<T>, +Drop<T>>(error: T, message: ByteArray) -> ByteArray {\\n format!(\\\"{}_{}::{}\\\", Error::<T>::prefix(), error.name(), message)\\n}\\n\\n/// Assert that a condition is true and panic with a byte array error message\\npub fn assert_with_byte_array(condition: bool, err: ByteArray) {\\n #[allow(manual_assert)]\\n if !condition {\\n panic_with_byte_array(err: @err)\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils/src/keccak.cairo\": \"use core::keccak::compute_keccak_byte_array;\\nuse crate::byte_array_ext::utils::u256_reverse_endian;\\nuse crate::bytes::Bytes32;\\n\\n/// Computes the keccak256 hash of a byte array and returns it as a u256 value\\n///\\n/// # Arguments\\n/// * `arr` - A reference to a byte array to be hashed\\n///\\n/// # Returns\\n/// * `Bytes32` - The keccak256 hash of the input as a u256\\npub fn keccak256(arr: @ByteArray) -> Bytes32 {\\n Bytes32 { value: u256_reverse_endian(compute_keccak_byte_array(arr)) }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils/src/lib.cairo\": \"pub mod bytes;\\npub mod error;\\npub mod keccak;\\n\\npub mod byte_array_ext {\\n pub mod bit_array;\\n pub mod byte_appender;\\n pub mod byte_array_ext;\\n pub mod utils;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/lz_utils/Scarb.toml\": \"[package]\\nname = \\\"lz_utils\\\"\\nversion = \\\"0.1.0\\\"\\nedition = \\\"2024_07\\\"\\n\\n[dependencies]\\nstarknet = \\\"2.14.0\\\"\\n\\n[dev-dependencies]\\nsnforge_std = \\\"0.49.0\\\"\\nassert_macros = \\\"2.12.0\\\"\\n\\n[scripts]\\ntest = \\\"snforge test\\\"\\n\\n[tool.scarb]\\nallow-prebuilt-plugins = [\\\"snforge_scarb_plugin\\\", \\\"snforge_std\\\"]\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/common/constants.cairo\": \"//! Common constants\\n\\nuse core::num::traits::Pow;\\nuse starknet::ContractAddress;\\n\\n/// Contract address for the ETH ERC20 token on Starknet\\npub const ETH_CONTRACT_ADDRESS: ContractAddress =\\n 0x049d36570d4e46f48e99674bd3fcc84644ddd6b96f7c741b1562b82f9e004dc7\\n .try_into()\\n .unwrap();\\n\\npub const ZERO_ADDRESS: ContractAddress = 0.try_into().unwrap();\\npub const DEAD_ADDRESS: ContractAddress = 0xdead.try_into().unwrap();\\n\\n/// Basis points denominator (10,000 bps = 100%)\\n/// Used for percentage calculations where 1 bp = 0.01%\\npub const BPS_DENOMINATOR: u256 = 10000;\\n\\n/// Native decimals rate\\n/// - STRK has 18 decimals\\n/// - https://docs.starknet.io/guides/becoming-a-validator/stake/\\n/// NOTE: You might need to change this if you want to deploy and EndpointV2Alt with a different\\n/// native token\\npub const NATIVE_DECIMALS_RATE: u256 = 10_u256.pow(18);\\n\\n/// Maximum v1 EID\\npub const MAX_V1_EID: u32 = 30_000;\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/common/conversions.cairo\": \"//! Common conversions\\n\\nuse lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\n\\n/// Converts felt252 arrays to byte arrays in the event data\\npub impl FeltArrayIntoByteArrayImpl of Into<Array<felt252>, ByteArray> {\\n fn into(self: Array<felt252>) -> ByteArray {\\n let mut byte_array = Default::default();\\n\\n for felt in self.into_iter() {\\n byte_array.append_felt252(felt);\\n }\\n\\n byte_array\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/common/guid.cairo\": \"/// GUID generation library\\npub mod GUID {\\n use lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\n use lz_utils::bytes::Bytes32;\\n use lz_utils::keccak::keccak256;\\n\\n pub fn generate(\\n nonce: u64, src_eid: u32, sender: Bytes32, dst_eid: u32, receiver: Bytes32,\\n ) -> Bytes32 {\\n let mut bytes: ByteArray = Default::default();\\n\\n bytes.append_u64(nonce);\\n bytes.append_u32(src_eid);\\n bytes.append_u256(sender.value);\\n bytes.append_u32(dst_eid);\\n bytes.append_u256(receiver.value);\\n\\n keccak256(@bytes)\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/common/packet_v1_codec.cairo\": \"/// Cairo implementation of the Solidity PacketV1Codec library\\n///\\n/// Handles encoding and decoding of LayerZero packets\\npub mod PacketV1Codec {\\n use lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\n use lz_utils::bytes::{Bytes32, ContractAddressIntoBytes32};\\n use lz_utils::error::{Error, assert_with_byte_array, format_error};\\n use lz_utils::keccak::keccak256;\\n use starknet::ContractAddress;\\n use crate::common::structs::packet::Packet;\\n\\n // Constants\\n pub const PACKET_VERSION: u8 = 1;\\n pub const PACKET_HEADER_LENGTH: u32 = 81;\\n\\n // Offsets for packet structure\\n // header (version + nonce + path)\\n pub const PACKET_VERSION_OFFSET: usize = 0;\\n pub const NONCE_OFFSET: usize = 1;\\n pub const SRC_EID_OFFSET: usize = 9;\\n pub const SENDER_OFFSET: usize = 13;\\n pub const DST_EID_OFFSET: usize = 45;\\n pub const RECEIVER_OFFSET: usize = 49;\\n // payload (guid + message)\\n pub const GUID_OFFSET: usize = 81;\\n pub const MESSAGE_OFFSET: usize = 113;\\n\\n /// Struct for decoding the packet payload\\n pub struct PacketPayload {\\n pub guid: Bytes32,\\n pub message: ByteArray,\\n }\\n\\n /// Same as [`Packet`] but with `Bytes32` sender\\n pub struct PacketSenderBytes {\\n pub nonce: u64,\\n pub src_eid: u32,\\n pub sender: Bytes32,\\n pub dst_eid: u32,\\n pub receiver: Bytes32,\\n pub guid: Bytes32,\\n pub message: ByteArray,\\n }\\n\\n #[derive(Drop)]\\n pub enum PacketV1CodecError {\\n InvalidSenderAddress,\\n InvalidReceiverAddress,\\n InvalidPacketVersion,\\n InvalidPacketHeader,\\n InvalidEid,\\n }\\n\\n impl ErrorNameImpl of Error<PacketV1CodecError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_PACKET_V1_CODEC\\\"\\n }\\n\\n fn name(self: PacketV1CodecError) -> ByteArray {\\n match self {\\n PacketV1CodecError::InvalidSenderAddress => \\\"INVALID_SENDER_ADDRESS\\\",\\n PacketV1CodecError::InvalidReceiverAddress => \\\"INVALID_RECEIVER_ADDRESS\\\",\\n PacketV1CodecError::InvalidPacketVersion => \\\"INVALID_PACKET_VERSION\\\",\\n PacketV1CodecError::InvalidPacketHeader => \\\"INVALID_PACKET_HEADER\\\",\\n PacketV1CodecError::InvalidEid => \\\"INVALID_EID\\\",\\n }\\n }\\n }\\n\\n pub fn err_invalid_sender_address(sender: Bytes32) -> ByteArray {\\n format_error(PacketV1CodecError::InvalidSenderAddress, format!(\\\"sender: {}\\\", sender.value))\\n }\\n\\n pub fn err_invalid_receiver_address(receiver: Bytes32) -> ByteArray {\\n format_error(\\n PacketV1CodecError::InvalidReceiverAddress, format!(\\\"receiver: {}\\\", receiver.value),\\n )\\n }\\n\\n pub fn err_invalid_packet_version(version: u8) -> ByteArray {\\n format_error(PacketV1CodecError::InvalidPacketVersion, format!(\\\"version: {}\\\", version))\\n }\\n\\n pub fn err_invalid_packet_header(expected_length: u32, actual_length: u32) -> ByteArray {\\n format_error(\\n PacketV1CodecError::InvalidPacketHeader,\\n format!(\\\"expected_length: {}, actual_length: {}\\\", expected_length, actual_length),\\n )\\n }\\n\\n pub fn err_invalid_eid(expected_eid: u32, actual_eid: u32) -> ByteArray {\\n format_error(\\n PacketV1CodecError::InvalidEid,\\n format!(\\\"expected_eid: {}, actual_eid: {}\\\", expected_eid, actual_eid),\\n )\\n }\\n\\n /// Encodes only the packet header (version + nonce + path) into a byte array\\n pub fn encode_header(packet: @Packet) -> ByteArray {\\n let sender_bytes32: Bytes32 = (*packet.sender).into();\\n\\n // Packet header encoding format:\\n // 1 byte version\\n // 8 bytes nonce\\n // 4 bytes srcEid\\n // 32 bytes sender\\n // 4 bytes dstEid\\n // 32 bytes receiver\\n let mut header: ByteArray = Default::default();\\n\\n header.append_u8(PACKET_VERSION);\\n header.append_u64(*packet.nonce);\\n header.append_u32(*packet.src_eid);\\n header.append_u256(sender_bytes32.value);\\n header.append_u32(*packet.dst_eid);\\n header.append_u256(*packet.receiver.value);\\n\\n header\\n }\\n\\n /// Encodes the packet payload (guid + message) into a byte array\\n pub fn encode_payload(packet: @Packet) -> ByteArray {\\n let mut payload: ByteArray = Default::default();\\n\\n payload.append_u256(*packet.guid.value);\\n payload.append(packet.message);\\n\\n payload\\n }\\n\\n /// Encodes a packet struct into a byte array following the LayerZero packet format\\n pub fn encode(packet: @Packet) -> ByteArray {\\n // Packet encoding:\\n // PacketHeader + bytes32 guid + byteArray message\\n let mut encoded_header: ByteArray = encode_header(packet);\\n let mut encoded_payload: ByteArray = encode_payload(packet);\\n encoded_header.append(@encoded_payload);\\n encoded_header\\n }\\n\\n /// Extracts the header from an encoded packet\\n pub fn header(packet: @ByteArray) -> ByteArray {\\n let (_, header_value) = packet.read_bytes(0, GUID_OFFSET);\\n header_value\\n }\\n\\n /// Extracts the version from an encoded packet\\n pub fn version(packet: @ByteArray) -> u8 {\\n let (_, version_value) = packet.read_u8(PACKET_VERSION_OFFSET);\\n version_value\\n }\\n\\n /// Extracts the nonce from an encoded packet\\n pub fn nonce(packet: @ByteArray) -> u64 {\\n let (_, nonce_value) = packet.read_u64(NONCE_OFFSET);\\n nonce_value\\n }\\n\\n /// Extracts the source EID from an encoded packet\\n pub fn src_eid(packet: @ByteArray) -> u32 {\\n let (_, src_eid_value) = packet.read_u32(SRC_EID_OFFSET);\\n src_eid_value\\n }\\n\\n /// Extracts the sender as Bytes32 from an encoded packet\\n pub fn sender(packet: @ByteArray) -> Bytes32 {\\n let (_, sender_value) = packet.read_u256(SENDER_OFFSET);\\n Bytes32 { value: sender_value }\\n }\\n\\n /// Extracts the sender as ContractAddress from an encoded packet\\n pub fn sender_address(packet: @ByteArray) -> ContractAddress {\\n let sender_bytes32 = sender(packet);\\n let sender_address = sender_bytes32.try_into();\\n assert_with_byte_array(\\n sender_address.is_some(), err_invalid_sender_address(sender_bytes32),\\n );\\n\\n sender_address.unwrap()\\n }\\n\\n /// Extracts the destination EID from an encoded packet\\n pub fn dst_eid(packet: @ByteArray) -> u32 {\\n let (_, dst_eid_value) = packet.read_u32(DST_EID_OFFSET);\\n dst_eid_value\\n }\\n\\n /// Extracts the receiver from an encoded packet\\n pub fn receiver(packet: @ByteArray) -> Bytes32 {\\n let (_, receiver_value) = packet.read_u256(RECEIVER_OFFSET);\\n Bytes32 { value: receiver_value }\\n }\\n\\n /// Extracts the receiver as ContractAddress from an encoded packet\\n pub fn receiver_address(packet: @ByteArray) -> ContractAddress {\\n let receiver_bytes32 = receiver(packet);\\n let receiver_address = receiver_bytes32.try_into();\\n assert_with_byte_array(\\n receiver_address.is_some(), err_invalid_receiver_address(receiver_bytes32),\\n );\\n\\n receiver_address.unwrap()\\n }\\n\\n /// Extracts the GUID from an encoded packet\\n pub fn guid(packet: @ByteArray) -> Bytes32 {\\n let (_, guid_value) = packet.read_u256(GUID_OFFSET);\\n Bytes32 { value: guid_value }\\n }\\n\\n /// Extracts the message from an encoded packet\\n /// * `ByteArray` - The message\\n pub fn message(packet: @ByteArray) -> ByteArray {\\n let message_length = packet.len() - MESSAGE_OFFSET;\\n let (_, message_value) = packet.read_bytes(MESSAGE_OFFSET, message_length);\\n message_value\\n }\\n\\n /// Extracts the payload (guid + message) from an encoded packet\\n pub fn payload(packet: @ByteArray) -> ByteArray {\\n let payload_length = packet.len() - GUID_OFFSET;\\n let (_, payload_value) = packet.read_bytes(GUID_OFFSET, payload_length);\\n payload_value\\n }\\n\\n /// Computes the keccak256 hash of the payload\\n pub fn payload_hash(packet: @ByteArray) -> Bytes32 {\\n let payload_bytes = payload(packet);\\n keccak256(@payload_bytes)\\n }\\n\\n /// Decodes only the packet payload from a byte array into individual components\\n /// Returns: (guid, message)\\n pub fn decode_payload(encoded_packet: @ByteArray) -> PacketPayload {\\n PacketPayload { guid: guid(encoded_packet), message: message(encoded_packet) }\\n }\\n\\n /// Decodes a complete encoded packet into a Packet struct\\n /// Note: This assumes the sender can be converted to ContractAddress\\n /// If conversion fails, it will panic - use decode_with_bytes32_sender for safer decoding\\n pub fn decode(encoded_packet: @ByteArray) -> Packet {\\n get_and_assert_version(encoded_packet);\\n\\n let PacketSenderBytes {\\n nonce, src_eid, sender: sender_bytes32, dst_eid, receiver, guid, message,\\n } = decode_with_bytes32_sender(encoded_packet);\\n\\n Packet {\\n nonce,\\n src_eid,\\n dst_eid,\\n receiver,\\n guid,\\n message,\\n sender: sender_bytes32.try_into().expect('Invalid sender address'),\\n }\\n }\\n\\n /// Decodes a complete encoded packet into a Packet struct with Bytes32 sender\\n /// This is safer than decode() as it doesn't attempt address conversion\\n pub fn decode_with_bytes32_sender(encoded_packet: @ByteArray) -> PacketSenderBytes {\\n get_and_assert_version(encoded_packet);\\n\\n PacketSenderBytes {\\n nonce: nonce(encoded_packet),\\n src_eid: src_eid(encoded_packet),\\n sender: sender(encoded_packet),\\n dst_eid: dst_eid(encoded_packet),\\n receiver: receiver(encoded_packet),\\n guid: guid(encoded_packet),\\n message: message(encoded_packet),\\n }\\n }\\n\\n pub fn get_and_assert_version(packet_header: @ByteArray) -> u8 {\\n let header_version = version(packet_header);\\n assert_with_byte_array(\\n header_version == PACKET_VERSION, err_invalid_packet_version(header_version),\\n );\\n\\n header_version\\n }\\n\\n /// Asserts that a packet header is valid for the given local endpoint ID\\n /// Validates:\\n /// - Header length is exactly 81 bytes\\n /// - Packet version matches PACKET_VERSION\\n /// - Destination EID matches the local endpoint ID\\n pub fn assert_header(packet_header: @ByteArray, local_eid: u32) {\\n // Assert packet header is of right size (81 bytes)\\n let header_length = packet_header.len();\\n assert_with_byte_array(\\n header_length == PACKET_HEADER_LENGTH,\\n err_invalid_packet_header(PACKET_HEADER_LENGTH, header_length),\\n );\\n\\n // Assert packet header version is the same as ULN\\n get_and_assert_version(packet_header);\\n\\n // Assert the packet is for this endpoint\\n let packet_dst_eid = dst_eid(packet_header);\\n assert_with_byte_array(\\n packet_dst_eid == local_eid, err_invalid_eid(local_eid, packet_dst_eid),\\n );\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/common/structs/messaging.cairo\": \"//! Common messaging structs\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\n\\n/// Parameters required to send a message\\n#[derive(Drop, Serde, Clone, PartialEq, Debug, Default)]\\npub struct MessagingParams {\\n pub dst_eid: u32,\\n pub receiver: Bytes32,\\n pub message: ByteArray,\\n pub options: ByteArray,\\n pub pay_in_lz_token: bool,\\n}\\n\\n#[derive(Drop, Serde, Default, PartialEq, Clone, Debug)]\\npub struct MessagingFee {\\n pub native_fee: u256,\\n pub lz_token_fee: u256,\\n}\\n\\n#[derive(Drop, Clone, Serde, PartialEq, Debug)]\\npub struct Payee {\\n pub receiver: ContractAddress,\\n pub native_amount: u256,\\n pub lz_token_amount: u256,\\n}\\n\\n#[derive(Drop, Serde, Default, PartialEq, Clone, Debug)]\\npub struct MessageReceipt {\\n pub guid: Bytes32,\\n pub nonce: u64,\\n pub payees: Array<Payee>,\\n}\\n\\n#[derive(Drop, Serde, PartialEq, Clone, Debug)]\\npub struct MessageLibSendResult {\\n pub message_receipt: MessageReceipt,\\n pub encoded_packet: ByteArray,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/common/structs/packet.cairo\": \"//! Common structs - `Packet` and `Origin`\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\n\\n#[derive(Clone, Drop, Serde)]\\npub struct PacketHeader {\\n pub nonce: u64,\\n pub src_eid: u32,\\n pub sender: ContractAddress,\\n pub dst_eid: u32,\\n pub receiver: Bytes32,\\n}\\n\\n#[derive(Clone, Drop, Serde)]\\npub struct Packet {\\n pub nonce: u64,\\n pub src_eid: u32,\\n pub sender: ContractAddress,\\n pub dst_eid: u32,\\n pub receiver: Bytes32,\\n pub guid: Bytes32,\\n pub message: ByteArray,\\n}\\n\\n#[derive(Clone, Drop, Serde, Debug, PartialEq, Default)]\\npub struct Origin {\\n pub src_eid: u32,\\n pub sender: Bytes32,\\n pub nonce: u64,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/constants.cairo\": \"//! EndpointV2 constants\\n\\nuse lz_utils::bytes::Bytes32;\\n\\n/// Represents an empty payload hash (default state after message execution)\\n///\\n/// Assumes computationally infeasible that payload can hash to 0\\n/// this is equivalent to Default::default() but we're making it explicit\\npub const EMPTY_PAYLOAD_HASH: Bytes32 = Bytes32 { value: 0 };\\n\\n/// Represents a nilified payload hash (message verified but execution prevented)\\n///\\n/// Assumes computational intractability of finding a payload that hashes to bytes32.max\\npub const NIL_PAYLOAD_HASH: Bytes32 = Bytes32 { value: core::num::traits::Bounded::<u256>::MAX };\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/endpoint_v2.cairo\": \"/// # EndpointV2 Contract\\n///\\n/// The EndpointV2 contract is the core component of the LayerZero protocol, responsible for\\n/// managing the lifecycle of messages between different OApps. It provides a comprehensive set of\\n/// functionalities that enable developers to build sophisticated omnichain applications (OApps)\\n/// with ease.\\n///\\n/// ## Key Features\\n/// - **Message Sending and Receiving**: Core functions for sending and receiving messages across\\n/// different blockchains, abstracting away the complexities of cross-chain communication.\\n/// - **Configurable Security**: OApps can define their own security requirements by specifying a\\n/// set of Data Verification Networks (DVNs) and a threshold of required verifications,\\n/// ensuring that each message meets the application's security standards.\\n/// - **Fee Quotation**: Provides a mechanism to quote the cost of sending a message, allowing\\n/// applications to estimate and manage transaction fees transparently.\\n/// - **Message Verification and Execution**: Verifies the authenticity of incoming messages\\n/// through the configured DVNs and ensures that only valid messages are executed.\\n/// - **Verify-Store-Execute Pattern**: Implements a secure message handling pattern where message\\n/// payload hashes are stored on-chain and executed only after successful verification,\\n/// preventing race conditions and other security vulnerabilities.\\n/// - **Alerts and Error Handling**: Includes a system for receiving alerts about failed\\n/// messages, enabling robust error handling and recovery mechanisms.\\n/// - **Delegate and Token Management**: Supports delegation of OApp configuration management and\\n/// allows for the use of the ZRO token for paying fees.\\n#[starknet::contract]\\npub mod EndpointV2 {\\n use core::num::traits::Zero;\\n use lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\n use lz_utils::bytes::{Bytes32, ContractAddressIntoBytes32};\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::security::ReentrancyGuardComponent;\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use starknet::storage::{\\n Map, StoragePathEntry, StoragePointerReadAccess, StoragePointerWriteAccess,\\n };\\n use starknet::{ContractAddress, get_caller_address, get_contract_address};\\n use crate::MessagingFee;\\n use crate::common::guid::GUID;\\n use crate::common::structs::messaging::{MessageLibSendResult, MessageReceipt, MessagingParams};\\n use crate::common::structs::packet::{Origin, Packet};\\n use crate::endpoint::constants::{EMPTY_PAYLOAD_HASH, NIL_PAYLOAD_HASH};\\n use crate::endpoint::errors::{\\n err_insufficient_fee, err_invalid_lz_token_address, err_invalid_payload_hash,\\n err_invalid_receive_library, err_lz_receive_value_exceeds_allowance,\\n err_lz_token_unavailable, err_native_transfer_failed, err_path_not_initializable,\\n err_path_not_verifiable, err_unauthorized, err_zro_transfer_failed,\\n };\\n use crate::endpoint::events::{\\n DelegateSet, LzReceiveAlert, LzTokenSet, PacketDelivered, PacketSent, PacketVerified,\\n };\\n use crate::endpoint::interfaces::endpoint_v2::{ExecutionState, IEndpointV2};\\n use crate::endpoint::interfaces::layerzero_receiver::{\\n ILayerZeroReceiverDispatcher, ILayerZeroReceiverDispatcherTrait,\\n };\\n use crate::endpoint::message_lib_manager::message_lib_manager::MessageLibManagerComponent;\\n use crate::endpoint::message_lib_manager::structs::GetLibraryResponse;\\n use crate::endpoint::messaging_channel::interface::IMessagingChannel;\\n use crate::endpoint::messaging_channel::messaging_channel::MessagingChannelComponent;\\n use crate::endpoint::messaging_composer::messaging_composer::MessagingComposerComponent;\\n use crate::message_lib::interface::{IMessageLibDispatcher, IMessageLibDispatcherTrait};\\n\\n ////////////////\\n // Components //\\n ////////////////\\n\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n component!(\\n path: MessageLibManagerComponent,\\n storage: message_lib_manager,\\n event: MessageLibManagerEvent,\\n );\\n component!(\\n path: ReentrancyGuardComponent, storage: reentrancy_guard, event: ReentrancyGuardEvent,\\n );\\n component!(\\n path: MessagingChannelComponent, storage: messaging_channel, event: MessagingChannelEvent,\\n );\\n component!(\\n path: MessagingComposerComponent,\\n storage: messaging_composer,\\n event: MessagingComposerEvent,\\n );\\n\\n // Ownable\\n #[abi(embed_v0)]\\n impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;\\n impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl MessageLibManagerImpl =\\n MessageLibManagerComponent::MessageLibManagerImpl<ContractState>;\\n impl MessageLibManagerInternalImpl = MessageLibManagerComponent::InternalImpl<ContractState>;\\n\\n // ReentrancyGuard\\n impl ReentrancyGuardInternalImpl = ReentrancyGuardComponent::InternalImpl<ContractState>;\\n\\n // MessagingChannel\\n #[abi(embed_v0)]\\n impl MessagingChannelImpl =\\n MessagingChannelComponent::MessagingChannelImpl<ContractState>;\\n impl MessagingChannelInternalImpl = MessagingChannelComponent::InternalImpl<ContractState>;\\n\\n // MessagingComposer\\n #[abi(embed_v0)]\\n impl MessagingComposerImpl =\\n MessagingComposerComponent::MessagingComposerImpl<ContractState>;\\n impl MessagingComposerInternalImpl = MessagingComposerComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n // Native token address\\n native_token_address: ContractAddress,\\n lz_token_address: ContractAddress,\\n // Delegates\\n // Used to authorize OApps to set their own libraries\\n // oapp => delegate\\n delegates: Map<ContractAddress, ContractAddress>,\\n // Component substorages:\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n #[substorage(v0)]\\n message_lib_manager: MessageLibManagerComponent::Storage,\\n #[substorage(v0)]\\n reentrancy_guard: ReentrancyGuardComponent::Storage,\\n #[substorage(v0)]\\n messaging_channel: MessagingChannelComponent::Storage,\\n #[substorage(v0)]\\n messaging_composer: MessagingComposerComponent::Storage,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n PacketSent: PacketSent,\\n PacketVerified: PacketVerified,\\n PacketDelivered: PacketDelivered,\\n LzTokenSet: LzTokenSet,\\n LzReceiveAlert: LzReceiveAlert,\\n DelegateSet: DelegateSet,\\n // Component events:\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n #[flat]\\n ReentrancyGuardEvent: ReentrancyGuardComponent::Event,\\n #[flat]\\n MessagingChannelEvent: MessagingChannelComponent::Event,\\n #[flat]\\n MessageLibManagerEvent: MessageLibManagerComponent::Event,\\n #[flat]\\n MessagingComposerEvent: MessagingComposerComponent::Event,\\n }\\n\\n #[constructor]\\n fn constructor(\\n ref self: ContractState,\\n owner: ContractAddress,\\n eid: u32,\\n native_token_address: ContractAddress,\\n blocked_library: ContractAddress,\\n ) {\\n self.ownable.initializer(owner);\\n // Initialize MessagingChannel with EID\\n self.messaging_channel.initializer(eid);\\n // Initialize Native token\\n self.native_token_address.write(native_token_address);\\n // Initialize MessagingComposer with native token\\n self.messaging_composer.initializer(native_token_address);\\n // Initialize MessageLibManager with blocked library\\n self.message_lib_manager.initializer(blocked_library);\\n }\\n\\n #[abi(embed_v0)]\\n impl EndpointV2Impl of IEndpointV2<ContractState> {\\n /// Here we're assuming that the OApp takes an allowance from the user,\\n /// takes that money from the user, gives that as allowance to the EndpointV2\\n /// and then the endpoint gives the remainder back to the refund_address provided\\n fn send(\\n ref self: ContractState, params: MessagingParams, refund_address: ContractAddress,\\n ) -> MessageReceipt {\\n self.reentrancy_guard.start();\\n\\n let sender = get_caller_address();\\n\\n // Create the packet and find the send message lib\\n let (packet, message_lib_dispatcher) = self._send(sender, @params);\\n\\n let MessagingParams { options, pay_in_lz_token, dst_eid, receiver, .. } = params;\\n\\n // Update the nonce\\n self\\n .messaging_channel\\n ._outbound_nonce_entry(sender, dst_eid, receiver)\\n .write(packet.nonce);\\n\\n // Call send on the message lib\\n let MessageLibSendResult {\\n message_receipt, encoded_packet,\\n } = message_lib_dispatcher.send(packet, options.clone(), pay_in_lz_token);\\n\\n // Pay the workers based on the quote provided by the message lib\\n self._pay_workers(sender, @message_receipt, refund_address, pay_in_lz_token);\\n\\n self\\n .emit(\\n PacketSent {\\n encoded_packet,\\n options,\\n send_library: message_lib_dispatcher.contract_address,\\n },\\n );\\n\\n self.reentrancy_guard.end();\\n message_receipt\\n }\\n\\n fn lz_receive_alert(\\n ref self: ContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n guid: Bytes32,\\n gas: u256,\\n value: u256,\\n message: ByteArray,\\n extra_data: ByteArray,\\n reason: Array<felt252>,\\n ) {\\n let executor = get_caller_address();\\n self\\n .emit(\\n LzReceiveAlert {\\n origin, receiver, executor, guid, gas, value, message, extra_data, reason,\\n },\\n );\\n }\\n\\n fn verify(\\n ref self: ContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n payload_hash: Bytes32,\\n ) {\\n self.reentrancy_guard.start();\\n\\n // Assert that the caller is the receive library for this path\\n self._assert_only_receive_library(receiver, origin.src_eid);\\n\\n // Get the lazy inbound nonce for this path\\n let lazy_nonce = self\\n .messaging_channel\\n .lazy_inbound_nonce(receiver, origin.src_eid, origin.sender);\\n\\n // Ensure that the path is initializable\\n assert_with_byte_array(\\n self._initializable(origin.clone(), receiver, lazy_nonce),\\n err_path_not_initializable(),\\n );\\n\\n // Ensure that the path is verifiable\\n assert_with_byte_array(\\n self._verifiable(origin.clone(), receiver, lazy_nonce), err_path_not_verifiable(),\\n );\\n\\n // Ensure that the payload hash is valid\\n assert_with_byte_array(payload_hash != EMPTY_PAYLOAD_HASH, err_invalid_payload_hash());\\n\\n // Store the payload hash for this inbound message\\n self\\n .messaging_channel\\n ._inbound_payload_hash_entry(receiver, origin.src_eid, origin.sender, origin.nonce)\\n .write(payload_hash);\\n\\n self.emit(PacketVerified { origin, receiver, payload_hash });\\n\\n self.reentrancy_guard.end();\\n }\\n\\n fn lz_receive(\\n ref self: ContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n guid: Bytes32,\\n message: ByteArray,\\n extra_data: ByteArray,\\n value: u256,\\n ) {\\n // Create payload by concatenating guid and message\\n let payload = self._create_payload(guid, @message);\\n\\n // Clear the payload first to prevent reentrancy, then execute the message\\n self.messaging_channel._clear_payload(receiver, @origin, @payload);\\n\\n // Check if the LzReceive.value is greater than the allowance\\n let executor = get_caller_address();\\n\\n let native_token = IERC20Dispatcher {\\n contract_address: self.native_token_address.read(),\\n };\\n let allowance = native_token.allowance(executor, get_contract_address());\\n assert_with_byte_array(\\n value <= allowance, err_lz_receive_value_exceeds_allowance(value, allowance),\\n );\\n\\n // Transfer the LzReceive.value to the receiver\\n let success = native_token.transfer_from(executor, receiver, value);\\n assert_with_byte_array(success, err_native_transfer_failed());\\n\\n // We're calling .lz_receive after giving it the money, so they can have the money\\n // available to use it to handle the message\\n let receiver_dispatcher = ILayerZeroReceiverDispatcher { contract_address: receiver };\\n receiver_dispatcher\\n .lz_receive(origin.clone(), guid, message, executor, extra_data, value);\\n\\n self.emit(PacketDelivered { origin, receiver });\\n }\\n\\n fn clear(\\n ref self: ContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n guid: Bytes32,\\n message: ByteArray,\\n ) {\\n self._assert_authorized(receiver);\\n\\n /// Create payload by concatenating guid and message\\n let payload = self._create_payload(guid, @message);\\n\\n /// Clear the payload first to prevent reentrancy, then execute the message\\n self.messaging_channel._clear_payload(receiver, @origin, @payload);\\n\\n self.emit(PacketDelivered { origin, receiver });\\n }\\n\\n fn quote(\\n self: @ContractState, params: MessagingParams, sender: ContractAddress,\\n ) -> MessagingFee {\\n let (packet, msg_lib_dispatcher) = self._send(sender, @params);\\n msg_lib_dispatcher.quote(packet, params.options, params.pay_in_lz_token)\\n }\\n\\n fn get_lz_token(self: @ContractState) -> ContractAddress {\\n self.lz_token_address.read()\\n }\\n\\n fn get_eid(self: @ContractState) -> u32 {\\n self.messaging_channel.eid.read()\\n }\\n\\n fn set_lz_token(ref self: ContractState, lz_token_address: ContractAddress) {\\n self.ownable.assert_only_owner();\\n assert_with_byte_array(\\n self.native_token_address.read() != lz_token_address,\\n err_invalid_lz_token_address(lz_token_address),\\n );\\n\\n self.lz_token_address.write(lz_token_address);\\n self.emit(LzTokenSet { lz_token_address });\\n }\\n\\n fn set_delegate(ref self: ContractState, delegate: ContractAddress) {\\n let oapp = get_caller_address();\\n self.delegates.entry(oapp).write(delegate);\\n self.emit(DelegateSet { oapp, delegate });\\n }\\n\\n fn get_delegate(self: @ContractState, oapp: ContractAddress) -> ContractAddress {\\n self.delegates.entry(oapp).read()\\n }\\n\\n fn initializable(self: @ContractState, origin: Origin, receiver: ContractAddress) -> bool {\\n let lazy_nonce = self\\n .messaging_channel\\n .lazy_inbound_nonce(receiver, origin.src_eid, origin.sender);\\n self._initializable(origin, receiver, lazy_nonce)\\n }\\n\\n fn verifiable(self: @ContractState, origin: Origin, receiver: ContractAddress) -> bool {\\n let Origin { src_eid, sender, .. } = origin.clone();\\n let lazy_nonce = self.messaging_channel.lazy_inbound_nonce(receiver, src_eid, sender);\\n self._verifiable(origin, receiver, lazy_nonce)\\n }\\n\\n fn verifiable_with_receive_lib(\\n self: @ContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n receive_lib: ContractAddress,\\n ) -> bool {\\n self.verifiable(origin.clone(), receiver)\\n && self\\n .message_lib_manager\\n .is_valid_receive_library(receiver, origin.src_eid, receive_lib)\\n }\\n\\n fn executable(\\n self: @ContractState, origin: Origin, receiver: ContractAddress,\\n ) -> ExecutionState {\\n let Origin { src_eid, sender, nonce } = origin;\\n\\n let payload_hash = self\\n .messaging_channel\\n .inbound_payload_hash(receiver, src_eid, sender, nonce);\\n\\n // executed if the payload hash has been cleared and the nonce is less than or equal to\\n // lazyInboundNonce\\n if payload_hash == EMPTY_PAYLOAD_HASH\\n && nonce <= self.messaging_channel.lazy_inbound_nonce(receiver, src_eid, sender) {\\n return ExecutionState::Executed;\\n }\\n\\n // executable if nonce has not been executed and has not been nilified and nonce is less\\n // than or equal to inboundNonce\\n if payload_hash != NIL_PAYLOAD_HASH\\n && nonce <= self.messaging_channel.inbound_nonce(receiver, src_eid, sender) {\\n return ExecutionState::Executable;\\n }\\n\\n // only start active executable polling if payload hash is not empty nor nil\\n if payload_hash != EMPTY_PAYLOAD_HASH && payload_hash != NIL_PAYLOAD_HASH {\\n return ExecutionState::VerifiedButNotExecutable;\\n }\\n\\n // return NotExecutable as a catch-all\\n ExecutionState::NotExecutable\\n }\\n }\\n\\n // =============================== Internal Functions ===============================\\n\\n #[generate_trait]\\n impl InternalImpl of InternalTrait {\\n fn _send(\\n self: @ContractState, sender: ContractAddress, params: @MessagingParams,\\n ) -> (Packet, IMessageLibDispatcher) {\\n let MessagingParams { dst_eid, receiver, message, pay_in_lz_token, .. } = params;\\n let src_eid = self.messaging_channel.eid.read();\\n\\n assert_with_byte_array(\\n !(*pay_in_lz_token && self.lz_token_address.read().is_zero()),\\n err_lz_token_unavailable(),\\n );\\n\\n let nonce = self.messaging_channel.outbound_nonce(sender, *dst_eid, *receiver) + 1;\\n\\n let packet = Packet {\\n nonce,\\n src_eid,\\n sender,\\n dst_eid: *dst_eid,\\n receiver: *receiver,\\n guid: GUID::generate(nonce, src_eid, sender.into(), *dst_eid, *receiver),\\n message: message.clone(),\\n };\\n\\n let GetLibraryResponse {\\n lib: send_msglib, ..,\\n } = self.message_lib_manager.get_send_library(sender, *dst_eid);\\n\\n let message_lib_dispatcher = IMessageLibDispatcher { contract_address: send_msglib };\\n\\n (packet, message_lib_dispatcher)\\n }\\n\\n fn _pay_workers(\\n ref self: ContractState,\\n sender: ContractAddress,\\n message_receipt: @MessageReceipt,\\n refund_address: ContractAddress,\\n pay_in_lz_token: bool,\\n ) {\\n // In order to satisfy the requirement of throwing a custom error in case the user\\n // didn't send enough fees to pay all of the workers,\\n // We follow this two step process to make sure none of the ERC20 transfers fail.\\n // First, we loop through the payees and make sure we have enough allowance to pay all\\n // of them\\n // Note that we do this loop twice, because we can't trust the message library to\\n // send us a non-consistent receipt (total_native_fee != sum(payees.native_amount))\\n // which would result in inaccurate allowance checks and some money remaining in the\\n // allowance.\\n let mut total_native_fee: u256 = 0;\\n let mut total_zro_fee: u256 = 0;\\n\\n for payee in @message_receipt.payees {\\n total_native_fee += *payee.native_amount;\\n total_zro_fee += *payee.lz_token_amount;\\n }\\n\\n // Native token allowance\\n let contract_address = get_contract_address();\\n let native_token = IERC20Dispatcher {\\n contract_address: self.native_token_address.read(),\\n };\\n let native_allowance = native_token.allowance(sender, contract_address);\\n let native_balance = native_token.balance_of(sender);\\n\\n // ZRO token allowance\\n let zro_token = if pay_in_lz_token {\\n Some(IERC20Dispatcher { contract_address: self.lz_token_address.read() })\\n } else {\\n None\\n };\\n let zro_allowance = zro_token\\n .map(|dispatcher| dispatcher.allowance(sender, contract_address))\\n .unwrap_or_default();\\n let zro_balance = zro_token\\n .map(|dispatcher| dispatcher.balance_of(sender))\\n .unwrap_or_default();\\n\\n Self::_assert_messaging_fee(\\n total_native_fee,\\n native_allowance,\\n native_balance,\\n total_zro_fee,\\n zro_allowance,\\n zro_balance,\\n );\\n\\n // Pay the workers & refund the remainder of the allowances\\n self\\n ._pay_native_fees(\\n sender,\\n native_token,\\n message_receipt,\\n refund_address,\\n native_allowance,\\n total_native_fee,\\n );\\n\\n self\\n ._pay_zro_fees(\\n sender,\\n zro_token,\\n message_receipt,\\n refund_address,\\n zro_allowance,\\n total_zro_fee,\\n );\\n }\\n\\n fn _assert_only_receive_library(\\n ref self: ContractState, receiver: ContractAddress, src_eid: u32,\\n ) {\\n let caller = get_caller_address();\\n assert_with_byte_array(\\n self.message_lib_manager.is_valid_receive_library(receiver, src_eid, caller),\\n err_invalid_receive_library(),\\n );\\n }\\n\\n // Checkers for packet conditions\\n fn _initializable(\\n self: @ContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n lazy_inbound_nonce: u64,\\n ) -> bool {\\n let receiver_dispatcher = ILayerZeroReceiverDispatcher { contract_address: receiver };\\n lazy_inbound_nonce > 0 || receiver_dispatcher.allow_initialize_path(origin)\\n }\\n\\n fn _verifiable(\\n self: @ContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n lazy_inbound_nonce: u64,\\n ) -> bool {\\n origin.nonce > lazy_inbound_nonce\\n || self\\n .messaging_channel\\n ._has_payload_hash(receiver, origin.src_eid, origin.sender, origin.nonce)\\n }\\n\\n /// Helper function to create payload by concatenating guid and message\\n /// This mimics Solidity's abi.encodePacked(_guid, _message)\\n fn _create_payload(\\n ref self: ContractState, guid: Bytes32, message: @ByteArray,\\n ) -> ByteArray {\\n let mut payload: ByteArray = \\\"\\\";\\n payload.append_u256(guid.value);\\n payload.append(message);\\n\\n payload\\n }\\n\\n fn _assert_authorized(self: @ContractState, oapp: ContractAddress) {\\n let caller = get_caller_address();\\n assert_with_byte_array(\\n self.delegates.entry(oapp).read() == caller || oapp == caller, err_unauthorized(),\\n );\\n }\\n\\n /// Checks that the supplied fees are greater than or equal to the required fees or panics\\n fn _assert_messaging_fee(\\n required_native_fee: u256,\\n supplied_native_fee_allowance: u256,\\n supplied_native_balance: u256,\\n required_zro_token_fee: u256,\\n supplied_zro_fee_allowance: u256,\\n supplied_zro_balance: u256,\\n ) {\\n let has_required_native_fee = supplied_native_fee_allowance >= required_native_fee\\n && supplied_native_balance >= supplied_native_fee_allowance;\\n let has_required_zro_token_fee = supplied_zro_fee_allowance >= required_zro_token_fee\\n && supplied_zro_balance >= supplied_zro_fee_allowance;\\n\\n assert_with_byte_array(\\n has_required_native_fee && has_required_zro_token_fee,\\n err_insufficient_fee(\\n required_native_fee,\\n supplied_native_fee_allowance,\\n supplied_native_balance,\\n required_zro_token_fee,\\n supplied_zro_fee_allowance,\\n supplied_zro_balance,\\n ),\\n );\\n }\\n\\n /// Refund the remainder of the native token allowance\\n fn _refund_native(\\n self: @ContractState,\\n native_token: IERC20Dispatcher,\\n allowance: u256,\\n fee: u256,\\n sender: ContractAddress,\\n refund_address: ContractAddress,\\n ) {\\n if allowance > fee {\\n let success = native_token.transfer_from(sender, refund_address, allowance - fee);\\n assert_with_byte_array(success, err_native_transfer_failed());\\n }\\n }\\n\\n /// Refund the remainder of the ZRO token allowance\\n fn _refund_zro(\\n self: @ContractState,\\n zro_token: IERC20Dispatcher,\\n allowance: u256,\\n fee: u256,\\n sender: ContractAddress,\\n refund_address: ContractAddress,\\n ) {\\n if allowance > fee {\\n let success = zro_token.transfer_from(sender, refund_address, allowance - fee);\\n assert_with_byte_array(success, err_zro_transfer_failed());\\n }\\n }\\n\\n /// Pay the native token fees\\n fn _pay_native_fees(\\n self: @ContractState,\\n sender: ContractAddress,\\n native_token: IERC20Dispatcher,\\n message_receipt: @MessageReceipt,\\n refund_address: ContractAddress,\\n native_allowance: u256,\\n total_native_fee: u256,\\n ) {\\n for payee in @message_receipt.payees {\\n let native_amount = *payee.native_amount;\\n if native_amount > 0 {\\n let success = native_token\\n .transfer_from(sender, *payee.receiver, native_amount);\\n assert_with_byte_array(success, err_native_transfer_failed());\\n }\\n }\\n self\\n ._refund_native(\\n native_token, native_allowance, total_native_fee, sender, refund_address,\\n );\\n }\\n\\n /// Pay the ZRO token fees\\n fn _pay_zro_fees(\\n ref self: ContractState,\\n sender: ContractAddress,\\n zro_token: Option<IERC20Dispatcher>,\\n message_receipt: @MessageReceipt,\\n refund_address: ContractAddress,\\n zro_allowance: u256,\\n total_zro_fee: u256,\\n ) {\\n if let Some(zro_token) = zro_token {\\n for payee in @message_receipt.payees {\\n let lz_token_amount = *payee.lz_token_amount;\\n if lz_token_amount > 0 {\\n let success = zro_token\\n .transfer_from(sender, *payee.receiver, lz_token_amount);\\n assert_with_byte_array(success, err_zro_transfer_failed());\\n }\\n }\\n self._refund_zro(zro_token, zro_allowance, total_zro_fee, sender, refund_address);\\n }\\n }\\n }\\n\\n // =============================== Component Hooks =================================\\n\\n impl MessageLibManagerHooksImpl of MessageLibManagerComponent::MessageLibManagerHooks<\\n ContractState,\\n > {\\n fn _assert_authorized(\\n self: @MessageLibManagerComponent::ComponentState<ContractState>, oapp: ContractAddress,\\n ) {\\n self.get_contract()._assert_authorized(oapp);\\n }\\n }\\n\\n impl MessagingChannelHooksImpl of MessagingChannelComponent::MessagingChannelHooks<\\n ContractState,\\n > {\\n fn _assert_authorized(\\n self: @MessagingChannelComponent::ComponentState<ContractState>,\\n receiver: ContractAddress,\\n ) {\\n self.get_contract()._assert_authorized(receiver);\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/errors.cairo\": \"//! EndpointV2 errors\\n\\nuse lz_utils::error::{Error, format_error};\\nuse starknet::ContractAddress;\\n\\n#[derive(Drop)]\\npub enum EndpointV2Error {\\n /// Triggered when a message is committed by a contract that is not a valid receive library for\\n /// the given path.\\n InvalidReceiveLibrary,\\n /// Triggered when an attempt is made to commit a message to a path that has not been\\n /// initialized.\\n PathNotInitializable,\\n PathNotVerifiable,\\n InvalidPayloadHash,\\n /// Triggered when a message with an invalid nonce is received.\\n InvalidNonce,\\n /// Triggered when the payload hash of a received message does not match the committed payload\\n /// hash.\\n PayloadHashNotFound,\\n /// Triggered when the value sent with `lz_receive` exceeds the executor's token allowance.\\n LzReceiveValueExceedsAllowance,\\n /// Triggered when an unauthorized address attempts to perform a restricted action.\\n Unauthorized,\\n /// Triggered when an attempt is made to pay fees in the LZ token, but no LZ token address is\\n /// set.\\n LzTokenUnavailable,\\n /// Triggered when an attempt is made to pay fees in the LZ token, but the fee is zero.\\n ZeroLzTokenFee,\\n /// Triggered when the fees provided are insufficient to cover the cost of the message.\\n InsufficientFee,\\n /// Triggered when the transfer of a native token fails.\\n NativeTransferFailed,\\n /// Triggered when the transfer of the ZRO token fails.\\n ZroTransferFailed,\\n /// Triggered when the LZ token address is the same as the native token address.\\n InvalidLzTokenAddress,\\n}\\n\\nimpl ErrorNameImpl of Error<EndpointV2Error> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_ENDPOINT\\\"\\n }\\n\\n fn name(self: EndpointV2Error) -> ByteArray {\\n match self {\\n EndpointV2Error::InvalidReceiveLibrary => \\\"INVALID_RECEIVE_LIBRARY\\\",\\n EndpointV2Error::PathNotInitializable => \\\"PATH_NOT_INITIALIZABLE\\\",\\n EndpointV2Error::PathNotVerifiable => \\\"PATH_NOT_VERIFIABLE\\\",\\n EndpointV2Error::InvalidPayloadHash => \\\"INVALID_PAYLOAD_HASH\\\",\\n EndpointV2Error::InvalidNonce => \\\"INVALID_NONCE\\\",\\n EndpointV2Error::PayloadHashNotFound => \\\"PAYLOAD_HASH_NOT_FOUND\\\",\\n EndpointV2Error::LzReceiveValueExceedsAllowance => \\\"LZ_RECEIVE_VALUE_EXCEEDS_ALLOWANCE\\\",\\n EndpointV2Error::Unauthorized => \\\"UNAUTHORIZED\\\",\\n EndpointV2Error::LzTokenUnavailable => \\\"LZ_TOKEN_UNAVAILABLE\\\",\\n EndpointV2Error::ZeroLzTokenFee => \\\"ZERO_LZ_TOKEN_FEE\\\",\\n EndpointV2Error::InsufficientFee => \\\"INSUFFICIENT_FEE\\\",\\n EndpointV2Error::NativeTransferFailed => \\\"NATIVE_TRANSFER_FAILED\\\",\\n EndpointV2Error::ZroTransferFailed => \\\"ZRO_TRANSFER_FAILED\\\",\\n EndpointV2Error::InvalidLzTokenAddress => \\\"INVALID_LZ_TOKEN_ADDRESS\\\",\\n }\\n }\\n}\\n\\npub fn err_invalid_receive_library() -> ByteArray {\\n format_error(EndpointV2Error::InvalidReceiveLibrary, \\\"\\\")\\n}\\n\\npub fn err_path_not_initializable() -> ByteArray {\\n format_error(EndpointV2Error::PathNotInitializable, \\\"\\\")\\n}\\n\\npub fn err_path_not_verifiable() -> ByteArray {\\n format_error(EndpointV2Error::PathNotVerifiable, \\\"\\\")\\n}\\n\\npub fn err_invalid_payload_hash() -> ByteArray {\\n format_error(EndpointV2Error::InvalidPayloadHash, \\\"\\\")\\n}\\n\\npub fn err_lz_receive_value_exceeds_allowance(\\n lz_receive_value: u256, allowance: u256,\\n) -> ByteArray {\\n format_error(\\n EndpointV2Error::LzReceiveValueExceedsAllowance,\\n format!(\\\"LZ receive value: {}, Allowance: {}\\\", lz_receive_value, allowance),\\n )\\n}\\n\\npub fn err_unauthorized() -> ByteArray {\\n format_error(EndpointV2Error::Unauthorized, \\\"\\\")\\n}\\n\\npub fn err_lz_token_unavailable() -> ByteArray {\\n format_error(EndpointV2Error::LzTokenUnavailable, \\\"\\\")\\n}\\n\\npub fn err_zero_lz_token_fee() -> ByteArray {\\n format_error(EndpointV2Error::ZeroLzTokenFee, \\\"\\\")\\n}\\n\\npub fn err_insufficient_fee(\\n required_native_fee: u256,\\n supplied_native_fee_allowance: u256,\\n supplied_native_balance: u256,\\n required_zro_token_fee: u256,\\n supplied_zro_fee_allowance: u256,\\n supplied_zro_balance: u256,\\n) -> ByteArray {\\n format_error(\\n EndpointV2Error::InsufficientFee,\\n format!(\\n \\\"Required native fee: {}, Supplied native fee allowance: {}, Supplied native balance: {}, Required zro fee: {}, Supplied zro fee allowance: {}, Supplied zro balance: {}\\\",\\n required_native_fee,\\n supplied_native_fee_allowance,\\n supplied_native_balance,\\n required_zro_token_fee,\\n supplied_zro_fee_allowance,\\n supplied_zro_balance,\\n ),\\n )\\n}\\n\\npub fn err_native_transfer_failed() -> ByteArray {\\n format_error(EndpointV2Error::NativeTransferFailed, \\\"\\\")\\n}\\n\\npub fn err_zro_transfer_failed() -> ByteArray {\\n format_error(EndpointV2Error::ZroTransferFailed, \\\"\\\")\\n}\\n\\npub fn err_invalid_lz_token_address(lz_token_address: ContractAddress) -> ByteArray {\\n format_error(\\n EndpointV2Error::InvalidLzTokenAddress, format!(\\\"Lz token address: {:?}\\\", lz_token_address),\\n )\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/events.cairo\": \"//! EndpointV2 events\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::common::structs::packet::Origin;\\n\\n/// Emitted when a packet is sent from the EndpointV2.\\n#[derive(Drop, Debug, PartialEq, starknet::Event)]\\npub struct PacketSent {\\n /// The encoded packet data.\\n pub encoded_packet: ByteArray,\\n /// The options specified for the message.\\n pub options: ByteArray,\\n /// The address of the send library used.\\n #[key]\\n pub send_library: ContractAddress,\\n}\\n\\n/// Emitted when a packet is verified and the payload hash is stored.\\n#[derive(Drop, Debug, PartialEq, starknet::Event)]\\npub struct PacketVerified {\\n /// The origin of the packet.\\n #[key]\\n pub origin: Origin,\\n /// The intended receiver of the packet.\\n #[key]\\n pub receiver: ContractAddress,\\n /// The hash of the packet's payload.\\n #[key]\\n pub payload_hash: Bytes32,\\n}\\n\\n/// Emitted when a packet is successfully delivered to the receiver.\\n#[derive(Drop, Debug, PartialEq, starknet::Event)]\\npub struct PacketDelivered {\\n /// The origin of the packet.\\n #[key]\\n pub origin: Origin,\\n /// The receiver of the packet.\\n #[key]\\n pub receiver: ContractAddress,\\n}\\n\\n/// Emitted when a receive message fails.\\n#[derive(Drop, Debug, PartialEq, starknet::Event)]\\npub struct LzReceiveAlert {\\n /// The origin of the message.\\n #[key]\\n pub origin: Origin,\\n /// The intended receiver of the message.\\n #[key]\\n pub receiver: ContractAddress,\\n /// The address of the executor that triggered the alert.\\n #[key]\\n pub executor: ContractAddress,\\n /// The GUID of the message.\\n #[key]\\n pub guid: Bytes32,\\n /// The gas amount related to the alert.\\n pub gas: u256,\\n /// The value sent with the message.\\n pub value: u256,\\n /// The message payload.\\n pub message: ByteArray,\\n /// Extra data provided with the alert.\\n pub extra_data: ByteArray,\\n /// The reason for the alert.\\n pub reason: Array<felt252>,\\n}\\n\\n/// Emitted when the LZ token address is set.\\n#[derive(Drop, Debug, PartialEq, starknet::Event)]\\npub struct LzTokenSet {\\n /// The new address of the LZ token.\\n #[key]\\n pub lz_token_address: ContractAddress,\\n}\\n\\n/// Emitted when a delegate is set for an OApp.\\n#[derive(Drop, starknet::Event)]\\npub struct DelegateSet {\\n /// The OApp's address.\\n #[key]\\n pub oapp: ContractAddress,\\n /// The delegate's address.\\n #[key]\\n pub delegate: ContractAddress,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/interfaces/endpoint_v2.cairo\": \"//! EndpointV2 interface\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::MessagingFee;\\nuse crate::common::structs::messaging::{MessageReceipt, MessagingParams};\\nuse crate::common::structs::packet::Origin;\\n\\n/// # `IEndpointV2` Interface\\n///\\n/// The `IEndpointV2` interface is the central component of the LayerZero protocol, designed to\\n/// facilitate seamless, secure, and efficient cross-chain messaging. As the primary entry point for\\n/// all LayerZero messages, the EndpointV2 contract manages the entire lifecycle of a message, from\\n/// sending to receiving, while ensuring reliable delivery and robust security. It provides a\\n/// comprehensive set of functionalities that enable developers to build sophisticated omnichain\\n/// applications (OApps) with ease.\\n///\\n/// ## Key Features\\n/// - **Message Sending and Receiving**: Core functions for sending and receiving messages across\\n/// different blockchains,\\n/// abstracting away the complexities of cross-chain communication.\\n/// - **Configurable Security**: OApps can define their own security requirements by specifying a\\n/// set of Data Verification\\n/// Networks (DVNs) and a threshold of required verifications, ensuring that each message meets\\n/// the application's security standards.\\n/// - **Fee Quotation**: Provides a mechanism to quote the cost of sending a message, allowing\\n/// applications to estimate\\n/// and manage transaction fees transparently.\\n/// - **Message Verification and Execution**: Verifies the authenticity of incoming messages through\\n/// the configured DVNs\\n/// and ensures that only valid messages are executed.\\n/// - **Verify-Store-Execute Pattern**: Implements a secure message handling pattern where message\\n/// payload hashes are stored\\n/// on-chain and executed only after successful verification, preventing race conditions and other\\n/// security vulnerabilities.\\n/// - **Alerts and Error Handling**: Includes a system for receiving alerts about failed messages,\\n/// enabling robust error\\n/// handling and recovery mechanisms.\\n/// - **Delegate and Token Management**: Supports delegation of OApp configuration management and\\n/// allows for the use of\\n/// a specific token for paying LayerZero fees.\\n#[derive(Drop, Serde)]\\npub enum ExecutionState {\\n NotExecutable, // executor: waits for PayloadVerified event and starts polling for executable\\n VerifiedButNotExecutable, // executor: starts active polling for executable\\n Executable,\\n Executed,\\n}\\n\\n#[starknet::interface]\\npub trait IEndpointV2<TContractState> {\\n /// Sends a message to a remote OApp.\\n ///\\n /// # Arguments\\n ///\\n /// * `params` - A `MessagingParams` struct containing the destination EID, receiver address,\\n /// message payload,\\n /// OApp-specific options, and whether to pay in the LZ token.\\n /// * `refund_address` - The address to which any remaining gas fees should be refunded.\\n ///\\n /// # Returns\\n ///\\n /// * `MessageReceipt` - A struct containing the GUID of the message and the nonce.\\n ///\\n /// @dev This function is the primary entry point for sending a message from a local OApp to a\\n /// remote OApp.\\n /// It encodes the message, calculates the required fee, and dispatches it to the LayerZero\\n /// network.\\n fn send(\\n ref self: TContractState, params: MessagingParams, refund_address: ContractAddress,\\n ) -> MessageReceipt;\\n\\n /// Quotes the fee for sending a message.\\n ///\\n /// # Arguments\\n ///\\n /// * `params` - A `MessagingParams` struct containing the destination EID, receiver address,\\n /// message payload,\\n /// OApp-specific options, and whether to pay in the LZ token.\\n /// * `sender` - The address of the OApp sending the message.\\n ///\\n /// # Returns\\n ///\\n /// * `MessagingFee` - A struct containing the native fee and the LZ token fee required to send\\n /// the message.\\n ///\\n /// @dev This function allows an OApp to estimate the cost of sending a message before actually\\n /// sending it.\\n /// The fee is calculated based on the message parameters and the current network conditions.\\n fn quote(\\n self: @TContractState, params: MessagingParams, sender: ContractAddress,\\n ) -> MessagingFee;\\n\\n /// Verifies a message and stores the payload hash.\\n ///\\n /// # Arguments\\n ///\\n /// * `origin` - An `Origin` struct containing the source EID and sender address.\\n /// * `receiver` - The address of the OApp that will receive the message.\\n /// * `payload_hash` - The Keccak-256 hash of the message payload.\\n ///\\n /// @dev This function is called by the LayerZero network to verify a message and store the\\n /// payload hash EndpointV2.\\n /// It stores a hash of the message payload, which will be used later for verification.\\n /// This is part of the verify-store-execute pattern to ensure secure message handling.\\n fn verify(\\n ref self: TContractState, origin: Origin, receiver: ContractAddress, payload_hash: Bytes32,\\n );\\n\\n /// Receives and executes a message from a remote OApp.\\n ///\\n /// # Arguments\\n ///\\n /// * `origin` - An `Origin` struct containing the source EID and sender address.\\n /// * `receiver` - The address of the OApp that will receive the message.\\n /// * `guid` - The globally unique identifier of the message.\\n /// * `message` - The message payload.\\n /// * `extra_data` - Additional data provided by the executor.\\n /// * `value` - The value sent with the message.\\n ///\\n /// @dev This function is called by the LayerZero network after a message has been successfully\\n /// verified.\\n /// It decodes the message and calls the `lz_receive` function on the destination OApp.\\n fn lz_receive(\\n ref self: TContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n guid: Bytes32,\\n message: ByteArray,\\n extra_data: ByteArray,\\n value: u256,\\n );\\n\\n /// Receives an alert about a failed message.\\n ///\\n /// # Arguments\\n ///\\n /// * `origin` - An `Origin` struct containing the source EID and sender address.\\n /// * `receiver` - The address of the OApp that was supposed to receive the message.\\n /// * `guid` - The GUID of the failed message.\\n /// * `gas` - The amount of gas used before the failure.\\n /// * `value` - The value sent with the message.\\n /// * `message` - The message payload.\\n /// * `extra_data` - Additional data provided by the executor.\\n /// * `reason` - An array of felts describing the reason for the failure.\\n ///\\n /// @dev This function is called by the LayerZero network when a message fails to be delivered\\n /// or executed.\\n /// It allows the OApp to handle the failure gracefully, for example, by retrying the message or\\n /// notifying a user.\\n fn lz_receive_alert(\\n ref self: TContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n guid: Bytes32,\\n gas: u256,\\n value: u256,\\n message: ByteArray,\\n extra_data: ByteArray,\\n reason: Array<felt252>,\\n );\\n\\n /// Clears a stored message payload from the contract's storage.\\n ///\\n /// # Arguments\\n ///\\n /// * `origin` - An `Origin` struct containing the source EID and sender address.\\n /// * `receiver` - The address of the OApp that received the message.\\n /// * `guid` - The GUID of the message.\\n /// * `message` - The message payload.\\n ///\\n /// @dev This function is called by the LayerZero network after a message has been successfully\\n /// executed to remove the stored payload hash and free up storage space.\\n fn clear(\\n ref self: TContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n guid: Bytes32,\\n message: ByteArray,\\n );\\n\\n /// Gets the address of the LZ token used for paying fees.\\n ///\\n /// # Returns\\n ///\\n /// * `lz_token_address` - The address of the LZ token contract.\\n ///\\n /// @dev The LZ token is an alternative to the native token for paying LayerZero fees.\\n /// This function returns the address of the LZ token contract.\\n fn get_lz_token(self: @TContractState) -> ContractAddress;\\n\\n /// Gets the endpoint ID (EID) of the local chain.\\n ///\\n /// # Returns\\n ///\\n /// * `eid` - The EID of the local chain.\\n ///\\n /// @dev The EID is a unique identifier for each chain supported by LayerZero.\\n /// This function returns the EID of the chain where the EndpointV2 contract is deployed.\\n fn get_eid(self: @TContractState) -> u32;\\n\\n /// Sets the address of the LZ token used for paying fees.\\n ///\\n /// # Arguments\\n ///\\n /// * `lz_token_address` - The new address of the LZ token contract.\\n ///\\n /// # Panics\\n /// * If the LZ token address is the same as the native token address.\\n fn set_lz_token(ref self: TContractState, lz_token_address: ContractAddress);\\n\\n /// Sets the delegate for an OApp.\\n ///\\n /// # Arguments\\n /// * `delegate` - The address to be set as the delegate.\\n ///\\n /// @dev The delegate is an address that is authorized to manage the OApp's configurations,\\n /// such as the required DVNs and the verification threshold.\\n /// This allows for separation of concerns, where the OApp owner can delegate configuration\\n /// management to a separate address.\\n fn set_delegate(ref self: TContractState, delegate: ContractAddress);\\n\\n /// Gets the delegate for an OApp.\\n ///\\n /// # Arguments\\n /// * `oapp` - The address of the OApp.\\n ///\\n /// # Returns\\n /// * `ContractAddress` - The address of the delegate.\\n fn get_delegate(self: @TContractState, oapp: ContractAddress) -> ContractAddress;\\n\\n\\n /// Checks if a message path is initializable.\\n ///\\n /// # Arguments\\n ///\\n /// * `origin` - An `Origin` struct containing the source EID and sender address.\\n /// * `receiver` - The address of the OApp that will receive the message.\\n ///\\n /// # Returns\\n /// * `bool` - `true` if the message path is initializable, `false` otherwise.\\n ///\\n /// @dev A message path is initializable if it has not been configured yet.\\n /// This function is used to determine if a new configuration can be set for a given message\\n /// path.\\n fn initializable(self: @TContractState, origin: Origin, receiver: ContractAddress) -> bool;\\n\\n /// Check if the message is verifiable\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin of the message\\n /// * `receiver`: The receiver of the message\\n ///\\n /// # Returns\\n /// * `bool` - True if the message is verifiable, false otherwise\\n fn verifiable(self: @TContractState, origin: Origin, receiver: ContractAddress) -> bool;\\n\\n /// Check if the message is verifiable with a receive library\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin of the message\\n /// * `receiver`: The receiver of the message\\n /// * `receive_lib`: The receive library of the message\\n ///\\n /// # Returns\\n /// * `bool` - True if the message is verifiable with a receive library, false otherwise\\n fn verifiable_with_receive_lib(\\n self: @TContractState,\\n origin: Origin,\\n receiver: ContractAddress,\\n receive_lib: ContractAddress,\\n ) -> bool;\\n\\n /// Check if the message is executable\\n ///\\n /// # Arguments\\n ///\\n /// * `origin` - An `Origin` struct containing the source EID and sender address.\\n /// * `receiver` - The address of the OApp that will receive the message.\\n ///\\n /// # Returns\\n /// * `ExecutionState` - The execution state of the message\\n fn executable(\\n self: @TContractState, origin: Origin, receiver: ContractAddress,\\n ) -> ExecutionState;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/interfaces/layerzero_composer.cairo\": \"//! LayerZero composer interface\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\n\\n/// # `ILayerZeroComposer` Interface\\n///\\n/// The `ILayerZeroComposer` interface is responsible for receiving and processing compose payloads\\n/// from LayerZero messages.\\n/// It provides a function for handling the compose request and verifying the payload before\\n/// executing it.\\n///\\n/// ## Key Features\\n/// - **Compose Handling**: Receives and processes compose payloads from LayerZero messages.\\n/// - **Verification**: Verifies the compose request and payload before executing it.\\n/// - **Security**: Ensures that only valid compose requests are processed.\\n///\\n/// Contracts that wish to receive compose payloads must implement this\\n/// interface. The endpoint's `MessagingComposer` component verifies the\\n/// compose request and then invokes `lz_compose` on the target contract.\\n///\\n/// ## High-level flow\\n/// - An OApp on the source chain requests a compose to a target contract\\n/// on the destination chain\\n/// - The destination endpoint's `MessagingComposer` validates the request,\\n/// prevents reentrancy by marking the message as received, and, if\\n/// `value > 0`, transfers the configured compose token to the target\\n/// contract before calling `lz_compose`\\n/// - The target contract handles the payload in `lz_compose`\\n#[starknet::interface]\\npub trait ILayerZeroComposer<TContractState> {\\n /// Receives a compose payload for a previously delivered LayerZero message\\n ///\\n /// This function is called by the endpoint's `MessagingComposer` after it\\n /// has verified the compose request and optionally transferred value to\\n /// this contract. Implementations must not assume that the caller equals\\n /// `from`; the caller is the executor that relayed the compose.\\n ///\\n /// # Arguments\\n /// * `from` - The originating OApp address that initiated the compose on the\\n /// source chain\\n /// * `guid` - Globally unique identifier of the original LayerZero message\\n /// * `message` - Opaque compose payload provided by the sender\\n /// * `executor` - The contract address that executed the compose on-chain\\n /// * `extra_data` - Additional metadata from the executor (e.g., execution\\n /// context or options); protocol-opaque\\n /// * `value` - Amount of compose token that was transferred to this\\n /// contract immediately before this call (0 if none)\\n ///\\n /// # Panics\\n /// * Implementation-defined. Implementations should revert if the payload is invalid for this\\n /// contract or if execution preconditions are not met.\\n fn lz_compose(\\n ref self: TContractState,\\n from: ContractAddress,\\n guid: Bytes32,\\n message: ByteArray,\\n executor: ContractAddress,\\n extra_data: ByteArray,\\n value: u256,\\n );\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/interfaces/layerzero_receiver.cairo\": \"//! LayerZero receiver interface\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::common::structs::packet::Origin;\\n\\n/// # `ILayerZeroReceiver` Interface\\n///\\n/// The `ILayerZeroReceiver` interface is responsible for receiving and processing LayerZero\\n/// messages from other chains.\\n/// It provides a function for handling the received message and executing the payload.\\n///\\n/// ## Key Features\\n/// - **Message Receiving**: Receives and processes LayerZero messages from other chains.\\n/// - **Execution**: Executes the received message payload.\\n/// - **Security**: Ensures that only valid messages are processed.\\n#[starknet::interface]\\npub trait ILayerZeroReceiver<TContractState> {\\n /// Receives and processes LayerZero messages from other chains\\n /// This is the main entry point for incoming cross-chain messages\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin information containing source endpoint ID and sender\\n /// * `guid`: Globally unique identifier for this message\\n /// * `message`: The actual message payload as bytes\\n /// * `executor`: The contract address of the executor handling this message\\n /// * `extra_data`: Additional data that may be used for message processing. Note that this data\\n /// is passed from the executor directly, and not verified by DVNs. It needs to\\n /// be validated manually.\\n /// * `value`: The value sent with the message\\n fn lz_receive(\\n ref self: TContractState,\\n origin: Origin,\\n guid: Bytes32,\\n message: ByteArray,\\n executor: ContractAddress,\\n extra_data: ByteArray,\\n value: u256,\\n );\\n\\n /// Checks if a path can be initialized for the given origin\\n /// This is used to determine if a new communication path should be allowed\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin information to check for path initialization\\n ///\\n /// # Returns\\n ///\\n /// True if the path can be initialized, false otherwise\\n fn allow_initialize_path(self: @TContractState, origin: Origin) -> bool;\\n\\n /// Gets the next nonce value for a specific source endpoint and sender\\n /// Nonces are used to ensure message ordering and prevent replay attacks\\n ///\\n /// # Arguments\\n ///\\n /// * `src_eid`: The source endpoint ID\\n /// * `sender`: The sender address as a 32-byte value\\n ///\\n /// # Returns\\n ///\\n /// The next nonce value as a u64\\n fn next_nonce(self: @TContractState, src_eid: u32, sender: Bytes32) -> u64;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/message_lib_manager/errors.cairo\": \"//! Message lib manager errors\\n\\nuse lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum MessageLibManagerError {\\n /// Triggered when attempting to register a message library that is already registered.\\n AlreadyRegistered,\\n /// Triggered when the default send library is required but not set.\\n DefaultSendLibUnavailable,\\n /// Triggered when the default receive library is required but not set.\\n DefaultReceiveLibUnavailable,\\n /// Triggered when an invalid expiry value is provided.\\n InvalidExpiry,\\n /// Triggered when a default library is used where a non-default library is required.\\n OnlyNonDefaultLib,\\n /// Triggered when a library that is not a receive library is used in a receive-only context.\\n OnlyReceiveLib,\\n /// Triggered when an unregistered library is used.\\n OnlyRegisteredLib,\\n /// Triggered when a library that is not registered or a default library is used.\\n OnlyRegisteredOrDefaultLib,\\n /// Triggered when a library that is not a send library is used in a send-only context.\\n OnlySendLib,\\n /// Triggered when a new value is the same as the current value.\\n SameValue,\\n /// Triggered when an unsupported endpoint ID is used.\\n UnsupportedEid,\\n}\\n\\nimpl ErrorNameImpl of Error<MessageLibManagerError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_MESSAGE_LIB_MANAGER\\\"\\n }\\n\\n fn name(self: MessageLibManagerError) -> ByteArray {\\n match self {\\n MessageLibManagerError::AlreadyRegistered => \\\"ALREADY_REGISTERED\\\",\\n MessageLibManagerError::DefaultSendLibUnavailable => \\\"DEFAULT_SEND_LIB_UNAVAILABLE\\\",\\n MessageLibManagerError::DefaultReceiveLibUnavailable => \\\"DEFAULT_RECEIVE_LIB_UNAVAILABLE\\\",\\n MessageLibManagerError::InvalidExpiry => \\\"INVALID_EXPIRY\\\",\\n MessageLibManagerError::OnlyNonDefaultLib => \\\"ONLY_NON_DEFAULT_LIB\\\",\\n MessageLibManagerError::OnlyReceiveLib => \\\"ONLY_RECEIVE_LIB\\\",\\n MessageLibManagerError::OnlyRegisteredLib => \\\"ONLY_REGISTERED_LIB\\\",\\n MessageLibManagerError::OnlyRegisteredOrDefaultLib => \\\"ONLY_REGISTERED_OR_DEFAULT_LIB\\\",\\n MessageLibManagerError::OnlySendLib => \\\"ONLY_SEND_LIB\\\",\\n MessageLibManagerError::SameValue => \\\"SAME_VALUE\\\",\\n MessageLibManagerError::UnsupportedEid => \\\"UNSUPPORTED_EID\\\",\\n }\\n }\\n}\\n\\npub fn err_already_registered() -> ByteArray {\\n format_error(MessageLibManagerError::AlreadyRegistered, \\\"\\\")\\n}\\n\\npub fn err_default_send_lib_unavailable() -> ByteArray {\\n format_error(MessageLibManagerError::DefaultSendLibUnavailable, \\\"\\\")\\n}\\n\\npub fn err_default_receive_lib_unavailable() -> ByteArray {\\n format_error(MessageLibManagerError::DefaultReceiveLibUnavailable, \\\"\\\")\\n}\\n\\npub fn err_invalid_expiry() -> ByteArray {\\n format_error(MessageLibManagerError::InvalidExpiry, \\\"\\\")\\n}\\n\\npub fn err_only_non_default_lib() -> ByteArray {\\n format_error(MessageLibManagerError::OnlyNonDefaultLib, \\\"\\\")\\n}\\n\\npub fn err_only_receive_lib() -> ByteArray {\\n format_error(MessageLibManagerError::OnlyReceiveLib, \\\"\\\")\\n}\\n\\npub fn err_only_registered_lib() -> ByteArray {\\n format_error(MessageLibManagerError::OnlyRegisteredLib, \\\"\\\")\\n}\\n\\npub fn err_only_registered_or_default_lib() -> ByteArray {\\n format_error(MessageLibManagerError::OnlyRegisteredOrDefaultLib, \\\"\\\")\\n}\\n\\npub fn err_only_send_lib() -> ByteArray {\\n format_error(MessageLibManagerError::OnlySendLib, \\\"\\\")\\n}\\n\\npub fn err_same_value() -> ByteArray {\\n format_error(MessageLibManagerError::SameValue, \\\"\\\")\\n}\\n\\npub fn err_unsupported_eid(eid: u32) -> ByteArray {\\n format_error(MessageLibManagerError::UnsupportedEid, format!(\\\"EID: {}\\\", eid))\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/message_lib_manager/events.cairo\": \"//! Message lib manager events\\n\\nuse starknet::ContractAddress;\\n\\n/// Emitted when a new message library is registered.\\n#[derive(Drop, starknet::Event)]\\npub struct LibraryRegistered {\\n /// The address of the registered library.\\n #[key]\\n pub library: ContractAddress,\\n}\\n\\n/// Emitted when a send library is set for a specific sender and destination EID.\\n#[derive(Drop, starknet::Event)]\\npub struct SendLibrarySet {\\n /// The sender's address.\\n #[key]\\n pub sender: ContractAddress,\\n /// The destination EID.\\n #[key]\\n pub dst_eid: u32,\\n /// The address of the send library.\\n #[key]\\n pub library: ContractAddress,\\n}\\n\\n/// Emitted when a receive library is set for a specific receiver and source EID.\\n#[derive(Drop, starknet::Event)]\\npub struct ReceiveLibrarySet {\\n /// The receiver's address.\\n #[key]\\n pub receiver: ContractAddress,\\n /// The source EID.\\n #[key]\\n pub src_eid: u32,\\n /// The address of the receive library.\\n #[key]\\n pub library: ContractAddress,\\n}\\n\\n/// Emitted when a default send library is set for a specific EID.\\n#[derive(Drop, starknet::Event)]\\npub struct DefaultSendLibrarySet {\\n /// The EID for which the default send library is set.\\n #[key]\\n pub eid: u32,\\n /// The address of the default send library.\\n #[key]\\n pub library: ContractAddress,\\n}\\n\\n/// Emitted when a default receive library is set for a specific EID.\\n#[derive(Drop, starknet::Event)]\\npub struct DefaultReceiveLibrarySet {\\n /// The EID for which the default receive library is set.\\n #[key]\\n pub eid: u32,\\n /// The address of the default receive library.\\n #[key]\\n pub library: ContractAddress,\\n}\\n\\n/// Emitted when a timeout is set for a receive library.\\n#[derive(Drop, starknet::Event)]\\npub struct ReceiveLibraryTimeoutSet {\\n /// The OApp's address.\\n #[key]\\n pub receiver: ContractAddress,\\n /// The EID for which the timeout is set.\\n #[key]\\n pub eid: u32,\\n /// The address of the receive library.\\n #[key]\\n pub library: ContractAddress,\\n /// The expiry timestamp for the timeout.\\n pub expiry: u64,\\n}\\n\\n/// Emitted when a timeout is set for a default receive library.\\n#[derive(Drop, starknet::Event)]\\npub struct DefaultReceiveLibraryTimeoutSet {\\n /// The EID for which the timeout is set.\\n #[key]\\n pub eid: u32,\\n /// The address of the default receive library.\\n #[key]\\n pub library: ContractAddress,\\n /// The expiry timestamp for the timeout.\\n pub expiry: u64,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/message_lib_manager/interface.cairo\": \"use starknet::ContractAddress;\\nuse crate::endpoint::message_lib_manager::structs::{GetLibraryResponse, Timeout};\\nuse crate::message_lib::structs::SetConfigParam;\\n\\n/// # `IMessageLibManager` Interface\\n///\\n/// The `IMessageLibManager` is responsible for managing the lifecycle and configuration of\\n/// message libraries within the LayerZero protocol. It handles both default (system-wide)\\n/// and custom (OApp-specific) library configurations for sending and receiving messages.\\n///\\n/// ## Key responsibilities\\n/// - Library registration and validation\\n/// - Default library management for the protocol\\n/// - Per-OApp library configuration\\n/// - Grace period management for library upgrades\\n/// - Configuration delegation to message libraries\\n#[starknet::interface]\\npub trait IMessageLibManager<TContractState> {\\n // ========================= Library Registration =========================\\n\\n /// Register a new message library with the endpoint (owner only)\\n ///\\n /// Only registered libraries can be used as send/receive libraries or set as defaults.\\n /// The library must support the IMessageLib interface to be registered.\\n ///\\n /// # Arguments\\n /// * `lib` - The contract address of the message library to register\\n ///\\n /// # Panics\\n /// * If caller is not the owner\\n /// * If library is already registered\\n /// * If library doesn't implement the required interface\\n fn register_library(ref self: TContractState, lib: ContractAddress);\\n\\n /// Get all registered message libraries\\n ///\\n /// Returns a list of all libraries that have been registered with the endpoint.\\n /// This includes both active libraries and any that may be deprecated but still\\n /// registered for backward compatibility.\\n ///\\n /// # Returns\\n /// * `Array<ContractAddress>` - Array of all registered library addresses\\n fn get_registered_libraries(self: @TContractState) -> Array<ContractAddress>;\\n\\n /// Check if a library is registered\\n ///\\n /// Returns true if the library has been registered with the endpoint.\\n ///\\n /// # Arguments\\n /// * `lib` - The library address to check\\n ///\\n /// # Returns\\n /// * `bool` - True if the library is registered, false otherwise\\n fn is_registered_library(self: @TContractState, lib: ContractAddress) -> bool;\\n\\n // ========================= Send Library Management =========================\\n\\n /// Set the send library for the specified OApp and destination endpoint\\n ///\\n /// The send library is responsible for encoding and transmitting messages to the\\n /// destination chain. If not set, the OApp will use the default send library.\\n /// Only the OApp itself or its authorized delegates can set its send library.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address setting its send library\\n /// * `eid` - The destination endpoint ID\\n /// * `lib` - The message library address (or DEFAULT_LIB to use default)\\n ///\\n /// # Panics\\n /// * If caller is not the OApp or its authorized delegate\\n /// * If library is not registered (unless DEFAULT_LIB)\\n /// * If library doesn't support sending\\n /// * If library doesn't support the specified endpoint\\n /// * If the same library is already set (no-op protection)\\n fn set_send_library(\\n ref self: TContractState, oapp: ContractAddress, eid: u32, lib: ContractAddress,\\n );\\n\\n /// Get the send library for a specific oapp and destination endpoint\\n ///\\n /// If the oapp hasn't set a custom send library, this resolves to the default\\n /// send library configured by LayerZero. The library returned by this function\\n /// will be used to process outbound messages.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address that wants to send messages\\n /// * `dst_eid` - The destination endpoint ID\\n ///\\n /// # Returns\\n /// * `GetLibraryResponse` - Struct containing the resolved library address and whether it's the\\n /// default\\n ///\\n /// # Panics\\n /// * If no default send library is configured for the endpoint\\n fn get_send_library(\\n self: @TContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> GetLibraryResponse;\\n\\n /// Get the raw send library for a specific oapp and destination endpoint\\n ///\\n /// Returns the raw send library for the given oapp and destination endpoint.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address that wants to send messages\\n /// * `dst_eid` - The destination endpoint ID\\n ///\\n /// # Returns\\n /// * `ContractAddress` - The raw send library address\\n fn get_raw_send_library(\\n self: @TContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> ContractAddress;\\n\\n /// Check if an OApp is using the default send library\\n ///\\n /// Returns true if the OApp hasn't set a custom send library for the given\\n /// destination, meaning it will use the protocol's default send library.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address to check\\n /// * `dst_eid` - The destination endpoint ID\\n ///\\n /// # Returns\\n /// * `bool` - True if using default library, false if using custom library\\n fn is_default_send_library(self: @TContractState, oapp: ContractAddress, dst_eid: u32) -> bool;\\n\\n /// Set the default send library for an endpoint (owner only)\\n ///\\n /// The default send library is used by OApps that haven't configured a custom\\n /// send library. This is a protocol-level configuration that affects all OApps.\\n ///\\n /// # Arguments\\n /// * `eid` - The destination endpoint ID\\n /// * `lib` - The message library address to set as default\\n ///\\n /// # Panics\\n /// * If caller is not the owner\\n /// * If library is not registered\\n /// * If library doesn't support sending\\n /// * If library doesn't support the specified endpoint\\n /// * If the same library is already set as default\\n fn set_default_send_library(ref self: TContractState, eid: u32, lib: ContractAddress);\\n\\n\\n /// Get the default send library for an endpoint\\n ///\\n /// Returns the default send library for the given endpoint.\\n ///\\n /// # Arguments\\n /// * `eid` - The destination endpoint ID\\n ///\\n /// # Returns\\n /// * `ContractAddress` - The default send library address\\n fn get_default_send_library(self: @TContractState, eid: u32) -> ContractAddress;\\n\\n // ========================= Receive Library Management =========================\\n\\n /// Set the receive library for the specified OApp and source endpoint\\n ///\\n /// The receive library is responsible for verifying and processing incoming messages\\n /// from the source chain. An optional grace period can be specified to allow the\\n /// old library to remain valid during the transition.\\n /// Only the OApp itself or its authorized delegates can set its receive library.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address setting its receive library\\n /// * `eid` - The source endpoint ID\\n /// * `lib` - The message library address (or DEFAULT_LIB to use default)\\n /// * `grace_period` - Number of blocks to keep the old library valid (0 for immediate switch)\\n ///\\n /// # Panics\\n /// * If caller is not the OApp or its authorized delegate\\n /// * If library is not registered (unless DEFAULT_LIB)\\n /// * If library doesn't support receiving\\n /// * If library doesn't support the specified endpoint\\n /// * If the same library is already set (no-op protection)\\n /// * If grace_period > 0 but either old or new library is DEFAULT_LIB\\n fn set_receive_library(\\n ref self: TContractState,\\n oapp: ContractAddress,\\n eid: u32,\\n lib: ContractAddress,\\n grace_period: u64,\\n );\\n\\n /// Get the receive library for a specific oapp and source endpoint\\n ///\\n /// If the oapp hasn't set a custom receive library, this resolves to the default\\n /// receive library configured by LayerZero.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address that will receive messages\\n /// * `src_eid` - The source endpoint ID\\n ///\\n /// # Returns\\n /// * `GetLibraryResponse` - Struct containing the resolved library address and whether it's the\\n /// default\\n ///\\n /// # Panics\\n /// * If no default receive library is configured for the endpoint\\n fn get_receive_library(\\n self: @TContractState, oapp: ContractAddress, src_eid: u32,\\n ) -> GetLibraryResponse;\\n\\n /// Get the raw receive library for a specific oapp and source endpoint\\n ///\\n /// Returns the raw receive library for the given oapp and source endpoint.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address that will receive messages\\n /// * `src_eid` - The source endpoint ID\\n ///\\n /// # Returns\\n /// * `ContractAddress` - The raw receive library address\\n fn get_raw_receive_library(\\n self: @TContractState, oapp: ContractAddress, src_eid: u32,\\n ) -> ContractAddress;\\n\\n /// Check if a receive library is valid for processing messages\\n ///\\n /// This validates whether the specified library can be used to verify messages\\n /// for the given oapp and source endpoint. It considers both the currently\\n /// configured library and any libraries in their grace period.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address that will receive messages\\n /// * `src_eid` - The source endpoint ID\\n /// * `lib` - The library address attempting to verify the message\\n ///\\n /// # Returns\\n /// * `bool` - True if the library is valid for verification, false otherwise\\n fn is_valid_receive_library(\\n self: @TContractState, oapp: ContractAddress, src_eid: u32, lib: ContractAddress,\\n ) -> bool;\\n\\n /// Set the default receive library for an endpoint (owner only)\\n ///\\n /// The default receive library is used by OApps that haven't configured a custom\\n /// receive library. An optional grace period allows the old default library to\\n /// remain valid during the transition.\\n ///\\n /// # Arguments\\n /// * `eid` - The source endpoint ID\\n /// * `lib` - The message library address to set as default\\n /// * `grace_period` - Number of blocks to keep the old library valid (0 for immediate switch)\\n ///\\n /// # Panics\\n /// * If caller is not the owner\\n /// * If library is not registered\\n /// * If library doesn't support receiving\\n /// * If library doesn't support the specified endpoint\\n /// * If the same library is already set as default\\n fn set_default_receive_library(\\n ref self: TContractState, eid: u32, lib: ContractAddress, grace_period: u64,\\n );\\n\\n /// Get the default receive library for an endpoint\\n ///\\n /// Returns the default receive library for the given endpoint.\\n ///\\n /// # Arguments\\n /// * `eid` - The source endpoint ID\\n ///\\n /// # Returns\\n /// * `ContractAddress` - The default receive library address\\n fn get_default_receive_library(self: @TContractState, eid: u32) -> ContractAddress;\\n\\n /// Check if an OApp is using the default receive library\\n ///\\n /// Returns true if the OApp hasn't set a custom receive library for the given\\n /// source, meaning it will use the protocol's default receive library.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address to check\\n /// * `src_eid` - The source endpoint ID\\n fn is_default_receive_library(\\n self: @TContractState, oapp: ContractAddress, src_eid: u32,\\n ) -> bool;\\n\\n /// Set a timeout for a receive library transition\\n ///\\n /// This allows fine-grained control over when libraries in grace period expire.\\n /// Can be used to extend, shorten, or remove grace periods for library transitions.\\n /// Only affects non-default library configurations.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address setting the timeout\\n /// * `eid` - The source endpoint ID\\n /// * `lib` - The library address to set timeout for\\n /// * `expiry` - Block number when the library expires (0 to remove timeout)\\n ///\\n /// # Panics\\n /// * If caller is not the OApp or its authorized delegate\\n /// * If library is not registered\\n /// * If library doesn't support receiving\\n /// * If library doesn't support the specified endpoint\\n /// * If OApp is using default library (can't set custom timeout)\\n /// * If expiry is not in the future (when setting non-zero expiry)\\n fn set_receive_library_timeout(\\n ref self: TContractState,\\n oapp: ContractAddress,\\n eid: u32,\\n lib: ContractAddress,\\n expiry: u64,\\n );\\n\\n /// Get the timeout for a receive library\\n ///\\n /// Returns the timeout for the specified receive library.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address that will receive messages\\n /// * `eid` - The source endpoint ID\\n ///\\n /// # Returns\\n /// * `Timeout` - The timeout for the specified library\\n fn get_receive_library_timeout(\\n self: @TContractState, oapp: ContractAddress, eid: u32,\\n ) -> Timeout;\\n\\n /// Set a timeout for the default receive library (owner only)\\n ///\\n /// This controls the grace period for the protocol's default receive library.\\n /// Unlike the OApp-specific timeout, this affects all OApps using the default library.\\n ///\\n /// # Arguments\\n /// * `eid` - The source endpoint ID\\n /// * `lib` - The library address to set timeout for\\n /// * `expiry` - Block number when the library expires (0 to remove timeout)\\n ///\\n /// # Panics\\n /// * If caller is not the owner\\n /// * If library is not registered\\n /// * If library doesn't support receiving\\n /// * If library doesn't support the specified endpoint\\n /// * If expiry is not in the future (when setting non-zero expiry)\\n fn set_default_receive_library_timeout(\\n ref self: TContractState, eid: u32, lib: ContractAddress, expiry: u64,\\n );\\n\\n /// Get the timeout for the default receive library\\n ///\\n /// Returns the timeout for the default receive library.\\n ///\\n /// # Arguments\\n /// * `eid` - The source endpoint ID\\n ///\\n /// # Returns\\n /// * `Timeout` - The timeout for the default library\\n fn get_default_receive_library_timeout(self: @TContractState, eid: u32) -> Timeout;\\n\\n // ========================= Configuration Management =========================\\n\\n /// Set send configuration for an OApp\\n ///\\n /// This function allows an OApp to set configuration parameters for its send library.\\n /// The configuration is specific to the message library. Endpoint-specific settings\\n /// are provided within the SetConfigParam array.\\n /// Only the OApp itself or its authorized delegates can set its configuration.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address setting configuration\\n /// * `lib` - The message library to set configuration for\\n /// * `params` - Array of configuration parameters to set\\n ///\\n /// # Panics\\n /// * If caller is not the OApp or its authorized delegate\\n /// * If library is not registered\\n /// * If library doesn't support sending\\n fn set_send_configs(\\n ref self: TContractState,\\n oapp: ContractAddress,\\n lib: ContractAddress,\\n params: Array<SetConfigParam>,\\n );\\n\\n /// Get send configuration from a message library\\n ///\\n /// This is a pass-through function that delegates configuration queries to the\\n /// specified message library. The configuration is OApp-specific and depends on\\n /// the library's implementation.\\n ///\\n /// Note: This queries the configuration from the message library. Configuration can be set\\n /// either through this endpoint's set_send_configs function or directly via the library.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address requesting configuration\\n /// * `lib` - The message library to query\\n /// * `eid` - The endpoint ID for the configuration\\n /// * `config_type` - The type of configuration being requested\\n ///\\n /// # Returns\\n /// * `Array<felt252>` - The encoded configuration data\\n ///\\n /// # Panics\\n /// * If library is not registered\\n /// * If library doesn't support sending\\n fn get_send_config(\\n self: @TContractState,\\n oapp: ContractAddress,\\n lib: ContractAddress,\\n eid: u32,\\n config_type: u32,\\n ) -> Array<felt252>;\\n\\n /// Set receive configuration for an OApp\\n ///\\n /// This function allows an OApp to set configuration parameters for its receive library.\\n /// The configuration is specific to the message library. Endpoint-specific settings\\n /// are provided within the SetConfigParam array.\\n /// Only the OApp itself or its authorized delegates can set its configuration.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address setting configuration\\n /// * `lib` - The message library to set configuration for\\n /// * `params` - Array of configuration parameters to set\\n ///\\n /// # Panics\\n /// * If caller is not the OApp or its authorized delegate\\n /// * If library is not registered\\n /// * If library doesn't support receiving\\n fn set_receive_configs(\\n ref self: TContractState,\\n oapp: ContractAddress,\\n lib: ContractAddress,\\n params: Array<SetConfigParam>,\\n );\\n\\n /// Get receive configuration from a message library\\n ///\\n /// This is a pass-through function that delegates configuration queries to the\\n /// specified message library. The configuration is OApp-specific and depends on\\n /// the library's implementation.\\n ///\\n /// Note: This queries the configuration from the message library. Configuration can be set\\n /// either through this endpoint's set_receive_configs function or directly via the library.\\n ///\\n /// # Arguments\\n /// * `oapp` - The OApp address requesting configuration\\n /// * `lib` - The message library to query\\n /// * `eid` - The endpoint ID for the configuration\\n /// * `config_type` - The type of configuration being requested\\n ///\\n /// # Returns\\n /// * `Array<felt252>` - The encoded configuration data\\n ///\\n /// # Panics\\n /// * If library is not registered\\n /// * If library doesn't support receiving\\n fn get_receive_config(\\n self: @TContractState,\\n oapp: ContractAddress,\\n lib: ContractAddress,\\n eid: u32,\\n config_type: u32,\\n ) -> Array<felt252>;\\n\\n // ========================= Utility Functions =========================\\n\\n /// Check if an endpoint is supported by the protocol\\n ///\\n /// An endpoint is considered supported if it has both default send and receive\\n /// libraries configured. This indicates that the endpoint is ready for general use.\\n ///\\n /// # Arguments\\n /// * `eid` - The endpoint ID to check\\n ///\\n /// # Returns\\n /// * `bool` - True if the endpoint has both default libraries configured\\n fn is_supported_eid(self: @TContractState, eid: u32) -> bool;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/message_lib_manager/message_lib_manager.cairo\": \"//! Message library manager component\\n\\n/// # `MessageLibManagerComponent`\\n///\\n/// The MessageLibManager is the core component responsible for managing the lifecycle of message\\n/// libraries within the LayerZero protocol. It provides a unified interface for:\\n///\\n/// - **Library Registration**: Validating and registering message libraries that implement the\\n/// IMessageLib interface - **Default Library Management**: Managing protocol-wide default libraries\\n/// for each endpoint - **Per-OApp Configuration**: Allowing individual OApps to configure custom\\n/// send/receive libraries - **Grace Period Handling**: Managing smooth transitions between library\\n/// versions with configurable timeouts\\n/// requests to the appropriate message libraries\\n///\\n/// ## Library Resolution Logic\\n///\\n/// ### Send Libraries\\n/// When an OApp sends a message, the library resolution follows this priority:\\n/// 1. OApp's custom send library (if configured)\\n/// 2. Protocol's default send library for the destination endpoint\\n///\\n/// ### Receive Libraries\\n/// When validating incoming messages, libraries are considered valid if they are:\\n/// 1. The currently configured receive library for the OApp/endpoint\\n/// 2. A library in its grace period (during library transitions)\\n///\\n/// ## Grace Period Mechanism\\n///\\n/// To ensure smooth upgrades without breaking in-flight messages, the MessageLibManager supports\\n/// grace periods during library transitions. When a new receive library is set, the old library\\n/// can remain valid for a specified number of blocks, allowing time for pending messages to be\\n/// processed.\\n#[starknet::component]\\npub mod MessageLibManagerComponent {\\n use core::num::traits::Zero;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::access::ownable::OwnableComponent::{\\n InternalImpl as OwnableInternalImpl, InternalTrait as OwnableInternalTrait,\\n };\\n use starknet::storage::{\\n Map, MutableVecTrait, StoragePathEntry, StoragePointerReadAccess, StoragePointerWriteAccess,\\n Vec, VecTrait,\\n };\\n use starknet::{ContractAddress, get_block_number};\\n use crate::common::constants::ZERO_ADDRESS;\\n use crate::endpoint::message_lib_manager::errors::{\\n err_already_registered, err_default_receive_lib_unavailable,\\n err_default_send_lib_unavailable, err_invalid_expiry, err_only_non_default_lib,\\n err_only_receive_lib, err_only_registered_lib, err_only_registered_or_default_lib,\\n err_only_send_lib, err_same_value, err_unsupported_eid,\\n };\\n use crate::endpoint::message_lib_manager::events::{\\n DefaultReceiveLibrarySet, DefaultReceiveLibraryTimeoutSet, DefaultSendLibrarySet,\\n LibraryRegistered, ReceiveLibrarySet, ReceiveLibraryTimeoutSet, SendLibrarySet,\\n };\\n use crate::endpoint::message_lib_manager::interface::IMessageLibManager;\\n use crate::endpoint::message_lib_manager::structs::{GetLibraryResponse, Timeout};\\n use crate::message_lib::interface::{IMessageLibDispatcher, IMessageLibDispatcherTrait};\\n use crate::message_lib::structs::{MessageLibType, SetConfigParam};\\n\\n /// Constant representing the default library (address 0)\\n /// Used to indicate when an OApp wants to use the protocol's default library\\n pub const DEFAULT_LIB: ContractAddress = ZERO_ADDRESS;\\n\\n const DEFAULT_EXPIRY: u64 = 0;\\n\\n const DEFAULT_TIMEOUT: Timeout = Timeout { lib: DEFAULT_LIB, expiry: DEFAULT_EXPIRY };\\n\\n /// =============================== Storage =================================\\n #[storage]\\n pub struct Storage {\\n /// Immutable library that reverts both on send and quote operations\\n /// This is set during initialization and provides a way to \\\"block\\\" an endpoint\\n pub blocked_library: ContractAddress,\\n /// Mapping to track which libraries have been registered with the endpoint\\n /// Only registered libraries can be used as send/receive libraries or defaults\\n /// lib_address => is_registered\\n pub is_registered_library: Map<ContractAddress, bool>,\\n /// Dynamic array storing all registered library addresses\\n /// Used for querying the complete list of registered libraries\\n pub registered_libraries: Vec<ContractAddress>,\\n /// OApp-specific send library configurations\\n /// Maps from sender address to destination endpoint to library address\\n /// If not set or set to DEFAULT_LIB, resolves to the default send library\\n /// sender_address => dst_eid => library_address\\n pub send_library: Map<ContractAddress, Map<u32, ContractAddress>>,\\n /// OApp-specific receive library configurations\\n /// Maps from receiver address to source endpoint to library address\\n /// If not set or set to DEFAULT_LIB, resolves to the default receive library\\n /// receiver_address => src_eid => library_address\\n pub receive_library: Map<ContractAddress, Map<u32, ContractAddress>>,\\n /// Timeout configurations for OApp-specific receive library transitions\\n /// Stores grace period information when OApps upgrade their receive libraries\\n /// receiver_address => src_eid => timeout_info\\n pub receive_library_timeout: Map<ContractAddress, Map<u32, Timeout>>,\\n /// Protocol-wide default send libraries for each endpoint\\n /// Used when OApps haven't configured a custom send library\\n /// dst_eid => library_address\\n pub default_send_library: Map<u32, ContractAddress>,\\n /// Protocol-wide default receive libraries for each endpoint\\n /// Used when OApps haven't configured a custom receive library\\n /// src_eid => library_address\\n pub default_receive_library: Map<u32, ContractAddress>,\\n /// Timeout configurations for default receive library transitions\\n /// Manages grace periods when the protocol upgrades default receive libraries\\n /// src_eid => timeout_info\\n pub default_receive_library_timeout: Map<u32, Timeout>,\\n }\\n\\n /// =============================== Events =================================\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n LibraryRegistered: LibraryRegistered,\\n SendLibrarySet: SendLibrarySet,\\n ReceiveLibrarySet: ReceiveLibrarySet,\\n DefaultSendLibrarySet: DefaultSendLibrarySet,\\n DefaultReceiveLibrarySet: DefaultReceiveLibrarySet,\\n ReceiveLibraryTimeoutSet: ReceiveLibraryTimeoutSet,\\n DefaultReceiveLibraryTimeoutSet: DefaultReceiveLibraryTimeoutSet,\\n }\\n\\n // =============================== Hooks =================================\\n pub trait MessageLibManagerHooks<TContractState> {\\n fn _assert_authorized(self: @ComponentState<TContractState>, oapp: ContractAddress);\\n }\\n\\n /// =============================== Implementation =================================\\n #[embeddable_as(MessageLibManagerImpl)]\\n impl MessageLibManager<\\n TContractState,\\n +HasComponent<TContractState>,\\n impl Ownable: OwnableComponent::HasComponent<TContractState>,\\n +MessageLibManagerHooks<TContractState>,\\n +Drop<TContractState>,\\n > of IMessageLibManager<ComponentState<TContractState>> {\\n // ========================= Library Registration =========================\\n\\n fn register_library(ref self: ComponentState<TContractState>, lib: ContractAddress) {\\n // Only the owner can register new libraries\\n self._assert_only_owner();\\n\\n let is_registered_entry = self.is_registered_library.entry(lib);\\n\\n // Must not have been registered before to prevent duplicates\\n assert_with_byte_array(!is_registered_entry.read(), err_already_registered());\\n\\n // Query the library for its type to ensure it implements IMessageLib.\\n // This adds a safety check at registration time similar to EVM parity.\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: lib };\\n let _ = lib_dispatcher.message_lib_type();\\n\\n // Add to registered libraries mapping and array\\n is_registered_entry.write(true);\\n self.registered_libraries.push(lib);\\n\\n self.emit(LibraryRegistered { library: lib });\\n }\\n\\n fn is_registered_library(\\n self: @ComponentState<TContractState>, lib: ContractAddress,\\n ) -> bool {\\n self.is_registered_library.entry(lib).read()\\n }\\n\\n fn get_registered_libraries(\\n self: @ComponentState<TContractState>,\\n ) -> Array<ContractAddress> {\\n let mut libraries = array![];\\n\\n // Iterate through all registered libraries and collect them\\n for i in 0..self.registered_libraries.len() {\\n libraries.append(self.registered_libraries.get(i).unwrap().read());\\n }\\n\\n libraries\\n }\\n\\n // ========================= Send Library Management =========================\\n\\n fn set_send_library(\\n ref self: ComponentState<TContractState>,\\n oapp: ContractAddress,\\n eid: u32,\\n lib: ContractAddress,\\n ) {\\n // Only the OApp itself can set its send library\\n self._assert_authorized(oapp);\\n\\n let send_library_entry = self.send_library.entry(oapp).entry(eid);\\n // Prevent no-op updates (must provide a different value)\\n let old_lib = send_library_entry.read();\\n assert_with_byte_array(old_lib != lib, err_same_value());\\n\\n // Validate library registration, type, and endpoint support\\n self._assert_registered_or_default(lib);\\n self._assert_send_lib(lib);\\n self._assert_supported_send_eid(lib, eid);\\n\\n // Update the send library configuration\\n send_library_entry.write(lib);\\n self.emit(SendLibrarySet { sender: oapp, dst_eid: eid, library: lib });\\n }\\n\\n fn get_send_library(\\n self: @ComponentState<TContractState>, oapp: ContractAddress, dst_eid: u32,\\n ) -> GetLibraryResponse {\\n // Get the OApp's custom send library configuration\\n let lib = self.send_library.entry(oapp).entry(dst_eid).read();\\n\\n // If not set or set to DEFAULT_LIB, resolve to the protocol default\\n if lib == DEFAULT_LIB {\\n let default_lib = self.default_send_library.entry(dst_eid).read();\\n assert_with_byte_array(\\n default_lib.is_non_zero(), err_default_send_lib_unavailable(),\\n );\\n GetLibraryResponse { lib: default_lib, is_default: true }\\n } else {\\n GetLibraryResponse { lib, is_default: false }\\n }\\n }\\n\\n fn get_raw_send_library(\\n self: @ComponentState<TContractState>, oapp: ContractAddress, dst_eid: u32,\\n ) -> ContractAddress {\\n self.send_library.entry(oapp).entry(dst_eid).read()\\n }\\n\\n fn is_default_send_library(\\n self: @ComponentState<TContractState>, oapp: ContractAddress, dst_eid: u32,\\n ) -> bool {\\n // Check if the OApp is using the protocol's default send library\\n self.send_library.entry(oapp).entry(dst_eid).read() == DEFAULT_LIB\\n }\\n\\n fn set_default_send_library(\\n ref self: ComponentState<TContractState>, eid: u32, lib: ContractAddress,\\n ) {\\n // Only the protocol owner can set default libraries\\n self._assert_only_owner();\\n\\n // Prevent no-op updates (must provide a different value)\\n let old_lib = self.default_send_library.entry(eid).read();\\n assert_with_byte_array(old_lib != lib, err_same_value());\\n\\n // Validate library registration, type, and endpoint support\\n self._assert_registered(lib);\\n self._assert_send_lib(lib);\\n self._assert_supported_send_eid(lib, eid);\\n\\n // Update the default send library for the endpoint\\n self.default_send_library.entry(eid).write(lib);\\n self.emit(DefaultSendLibrarySet { eid, library: lib });\\n }\\n\\n fn get_default_send_library(\\n self: @ComponentState<TContractState>, eid: u32,\\n ) -> ContractAddress {\\n self.default_send_library.entry(eid).read()\\n }\\n\\n // ========================= Receive Library Management =========================\\n\\n fn set_receive_library(\\n ref self: ComponentState<TContractState>,\\n oapp: ContractAddress,\\n eid: u32,\\n lib: ContractAddress,\\n grace_period: u64,\\n ) {\\n // Only the OApp itself can set its receive library\\n self._assert_authorized(oapp);\\n\\n let receive_library_entry = self.receive_library.entry(oapp).entry(eid);\\n // Prevent no-op updates (must provide new values)\\n let old_lib = receive_library_entry.read();\\n assert_with_byte_array(old_lib != lib, err_same_value());\\n\\n // Validate library registration, type, and endpoint support\\n self._assert_registered_or_default(lib);\\n self._assert_receive_lib(lib);\\n self._assert_supported_receive_eid(lib, eid);\\n\\n // Update the receive library configuration\\n receive_library_entry.write(lib);\\n self.emit(ReceiveLibrarySet { receiver: oapp, src_eid: eid, library: lib });\\n\\n if grace_period > 0 {\\n // To simplify logic, we only allow timeout if neither new lib nor old lib is\\n // DEFAULT_LIB. This prevents complex interactions with default library timeouts.\\n assert_with_byte_array(\\n old_lib != DEFAULT_LIB && lib != DEFAULT_LIB, err_only_non_default_lib(),\\n );\\n\\n // Set grace period for the old library to remain valid during transition\\n let timeout = Timeout { lib: old_lib, expiry: get_block_number() + grace_period };\\n self.receive_library_timeout.entry(oapp).entry(eid).write(timeout);\\n self\\n .emit(\\n ReceiveLibraryTimeoutSet {\\n receiver: oapp, eid, library: old_lib, expiry: timeout.expiry,\\n },\\n );\\n } else {\\n // Clear any existing timeout when no grace period is specified\\n // this writes the default value for Timeout struct\\n self.receive_library_timeout.entry(oapp).entry(eid).write(DEFAULT_TIMEOUT);\\n self\\n .emit(\\n ReceiveLibraryTimeoutSet {\\n receiver: oapp, eid, library: old_lib, expiry: DEFAULT_EXPIRY,\\n },\\n );\\n }\\n }\\n\\n fn get_receive_library(\\n self: @ComponentState<TContractState>, oapp: ContractAddress, src_eid: u32,\\n ) -> GetLibraryResponse {\\n // Get the OApp's custom receive library configuration\\n let lib = self.receive_library.entry(oapp).entry(src_eid).read();\\n\\n // If not set or set to DEFAULT_LIB, resolve to the protocol default\\n if lib == DEFAULT_LIB {\\n let default_lib = self.default_receive_library.entry(src_eid).read();\\n assert_with_byte_array(\\n !default_lib.is_zero(), err_default_receive_lib_unavailable(),\\n );\\n GetLibraryResponse {\\n lib: default_lib, is_default: true,\\n } // Return library and indicate it's the default\\n } else {\\n GetLibraryResponse {\\n lib, is_default: false,\\n } // Return custom library and indicate it's not the default\\n }\\n }\\n\\n fn get_raw_receive_library(\\n self: @ComponentState<TContractState>, oapp: ContractAddress, src_eid: u32,\\n ) -> ContractAddress {\\n self.receive_library.entry(oapp).entry(src_eid).read()\\n }\\n\\n fn is_valid_receive_library(\\n self: @ComponentState<TContractState>,\\n oapp: ContractAddress,\\n src_eid: u32,\\n lib: ContractAddress,\\n ) -> bool {\\n // First check if the lib is the currently configured receive library\\n let GetLibraryResponse {\\n lib: expected_lib, is_default,\\n } = self.get_receive_library(oapp, src_eid);\\n if lib == expected_lib {\\n return true;\\n }\\n\\n // If not the current library, check if it's in a valid grace period\\n // Use the appropriate timeout configuration based on whether default is being used\\n let timeout = if is_default {\\n // OApp is using default library, check default timeout configuration\\n self.default_receive_library_timeout.entry(src_eid).read()\\n } else {\\n // OApp has custom library, check OApp-specific timeout configuration\\n self.receive_library_timeout.entry(oapp).entry(src_eid).read()\\n };\\n\\n // Library is valid if it matches the timeout library and hasn't expired\\n timeout.lib == lib && timeout.expiry > get_block_number()\\n }\\n\\n fn set_default_receive_library(\\n ref self: ComponentState<TContractState>,\\n eid: u32,\\n lib: ContractAddress,\\n grace_period: u64,\\n ) {\\n // Only the protocol owner can set default libraries\\n self._assert_only_owner();\\n\\n // Prevent no-op updates (must provide a different value)\\n let old_lib = self.default_receive_library.entry(eid).read();\\n assert_with_byte_array(old_lib != lib, err_same_value());\\n\\n // Validate library registration, type, and endpoint support\\n self._assert_registered(lib);\\n self._assert_receive_lib(lib);\\n self._assert_supported_receive_eid(lib, eid);\\n\\n // Update the default receive library for the endpoint\\n self.default_receive_library.entry(eid).write(lib);\\n self.emit(DefaultReceiveLibrarySet { eid, library: lib });\\n\\n if grace_period > 0 {\\n // Set grace period for the old default library to remain valid\\n let timeout = Timeout { lib: old_lib, expiry: get_block_number() + grace_period };\\n self.default_receive_library_timeout.entry(eid).write(timeout);\\n self\\n .emit(\\n DefaultReceiveLibraryTimeoutSet {\\n eid, library: old_lib, expiry: timeout.expiry,\\n },\\n );\\n } else {\\n // Remove any existing timeout configuration\\n // this writes the default value for Timeout struct\\n self.default_receive_library_timeout.entry(eid).write(DEFAULT_TIMEOUT);\\n self\\n .emit(\\n DefaultReceiveLibraryTimeoutSet {\\n eid, library: old_lib, expiry: DEFAULT_EXPIRY,\\n },\\n );\\n }\\n }\\n\\n fn get_default_receive_library(\\n self: @ComponentState<TContractState>, eid: u32,\\n ) -> ContractAddress {\\n self.default_receive_library.entry(eid).read()\\n }\\n\\n fn is_default_receive_library(\\n self: @ComponentState<TContractState>, oapp: ContractAddress, src_eid: u32,\\n ) -> bool {\\n self.receive_library.entry(oapp).entry(src_eid).read() == DEFAULT_LIB\\n }\\n\\n fn set_receive_library_timeout(\\n ref self: ComponentState<TContractState>,\\n oapp: ContractAddress,\\n eid: u32,\\n lib: ContractAddress,\\n expiry: u64,\\n ) {\\n // Only the OApp itself can manage its timeout configurations\\n self._assert_authorized(oapp);\\n\\n // Validate library registration, type, and endpoint support\\n self._assert_registered(lib);\\n self._assert_receive_lib(lib);\\n self._assert_supported_receive_eid(lib, eid);\\n\\n let GetLibraryResponse { is_default, .. } = self.get_receive_library(oapp, eid);\\n // OApps using default libraries cannot set custom timeouts\\n assert_with_byte_array(!is_default, err_only_non_default_lib());\\n\\n if expiry > 0 {\\n // Set new timeout configuration (expiry must be in the future)\\n assert_with_byte_array(expiry > get_block_number(), err_invalid_expiry());\\n let timeout = Timeout { lib, expiry };\\n self.receive_library_timeout.entry(oapp).entry(eid).write(timeout);\\n } else {\\n // Remove the timeout configuration (force expire)\\n self.receive_library_timeout.entry(oapp).entry(eid).write(DEFAULT_TIMEOUT);\\n }\\n self.emit(ReceiveLibraryTimeoutSet { receiver: oapp, eid, library: lib, expiry });\\n }\\n\\n fn get_receive_library_timeout(\\n self: @ComponentState<TContractState>, oapp: ContractAddress, eid: u32,\\n ) -> Timeout {\\n self.receive_library_timeout.entry(oapp).entry(eid).read()\\n }\\n\\n fn set_default_receive_library_timeout(\\n ref self: ComponentState<TContractState>, eid: u32, lib: ContractAddress, expiry: u64,\\n ) {\\n // Only the protocol owner can manage default timeout configurations\\n self._assert_only_owner();\\n\\n // Validate library registration, type, and endpoint support\\n self._assert_registered(lib);\\n self._assert_receive_lib(lib);\\n self._assert_supported_receive_eid(lib, eid);\\n\\n if expiry > 0 {\\n // Set new default timeout configuration (expiry must be in the future)\\n assert_with_byte_array(expiry > get_block_number(), err_invalid_expiry());\\n let timeout = Timeout { lib, expiry };\\n self.default_receive_library_timeout.entry(eid).write(timeout);\\n } else {\\n // Remove the default timeout configuration (force expire)\\n self.default_receive_library_timeout.entry(eid).write(DEFAULT_TIMEOUT);\\n }\\n self.emit(DefaultReceiveLibraryTimeoutSet { eid, library: lib, expiry });\\n }\\n\\n fn get_default_receive_library_timeout(\\n self: @ComponentState<TContractState>, eid: u32,\\n ) -> Timeout {\\n self.default_receive_library_timeout.entry(eid).read()\\n }\\n\\n // ========================= Configuration Management =========================\\n\\n fn set_send_configs(\\n ref self: ComponentState<TContractState>,\\n oapp: ContractAddress,\\n lib: ContractAddress,\\n params: Array<SetConfigParam>,\\n ) {\\n // Only the OApp itself can set its send configuration\\n self._assert_authorized(oapp);\\n\\n self._assert_registered(lib);\\n self._assert_send_lib(lib);\\n\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: lib };\\n lib_dispatcher.set_send_configs(oapp, params);\\n }\\n\\n fn set_receive_configs(\\n ref self: ComponentState<TContractState>,\\n oapp: ContractAddress,\\n lib: ContractAddress,\\n params: Array<SetConfigParam>,\\n ) {\\n // Only the OApp itself can set its receive configuration\\n self._assert_authorized(oapp);\\n\\n self._assert_registered(lib);\\n self._assert_receive_lib(lib);\\n\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: lib };\\n lib_dispatcher.set_receive_configs(oapp, params);\\n }\\n\\n fn get_send_config(\\n self: @ComponentState<TContractState>,\\n oapp: ContractAddress,\\n lib: ContractAddress,\\n eid: u32,\\n config_type: u32,\\n ) -> Array<felt252> {\\n // Only registered libraries can provide configuration\\n self._assert_registered(lib);\\n self._assert_send_lib(lib);\\n\\n // Delegate configuration query to the message library\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: lib };\\n lib_dispatcher.get_send_config(eid, oapp, config_type)\\n }\\n\\n fn get_receive_config(\\n self: @ComponentState<TContractState>,\\n oapp: ContractAddress,\\n lib: ContractAddress,\\n eid: u32,\\n config_type: u32,\\n ) -> Array<felt252> {\\n // Only registered libraries can provide configuration\\n self._assert_registered(lib);\\n self._assert_receive_lib(lib);\\n\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: lib };\\n lib_dispatcher.get_receive_config(eid, oapp, config_type)\\n }\\n\\n // ========================= Utility Functions =========================\\n\\n fn is_supported_eid(self: @ComponentState<TContractState>, eid: u32) -> bool {\\n // An endpoint is considered supported if it has both default send and receive libraries\\n let default_send = self.default_send_library.entry(eid).read();\\n let default_receive = self.default_receive_library.entry(eid).read();\\n !default_send.is_zero() && !default_receive.is_zero()\\n }\\n }\\n\\n /// =============================== Internal Functions =================================\\n #[generate_trait]\\n pub impl InternalImpl<\\n TContractState,\\n +HasComponent<TContractState>,\\n impl Ownable: OwnableComponent::HasComponent<TContractState>,\\n +Drop<TContractState>,\\n > of InternalTrait<TContractState> {\\n /// Initialize the MessageLibManager component with a blocked library\\n ///\\n /// The blocked library is automatically registered and serves as a way to\\n /// disable sending/receiving on specific endpoints by setting it as the default.\\n ///\\n /// # Arguments\\n /// * `blocked_library` - Address of the library that blocks operations\\n fn initializer(ref self: ComponentState<TContractState>, blocked_library: ContractAddress) {\\n // Query the library for its type to ensure it implements IMessageLib.\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: blocked_library };\\n let _ = lib_dispatcher.message_lib_type();\\n\\n self.blocked_library.write(blocked_library);\\n\\n // Register blocked library directly without owner check during initialization\\n self.is_registered_library.entry(blocked_library).write(true);\\n self.registered_libraries.push(blocked_library);\\n self.emit(LibraryRegistered { library: blocked_library });\\n }\\n\\n /// Assert that the caller is the contract owner\\n ///\\n /// Uses the Ownable component to verify ownership permissions.\\n /// Used for operations that require protocol-level administrative access.\\n fn _assert_only_owner(self: @ComponentState<TContractState>) {\\n let ownable = get_dep_component!(self, Ownable);\\n ownable.assert_only_owner();\\n }\\n\\n /// Assert that a library is registered with the endpoint\\n ///\\n /// # Arguments\\n /// * `lib` - The library address to validate\\n ///\\n /// # Panics\\n /// * If the library is not registered\\n fn _assert_registered(self: @ComponentState<TContractState>, lib: ContractAddress) {\\n assert_with_byte_array(\\n self.is_registered_library.entry(lib).read(), err_only_registered_lib(),\\n );\\n }\\n\\n /// Assert that a library is registered or is the DEFAULT_LIB constant\\n ///\\n /// This allows functions to accept either a registered library or the special\\n /// DEFAULT_LIB value that indicates the default library should be used.\\n ///\\n /// # Arguments\\n /// * `lib` - The library address to validate\\n ///\\n /// # Panics\\n /// * If the library is not registered and is not DEFAULT_LIB\\n fn _assert_registered_or_default(\\n self: @ComponentState<TContractState>, lib: ContractAddress,\\n ) {\\n if lib != DEFAULT_LIB {\\n assert_with_byte_array(\\n self.is_registered_library.entry(lib).read(),\\n err_only_registered_or_default_lib(),\\n );\\n }\\n }\\n\\n /// Assert that a library supports send operations\\n ///\\n /// Validates that the library's type is either Send or SendAndReceive.\\n /// Skips validation for DEFAULT_LIB as it will be resolved later.\\n ///\\n /// # Arguments\\n /// * `lib` - The library address to validate\\n ///\\n /// # Panics\\n /// * If the library doesn't support send operations\\n fn _assert_send_lib(self: @ComponentState<TContractState>, lib: ContractAddress) {\\n if lib != DEFAULT_LIB {\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: lib };\\n let lib_type = lib_dispatcher.message_lib_type();\\n assert_with_byte_array(\\n lib_type == MessageLibType::Send || lib_type == MessageLibType::SendAndReceive,\\n err_only_send_lib(),\\n );\\n }\\n }\\n\\n /// Assert that a library supports receive operations\\n ///\\n /// Validates that the library's type is either Receive or SendAndReceive.\\n /// Skips validation for DEFAULT_LIB as it will be resolved later.\\n ///\\n /// # Arguments\\n /// * `lib` - The library address to validate\\n ///\\n /// # Panics\\n /// * If the library doesn't support receive operations\\n fn _assert_receive_lib(self: @ComponentState<TContractState>, lib: ContractAddress) {\\n if lib != DEFAULT_LIB {\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: lib };\\n let lib_type = lib_dispatcher.message_lib_type();\\n assert_with_byte_array(\\n lib_type == MessageLibType::Receive\\n || lib_type == MessageLibType::SendAndReceive,\\n err_only_receive_lib(),\\n );\\n }\\n }\\n\\n /// Assert that a library supports operations for a specific endpoint\\n ///\\n /// Validates that the library has enabled support for the given endpoint ID.\\n /// This ensures libraries can only be used for endpoints they're designed to handle.\\n /// Skips validation for DEFAULT_LIB as it will be resolved later.\\n ///\\n /// # Arguments\\n /// * `lib` - The library address to validate\\n /// * `eid` - The endpoint ID to check support for\\n ///\\n /// # Panics\\n /// * If the library doesn't support the specified endpoint\\n fn _assert_supported_send_eid(\\n self: @ComponentState<TContractState>, lib: ContractAddress, eid: u32,\\n ) {\\n if lib != DEFAULT_LIB {\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: lib };\\n assert_with_byte_array(\\n lib_dispatcher.is_supported_send_eid(eid), err_unsupported_eid(eid),\\n );\\n }\\n }\\n\\n fn _assert_supported_receive_eid(\\n self: @ComponentState<TContractState>, lib: ContractAddress, eid: u32,\\n ) {\\n if lib != DEFAULT_LIB {\\n let lib_dispatcher = IMessageLibDispatcher { contract_address: lib };\\n assert_with_byte_array(\\n lib_dispatcher.is_supported_receive_eid(eid), err_unsupported_eid(eid),\\n );\\n }\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/message_lib_manager/structs.cairo\": \"//! Message library manager structs\\n\\nuse starknet::ContractAddress;\\nuse crate::endpoint::message_lib_manager::message_lib_manager::MessageLibManagerComponent::DEFAULT_LIB;\\n\\n/// Timeout struct for receive library grace periods\\n///\\n/// When upgrading receive libraries, the old library can be given a grace period\\n/// during which it remains valid for receiving messages. This allows for smooth\\n/// transitions without breaking in-flight messages.\\n#[derive(Copy, Drop, Serde, starknet::Store, PartialEq)]\\npub struct Timeout {\\n /// The library contract address that is in grace period\\n pub lib: ContractAddress,\\n /// Block number when the grace period expires\\n pub expiry: u64,\\n}\\n\\nimpl DefaultTimeout of Default<Timeout> {\\n fn default() -> Timeout {\\n Timeout { lib: DEFAULT_LIB, expiry: 0 }\\n }\\n}\\n\\n/// Response struct for get_receive_library function\\n///\\n/// Contains the library address and a boolean indicating if it's the default library\\n/// Used to return the resolved library and its type (custom or default)\\n#[derive(Copy, Drop, Serde, starknet::Store, PartialEq)]\\npub struct GetLibraryResponse {\\n pub lib: ContractAddress,\\n pub is_default: bool,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/messaging_channel/errors.cairo\": \"//! Messaging channel errors\\n\\nuse lz_utils::bytes::Bytes32;\\nuse lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum MessagingChannelError {\\n /// Triggered when a message with an invalid nonce is received.\\n InvalidNonce,\\n /// Triggered when the payload hash of a received message does not match the committed payload\\n /// hash.\\n PayloadHashNotFound,\\n}\\n\\nimpl ErrorNameImpl of Error<MessagingChannelError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_MESSAGING_CHANNEL\\\"\\n }\\n\\n fn name(self: MessagingChannelError) -> ByteArray {\\n match self {\\n MessagingChannelError::InvalidNonce => \\\"INVALID_NONCE\\\",\\n MessagingChannelError::PayloadHashNotFound => \\\"PAYLOAD_HASH_NOT_FOUND\\\",\\n }\\n }\\n}\\n\\npub fn err_invalid_nonce() -> ByteArray {\\n format_error(MessagingChannelError::InvalidNonce, \\\"\\\")\\n}\\n\\npub fn err_payload_hash_not_found(expected_hash: Bytes32, actual_hash: Bytes32) -> ByteArray {\\n format_error(\\n MessagingChannelError::PayloadHashNotFound,\\n format!(\\\"Expected hash: {}, Actual hash: {}\\\", expected_hash.value, actual_hash.value),\\n )\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/messaging_channel/events.cairo\": \"//! Messaging channel events\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\n\\n/// Emitted when an inbound nonce is skipped.\\n#[derive(Drop, starknet::Event)]\\npub struct InboundNonceSkipped {\\n /// The receiver's address.\\n #[key]\\n pub receiver: ContractAddress,\\n /// The source EID.\\n #[key]\\n pub src_eid: u32,\\n /// The sender's address.\\n #[key]\\n pub sender: Bytes32,\\n /// The skipped nonce.\\n pub nonce: u64,\\n}\\n\\n/// Emitted when a packet's payload hash is nilified (set to a placeholder value).\\n#[derive(Drop, starknet::Event)]\\npub struct PacketNilified {\\n /// The receiver's address.\\n #[key]\\n pub receiver: ContractAddress,\\n /// The source EID.\\n #[key]\\n pub src_eid: u32,\\n /// The sender's address.\\n #[key]\\n pub sender: Bytes32,\\n /// The nonce of the packet.\\n pub nonce: u64,\\n /// The payload hash that was nilified.\\n #[key]\\n pub payload_hash: Bytes32,\\n}\\n\\n/// Emitted when a packet's payload hash is burnt (cleared from storage).\\n#[derive(Drop, starknet::Event)]\\npub struct PacketBurnt {\\n /// The receiver's address.\\n #[key]\\n pub receiver: ContractAddress,\\n /// The source EID.\\n #[key]\\n pub src_eid: u32,\\n /// The sender's address.\\n #[key]\\n pub sender: Bytes32,\\n /// The nonce of the packet.\\n pub nonce: u64,\\n /// The payload hash that was burnt.\\n #[key]\\n pub payload_hash: Bytes32,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/messaging_channel/interface.cairo\": \"//! Messaging channel interface\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::common::structs::packet::Origin;\\n\\n/// # `IMessagingChannel` Interface\\n///\\n/// The `IMessagingChannel` interface is responsible for nonce management and message verification\\n/// for LayerZero cross-chain messaging. It ensures ordered execution and provides mechanisms for\\n/// skipping, nilifying, and burning messages as needed.\\n#[starknet::interface]\\npub trait IMessagingChannel<TContractState> {\\n /// Returns the max index of the longest gapless sequence of verified message nonces\\n ///\\n /// The uninitialized value is 0. The first nonce is always 1.\\n /// Starts from lazy_inbound_nonce and iteratively checks if the next nonce has been verified.\\n /// NOTE: OApp explicitly skipped nonces count as \\\"verified\\\" for these purposes.\\n /// Example: [1,2,3,4,6,7] => 4, [1,2,6,8,10] => 2, [1,3,4,5,6] => 1\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `src_eid`: The source endpoint ID\\n /// * `sender`: The sender address from the source chain\\n ///\\n /// # Returns\\n ///\\n /// * `u64`: The highest consecutively verified nonce\\n ///\\n /// # Panics\\n /// * If too many backlogs exist and the function runs out of gas (can be fixed by clearing\\n /// prior messages)\\n fn inbound_nonce(\\n self: @TContractState, receiver: ContractAddress, src_eid: u32, sender: Bytes32,\\n ) -> u64;\\n\\n /// Returns the current outbound nonce for a specific path\\n ///\\n /// Used to track the number of messages sent on a specific path.\\n /// Incremented each time a message is sent through the endpoint.\\n ///\\n /// # Arguments\\n ///\\n /// * `sender`: The sender contract address\\n /// * `dst_eid`: The destination endpoint ID\\n /// * `receiver`: The receiver address on the destination chain\\n ///\\n /// # Returns\\n ///\\n /// * `u64`: The current outbound nonce for this path\\n fn outbound_nonce(\\n self: @TContractState, sender: ContractAddress, dst_eid: u32, receiver: Bytes32,\\n ) -> u64;\\n\\n /// Returns the stored payload hash for a specific message\\n ///\\n /// Returns EMPTY_PAYLOAD_HASH (0) if the message has been executed.\\n /// Returns NIL_PAYLOAD_HASH (bytes32.max) if the message has been nilified.\\n /// Returns the actual payload hash if the message is verified but not executed.\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `src_eid`: The source endpoint ID\\n /// * `sender`: The sender address from the source chain\\n /// * `nonce`: The message nonce\\n ///\\n /// # Returns\\n ///\\n /// * `Bytes32`: The payload hash for the specified message\\n fn inbound_payload_hash(\\n self: @TContractState, receiver: ContractAddress, src_eid: u32, sender: Bytes32, nonce: u64,\\n ) -> Bytes32;\\n\\n /// Returns the lazy inbound nonce (last checkpoint) for a specific path\\n ///\\n /// This is the last nonce that was processed (executed or skipped).\\n /// Used as a starting point for calculating the effective inbound nonce.\\n /// Updated lazily when messages are executed or explicitly skipped.\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `src_eid`: The source endpoint ID\\n /// * `sender`: The sender address from the source chain\\n ///\\n /// # Returns\\n ///\\n /// * `u64`: The lazy inbound nonce representing the last processed checkpoint\\n fn lazy_inbound_nonce(\\n self: @TContractState, receiver: ContractAddress, src_eid: u32, sender: Bytes32,\\n ) -> u64;\\n\\n /// Skips the next expected nonce to prevent message verification\\n ///\\n /// Usage: Skip messages when Precrime throws alerts or other security concerns arise.\\n /// After skipping, the lazy_inbound_nonce is set to the provided nonce.\\n /// This allows the Receiver to increment the lazy_inbound_nonce without verification.\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin of the message\\n ///\\n /// # Panics\\n /// * If the provided nonce is not exactly the next expected nonce\\n /// * If a race condition occurs (e.g. trying to skip nonce 3 but nonce 3 was consumed\\n /// first)\\n fn skip(ref self: TContractState, receiver: ContractAddress, origin: Origin);\\n\\n /// Marks a packet as verified but disallows execution until it is re-verified\\n ///\\n /// A non-verified nonce can be nilified by passing EMPTY_PAYLOAD_HASH for payload_hash.\\n /// Assumes computational intractability of finding a payload that hashes to bytes32.max.\\n /// Sets the payload hash to NIL_PAYLOAD_HASH to prevent execution while keeping\\n /// verification.\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `src_eid`: The source endpoint ID where the message originated\\n /// * `sender`: The sender address from the source chain\\n /// * `nonce`: The nonce of the message to nilify\\n /// * `payload_hash`: The expected payload hash that must match the stored hash\\n ///\\n /// # Panics\\n /// * If the provided payload_hash does not match the currently verified payload hash\\n /// * If the nonce is greater than the lazy inbound nonce\\n /// * If the nonce has already been executed (payload hash is EMPTY_PAYLOAD_HASH)\\n fn nilify(\\n ref self: TContractState, receiver: ContractAddress, origin: Origin, payload_hash: Bytes32,\\n );\\n\\n\\n /// Marks a nonce as unexecutable and un-verifiable permanently\\n ///\\n /// The nonce can never be re-verified or executed after burning.\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin of the message\\n /// * `origin`: The origin of the message, including the nonce to burn\\n /// * `payload_hash`: The expected payload hash that must match the stored hash\\n ///\\n /// # Panics\\n /// * If the provided payload_hash does not match the currently verified payload hash\\n /// * If the nonce is greater than the lazy inbound nonce\\n /// * If the nonce has already been executed (payload hash is EMPTY_PAYLOAD_HASH)\\n fn burn(\\n ref self: TContractState, receiver: ContractAddress, origin: Origin, payload_hash: Bytes32,\\n );\\n\\n\\n /// Returns the GUID for the next message given the path\\n ///\\n /// The OApp might want to include the GUID into the message in some cases.\\n /// Uses the next outbound nonce to generate a unique identifier.\\n ///\\n /// # Arguments\\n ///\\n /// * `sender`: The sender contract address\\n /// * `dst_eid`: The destination endpoint ID\\n /// * `receiver`: The receiver address on the destination chain\\n ///\\n /// # Returns\\n ///\\n /// * `Bytes32`: The globally unique identifier for the next message\\n fn next_guid(\\n self: @TContractState, sender: ContractAddress, dst_eid: u32, receiver: Bytes32,\\n ) -> Bytes32;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/messaging_channel/messaging_channel.cairo\": \"//! Messaging channel component\\n\\n/// # `MessagingChannelComponent`\\n///\\n/// This component handles the critical messaging infrastructure for LayerZero cross-chain\\n/// communication.\\n/// It manages inbound and outbound nonces, payload hash verification, and provides mechanisms for\\n/// message lifecycle management including skipping, nilifying, and burning messages.\\n///\\n/// ## Key features\\n/// - Ordered message execution with nonce management\\n/// - Payload hash verification for message integrity\\n/// - Lazy nonce updates for gas optimization\\n/// - Message lifecycle management (skip, nilify, burn)\\n/// - GUID generation for unique message identification\\n#[starknet::component]\\npub mod MessagingChannelComponent {\\n use lz_utils::bytes::{Bytes32, ContractAddressIntoBytes32};\\n use lz_utils::error::assert_with_byte_array;\\n use lz_utils::keccak::keccak256;\\n use starknet::ContractAddress;\\n use starknet::storage::{\\n Map, Mutable, StoragePath, StoragePathEntry, StoragePointerReadAccess,\\n StoragePointerWriteAccess,\\n };\\n use crate::common::guid::GUID;\\n use crate::common::structs::packet::Origin;\\n use crate::endpoint::constants::{EMPTY_PAYLOAD_HASH, NIL_PAYLOAD_HASH};\\n use crate::endpoint::messaging_channel::errors::{err_invalid_nonce, err_payload_hash_not_found};\\n use crate::endpoint::messaging_channel::events::{\\n InboundNonceSkipped, PacketBurnt, PacketNilified,\\n };\\n use crate::endpoint::messaging_channel::interface::IMessagingChannel;\\n\\n /// =============================== Storage =================================\\n\\n #[storage]\\n pub struct Storage {\\n /// The universally unique endpoint identifier for this deployed instance\\n pub eid: u32,\\n /// Outbound nonce tracking: sender => [dstEid => [receiver => nonce]]\\n ///\\n /// Tracks the number of messages sent from each sender to each destination.\\n /// Incremented atomically when messages are sent.\\n pub outbound_nonce: Map<ContractAddress, Map<u32, Map<Bytes32, u64>>>,\\n /// Lazy inbound nonce tracking: receiver => [srcEid => [sender => nonce]]\\n ///\\n /// Represents the last processed nonce (checkpoint) for each path.\\n /// Updated lazily when messages are executed or explicitly skipped.\\n /// Used as starting point for calculating effective inbound nonce.\\n pub lazy_inbound_nonce: Map<ContractAddress, Map<u32, Map<Bytes32, u64>>>,\\n /// Inbound payload hash storage: receiver => [srcEid => [sender => [nonce => payloadHash]]]\\n ///\\n /// Stores payload hashes for verified but not yet executed messages.\\n /// EMPTY_PAYLOAD_HASH (0) indicates message has been executed.\\n /// NIL_PAYLOAD_HASH (max) indicates message has been nilified.\\n /// Actual hash indicates message is verified and ready for execution.\\n pub inbound_payload_hash: Map<ContractAddress, Map<u32, Map<Bytes32, Map<u64, Bytes32>>>>,\\n }\\n\\n /// =============================== Events =================================\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n InboundNonceSkipped: InboundNonceSkipped,\\n PacketNilified: PacketNilified,\\n PacketBurnt: PacketBurnt,\\n }\\n\\n // =============================== Hooks =================================\\n pub trait MessagingChannelHooks<TContractState> {\\n fn _assert_authorized(self: @ComponentState<TContractState>, receiver: ContractAddress);\\n }\\n\\n /// =============================== Public Interface =================================\\n\\n #[embeddable_as(MessagingChannelImpl)]\\n impl MessagingChannel<\\n TContractState, +HasComponent<TContractState>, +MessagingChannelHooks<TContractState>,\\n > of IMessagingChannel<ComponentState<TContractState>> {\\n fn inbound_nonce(\\n self: @ComponentState<TContractState>,\\n receiver: ContractAddress,\\n src_eid: u32,\\n sender: Bytes32,\\n ) -> u64 {\\n // Start from the last lazy checkpoint\\n let mut nonce_cursor = self.lazy_inbound_nonce(receiver, src_eid, sender);\\n\\n // Find the effective inbound nonce by checking consecutive verified nonces\\n while self._has_payload_hash(receiver, src_eid, sender, nonce_cursor + 1) {\\n nonce_cursor += 1;\\n }\\n nonce_cursor\\n }\\n\\n fn outbound_nonce(\\n self: @ComponentState<TContractState>,\\n sender: ContractAddress,\\n dst_eid: u32,\\n receiver: Bytes32,\\n ) -> u64 {\\n self.outbound_nonce.entry(sender).entry(dst_eid).entry(receiver).read()\\n }\\n\\n fn inbound_payload_hash(\\n self: @ComponentState<TContractState>,\\n receiver: ContractAddress,\\n src_eid: u32,\\n sender: Bytes32,\\n nonce: u64,\\n ) -> Bytes32 {\\n self._inbound_payload_hash(receiver, src_eid, sender, nonce)\\n }\\n\\n fn lazy_inbound_nonce(\\n self: @ComponentState<TContractState>,\\n receiver: ContractAddress,\\n src_eid: u32,\\n sender: Bytes32,\\n ) -> u64 {\\n // Using helper function for consistent storage access\\n self.lazy_inbound_nonce.entry(receiver).entry(src_eid).entry(sender).read()\\n }\\n\\n fn skip(\\n ref self: ComponentState<TContractState>, receiver: ContractAddress, origin: Origin,\\n ) {\\n self._assert_authorized(receiver);\\n\\n let Origin { src_eid, sender, nonce } = origin;\\n\\n // Ensure the provided nonce is exactly the next expected nonce\\n assert_with_byte_array(\\n nonce == self.inbound_nonce(receiver, src_eid, sender) + 1, err_invalid_nonce(),\\n );\\n\\n // Update the lazy inbound nonce to the skipped nonce (using helper function)\\n self._lazy_inbound_nonce_entry(receiver, src_eid, sender).write(nonce);\\n\\n self.emit(InboundNonceSkipped { receiver, src_eid, sender, nonce });\\n }\\n\\n fn nilify(\\n ref self: ComponentState<TContractState>,\\n receiver: ContractAddress,\\n origin: Origin,\\n payload_hash: Bytes32,\\n ) {\\n self._assert_authorized(receiver);\\n\\n // Validate and get current payload hash (using consolidated validation helper)\\n self._validate_payload_hash(receiver, @origin, payload_hash);\\n\\n let Origin { src_eid, sender, nonce } = origin;\\n\\n // Get the current lazy nonce for validation (using helper function)\\n let lazy_nonce = self._lazy_inbound_nonce_entry(receiver, src_eid, sender).read();\\n\\n // If nonce is smaller or equal to the lazy nonce, ensure it's not already executed\\n assert_with_byte_array(\\n nonce > lazy_nonce || payload_hash != EMPTY_PAYLOAD_HASH, err_invalid_nonce(),\\n );\\n\\n // Set the payload hash to NIL to prevent execution (using helper function)\\n self\\n ._inbound_payload_hash_entry(receiver, src_eid, sender, nonce)\\n .write(NIL_PAYLOAD_HASH);\\n\\n self.emit(PacketNilified { receiver, src_eid, sender, nonce, payload_hash });\\n }\\n\\n fn burn(\\n ref self: ComponentState<TContractState>,\\n receiver: ContractAddress,\\n origin: Origin,\\n payload_hash: Bytes32,\\n ) {\\n self._assert_authorized(receiver);\\n\\n self._validate_payload_hash(receiver, @origin, payload_hash);\\n\\n let Origin { src_eid, sender, nonce } = origin;\\n\\n let lazy_nonce = self._lazy_inbound_nonce_entry(receiver, src_eid, sender).read();\\n\\n // Ensure the message hasn't been executed and nonce is smaller or equal to the lazy\\n // nonce\\n assert_with_byte_array(\\n payload_hash != EMPTY_PAYLOAD_HASH && nonce <= lazy_nonce, err_invalid_nonce(),\\n );\\n\\n // Permanently remove the payload hash (using helper function)\\n self\\n ._inbound_payload_hash_entry(receiver, src_eid, sender, nonce)\\n .write(EMPTY_PAYLOAD_HASH);\\n\\n self.emit(PacketBurnt { receiver, src_eid, sender, nonce, payload_hash });\\n }\\n\\n fn next_guid(\\n self: @ComponentState<TContractState>,\\n sender: ContractAddress,\\n dst_eid: u32,\\n receiver: Bytes32,\\n ) -> Bytes32 {\\n let next_nonce = self.outbound_nonce(sender, dst_eid, receiver) + 1;\\n\\n GUID::generate(next_nonce, self.eid.read(), sender.into(), dst_eid, receiver)\\n }\\n }\\n\\n /// =============================== Internal Interface =================================\\n\\n /// Internal interface for component functions used by the endpoint and other components\\n #[generate_trait]\\n pub impl InternalImpl<\\n TContractState, +HasComponent<TContractState>,\\n > of InternalTrait<TContractState> {\\n /// Initialize the MessagingChannel component with the endpoint ID\\n ///\\n /// Should be called during contract deployment/initialization.\\n /// The endpoint ID is immutable once set.\\n ///\\n /// # Arguments\\n ///\\n /// * `eid`: The universally unique endpoint identifier\\n fn initializer(ref self: ComponentState<TContractState>, eid: u32) {\\n self.eid.write(eid);\\n }\\n\\n /// Returns a mutable storage path for the outbound nonce\\n ///\\n /// Used internally by the endpoint to increment nonces when sending messages.\\n ///\\n /// # Arguments\\n ///\\n /// * `sender`: The sender contract address\\n /// * `dst_eid`: The destination endpoint ID\\n /// * `receiver`: The receiver address on the destination chain\\n ///\\n /// # Returns\\n ///\\n /// * `StoragePath<Mutable<u64>>`: Mutable storage path for the outbound nonce\\n fn _outbound_nonce_entry(\\n ref self: ComponentState<TContractState>,\\n sender: ContractAddress,\\n dst_eid: u32,\\n receiver: Bytes32,\\n ) -> StoragePath<Mutable<u64>> {\\n self.outbound_nonce.entry(sender).entry(dst_eid).entry(receiver)\\n }\\n\\n /// Returns a mutable storage path for the lazy inbound nonce\\n ///\\n /// Used internally to update checkpoint nonces during message execution.\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `src_eid`: The source endpoint ID\\n /// * `sender`: The sender address on the source chain\\n ///\\n /// # Returns\\n ///\\n /// * `StoragePath<Mutable<u64>>`: Mutable storage path for the lazy inbound nonce\\n fn _lazy_inbound_nonce_entry(\\n ref self: ComponentState<TContractState>,\\n receiver: ContractAddress,\\n src_eid: u32,\\n sender: Bytes32,\\n ) -> StoragePath<Mutable<u64>> {\\n self.lazy_inbound_nonce.entry(receiver).entry(src_eid).entry(sender)\\n }\\n\\n /// Returns a mutable storage path for the inbound payload hash\\n ///\\n /// Used internally to store and clear payload hashes during verification and execution.\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `src_eid`: The source endpoint ID\\n /// * `sender`: The sender address on the source chain\\n /// * `nonce`: The message nonce\\n ///\\n /// # Returns\\n ///\\n /// * `StoragePath<Mutable<Bytes32>>`: Mutable storage path for the payload hash\\n fn _inbound_payload_hash_entry(\\n ref self: ComponentState<TContractState>,\\n receiver: ContractAddress,\\n src_eid: u32,\\n sender: Bytes32,\\n nonce: u64,\\n ) -> StoragePath<Mutable<Bytes32>> {\\n self.inbound_payload_hash.entry(receiver).entry(src_eid).entry(sender).entry(nonce)\\n }\\n\\n /// Returns the inbound payload hash\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `src_eid`: The source endpoint ID\\n /// * `sender`: The sender address on the source chain\\n /// * `nonce`: The message nonce\\n ///\\n /// # Returns\\n ///\\n /// * `Bytes32`: The payload hash\\n fn _inbound_payload_hash(\\n self: @ComponentState<TContractState>,\\n receiver: ContractAddress,\\n src_eid: u32,\\n sender: Bytes32,\\n nonce: u64,\\n ) -> Bytes32 {\\n self\\n .inbound_payload_hash\\n .entry(receiver)\\n .entry(src_eid)\\n .entry(sender)\\n .entry(nonce)\\n .read()\\n }\\n\\n /// Checks if a payload hash exists for a specific message\\n ///\\n /// Checks if the storage slot is not initialized.\\n /// Assumes computationally infeasible that payload can hash to 0.\\n /// Returns false for EMPTY_PAYLOAD_HASH (executed messages).\\n /// Returns true for both actual hashes and NIL_PAYLOAD_HASH (nilified messages).\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `src_eid`: The source endpoint ID\\n /// * `sender`: The sender address on the source chain\\n /// * `nonce`: The message nonce to check\\n ///\\n /// # Returns\\n ///\\n /// * `bool`: True if a payload hash exists (message is verified), false otherwise\\n fn _has_payload_hash(\\n self: @ComponentState<TContractState>,\\n receiver: ContractAddress,\\n src_eid: u32,\\n sender: Bytes32,\\n nonce: u64,\\n ) -> bool {\\n self._inbound_payload_hash(receiver, src_eid, sender, nonce) != EMPTY_PAYLOAD_HASH\\n }\\n\\n /// Validates that the provided payload hash matches the stored hash and returns it\\n ///\\n /// Consolidates repetitive payload hash validation logic used in nilify() and burn().\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `origin`: The origin information containing source endpoint, sender, and nonce\\n /// * `expected_payload_hash`: The payload hash to validate against stored hash\\n ///\\n /// # Returns\\n ///\\n /// * `Bytes32`: The validated current payload hash from storage\\n ///\\n /// # Panics\\n ///\\n /// * `err_payload_hash_not_found`: If the stored hash doesn't match the expected hash\\n fn _validate_payload_hash(\\n self: @ComponentState<TContractState>,\\n receiver: ContractAddress,\\n origin: @Origin,\\n expected_payload_hash: Bytes32,\\n ) {\\n let current_payload_hash = self\\n ._inbound_payload_hash(receiver, *origin.src_eid, *origin.sender, *origin.nonce);\\n assert_with_byte_array(\\n current_payload_hash == expected_payload_hash,\\n err_payload_hash_not_found(expected_payload_hash, current_payload_hash),\\n );\\n }\\n\\n /// Clears a payload after successful execution and updates lazy nonce\\n ///\\n /// This function is called during message execution to clear verified payloads.\\n /// Updates the lazy_inbound_nonce to the provided nonce if it's greater than current.\\n /// Verifies that all nonces between current and target have payload hashes (ordered\\n /// execution).\\n /// Validates the payload hash matches the stored hash before clearing.\\n /// Sets the payload hash to EMPTY_PAYLOAD_HASH to mark as executed.\\n ///\\n /// # Arguments\\n ///\\n /// * `receiver`: The receiver contract address\\n /// * `origin`: The origin information containing source endpoint, sender, and nonce\\n /// * `payload`: The payload bytes to verify and clear\\n fn _clear_payload(\\n ref self: ComponentState<TContractState>,\\n receiver: ContractAddress,\\n origin: @Origin,\\n payload: @ByteArray,\\n ) {\\n // Get the current lazy nonce checkpoint\\n let lazy_nonce_entry = self\\n ._lazy_inbound_nonce_entry(receiver, *origin.src_eid, *origin.sender);\\n let current_nonce = lazy_nonce_entry.read();\\n\\n // If this nonce is beyond the current checkpoint, validate ordered execution\\n if *origin.nonce > current_nonce {\\n // Ensure that no nonce between current_nonce and origin.nonce is missing a payload\\n // hash. Because if it is, it means we have an unverified nonce in between\\n // and we can't execute the packet until everything before it is committed\\n for nonce in current_nonce + 1..*origin.nonce {\\n assert_with_byte_array(\\n self._has_payload_hash(receiver, *origin.src_eid, *origin.sender, nonce),\\n err_invalid_nonce(),\\n );\\n }\\n // Update the lazy nonce to the current execution point\\n lazy_nonce_entry.write(*origin.nonce);\\n }\\n\\n // Verify the payload hash matches what was stored during verification\\n let actual_payload_hash = keccak256(payload);\\n let hash_entry = self\\n ._inbound_payload_hash_entry(\\n receiver, *origin.src_eid, *origin.sender, *origin.nonce,\\n );\\n let expected_payload_hash = hash_entry.read();\\n\\n assert_with_byte_array(\\n actual_payload_hash == expected_payload_hash,\\n err_payload_hash_not_found(expected_payload_hash, actual_payload_hash),\\n );\\n\\n // Clear the payload hash to mark as executed\\n hash_entry.write(EMPTY_PAYLOAD_HASH);\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/messaging_composer/errors.cairo\": \"//! Messaging composer errors\\n\\nuse lz_utils::bytes::Bytes32;\\nuse lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum MessagingChannelError {\\n /// Triggered when a compose message already exists and cannot be overwritten.\\n LzComposeAlreadyExists,\\n /// Triggered when a compose message is not found.\\n LzComposeNotFound,\\n /// Triggered when the value sent with a compose message exceeds the token allowance.\\n LzComposeValueExceedsAllowance,\\n /// Triggered when a transfer fails.\\n TransferFailed,\\n}\\n\\nimpl ErrorNameImpl of Error<MessagingChannelError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_MESSAGING_COMPOSER\\\"\\n }\\n\\n fn name(self: MessagingChannelError) -> ByteArray {\\n match self {\\n MessagingChannelError::LzComposeAlreadyExists => \\\"LZ_COMPOSE_ALREADY_EXISTS\\\",\\n MessagingChannelError::LzComposeNotFound => \\\"LZ_COMPOSE_NOT_FOUND\\\",\\n MessagingChannelError::LzComposeValueExceedsAllowance => \\\"LZ_COMPOSE_VALUE_EXCEEDS_ALLOWANCE\\\",\\n MessagingChannelError::TransferFailed => \\\"TRANSFER_FAILED\\\",\\n }\\n }\\n}\\n\\npub fn err_lz_compose_not_found(expected_hash: Bytes32, actual_hash: Bytes32) -> ByteArray {\\n format_error(\\n MessagingChannelError::LzComposeNotFound,\\n format!(\\\"Expected hash: {}, Actual hash: {}\\\", expected_hash.value, actual_hash.value),\\n )\\n}\\n\\npub fn err_lz_compose_value_exceeds_allowance(value: u256, allowance: u256) -> ByteArray {\\n format_error(\\n MessagingChannelError::LzComposeValueExceedsAllowance,\\n format!(\\\"Value: {}, Allowance: {}\\\", value, allowance),\\n )\\n}\\n\\npub fn err_lz_compose_already_exists() -> ByteArray {\\n format_error(MessagingChannelError::LzComposeAlreadyExists, \\\"\\\")\\n}\\n\\npub fn err_transfer_failed() -> ByteArray {\\n format_error(MessagingChannelError::TransferFailed, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/messaging_composer/events.cairo\": \"//! Messaging composer events\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\n\\n/// Emitted when a compose message is sent.\\n#[derive(Drop, starknet::Event)]\\npub struct ComposeSent {\\n /// The sender of the compose message.\\n #[key]\\n pub from: ContractAddress,\\n /// The recipient of the compose message.\\n #[key]\\n pub to: ContractAddress,\\n /// The GUID of the original message.\\n #[key]\\n pub guid: Bytes32,\\n /// The index of the compose message.\\n pub index: u16,\\n /// The message payload.\\n pub message: ByteArray,\\n}\\n\\n/// Emitted when a compose message is delivered.\\n#[derive(Drop, starknet::Event)]\\npub struct ComposeDelivered {\\n /// The sender of the compose message.\\n #[key]\\n pub from: ContractAddress,\\n /// The recipient of the compose message.\\n #[key]\\n pub to: ContractAddress,\\n /// The GUID of the original message.\\n #[key]\\n pub guid: Bytes32,\\n /// The index of the compose message.\\n pub index: u16,\\n}\\n\\n/// Emitted when a compose message fails.\\n#[derive(Drop, starknet::Event)]\\npub struct LzComposeAlert {\\n /// The sender of the compose message.\\n #[key]\\n pub from: ContractAddress,\\n /// The recipient of the compose message.\\n #[key]\\n pub to: ContractAddress,\\n /// The address of the executor that triggered the alert.\\n #[key]\\n pub executor: ContractAddress,\\n /// The GUID of the original message.\\n #[key]\\n pub guid: Bytes32,\\n /// The index of the compose message.\\n pub index: u16,\\n /// The gas amount related to the alert.\\n pub gas: u256,\\n /// The value sent with the message.\\n pub value: u256,\\n /// The message payload.\\n pub message: ByteArray,\\n /// Extra data provided with the alert.\\n pub extra_data: ByteArray,\\n /// The reason for the alert.\\n pub reason: Array<felt252>,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/messaging_composer/interface.cairo\": \"//! Messaging composer interface\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\n\\n/// # `IMessagingComposer` Interface\\n///\\n/// The `IMessagingComposer` manages compose payloads that are sent after a LayerZero message has\\n/// been delivered.\\n///\\n/// ## Key features\\n/// - Queueing of compose payloads by the originating OApp\\n/// - Verified delivery of compose payloads to a target contract\\n/// - Optional value transfer (ERC20) to the target prior to callback\\n/// - Alerting hooks for off-chain/executor reporting\\n/// - Introspection of the compose queue state\\n#[starknet::interface]\\npub trait IMessagingComposer<TContractState> {\\n /// Queue a compose payload for later delivery\\n ///\\n /// Records the keccak hash of `message` keyed by (sender, `to`, `guid`, `index`).\\n /// A corresponding delivery will be executed via `lz_compose` by an executor.\\n ///\\n /// # Arguments\\n /// * `to` - Target contract that will receive the compose callback\\n /// * `guid` - Unique identifier of the original LayerZero message\\n /// * `index` - Compose index associated with the original message\\n /// * `message` - Opaque compose payload\\n ///\\n /// # Emits\\n /// * ComposeSent\\n ///\\n /// # Panics\\n /// * If a compose payload is already queued for the given (sender, `to`, `guid`, `index`)\\n fn send_compose(\\n ref self: TContractState,\\n to: ContractAddress,\\n guid: Bytes32,\\n index: u16,\\n message: ByteArray,\\n );\\n\\n /// Deliver a previously queued compose payload to the target contract\\n ///\\n /// Verifies that the provided `message` matches the queued hash, marks the\\n /// compose as received to prevent reentrancy, optionally transfers compose\\n /// value (ERC20) from the executor to `to`, then calls `ILayerZeroComposer.lz_compose`.\\n ///\\n /// Note: The caller is expected to be the executor. Do not assume `from == caller`.\\n ///\\n /// # Arguments\\n /// * `from` - Originating OApp that queued the compose on source chain\\n /// * `to` - Target contract that implements `ILayerZeroComposer`\\n /// * `guid` - Unique identifier of the original LayerZero message\\n /// * `index` - Compose index associated with the original message\\n /// * `message` - Compose payload; must match the queued hash\\n /// * `extra_data` - Executor-provided metadata (protocol-opaque)\\n /// * `value` - Amount of compose token to transfer to `to` prior to callback\\n ///\\n /// # Emits\\n /// * ComposeDelivered\\n ///\\n /// # Panics\\n /// * If no compose is found or the hash does not match\\n /// * If `value > 0` and executor allowance is insufficient\\n fn lz_compose(\\n ref self: TContractState,\\n from: ContractAddress,\\n to: ContractAddress,\\n guid: Bytes32,\\n index: u16,\\n message: ByteArray,\\n extra_data: ByteArray,\\n value: u256,\\n );\\n\\n /// Report an alert related to compose execution\\n ///\\n /// Allows the executor to emit a structured alert event that associates\\n /// telemetry or failure information with a compose attempt. Does not modify\\n /// queue state.\\n ///\\n /// # Arguments\\n /// * `from` - Originating OApp\\n /// * `to` - Target contract\\n /// * `guid` - Message GUID\\n /// * `index` - Compose index\\n /// * `gas` - Gas usage or gas limit context provided by the executor\\n /// * `value` - Intended compose token value\\n /// * `message` - Compose payload (for correlation)\\n /// * `extra_data` - Executor-provided metadata\\n /// * `reason` - Opaque reason for the alert\\n ///\\n /// # Emits\\n /// * LzComposeAlert\\n fn lz_compose_alert(\\n ref self: TContractState,\\n from: ContractAddress,\\n to: ContractAddress,\\n guid: Bytes32,\\n index: u16,\\n gas: u256,\\n value: u256,\\n message: ByteArray,\\n extra_data: ByteArray,\\n reason: Array<felt252>,\\n );\\n\\n /// Inspect the compose queue\\n ///\\n /// Returns the stored value for a compose entry keyed by (`sender`, `to`, `guid`, `index`).\\n /// Semantics of the returned `Bytes32`:\\n /// - `0` — no compose queued\\n /// - `1` — compose has been delivered (RECEIVED_MESSAGE_HASH)\\n /// - otherwise — keccak hash of the queued `message`\\n ///\\n /// # Arguments\\n /// * `from` - Originating OApp that called `send_compose`\\n /// * `to` - Target contract\\n /// * `guid` - Message GUID\\n /// * `index` - Compose index\\n ///\\n /// # Returns\\n /// * `Bytes32` - Encoded queue state or message hash as described above\\n fn get_compose_queue(\\n self: @TContractState,\\n from: ContractAddress,\\n to: ContractAddress,\\n guid: Bytes32,\\n index: u16,\\n ) -> Bytes32;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/endpoint/messaging_composer/messaging_composer.cairo\": \"//! Messaging composer component\\n\\n/// # `MessagingComposerComponent`\\n///\\n/// The `MessagingComposerComponent` is responsible for the lifecycle of \\\"compose\\\"\\n/// payloads that are requested by an OApp after a LayerZero message has been\\n/// delivered. It provides a minimal, verifiable queue keyed by the originating\\n/// OApp, target contract, message GUID, and compose index. The executor later\\n/// triggers delivery to the target contract implementing `ILayerZeroComposer`.\\n///\\n/// ## High-level responsibilities\\n/// - Queue compose payloads by recording their keccak hash\\n/// - Verify and deliver compose payloads to the target contract\\n/// - Optionally transfer an ERC20 compose token to the target prior to callback\\n/// - Emit alert events to aid off-chain/executor diagnostics\\n/// - Expose read accessors for compose queue inspection\\n///\\n/// ## Security considerations\\n/// - Delivery marks a compose entry as received using a sentinel value to\\n/// prevent reentrancy or replay, rather than deleting the entry\\n/// - Value transfer requires sufficient allowance from the executor to the\\n/// composer contract\\n/// - The executor is the caller of `lz_compose`; do not assume `from == caller`\\n///\\n/// ## Events emitted by the implementation\\n/// - `ComposeSent(from, to, guid, index, message)`\\n/// - `ComposeDelivered(from, to, guid, index)`\\n/// - `LzComposeAlert(from, to, executor, guid, index, gas, value, message, extra_data, reason)`\\n#[starknet::component]\\npub mod MessagingComposerComponent {\\n use lz_utils::bytes::Bytes32;\\n use lz_utils::error::assert_with_byte_array;\\n use lz_utils::keccak::keccak256;\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use starknet::storage::{\\n Map, StoragePathEntry, StoragePointerReadAccess, StoragePointerWriteAccess,\\n };\\n use starknet::{ContractAddress, get_caller_address, get_contract_address};\\n use crate::endpoint::constants::EMPTY_PAYLOAD_HASH;\\n use crate::endpoint::interfaces::layerzero_composer::{\\n ILayerZeroComposerDispatcher, ILayerZeroComposerDispatcherTrait,\\n };\\n use crate::endpoint::messaging_composer::errors::{\\n err_lz_compose_already_exists, err_lz_compose_not_found,\\n err_lz_compose_value_exceeds_allowance, err_transfer_failed,\\n };\\n use crate::endpoint::messaging_composer::events::{\\n ComposeDelivered, ComposeSent, LzComposeAlert,\\n };\\n use crate::endpoint::messaging_composer::interface::IMessagingComposer;\\n\\n /// Sentinel value written to the compose queue when a compose has been\\n /// successfully delivered. Used to prevent reentrancy/replay.\\n const RECEIVED_MESSAGE_HASH: Bytes32 = Bytes32 { value: 0x1 };\\n\\n #[storage]\\n pub struct Storage {\\n /// ERC20 token used for value transfer on compose\\n compose_token_address: ContractAddress,\\n /// Compose queue mapping structure that stores the keccak hash of the\\n /// queued payload, or `RECEIVED_MESSAGE_HASH` once delivered.\\n /// uses keccak hash\\n ///\\n /// from => to => guid => index => messageHash\\n compose_queue: Map<ContractAddress, Map<ContractAddress, Map<Bytes32, Map<u16, Bytes32>>>>,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n ComposeSent: ComposeSent,\\n ComposeDelivered: ComposeDelivered,\\n LzComposeAlert: LzComposeAlert,\\n }\\n\\n #[embeddable_as(MessagingComposerImpl)]\\n impl MessagingComposer<\\n TContractState, +HasComponent<TContractState>,\\n > of IMessagingComposer<ComponentState<TContractState>> {\\n /// Queue a compose payload for later delivery\\n ///\\n /// Stores the keccak hash of `message` under the key composed of\\n /// `(sender, to, guid, index)`. Reverts if an entry already exists.\\n ///\\n /// Emits: `ComposeSent`\\n ///\\n /// Panics:\\n /// - If a compose payload is already queued for the given key\\n fn send_compose(\\n ref self: ComponentState<TContractState>,\\n to: ContractAddress,\\n guid: Bytes32,\\n index: u16,\\n message: ByteArray,\\n ) {\\n let sender = get_caller_address();\\n let entry = self.compose_queue.entry(sender).entry(to).entry(guid).entry(index);\\n let current_hash = entry.read();\\n assert_with_byte_array(\\n current_hash == EMPTY_PAYLOAD_HASH, err_lz_compose_already_exists(),\\n );\\n // Hash message and store it in the compose queue\\n // Note: No endianness conversion is required; this is not cross-chain dependent\\n let message_hash = keccak256(@message);\\n entry.write(message_hash);\\n self.emit(ComposeSent { from: sender, to, guid, index, message });\\n }\\n\\n /// Deliver a previously queued compose payload to the target contract\\n ///\\n /// Verifies the provided `message` against the queued hash. Marks the\\n /// queue entry as received using `RECEIVED_MESSAGE_HASH` to prevent\\n /// reentrancy/replay. If `value > 0`, transfers compose token from the\\n /// executor (caller) to the target prior to invoking\\n /// `ILayerZeroComposer.lz_compose`.\\n ///\\n /// Emits: `ComposeDelivered`\\n ///\\n /// Panics:\\n /// - If the compose entry is missing or the hash does not match\\n /// - If `value > 0` and the executor's allowance is insufficient\\n fn lz_compose(\\n ref self: ComponentState<TContractState>,\\n from: ContractAddress,\\n to: ContractAddress,\\n guid: Bytes32,\\n index: u16,\\n message: ByteArray,\\n extra_data: ByteArray,\\n value: u256,\\n ) {\\n let entry = self.compose_queue.entry(from).entry(to).entry(guid).entry(index);\\n let expected_hash = entry.read();\\n let actual_hash = keccak256(@message);\\n assert_with_byte_array(\\n expected_hash == actual_hash, err_lz_compose_not_found(expected_hash, actual_hash),\\n );\\n\\n // marks the message as received to prevent reentrancy\\n // cannot just delete the value, otherwise the message can be sent again and could\\n // result in some undefined behaviour even though the sender(composing Oapp) is\\n // implicitly fully trusted by the composer.\\n // eg. sender may not even realize it has such a bug\\n entry.write(RECEIVED_MESSAGE_HASH);\\n\\n let executor = get_caller_address();\\n\\n // Verify allowance and transfer only when value > 0\\n if value > 0 {\\n let compose_token = IERC20Dispatcher {\\n contract_address: self.compose_token_address.read(),\\n };\\n let allowance = compose_token.allowance(executor, get_contract_address());\\n assert_with_byte_array(\\n value <= allowance, err_lz_compose_value_exceeds_allowance(value, allowance),\\n );\\n\\n let success = compose_token.transfer_from(executor, to, value);\\n assert_with_byte_array(success, err_transfer_failed());\\n }\\n\\n let composer_dispatcher = ILayerZeroComposerDispatcher { contract_address: to };\\n composer_dispatcher.lz_compose(from, guid, message, executor, extra_data, value);\\n\\n self.emit(ComposeDelivered { from, to, guid, index });\\n }\\n\\n /// Emit an alert related to compose execution\\n ///\\n /// Allows the executor to surface telemetry or failure information for a\\n /// compose attempt. This does not modify the compose queue state.\\n ///\\n /// Emits: `LzComposeAlert`\\n fn lz_compose_alert(\\n ref self: ComponentState<TContractState>,\\n from: ContractAddress,\\n to: ContractAddress,\\n guid: Bytes32,\\n index: u16,\\n gas: u256,\\n value: u256,\\n message: ByteArray,\\n extra_data: ByteArray,\\n reason: Array<felt252>,\\n ) {\\n let executor = get_caller_address();\\n self\\n .emit(\\n LzComposeAlert {\\n from, to, executor, guid, index, gas, value, message, extra_data, reason,\\n },\\n );\\n }\\n\\n /// Inspect a specific compose queue entry\\n ///\\n /// Returns the stored value for a compose entry keyed by\\n /// `(sender, to, guid, index)` with the following semantics:\\n /// - `0` — no compose queued\\n /// - `RECEIVED_MESSAGE_HASH` (1) — compose delivered\\n /// - otherwise — keccak hash of the queued `message`\\n fn get_compose_queue(\\n self: @ComponentState<TContractState>,\\n from: ContractAddress,\\n to: ContractAddress,\\n guid: Bytes32,\\n index: u16,\\n ) -> Bytes32 {\\n self.compose_queue.entry(from).entry(to).entry(guid).entry(index).read()\\n }\\n }\\n\\n /// Internal functions for initialization\\n #[generate_trait]\\n pub impl InternalImpl<\\n TContractState, +HasComponent<TContractState>,\\n > of InternalTrait<TContractState> {\\n /// Initialize the MessagingComposer with the ERC20 token address used\\n /// for value transfers during compose delivery.\\n fn initializer(ref self: ComponentState<TContractState>, token_address: ContractAddress) {\\n self.compose_token_address.write(token_address);\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/lib.cairo\": \"//! # LayerZero Protocol Implementation for Starknet\\n//!\\n//! This project provides a comprehensive implementation of the LayerZero protocol for the Starknet\\n//! ecosystem.\\n//! It includes the core components necessary for enabling seamless cross-chain messaging, allowing\\n//! developers to build sophisticated omnichain applications (OApps) that can interact with other\\n//! blockchains.\\n//!\\n//! The project is structured into several modules, each responsible for a specific aspect of the\\n//! LayerZero protocol:\\n//! - **Common**: Contains shared data structures, constants, and utility functions used across the\\n//! project.\\n//! - **EndpointV2**: The core of the LayerZero protocol, responsible for sending and receiving\\n//! messages.\\n//! - **MessageLib**: Defines the different message libraries that OApps can use to configure their\\n//! security posture.\\n//! - **Treasury**: Manages the fees collected by the protocol.\\n//! - **Workers**: A collection of contracts that perform specific tasks, such as price feeds and\\n//! data verification.\\n//! - **OApps**: Example omnichain applications that demonstrate how to use the LayerZero protocol.\\n\\npub mod common {\\n pub mod structs {\\n pub mod messaging;\\n pub mod packet;\\n }\\n pub mod constants;\\n pub mod conversions;\\n pub mod guid;\\n pub mod packet_v1_codec;\\n}\\n\\npub mod endpoint {\\n pub mod message_lib_manager {\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n pub mod message_lib_manager;\\n pub mod structs;\\n }\\n pub mod messaging_channel {\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n pub mod messaging_channel;\\n }\\n pub mod messaging_composer {\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n pub mod messaging_composer;\\n }\\n pub mod interfaces {\\n pub mod endpoint_v2;\\n pub mod layerzero_composer;\\n pub mod layerzero_receiver;\\n }\\n pub mod constants;\\n pub mod endpoint_v2;\\n pub mod errors;\\n pub mod events;\\n}\\n\\npub mod message_lib {\\n pub mod interface;\\n pub mod sml {\\n pub mod errors;\\n pub mod events;\\n pub mod simple_message_lib;\\n }\\n pub mod structs;\\n pub mod uln_302 {\\n pub mod errors;\\n pub mod events;\\n pub mod options;\\n pub mod structs {\\n pub mod executor_config;\\n pub mod payment_info;\\n pub mod uln_config;\\n pub mod uln_config_storage_node;\\n pub mod verification;\\n }\\n pub mod interface;\\n pub mod ultra_light_node_302;\\n }\\n pub mod blocked_message_lib;\\n}\\n\\npub mod treasury {\\n pub mod interfaces {\\n pub mod layerzero_treasury;\\n pub mod lz_token_fee_lib;\\n pub mod treasury_admin;\\n }\\n pub mod errors;\\n pub mod events;\\n pub mod treasury;\\n}\\n\\npub mod workers {\\n pub mod base {\\n pub mod base;\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n pub mod structs;\\n }\\n pub mod executor {\\n pub mod errors;\\n pub mod events;\\n pub mod executor;\\n pub mod fee_lib {\\n pub mod executor_fee_lib;\\n pub mod interface;\\n }\\n pub mod interface;\\n pub mod options;\\n pub mod structs;\\n }\\n pub mod price_feed {\\n pub mod constants;\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n pub mod price_feed;\\n pub mod structs;\\n }\\n pub mod dvn {\\n pub mod constants;\\n pub mod dvn;\\n pub mod errors;\\n pub mod events;\\n pub mod fee_lib {\\n pub mod dvn_fee_lib;\\n pub mod interface;\\n }\\n pub mod interface;\\n pub mod options;\\n pub mod structs;\\n }\\n pub mod access_control;\\n pub mod common;\\n pub mod interface;\\n}\\n\\npub mod oapps {\\n pub mod common {\\n pub mod oapp_options_type_3 {\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n pub mod oapp_options_type_3;\\n pub mod structs;\\n }\\n pub mod fee {\\n pub mod errors;\\n pub mod events;\\n pub mod fee;\\n pub mod interface;\\n pub mod structs;\\n }\\n pub mod rate_limiter {\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n pub mod rate_limiter;\\n pub mod structs;\\n }\\n pub mod allow_list {\\n pub mod allow_list;\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n }\\n }\\n pub mod oapp {\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n pub mod oapp;\\n pub mod oapp_core;\\n }\\n pub mod oft {\\n pub mod errors;\\n pub mod events;\\n pub mod interface;\\n pub mod oft_compose_msg_codec;\\n pub mod oft_core {\\n pub mod default_oapp_hooks;\\n pub mod default_oft_hooks;\\n pub mod oft_core;\\n }\\n pub mod oft_msg_codec;\\n pub mod structs;\\n }\\n pub mod counter {\\n pub mod constants;\\n pub mod counter;\\n pub mod errors;\\n pub mod interface;\\n pub mod msg_codec;\\n pub mod options;\\n pub mod structs;\\n }\\n pub mod message_inspector {\\n pub mod interface;\\n }\\n}\\n\\n// Re-export commonly used types for easier access\\npub use common::structs::messaging::{MessageReceipt, MessagingFee, MessagingParams};\\npub use common::structs::packet::{Origin, Packet};\\npub use oapps::oapp::oapp_core::OAppCoreComponent;\\npub use workers::base::base::WorkerBaseComponent;\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/blocked_message_lib.cairo\": \"/// This is a message library that is used to block all messages from being sent or received.\\n#[starknet::contract]\\npub mod BlockedMessageLib {\\n use core::num::traits::Bounded;\\n use core::panics::panic_with_byte_array;\\n use lz_utils::bytes::Bytes32;\\n use lz_utils::error::{Error, format_error};\\n use starknet::ContractAddress;\\n use crate::common::structs::messaging::{MessageLibSendResult, MessagingFee};\\n use crate::common::structs::packet::Packet;\\n use crate::message_lib::interface::{IMessageLib, VerificationState};\\n use crate::message_lib::structs::{MessageLibType, MessageLibVersion, SetConfigParam};\\n\\n // === Error Definitions ===\\n #[derive(Drop)]\\n pub enum BlockedMessageLibError {\\n NotImplemented,\\n }\\n\\n impl ErrorNameImpl of Error<BlockedMessageLibError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_BLOCKED_MESSAGE_LIB\\\"\\n }\\n\\n fn name(self: BlockedMessageLibError) -> ByteArray {\\n match self {\\n BlockedMessageLibError::NotImplemented => \\\"NOT_IMPLEMENTED\\\",\\n }\\n }\\n }\\n\\n pub fn err_not_implemented() -> ByteArray {\\n format_error(BlockedMessageLibError::NotImplemented, \\\"\\\")\\n }\\n\\n // === Storage ===\\n #[storage]\\n struct Storage {}\\n\\n // === Constructor ===\\n #[constructor]\\n fn constructor(ref self: ContractState) { // No initialization needed\\n }\\n\\n // === IMessageLib Implementation ===\\n #[abi(embed_v0)]\\n impl MessageLibImpl of IMessageLib<ContractState> {\\n fn send(\\n ref self: ContractState, packet: Packet, options: ByteArray, pay_in_lz_token: bool,\\n ) -> MessageLibSendResult {\\n panic_with_byte_array(@err_not_implemented());\\n }\\n\\n fn verify(\\n ref self: ContractState,\\n packet_header: ByteArray,\\n payload_hash: Bytes32,\\n confirmations: u64,\\n ) {\\n panic_with_byte_array(@err_not_implemented());\\n }\\n\\n fn commit(ref self: ContractState, packet_header: ByteArray, payload_hash: Bytes32) {\\n panic_with_byte_array(@err_not_implemented());\\n }\\n\\n fn quote(\\n self: @ContractState, packet: Packet, options: ByteArray, pay_in_lz_token: bool,\\n ) -> MessagingFee {\\n panic_with_byte_array(@err_not_implemented());\\n }\\n\\n fn message_lib_type(self: @ContractState) -> MessageLibType {\\n MessageLibType::SendAndReceive\\n }\\n\\n fn is_supported_send_eid(self: @ContractState, dst_eid: u32) -> bool {\\n true\\n }\\n\\n fn is_supported_receive_eid(self: @ContractState, src_eid: u32) -> bool {\\n true\\n }\\n\\n fn version(self: @ContractState) -> MessageLibVersion {\\n MessageLibVersion {\\n major: Bounded::<u64>::MAX, minor: Bounded::<u8>::MAX, endpoint_version: 2,\\n }\\n }\\n\\n fn set_send_configs(\\n ref self: ContractState, oapp: ContractAddress, params: Array<SetConfigParam>,\\n ) {\\n panic_with_byte_array(@err_not_implemented());\\n }\\n\\n fn set_receive_configs(\\n ref self: ContractState, oapp: ContractAddress, params: Array<SetConfigParam>,\\n ) {\\n panic_with_byte_array(@err_not_implemented());\\n }\\n\\n fn get_send_config(\\n self: @ContractState, eid: u32, oapp: ContractAddress, config_type: u32,\\n ) -> Array<felt252> {\\n panic_with_byte_array(@err_not_implemented());\\n }\\n\\n fn get_receive_config(\\n self: @ContractState, eid: u32, oapp: ContractAddress, config_type: u32,\\n ) -> Array<felt252> {\\n panic_with_byte_array(@err_not_implemented());\\n }\\n\\n fn verifiable(\\n self: @ContractState, packet_header: ByteArray, payload_hash: Bytes32,\\n ) -> VerificationState {\\n VerificationState::NotInitializable\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/interface.cairo\": \"//! Message library interface\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::common::structs::messaging::{MessageLibSendResult, MessagingFee};\\nuse crate::common::structs::packet::Packet;\\nuse crate::message_lib::structs::{MessageLibType, MessageLibVersion, SetConfigParam};\\n\\n#[derive(Drop, Serde, PartialEq, Debug)]\\npub enum VerificationState {\\n Verifying,\\n Verifiable,\\n Verified,\\n NotInitializable,\\n}\\n\\n/// Interface for message libraries\\n#[starknet::interface]\\npub trait IMessageLib<TContractState> {\\n fn send(\\n ref self: TContractState, packet: Packet, options: ByteArray, pay_in_lz_token: bool,\\n ) -> MessageLibSendResult;\\n\\n fn verify(\\n ref self: TContractState,\\n packet_header: ByteArray,\\n payload_hash: Bytes32,\\n confirmations: u64,\\n );\\n\\n fn commit(ref self: TContractState, packet_header: ByteArray, payload_hash: Bytes32);\\n\\n fn quote(\\n self: @TContractState, packet: Packet, options: ByteArray, pay_in_lz_token: bool,\\n ) -> MessagingFee;\\n\\n fn version(self: @TContractState) -> MessageLibVersion;\\n\\n fn message_lib_type(self: @TContractState) -> MessageLibType;\\n\\n fn is_supported_send_eid(self: @TContractState, dst_eid: u32) -> bool;\\n\\n fn is_supported_receive_eid(self: @TContractState, src_eid: u32) -> bool;\\n\\n fn set_send_configs(\\n ref self: TContractState, oapp: ContractAddress, params: Array<SetConfigParam>,\\n );\\n\\n fn set_receive_configs(\\n ref self: TContractState, oapp: ContractAddress, params: Array<SetConfigParam>,\\n );\\n\\n fn get_send_config(\\n self: @TContractState, eid: u32, oapp: ContractAddress, config_type: u32,\\n ) -> Array<felt252>;\\n\\n fn get_receive_config(\\n self: @TContractState, eid: u32, oapp: ContractAddress, config_type: u32,\\n ) -> Array<felt252>;\\n\\n fn verifiable(\\n self: @TContractState, packet_header: ByteArray, payload_hash: Bytes32,\\n ) -> VerificationState;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/sml/errors.cairo\": \"//! Simple message library errors\\n\\nuse lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum SimpleMessageLibError {\\n OnlyWhitelistCaller,\\n}\\n\\nimpl ErrorNameImpl of Error<SimpleMessageLibError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_SIMPLE_MESSAGE_LIB\\\"\\n }\\n\\n fn name(self: SimpleMessageLibError) -> ByteArray {\\n match self {\\n SimpleMessageLibError::OnlyWhitelistCaller => \\\"ONLY_WHITELIST_CALLER\\\",\\n }\\n }\\n}\\npub fn err_only_whitelist_caller() -> ByteArray {\\n format_error(SimpleMessageLibError::OnlyWhitelistCaller, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/sml/events.cairo\": \"//! Simple message library events\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\n\\n#[derive(Drop, PartialEq, starknet::Event)]\\npub struct PacketSent {\\n pub nonce: u64,\\n #[key]\\n pub src_eid: u32,\\n #[key]\\n pub sender: ContractAddress,\\n #[key]\\n pub dst_eid: u32,\\n #[key]\\n pub receiver: Bytes32,\\n #[key]\\n pub guid: Bytes32,\\n}\\n\\n#[derive(Drop, PartialEq, starknet::Event, Serde)]\\npub struct PacketVerified {\\n pub nonce: u64,\\n #[key]\\n pub src_eid: u32,\\n #[key]\\n pub sender: Bytes32,\\n #[key]\\n pub dst_eid: u32,\\n #[key]\\n pub receiver: ContractAddress,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/sml/simple_message_lib.cairo\": \"//! Simple message library component implementation\\n\\n#[starknet::contract]\\npub mod SimpleMessageLib {\\n use lz_utils::bytes::Bytes32;\\n use lz_utils::error::assert_with_byte_array;\\n use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};\\n use starknet::{ContractAddress, get_caller_address};\\n use crate::Origin;\\n use crate::common::packet_v1_codec::PacketV1Codec;\\n use crate::common::structs::messaging::{\\n MessageLibSendResult, MessageReceipt, MessagingFee, Payee,\\n };\\n use crate::common::structs::packet::Packet;\\n use crate::endpoint::interfaces::endpoint_v2::{\\n IEndpointV2Dispatcher, IEndpointV2DispatcherTrait,\\n };\\n use crate::message_lib::interface::{IMessageLib, VerificationState};\\n use crate::message_lib::sml::errors::err_only_whitelist_caller;\\n use crate::message_lib::sml::events::{PacketSent, PacketVerified};\\n use crate::message_lib::structs::{MessageLibType, MessageLibVersion, SetConfigParam};\\n\\n const DEFAULT_NATIVE_FEE: u256 = 1000_u256;\\n const DEFAULT_LZ_TOKEN_FEE: u256 = 999_u256;\\n\\n const PAYEE_1: ContractAddress = 'payee1'.try_into().unwrap();\\n const PAYEE_2: ContractAddress = 'payee2'.try_into().unwrap();\\n\\n #[derive(Drop, starknet::Store)]\\n enum MockPayeeType {\\n #[default]\\n Native,\\n LzToken,\\n MixedToken,\\n }\\n\\n #[storage]\\n struct Storage {\\n send_call_count: u64,\\n should_fail: bool,\\n mock_payees_type: Option<MockPayeeType>,\\n endpoint: ContractAddress,\\n native_fee: u256,\\n lz_token_fee: u256,\\n whitelist_caller: ContractAddress,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n PacketSent: PacketSent,\\n PacketVerified: PacketVerified,\\n }\\n\\n #[constructor]\\n fn constructor(ref self: ContractState, endpoint: ContractAddress) {\\n self.send_call_count.write(0);\\n self.should_fail.write(false);\\n self.mock_payees_type.write(None);\\n self.endpoint.write(endpoint);\\n self.native_fee.write(DEFAULT_NATIVE_FEE);\\n self.lz_token_fee.write(DEFAULT_LZ_TOKEN_FEE);\\n }\\n\\n #[abi(embed_v0)]\\n impl SimpleMessageLibImpl of IMessageLib<ContractState> {\\n fn send(\\n ref self: ContractState, packet: Packet, options: ByteArray, pay_in_lz_token: bool,\\n ) -> MessageLibSendResult {\\n // Increment call count\\n let count = self.send_call_count.read();\\n self.send_call_count.write(count + 1);\\n\\n // Check if we should simulate failure\\n assert_with_byte_array(!self.should_fail.read(), self.get_message_lib_failure());\\n\\n let payees = match self.mock_payees_type.read() {\\n Some(MockPayeeType::Native) => self.get_mock_payees(),\\n Some(MockPayeeType::LzToken) => self.get_mock_lz_payees(),\\n Some(MockPayeeType::MixedToken) => self.get_mock_mixed_payees(),\\n None => array![],\\n };\\n\\n self\\n .emit(\\n PacketSent {\\n nonce: packet.nonce,\\n src_eid: packet.src_eid,\\n sender: packet.sender,\\n dst_eid: packet.dst_eid,\\n receiver: packet.receiver,\\n guid: packet.guid,\\n },\\n );\\n\\n MessageLibSendResult {\\n message_receipt: MessageReceipt { guid: packet.guid, nonce: packet.nonce, payees },\\n encoded_packet: self.get_encoded_packet_data(),\\n }\\n }\\n\\n fn verify(\\n ref self: ContractState,\\n packet_header: ByteArray,\\n payload_hash: Bytes32,\\n confirmations: u64,\\n ) {\\n // There is no actual verification.\\n\\n self\\n .emit(\\n PacketVerified {\\n nonce: PacketV1Codec::nonce(@packet_header),\\n src_eid: PacketV1Codec::src_eid(@packet_header),\\n sender: PacketV1Codec::sender(@packet_header),\\n dst_eid: PacketV1Codec::dst_eid(@packet_header),\\n receiver: PacketV1Codec::receiver_address(@packet_header),\\n },\\n );\\n }\\n\\n fn commit(ref self: ContractState, packet_header: ByteArray, payload_hash: Bytes32) {\\n assert_with_byte_array(\\n get_caller_address() == self.whitelist_caller.read(), err_only_whitelist_caller(),\\n );\\n\\n let receiver = PacketV1Codec::receiver_address(@packet_header);\\n let src_eid = PacketV1Codec::src_eid(@packet_header);\\n let nonce = PacketV1Codec::nonce(@packet_header);\\n let sender = PacketV1Codec::sender(@packet_header);\\n\\n let origin = Origin { src_eid, sender, nonce };\\n\\n let endpoint_dispatcher = IEndpointV2Dispatcher {\\n contract_address: self.endpoint.read(),\\n };\\n\\n endpoint_dispatcher.verify(origin, receiver, payload_hash);\\n }\\n\\n fn quote(\\n self: @ContractState, packet: Packet, options: ByteArray, pay_in_lz_token: bool,\\n ) -> MessagingFee {\\n MessagingFee {\\n native_fee: self.native_fee.read(),\\n lz_token_fee: if pay_in_lz_token {\\n self.lz_token_fee.read()\\n } else {\\n 0\\n },\\n }\\n }\\n\\n fn version(self: @ContractState) -> MessageLibVersion {\\n MessageLibVersion { minor: 0, major: 0, endpoint_version: 2 }\\n }\\n\\n fn message_lib_type(self: @ContractState) -> MessageLibType {\\n MessageLibType::SendAndReceive\\n }\\n\\n fn is_supported_send_eid(self: @ContractState, dst_eid: u32) -> bool {\\n // SimpleMessageLib supports all EIDs for testing\\n true\\n }\\n\\n fn is_supported_receive_eid(self: @ContractState, src_eid: u32) -> bool {\\n // SimpleMessageLib supports all EIDs for testing\\n true\\n }\\n\\n fn set_send_configs(\\n ref self: ContractState, oapp: ContractAddress, params: Array<SetConfigParam>,\\n ) { // SimpleMessageLib doesn't need configuration for testing\\n }\\n\\n fn get_send_config(\\n self: @ContractState, eid: u32, oapp: ContractAddress, config_type: u32,\\n ) -> Array<felt252> {\\n // Return empty config for SimpleMessageLib\\n array![]\\n }\\n\\n fn set_receive_configs(\\n ref self: ContractState, oapp: ContractAddress, params: Array<SetConfigParam>,\\n ) { // SimpleMessageLib doesn't need configuration for testing\\n }\\n\\n fn get_receive_config(\\n self: @ContractState, eid: u32, oapp: ContractAddress, config_type: u32,\\n ) -> Array<felt252> {\\n // Return empty config for SimpleMessageLib\\n array![]\\n }\\n\\n fn verifiable(\\n self: @ContractState, packet_header: ByteArray, payload_hash: Bytes32,\\n ) -> VerificationState {\\n VerificationState::Verifiable\\n }\\n }\\n\\n // Helper interface trait definition\\n #[starknet::interface]\\n pub trait ISimpleMessageLibHelpers<TContractState> {\\n fn set_should_fail(ref self: TContractState, should_fail: bool);\\n fn set_use_mock_payees(ref self: TContractState);\\n fn set_use_mock_lz_payees(ref self: TContractState);\\n fn set_use_mock_mixed_payees(ref self: TContractState);\\n fn disable_mock_payees(ref self: TContractState);\\n fn get_send_call_count(self: @TContractState) -> u64;\\n fn get_native_fee(self: @TContractState) -> u256;\\n fn get_lz_token_fee(self: @TContractState) -> u256;\\n fn set_native_fee(ref self: TContractState, fee: u256);\\n fn set_lz_token_fee(ref self: TContractState, fee: u256);\\n fn get_mock_payees(self: @TContractState) -> Array<Payee>;\\n fn get_mock_lz_payees(self: @TContractState) -> Array<Payee>;\\n fn get_mock_mixed_payees(self: @TContractState) -> Array<Payee>;\\n fn get_encoded_packet_data(self: @TContractState) -> ByteArray;\\n fn get_message_lib_failure(self: @TContractState) -> ByteArray;\\n fn set_whitelist_caller(ref self: TContractState, caller: ContractAddress);\\n }\\n\\n // Helper functions for testing\\n #[abi(embed_v0)]\\n impl SimpleMessageLibHelpers of ISimpleMessageLibHelpers<ContractState> {\\n fn set_should_fail(ref self: ContractState, should_fail: bool) {\\n self.should_fail.write(should_fail);\\n }\\n\\n fn set_use_mock_payees(ref self: ContractState) {\\n self.mock_payees_type.write(Some(MockPayeeType::Native));\\n }\\n\\n fn set_use_mock_lz_payees(ref self: ContractState) {\\n self.mock_payees_type.write(Some(MockPayeeType::LzToken));\\n }\\n\\n fn set_use_mock_mixed_payees(ref self: ContractState) {\\n self.mock_payees_type.write(Some(MockPayeeType::MixedToken));\\n }\\n\\n fn disable_mock_payees(ref self: ContractState) {\\n self.mock_payees_type.write(None);\\n }\\n\\n fn get_send_call_count(self: @ContractState) -> u64 {\\n self.send_call_count.read()\\n }\\n\\n fn get_native_fee(self: @ContractState) -> u256 {\\n self.native_fee.read()\\n }\\n\\n fn get_lz_token_fee(self: @ContractState) -> u256 {\\n self.lz_token_fee.read()\\n }\\n\\n fn set_native_fee(ref self: ContractState, fee: u256) {\\n self.native_fee.write(fee)\\n }\\n\\n fn set_lz_token_fee(ref self: ContractState, fee: u256) {\\n self.lz_token_fee.write(fee)\\n }\\n\\n fn get_mock_payees(self: @ContractState) -> Array<Payee> {\\n let native_fee = self.native_fee.read();\\n let native_amount = native_fee / 2;\\n\\n array![\\n Payee { receiver: PAYEE_1, native_amount, lz_token_amount: 0 },\\n Payee {\\n receiver: PAYEE_2,\\n native_amount: native_fee - native_amount,\\n lz_token_amount: 0,\\n },\\n ]\\n }\\n\\n fn get_mock_lz_payees(self: @ContractState) -> Array<Payee> {\\n let lz_token_fee = self.lz_token_fee.read();\\n let amount = lz_token_fee / 2;\\n\\n array![\\n Payee { receiver: PAYEE_1, native_amount: 0, lz_token_amount: amount },\\n Payee {\\n receiver: PAYEE_2, native_amount: 0, lz_token_amount: lz_token_fee - amount,\\n },\\n ]\\n }\\n\\n fn get_mock_mixed_payees(self: @ContractState) -> Array<Payee> {\\n array![\\n Payee {\\n receiver: PAYEE_1, native_amount: self.native_fee.read(), lz_token_amount: 0,\\n },\\n Payee {\\n receiver: PAYEE_2, native_amount: 0, lz_token_amount: self.lz_token_fee.read(),\\n },\\n ]\\n }\\n\\n fn get_encoded_packet_data(self: @ContractState) -> ByteArray {\\n \\\"mock_encoded_packet_data\\\"\\n }\\n\\n fn get_message_lib_failure(self: @ContractState) -> ByteArray {\\n \\\"Mock message library failure\\\"\\n }\\n\\n fn set_whitelist_caller(ref self: ContractState, caller: ContractAddress) {\\n self.whitelist_caller.write(caller);\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/structs.cairo\": \"//! Message library structs\\n\\n#[derive(Copy, Drop, Serde, starknet::Store, PartialEq)]\\n#[allow(starknet::store_no_default_variant)]\\npub enum MessageLibType {\\n Send,\\n Receive,\\n SendAndReceive,\\n}\\n\\n/// Parameter for setting configuration on message libraries\\n#[derive(Drop, Serde)]\\npub struct SetConfigParam {\\n pub eid: u32,\\n pub config_type: u32,\\n // this is the encoded config for the message lib\\n // this is done to allow changing the config type depending on the message lib used\\n pub config: Array<felt252>,\\n}\\n\\n#[derive(Drop, Serde)]\\npub struct MessageLibVersion {\\n pub major: u64,\\n pub minor: u8,\\n pub endpoint_version: u8,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/errors.cairo\": \"//! Ultra light node errors\\n\\nuse core::byte_array::ByteArray;\\nuse lz_utils::error::{Error, format_error};\\nuse starknet::ContractAddress;\\n\\n#[derive(Drop)]\\npub enum UlnError {\\n MustHaveAtLeastOneDvn,\\n TooManyDvns,\\n InvalidWorkerOptions,\\n InvalidWorkerId,\\n UnsupportedOptionType,\\n InvalidOptionalDvnThreshold,\\n UnsortedDvns,\\n UnsupportedSendEid,\\n UnsupportedReceiveEid,\\n InvalidConfirmations,\\n MessageTooLarge,\\n CallerNotEndpoint,\\n InvalidTreasuryNativeFeeCap,\\n Verifying,\\n InvalidConfigType,\\n InvalidExecutor,\\n ZeroMessageSize,\\n}\\n\\nimpl ErrorNameImpl of Error<UlnError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_ULN\\\"\\n }\\n\\n fn name(self: UlnError) -> ByteArray {\\n match self {\\n UlnError::InvalidWorkerOptions => \\\"INVALID_WORKER_OPTIONS\\\",\\n UlnError::InvalidWorkerId => \\\"INVALID_WORKER_ID\\\",\\n UlnError::UnsupportedOptionType => \\\"UNSUPPORTED_OPTION_TYPE\\\",\\n UlnError::MustHaveAtLeastOneDvn => \\\"MUST_HAVE_AT_LEAST_ONE_DVN\\\",\\n UlnError::TooManyDvns => \\\"TOO_MANY_DVNS\\\",\\n UlnError::InvalidOptionalDvnThreshold => \\\"INVALID_OPTIONAL_DVN_THRESHOLD\\\",\\n UlnError::UnsortedDvns => \\\"UNSORTED_DVNS\\\",\\n UlnError::UnsupportedSendEid => \\\"UNSUPPORTED_SEND_EID\\\",\\n UlnError::UnsupportedReceiveEid => \\\"UNSUPPORTED_RECEIVE_EID\\\",\\n UlnError::InvalidConfirmations => \\\"INVALID_CONFIRMATIONS\\\",\\n UlnError::MessageTooLarge => \\\"MESSAGE_TOO_LARGE\\\",\\n UlnError::CallerNotEndpoint => \\\"CALLER_NOT_ENDPOINT\\\",\\n UlnError::InvalidTreasuryNativeFeeCap => \\\"INVALID_TREASURY_NATIVE_FEE_CAP\\\",\\n UlnError::Verifying => \\\"VERIFYING\\\",\\n UlnError::InvalidConfigType => \\\"INVALID_CONFIG_TYPE\\\",\\n UlnError::InvalidExecutor => \\\"INVALID_EXECUTOR\\\",\\n UlnError::ZeroMessageSize => \\\"ZERO_MESSAGE_SIZE\\\",\\n }\\n }\\n}\\n\\npub fn err_invalid_worker_options(cursor: usize) -> ByteArray {\\n format_error(UlnError::InvalidWorkerOptions, format!(\\\"cursor: {}\\\", cursor))\\n}\\n\\npub fn err_invalid_worker_id(worker_id: u8) -> ByteArray {\\n format_error(UlnError::InvalidWorkerId, format!(\\\"worker_id: {}\\\", worker_id))\\n}\\n\\npub fn err_unsupported_option_type(option_type: u16) -> ByteArray {\\n format_error(UlnError::UnsupportedOptionType, format!(\\\"option_type: {}\\\", option_type))\\n}\\n\\npub fn err_must_have_at_least_one_dvn() -> ByteArray {\\n format_error(UlnError::MustHaveAtLeastOneDvn, \\\"\\\")\\n}\\n\\npub fn err_too_many_dvns(required_count: usize, optional_count: usize) -> ByteArray {\\n format_error(\\n UlnError::TooManyDvns,\\n format!(\\\"required.count: {}, optional.count: {}\\\", required_count, optional_count),\\n )\\n}\\n\\npub fn err_invalid_optional_dvn_threshold(optional_dvn_length: usize, threshold: u8) -> ByteArray {\\n format_error(\\n UlnError::InvalidOptionalDvnThreshold,\\n format!(\\\"array length: {}, threshold: {}\\\", optional_dvn_length, threshold),\\n )\\n}\\n\\npub fn err_unsorted_dvns() -> ByteArray {\\n format_error(\\n UlnError::UnsortedDvns, \\\"DVNs must be sorted in ascending order with no duplicates\\\",\\n )\\n}\\n\\npub fn err_unsupported_send_eid(eid: u32) -> ByteArray {\\n format_error(UlnError::UnsupportedSendEid, format!(\\\"eid: {}\\\", eid))\\n}\\n\\npub fn err_unsupported_receive_eid(eid: u32) -> ByteArray {\\n format_error(UlnError::UnsupportedReceiveEid, format!(\\\"eid: {}\\\", eid))\\n}\\n\\npub fn err_invalid_confirmations() -> ByteArray {\\n format_error(UlnError::InvalidConfirmations, \\\"confirmations must be greater than 0\\\")\\n}\\n\\npub fn err_message_too_large(message_size: usize, max_message_size: usize) -> ByteArray {\\n format_error(\\n UlnError::MessageTooLarge,\\n format!(\\\"message_size: {}, max_message_size: {}\\\", message_size, max_message_size),\\n )\\n}\\n\\npub fn err_caller_not_endpoint(caller: ContractAddress, endpoint: ContractAddress) -> ByteArray {\\n let caller_str: felt252 = caller.try_into().unwrap();\\n let endpoint_str: felt252 = endpoint.try_into().unwrap();\\n format_error(\\n UlnError::CallerNotEndpoint, format!(\\\"caller: {}, endpoint: {}\\\", caller_str, endpoint_str),\\n )\\n}\\n\\npub fn err_invalid_treasury_native_fee_cap(old_cap: u256, new_cap: u256) -> ByteArray {\\n format_error(\\n UlnError::InvalidTreasuryNativeFeeCap,\\n format!(\\\"old_cap: {}, new_cap: {}\\\", old_cap, new_cap),\\n )\\n}\\n\\npub fn err_uln_verifying() -> ByteArray {\\n format_error(UlnError::Verifying, \\\"Verification not ready for commit\\\")\\n}\\n\\npub fn err_invalid_config_type(config_type: u32) -> ByteArray {\\n format_error(UlnError::InvalidConfigType, format!(\\\"config_type: {}\\\", config_type))\\n}\\n\\npub fn err_invalid_executor() -> ByteArray {\\n format_error(UlnError::InvalidExecutor, \\\"\\\")\\n}\\n\\npub fn err_zero_message_size() -> ByteArray {\\n format_error(UlnError::ZeroMessageSize, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/events.cairo\": \"//! Ultra light node events\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::common::structs::messaging::Payee;\\nuse crate::common::structs::packet::PacketHeader;\\nuse crate::message_lib::uln_302::structs::executor_config::{\\n ExecutorConfig, SetDefaultExecutorConfigParam,\\n};\\nuse crate::message_lib::uln_302::structs::uln_config::{SetDefaultUlnConfigParam, UlnConfig};\\n\\n#[derive(Drop, PartialEq, starknet::Event)]\\npub struct DefaultUlnSendConfigsSet {\\n pub params: Array<SetDefaultUlnConfigParam>,\\n}\\n\\n#[derive(Drop, PartialEq, starknet::Event)]\\npub struct DefaultUlnReceiveConfigsSet {\\n pub params: Array<SetDefaultUlnConfigParam>,\\n}\\n\\n\\n#[derive(Drop, PartialEq, starknet::Event)]\\npub struct OAppUlnSendConfigSet {\\n #[key]\\n pub oapp: ContractAddress,\\n pub dst_eid: u32,\\n pub config: UlnConfig,\\n}\\n\\n#[derive(Drop, PartialEq, starknet::Event)]\\npub struct OAppUlnReceiveConfigSet {\\n #[key]\\n pub oapp: ContractAddress,\\n pub src_eid: u32,\\n pub config: UlnConfig,\\n}\\n\\n#[derive(Drop, PartialEq, starknet::Event)]\\npub struct DefaultExecutorConfigsSet {\\n pub params: Array<SetDefaultExecutorConfigParam>,\\n}\\n\\n#[derive(Drop, PartialEq, starknet::Event)]\\npub struct OAppExecutorConfigSet {\\n #[key]\\n pub oapp: ContractAddress,\\n pub dst_eid: u32,\\n pub config: ExecutorConfig,\\n}\\n\\n#[derive(Drop, starknet::Event)]\\npub struct DvnFeesPaid {\\n #[key]\\n pub oapp: ContractAddress,\\n pub payees: Array<Payee>,\\n #[key]\\n pub packet_header: PacketHeader,\\n}\\n\\n#[derive(Drop, starknet::Event)]\\npub struct ExecutorFeePaid {\\n #[key]\\n pub oapp: ContractAddress,\\n #[key]\\n pub payee: Payee,\\n #[key]\\n pub packet_header: PacketHeader,\\n}\\n\\n#[derive(Drop, starknet::Event)]\\npub struct TreasuryFeePaid {\\n #[key]\\n pub oapp: ContractAddress,\\n #[key]\\n pub payee: Payee,\\n #[key]\\n pub packet_header: PacketHeader,\\n}\\n\\n#[derive(Drop, starknet::Event)]\\npub struct TreasuryNativeFeeCapSet {\\n pub native_fee_cap: u256,\\n}\\n\\n/// This is emitted when a Payload Hash is verified by a single DVN\\n#[derive(Drop, Debug, PartialEq, starknet::Event)]\\npub struct PayloadVerified {\\n #[key]\\n pub dvn: ContractAddress,\\n pub header: ByteArray,\\n pub confirmations: u256,\\n pub proof_hash: Bytes32,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/interface.cairo\": \"//! Ultra light node admin interface\\n\\nuse layerzero::message_lib::uln_302::structs::executor_config::{\\n ExecutorConfig, SetDefaultExecutorConfigParam,\\n};\\nuse layerzero::message_lib::uln_302::structs::uln_config::{SetDefaultUlnConfigParam, UlnConfig};\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\n\\n#[starknet::interface]\\npub trait IUltraLightNode302Admin<TContractState> {\\n // -- Setter functions for configuration\\n /// Sets the default ULN send configuration for multiple destination endpoints\\n fn set_default_uln_send_configs(\\n ref self: TContractState, params: Array<SetDefaultUlnConfigParam>,\\n );\\n\\n /// Sets the default ULN receive configuration for multiple destination endpoints\\n fn set_default_uln_receive_configs(\\n ref self: TContractState, params: Array<SetDefaultUlnConfigParam>,\\n );\\n\\n /// Sets the default executor configurations for multiple destination endpoints\\n fn set_default_executor_configs(\\n ref self: TContractState, params: Array<SetDefaultExecutorConfigParam>,\\n );\\n\\n // -- Getter functions for verification\\n /// Gets the default ULN send configuration for a destination endpoint\\n fn get_default_uln_send_config(self: @TContractState, dst_eid: u32) -> UlnConfig;\\n\\n /// Gets the default ULN receive configuration for a destination endpoint\\n fn get_default_uln_receive_config(self: @TContractState, src_eid: u32) -> UlnConfig;\\n\\n /// Gets the raw (stored) ULN send configuration for a specific OApp\\n fn get_raw_oapp_uln_send_config(\\n self: @TContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> UlnConfig;\\n\\n /// Gets the raw (stored) ULN receive configuration for a specific OApp\\n fn get_raw_oapp_uln_receive_config(\\n self: @TContractState, oapp: ContractAddress, src_eid: u32,\\n ) -> UlnConfig;\\n\\n /// Gets the effective ULN send configuration for a specific OApp\\n fn get_oapp_uln_send_config(\\n self: @TContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> UlnConfig;\\n\\n /// Gets the effective ULN receive configuration for a specific OApp\\n fn get_oapp_uln_receive_config(\\n self: @TContractState, oapp: ContractAddress, src_eid: u32,\\n ) -> UlnConfig;\\n\\n /// Gets the default executor configuration for a destination endpoint\\n fn get_default_executor_config(self: @TContractState, dst_eid: u32) -> ExecutorConfig;\\n\\n /// Gets the raw (stored) executor configuration for a specific OApp\\n fn get_raw_oapp_executor_config(\\n self: @TContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> ExecutorConfig;\\n\\n /// Gets the effective executor configuration for a specific OApp\\n fn get_oapp_executor_config(\\n self: @TContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> ExecutorConfig;\\n\\n /// Gets the current treasury contract address\\n fn get_treasury(self: @TContractState) -> ContractAddress;\\n\\n /// Sets the treasury floor fee\\n fn set_treasury_native_fee_cap(ref self: TContractState, native_fee_cap: u256);\\n\\n /// Gets the treasury native fee cap\\n fn get_treasury_native_fee_cap(self: @TContractState) -> u256;\\n\\n /// Checks if the payload has been signed by a DVN\\n ///\\n /// # Arguments\\n ///\\n /// * `header_hash`: The header hash of the payload\\n /// * `payload_hash`: The payload hash\\n /// * `dvn`: The DVN contract address\\n fn has_payload_signed(\\n self: @TContractState, header_hash: Bytes32, payload_hash: Bytes32, dvn: ContractAddress,\\n ) -> bool;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/options.cairo\": \"use core::byte_array::{ByteArray, ByteArrayTrait};\\nuse lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\nuse lz_utils::error::assert_with_byte_array;\\n\\n// Import error functions\\nuse crate::message_lib::uln_302::errors::{\\n err_invalid_worker_id, err_invalid_worker_options, err_unsupported_option_type,\\n};\\nuse crate::workers::dvn::options::DVN_WORKER_ID;\\nuse crate::workers::executor::options::EXECUTOR_WORKER_ID;\\n\\n// Option type constants\\npub const TYPE_3: u16 = 3;\\n\\n/// Decode the options into executor_options and dvn_options\\n///\\n/// # Arguments\\n/// * `options` - The options can be either legacy options (type 1 or 2) or type 3 options\\n///\\n/// # Returns\\n/// * `(executor_options, dvn_options)` - The executor options and DVN options in type 3 format\\npub fn split_options(options: @ByteArray) -> (ByteArray, ByteArray) {\\n // At least 2 bytes for the option type, but can have no options\\n assert_with_byte_array(options.len() >= 2, err_invalid_worker_options(0));\\n\\n // we don't support legacy options here, only allowing option type 3\\n let (mut cursor, options_type) = options.read_u16(0);\\n assert_with_byte_array(options_type == TYPE_3, err_unsupported_option_type(options_type));\\n\\n // Type3 options: [worker_option][worker_option]...\\n // worker_option: [worker_id][option_size][option]\\n // worker_id: u8, option_size: u16, option: bytes\\n\\n let mut executor_options: ByteArray = Default::default();\\n let mut dvn_options: ByteArray = Default::default();\\n\\n while cursor != options.len() {\\n // worker_id can't be zero\\n let (new_cursor, worker_id) = options.read_u8(cursor);\\n assert_with_byte_array(worker_id != 0, err_invalid_worker_id(0));\\n\\n let (new_cursor, options_size) = options.read_u16(new_cursor);\\n assert_with_byte_array(options_size != 0, err_invalid_worker_options(new_cursor));\\n\\n let (new_cursor, option) = options.read_bytes(new_cursor, options_size.into());\\n\\n if worker_id == EXECUTOR_WORKER_ID {\\n executor_options.append_u8(EXECUTOR_WORKER_ID);\\n executor_options.append_u16(options_size);\\n executor_options.append(@option);\\n } else {\\n assert_with_byte_array(worker_id == DVN_WORKER_ID, err_invalid_worker_id(worker_id));\\n dvn_options.append_u8(DVN_WORKER_ID);\\n dvn_options.append_u16(options_size);\\n dvn_options.append(@option);\\n }\\n cursor = new_cursor;\\n\\n // The cursor must never exceed option length\\n assert_with_byte_array(cursor <= options.len(), err_invalid_worker_options(cursor));\\n }\\n\\n (executor_options, dvn_options)\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/structs/executor_config.cairo\": \"//! Executor configuration struct\\n\\nuse core::num::traits::Zero;\\nuse starknet::ContractAddress;\\nuse crate::common::constants::ZERO_ADDRESS;\\n\\n#[derive(Drop, Serde, Clone, PartialEq, starknet::Store)]\\npub struct ExecutorConfig {\\n pub max_message_size: u32,\\n pub executor: ContractAddress,\\n}\\n\\n#[derive(Drop, Serde, Clone, PartialEq, starknet::Store)]\\npub struct SetDefaultExecutorConfigParam {\\n pub dst_eid: u32,\\n pub config: ExecutorConfig,\\n}\\n\\nimpl ExecutorConfigDefault of Default<ExecutorConfig> {\\n fn default() -> ExecutorConfig {\\n ExecutorConfig { max_message_size: 0, executor: ZERO_ADDRESS }\\n }\\n}\\n\\npub trait ExecutorConfigResolver {\\n /// Resolves a ULN configuration by merging default and custom configurations\\n /// Following the same logic as getUlnConfig in the Solidity implementation\\n fn resolve(default_config: @ExecutorConfig, custom_config: @ExecutorConfig) -> ExecutorConfig;\\n}\\n\\npub impl ExecutorConfigResolverImpl of ExecutorConfigResolver {\\n fn resolve(default_config: @ExecutorConfig, custom_config: @ExecutorConfig) -> ExecutorConfig {\\n let mut resolved_config: ExecutorConfig = default_config.clone();\\n if *custom_config.max_message_size != 0 {\\n resolved_config.max_message_size = *custom_config.max_message_size;\\n }\\n if !custom_config.executor.is_zero() {\\n resolved_config.executor = *custom_config.executor;\\n }\\n resolved_config\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/structs/payment_info.cairo\": \"use crate::common::structs::messaging::Payee;\\n\\n#[derive(Drop, Serde, PartialEq, Clone, Debug)]\\npub struct DvnPaymentInfo {\\n pub payees: Array<Payee>,\\n pub total_native_fee: u256,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/structs/uln_config.cairo\": \"use lz_utils::error::assert_with_byte_array;\\nuse starknet::ContractAddress;\\nuse crate::message_lib::uln_302::errors::{\\n err_invalid_confirmations, err_invalid_optional_dvn_threshold, err_must_have_at_least_one_dvn,\\n err_too_many_dvns, err_unsorted_dvns,\\n};\\n\\n#[derive(Debug, Drop, Serde, Clone, PartialEq)]\\npub struct UlnConfig {\\n // Using the has_* method instead of *_is_null (as we did in TON), because\\n // The Starknet Map<Key, Value> will always fall back to the default of <Value> if\\n // we haven't explicitly set the relevant <Key> in there.\\n // If we use the *_is_null method, all of the unset custom configurations will\\n // fall back to being not_null, which means an unset custom OApp configuration will overwrite\\n // the set default configuration\\n // the has_* fields are ignored in the `defaultConfig` variations.\\n pub confirmations: u64,\\n pub has_confirmations: bool,\\n // no duplicates. sorted in ascending order. allowed overlap with optionalDVNs\\n pub required_dvns: Array<ContractAddress>,\\n pub has_required_dvns: bool,\\n // no duplicates. sorted in ascending order. allowed overlap with requiredDVNs\\n pub optional_dvns: Array<ContractAddress>,\\n pub optional_dvn_threshold: u8, // (0, optionalDvnCount]\\n pub has_optional_dvns: bool,\\n}\\n\\n/// Total number of DVNs to prevent exceeding uint8.max\\n/// by limiting the total size, it would help constraint the design of DVNOptions\\npub const MAX_DVN_COUNT: u32 = 255;\\n\\n#[derive(Drop, Serde, Clone, PartialEq)]\\npub struct SetDefaultUlnConfigParam {\\n pub eid: u32, // endpoint ID\\n pub config: UlnConfig,\\n}\\n\\npub trait UlnConfigUtils {\\n /// Resolves a ULN configuration by merging default and custom configurations\\n /// Following the same logic as getUlnConfig in the Solidity implementation\\n fn resolve(default_config: @UlnConfig, custom_config: @UlnConfig) -> UlnConfig;\\n\\n /// Asserts that both dvn arrays of the config have no duplicates\\n fn assert_no_duplicate_dvns(config: @UlnConfig);\\n\\n /// Asserts that DVNs are sorted in ascending order with no duplicates\\n fn assert_no_duplicates_in_dvn_array(dvns: @Array<ContractAddress>);\\n\\n /// Asserts that at least one DVN is configured\\n fn assert_at_least_one_dvn(config: @UlnConfig);\\n\\n /// Asserts that the optional DVN threshold is valid\\n fn assert_valid_optional_threshold(config: @UlnConfig);\\n\\n /// Asserts that the total DVN count doesn't exceed the maximum\\n fn assert_max_dvn_count(config: @UlnConfig);\\n\\n /// Asserts that the config confirmations are valid\\n fn assert_valid_confirmations(config: @UlnConfig);\\n\\n // Asserts that a standalone config (post-resolve / default) is valid\\n fn assert_valid_standalone_config(config: @UlnConfig);\\n\\n /// Asserts that a send/receive config is valid\\n fn assert_valid_config(config: @UlnConfig);\\n}\\n\\npub impl UlnConfigUtilsImpl of UlnConfigUtils {\\n fn resolve(default_config: @UlnConfig, custom_config: @UlnConfig) -> UlnConfig {\\n let mut resolved_config = default_config.clone();\\n\\n // Resolve confirmations\\n if *custom_config.has_confirmations {\\n resolved_config.confirmations = *custom_config.confirmations;\\n }\\n\\n // Resolve required DVNs\\n if *custom_config.has_required_dvns {\\n resolved_config.required_dvns = custom_config.required_dvns.clone();\\n }\\n\\n // Resolve optional DVNs\\n if *custom_config.has_optional_dvns {\\n resolved_config.optional_dvns = custom_config.optional_dvns.clone();\\n resolved_config.optional_dvn_threshold = *custom_config.optional_dvn_threshold;\\n }\\n\\n Self::assert_valid_standalone_config(@resolved_config);\\n\\n resolved_config\\n }\\n\\n fn assert_no_duplicate_dvns(config: @UlnConfig) {\\n Self::assert_no_duplicates_in_dvn_array(config.required_dvns);\\n Self::assert_no_duplicates_in_dvn_array(config.optional_dvns);\\n }\\n\\n fn assert_no_duplicates_in_dvn_array(dvns: @Array<ContractAddress>) {\\n if dvns.len() < 2 {\\n return;\\n }\\n\\n // Pair each DVN with its next DVN, and iterate over the pairs.\\n for (current, next) in dvns.into_iter().zip(dvns.span().slice(1, dvns.len() - 1)) {\\n // Check that consecutive DVNs are different and sorted.\\n assert_with_byte_array(current < next, err_unsorted_dvns());\\n }\\n }\\n\\n fn assert_at_least_one_dvn(config: @UlnConfig) {\\n let required_count = config.required_dvns.len();\\n let optional_threshold = *config.optional_dvn_threshold;\\n\\n assert_with_byte_array(\\n required_count != 0 || optional_threshold != 0, err_must_have_at_least_one_dvn(),\\n );\\n }\\n\\n fn assert_valid_optional_threshold(config: @UlnConfig) {\\n let optional_count = config.optional_dvns.len();\\n let threshold = *config.optional_dvn_threshold;\\n\\n assert_with_byte_array(\\n optional_count >= threshold.into(),\\n err_invalid_optional_dvn_threshold(optional_count, threshold),\\n );\\n\\n assert_with_byte_array(\\n optional_count == 0 || threshold > 0,\\n err_invalid_optional_dvn_threshold(optional_count, threshold),\\n );\\n }\\n\\n fn assert_max_dvn_count(config: @UlnConfig) {\\n let required_count = config.required_dvns.len();\\n let optional_count = config.optional_dvns.len();\\n\\n assert_with_byte_array(\\n optional_count + required_count <= MAX_DVN_COUNT,\\n err_too_many_dvns(required_count, optional_count),\\n );\\n }\\n\\n fn assert_valid_confirmations(config: @UlnConfig) {\\n assert_with_byte_array(*config.confirmations > 0, err_invalid_confirmations());\\n }\\n\\n fn assert_valid_standalone_config(config: @UlnConfig) {\\n Self::assert_at_least_one_dvn(config);\\n Self::assert_valid_optional_threshold(config);\\n Self::assert_max_dvn_count(config);\\n }\\n\\n fn assert_valid_config(config: @UlnConfig) {\\n Self::assert_no_duplicate_dvns(config);\\n Self::assert_valid_standalone_config(config);\\n Self::assert_valid_confirmations(config);\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/structs/uln_config_storage_node.cairo\": \"// UlnConfigStorageNode - Storage-compatible version of UlnConfig\\n//\\n// This is a different version of UlnConfig specifically designed for contract storage.\\n// While UlnConfig uses Array<ContractAddress> for DVN lists (which are suitable for\\n// function parameters and return values), UlnConfigStorageNode uses Vec<ContractAddress>\\n// which is the proper storage type in Starknet for dynamic arrays.\\n//\\n// Key differences:\\n// - UlnConfig: Uses Array<ContractAddress> - suitable for function parameters/returns\\n// - UlnConfigStorageNode: Uses Vec<ContractAddress> - required for contract storage\\n//\\n// We need both because:\\n// 1. Arrays cannot be directly stored in contract storage in Starknet\\n// 2. Vecs are storage-native but cannot be used in function signatures\\n// 3. This provides conversion methods between the two representations\\n// 4. Allows efficient storage operations while maintaining clean external interfaces\\n\\nuse starknet::ContractAddress;\\nuse starknet::storage::{\\n Mutable, MutableVecTrait, StoragePath, StoragePointerReadAccess, StoragePointerWriteAccess, Vec,\\n VecTrait,\\n};\\nuse crate::message_lib::uln_302::structs::uln_config::UlnConfig;\\n\\n#[starknet::storage_node]\\npub struct UlnConfigStorageNode {\\n pub confirmations: u64,\\n pub has_confirmations: bool,\\n // no duplicates. sorted in ascending order. allowed overlap with optionalDVNs\\n pub required_dvns: Vec<ContractAddress>,\\n pub has_required_dvns: bool,\\n // no duplicates. sorted in ascending order. allowed overlap with requiredDVNs\\n pub optional_dvns: Vec<ContractAddress>,\\n pub optional_dvn_threshold: u8, // (0, optionalDvnCount]\\n pub has_optional_dvns: bool,\\n}\\n\\n#[generate_trait]\\npub impl UlnConfigStorageNodeImpl of UlnConfigStorageNodeTrait {\\n // This function is used to take in a UlnConfig and store in a\\n // contract storage which has a ConfigNode for storing the config.\\n fn set_uln_config(self: StoragePath<Mutable<UlnConfigStorageNode>>, config: UlnConfig) {\\n self.confirmations.write(config.confirmations);\\n self.has_confirmations.write(config.has_confirmations);\\n self.optional_dvn_threshold.write(config.optional_dvn_threshold);\\n self.has_required_dvns.write(config.has_required_dvns);\\n self.has_optional_dvns.write(config.has_optional_dvns);\\n\\n // convert from Array to Vec\\n self._clear_dvns();\\n for dvn in config.required_dvns {\\n self.required_dvns.push(dvn);\\n }\\n for dvn in config.optional_dvns {\\n self.optional_dvns.push(dvn);\\n }\\n }\\n\\n fn _clear_dvns(self: StoragePath<Mutable<UlnConfigStorageNode>>) {\\n while self.required_dvns.len() != 0 {\\n let _ = self.required_dvns.pop();\\n }\\n while self.optional_dvns.len() != 0 {\\n let _ = self.optional_dvns.pop();\\n }\\n }\\n\\n // This function is used to get the UlnConfig from a\\n // contract storage which has a ConfigNode for storing the config.\\n fn get_uln_config(self: StoragePath<UlnConfigStorageNode>) -> UlnConfig {\\n let mut required_dvns_array = array![];\\n let mut optional_dvns_array = array![];\\n\\n for i in 0..self.required_dvns.len() {\\n required_dvns_array.append(self.required_dvns.at(i).read());\\n }\\n for i in 0..self.optional_dvns.len() {\\n optional_dvns_array.append(self.optional_dvns.at(i).read());\\n }\\n\\n UlnConfig {\\n confirmations: self.confirmations.read(),\\n has_confirmations: self.has_confirmations.read(),\\n required_dvns: required_dvns_array,\\n has_required_dvns: self.has_required_dvns.read(),\\n optional_dvns: optional_dvns_array,\\n optional_dvn_threshold: self.optional_dvn_threshold.read(),\\n has_optional_dvns: self.has_optional_dvns.read(),\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/structs/verification.cairo\": \"//! ULN verification struct\\n\\n#[derive(Debug, Drop, Serde, starknet::Store, Default, PartialEq)]\\npub struct Verification {\\n pub submitted: bool,\\n pub confirmations: u64,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/message_lib/uln_302/ultra_light_node_302.cairo\": \"//! Ultra light node component implementation\\n\\n#[starknet::contract]\\npub mod UltraLightNode302 {\\n use core::cmp::{max, min};\\n use core::dict::Felt252DictEntryTrait;\\n use core::num::traits::Zero;\\n use lz_utils::bytes::Bytes32;\\n use lz_utils::error::assert_with_byte_array;\\n use lz_utils::keccak::keccak256;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use starknet::storage::{\\n Map, Mutable, StoragePath, StoragePathEntry, StoragePointerReadAccess,\\n StoragePointerWriteAccess,\\n };\\n use starknet::{ContractAddress, get_caller_address, get_contract_address};\\n use crate::common::constants::ZERO_ADDRESS;\\n use crate::common::packet_v1_codec::PacketV1Codec;\\n use crate::common::structs::messaging::{\\n MessageLibSendResult, MessageReceipt, MessagingFee, Payee,\\n };\\n use crate::common::structs::packet::{Origin, Packet, PacketHeader};\\n use crate::endpoint::constants::EMPTY_PAYLOAD_HASH;\\n use crate::endpoint::interfaces::endpoint_v2::{\\n IEndpointV2Dispatcher, IEndpointV2DispatcherTrait, IEndpointV2SafeDispatcher,\\n IEndpointV2SafeDispatcherTrait,\\n };\\n use crate::endpoint::messaging_channel::interface::{\\n IMessagingChannelDispatcher, IMessagingChannelDispatcherTrait,\\n };\\n use crate::message_lib::interface::{IMessageLib, VerificationState};\\n use crate::message_lib::structs::{MessageLibType, MessageLibVersion, SetConfigParam};\\n use crate::message_lib::uln_302::errors::{\\n err_caller_not_endpoint, err_invalid_config_type, err_invalid_executor,\\n err_invalid_treasury_native_fee_cap, err_message_too_large, err_uln_verifying,\\n err_unsupported_receive_eid, err_unsupported_send_eid, err_zero_message_size,\\n };\\n use crate::message_lib::uln_302::events::{\\n DefaultExecutorConfigsSet, DefaultUlnReceiveConfigsSet, DefaultUlnSendConfigsSet,\\n DvnFeesPaid, ExecutorFeePaid, OAppExecutorConfigSet, OAppUlnReceiveConfigSet,\\n OAppUlnSendConfigSet, PayloadVerified, TreasuryFeePaid, TreasuryNativeFeeCapSet,\\n };\\n use crate::message_lib::uln_302::interface::IUltraLightNode302Admin;\\n use crate::message_lib::uln_302::options::split_options;\\n use crate::message_lib::uln_302::structs::executor_config::{\\n ExecutorConfig, ExecutorConfigResolverImpl, SetDefaultExecutorConfigParam,\\n };\\n use crate::message_lib::uln_302::structs::payment_info::DvnPaymentInfo;\\n use crate::message_lib::uln_302::structs::uln_config::{\\n SetDefaultUlnConfigParam, UlnConfig, UlnConfigUtilsImpl,\\n };\\n use crate::message_lib::uln_302::structs::uln_config_storage_node::{\\n UlnConfigStorageNode, UlnConfigStorageNodeTrait,\\n };\\n use crate::message_lib::uln_302::structs::verification::Verification;\\n use crate::treasury::interfaces::layerzero_treasury::{\\n ILayerZeroTreasuryDispatcher, ILayerZeroTreasuryDispatcherTrait,\\n };\\n use crate::workers::base::structs::QuoteParams;\\n use crate::workers::dvn::options::group_dvn_options_by_idx;\\n use crate::workers::interface::{ILayerZeroWorkerDispatcher, ILayerZeroWorkerDispatcherTrait};\\n\\n // Default configuration address\\n const DEFAULT_CONFIG: ContractAddress = ZERO_ADDRESS;\\n\\n // Config type constants\\n pub const CONFIG_TYPE_EXECUTOR: u32 = 1;\\n pub const CONFIG_TYPE_ULN: u32 = 2;\\n\\n // Empty verification, equivalent to Default::default() but more explicit\\n pub const EMPTY_VERIFICATION: Verification = Verification {\\n submitted: false, confirmations: 0,\\n };\\n\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n\\n // Ownable Mixin\\n #[abi(embed_v0)]\\n impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;\\n impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n // Send-side storage items:\\n // sender => dst_eid => UlnConfig\\n send_configs: Map<ContractAddress, Map<u32, UlnConfigStorageNode>>,\\n executor_configs: Map<ContractAddress, Map<u32, ExecutorConfig>>,\\n treasury: ContractAddress,\\n endpoint: ContractAddress,\\n treasury_native_fee_cap: u256,\\n // Receive-side storage items:\\n // headerHash => payloadHash => dvn => Verification\\n hash_lookup: Map<Bytes32, Map<Bytes32, Map<ContractAddress, Verification>>>,\\n // receiver => src_eid => UlnConfig\\n receive_configs: Map<ContractAddress, Map<u32, UlnConfigStorageNode>>,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n DefaultUlnSendConfigsSet: DefaultUlnSendConfigsSet,\\n DefaultUlnReceiveConfigsSet: DefaultUlnReceiveConfigsSet,\\n OAppUlnSendConfigSet: OAppUlnSendConfigSet,\\n OAppUlnReceiveConfigSet: OAppUlnReceiveConfigSet,\\n DefaultExecutorConfigsSet: DefaultExecutorConfigsSet,\\n OAppExecutorConfigSet: OAppExecutorConfigSet,\\n DvnFeesPaid: DvnFeesPaid,\\n ExecutorFeePaid: ExecutorFeePaid,\\n TreasuryFeePaid: TreasuryFeePaid,\\n TreasuryNativeFeeCapSet: TreasuryNativeFeeCapSet,\\n PayloadVerified: PayloadVerified,\\n }\\n\\n #[constructor]\\n fn constructor(\\n ref self: ContractState,\\n owner: ContractAddress,\\n treasury: ContractAddress,\\n endpoint: ContractAddress,\\n treasury_native_fee_cap: u256,\\n ) {\\n self.ownable.initializer(owner);\\n self.treasury.write(treasury);\\n self.endpoint.write(endpoint);\\n self.treasury_native_fee_cap.write(treasury_native_fee_cap);\\n }\\n\\n #[abi(embed_v0)]\\n impl UltraLightNode302Impl of IMessageLib<ContractState> {\\n fn send(\\n ref self: ContractState, packet: Packet, options: ByteArray, pay_in_lz_token: bool,\\n ) -> MessageLibSendResult {\\n // Assert onlyEndpointV2\\n self._assert_only_endpoint();\\n let sender = packet.sender;\\n\\n let (executor_options, dvn_options) = split_options(@options);\\n let uln_config = self.get_oapp_uln_send_config(packet.sender, packet.dst_eid);\\n\\n let packet_header = PacketHeader {\\n nonce: packet.nonce,\\n src_eid: packet.src_eid,\\n sender: packet.sender,\\n dst_eid: packet.dst_eid,\\n receiver: packet.receiver,\\n };\\n\\n // pay DVNs\\n let DvnPaymentInfo {\\n mut payees, mut total_native_fee,\\n } = self._pay_dvns(@uln_config, dvn_options, @packet);\\n self\\n .emit(\\n DvnFeesPaid {\\n oapp: sender, payees: payees.clone(), packet_header: packet_header.clone(),\\n },\\n );\\n\\n // pay executor\\n let executor_payee = self._pay_executor(@uln_config, executor_options, @packet);\\n total_native_fee += executor_payee.native_amount;\\n payees.append(executor_payee.clone());\\n self\\n .emit(\\n ExecutorFeePaid {\\n oapp: sender, payee: executor_payee, packet_header: packet_header.clone(),\\n },\\n );\\n\\n // pay treasury\\n let treasury_payee = self._pay_treasury(@packet, total_native_fee, pay_in_lz_token);\\n payees.append(treasury_payee.clone());\\n self.emit(TreasuryFeePaid { oapp: sender, payee: treasury_payee, packet_header });\\n\\n MessageLibSendResult {\\n message_receipt: MessageReceipt { guid: packet.guid, nonce: packet.nonce, payees },\\n encoded_packet: PacketV1Codec::encode(@packet),\\n }\\n }\\n\\n fn verify(\\n ref self: ContractState,\\n packet_header: ByteArray,\\n payload_hash: Bytes32,\\n confirmations: u64,\\n ) {\\n let dvn = get_caller_address();\\n let header_hash = keccak256(@packet_header);\\n\\n // Store the verification: hashLookup[headerHash][payloadHash][dvn] = Verification\\n self\\n ._hash_lookup_entry(header_hash, payload_hash, dvn)\\n .write(Verification { submitted: true, confirmations });\\n\\n // Emit PayloadVerified event\\n self\\n .emit(\\n PayloadVerified {\\n dvn,\\n header: packet_header,\\n confirmations: confirmations.into(),\\n proof_hash: payload_hash,\\n },\\n );\\n }\\n\\n fn commit(ref self: ContractState, packet_header: ByteArray, payload_hash: Bytes32) {\\n let endpoint_dispatcher = IEndpointV2Dispatcher {\\n contract_address: self.endpoint.read(),\\n };\\n\\n // Validate the packet header\\n PacketV1Codec::assert_header(@packet_header, endpoint_dispatcher.get_eid());\\n\\n // Extract receiver and src_eid from packet header\\n let receiver = PacketV1Codec::receiver_address(@packet_header);\\n let src_eid = PacketV1Codec::src_eid(@packet_header);\\n\\n // Get the receive configuration for this path\\n let config = self.get_oapp_uln_receive_config(receiver, src_eid);\\n\\n // Verify and reclaim storage\\n self._verify_and_reclaim_storage(@config, keccak256(@packet_header), payload_hash);\\n\\n // Create Origin struct for endpoint.verify\\n let origin = Origin {\\n src_eid,\\n sender: PacketV1Codec::sender(@packet_header),\\n nonce: PacketV1Codec::nonce(@packet_header),\\n };\\n\\n // Call endpoint to verify and store the payload hash\\n endpoint_dispatcher.verify(origin, receiver, payload_hash);\\n }\\n\\n fn quote(\\n self: @ContractState, packet: Packet, options: ByteArray, pay_in_lz_token: bool,\\n ) -> MessagingFee {\\n let (executor_options, dvn_options) = split_options(@options);\\n\\n let uln_config = self.get_oapp_uln_send_config(packet.sender, packet.dst_eid);\\n\\n let native_fee = self._quote_dvns(@uln_config, dvn_options, @packet)\\n + self._quote_executor(@uln_config, executor_options, @packet);\\n let treasury_payee = self._quote_treasury(@packet, native_fee, pay_in_lz_token);\\n\\n MessagingFee {\\n native_fee: native_fee + treasury_payee.native_amount,\\n lz_token_fee: treasury_payee.lz_token_amount,\\n }\\n }\\n\\n fn version(self: @ContractState) -> MessageLibVersion {\\n MessageLibVersion { minor: 3, major: 0, endpoint_version: 2 }\\n }\\n\\n fn message_lib_type(self: @ContractState) -> MessageLibType {\\n MessageLibType::SendAndReceive\\n }\\n\\n /// @dev a supported Eid must have a valid default uln config, which has at least one dvn\\n fn is_supported_send_eid(self: @ContractState, dst_eid: u32) -> bool {\\n let default_config = self.get_default_uln_send_config(dst_eid);\\n\\n let required_count = default_config.required_dvns.len();\\n let optional_threshold = default_config.optional_dvn_threshold;\\n\\n required_count > 0 || optional_threshold > 0\\n }\\n\\n /// @dev a supported receive Eid must have a valid default uln receive config, which has at\\n /// least one dvn\\n fn is_supported_receive_eid(self: @ContractState, src_eid: u32) -> bool {\\n let default_config = self.get_default_uln_receive_config(src_eid);\\n\\n let required_count = default_config.required_dvns.len();\\n let optional_threshold = default_config.optional_dvn_threshold;\\n\\n required_count > 0 || optional_threshold > 0\\n }\\n\\n fn set_send_configs(\\n ref self: ContractState, oapp: ContractAddress, params: Array<SetConfigParam>,\\n ) {\\n self._assert_only_endpoint();\\n\\n for param in params.into_iter() {\\n // only allow it to happen if there is a default config for the eid\\n self._assert_supported_send_eid(param.eid);\\n\\n if param.config_type == CONFIG_TYPE_EXECUTOR {\\n let mut config_span = param.config.span();\\n let config: ExecutorConfig = Serde::deserialize(ref config_span).unwrap();\\n self._set_oapp_executor_config(oapp, param.eid, config);\\n } else {\\n assert_with_byte_array(\\n param.config_type == CONFIG_TYPE_ULN,\\n err_invalid_config_type(param.config_type),\\n );\\n let mut config_span = param.config.span();\\n let config: UlnConfig = Serde::deserialize(ref config_span).unwrap();\\n self._set_oapp_uln_send_config(oapp, param.eid, config);\\n }\\n }\\n }\\n\\n fn get_send_config(\\n self: @ContractState, eid: u32, oapp: ContractAddress, config_type: u32,\\n ) -> Array<felt252> {\\n let mut serialized = array![];\\n if config_type == CONFIG_TYPE_EXECUTOR {\\n let config = self.get_oapp_executor_config(oapp, eid);\\n Serde::serialize(@config, ref serialized);\\n } else {\\n assert_with_byte_array(\\n config_type == CONFIG_TYPE_ULN, err_invalid_config_type(config_type),\\n );\\n let config = self.get_oapp_uln_send_config(oapp, eid);\\n Serde::serialize(@config, ref serialized);\\n }\\n serialized\\n }\\n\\n fn set_receive_configs(\\n ref self: ContractState, oapp: ContractAddress, params: Array<SetConfigParam>,\\n ) {\\n self._assert_only_endpoint();\\n\\n for param in params.into_iter() {\\n // only allow it to happen if there is a default config for the eid\\n self._assert_supported_receive_eid(param.eid);\\n\\n assert_with_byte_array(\\n param.config_type == CONFIG_TYPE_ULN,\\n err_invalid_config_type(param.config_type),\\n );\\n\\n let mut config_span = param.config.span();\\n let config: UlnConfig = Serde::deserialize(ref config_span).unwrap();\\n self._set_oapp_uln_receive_config(oapp, param.eid, config);\\n }\\n }\\n\\n fn get_receive_config(\\n self: @ContractState, eid: u32, oapp: ContractAddress, config_type: u32,\\n ) -> Array<felt252> {\\n let mut serialized = array![];\\n assert_with_byte_array(\\n config_type == CONFIG_TYPE_ULN, err_invalid_config_type(config_type),\\n );\\n let config = self.get_oapp_uln_receive_config(oapp, eid);\\n Serde::serialize(@config, ref serialized);\\n\\n serialized\\n }\\n\\n fn verifiable(\\n self: @ContractState, packet_header: ByteArray, payload_hash: Bytes32,\\n ) -> VerificationState {\\n let endpoint_dispatcher = IEndpointV2Dispatcher {\\n contract_address: self.endpoint.read(),\\n };\\n PacketV1Codec::assert_header(@packet_header, endpoint_dispatcher.get_eid());\\n\\n let receiver = PacketV1Codec::receiver_address(@packet_header);\\n\\n let src_eid = PacketV1Codec::src_eid(@packet_header);\\n let sender = PacketV1Codec::sender(@packet_header);\\n let nonce = PacketV1Codec::nonce(@packet_header);\\n\\n let origin = Origin { src_eid, sender, nonce };\\n\\n // check endpoint initializable\\n if (!self._safe_endpoint_initializable(origin.clone(), receiver)) {\\n return VerificationState::NotInitializable;\\n }\\n\\n // check endpoint verifiable\\n if !self._endpoint_verifiable(origin, receiver, payload_hash) {\\n return VerificationState::Verified;\\n }\\n\\n // check uln verifiable\\n if self\\n ._check_verifiable(\\n @self.get_oapp_uln_receive_config(receiver, src_eid),\\n keccak256(@packet_header),\\n payload_hash,\\n ) {\\n VerificationState::Verifiable\\n } else {\\n VerificationState::Verifying\\n }\\n }\\n }\\n\\n // Admin functions for configuration management\\n #[abi(embed_v0)]\\n impl UltraLightNode302AdminImpl of IUltraLightNode302Admin<ContractState> {\\n // =============================== ULN Config Setters ======================================\\n\\n fn set_default_uln_send_configs(\\n ref self: ContractState, params: Array<SetDefaultUlnConfigParam>,\\n ) {\\n self.ownable.assert_only_owner();\\n\\n for param in @params {\\n UlnConfigUtilsImpl::assert_valid_config(param.config);\\n\\n self\\n .send_configs\\n .entry(DEFAULT_CONFIG)\\n .entry(*param.eid)\\n .set_uln_config(param.config.clone());\\n }\\n\\n self.emit(DefaultUlnSendConfigsSet { params });\\n }\\n\\n fn set_default_uln_receive_configs(\\n ref self: ContractState, params: Array<SetDefaultUlnConfigParam>,\\n ) {\\n self.ownable.assert_only_owner();\\n\\n for param in @params {\\n UlnConfigUtilsImpl::assert_valid_config(param.config);\\n\\n self\\n .receive_configs\\n .entry(DEFAULT_CONFIG)\\n .entry(*param.eid)\\n .set_uln_config(param.config.clone());\\n }\\n\\n self.emit(DefaultUlnReceiveConfigsSet { params });\\n }\\n\\n // =============================== ULN Config Getters ======================================\\n\\n // Getter functions for testing and verification\\n fn get_default_uln_send_config(self: @ContractState, dst_eid: u32) -> UlnConfig {\\n self.send_configs.entry(DEFAULT_CONFIG).entry(dst_eid).get_uln_config()\\n }\\n\\n fn get_default_uln_receive_config(self: @ContractState, src_eid: u32) -> UlnConfig {\\n self.receive_configs.entry(DEFAULT_CONFIG).entry(src_eid).get_uln_config()\\n }\\n\\n fn get_raw_oapp_uln_send_config(\\n self: @ContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> UlnConfig {\\n self.send_configs.entry(oapp).entry(dst_eid).get_uln_config()\\n }\\n\\n fn get_oapp_uln_send_config(\\n self: @ContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> UlnConfig {\\n let default_config = self.get_default_uln_send_config(dst_eid);\\n let raw_oapp_config = self.get_raw_oapp_uln_send_config(oapp, dst_eid);\\n UlnConfigUtilsImpl::resolve(@default_config, @raw_oapp_config)\\n }\\n\\n fn get_raw_oapp_uln_receive_config(\\n self: @ContractState, oapp: ContractAddress, src_eid: u32,\\n ) -> UlnConfig {\\n self.receive_configs.entry(oapp).entry(src_eid).get_uln_config()\\n }\\n\\n fn get_oapp_uln_receive_config(\\n self: @ContractState, oapp: ContractAddress, src_eid: u32,\\n ) -> UlnConfig {\\n let default_config = self.get_default_uln_receive_config(src_eid);\\n let raw_oapp_config = self.get_raw_oapp_uln_receive_config(oapp, src_eid);\\n UlnConfigUtilsImpl::resolve(@default_config, @raw_oapp_config)\\n }\\n\\n // =============================== Executor Config Setters ===============================\\n\\n fn set_default_executor_configs(\\n ref self: ContractState, params: Array<SetDefaultExecutorConfigParam>,\\n ) {\\n self.ownable.assert_only_owner();\\n\\n for param in @params {\\n assert_with_byte_array(param.config.executor.is_non_zero(), err_invalid_executor());\\n assert_with_byte_array(\\n param.config.max_message_size.is_non_zero(), err_zero_message_size(),\\n );\\n\\n self\\n .executor_configs\\n .entry(DEFAULT_CONFIG)\\n .entry(*param.dst_eid)\\n .write(param.config.clone());\\n }\\n\\n self.emit(DefaultExecutorConfigsSet { params });\\n }\\n\\n // =============================== Executor Config Getters ===============================\\n\\n fn get_default_executor_config(self: @ContractState, dst_eid: u32) -> ExecutorConfig {\\n self.executor_configs.entry(DEFAULT_CONFIG).entry(dst_eid).read()\\n }\\n\\n fn get_raw_oapp_executor_config(\\n self: @ContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> ExecutorConfig {\\n self.executor_configs.entry(oapp).entry(dst_eid).read()\\n }\\n\\n fn get_oapp_executor_config(\\n self: @ContractState, oapp: ContractAddress, dst_eid: u32,\\n ) -> ExecutorConfig {\\n let default_config = self.get_default_executor_config(dst_eid);\\n let raw_oapp_config = self.get_raw_oapp_executor_config(oapp, dst_eid);\\n ExecutorConfigResolverImpl::resolve(@default_config, @raw_oapp_config)\\n }\\n\\n // =============================== Treasury Config Setters ===============================\\n\\n fn set_treasury_native_fee_cap(ref self: ContractState, native_fee_cap: u256) {\\n self.ownable.assert_only_owner();\\n let old_cap = self.treasury_native_fee_cap.read();\\n assert_with_byte_array(\\n native_fee_cap < old_cap,\\n err_invalid_treasury_native_fee_cap(old_cap, native_fee_cap),\\n );\\n self.treasury_native_fee_cap.write(native_fee_cap);\\n self.emit(TreasuryNativeFeeCapSet { native_fee_cap });\\n }\\n\\n // =============================== Treasury Config Getters ===============================\\n\\n fn get_treasury(self: @ContractState) -> ContractAddress {\\n self.treasury.read()\\n }\\n\\n fn get_treasury_native_fee_cap(self: @ContractState) -> u256 {\\n self.treasury_native_fee_cap.read()\\n }\\n\\n fn has_payload_signed(\\n self: @ContractState, header_hash: Bytes32, payload_hash: Bytes32, dvn: ContractAddress,\\n ) -> bool {\\n self._hash_lookup(header_hash, payload_hash, dvn) != EMPTY_VERIFICATION\\n }\\n }\\n\\n #[generate_trait]\\n impl UltraLightNode302InternalImpl of UltraLightNode302InternalTrait {\\n fn _assert_supported_send_eid(self: @ContractState, dst_eid: u32) {\\n assert_with_byte_array(\\n self.is_supported_send_eid(dst_eid), err_unsupported_send_eid(dst_eid),\\n );\\n }\\n\\n fn _assert_supported_receive_eid(self: @ContractState, src_eid: u32) {\\n assert_with_byte_array(\\n self.is_supported_receive_eid(src_eid), err_unsupported_receive_eid(src_eid),\\n );\\n }\\n\\n /// Given a packet, return the dst_eid, sender, and message size\\n fn _expand_packet(self: @ContractState, packet: @Packet) -> (u32, ContractAddress, u32) {\\n (*packet.dst_eid, *packet.sender, packet.message.len())\\n }\\n\\n /// Prepare quote parameters for DVNs.\\n ///\\n /// We first prepare the parameters as an array, and then either quote or pay the fee for\\n /// each DVN in order to separate the immutable `_quote_dvns` and mutable `_pay_dvns`\\n /// functions. Looping over all the DVNs twice would not cost too much gas since the total\\n /// DVN count is limited in practice and loops are cheap compared to the other operations on\\n /// the VM.\\n fn _prepare_dvn_quotes(\\n self: @ContractState, uln_config: @UlnConfig, options: ByteArray, packet: @Packet,\\n ) -> Array<(ContractAddress, QuoteParams)> {\\n let (dst_eid, sender, calldata_size) = self._expand_packet(packet);\\n let mut dvn_options_dict = group_dvn_options_by_idx(@options);\\n // Accumulate quote params for DVNs.\\n let mut params_array = array![];\\n\\n let mut all_dvns = uln_config.required_dvns.clone();\\n all_dvns.append_span(uln_config.optional_dvns.into());\\n\\n for (index, dvn) in all_dvns.into_iter().enumerate() {\\n let (entry, dvn_options_nullable) = dvn_options_dict.entry(index.into());\\n dvn_options_dict = entry.finalize(Default::default());\\n\\n params_array\\n .append(\\n (\\n dvn,\\n QuoteParams {\\n dst_eid,\\n confirmations: *uln_config.confirmations,\\n sender,\\n options: dvn_options_nullable.deref_or(Default::default()),\\n calldata_size,\\n },\\n ),\\n );\\n }\\n\\n params_array\\n }\\n\\n fn _quote_dvns(\\n self: @ContractState, uln_config: @UlnConfig, options: ByteArray, packet: @Packet,\\n ) -> u256 {\\n let mut total_native_fee = 0;\\n\\n for (dvn, params) in self._prepare_dvn_quotes(uln_config, options, packet) {\\n total_native_fee += ILayerZeroWorkerDispatcher { contract_address: dvn }\\n .quote(params);\\n }\\n\\n total_native_fee\\n }\\n\\n fn _pay_dvns(\\n ref self: ContractState, uln_config: @UlnConfig, options: ByteArray, packet: @Packet,\\n ) -> DvnPaymentInfo {\\n let mut total_native_fee = 0;\\n let mut payees = array![];\\n\\n for (dvn, params) in self._prepare_dvn_quotes(uln_config, options, packet) {\\n let native_amount = ILayerZeroWorkerDispatcher { contract_address: dvn }\\n .assign_job(params);\\n\\n total_native_fee += native_amount;\\n payees.append(Payee { receiver: dvn, native_amount, lz_token_amount: 0 });\\n }\\n\\n DvnPaymentInfo { total_native_fee, payees }\\n }\\n\\n fn _prepare_executor_quote(\\n self: @ContractState,\\n uln_config: @UlnConfig,\\n options: ByteArray,\\n packet: @Packet,\\n executor_config: @ExecutorConfig,\\n ) -> QuoteParams {\\n self._verify_packet_size(packet, executor_config);\\n let (dst_eid, sender, calldata_size) = self._expand_packet(packet);\\n\\n QuoteParams {\\n dst_eid, sender, calldata_size, options, confirmations: *uln_config.confirmations,\\n }\\n }\\n\\n fn _quote_executor(\\n self: @ContractState, uln_config: @UlnConfig, options: ByteArray, packet: @Packet,\\n ) -> u256 {\\n let executor_config = self.get_oapp_executor_config(*packet.sender, *packet.dst_eid);\\n let params = self\\n ._prepare_executor_quote(uln_config, options, packet, @executor_config);\\n\\n ILayerZeroWorkerDispatcher { contract_address: executor_config.executor }.quote(params)\\n }\\n\\n fn _pay_executor(\\n ref self: ContractState, uln_config: @UlnConfig, options: ByteArray, packet: @Packet,\\n ) -> Payee {\\n let executor_config = self.get_oapp_executor_config(*packet.sender, *packet.dst_eid);\\n let params = self\\n ._prepare_executor_quote(uln_config, options, packet, @executor_config);\\n let native_amount = ILayerZeroWorkerDispatcher {\\n contract_address: executor_config.executor,\\n }\\n .assign_job(params);\\n\\n Payee { receiver: executor_config.executor, native_amount, lz_token_amount: 0 }\\n }\\n\\n fn _process_treasury_fee(\\n self: @ContractState,\\n treasury: ContractAddress,\\n native_fee: u256,\\n treasury_fee: u256,\\n pay_in_lz_token: bool,\\n ) -> Payee {\\n let treasury_fee_capped = self\\n ._apply_treasury_fee_cap(native_fee, treasury_fee, pay_in_lz_token);\\n\\n let (native_amount, lz_token_amount) = if pay_in_lz_token {\\n (0, treasury_fee_capped)\\n } else {\\n (treasury_fee_capped, 0)\\n };\\n\\n Payee { receiver: treasury, native_amount, lz_token_amount }\\n }\\n\\n fn _quote_treasury(\\n self: @ContractState, packet: @Packet, native_fee: u256, pay_in_lz_token: bool,\\n ) -> Payee {\\n let treasury = self.treasury.read();\\n let (dst_eid, sender, _) = self._expand_packet(packet);\\n let treasury_fee = ILayerZeroTreasuryDispatcher { contract_address: treasury }\\n .get_fee(sender, dst_eid, native_fee, pay_in_lz_token);\\n\\n self._process_treasury_fee(treasury, native_fee, treasury_fee, pay_in_lz_token)\\n }\\n\\n fn _pay_treasury(\\n ref self: ContractState, packet: @Packet, native_fee: u256, pay_in_lz_token: bool,\\n ) -> Payee {\\n let treasury = self.treasury.read();\\n let (dst_eid, sender, _) = self._expand_packet(packet);\\n let treasury_fee = ILayerZeroTreasuryDispatcher { contract_address: treasury }\\n .pay_fee(sender, dst_eid, native_fee, pay_in_lz_token);\\n\\n self._process_treasury_fee(treasury, native_fee, treasury_fee, pay_in_lz_token)\\n }\\n\\n fn _apply_treasury_fee_cap(\\n self: @ContractState, native_fee: u256, treasury_fee: u256, pay_in_lz_token: bool,\\n ) -> u256 {\\n if pay_in_lz_token {\\n return treasury_fee;\\n }\\n\\n // we must prevent high-treasuryFee Dos attack\\n // nativeFee = min(treasureFeeQuote, maxNativeFee)\\n // opportunistically raise the maxNativeFee to be the same as _totalNativeFee\\n // can't use the _totalNativeFee alone because the oapp can use custom workers to force\\n // the fee to 0.\\n // maxNativeFee = max (_totalNativeFee, treasuryNativeFeeCap)\\n let treasury_native_fee_cap = self.treasury_native_fee_cap.read();\\n\\n min(treasury_fee, max(native_fee, treasury_native_fee_cap))\\n }\\n\\n // Asserts whether the packet has a valid size and returns the executor address if so\\n fn _verify_packet_size(\\n self: @ContractState, packet: @Packet, executor_config: @ExecutorConfig,\\n ) {\\n let packet_message_size = packet.message.len();\\n let max_message_size = *executor_config.max_message_size;\\n\\n assert_with_byte_array(\\n packet_message_size <= max_message_size,\\n err_message_too_large(packet_message_size, max_message_size),\\n );\\n }\\n\\n fn _assert_only_endpoint(self: @ContractState) {\\n let caller = get_caller_address();\\n let endpoint = self.endpoint.read();\\n assert_with_byte_array(caller == endpoint, err_caller_not_endpoint(caller, endpoint));\\n }\\n\\n /// @dev checks for endpoint verifiable and endpoint has payload hash\\n fn _endpoint_verifiable(\\n self: @ContractState, origin: Origin, receiver: ContractAddress, payload_hash: Bytes32,\\n ) -> bool {\\n if payload_hash == EMPTY_PAYLOAD_HASH {\\n return false;\\n }\\n\\n let endpoint_dispatcher = IEndpointV2Dispatcher {\\n contract_address: self.endpoint.read(),\\n };\\n let channel_dispatcher = IMessagingChannelDispatcher {\\n contract_address: self.endpoint.read(),\\n };\\n\\n // check endpoint verifiable (equivalent to verifiable in Cairo)\\n if !endpoint_dispatcher\\n .verifiable_with_receive_lib(origin.clone(), receiver, get_contract_address()) {\\n return false;\\n }\\n\\n // if endpoint.verifiable, also check if the payload hash matches\\n // endpoint allows re-verify, check if this payload has already been verified\\n channel_dispatcher\\n .inbound_payload_hash(\\n receiver, origin.src_eid, origin.sender, origin.nonce,\\n ) != payload_hash\\n }\\n\\n #[feature(\\\"safe_dispatcher\\\")]\\n fn _safe_endpoint_initializable(\\n self: @ContractState, origin: Origin, receiver: ContractAddress,\\n ) -> bool {\\n let endpoint_dispatcher = IEndpointV2SafeDispatcher {\\n contract_address: self.endpoint.read(),\\n };\\n endpoint_dispatcher.initializable(origin, receiver).unwrap_or(false)\\n }\\n\\n /// Checks if the verification is ready to be committed to the endpoint\\n fn _check_verifiable(\\n self: @ContractState, config: @UlnConfig, header_hash: Bytes32, payload_hash: Bytes32,\\n ) -> bool {\\n // Check required DVNs\\n if config.required_dvns.len() > 0 {\\n for dvn in config.required_dvns {\\n if !self._verified(*dvn, header_hash, payload_hash, *config.confirmations) {\\n // return if any of the required DVNs haven't signed\\n return false;\\n }\\n }\\n if config.optional_dvns.is_empty() {\\n // returns early if all required DVNs have signed and there are no optional DVNs\\n return true;\\n }\\n }\\n\\n // Check optional DVNs threshold\\n let mut remaining_threshold = *config.optional_dvn_threshold;\\n for dvn in config.optional_dvns {\\n if self._verified(*dvn, header_hash, payload_hash, *config.confirmations) {\\n // decrement the threshold if the optional DVN has signed\\n remaining_threshold -= 1;\\n if remaining_threshold == 0 {\\n // early return if the optional threshold has hit\\n return true;\\n }\\n }\\n }\\n\\n // return false as a catch-all\\n false\\n }\\n\\n /// Checks if a specific DVN has verified the payload with sufficient confirmations\\n fn _verified(\\n self: @ContractState,\\n dvn: ContractAddress,\\n header_hash: Bytes32,\\n payload_hash: Bytes32,\\n required_confirmations: u64,\\n ) -> bool {\\n let verification = self._hash_lookup(header_hash, payload_hash, dvn);\\n verification.submitted && verification.confirmations >= required_confirmations\\n }\\n\\n /// Verifies that all required DVNs have signed and reclaims storage\\n fn _verify_and_reclaim_storage(\\n ref self: ContractState,\\n config: @UlnConfig,\\n header_hash: Bytes32,\\n payload_hash: Bytes32,\\n ) {\\n assert_with_byte_array(\\n self._check_verifiable(config, header_hash, payload_hash), err_uln_verifying(),\\n );\\n\\n // iterate the required DVNs and delete their verifications\\n if config.required_dvns.len() > 0 {\\n for dvn in config.required_dvns {\\n self\\n ._hash_lookup_entry(header_hash, payload_hash, *dvn)\\n .write(EMPTY_VERIFICATION);\\n }\\n }\\n\\n // iterate the optional DVNs and delete their verifications\\n if config.optional_dvns.len() > 0 {\\n for dvn in config.optional_dvns {\\n self\\n ._hash_lookup_entry(header_hash, payload_hash, *dvn)\\n .write(EMPTY_VERIFICATION);\\n }\\n }\\n }\\n\\n // =============================== OApp Config Setters ==================\\n\\n fn _set_oapp_executor_config(\\n ref self: ContractState, oapp: ContractAddress, dst_eid: u32, config: ExecutorConfig,\\n ) {\\n self._assert_supported_send_eid(dst_eid);\\n self.executor_configs.entry(oapp).entry(dst_eid).write(config.clone());\\n self.emit(OAppExecutorConfigSet { oapp, dst_eid, config });\\n }\\n\\n fn _set_oapp_uln_send_config(\\n ref self: ContractState, oapp: ContractAddress, dst_eid: u32, config: UlnConfig,\\n ) {\\n self._assert_supported_send_eid(dst_eid);\\n\\n // Assert no duplicates in DVN arrays before setting\\n UlnConfigUtilsImpl::assert_no_duplicate_dvns(@config);\\n\\n self.send_configs.entry(oapp).entry(dst_eid).set_uln_config(config.clone());\\n\\n // Calling this will make sure the newly set OApp config\\n // will end up with us having a valid resolved config,\\n // if not, it will revert.\\n let _config = self.get_oapp_uln_send_config(oapp, dst_eid);\\n\\n self.emit(OAppUlnSendConfigSet { oapp, dst_eid, config });\\n }\\n\\n fn _set_oapp_uln_receive_config(\\n ref self: ContractState, oapp: ContractAddress, src_eid: u32, config: UlnConfig,\\n ) {\\n self._assert_supported_receive_eid(src_eid);\\n\\n // Assert no duplicates in DVN arrays before setting\\n UlnConfigUtilsImpl::assert_no_duplicate_dvns(@config);\\n\\n self.receive_configs.entry(oapp).entry(src_eid).set_uln_config(config.clone());\\n\\n // Calling this will make sure the newly set OApp config\\n // will end up with us having a valid resolved config,\\n // if not, it will revert.\\n let _config = self.get_oapp_uln_receive_config(oapp, src_eid);\\n\\n self.emit(OAppUlnReceiveConfigSet { oapp, src_eid, config });\\n }\\n\\n // Read-only getter for hash_lookup\\n fn _hash_lookup(\\n self: @ContractState, header_hash: Bytes32, payload_hash: Bytes32, dvn: ContractAddress,\\n ) -> Verification {\\n self.hash_lookup.entry(header_hash).entry(payload_hash).entry(dvn).read()\\n }\\n\\n // Mutable setter for hash_lookup\\n fn _hash_lookup_entry(\\n ref self: ContractState,\\n header_hash: Bytes32,\\n payload_hash: Bytes32,\\n dvn: ContractAddress,\\n ) -> StoragePath<Mutable<Verification>> {\\n self.hash_lookup.entry(header_hash).entry(payload_hash).entry(dvn)\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/allow_list/allow_list.cairo\": \"//! AllowList component implementation\\n//!\\n//! Provides toggleable allowlist functionality between open, blacklist, and whitelist modes.\\n//!\\n//! - **Open mode**: All users are allowed\\n//! - **Blacklist mode**: Users on the blacklist are denied, all others are allowed\\n//! - **Whitelist mode**: Only users on the whitelist are allowed\\n\\n#[starknet::component]\\npub mod AllowlistComponent {\\n use lz_utils::error::assert_with_byte_array;\\n use starknet::ContractAddress;\\n use starknet::storage::{\\n Map, StoragePathEntry, StoragePointerReadAccess, StoragePointerWriteAccess,\\n };\\n use crate::oapps::common::allow_list::errors::err_not_allowlisted;\\n use crate::oapps::common::allow_list::events::{\\n AllowlistModeUpdated, BlacklistUpdated, WhitelistUpdated,\\n };\\n use crate::oapps::common::allow_list::interface::{AllowlistMode, IAllowlist};\\n\\n #[storage]\\n pub struct Storage {\\n /// Current allowlist mode\\n pub Allowlist_mode: AllowlistMode,\\n /// Mapping of user addresses to their blacklist state\\n pub Allowlist_blacklisted: Map<ContractAddress, bool>,\\n /// Mapping of user addresses to their whitelist state\\n pub Allowlist_whitelisted: Map<ContractAddress, bool>,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n AllowlistModeUpdated: AllowlistModeUpdated,\\n WhitelistUpdated: WhitelistUpdated,\\n BlacklistUpdated: BlacklistUpdated,\\n }\\n\\n #[embeddable_as(AllowlistImpl)]\\n pub impl Allowlist<\\n TContractState, +HasComponent<TContractState>,\\n > of IAllowlist<ComponentState<TContractState>> {\\n /// Returns the current allowlist mode\\n fn allowlist_mode(self: @ComponentState<TContractState>) -> AllowlistMode {\\n self.Allowlist_mode.read()\\n }\\n\\n /// Checks if a user is allowlisted under the current mode\\n fn is_user_allowlisted(\\n self: @ComponentState<TContractState>, user: ContractAddress,\\n ) -> bool {\\n let mode = self.Allowlist_mode.read();\\n match mode {\\n AllowlistMode::Open => true,\\n AllowlistMode::Blacklist => !self.Allowlist_blacklisted.entry(user).read(),\\n AllowlistMode::Whitelist => self.Allowlist_whitelisted.entry(user).read(),\\n }\\n }\\n\\n /// Checks if a user is blacklisted\\n fn blacklisted(self: @ComponentState<TContractState>, user: ContractAddress) -> bool {\\n self.Allowlist_blacklisted.entry(user).read()\\n }\\n\\n /// Checks if a user is whitelisted\\n fn whitelisted(self: @ComponentState<TContractState>, user: ContractAddress) -> bool {\\n self.Allowlist_whitelisted.entry(user).read()\\n }\\n }\\n\\n #[generate_trait]\\n pub impl InternalImpl<\\n TContractState, +HasComponent<TContractState>,\\n > of InternalTrait<TContractState> {\\n /// Initializes the allowlist with the given mode\\n ///\\n /// # Arguments\\n /// * `mode` - Initial allowlist mode\\n fn initializer(ref self: ComponentState<TContractState>, mode: AllowlistMode) {\\n self._set_allowlist_mode(mode);\\n }\\n\\n /// Asserts that the user is allowlisted under the current mode.\\n /// Reverts with NotAllowlisted error if not.\\n ///\\n /// # Arguments\\n /// * `user` - User address to check\\n fn assert_allowlisted(self: @ComponentState<TContractState>, user: ContractAddress) {\\n assert_with_byte_array(self.is_user_allowlisted(user), err_not_allowlisted(user));\\n }\\n\\n /// Sets the allowlist mode\\n ///\\n /// # Arguments\\n /// * `mode` - New allowlist mode\\n fn _set_allowlist_mode(ref self: ComponentState<TContractState>, mode: AllowlistMode) {\\n self.Allowlist_mode.write(mode);\\n self.emit(AllowlistModeUpdated { mode });\\n }\\n\\n /// Sets the whitelist state for multiple users\\n ///\\n /// # Arguments\\n /// * `users` - Array of user addresses\\n /// * `status` - Whether to whitelist (true) or unwhitelist (false) all users\\n fn _set_whitelisted(\\n ref self: ComponentState<TContractState>, users: Span<ContractAddress>, status: bool,\\n ) {\\n for user in users {\\n self.Allowlist_whitelisted.entry(*user).write(status);\\n self.emit(WhitelistUpdated { user: *user, status });\\n }\\n }\\n\\n /// Sets the blacklist state for multiple users\\n ///\\n /// # Arguments\\n /// * `users` - Array of user addresses\\n /// * `status` - Whether to blacklist (true) or unblacklist (false) all users\\n fn _set_blacklisted(\\n ref self: ComponentState<TContractState>, users: Span<ContractAddress>, status: bool,\\n ) {\\n for user in users {\\n self.Allowlist_blacklisted.entry(*user).write(status);\\n self.emit(BlacklistUpdated { user: *user, status });\\n }\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/allow_list/errors.cairo\": \"//! AllowList errors\\n\\nuse lz_utils::error::{Error, format_error};\\nuse starknet::ContractAddress;\\n\\n/// An allow list error\\n#[derive(Drop)]\\npub enum AllowlistError {\\n /// User is not allowlisted under the current mode.\\n NotAllowlisted,\\n}\\n\\nimpl ErrorNameImpl of Error<AllowlistError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_OAPP_ALLOWLIST\\\"\\n }\\n\\n fn name(self: AllowlistError) -> ByteArray {\\n match self {\\n AllowlistError::NotAllowlisted => \\\"NOT_ALLOWLISTED\\\",\\n }\\n }\\n}\\n\\npub fn err_not_allowlisted(user: ContractAddress) -> ByteArray {\\n format_error(AllowlistError::NotAllowlisted, format!(\\\"user: {:?}\\\", user))\\n}\\n\\n/// Simple error for allowlist checks without detailed context\\npub fn err_not_allowed() -> ByteArray {\\n format_error(AllowlistError::NotAllowlisted, \\\"\\\")\\n}\\n\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/allow_list/events.cairo\": \"//! AllowList events\\n\\nuse starknet::ContractAddress;\\nuse crate::oapps::common::allow_list::interface::AllowlistMode;\\n\\n/// Emitted when the allowlist mode is updated\\n#[derive(Drop, starknet::Event)]\\npub struct AllowlistModeUpdated {\\n #[key]\\n pub mode: AllowlistMode,\\n}\\n\\n/// Emitted when a user's whitelist status is updated\\n#[derive(Drop, starknet::Event)]\\npub struct WhitelistUpdated {\\n #[key]\\n pub user: ContractAddress,\\n pub status: bool,\\n}\\n\\n/// Emitted when a user's blacklist status is updated\\n#[derive(Drop, starknet::Event)]\\npub struct BlacklistUpdated {\\n #[key]\\n pub user: ContractAddress,\\n pub status: bool,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/allow_list/interface.cairo\": \"//! AllowList public interface\\n\\nuse starknet::ContractAddress;\\n\\n/// Allowlist mode enum - determines how the allowlist operates\\n#[derive(Drop, Copy, PartialEq, Serde, starknet::Store, Debug)]\\npub enum AllowlistMode {\\n /// All users are allowed (default)\\n #[default]\\n Open,\\n /// Users on the blacklist are denied, all others allowed\\n Blacklist,\\n /// Only users on the whitelist are allowed\\n Whitelist,\\n}\\n\\n/// AllowList public functions\\n#[starknet::interface]\\npub trait IAllowlist<TContractState> {\\n /// Returns the current allowlist mode\\n fn allowlist_mode(self: @TContractState) -> AllowlistMode;\\n\\n /// Checks if a user is allowlisted under the current mode\\n fn is_user_allowlisted(self: @TContractState, user: ContractAddress) -> bool;\\n\\n /// Checks if a user is blacklisted\\n fn blacklisted(self: @TContractState, user: ContractAddress) -> bool;\\n\\n /// Checks if a user is whitelisted\\n fn whitelisted(self: @TContractState, user: ContractAddress) -> bool;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/fee/errors.cairo\": \"use lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum FeeError {\\n InvalidBps,\\n InvalidFeeOwner,\\n}\\n\\nimpl ErrorNameImpl of Error<FeeError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_OAPP_FEE\\\"\\n }\\n\\n fn name(self: FeeError) -> ByteArray {\\n match self {\\n FeeError::InvalidBps => \\\"INVALID_BPS\\\",\\n FeeError::InvalidFeeOwner => \\\"INVALID_FEE_OWNER\\\",\\n }\\n }\\n}\\n\\npub fn err_invalid_bps(bps: u16) -> ByteArray {\\n format_error(FeeError::InvalidBps, format!(\\\"bps: {}\\\", bps))\\n}\\n\\npub fn err_invalid_fee_owner() -> ByteArray {\\n format_error(FeeError::InvalidFeeOwner, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/fee/events.cairo\": \"#[derive(Drop, starknet::Event)]\\npub struct FeeBpsSet {\\n pub dst_eid: u32,\\n pub fee_bps: u16,\\n pub enabled: bool,\\n}\\n\\n#[derive(Drop, starknet::Event)]\\npub struct DefaultFeeBpsSet {\\n pub fee_bps: u16,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/fee/fee.cairo\": \"//! Fee component implementation\\n\\n#[starknet::component]\\npub mod FeeComponent {\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::access::ownable::OwnableComponent::{\\n InternalImpl as OwnableInternalImpl, InternalTrait as OwnableInternalTrait,\\n };\\n use starknet::storage::{\\n Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess,\\n StoragePointerWriteAccess,\\n };\\n use crate::common::constants::BPS_DENOMINATOR;\\n use crate::oapps::common::fee::errors::err_invalid_bps;\\n use crate::oapps::common::fee::events::{DefaultFeeBpsSet, FeeBpsSet};\\n use crate::oapps::common::fee::interface::IFee;\\n use crate::oapps::common::fee::structs::FeeConfig;\\n\\n #[storage]\\n pub struct Storage {\\n /// dst_eid => fee config\\n pub Fee_fee_bps: Map<u32, FeeConfig>,\\n pub Fee_default_fee_bps: u16,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n FeeBpsSet: FeeBpsSet,\\n DefaultFeeBpsSet: DefaultFeeBpsSet,\\n }\\n\\n // =============================== Hooks =================================\\n\\n /// Hooks for the Fee component.\\n ///\\n /// Contracts embedding this component can override these to customize how\\n /// BPS are resolved while retaining access to the component's storage and\\n /// functions via `ComponentState<TContractState>`.\\n pub trait FeeHooks<TContractState> {\\n /// Returns the fee for a destination.\\n ///\\n /// Default behavior:\\n /// - If a per-destination config is enabled, use it\\n /// - Otherwise fall back to the default BPS\\n /// - Apply the BPS to the amount\\n fn _get_fee(\\n self: @ComponentState<TContractState>, dst_eid: u32, amount: u256,\\n ) -> u256 {\\n let fee_config = self.Fee_fee_bps.read(dst_eid);\\n let bps = if fee_config.enabled {\\n fee_config.fee_bps\\n } else {\\n self.Fee_default_fee_bps.read()\\n };\\n\\n amount * bps.into() / BPS_DENOMINATOR\\n }\\n }\\n\\n #[embeddable_as(FeeImpl)]\\n impl Fee<\\n TContractState,\\n +HasComponent<TContractState>,\\n +OwnableComponent::HasComponent<TContractState>,\\n +FeeHooks<TContractState>,\\n > of IFee<ComponentState<TContractState>> {\\n fn set_default_fee_bps(ref self: ComponentState<TContractState>, fee_bps: u16) {\\n self._assert_only_owner();\\n self._assert_valid_fee_bps(fee_bps);\\n self.Fee_default_fee_bps.write(fee_bps);\\n self.emit(DefaultFeeBpsSet { fee_bps });\\n }\\n\\n fn set_fee_bps(\\n ref self: ComponentState<TContractState>, dst_eid: u32, fee_bps: u16, enabled: bool,\\n ) {\\n self._assert_only_owner();\\n self._assert_valid_fee_bps(fee_bps);\\n self.Fee_fee_bps.write(dst_eid, FeeConfig { fee_bps, enabled });\\n self.emit(FeeBpsSet { dst_eid, fee_bps, enabled });\\n }\\n\\n fn get_fee(self: @ComponentState<TContractState>, dst_eid: u32, amount: u256) -> u256 {\\n self._get_fee(dst_eid, amount)\\n }\\n\\n fn get_raw_fee_bps(self: @ComponentState<TContractState>, dst_eid: u32) -> FeeConfig {\\n self.Fee_fee_bps.read(dst_eid)\\n }\\n\\n fn get_raw_default_fee_bps(self: @ComponentState<TContractState>) -> u16 {\\n self.Fee_default_fee_bps.read()\\n }\\n\\n fn get_raw_bps_denominator(self: @ComponentState<TContractState>) -> u16 {\\n BPS_DENOMINATOR.try_into().unwrap()\\n }\\n }\\n\\n // =============================== Internal Functions =================================\\n\\n #[generate_trait]\\n pub impl InternalImpl<\\n TContractState, +HasComponent<TContractState>,\\n > of InternalTrait<TContractState> {\\n /// Restricts function access to only the contract owner\\n /// Delegates to the OpenZeppelin Ownable component for ownership checks\\n fn _assert_only_owner<impl Ownable: OwnableComponent::HasComponent<TContractState>>(\\n self: @ComponentState<TContractState>,\\n ) {\\n get_dep_component!(self, Ownable).assert_only_owner();\\n }\\n\\n /// Asserts that the fee basis points are valid\\n /// Checks that the fee basis points are less than or equal to the BPS denominator\\n fn _assert_valid_fee_bps(self: @ComponentState<TContractState>, fee_bps: u16) {\\n assert_with_byte_array(\\n fee_bps <= BPS_DENOMINATOR.try_into().unwrap(), err_invalid_bps(fee_bps),\\n );\\n }\\n }\\n}\\n\\n/// Default implementation of the Fee hooks\\npub impl FeeHooksDefaultImpl<TContractState> of FeeComponent::FeeHooks<TContractState> {}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/fee/interface.cairo\": \"use crate::oapps::common::fee::structs::FeeConfig;\\n\\n#[starknet::interface]\\npub trait IFee<TContractState> {\\n // ================================== Only Owner ===============================\\n\\n /// Sets the default fee basis points for all destinations\\n ///\\n /// # Arguments\\n /// * `fee_bps` - The fee basis points\\n fn set_default_fee_bps(ref self: TContractState, fee_bps: u16);\\n\\n /// Sets the fee basis points for a specific destination endpoint\\n ///\\n /// # Arguments\\n /// * `dst_eid` - The destination endpoint ID\\n /// * `fee_bps` - The fee basis points\\n /// * `enabled` - Whether the fee is enabled\\n fn set_fee_bps(ref self: TContractState, dst_eid: u32, fee_bps: u16, enabled: bool);\\n\\n // ================================== View ===============================\\n\\n /// Gets the fee for a given destination endpoint\\n ///\\n /// # Arguments\\n /// * `dst_eid` - The destination endpoint ID\\n /// * `amount` - The amount to calculate the fee for\\n ///\\n /// # Returns\\n /// * `u256` - The fee amount\\n fn get_fee(self: @TContractState, dst_eid: u32, amount: u256) -> u256;\\n\\n /// Gets the fee basis points for a given destination endpoint\\n ///\\n /// # Arguments\\n /// * `dst_eid` - The destination endpoint ID\\n ///\\n /// # Returns\\n /// * `FeeConfig` - The fee basis points\\n fn get_raw_fee_bps(self: @TContractState, dst_eid: u32) -> FeeConfig;\\n\\n /// Gets the default fee basis points\\n ///\\n /// # Returns\\n /// * `u16` - The default fee basis points\\n fn get_raw_default_fee_bps(self: @TContractState) -> u16;\\n\\n /// Gets the BPS denominator\\n ///\\n /// # Returns\\n /// * `u16` - The BPS denominator\\n fn get_raw_bps_denominator(self: @TContractState) -> u16;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/fee/structs.cairo\": \"#[derive(Drop, Serde, Default, starknet::Store, PartialEq, Debug)]\\npub struct FeeConfig {\\n pub fee_bps: u16,\\n pub enabled: bool,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/oapp_options_type_3/errors.cairo\": \"use lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum OAppOptionsType3Error {\\n InvalidOptions,\\n}\\n\\nimpl ErrorNameImpl of Error<OAppOptionsType3Error> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_OAPP_OPTIONS_TYPE3\\\"\\n }\\n\\n fn name(self: OAppOptionsType3Error) -> ByteArray {\\n match self {\\n OAppOptionsType3Error::InvalidOptions => \\\"INVALID_OPTIONS\\\",\\n }\\n }\\n}\\n\\npub fn err_invalid_options(options: @ByteArray) -> ByteArray {\\n format_error(OAppOptionsType3Error::InvalidOptions, format!(\\\"options: {}\\\", options))\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/oapp_options_type_3/events.cairo\": \"use crate::oapps::common::oapp_options_type_3::structs::EnforcedOptionParam;\\n\\n#[derive(Drop, starknet::Event)]\\npub struct EnforcedOptionSet {\\n pub options: Array<EnforcedOptionParam>,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/oapp_options_type_3/interface.cairo\": \"use crate::oapps::common::oapp_options_type_3::structs::EnforcedOptionParam;\\n\\n#[starknet::interface]\\npub trait IOAppOptionsType3<TContractState> {\\n /// Sets the enforced options for specific endpoint and message type combinations.\\n /// Only the owner/admin of the OApp can call this function.\\n ///\\n /// # Arguments\\n /// * `enforced_options` - Array of EnforcedOptionParam structures specifying enforced options\\n fn set_enforced_options(ref self: TContractState, enforced_options: Array<EnforcedOptionParam>);\\n\\n /// Combines options for a given endpoint and message type.\\n ///\\n /// # Arguments\\n /// * `eid` - The endpoint ID\\n /// * `msg_type` - The OApp message type\\n /// * `extra_options` - Additional options passed by the caller\\n ///\\n /// # Returns\\n /// * `ByteArray` - The combination of caller specified options AND enforced options\\n fn combine_options(\\n self: @TContractState, eid: u32, msg_type: u16, extra_options: ByteArray,\\n ) -> ByteArray;\\n\\n /// Gets the enforced options for a specific endpoint and message type\\n ///\\n /// # Arguments\\n /// * `eid` - The endpoint ID\\n /// * `msg_type` - The OApp message type\\n ///\\n /// # Returns\\n /// * `ByteArray` - The enforced options\\n fn get_enforced_options(self: @TContractState, eid: u32, msg_type: u16) -> ByteArray;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/oapp_options_type_3/oapp_options_type_3.cairo\": \"#[starknet::component]\\npub mod OAppOptionsType3Component {\\n use core::panics::panic_with_byte_array;\\n use lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::access::ownable::OwnableComponent::{\\n InternalImpl as OwnableInternalImpl, InternalTrait as OwnableInternalTrait,\\n };\\n use starknet::storage::{Map, StorageMapReadAccess, StorageMapWriteAccess};\\n use crate::oapps::common::oapp_options_type_3::errors::err_invalid_options;\\n use crate::oapps::common::oapp_options_type_3::events::EnforcedOptionSet;\\n use crate::oapps::common::oapp_options_type_3::interface::IOAppOptionsType3;\\n use crate::oapps::common::oapp_options_type_3::structs::EnforcedOptionParam;\\n\\n // Constants\\n pub const OPTION_TYPE_3: u16 = 3;\\n\\n #[storage]\\n pub struct Storage {\\n /// Mapping from (eid, msg_type) => enforced options\\n OAppOptionsType3_enforced_options: Map<(u32, u16), ByteArray>,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n EnforcedOptionSet: EnforcedOptionSet,\\n }\\n\\n #[generate_trait]\\n pub impl InternalImpl<\\n TContractState, +HasComponent<TContractState>,\\n > of InternalTrait<TContractState> {\\n /// Internal function to set enforced options\\n fn _set_enforced_options(\\n ref self: ComponentState<TContractState>, enforced_options: Array<EnforcedOptionParam>,\\n ) {\\n for option in enforced_options.clone().into_iter() {\\n // Enforced options are only available for optionType 3\\n self._assert_options_type_3(@option.options);\\n\\n // Store the enforced option\\n self\\n .OAppOptionsType3_enforced_options\\n .write((option.eid, option.msg_type), option.options.clone());\\n }\\n\\n self.emit(EnforcedOptionSet { options: enforced_options });\\n }\\n\\n /// Internal function to assert that options are of type 3\\n fn _assert_options_type_3(self: @ComponentState<TContractState>, options: @ByteArray) {\\n // Use the ByteArrayTraitExt to read u16 from the beginning\\n let (_, option_type) = options.read_u16(0);\\n\\n assert_with_byte_array(option_type == OPTION_TYPE_3, err_invalid_options(options));\\n }\\n }\\n\\n #[embeddable_as(OAppOptionsType3Impl)]\\n impl OAppOptionsType3<\\n TContractState,\\n +HasComponent<TContractState>,\\n impl Ownable: OwnableComponent::HasComponent<TContractState>,\\n > of IOAppOptionsType3<ComponentState<TContractState>> {\\n fn set_enforced_options(\\n ref self: ComponentState<TContractState>, enforced_options: Array<EnforcedOptionParam>,\\n ) {\\n // Only owner can set enforced options\\n let ownable = get_dep_component!(@self, Ownable);\\n ownable.assert_only_owner();\\n\\n self._set_enforced_options(enforced_options);\\n }\\n\\n fn combine_options(\\n self: @ComponentState<TContractState>,\\n eid: u32,\\n msg_type: u16,\\n extra_options: ByteArray,\\n ) -> ByteArray {\\n let enforced = self.OAppOptionsType3_enforced_options.read((eid, msg_type));\\n\\n // No enforced options, pass whatever the caller supplied\\n if enforced.len() == 0 {\\n return extra_options;\\n }\\n\\n // No caller options, return enforced\\n if extra_options.len() == 0 {\\n return enforced;\\n }\\n\\n // If caller provided extra_options, must be type 3 as it's the ONLY type that can be\\n // combined\\n if extra_options.len() >= 2 {\\n self._assert_options_type_3(@extra_options);\\n\\n // Remove the first 2 bytes containing the type from the extra_options and combine\\n // with enforced\\n let mut combined = enforced;\\n if extra_options.len() > 2 {\\n let (_, extra_data) = extra_options.read_bytes(2, extra_options.len() - 2);\\n combined.append(@extra_data);\\n }\\n return combined;\\n }\\n\\n // No valid set of options was found\\n panic_with_byte_array(@err_invalid_options(@extra_options));\\n }\\n\\n fn get_enforced_options(\\n self: @ComponentState<TContractState>, eid: u32, msg_type: u16,\\n ) -> ByteArray {\\n self.OAppOptionsType3_enforced_options.read((eid, msg_type))\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/oapp_options_type_3/structs.cairo\": \"#[derive(Drop, Serde, Clone)]\\npub struct EnforcedOptionParam {\\n pub eid: u32,\\n pub msg_type: u16,\\n pub options: ByteArray,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/rate_limiter/errors.cairo\": \"use lz_utils::error::{Error, format_error};\\n\\n/// A rate limiter error\\n#[derive(Drop)]\\npub enum RateLimiterError {\\n /// A rate limit is exceeded.\\n RateLimitExceeded,\\n}\\n\\nimpl ErrorNameImpl of Error<RateLimiterError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_OAPP_RATE_LIMITER\\\"\\n }\\n\\n fn name(self: RateLimiterError) -> ByteArray {\\n match self {\\n RateLimiterError::RateLimitExceeded => \\\"RATE_LIMIT_EXCEEDED\\\",\\n }\\n }\\n}\\n\\npub fn err_rate_limit_exceeded() -> ByteArray {\\n format_error(RateLimiterError::RateLimitExceeded, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/rate_limiter/events.cairo\": \"use crate::oapps::common::rate_limiter::structs::{\\n RateLimitConfig, RateLimitDirection, RateLimitEnabled,\\n};\\n\\n/// An event when rate limits are changed.\\n#[derive(Debug, Drop, starknet::Event)]\\npub struct RateLimitsChanged {\\n /// Rate limit configurations.\\n pub configs: Array<RateLimitConfig>,\\n /// Rate limit direction.\\n pub direction: RateLimitDirection,\\n}\\n\\n/// An event when rate limits are reset.\\n#[derive(Debug, Drop, starknet::Event)]\\npub struct RateLimitsReset {\\n /// Endpoint IDs that were reset.\\n pub eids: Array<u32>,\\n}\\n\\n/// An event when the rate limit is enabled.\\n#[derive(Debug, Drop, starknet::Event)]\\npub struct RateLimitEnabledChanged {\\n /// Rate limit enabled.\\n pub rate_limit_enabled: RateLimitEnabled,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/rate_limiter/interface.cairo\": \"use crate::oapps::common::rate_limiter::structs::{\\n RateLimit, RateLimitEnabled, ReceivableAmount, SendableAmount,\\n};\\n\\n/// An interface for a rate limiter component.\\n#[starknet::interface]\\npub trait IRateLimiter<TContractState> {\\n /// Gets the current amount that can be sent to the destination endpoint ID for the given rate\\n /// limit window.\\n ///\\n /// # Arguments\\n /// * `dst_eid` - The destination endpoint ID.\\n ///\\n /// # Returns\\n /// * `SendableAmount` - The sendable amount.\\n fn get_sendable_amount(self: @TContractState, dst_eid: u32) -> SendableAmount;\\n\\n /// Gets the current amount that can be received from the source endpoint ID for the given\\n /// rate limit window.\\n ///\\n /// # Arguments\\n /// * `src_eid` - The source endpoint ID.\\n ///\\n /// # Returns\\n /// * `ReceivableAmount` - The receivable amount.\\n fn get_receivable_amount(self: @TContractState, src_eid: u32) -> ReceivableAmount;\\n\\n /// Gets the current outbound rate limit for the destination endpoint ID.\\n ///\\n /// # Arguments\\n /// * `dst_eid` - The destination endpoint ID.\\n ///\\n /// # Returns\\n /// * `RateLimit` - The rate limit state.\\n fn get_outbound_rate_limit(self: @TContractState, dst_eid: u32) -> RateLimit;\\n\\n /// Gets the current inbound rate limit for the source endpoint ID.\\n ///\\n /// # Arguments\\n /// * `src_eid` - The source endpoint ID.\\n ///\\n /// # Returns\\n /// * `RateLimit` - The rate limit state.\\n fn get_inbound_rate_limit(self: @TContractState, src_eid: u32) -> RateLimit;\\n\\n /// Gets enabled configuration of rate limits.\\n fn get_rate_limit_enabled(self: @TContractState) -> RateLimitEnabled;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/rate_limiter/rate_limiter.cairo\": \"//! RateLimiter component implementation\\n\\n/// The rate limiter component.\\n///\\n/// It implements rate limiting functionality. This component provides a basic framework for rate\\n/// limiting how often a function can be executed.\\n/// It is designed to be embedded into other contracts requiring rate limiting capabilities to\\n/// protect resources or services from excessive use.\\n///\\n/// The ordering of transactions within a given block (timestamp) affects the consumed capacity.\\n/// Carefully consider the minimum window duration for the given blockchain. For example, on\\n/// Starknet, the minimum window duration should be at least 6 seconds as of September 1,\\n/// 2025. If a window less than the time is configured, then the rate limit will effectively\\n/// reset with each block, rendering rate limiting ineffective.\\n///\\n/// Carefully consider the proportion of the limit to the window. If the limit is much smaller\\n/// than the window, the decay function is lossy. Consider using a limit that is greater than or\\n/// equal to the window to avoid this. This is especially important for blockchains with short\\n/// average block times.\\n///\\n/// Example 1: Max rate limit reached at beginning of window. As time continues the amount of in\\n/// flights comes down.\\n///\\n/// Rate Limit Config:\\n/// limit: 100 units\\n/// window: 60 seconds\\n///\\n/// Amount in Flight (units) vs. Time Graph (seconds)\\n///\\n/// 100 | * - (Max limit reached at beginning of window)\\n/// | *\\n/// | *\\n/// | *\\n/// 50 | * (After 30 seconds only 50 units in flight)\\n/// | *\\n/// | *\\n/// | *\\n/// 0 +-|---|---|---|---|--> (After 60 seconds 0 units are in flight)\\n/// 0 15 30 45 60 (seconds)\\n///\\n/// Example 2: Max rate limit reached at beginning of window. As time continues the amount of in\\n/// flights comes down allowing for more to be sent. At the 90 second mark, more in flights come in.\\n///\\n/// Rate Limit Config:\\n/// limit: 100 units\\n/// window: 60 seconds\\n///\\n/// Amount in Flight (units) vs. Time Graph (seconds)\\n///\\n/// 100 | * - (Max limit reached at beginning of window)\\n/// | *\\n/// | *\\n/// 50 | * * (50 inflight)\\n/// | * *\\n/// | * *\\n/// | * *\\n/// 0 +-|--|--|--|--|--|--|--|--|--> Time\\n/// 0 15 30 45 60 75 90 105 120 (seconds)\\n///\\n/// Example 3: Max rate limit reached at beginning of window. At the 30 second mark, the window gets\\n/// updated to 60 seconds and the limit gets updated to 50 units. This scenario shows the direct\\n/// depiction of \\\"in flight\\\" from the previous window affecting the current window.\\n///\\n/// Initial Rate Limit Config: For first 30 seconds\\n/// limit: 100 units\\n/// window: 60 seconds\\n///\\n/// Updated Rate Limit Config: Updated at 30 second mark\\n/// limit: 50 units\\n/// window: 60 seconds\\n///\\n/// Amount in Flight (units) vs. Time Graph (seconds)\\n///\\n/// 100 | * - (Max limit reached at beginning of window)\\n/// | *\\n/// | *\\n/// 75 | *\\n/// | *\\n/// | *\\n/// | *\\n/// 50 | *\\n/// | . *\\n/// | . *\\n/// | . *\\n/// 25 | . *\\n/// | . *\\n/// | . *\\n/// | . *\\n/// 0 +-|-------------|-------------|-------------|---------> Time\\n/// 0 30 60 90 (seconds)\\n/// [ original window ]\\n/// [ updated window ]\\n#[starknet::component]\\npub mod RateLimiterComponent {\\n use core::cmp::max;\\n use core::num::traits::SaturatingSub;\\n use lz_utils::error::assert_with_byte_array;\\n use starknet::get_block_timestamp;\\n use starknet::storage::{\\n Map, StorageMapReadAccess, StoragePathEntry, StoragePointerReadAccess,\\n StoragePointerWriteAccess,\\n };\\n use crate::oapps::common::rate_limiter::errors::err_rate_limit_exceeded;\\n use crate::oapps::common::rate_limiter::events::{\\n RateLimitEnabledChanged, RateLimitsChanged, RateLimitsReset,\\n };\\n use crate::oapps::common::rate_limiter::interface::IRateLimiter;\\n use crate::oapps::common::rate_limiter::structs::{\\n FlowableAmount, RateLimit, RateLimitConfig, RateLimitDirection, RateLimitEnabled,\\n ReceivableAmount, SendableAmount,\\n };\\n\\n #[storage]\\n pub struct Storage {\\n /// A map from endpoint IDs to their rate limit configurations and states.\\n pub RateLimiter_outbound_rate_limits: Map<u32, RateLimit>,\\n /// A map from endpoint IDs to their inbound rate limit configurations and states.\\n pub RateLimiter_inbound_rate_limits: Map<u32, RateLimit>,\\n /// Whether the outbound and inbound rate limits are enabled.\\n pub RateLimiter_enabled: RateLimitEnabled,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n RateLimitsChanged: RateLimitsChanged,\\n RateLimitsReset: RateLimitsReset,\\n RateLimitEnabledChanged: RateLimitEnabledChanged,\\n }\\n\\n pub trait RateLimiterHooks<TContractState, +HasComponent<TContractState>> {\\n fn _get_flowable_amount(\\n self: @ComponentState<TContractState>, limit: @RateLimit,\\n ) -> FlowableAmount {\\n let RateLimit { amount_in_flight, last_updated, limit, window } = limit;\\n\\n // Prevent division by zero.\\n let window = max(*window, 1);\\n let duration = get_block_timestamp() - *last_updated;\\n\\n // Presume linear decay.\\n let amount_in_flight: u256 = (*amount_in_flight)\\n .into()\\n .saturating_sub((*limit).into() * duration.into() / window.into());\\n\\n FlowableAmount {\\n // Although the amount in flight should never be above the limit, we double-check\\n // that with saturating subtraction.\\n amount_in_flight, flowable_amount: (*limit).into().saturating_sub(amount_in_flight),\\n }\\n }\\n\\n /// Checks and updates the rate limit for the given endpoint ID and amount.\\n ///\\n /// For each direction we need to check and update the rate limit, and also update the\\n /// opposite direction.\\n /// but in case the direction is disabled, we don't need to update the rate limit.\\n ///\\n /// # Arguments\\n /// * `eid` - The endpoint ID.\\n /// * `amount` - The amount to check and update.\\n /// * `direction` - The direction of the rate limit.\\n ///\\n /// # Panics\\n /// Reverts if the rate limit is exceeded for the given direction.\\n fn _check_and_update_rate_limit(\\n ref self: ComponentState<TContractState>,\\n eid: u32,\\n amount: u256,\\n direction: RateLimitDirection,\\n ) {\\n let RateLimitEnabled {\\n is_outbound_enabled, is_inbound_enabled,\\n } = self.RateLimiter_enabled.read();\\n\\n let is_direction_enabled = match direction {\\n RateLimitDirection::Outbound => is_outbound_enabled,\\n RateLimitDirection::Inbound => is_inbound_enabled,\\n };\\n\\n if is_direction_enabled {\\n let direction_entry = match direction {\\n RateLimitDirection::Outbound => self\\n .RateLimiter_outbound_rate_limits\\n .entry(eid),\\n RateLimitDirection::Inbound => self.RateLimiter_inbound_rate_limits.entry(eid),\\n };\\n\\n let rate_limit = direction_entry.read();\\n\\n let FlowableAmount {\\n amount_in_flight, flowable_amount,\\n } = Self::_get_flowable_amount(@self, @rate_limit);\\n\\n assert_with_byte_array(amount <= flowable_amount, err_rate_limit_exceeded());\\n\\n direction_entry\\n .write(\\n RateLimit {\\n amount_in_flight: (amount_in_flight + amount).try_into().unwrap(),\\n last_updated: get_block_timestamp(),\\n ..rate_limit,\\n },\\n );\\n }\\n\\n let is_opposite_direction_enabled = match direction {\\n RateLimitDirection::Outbound => is_inbound_enabled,\\n RateLimitDirection::Inbound => is_outbound_enabled,\\n };\\n\\n if is_opposite_direction_enabled {\\n let opposite_direction_entry = match direction {\\n RateLimitDirection::Outbound => self.RateLimiter_inbound_rate_limits.entry(eid),\\n RateLimitDirection::Inbound => self.RateLimiter_outbound_rate_limits.entry(eid),\\n };\\n\\n let rate_limit = opposite_direction_entry.read();\\n\\n // First apply the decay to get current amount in flight, THEN subtract the flow\\n let FlowableAmount {\\n amount_in_flight: decayed_amount, flowable_amount: _,\\n } = Self::_get_flowable_amount(@self, @rate_limit);\\n let amount_in_flight = decayed_amount.saturating_sub(amount);\\n\\n opposite_direction_entry\\n .write(\\n RateLimit {\\n amount_in_flight: amount_in_flight.try_into().unwrap(),\\n last_updated: get_block_timestamp(),\\n ..rate_limit,\\n },\\n );\\n }\\n }\\n\\n /// Increases the amount in flight by the given amount.\\n ///\\n /// It verifies whether the specified amount falls within the rate limit constraints\\n /// for the destination endpoint ID. On successful verification, it updates the\\n /// amount in flight and the last-updated timestamp. If the amount exceeds the rate limit,\\n /// the operation reverts.\\n ///\\n /// * `dst_eid` The destination endpoint ID.\\n /// * `amount` The amount to outflow.\\n fn _outflow(\\n ref self: ComponentState<TContractState>, dst_eid: u32, amount: u256,\\n ) {\\n Self::_check_and_update_rate_limit(\\n ref self, dst_eid, amount, RateLimitDirection::Outbound,\\n );\\n }\\n\\n /// Checks and updates the inbound rate limit.\\n ///\\n /// It verifies whether the specified amount falls within the inbound rate limit constraints\\n /// for the source endpoint ID. On successful verification, it updates the\\n /// amount in flight and the last-updated timestamp. If the amount exceeds the rate limit,\\n /// the operation reverts.\\n ///\\n /// # Arguments\\n /// * `src_eid` - The source endpoint ID.\\n /// * `amount` - The amount to inflow.\\n fn _inflow(\\n ref self: ComponentState<TContractState>, src_eid: u32, amount: u256,\\n ) {\\n Self::_check_and_update_rate_limit(\\n ref self, src_eid, amount, RateLimitDirection::Inbound,\\n );\\n }\\n\\n /// Checkpoints the rate limit state, updating both outbound and inbound with decayed\\n /// values.\\n ///\\n /// This is called before updating rate limit configurations to preserve the current\\n /// amount_in_flight with the old rate parameters before applying new ones.\\n ///\\n /// # Arguments\\n /// * `eid` - The endpoint ID.\\n fn _checkpoint_rate_limit(\\n ref self: ComponentState<TContractState>, eid: u32,\\n ) {\\n let timestamp = get_block_timestamp();\\n\\n // Checkpoint outbound\\n let outbound_entry = self.RateLimiter_outbound_rate_limits.entry(eid);\\n let outbound_limit = outbound_entry.read();\\n let FlowableAmount {\\n amount_in_flight: outbound_in_flight, flowable_amount: _,\\n } = Self::_get_flowable_amount(@self, @outbound_limit);\\n outbound_entry\\n .write(\\n RateLimit {\\n amount_in_flight: outbound_in_flight.try_into().unwrap(),\\n last_updated: timestamp,\\n ..outbound_limit,\\n },\\n );\\n\\n // Checkpoint inbound\\n let inbound_entry = self.RateLimiter_inbound_rate_limits.entry(eid);\\n let inbound_limit = inbound_entry.read();\\n let FlowableAmount {\\n amount_in_flight: inbound_in_flight, flowable_amount: _,\\n } = Self::_get_flowable_amount(@self, @inbound_limit);\\n inbound_entry\\n .write(\\n RateLimit {\\n amount_in_flight: inbound_in_flight.try_into().unwrap(),\\n last_updated: timestamp,\\n ..inbound_limit,\\n },\\n );\\n }\\n\\n /// Sets the rate limits.\\n ///\\n /// # Arguments\\n /// * `configs` - Rate limit configurations.\\n fn _set_rate_limits(\\n ref self: ComponentState<TContractState>,\\n configs: Array<RateLimitConfig>,\\n direction: RateLimitDirection,\\n ) {\\n for config in @configs {\\n // Update usages with old slopes before setting new limits and windows.\\n // This updates BOTH outbound and inbound directions, matching EVM behavior.\\n Self::_checkpoint_rate_limit(ref self, *config.dst_eid);\\n\\n let entry = match direction {\\n RateLimitDirection::Outbound => self\\n .RateLimiter_outbound_rate_limits\\n .entry(*config.dst_eid),\\n RateLimitDirection::Inbound => self\\n .RateLimiter_inbound_rate_limits\\n .entry(*config.dst_eid),\\n };\\n // Do NOT reset the `amount_in_flight` or `last_updated` of the existing\\n // rate limit.\\n entry\\n .write(\\n RateLimit { limit: *config.limit, window: *config.window, ..entry.read() },\\n );\\n }\\n\\n self.emit(RateLimitsChanged { configs, direction });\\n }\\n\\n\\n /// Resets the outbound and inbound rate limits (sets `amount_in_flight` to 0) for the given\\n /// endpoint IDs.\\n ///\\n /// # Arguments\\n /// * `eids` - The endpoint IDs to reset the rate limits for.\\n fn _reset_rate_limits(\\n ref self: ComponentState<TContractState>, eids: Array<u32>,\\n ) {\\n for eid in @eids {\\n let entry = self.RateLimiter_outbound_rate_limits.entry(*eid);\\n entry\\n .write(\\n RateLimit {\\n amount_in_flight: 0,\\n last_updated: get_block_timestamp(),\\n ..entry.read(),\\n },\\n );\\n\\n let entry = self.RateLimiter_inbound_rate_limits.entry(*eid);\\n entry\\n .write(\\n RateLimit {\\n amount_in_flight: 0,\\n last_updated: get_block_timestamp(),\\n ..entry.read(),\\n },\\n );\\n }\\n\\n self.emit(RateLimitsReset { eids });\\n }\\n\\n fn _set_rate_limit_enabled(\\n ref self: ComponentState<TContractState>, enabled: RateLimitEnabled,\\n ) {\\n self.RateLimiter_enabled.write(enabled);\\n self.emit(RateLimitEnabledChanged { rate_limit_enabled: enabled });\\n }\\n }\\n\\n #[embeddable_as(RateLimiterImpl)]\\n impl RateLimiter<\\n TContractState, +HasComponent<TContractState>, +RateLimiterHooks<TContractState>,\\n > of IRateLimiter<ComponentState<TContractState>> {\\n fn get_sendable_amount(\\n self: @ComponentState<TContractState>, dst_eid: u32,\\n ) -> SendableAmount {\\n let FlowableAmount {\\n amount_in_flight, flowable_amount,\\n } = self._get_flowable_amount(@self.RateLimiter_outbound_rate_limits.read(dst_eid));\\n SendableAmount { amount_in_flight, sendable_amount: flowable_amount }\\n }\\n\\n fn get_receivable_amount(\\n self: @ComponentState<TContractState>, src_eid: u32,\\n ) -> ReceivableAmount {\\n let FlowableAmount {\\n amount_in_flight, flowable_amount,\\n } = self._get_flowable_amount(@self.RateLimiter_inbound_rate_limits.read(src_eid));\\n ReceivableAmount { amount_in_flight, receivable_amount: flowable_amount }\\n }\\n\\n fn get_outbound_rate_limit(\\n self: @ComponentState<TContractState>, dst_eid: u32,\\n ) -> RateLimit {\\n self.RateLimiter_outbound_rate_limits.read(dst_eid)\\n }\\n\\n fn get_inbound_rate_limit(\\n self: @ComponentState<TContractState>, src_eid: u32,\\n ) -> RateLimit {\\n self.RateLimiter_inbound_rate_limits.read(src_eid)\\n }\\n\\n fn get_rate_limit_enabled(self: @ComponentState<TContractState>) -> RateLimitEnabled {\\n self.RateLimiter_enabled.read()\\n }\\n }\\n}\\n\\npub impl RateLimiterHooksDefaultImpl<\\n TContractState, +RateLimiterComponent::HasComponent<TContractState>,\\n> of RateLimiterComponent::RateLimiterHooks<TContractState> {}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/common/rate_limiter/structs.cairo\": \"/// A rate limit state for a destination endpoint ID.\\n#[derive(Drop, Serde, Default, starknet::Store, PartialEq, Debug)]\\npub struct RateLimit {\\n /// An amount in flight.\\n pub amount_in_flight: u128,\\n /// A timestamp from which we calculate decays.\\n pub last_updated: u64,\\n /// An amount limit of the rate.\\n pub limit: u128,\\n /// A time window of the rate.\\n pub window: u64,\\n}\\n\\n/// A rate limit configuration.\\n#[derive(Clone, Drop, Serde, Default, starknet::Store, PartialEq, Debug)]\\npub struct RateLimitConfig {\\n /// A destination endpoint ID.\\n pub dst_eid: u32,\\n /// An amount limit of the rate.\\n pub limit: u128,\\n /// A time window of the rate.\\n pub window: u64,\\n}\\n\\n/// A flowable amount.\\n#[derive(Drop, Serde, starknet::Store, PartialEq, Debug)]\\npub struct FlowableAmount {\\n /// The current amount that is flowing.\\n pub amount_in_flight: u256,\\n /// An amount that can be sent.\\n pub flowable_amount: u256,\\n}\\n\\n#[derive(Drop, Serde, starknet::Store, PartialEq, Debug)]\\npub struct SendableAmount {\\n /// The current amount that is flowing.\\n pub amount_in_flight: u256,\\n /// An amount that can be sent.\\n pub sendable_amount: u256,\\n}\\n\\n#[derive(Drop, Serde, starknet::Store, PartialEq, Debug)]\\npub struct ReceivableAmount {\\n /// The current amount that is flowing.\\n pub amount_in_flight: u256,\\n /// An amount that can be received.\\n pub receivable_amount: u256,\\n}\\n\\n#[derive(Drop, Serde, PartialEq, Debug, Copy)]\\npub enum RateLimitDirection {\\n Outbound,\\n Inbound,\\n}\\n\\n#[derive(Drop, Serde, Default, starknet::Store, PartialEq, Debug, Copy)]\\npub struct RateLimitEnabled {\\n pub is_outbound_enabled: bool,\\n pub is_inbound_enabled: bool,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/counter/constants.cairo\": \"// Message type constants - matching Solidity\\npub const VANILLA_TYPE: u8 = 1;\\npub const COMPOSED_TYPE: u8 = 2;\\npub const ABA_TYPE: u8 = 3;\\npub const COMPOSED_ABA_TYPE: u8 = 4;\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/counter/counter.cairo\": \"#[starknet::contract]\\npub mod OmniCounter {\\n use lz_utils::bytes::Bytes32;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use starknet::storage::{\\n Map, StoragePathEntry, StoragePointerReadAccess, StoragePointerWriteAccess,\\n };\\n use starknet::{ContractAddress, get_caller_address, get_contract_address};\\n use crate::common::structs::messaging::{MessageReceipt, MessagingFee};\\n use crate::common::structs::packet::Origin;\\n use crate::endpoint::interfaces::endpoint_v2::{\\n IEndpointV2Dispatcher, IEndpointV2DispatcherTrait,\\n };\\n use crate::endpoint::interfaces::layerzero_composer::ILayerZeroComposer;\\n use crate::endpoint::messaging_channel::interface::{\\n IMessagingChannelDispatcher, IMessagingChannelDispatcherTrait,\\n };\\n use crate::endpoint::messaging_composer::interface::{\\n IMessagingComposerDispatcher, IMessagingComposerDispatcherTrait,\\n };\\n use crate::oapps::counter::constants::{\\n ABA_TYPE, COMPOSED_ABA_TYPE, COMPOSED_TYPE, VANILLA_TYPE,\\n };\\n use crate::oapps::counter::errors::{\\n err_insufficient_value, err_invalid_message_type, err_invalid_nonce, err_not_endpoint,\\n err_not_oapp, err_only_admin, err_withdraw_failed,\\n };\\n use crate::oapps::counter::interface::IOmniCounter;\\n use crate::oapps::counter::msg_codec;\\n use crate::oapps::counter::options::executor_lz_receive_option;\\n use crate::oapps::counter::structs::{IncrementReceived, IncrementSent};\\n use crate::oapps::oapp::oapp_core::OAppCoreComponent;\\n\\n component!(path: OAppCoreComponent, storage: oapp_core, event: OAppCoreEvent);\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n\\n // OAppCore Mixin - now with built-in ownership control\\n #[abi(embed_v0)]\\n impl OAppCoreImpl = OAppCoreComponent::OAppCoreImpl<ContractState>;\\n impl OAppCoreInternalImpl = OAppCoreComponent::InternalImpl<ContractState>;\\n impl OAppCoreSenderImpl = OAppCoreComponent::OAppSenderImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl OAppCoreReceiverImpl = OAppCoreComponent::OAppReceiverImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl ILayerZeroReceiverImpl =\\n OAppCoreComponent::LayerZeroReceiverImpl<ContractState>;\\n\\n // Ownable Mixin\\n #[abi(embed_v0)]\\n impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;\\n impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n // Global counters\\n count: u256,\\n composed_count: u256,\\n // Admin address\\n admin: ContractAddress,\\n // Local endpoint ID\\n eid: u32,\\n // Ordered nonce tracking\\n max_received_nonce: Map<(u32, Bytes32), u64>, // (srcEid, sender) => nonce\\n ordered_nonce: bool,\\n // Global assertions\\n inbound_count: Map<u32, u256>, // srcEid => count\\n outbound_count: Map<u32, u256>, // dstEid => count\\n #[substorage(v0)]\\n oapp_core: OAppCoreComponent::Storage,\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n #[flat]\\n OAppCoreEvent: OAppCoreComponent::Event,\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n IncrementSent: IncrementSent,\\n IncrementReceived: IncrementReceived,\\n }\\n\\n #[constructor]\\n fn constructor(\\n ref self: ContractState,\\n endpoint: ContractAddress,\\n owner: ContractAddress,\\n native_token: ContractAddress,\\n ) {\\n self.oapp_core.initializer(endpoint, owner, native_token);\\n self.ownable.initializer(owner);\\n self.admin.write(owner);\\n\\n // Get and store the local endpoint ID\\n let endpoint_dispatcher = IEndpointV2Dispatcher { contract_address: endpoint };\\n self.eid.write(endpoint_dispatcher.get_eid());\\n }\\n\\n\\n #[abi(embed_v0)]\\n impl OmniCounterImpl of IOmniCounter<ContractState> {\\n fn get_counter(self: @ContractState, remote_eid: u32) -> u256 {\\n // This matches the old implementation that tests expect\\n self.inbound_count.entry(remote_eid).read()\\n }\\n\\n fn get_count(self: @ContractState) -> u256 {\\n self.count.read()\\n }\\n\\n fn get_composed_count(self: @ContractState) -> u256 {\\n self.composed_count.read()\\n }\\n\\n fn get_inbound_count(self: @ContractState, src_eid: u32) -> u256 {\\n self.inbound_count.entry(src_eid).read()\\n }\\n\\n fn get_outbound_count(self: @ContractState, dst_eid: u32) -> u256 {\\n self.outbound_count.entry(dst_eid).read()\\n }\\n\\n fn get_admin(self: @ContractState) -> ContractAddress {\\n self.admin.read()\\n }\\n\\n fn get_eid(self: @ContractState) -> u32 {\\n self.eid.read()\\n }\\n\\n fn get_ordered_nonce(self: @ContractState) -> bool {\\n self.ordered_nonce.read()\\n }\\n\\n fn set_admin(ref self: ContractState, admin: ContractAddress) {\\n self._only_admin();\\n self.admin.write(admin);\\n }\\n\\n fn withdraw(ref self: ContractState, to: ContractAddress, amount: u256) {\\n self._only_admin();\\n let token_dispatcher = IERC20Dispatcher {\\n contract_address: self.oapp_core.OAppCore_native_token.read(),\\n };\\n\\n let success = token_dispatcher.transfer(to, amount);\\n\\n assert_with_byte_array(success, err_withdraw_failed());\\n }\\n\\n fn set_ordered_nonce(ref self: ContractState, ordered_nonce: bool) {\\n self.oapp_core._assert_only_owner();\\n self.ordered_nonce.write(ordered_nonce);\\n }\\n\\n fn quote(\\n self: @ContractState,\\n dst_eid: u32,\\n msg_type: u8,\\n options: ByteArray,\\n pay_in_lz_token: bool,\\n ) -> MessagingFee {\\n // Create message using msg_codec\\n let eid = self.eid.read();\\n let message = msg_codec::encode(msg_type, eid);\\n\\n self.oapp_core._quote(dst_eid, message, options, pay_in_lz_token)\\n }\\n\\n fn increment(\\n ref self: ContractState,\\n dst_eid: u32,\\n msg_type: u8,\\n options: ByteArray,\\n fee: MessagingFee,\\n refund_address: ContractAddress,\\n ) -> MessageReceipt {\\n let caller = get_caller_address();\\n\\n // Create message using msg_codec\\n let eid = self.eid.read();\\n let message = msg_codec::encode(msg_type, eid);\\n\\n self.emit(IncrementSent { sender: caller, dst_eid, increment_type: msg_type });\\n\\n self._increment_outbound(dst_eid);\\n\\n // Call the underlying OAppCore send function\\n self.oapp_core._lz_send(caller, dst_eid, message, options, fee, refund_address)\\n }\\n\\n fn skip_inbound_nonce(ref self: ContractState, src_eid: u32, sender: Bytes32, nonce: u64) {\\n self.oapp_core._assert_only_owner();\\n\\n let endpoint_dispatcher = IMessagingChannelDispatcher {\\n contract_address: self.oapp_core.OAppCore_endpoint.read(),\\n };\\n endpoint_dispatcher.skip(get_contract_address(), Origin { src_eid, sender, nonce });\\n\\n if self.ordered_nonce.read() {\\n let key = (src_eid, sender);\\n let current = self.max_received_nonce.entry(key).read();\\n self.max_received_nonce.entry(key).write(current + 1);\\n }\\n }\\n\\n fn is_peer(self: @ContractState, eid: u32, peer: Bytes32) -> bool {\\n self.oapp_core.get_peer(eid) == peer\\n }\\n }\\n\\n #[abi(embed_v0)]\\n impl ILayerZeroComposerImpl of ILayerZeroComposer<ContractState> {\\n fn lz_compose(\\n ref self: ContractState,\\n from: ContractAddress,\\n guid: Bytes32,\\n message: ByteArray,\\n executor: ContractAddress,\\n extra_data: ByteArray,\\n value: u256,\\n ) {\\n assert_with_byte_array(from == get_contract_address(), err_not_oapp());\\n let endpoint = self.oapp_core.get_endpoint();\\n assert_with_byte_array(get_caller_address() == endpoint, err_not_endpoint());\\n\\n // Extract message type using msg_codec\\n let msg_type = msg_codec::msg_type(@message);\\n\\n if msg_type == COMPOSED_TYPE {\\n self.composed_count.write(self.composed_count.read() + 1);\\n } else if msg_type == COMPOSED_ABA_TYPE {\\n self.composed_count.write(self.composed_count.read() + 1);\\n\\n let src_eid = msg_codec::src_eid(@message);\\n self._increment_outbound(src_eid);\\n\\n // Create response message using msg_codec\\n let eid = self.eid.read();\\n let response_message = msg_codec::encode(VANILLA_TYPE, eid);\\n let options = executor_lz_receive_option(200000, 0);\\n let fee = MessagingFee { native_fee: value, lz_token_fee: 0 };\\n let contract_address = get_contract_address();\\n\\n self\\n .oapp_core\\n ._lz_send(\\n contract_address, src_eid, response_message, options, fee, contract_address,\\n );\\n self\\n .emit(\\n IncrementSent {\\n sender: contract_address,\\n dst_eid: src_eid,\\n increment_type: VANILLA_TYPE,\\n },\\n );\\n } else {\\n assert_with_byte_array(false, err_invalid_message_type(msg_type));\\n }\\n }\\n }\\n\\n #[generate_trait]\\n impl InternalImpl of InternalTrait {\\n fn _only_admin(self: @ContractState) {\\n assert_with_byte_array(get_caller_address() == self.admin.read(), err_only_admin());\\n }\\n\\n fn _increment_inbound(ref self: ContractState, src_eid: u32) {\\n let entry = self.inbound_count.entry(src_eid);\\n entry.write(entry.read() + 1);\\n }\\n\\n fn _increment_outbound(ref self: ContractState, dst_eid: u32) {\\n let entry = self.outbound_count.entry(dst_eid);\\n entry.write(entry.read() + 1);\\n }\\n\\n fn _accept_nonce(ref self: ContractState, src_eid: u32, sender: Bytes32, nonce: u64) {\\n let current_nonce_entry = self.max_received_nonce.entry((src_eid, sender));\\n let current_nonce = current_nonce_entry.read();\\n\\n if self.ordered_nonce.read() {\\n assert_with_byte_array(\\n nonce == current_nonce + 1, err_invalid_nonce(current_nonce + 1, nonce),\\n );\\n }\\n\\n // Update the max nonce anyway\\n if nonce > current_nonce {\\n current_nonce_entry.write(nonce);\\n }\\n }\\n }\\n\\n // Implement OAppHooks to provide the required _lz_receive implementation\\n impl OAppHooks of OAppCoreComponent::OAppHooks<ContractState> {\\n fn _lz_receive(\\n ref self: OAppCoreComponent::ComponentState<ContractState>,\\n origin: Origin,\\n guid: Bytes32,\\n message: ByteArray,\\n executor: ContractAddress,\\n extra_data: ByteArray,\\n value: u256,\\n ) {\\n let mut contract = self.get_contract_mut();\\n\\n // Accept nonce\\n contract._accept_nonce(origin.src_eid, origin.sender, origin.nonce);\\n\\n // Extract message type using msg_codec\\n let msg_type = msg_codec::msg_type(@message);\\n\\n if msg_type == VANILLA_TYPE {\\n contract.count.write(contract.count.read() + 1);\\n\\n let message_value = msg_codec::value(@message);\\n\\n // Check if value is correct\\n assert_with_byte_array(\\n value >= message_value, err_insufficient_value(message_value, value),\\n );\\n\\n contract._increment_inbound(origin.src_eid);\\n\\n // Emit event\\n contract\\n .emit(\\n IncrementReceived {\\n src_eid: origin.src_eid,\\n old_value: contract.count.read() - 1,\\n new_value: contract.count.read(),\\n increment_type: msg_type,\\n value,\\n },\\n );\\n } else if msg_type == COMPOSED_TYPE || msg_type == COMPOSED_ABA_TYPE {\\n contract.count.write(contract.count.read() + 1);\\n contract._increment_inbound(origin.src_eid);\\n\\n // Send compose request to endpoint\\n let endpoint = self.get_endpoint();\\n let endpoint_dispatcher = IMessagingComposerDispatcher {\\n contract_address: endpoint,\\n };\\n endpoint_dispatcher.send_compose(get_contract_address(), guid, 0, message);\\n\\n // Emit event\\n contract\\n .emit(\\n IncrementReceived {\\n src_eid: origin.src_eid,\\n old_value: contract.count.read() - 1,\\n new_value: contract.count.read(),\\n increment_type: msg_type,\\n value,\\n },\\n );\\n } else if msg_type == ABA_TYPE {\\n contract.count.write(contract.count.read() + 1);\\n contract._increment_inbound(origin.src_eid);\\n\\n // Send back to sender\\n contract._increment_outbound(origin.src_eid);\\n\\n // Create response message using msg_codec\\n let eid = contract.eid.read();\\n let response_message = msg_codec::encode_with_value(VANILLA_TYPE, eid, 10);\\n let options = executor_lz_receive_option(200000, 10);\\n\\n // Quote the fee for the response message\\n let contract_address = get_contract_address();\\n self\\n ._lz_send(\\n contract_address,\\n origin.src_eid,\\n response_message,\\n options,\\n MessagingFee { native_fee: value, lz_token_fee: 0 },\\n contract_address,\\n );\\n\\n contract\\n .emit(\\n IncrementReceived {\\n src_eid: origin.src_eid,\\n old_value: contract.count.read() - 1,\\n new_value: contract.count.read(),\\n increment_type: msg_type,\\n value,\\n },\\n );\\n contract\\n .emit(\\n IncrementSent {\\n sender: contract_address,\\n dst_eid: origin.src_eid,\\n increment_type: VANILLA_TYPE,\\n },\\n );\\n } else {\\n assert_with_byte_array(false, err_invalid_message_type(msg_type));\\n }\\n }\\n\\n fn _next_nonce(\\n self: @OAppCoreComponent::ComponentState<ContractState>, src_eid: u32, sender: Bytes32,\\n ) -> u64 {\\n let contract = self.get_contract();\\n if contract.ordered_nonce.read() {\\n contract.max_received_nonce.entry((src_eid, sender)).read() + 1\\n } else {\\n 0\\n }\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/counter/errors.cairo\": \"//! OmniCounter errors\\n\\nuse lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum OmniCounterError {\\n /// Triggered when someone other than admin tries to access admin functions\\n OnlyAdmin,\\n /// Triggered when withdraw operation fails\\n WithdrawFailed,\\n /// Triggered when value sent is insufficient compared to the required value\\n InsufficientValue,\\n /// Triggered when an invalid message type is received\\n InvalidMessageType,\\n /// Triggered when the compose source is not the OApp itself\\n NotOApp,\\n /// Triggered when the caller is not the endpoint\\n NotEndpoint,\\n /// Triggered when an invalid nonce is received in ordered mode\\n InvalidNonce,\\n /// Triggered when array lengths don't match in batch operations\\n LengthMismatch,\\n /// Triggered when there's not enough native fee for operations\\n NotEnoughNative,\\n}\\n\\nimpl ErrorNameImpl of Error<OmniCounterError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_OMNI_COUNTER\\\"\\n }\\n\\n fn name(self: OmniCounterError) -> ByteArray {\\n match self {\\n OmniCounterError::OnlyAdmin => \\\"ONLY_ADMIN\\\",\\n OmniCounterError::WithdrawFailed => \\\"WITHDRAW_FAILED\\\",\\n OmniCounterError::InsufficientValue => \\\"INSUFFICIENT_VALUE\\\",\\n OmniCounterError::InvalidMessageType => \\\"INVALID_MESSAGE_TYPE\\\",\\n OmniCounterError::NotOApp => \\\"NOT_OAPP\\\",\\n OmniCounterError::NotEndpoint => \\\"NOT_ENDPOINT\\\",\\n OmniCounterError::InvalidNonce => \\\"INVALID_NONCE\\\",\\n OmniCounterError::LengthMismatch => \\\"LENGTH_MISMATCH\\\",\\n OmniCounterError::NotEnoughNative => \\\"NOT_ENOUGH_NATIVE\\\",\\n }\\n }\\n}\\n\\npub fn err_only_admin() -> ByteArray {\\n format_error(OmniCounterError::OnlyAdmin, \\\"\\\")\\n}\\n\\npub fn err_withdraw_failed() -> ByteArray {\\n format_error(OmniCounterError::WithdrawFailed, \\\"\\\")\\n}\\n\\npub fn err_insufficient_value(required: u256, provided: u256) -> ByteArray {\\n format_error(\\n OmniCounterError::InsufficientValue,\\n format!(\\\"required: {}, provided: {}\\\", required, provided),\\n )\\n}\\n\\npub fn err_invalid_message_type(msg_type: u8) -> ByteArray {\\n format_error(OmniCounterError::InvalidMessageType, format!(\\\"type: {}\\\", msg_type))\\n}\\n\\npub fn err_not_oapp() -> ByteArray {\\n format_error(OmniCounterError::NotOApp, \\\"\\\")\\n}\\n\\npub fn err_not_endpoint() -> ByteArray {\\n format_error(OmniCounterError::NotEndpoint, \\\"\\\")\\n}\\n\\npub fn err_invalid_nonce(expected: u64, received: u64) -> ByteArray {\\n format_error(\\n OmniCounterError::InvalidNonce, format!(\\\"expected: {}, received: {}\\\", expected, received),\\n )\\n}\\n\\npub fn err_length_mismatch() -> ByteArray {\\n format_error(OmniCounterError::LengthMismatch, \\\"\\\")\\n}\\n\\npub fn err_not_enough_native(msg_value: u256) -> ByteArray {\\n format_error(OmniCounterError::NotEnoughNative, format!(\\\"msg.value: {}\\\", msg_value))\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/counter/interface.cairo\": \"use lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::common::structs::messaging::{MessageReceipt, MessagingFee};\\n\\n#[starknet::interface]\\npub trait IOmniCounter<TContractState> {\\n // Get the counter value for a specific remote EID (to match existing tests)\\n fn get_counter(self: @TContractState, remote_eid: u32) -> u256;\\n\\n // State getters\\n fn get_count(self: @TContractState) -> u256;\\n fn get_composed_count(self: @TContractState) -> u256;\\n fn get_inbound_count(self: @TContractState, src_eid: u32) -> u256;\\n fn get_outbound_count(self: @TContractState, dst_eid: u32) -> u256;\\n fn get_admin(self: @TContractState) -> ContractAddress;\\n fn get_eid(self: @TContractState) -> u32;\\n fn get_ordered_nonce(self: @TContractState) -> bool;\\n\\n // Admin functions\\n fn set_admin(ref self: TContractState, admin: ContractAddress);\\n fn withdraw(ref self: TContractState, to: ContractAddress, amount: u256);\\n\\n // Nonce management\\n fn set_ordered_nonce(ref self: TContractState, ordered_nonce: bool);\\n fn skip_inbound_nonce(ref self: TContractState, src_eid: u32, sender: Bytes32, nonce: u64);\\n\\n // Peer management\\n fn is_peer(self: @TContractState, eid: u32, peer: Bytes32) -> bool;\\n\\n // Messaging functions\\n fn quote(\\n self: @TContractState,\\n dst_eid: u32,\\n msg_type: u8,\\n options: ByteArray,\\n pay_in_lz_token: bool,\\n ) -> MessagingFee;\\n\\n fn increment(\\n ref self: TContractState,\\n dst_eid: u32,\\n msg_type: u8,\\n options: ByteArray,\\n fee: MessagingFee,\\n refund_address: ContractAddress,\\n ) -> MessageReceipt;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/counter/msg_codec.cairo\": \"use lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\n\\nconst MSG_TYPE_OFFSET: usize = 0;\\nconst SRC_EID_OFFSET: usize = 1;\\nconst VALUE_OFFSET: usize = 5;\\n\\npub fn encode(msg_type: u8, src_eid: u32) -> ByteArray {\\n let mut message: ByteArray = Default::default();\\n message.append_u8(msg_type);\\n message.append_u32(src_eid);\\n message\\n}\\n\\npub fn encode_with_value(msg_type: u8, src_eid: u32, value: u256) -> ByteArray {\\n let mut message: ByteArray = Default::default();\\n message.append_u8(msg_type);\\n message.append_u32(src_eid);\\n message.append_u256(value);\\n message\\n}\\n\\npub fn msg_type(message: @ByteArray) -> u8 {\\n let (_, type_value) = message.read_u8(MSG_TYPE_OFFSET);\\n type_value\\n}\\n\\npub fn src_eid(message: @ByteArray) -> u32 {\\n let (_, eid_value) = message.read_u32(SRC_EID_OFFSET);\\n eid_value\\n}\\n\\npub fn value(message: @ByteArray) -> u256 {\\n if message.len() <= VALUE_OFFSET {\\n return 0;\\n }\\n\\n let (_, value_data) = message.read_u256(VALUE_OFFSET);\\n value_data\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/counter/options.cairo\": \"use lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\nuse crate::workers::executor::options::{EXECUTOR_WORKER_ID, OPTION_TYPE_LZRECEIVE};\\n\\npub fn executor_lz_receive_option(gas_limit: u128, value: u128) -> ByteArray {\\n let mut params = Default::default();\\n if value == 0 {\\n params.append_u128(gas_limit);\\n } else {\\n params.append_u128(gas_limit);\\n params.append_u128(value);\\n }\\n let mut options = Default::default();\\n options.append_u16(3); // append option type 3\\n options.append_u8(EXECUTOR_WORKER_ID); // append worker id\\n options.append_u16(params.len().try_into().unwrap() + 1); // append params length\\n options.append_u8(OPTION_TYPE_LZRECEIVE); // append option type\\n options.append(@params);\\n options\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/counter/structs.cairo\": \"use starknet::ContractAddress;\\n\\n#[derive(Drop, starknet::Event)]\\npub struct IncrementSent {\\n #[key]\\n pub sender: ContractAddress,\\n #[key]\\n pub dst_eid: u32,\\n pub increment_type: u8,\\n}\\n\\n#[derive(Drop, starknet::Event)]\\npub struct IncrementReceived {\\n #[key]\\n pub src_eid: u32,\\n pub old_value: u256,\\n pub new_value: u256,\\n pub increment_type: u8,\\n pub value: u256,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/message_inspector/interface.cairo\": \"//! Message inspector interface\\n\\n/// IMessageInspector defines the complete interface for message inspection.\\n#[starknet::interface]\\npub trait IMessageInspector<TContractState> {\\n /// Inspect the message and options\\n ///\\n /// This function is called to inspect the message and options before they are sent.\\n /// If the message or options fail inspection, the transaction will revert.\\n ///\\n /// # Arguments\\n /// * `message` - The message to inspect\\n /// * `options` - The options to inspect\\n ///\\n /// # Returns\\n /// * `bool` - True if the message and options pass inspection, false otherwise\\n ///\\n /// # Panics\\n /// * If the message or options fail inspection, the transaction will revert\\n fn inspect_msg(self: @TContractState, message: ByteArray, options: ByteArray) -> bool;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oapp/errors.cairo\": \"use lz_utils::bytes::Bytes32;\\nuse lz_utils::error::{Error, format_error};\\nuse starknet::ContractAddress;\\n\\n#[derive(Drop)]\\npub enum OAppCoreError {\\n OnlyEndpoint,\\n OnlyPeer,\\n NoPeer,\\n NotEnoughNative,\\n NotEnoughNativeAllowance,\\n NotEnoughLzToken,\\n NotEnoughLzTokenAllowance,\\n LzTokenUnavailable,\\n TransferFailed,\\n ApprovalFailed,\\n InvalidDelegate,\\n}\\n\\nimpl ErrorNameImpl of Error<OAppCoreError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_OAPP_CORE\\\"\\n }\\n\\n fn name(self: OAppCoreError) -> ByteArray {\\n match self {\\n OAppCoreError::OnlyEndpoint => \\\"ONLY_ENDPOINT\\\",\\n OAppCoreError::OnlyPeer => \\\"ONLY_PEER\\\",\\n OAppCoreError::NoPeer => \\\"NO_PEER\\\",\\n OAppCoreError::NotEnoughNative => \\\"NOT_ENOUGH_NATIVE\\\",\\n OAppCoreError::NotEnoughNativeAllowance => \\\"NOT_ENOUGH_NATIVE_ALLOWANCE\\\",\\n OAppCoreError::NotEnoughLzToken => \\\"NOT_ENOUGH_LZ_TOKEN\\\",\\n OAppCoreError::NotEnoughLzTokenAllowance => \\\"NOT_ENOUGH_LZ_TOKEN_ALLOWANCE\\\",\\n OAppCoreError::LzTokenUnavailable => \\\"LZ_TOKEN_UNAVAILABLE\\\",\\n OAppCoreError::TransferFailed => \\\"TRANSFER_FAILED\\\",\\n OAppCoreError::ApprovalFailed => \\\"APPROVAL_FAILED\\\",\\n OAppCoreError::InvalidDelegate => \\\"INVALID_DELEGATE\\\",\\n }\\n }\\n}\\n\\npub fn err_only_endpoint(endpoint: ContractAddress) -> ByteArray {\\n format_error(OAppCoreError::OnlyEndpoint, format!(\\\"{:?}\\\", endpoint))\\n}\\n\\npub fn err_only_peer(eid: u32, peer: Bytes32) -> ByteArray {\\n format_error(OAppCoreError::OnlyPeer, format!(\\\"eid: {:?}, peer: {:?}\\\", eid, peer))\\n}\\n\\npub fn err_no_peer(eid: u32) -> ByteArray {\\n format_error(OAppCoreError::NoPeer, format!(\\\"eid: {:?}\\\", eid))\\n}\\n\\npub fn err_not_enough_native(fee: u256, balance: u256) -> ByteArray {\\n format_error(OAppCoreError::NotEnoughNative, format!(\\\"fee: {:?}, balance: {:?}\\\", fee, balance))\\n}\\n\\npub fn err_not_enough_lz_token(fee: u256, balance: u256) -> ByteArray {\\n format_error(OAppCoreError::NotEnoughLzToken, format!(\\\"fee: {:?}, balance: {:?}\\\", fee, balance))\\n}\\n\\npub fn err_lz_token_unavailable() -> ByteArray {\\n format_error(OAppCoreError::LzTokenUnavailable, \\\"\\\")\\n}\\n\\npub fn err_not_enough_lz_token_allowance(fee: u256, allowance: u256) -> ByteArray {\\n format_error(\\n OAppCoreError::NotEnoughLzTokenAllowance,\\n format!(\\\"fee: {:?}, allowance: {:?}\\\", fee, allowance),\\n )\\n}\\n\\npub fn err_not_enough_native_allowance(fee: u256, allowance: u256) -> ByteArray {\\n format_error(\\n OAppCoreError::NotEnoughNativeAllowance,\\n format!(\\\"fee: {:?}, allowance: {:?}\\\", fee, allowance),\\n )\\n}\\n\\npub fn err_transfer_failed() -> ByteArray {\\n format_error(OAppCoreError::TransferFailed, \\\"\\\")\\n}\\n\\npub fn err_approval_failed() -> ByteArray {\\n format_error(OAppCoreError::ApprovalFailed, \\\"\\\")\\n}\\n\\npub fn err_invalid_delegate() -> ByteArray {\\n format_error(OAppCoreError::InvalidDelegate, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oapp/events.cairo\": \"use lz_utils::bytes::Bytes32;\\n\\n#[derive(Drop, starknet::Event)]\\npub struct PeerSet {\\n #[key]\\n pub eid: u32,\\n #[key]\\n pub peer: Bytes32,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oapp/interface.cairo\": \"use lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::Origin;\\n\\n#[starknet::interface]\\npub trait IOApp<TContractState> {\\n /// Gets the LayerZero endpoint contract address\\n ///\\n /// # Returns\\n ///\\n /// The contract address of the LayerZero endpoint\\n fn get_endpoint(self: @TContractState) -> ContractAddress;\\n\\n /// Sets a peer for a specific endpoint ID\\n /// This establishes a trusted connection to another OApp on a different chain\\n ///\\n /// # Arguments\\n ///\\n /// * `eid`: The endpoint ID of the destination chain\\n /// * `peer`: The peer address as a 32-byte value\\n fn set_peer(ref self: TContractState, eid: u32, peer: Bytes32);\\n\\n /// Gets the peer address for a specific endpoint ID\\n ///\\n /// # Arguments\\n ///\\n /// * `eid`: The endpoint ID of the destination chain\\n ///\\n /// # Returns\\n ///\\n /// The peer address as a 32-byte value\\n fn get_peer(self: @TContractState, eid: u32) -> Bytes32;\\n\\n /// Returns the OApp version information\\n ///\\n /// # Returns\\n ///\\n /// A tuple containing (sender_version, receiver_version) as u64 values\\n fn oapp_version(self: @TContractState) -> (u64, u64);\\n\\n /// Sets the send library for a specific endpoint ID\\n ///\\n /// # Arguments\\n ///\\n /// * `dst_eid`: The destination endpoint ID\\n /// * `delegate`: The contract address of the delegate\\n fn set_delegate(ref self: TContractState, delegate: ContractAddress);\\n}\\n\\n#[starknet::interface]\\npub trait IOAppReceiver<TContractState> {\\n /// Verifies if a sender is authorized for compose message operations\\n /// This is used in message composition scenarios to validate senders\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin information of the message\\n /// * `message`: The message content to validate\\n /// * `sender`: The contract address claiming to be the sender\\n ///\\n /// # Returns\\n ///\\n /// True if the sender is authorized for compose messages, false otherwise\\n fn is_compose_msg_sender(\\n self: @TContractState, origin: Origin, message: ByteArray, sender: ContractAddress,\\n ) -> bool;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oapp/oapp.cairo\": \"/// OApp - Simple LayerZero OApp using integrated OAppCore functionality\\n#[starknet::contract]\\npub mod OApp {\\n use layerzero::oapps::oapp::oapp_core::OAppCoreComponent;\\n use lz_utils::bytes::Bytes32;\\n // Core OApp implementation - all types are provided by the component traits\\n use openzeppelin::access::ownable::OwnableComponent;\\n use starknet::ContractAddress;\\n use crate::Origin;\\n\\n component!(path: OAppCoreComponent, storage: oapp_core, event: OAppCoreEvent);\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n\\n // OAppCore Mixin - Core functionality\\n #[abi(embed_v0)]\\n impl OAppCoreImpl = OAppCoreComponent::OAppCoreImpl<ContractState>;\\n #[abi(embed_v0)]\\n impl ILayerZeroReceiverImpl =\\n OAppCoreComponent::LayerZeroReceiverImpl<ContractState>;\\n #[abi(embed_v0)]\\n impl IOAppReceiverImpl = OAppCoreComponent::OAppReceiverImpl<ContractState>;\\n impl OAppCoreInternalImpl = OAppCoreComponent::InternalImpl<ContractState>;\\n\\n // Ownable Mixin\\n #[abi(embed_v0)]\\n impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;\\n impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n #[substorage(v0)]\\n oapp_core: OAppCoreComponent::Storage,\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n #[flat]\\n OAppCoreEvent: OAppCoreComponent::Event,\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n }\\n\\n #[constructor]\\n fn constructor(\\n ref self: ContractState,\\n endpoint: ContractAddress,\\n owner: ContractAddress,\\n native_token: ContractAddress,\\n ) {\\n self.oapp_core.initializer(endpoint, owner, native_token);\\n self.ownable.initializer(owner);\\n }\\n\\n // Implement OAppHooks to provide OApp-specific message handling operations\\n impl OAppHooks of OAppCoreComponent::OAppHooks<ContractState> {\\n fn _lz_receive(\\n ref self: OAppCoreComponent::ComponentState<ContractState>,\\n origin: Origin,\\n guid: Bytes32,\\n message: ByteArray,\\n executor: ContractAddress,\\n extra_data: ByteArray,\\n value: u256,\\n ) { // Contract should implement receive logic here\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oapp/oapp_core.cairo\": \"/// OAppCore Component - Complete LayerZero OApp functionality\\n\\n#[starknet::component]\\npub mod OAppCoreComponent {\\n use core::num::traits::Zero;\\n use lz_utils::bytes::{Bytes32, ContractAddressIntoBytes32};\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::access::ownable::OwnableComponent::{\\n InternalImpl as OwnableInternalImpl, InternalTrait as OwnableInternalTrait,\\n };\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use starknet::storage::{\\n Map, StoragePathEntry, StoragePointerReadAccess, StoragePointerWriteAccess,\\n };\\n use starknet::{ContractAddress, get_caller_address, get_contract_address};\\n use crate::common::structs::messaging::{MessageReceipt, MessagingFee, MessagingParams};\\n use crate::common::structs::packet::Origin;\\n use crate::endpoint::interfaces::endpoint_v2::{\\n IEndpointV2Dispatcher, IEndpointV2DispatcherTrait,\\n };\\n use crate::endpoint::interfaces::layerzero_receiver::ILayerZeroReceiver;\\n use crate::oapps::oapp::errors::{\\n err_approval_failed, err_invalid_delegate, err_lz_token_unavailable, err_no_peer,\\n err_not_enough_lz_token, err_not_enough_lz_token_allowance, err_not_enough_native,\\n err_not_enough_native_allowance, err_only_endpoint, err_only_peer, err_transfer_failed,\\n };\\n use crate::oapps::oapp::events::PeerSet;\\n\\n // Version constants\\n pub const OAPP_CORE_VERSION: u64 = 1;\\n pub const OAPP_SENDER_VERSION: u64 = 1;\\n pub const OAPP_RECEIVER_VERSION: u64 = 1;\\n\\n /// =============================== Storage =================================\\n #[storage]\\n pub struct Storage {\\n pub OAppCore_endpoint: ContractAddress,\\n pub OAppCore_native_token: ContractAddress,\\n // Mapping from remoteEid to peer address\\n pub OAppCore_peers: Map<u32, Bytes32>,\\n }\\n\\n /// =============================== Events =================================\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n PeerSet: PeerSet,\\n }\\n\\n /// =============================== Hooks =================================\\n\\n /// Hooks for the OApp component\\n ///\\n /// These hooks are used to override the default behavior of the OApp component.\\n /// They are used to implement the custom logic for the OApp component.\\n ///\\n /// Its mandatory to implement all the hooks.\\n /// _lz_receive doesn't have a default implementation\\n /// i.e. it must be implemented by the OApp.\\n /// _is_compose_msg_sender, _allow_initialize_path, _next_nonce have default implementations\\n /// and can be omitted in the contract implementation.\\n pub trait OAppHooks<TContractState> {\\n /// Entry point for receiving messages from the LayerZero endpoint\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin information containing the source endpoint and sender address\\n /// * `guid`: The unique identifier for the received LayerZero message\\n /// * `message`: The payload of the received message\\n fn _lz_receive(\\n ref self: ComponentState<TContractState>,\\n origin: Origin,\\n guid: Bytes32,\\n message: ByteArray,\\n executor: ContractAddress,\\n extra_data: ByteArray,\\n value: u256,\\n );\\n\\n /// Checks if the caller is a valid composeMsg sender\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin information containing the source endpoint and sender address\\n /// * `message`: The payload of the received message\\n /// * `sender`: The address of the sender\\n ///\\n /// # Returns\\n ///\\n /// * `bool`: True if the sender is a valid composeMsg sender, false otherwise\\n ///\\n /// Applications can optionally choose to implement separate composeMsg senders that are NOT\\n /// the bridging layer.\\n /// The default sender IS the OAppReceiver implementer.\\n fn _is_compose_msg_sender(\\n self: @ComponentState<TContractState>,\\n origin: Origin,\\n message: ByteArray,\\n sender: ContractAddress,\\n ) -> bool {\\n sender == get_contract_address()\\n }\\n\\n /// Checks if the path initialization is allowed based on the provided origin\\n ///\\n /// # Arguments\\n ///\\n /// * `origin`: The origin information containing the source endpoint and sender address\\n ///\\n /// # Returns\\n ///\\n /// * `bool`: True if the path has been initialized, false otherwise\\n ///\\n /// @dev This indicates to the endpoint that the OApp has enabled msgs for this particular\\n /// path to be received.\\n /// @dev This defaults to assuming if a peer has been set, its initialized.\\n /// Can be overridden by the OApp if there is other logic to determine this.\\n fn _allow_initialize_path(\\n self: @ComponentState<TContractState>, origin: Origin,\\n ) -> bool {\\n self.OAppCore_peers.entry(origin.src_eid).read() == origin.sender\\n }\\n\\n /// Returns the next nonce for a given source endpoint and sender address\\n ///\\n /// # Arguments\\n ///\\n /// * `src_eid`: The source endpoint ID\\n /// * `sender`: The sender address\\n ///\\n /// # Returns\\n ///\\n /// * `u64`: The next nonce\\n ///\\n /// @dev The path nonce starts from 1. If 0 is returned it means that there is NO nonce\\n /// ordered enforcement.\\n /// @dev Is required by the off-chain executor to determine the OApp expects msg execution\\n /// is ordered.\\n /// @dev This is also enforced by the OApp.\\n /// @dev By default this is NOT enabled. ie. nextNonce is hardcoded to return 0.\\n fn _next_nonce(\\n self: @ComponentState<TContractState>, src_eid: u32, sender: Bytes32,\\n ) -> u64 {\\n 0\\n }\\n }\\n\\n #[embeddable_as(OAppCoreImpl)]\\n impl OAppCore<\\n TContractState,\\n +HasComponent<TContractState>,\\n impl Ownable: OwnableComponent::HasComponent<TContractState>,\\n > of crate::oapps::oapp::interface::IOApp<ComponentState<TContractState>> {\\n fn get_endpoint(self: @ComponentState<TContractState>) -> ContractAddress {\\n self.OAppCore_endpoint.read()\\n }\\n\\n fn set_peer(ref self: ComponentState<TContractState>, eid: u32, peer: Bytes32) {\\n self._assert_only_owner();\\n self.OAppCore_peers.entry(eid).write(peer);\\n self.emit(PeerSet { eid, peer });\\n }\\n\\n fn get_peer(self: @ComponentState<TContractState>, eid: u32) -> Bytes32 {\\n self.OAppCore_peers.entry(eid).read()\\n }\\n\\n fn oapp_version(self: @ComponentState<TContractState>) -> (u64, u64) {\\n (OAPP_SENDER_VERSION, OAPP_RECEIVER_VERSION)\\n }\\n\\n fn set_delegate(ref self: ComponentState<TContractState>, delegate: ContractAddress) {\\n self._assert_only_owner();\\n\\n IEndpointV2Dispatcher { contract_address: self.OAppCore_endpoint.read() }\\n .set_delegate(delegate);\\n }\\n }\\n\\n /// LayerZero Receiver implementation\\n #[embeddable_as(LayerZeroReceiverImpl)]\\n impl LayerZeroReceiver<\\n TContractState,\\n +HasComponent<TContractState>,\\n impl Ownable: OwnableComponent::HasComponent<TContractState>,\\n +OAppHooks<TContractState>,\\n > of ILayerZeroReceiver<ComponentState<TContractState>> {\\n fn lz_receive(\\n ref self: ComponentState<TContractState>,\\n origin: Origin,\\n guid: Bytes32,\\n message: ByteArray,\\n executor: ContractAddress,\\n extra_data: ByteArray,\\n value: u256,\\n ) {\\n // Ensures that only the endpoint can attempt to lzReceive() messages to this OApp\\n self._assert_only_endpoint();\\n\\n // Ensure that the sender matches the expected peer for the source endpoint\\n let expected_peer = self._get_peer_or_revert(origin.src_eid);\\n assert_with_byte_array(\\n expected_peer == origin.sender, err_only_peer(origin.src_eid, origin.sender),\\n );\\n\\n // Call the internal OApp implementation of lzReceive\\n self._lz_receive(origin, guid, message, executor, extra_data, value);\\n }\\n\\n fn allow_initialize_path(self: @ComponentState<TContractState>, origin: Origin) -> bool {\\n self._allow_initialize_path(origin)\\n }\\n\\n fn next_nonce(self: @ComponentState<TContractState>, src_eid: u32, sender: Bytes32) -> u64 {\\n self._next_nonce(src_eid, sender)\\n }\\n }\\n\\n #[embeddable_as(OAppReceiverImpl)]\\n impl IOAppReceiver<\\n TContractState, +HasComponent<TContractState>, +OAppHooks<TContractState>,\\n > of crate::oapps::oapp::interface::IOAppReceiver<ComponentState<TContractState>> {\\n fn is_compose_msg_sender(\\n self: @ComponentState<TContractState>,\\n origin: Origin,\\n message: ByteArray,\\n sender: ContractAddress,\\n ) -> bool {\\n self._is_compose_msg_sender(origin, message, sender)\\n }\\n }\\n\\n\\n /// =============================== OApp Sender Functions =================================\\n #[generate_trait]\\n pub impl OAppSenderImpl<\\n TContractState,\\n +HasComponent<TContractState>,\\n impl Ownable: OwnableComponent::HasComponent<TContractState>,\\n > of OAppSender<TContractState> {\\n /// Quotes the fee for sending a message to a destination endpoint\\n ///\\n /// # Arguments\\n ///\\n /// * `dst_eid`: The destination endpoint ID\\n /// * `message`: The message payload to be sent\\n /// * `options`: Additional options for the message transmission\\n /// * `pay_in_lz_token`: Flag indicating whether to pay the fee in LZ tokens\\n ///\\n /// # Returns\\n ///\\n /// * `MessagingFee`: The calculated fee structure for the message\\n fn _quote(\\n self: @ComponentState<TContractState>,\\n dst_eid: u32,\\n message: ByteArray,\\n options: ByteArray,\\n pay_in_lz_token: bool,\\n ) -> MessagingFee {\\n let receiver = self._get_peer_or_revert(dst_eid);\\n let params = MessagingParams { dst_eid, receiver, message, options, pay_in_lz_token };\\n let sender = get_contract_address();\\n let endpoint = self.OAppCore_endpoint.read();\\n let endpoint_dispatcher = IEndpointV2Dispatcher { contract_address: endpoint };\\n endpoint_dispatcher.quote(params, sender)\\n }\\n\\n /// Sends a message through the LayerZero endpoint to a destination chain\\n ///\\n /// # Arguments\\n ///\\n /// * `dst_eid`: The destination endpoint ID\\n /// * `message`: The message payload to be sent\\n /// * `options`: Additional options for the message transmission\\n /// * `fee`: The messaging fee structure containing native and LZ token fees\\n /// * `refund_address`: Address to receive any excess fees\\n ///\\n /// # Returns\\n ///\\n /// * `MessageReceipt`: Receipt containing transaction details and message information\\n fn _lz_send(\\n ref self: ComponentState<TContractState>,\\n caller: ContractAddress,\\n dst_eid: u32,\\n message: ByteArray,\\n options: ByteArray,\\n fee: MessagingFee,\\n refund_address: ContractAddress,\\n ) -> MessageReceipt {\\n let contract_address = get_contract_address();\\n let endpoint = self.OAppCore_endpoint.read();\\n self._pay_native(caller, endpoint, contract_address, fee.native_fee);\\n if fee.lz_token_fee > 0 {\\n self._pay_lz_token(caller, endpoint, contract_address, fee.lz_token_fee);\\n }\\n\\n let endpoint_dispatcher = IEndpointV2Dispatcher { contract_address: endpoint };\\n\\n endpoint_dispatcher\\n .send(\\n MessagingParams {\\n dst_eid,\\n receiver: self._get_peer_or_revert(dst_eid),\\n message,\\n options,\\n pay_in_lz_token: fee.lz_token_fee > 0,\\n },\\n refund_address,\\n )\\n }\\n\\n /// Handles payment of native token fees for message transmission\\n ///\\n /// # Arguments\\n ///\\n /// * `caller`: The address making the payment\\n /// * `endpoint`: The LayerZero endpoint address\\n /// * `contract_address`: This contract's address\\n /// * `fee`: The amount of native tokens to pay\\n fn _pay_native(\\n ref self: ComponentState<TContractState>,\\n caller: ContractAddress,\\n endpoint: ContractAddress,\\n contract_address: ContractAddress,\\n fee: u256,\\n ) {\\n let native_token_address = self.OAppCore_native_token.read();\\n // Check if enough native fee is sent\\n let native_token_dispatcher = IERC20Dispatcher {\\n contract_address: native_token_address,\\n };\\n let balance = native_token_dispatcher.balance_of(caller);\\n assert_with_byte_array(balance >= fee, err_not_enough_native(fee, balance));\\n if caller != contract_address {\\n let allowance = native_token_dispatcher.allowance(caller, contract_address);\\n assert_with_byte_array(\\n allowance >= fee, err_not_enough_native_allowance(fee, allowance),\\n );\\n }\\n\\n self._pay_in_token(caller, endpoint, contract_address, fee, native_token_address);\\n }\\n\\n /// Handles payment of LayerZero token fees for message transmission\\n ///\\n /// # Arguments\\n ///\\n /// * `caller`: The address making the payment\\n /// * `endpoint`: The LayerZero endpoint address\\n /// * `contract_address`: This contract's address\\n /// * `fee`: The amount of LZ tokens to pay\\n fn _pay_lz_token(\\n ref self: ComponentState<TContractState>,\\n caller: ContractAddress,\\n endpoint: ContractAddress,\\n contract_address: ContractAddress,\\n fee: u256,\\n ) {\\n let endpoint_dispatcher = IEndpointV2Dispatcher { contract_address: endpoint };\\n let lz_token_address = endpoint_dispatcher.get_lz_token();\\n assert_with_byte_array(lz_token_address != Zero::zero(), err_lz_token_unavailable());\\n\\n // Check if enough lz token fee is sent\\n let lz_dispatcher = IERC20Dispatcher { contract_address: lz_token_address };\\n let balance = lz_dispatcher.balance_of(caller);\\n assert_with_byte_array(balance >= fee, err_not_enough_lz_token(fee, balance));\\n if caller != contract_address {\\n let allowance = lz_dispatcher.allowance(caller, contract_address);\\n assert_with_byte_array(\\n allowance >= fee, err_not_enough_lz_token_allowance(fee, allowance),\\n );\\n }\\n self._pay_in_token(caller, endpoint, contract_address, fee, lz_token_address);\\n }\\n\\n /// Internal function responsible for transferring tokens from caller to OApp\\n /// and approving the endpoint to spend the tokens\\n ///\\n /// # Arguments\\n ///\\n /// * `caller`: The address making the payment\\n /// * `endpoint`: The LayerZero endpoint address that needs approval\\n /// * `contract_address`: This contract's address (recipient of the transfer)\\n /// * `fee`: The amount of tokens to transfer and approve\\n /// * `token_address`: The address of the token contract\\n fn _pay_in_token(\\n ref self: ComponentState<TContractState>,\\n caller: ContractAddress,\\n endpoint: ContractAddress,\\n contract_address: ContractAddress,\\n fee: u256,\\n token_address: ContractAddress,\\n ) {\\n let token_dispatcher = IERC20Dispatcher { contract_address: token_address };\\n\\n if caller != contract_address {\\n let success = token_dispatcher.transfer_from(caller, contract_address, fee);\\n assert_with_byte_array(success, err_transfer_failed());\\n }\\n\\n let success = token_dispatcher.approve(endpoint, fee);\\n assert_with_byte_array(success, err_approval_failed());\\n }\\n }\\n\\n /// =============================== Internal Functions =================================\\n #[generate_trait]\\n pub impl InternalImpl<\\n TContractState,\\n +HasComponent<TContractState>,\\n impl Ownable: OwnableComponent::HasComponent<TContractState>,\\n > of InternalTrait<TContractState> {\\n /// Initialize the OApp component with the LayerZero endpoint address\\n /// This should be called during contract deployment\\n ///\\n /// # Arguments\\n ///\\n /// * `endpoint`: The LayerZero endpoint contract address\\n fn initializer(\\n ref self: ComponentState<TContractState>,\\n endpoint: ContractAddress,\\n delegate: ContractAddress,\\n native_token: ContractAddress,\\n ) {\\n self.OAppCore_endpoint.write(endpoint);\\n self.OAppCore_native_token.write(native_token);\\n\\n assert_with_byte_array(delegate.is_non_zero(), err_invalid_delegate());\\n\\n IEndpointV2Dispatcher { contract_address: endpoint }.set_delegate(delegate)\\n }\\n\\n /// Restricts function access to only the LayerZero endpoint contract\\n /// Used to ensure that only the endpoint can call certain functions like lz_receive\\n fn _assert_only_endpoint(self: @ComponentState<TContractState>) {\\n let caller = get_caller_address();\\n let endpoint = self.OAppCore_endpoint.read();\\n assert_with_byte_array(caller == endpoint, err_only_endpoint(endpoint));\\n }\\n\\n /// Restricts function access to only the contract owner\\n /// Delegates to the OpenZeppelin Ownable component for ownership checks\\n fn _assert_only_owner(self: @ComponentState<TContractState>) {\\n get_dep_component!(self, Ownable).assert_only_owner();\\n }\\n\\n /// Internal function to get the peer address associated with a specific endpoint\\n /// Reverts if the peer is not set (i.e. the peer is set to Bytes32 { value: 0 })\\n ///\\n /// # Arguments\\n ///\\n /// * `eid`: The endpoint ID to look up\\n ///\\n /// # Returns\\n ///\\n /// * `Bytes32`: The peer address associated with the specified endpoint\\n fn _get_peer_or_revert(self: @ComponentState<TContractState>, eid: u32) -> Bytes32 {\\n let peer = self.OAppCore_peers.entry(eid).read();\\n assert_with_byte_array(peer.value != 0, err_no_peer(eid));\\n peer\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oft/errors.cairo\": \"//! OFT errors\\n\\nuse lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum OFTCoreError {\\n InvalidLocalDecimals,\\n SlippageExceeded,\\n AmountSDOverflowed,\\n OFTTransferFailed,\\n}\\n\\nimpl ErrorNameImpl of Error<OFTCoreError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_OFT_CORE\\\"\\n }\\n\\n fn name(self: OFTCoreError) -> ByteArray {\\n match self {\\n OFTCoreError::InvalidLocalDecimals => \\\"INVALID_LOCAL_DECIMALS\\\",\\n OFTCoreError::SlippageExceeded => \\\"SLIPPAGE_EXCEEDED\\\",\\n OFTCoreError::AmountSDOverflowed => \\\"AMOUNT_SD_OVERFLOWED\\\",\\n OFTCoreError::OFTTransferFailed => \\\"OFT_TRANSFER_FAILED\\\",\\n }\\n }\\n}\\n\\npub fn err_invalid_local_decimals(local_decimals: u8, shared_decimals: u8) -> ByteArray {\\n format_error(\\n OFTCoreError::InvalidLocalDecimals,\\n format!(\\\"local_decimals: {}, shared_decimals: {}\\\", local_decimals, shared_decimals),\\n )\\n}\\n\\npub fn err_slippage_exceeded(amount_received_ld: u256, min_amount_ld: u256) -> ByteArray {\\n format_error(\\n OFTCoreError::SlippageExceeded,\\n format!(\\\"amount_received_ld: {}, min_amount_ld: {}\\\", amount_received_ld, min_amount_ld),\\n )\\n}\\n\\npub fn err_amount_sd_overflowed(amount_sd: u256) -> ByteArray {\\n format_error(OFTCoreError::AmountSDOverflowed, format!(\\\"amount_sd: {}\\\", amount_sd))\\n}\\n\\npub fn err_oft_transfer_failed() -> ByteArray {\\n format_error(OFTCoreError::OFTTransferFailed, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oft/events.cairo\": \"//! OFT events\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\n\\n#[derive(Drop, starknet::Event)]\\npub struct OFTSent {\\n #[key]\\n pub guid: Bytes32,\\n #[key]\\n pub dst_eid: u32,\\n #[key]\\n pub from: ContractAddress,\\n pub amount_sent_ld: u256,\\n pub amount_received_ld: u256,\\n}\\n\\n#[derive(Drop, starknet::Event)]\\npub struct OFTReceived {\\n #[key]\\n pub guid: Bytes32,\\n #[key]\\n pub src_eid: u32,\\n #[key]\\n pub to: ContractAddress,\\n pub amount_received_ld: u256,\\n}\\n\\n#[derive(Drop, starknet::Event)]\\npub struct MsgInspectorSet {\\n #[key]\\n pub msg_inspector: ContractAddress,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oft/interface.cairo\": \"//! OFT interface\\n\\nuse starknet::ContractAddress;\\nuse crate::common::structs::messaging::MessagingFee;\\nuse crate::oapps::oft::structs::{OFTQuote, OFTSendResult, OFTVersion, SendParam};\\n\\n/// IOFT defines the complete interface for Omnichain Fungible Token communication.\\n/// This interface provides comprehensive OFT functionality including quotes, limits, and receipts.\\n#[starknet::interface]\\npub trait IOFT<TContractState> {\\n /// Retrieves interfaceID and the version of the OFT.\\n ///\\n /// Returns:\\n /// - OFTVersion: Contains interface_id and version\\n ///\\n /// The interface ID is '1' and version indicates onchain interface version.\\n /// The version is 1 and indicates cross-chain compatibility.\\n fn oft_version(self: @TContractState) -> OFTVersion;\\n\\n /// Retrieves the address of the token associated with the OFT.\\n ///\\n /// Returns the address of the ERC20 token implementation.\\n fn token(self: @TContractState) -> ContractAddress;\\n\\n /// Indicates whether the OFT contract requires approval of the 'token()' to send.\\n ///\\n /// Returns true if approval of the underlying token implementation is required.\\n /// Allows things like wallet implementers to determine integration requirements.\\n fn approval_required(self: @TContractState) -> bool;\\n\\n /// Retrieves the shared decimals of the OFT.\\n ///\\n /// Returns the shared decimals of the OFT.\\n fn shared_decimals(self: @TContractState) -> u8;\\n\\n /// Retrieves the decimal conversion rate of the OFT.\\n ///\\n /// Returns the decimal conversion rate of the OFT.\\n fn decimal_conversion_rate(self: @TContractState) -> u256;\\n\\n /// Retrieves the address of the msg inspector.\\n ///\\n /// Returns the address of the msg inspector.\\n fn msg_inspector(self: @TContractState) -> ContractAddress;\\n\\n /// Sets the address of the msg inspector.\\n ///\\n /// Args:\\n /// - `msg_inspector`: The address of the msg inspector\\n fn set_msg_inspector(ref self: TContractState, msg_inspector: ContractAddress);\\n\\n /// Provides a quote for OFT-related operations.\\n ///\\n /// Args:\\n /// - `send_param`: The parameters for the send operation\\n ///\\n /// Returns:\\n /// - OFTQuote: Contains limit, oft_fee_details, and receipt\\n fn quote_oft(self: @TContractState, send_param: SendParam) -> OFTQuote;\\n\\n /// Provides a quote for the send() operation.\\n ///\\n /// Args:\\n /// - `send_param`: The parameters for the send() operation\\n /// - `pay_in_lz_token`: Flag indicating whether the caller is paying in the LZ token\\n ///\\n /// Returns the calculated LayerZero messaging fee from the send() operation.\\n fn quote_send(\\n self: @TContractState, send_param: SendParam, pay_in_lz_token: bool,\\n ) -> MessagingFee;\\n\\n /// Executes the send() operation.\\n ///\\n /// Args:\\n /// - `send_param`: The parameters for the send operation\\n /// - `fee`: The fee information supplied by the caller\\n /// - `refund_address`: The address to receive any excess funds from fees etc. on the src\\n ///\\n /// Returns:\\n /// - OFTSendResult: Contains message_receipt and oft_receipt\\n fn send(\\n ref self: TContractState,\\n send_param: SendParam,\\n fee: MessagingFee,\\n refund_address: ContractAddress,\\n ) -> OFTSendResult;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oft/oft_compose_msg_codec.cairo\": \"/// OFTComposeMsgCodec - Cairo implementation of the Solidity OFTComposeMsgCodec library\\n/// Handles encoding and decoding of OFT composed messages\\npub mod OFTComposeMsgCodec {\\n use lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\n use lz_utils::bytes::Bytes32;\\n use starknet::ContractAddress;\\n\\n // Offset constants for encoding and decoding OFT compose messages\\n pub const NONCE_OFFSET: usize = 8;\\n pub const SRC_EID_OFFSET: usize = 12;\\n pub const AMOUNT_LD_OFFSET: usize = 44;\\n pub const COMPOSE_FROM_OFFSET: usize = 76;\\n\\n /// Encodes an OFT composed message.\\n ///\\n /// # Arguments\\n /// * `nonce` - The nonce value (u64)\\n /// * `src_eid` - The source endpoint ID (u32)\\n /// * `amount_ld` - The amount in local decimals (u256)\\n /// * `compose_msg` - The composed message (composeFrom + composeMsg)\\n ///\\n /// # Returns\\n /// * `ByteArray` - The encoded composed message\\n pub fn encode(nonce: u64, src_eid: u32, amount_ld: u256, compose_msg: @ByteArray) -> ByteArray {\\n let mut message: ByteArray = Default::default();\\n\\n // Encode nonce (8 bytes)\\n message.append_u64(nonce);\\n\\n // Encode src_eid (4 bytes)\\n message.append_u32(src_eid);\\n\\n // Encode amount_ld (32 bytes)\\n message.append_u256(amount_ld);\\n\\n // Append compose message\\n message.append(compose_msg);\\n\\n message\\n }\\n\\n /// Retrieves the nonce from the composed message.\\n ///\\n /// # Arguments\\n /// * `message` - The composed message\\n ///\\n /// # Returns\\n /// * `u64` - The nonce value\\n pub fn nonce(message: @ByteArray) -> u64 {\\n let (_, nonce_value) = message.read_u64(0);\\n nonce_value\\n }\\n\\n /// Retrieves the source endpoint ID from the composed message.\\n ///\\n /// # Arguments\\n /// * `message` - The composed message\\n ///\\n /// # Returns\\n /// * `u32` - The source endpoint ID\\n pub fn src_eid(message: @ByteArray) -> u32 {\\n let (_, src_eid_value) = message.read_u32(NONCE_OFFSET);\\n src_eid_value\\n }\\n\\n /// Retrieves the amount in local decimals from the composed message.\\n ///\\n /// # Arguments\\n /// * `message` - The composed message\\n ///\\n /// # Returns\\n /// * `u256` - The amount in local decimals\\n pub fn amount_ld(message: @ByteArray) -> u256 {\\n let (_, amount_value) = message.read_u256(SRC_EID_OFFSET);\\n amount_value\\n }\\n\\n /// Retrieves the composeFrom value from the composed message.\\n ///\\n /// # Arguments\\n /// * `message` - The composed message\\n ///\\n /// # Returns\\n /// * `Bytes32` - The composeFrom value\\n pub fn compose_from(message: @ByteArray) -> Bytes32 {\\n let (_, compose_from_value) = message.read_u256(AMOUNT_LD_OFFSET);\\n Bytes32 { value: compose_from_value }\\n }\\n\\n /// Retrieves the composed message.\\n ///\\n /// # Arguments\\n /// * `message` - The full composed message\\n ///\\n /// # Returns\\n /// * `ByteArray` - The composed message portion\\n pub fn compose_msg(message: @ByteArray) -> ByteArray {\\n if message.len() > COMPOSE_FROM_OFFSET {\\n let compose_length = message.len() - COMPOSE_FROM_OFFSET;\\n let (_, compose_value) = message.read_bytes(COMPOSE_FROM_OFFSET, compose_length);\\n compose_value\\n } else {\\n Default::default()\\n }\\n }\\n\\n /// Converts a ContractAddress to Bytes32.\\n ///\\n /// # Arguments\\n /// * `addr` - The address to convert\\n ///\\n /// # Returns\\n /// * `Bytes32` - The bytes32 representation\\n pub fn address_to_bytes32(addr: ContractAddress) -> Bytes32 {\\n addr.into()\\n }\\n\\n /// Converts Bytes32 to a ContractAddress.\\n ///\\n /// # Arguments\\n /// * `b` - The bytes32 value to convert\\n ///\\n /// # Returns\\n /// * `Option<ContractAddress>` - The address if valid\\n pub fn bytes32_to_address(b: Bytes32) -> Option<ContractAddress> {\\n b.try_into()\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oft/oft_core/default_oapp_hooks.cairo\": \"//! Default implementation of OApp hooks\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::OAppCoreComponent::OAppHooks;\\nuse crate::oapps::oft::oft_core::oft_core::OFTCoreComponent;\\nuse crate::oapps::oft::oft_core::oft_core::OFTCoreComponent::OFTHooks;\\nuse crate::{OAppCoreComponent, Origin};\\n\\n/// Default implementation of the OApp hooks\\npub impl OFTCoreOAppHooksDefaultImpl<\\n TContractState,\\n +OAppCoreComponent::HasComponent<TContractState>,\\n +OFTHooks<TContractState>,\\n impl OFTCore: OFTCoreComponent::HasComponent<TContractState>,\\n impl OFTCoreInternal: OFTCoreComponent::InternalTrait<TContractState>,\\n +Drop<TContractState>,\\n> of OAppHooks<TContractState> {\\n fn _lz_receive(\\n ref self: OAppCoreComponent::ComponentState<TContractState>,\\n origin: Origin,\\n guid: Bytes32,\\n message: ByteArray,\\n executor: ContractAddress,\\n extra_data: ByteArray,\\n value: u256,\\n ) {\\n let mut contract = self.get_contract_mut();\\n let mut oft_core = OFTCore::get_component_mut(ref contract);\\n\\n OFTCoreInternal::_lz_receive(\\n ref oft_core, origin, guid, message, executor, extra_data, value,\\n );\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oft/oft_core/default_oft_hooks.cairo\": \"//! Default implementation of OFT hooks\\n\\nuse core::num::traits::Zero;\\nuse openzeppelin::token::erc20::ERC20Component;\\nuse starknet::ContractAddress;\\nuse crate::OAppCoreComponent;\\nuse crate::common::constants::DEAD_ADDRESS;\\nuse crate::oapps::oft::oft_core::oft_core::OFTCoreComponent;\\nuse crate::oapps::oft::structs::OFTDebit;\\n\\npub impl OFTCoreOFTHooksDefaultImpl<\\n TContractState,\\n +OAppCoreComponent::HasComponent<TContractState>,\\n impl OFTCore: OFTCoreComponent::HasComponent<TContractState>,\\n +ERC20Component::ERC20HooksTrait<TContractState>,\\n impl ERC20: ERC20Component::HasComponent<TContractState>,\\n impl ERC20Internal: ERC20Component::InternalTrait<TContractState>,\\n +Drop<TContractState>,\\n> of OFTCoreComponent::OFTHooks<TContractState> {\\n fn _debit(\\n ref self: OFTCoreComponent::ComponentState<TContractState>,\\n from: ContractAddress,\\n amount: u256,\\n min_amount: u256,\\n dst_eid: u32,\\n ) -> OFTDebit {\\n let mut contract = self.get_contract_mut();\\n let oft_core = OFTCore::get_component(@contract);\\n let oft_debit = Self::_debit_view(oft_core, amount, min_amount, dst_eid);\\n\\n // Burn tokens from sender\\n let mut erc20 = ERC20::get_component_mut(ref contract);\\n ERC20Internal::burn(ref erc20, from, oft_debit.amount_sent_ld);\\n\\n oft_debit\\n }\\n\\n fn _credit(\\n ref self: OFTCoreComponent::ComponentState<TContractState>,\\n to: ContractAddress,\\n amount: u256,\\n src_eid: u32,\\n ) -> u256 {\\n // Handle the zero address case\\n let recipient = if to.is_zero() {\\n DEAD_ADDRESS\\n } else {\\n to\\n };\\n\\n // Mint tokens to recipient\\n let mut contract = self.get_contract_mut();\\n let mut erc20 = ERC20::get_component_mut(ref contract);\\n ERC20Internal::mint(ref erc20, recipient, amount);\\n\\n // Return the actual amount received (same as input in default implementation)\\n amount\\n }\\n\\n fn _token(self: @OFTCoreComponent::ComponentState<TContractState>) -> ContractAddress {\\n starknet::get_contract_address()\\n }\\n\\n fn _approval_required(self: @OFTCoreComponent::ComponentState<TContractState>) -> bool {\\n false\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oft/oft_core/oft_core.cairo\": \"//! OFT core component implementation\\n\\n#[starknet::component]\\npub mod OFTCoreComponent {\\n use core::num::traits::{Pow, Zero};\\n use lz_utils::bytes::Bytes32;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::access::ownable::OwnableComponent::{\\n InternalImpl as OwnableInternalImpl, InternalTrait as OwnableInternalTrait,\\n };\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};\\n use starknet::{ContractAddress, get_caller_address};\\n use crate::Origin;\\n use crate::common::structs::messaging::MessagingFee;\\n use crate::endpoint::messaging_composer::interface::{\\n IMessagingComposerDispatcher, IMessagingComposerDispatcherTrait,\\n };\\n use crate::oapps::common::oapp_options_type_3::interface::IOAppOptionsType3;\\n use crate::oapps::common::oapp_options_type_3::oapp_options_type_3::OAppOptionsType3Component;\\n use crate::oapps::message_inspector::interface::{\\n IMessageInspectorDispatcher, IMessageInspectorDispatcherTrait,\\n };\\n use crate::oapps::oapp::oapp_core::OAppCoreComponent;\\n use crate::oapps::oft::errors::{\\n err_amount_sd_overflowed, err_invalid_local_decimals, err_slippage_exceeded,\\n };\\n use crate::oapps::oft::events::{MsgInspectorSet, OFTReceived, OFTSent};\\n use crate::oapps::oft::interface::IOFT;\\n use crate::oapps::oft::oft_compose_msg_codec::OFTComposeMsgCodec;\\n use crate::oapps::oft::oft_msg_codec::OFTMsgCodec;\\n use crate::oapps::oft::structs::{\\n OFTDebit, OFTLimit, OFTMsgAndOptions, OFTQuote, OFTReceipt, OFTSendResult, OFTVersion,\\n SendParam,\\n };\\n\\n // Constants\\n pub const SEND: u16 = 1;\\n pub const SEND_AND_CALL: u16 = 2;\\n\\n #[storage]\\n pub struct Storage {\\n pub OFTCore_decimal_conversion_rate: u256,\\n pub OFTCore_msg_inspector: ContractAddress,\\n pub OFTCore_shared_decimals: u8,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n OFTSent: OFTSent,\\n OFTReceived: OFTReceived,\\n MsgInspectorSet: MsgInspectorSet,\\n }\\n\\n // =============================== Traits =================================\\n\\n /// Hooks for the OFT (Omnichain Fungible Token) contract\\n ///\\n /// These hooks define the core token operations that must be implemented by any OFT contract.\\n /// They handle the actual token transfers, metadata, and approval requirements for cross-chain\\n /// operations.\\n pub trait OFTHooks<TContractState> {\\n /// Debits tokens from the sender's account when initiating a cross-chain transfer\\n ///\\n /// This function is called when a user sends tokens to another chain. It should:\\n /// - Remove the specified amount from the sender's balance\\n /// - Apply any fees or dust removal as needed\\n /// - Validate that the minimum amount requirements are met\\n /// - Return the actual amounts that were debited and will be received\\n ///\\n /// # Arguments\\n /// * `from` - The address to debit tokens from (typically the caller)\\n /// * `amount` - The amount of tokens to debit (in local decimals)\\n /// * `min_amount` - The minimum amount that must be received after fees/dust removal\\n /// * `dst_eid` - The destination endpoint ID where tokens are being sent\\n ///\\n /// # Returns\\n /// * `(amount_sent_ld, amount_received_ld)` - Tuple of actual amount debited and amount\\n /// that will be received\\n fn _debit(\\n ref self: ComponentState<TContractState>,\\n from: ContractAddress,\\n amount: u256,\\n min_amount: u256,\\n dst_eid: u32,\\n ) -> OFTDebit;\\n\\n /// Credits tokens to the recipient's account when receiving a cross-chain transfer\\n ///\\n /// This function is called when tokens arrive from another chain. It should:\\n /// - Add the specified amount to the recipient's balance\\n /// - Handle any minting or token release logic as appropriate\\n /// - Return the actual amount that was credited (may differ from input due to fees)\\n ///\\n /// # Arguments\\n /// * `to` - The address to credit tokens to\\n /// * `amount` - The amount of tokens to credit (in local decimals)\\n /// * `src_eid` - The source endpoint ID where tokens came from\\n ///\\n /// # Returns\\n /// * `amount_received_ld` - The actual amount credited to the recipient's account\\n fn _credit(\\n ref self: ComponentState<TContractState>,\\n to: ContractAddress,\\n amount: u256,\\n src_eid: u32,\\n ) -> u256;\\n\\n /// Returns the underlying token contract address\\n ///\\n /// For adapter OFTs, this returns the address of the existing ERC20 token.\\n /// For native OFTs, this typically returns the OFT contract's own address.\\n ///\\n /// # Returns\\n /// * `ContractAddress` - The address of the underlying token contract\\n fn _token(self: @ComponentState<TContractState>) -> ContractAddress;\\n\\n /// Indicates whether the OFT requires token approval before transfers\\n ///\\n /// Returns true if users must approve the OFT contract to spend their tokens\\n /// before calling send(). This is typically true for adapter OFTs that wrap\\n /// existing tokens, and false for native OFTs where the contract owns the tokens.\\n ///\\n /// # Returns\\n /// * `bool` - True if approval is required, false otherwise\\n fn _approval_required(self: @ComponentState<TContractState>) -> bool;\\n\\n /// Internal function to remove dust from the given local decimal amount\\n ///\\n /// Note: this is the default and can be overridden in the implementation.\\n ///\\n /// Prevents the loss of dust when moving amounts between chains with different decimals.\\n ///\\n /// # Arguments\\n /// * `amount_ld` - The amount in local decimals\\n ///\\n /// # Returns\\n /// * `u256` - The amount after removing dust\\n ///\\n /// # Example\\n /// uint(123) with a conversion rate of 100 becomes uint(100)\\n fn _remove_dust(\\n self: @ComponentState<TContractState>, amount_ld: u256,\\n ) -> u256 {\\n let conversion_rate = self.OFTCore_decimal_conversion_rate.read();\\n (amount_ld / conversion_rate) * conversion_rate\\n }\\n\\n /// Internal function to mock the amount mutation from a OFT debit() operation\\n ///\\n /// Note: this is the default and can be overridden in the implementation.\\n ///\\n /// This is where things like fees would be calculated and deducted from the amount to be\\n /// received on the remote.\\n ///\\n /// # Arguments\\n /// * `amount_ld` - The amount to send in local decimals\\n /// * `min_amount_ld` - The minimum amount to send in local decimals\\n /// * `dst_eid` - The destination endpoint ID\\n ///\\n /// # Returns\\n /// * `(u256, u256)` - Tuple of (amount_sent_ld, amount_received_ld)\\n /// - amount_sent_ld: The amount sent, in local decimals\\n /// - amount_received_ld: The amount to be received on the remote chain, in local decimals\\n ///\\n /// # Panics\\n /// * If `amount_received_ld` is less than `min_amount_ld` (slippage exceeded)\\n fn _debit_view(\\n self: @ComponentState<TContractState>,\\n amount_ld: u256,\\n min_amount_ld: u256,\\n dst_eid: u32,\\n ) -> OFTDebit {\\n // Removes the dust so nothing is lost on the conversion between chains with different\\n // decimals for the token.\\n let amount_sent_ld = Self::_remove_dust(self, amount_ld);\\n // The amount to send is the same as amount received in the default implementation.\\n let amount_received_ld = amount_sent_ld;\\n\\n // Check for slippage\\n assert_with_byte_array(\\n amount_received_ld >= min_amount_ld,\\n err_slippage_exceeded(amount_received_ld, min_amount_ld),\\n );\\n\\n OFTDebit { amount_sent_ld, amount_received_ld }\\n }\\n\\n /// Returns the OFT version\\n ///\\n /// # Returns\\n /// * `OFTVersion` - The OFT version\\n /// * `interface_id` - The OFT onchain interface ID\\n /// * `version` - The OFT version compatible cross-chain\\n fn _oft_version(\\n self: @ComponentState<TContractState>,\\n ) -> OFTVersion {\\n OFTVersion { interface_id: 1, // Standard OFT interface ID\\n version: 1_u64 }\\n }\\n }\\n\\n #[generate_trait]\\n pub impl InternalImpl<\\n TContractState, +HasComponent<TContractState>,\\n > of InternalTrait<TContractState> {\\n /// Initializes the OFT Core component with decimal configuration\\n ///\\n /// Provides a conversion rate when swapping between denominations of SD and LD:\\n /// - shareDecimals == SD == shared Decimals\\n /// - localDecimals == LD == local decimals\\n ///\\n /// Considers that tokens have different decimal amounts on various chains.\\n /// For a token:\\n /// - locally with 4 decimals --> 1.2345 => uint(12345)\\n /// - remotely with 2 decimals --> 1.23 => uint(123)\\n /// - The conversion rate would be 10 ** (4 - 2) = 100\\n ///\\n /// If you want to send 1.2345 -> (uint 12345), you CANNOT represent that value on the\\n /// remote, you can only display 1.23 -> uint(123).\\n /// To preserve the dust that would otherwise be lost on that conversion,\\n /// we need to unify a denomination that can be represented on ALL chains inside of the OFT\\n /// mesh.\\n ///\\n /// # Arguments\\n /// * `local_decimals` - The decimals of the token on the local chain (this chain)\\n ///\\n /// # Panics\\n /// * If `local_decimals` is less than `shared_decimals` (would cause precision loss)\\n fn initializer(\\n ref self: ComponentState<TContractState>, local_decimals: u8, shared_decimals: u8,\\n ) {\\n self.OFTCore_shared_decimals.write(shared_decimals);\\n\\n assert_with_byte_array(\\n local_decimals >= shared_decimals,\\n err_invalid_local_decimals(local_decimals, shared_decimals),\\n );\\n\\n // Calculate decimal conversion rate\\n let decimals_diff = local_decimals - shared_decimals;\\n let conversion_rate = 10_u256.pow(decimals_diff.into());\\n self.OFTCore_decimal_conversion_rate.write(conversion_rate);\\n }\\n\\n /// Internal function to handle the receive on the LayerZero endpoint\\n ///\\n /// The src sending chain doesn't know the address length on this chain (potentially\\n /// non-evm)\\n /// thus everything is bytes32() encoded in flight.\\n /// Credits the amountLD to the recipient and returns the ACTUAL amount the recipient\\n /// received in local decimals.\\n ///\\n /// # Arguments\\n /// * `origin` - The origin information containing:\\n /// - src_eid: The source chain endpoint ID\\n /// - sender: The sender address from the src chain\\n /// - nonce: The nonce of the LayerZero message\\n /// * `guid` - The unique identifier for the received LayerZero message\\n /// * `message` - The encoded message\\n /// * `executor` - The address of the executor (unused in the default implementation)\\n /// * `value` - Native token value sent with the message (unused in the default\\n /// implementation)\\n /// * `extra_data` - Additional data (unused in the default implementation)\\n fn _lz_receive<\\n impl OFTHooks: OFTHooks<TContractState>,\\n impl OAppCore: OAppCoreComponent::HasComponent<TContractState>,\\n >(\\n ref self: ComponentState<TContractState>,\\n origin: Origin,\\n guid: Bytes32,\\n message: ByteArray,\\n executor: ContractAddress,\\n extra_data: ByteArray,\\n value: u256,\\n ) {\\n let Origin { src_eid, nonce, .. } = origin;\\n\\n // Decode the OFT message\\n let to_bytes32 = OFTMsgCodec::send_to(@message);\\n let amount_sd = OFTMsgCodec::amount_sd(@message);\\n\\n // Convert to local decimals\\n let amount_ld = self._to_ld(amount_sd);\\n\\n // Convert recipient from bytes32 to address\\n let to_address = OFTMsgCodec::bytes32_to_address(to_bytes32).unwrap();\\n\\n let amount_received_ld = self._credit(to_address, amount_ld, src_eid);\\n\\n // Handle compose messages - Proprietary composeMsg format for the OFT\\n if OFTMsgCodec::is_composed(@message) {\\n let compose_msg = OFTMsgCodec::compose_msg(@message);\\n\\n let endpoint_dispatcher = IMessagingComposerDispatcher {\\n contract_address: get_dep_component!(@self, OAppCore).OAppCore_endpoint.read(),\\n };\\n\\n // Stores the lz_compose payload that will be executed in a separate tx.\\n // Standardizes functionality for executing arbitrary contract invocation on some\\n // non-evm chains.\\n // The off-chain executor will listen and process the msg based on the\\n // src-chain-callers compose options passed.\\n // The index is used when a OApp needs to compose multiple msgs on lzReceive.\\n // For default OFT implementation there is only 1 compose msg per lzReceive, thus\\n // its always 0.\\n endpoint_dispatcher\\n .send_compose(\\n to_address,\\n guid,\\n 0,\\n OFTComposeMsgCodec::encode(\\n nonce, src_eid, amount_received_ld, @compose_msg,\\n ),\\n );\\n }\\n\\n self.emit(OFTReceived { guid, src_eid, to: to_address, amount_received_ld });\\n }\\n\\n /// Internal function to convert an amount from shared decimals into local decimals\\n ///\\n /// # Arguments\\n /// * `amount_sd` - The amount in shared decimals\\n ///\\n /// # Returns\\n /// * `u256` - The amount in local decimals\\n fn _to_ld(self: @ComponentState<TContractState>, amount_sd: u64) -> u256 {\\n let conversion_rate = self.OFTCore_decimal_conversion_rate.read();\\n amount_sd.into() * conversion_rate\\n }\\n\\n /// Internal function to convert an amount from local decimals into shared decimals\\n ///\\n /// # Arguments\\n /// * `amount_ld` - The amount in local decimals\\n ///\\n /// # Returns\\n /// * `u64` - The amount in shared decimals\\n fn _to_sd(self: @ComponentState<TContractState>, amount_ld: u256) -> u64 {\\n let conversion_rate = self.OFTCore_decimal_conversion_rate.read();\\n let amount_sd_u256 = amount_ld / conversion_rate;\\n let converted = amount_sd_u256.try_into();\\n assert_with_byte_array(converted.is_some(), err_amount_sd_overflowed(amount_sd_u256));\\n converted.unwrap()\\n }\\n\\n\\n /// Internal function to build the message and options\\n ///\\n /// This generated message has the msg.sender encoded into the payload so the remote knows\\n /// who the caller is.\\n /// Must include a non empty bytes if you want to compose, EVEN if you don't need it on the\\n /// remote.\\n /// EVEN if you don't require an arbitrary payload to be sent... eg. '0x01'\\n /// Changes the msg type depending if it's composed or not.\\n /// Combines the caller's _extraOptions with the enforced options via the OAppOptionsType3.\\n ///\\n /// # Arguments\\n /// * `send_param` - The parameters for the send() operation\\n /// * `amount_ld` - The amount in local decimals\\n ///\\n /// # Returns\\n /// * `(ByteArray, ByteArray)` - Tuple of (message, options)\\n /// - message: The encoded message\\n /// - options: The encoded options\\n fn _build_msg_and_options<\\n impl Ownable: OwnableComponent::HasComponent<TContractState>,\\n impl OAppOptionsType3: OAppOptionsType3Component::HasComponent<TContractState>,\\n >(\\n self: @ComponentState<TContractState>, send_param: @SendParam, amount_ld: u256,\\n ) -> OFTMsgAndOptions {\\n let SendParam { to, compose_msg, extra_options, dst_eid, .. } = send_param;\\n\\n // Convert amount to shared decimals\\n let amount_sd = self._to_sd(amount_ld);\\n\\n // Encode OFT message\\n let (message, has_compose) = OFTMsgCodec::encode(*to, amount_sd, compose_msg);\\n\\n let msg_type = if has_compose {\\n SEND_AND_CALL\\n } else {\\n SEND\\n };\\n\\n let oapp_options_type_3 = get_dep_component!(self, OAppOptionsType3);\\n let options = oapp_options_type_3\\n .combine_options(*dst_eid, msg_type, extra_options.clone());\\n\\n // Optionally inspect the message and options depending\\n // if the OApp owner has set a msg inspector.\\n // If it fails inspection, needs to revert in the implementation.\\n // ie. does not rely on return boolean\\n let msg_inspector = self.OFTCore_msg_inspector.read();\\n if !msg_inspector.is_zero() {\\n let inspector_dispatcher = IMessageInspectorDispatcher {\\n contract_address: msg_inspector,\\n };\\n inspector_dispatcher.inspect_msg(message.clone(), options.clone());\\n }\\n\\n OFTMsgAndOptions { message, options }\\n }\\n }\\n\\n #[embeddable_as(OFTCoreImpl)]\\n impl OFT<\\n TContractState,\\n +HasComponent<TContractState>,\\n +OFTHooks<TContractState>,\\n impl Ownable: OwnableComponent::HasComponent<TContractState>,\\n impl OAppCore: OAppCoreComponent::HasComponent<TContractState>,\\n +OAppOptionsType3Component::HasComponent<TContractState>,\\n +Drop<TContractState>,\\n > of IOFT<ComponentState<TContractState>> {\\n fn oft_version(self: @ComponentState<TContractState>) -> OFTVersion {\\n self._oft_version()\\n }\\n\\n fn token(self: @ComponentState<TContractState>) -> ContractAddress {\\n self._token()\\n }\\n\\n fn approval_required(self: @ComponentState<TContractState>) -> bool {\\n self._approval_required()\\n }\\n\\n fn shared_decimals(self: @ComponentState<TContractState>) -> u8 {\\n self.OFTCore_shared_decimals.read()\\n }\\n\\n fn decimal_conversion_rate(self: @ComponentState<TContractState>) -> u256 {\\n self.OFTCore_decimal_conversion_rate.read()\\n }\\n\\n fn set_msg_inspector(\\n ref self: ComponentState<TContractState>, msg_inspector: ContractAddress,\\n ) {\\n get_dep_component!(@self, Ownable).assert_only_owner();\\n\\n self.OFTCore_msg_inspector.write(msg_inspector);\\n self.emit(MsgInspectorSet { msg_inspector });\\n }\\n\\n fn msg_inspector(self: @ComponentState<TContractState>) -> ContractAddress {\\n self.OFTCore_msg_inspector.read()\\n }\\n\\n fn quote_oft(self: @ComponentState<TContractState>, send_param: SendParam) -> OFTQuote {\\n let SendParam { dst_eid, amount_ld, min_amount_ld, .. } = send_param;\\n\\n // Calculate amounts using debit view\\n let OFTDebit {\\n amount_sent_ld, amount_received_ld,\\n } = self._debit_view(amount_ld, min_amount_ld, dst_eid);\\n\\n // Create limit using token total supply for max amount (mirror Solidity)\\n let oft_token_dispatcher = IERC20Dispatcher {\\n contract_address: OFTHooks::_token(self),\\n };\\n let limit = OFTLimit {\\n min_amount_ld: 0, max_amount_ld: oft_token_dispatcher.total_supply(),\\n };\\n\\n // No additional fees in default implementation\\n let oft_fee_details = array![];\\n\\n // Create receipt\\n let receipt = OFTReceipt { amount_sent_ld, amount_received_ld };\\n\\n OFTQuote { limit, oft_fee_details, receipt }\\n }\\n\\n fn quote_send(\\n self: @ComponentState<TContractState>, send_param: SendParam, pay_in_lz_token: bool,\\n ) -> MessagingFee {\\n let SendParam { dst_eid, amount_ld, min_amount_ld, .. } = send_param.clone();\\n // Get the amounts that would be debited/received\\n let OFTDebit {\\n amount_received_ld, ..,\\n } = self._debit_view(amount_ld, min_amount_ld, dst_eid);\\n\\n // Build message and options\\n let OFTMsgAndOptions {\\n message, options,\\n } = self._build_msg_and_options(@send_param, amount_received_ld);\\n\\n // Quote through OApp core\\n let oapp_core = get_dep_component!(self, OAppCore);\\n OAppCoreComponent::OAppSenderImpl::_quote(\\n oapp_core, dst_eid, message, options, pay_in_lz_token,\\n )\\n }\\n\\n fn send(\\n ref self: ComponentState<TContractState>,\\n send_param: SendParam,\\n fee: MessagingFee,\\n refund_address: ContractAddress,\\n ) -> OFTSendResult {\\n let SendParam { dst_eid, amount_ld, min_amount_ld, .. } = send_param.clone();\\n let from = get_caller_address();\\n\\n // 1. Debit tokens from sender\\n let OFTDebit {\\n amount_sent_ld, amount_received_ld,\\n } =\\n OFTHooks::_debit(\\n ref self,\\n from, // from - the address calling the send function\\n amount_ld,\\n min_amount_ld,\\n dst_eid,\\n );\\n\\n // 2. Build message and options\\n let OFTMsgAndOptions {\\n message, options,\\n } = self._build_msg_and_options(@send_param, amount_received_ld);\\n\\n // 3. Send message through LayerZero endpoint\\n let mut oapp_core = get_dep_component_mut!(ref self, OAppCore);\\n let message_receipt = OAppCoreComponent::OAppSenderImpl::_lz_send(\\n ref oapp_core, from, dst_eid, message, options, fee, refund_address,\\n );\\n\\n // 4. Emit event\\n self\\n .emit(\\n OFTSent {\\n guid: message_receipt.guid,\\n dst_eid,\\n from,\\n amount_sent_ld,\\n amount_received_ld,\\n },\\n );\\n\\n // 5. Return the result\\n OFTSendResult {\\n message_receipt, oft_receipt: OFTReceipt { amount_sent_ld, amount_received_ld },\\n }\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oft/oft_msg_codec.cairo\": \"/// OFTMsgCodec - Cairo implementation of the Solidity OFTMsgCodec library\\n/// Handles encoding and decoding of OFT messages\\npub mod OFTMsgCodec {\\n use lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\n use lz_utils::bytes::Bytes32;\\n use starknet::{ContractAddress, get_caller_address};\\n\\n // Offset constants for encoding and decoding OFT messages\\n pub const SEND_TO_OFFSET: usize = 32;\\n pub const SEND_AMOUNT_SD_OFFSET: usize = 40;\\n\\n /// Encodes an OFT LayerZero message.\\n ///\\n /// # Arguments\\n /// * `send_to` - The recipient address as bytes32\\n /// * `amount_sd` - The amount in shared decimals (u64)\\n /// * `compose_msg` - The composed message\\n ///\\n /// # Returns\\n /// * `(message, has_compose)` - The encoded message and whether it has compose\\n pub fn encode(send_to: Bytes32, amount_sd: u64, compose_msg: @ByteArray) -> (ByteArray, bool) {\\n let has_compose = compose_msg.len() > 0;\\n let mut message: ByteArray = Default::default();\\n\\n // Encode send_to (32 bytes)\\n message.append_u256(send_to.value);\\n\\n // Encode amount_sd (8 bytes)\\n message.append_u64(amount_sd);\\n\\n if has_compose {\\n // For composed messages, include the caller (msg.sender equivalent)\\n let caller_bytes32: Bytes32 = get_caller_address().into();\\n message.append_u256(caller_bytes32.value);\\n message.append(compose_msg);\\n }\\n\\n (message, has_compose)\\n }\\n\\n /// Checks if the OFT message is composed.\\n ///\\n /// # Arguments\\n /// * `message` - The OFT message\\n ///\\n /// # Returns\\n /// * `bool` - True if the message is composed\\n pub fn is_composed(message: @ByteArray) -> bool {\\n message.len() > SEND_AMOUNT_SD_OFFSET\\n }\\n\\n /// Retrieves the recipient address from the OFT message.\\n ///\\n /// # Arguments\\n /// * `message` - The OFT message\\n ///\\n /// # Returns\\n /// * `Bytes32` - The recipient address\\n pub fn send_to(message: @ByteArray) -> Bytes32 {\\n let (_, send_to_value) = message.read_u256(0);\\n Bytes32 { value: send_to_value }\\n }\\n\\n /// Retrieves the amount in shared decimals from the OFT message.\\n ///\\n /// # Arguments\\n /// * `message` - The OFT message\\n ///\\n /// # Returns\\n /// * `u64` - The amount in shared decimals\\n pub fn amount_sd(message: @ByteArray) -> u64 {\\n let (_, amount_value) = message.read_u64(SEND_TO_OFFSET);\\n amount_value\\n }\\n\\n /// Retrieves the composed message from the OFT message.\\n ///\\n /// # Arguments\\n /// * `message` - The OFT message\\n ///\\n /// # Returns\\n /// * `ByteArray` - The composed message\\n pub fn compose_msg(message: @ByteArray) -> ByteArray {\\n if message.len() > SEND_AMOUNT_SD_OFFSET {\\n let compose_length = message.len() - SEND_AMOUNT_SD_OFFSET;\\n let (_, compose_value) = message.read_bytes(SEND_AMOUNT_SD_OFFSET, compose_length);\\n compose_value\\n } else {\\n Default::default()\\n }\\n }\\n\\n /// Retrieves the sender address from a composed message.\\n /// Only valid for composed messages that include sender information.\\n ///\\n /// # Arguments\\n /// * `message` - The OFT message\\n ///\\n /// # Returns\\n /// * `Option<Bytes32>` - The sender address if available\\n pub fn composed_sender(message: @ByteArray) -> Option<Bytes32> {\\n if is_composed(message) && message.len() >= SEND_AMOUNT_SD_OFFSET + SEND_TO_OFFSET {\\n let (_, sender_value) = message.read_u256(SEND_AMOUNT_SD_OFFSET);\\n Option::Some(Bytes32 { value: sender_value })\\n } else {\\n Option::None\\n }\\n }\\n\\n /// Converts a ContractAddress to Bytes32.\\n ///\\n /// # Arguments\\n /// * `addr` - The address to convert\\n ///\\n /// # Returns\\n /// * `Bytes32` - The bytes32 representation\\n pub fn address_to_bytes32(addr: ContractAddress) -> Bytes32 {\\n addr.into()\\n }\\n\\n /// Converts Bytes32 to a ContractAddress.\\n ///\\n /// # Arguments\\n /// * `b` - The bytes32 value to convert\\n ///\\n /// # Returns\\n /// * `Option<ContractAddress>` - The address if valid\\n pub fn bytes32_to_address(b: Bytes32) -> Option<ContractAddress> {\\n b.try_into()\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/oapps/oft/structs.cairo\": \"use lz_utils::bytes::Bytes32;\\nuse crate::MessageReceipt;\\n\\n/// Struct representing token parameters for the OFT send() operation.\\n#[derive(Clone, Drop, Serde, Default)]\\npub struct SendParam {\\n pub dst_eid: u32, // Destination endpoint ID\\n pub to: Bytes32, // Recipient address\\n pub amount_ld: u256, // Amount to send in local decimals\\n pub min_amount_ld: u256, // Minimum amount to send in local decimals\\n pub extra_options: ByteArray, // Additional options supplied by the caller\\n pub compose_msg: ByteArray, // The composed message for the send() operation\\n pub oft_cmd: ByteArray // The OFT command to be executed\\n}\\n\\n/// Struct representing OFT limit information.\\n/// These amounts can change dynamically and are up to the specific oft implementation.\\n#[derive(Debug, Drop, Serde, Default, PartialEq)]\\npub struct OFTLimit {\\n pub min_amount_ld: u256, // Minimum amount in local decimals that can be sent\\n pub max_amount_ld: u256 // Maximum amount in local decimals that can be sent\\n}\\n\\n/// Struct representing OFT receipt information.\\n#[derive(Debug, Drop, Serde, Default, PartialEq)]\\npub struct OFTReceipt {\\n pub amount_sent_ld: u256, // Amount of tokens ACTUALLY debited from the sender in local decimals\\n pub amount_received_ld: u256 // Amount of tokens to be received on the remote side\\n}\\n\\n/// Struct representing OFT fee details.\\n/// Future proof mechanism to provide a standardized way to communicate fees to things like a UI.\\n#[derive(Debug, Drop, Serde, Default, PartialEq)]\\npub struct OFTFeeDetail {\\n pub fee_amount_ld: u256, // Amount of the fee in local decimals\\n pub reward_amount_ld: u256, // Amount of the reward in local decimals\\n pub description: ByteArray // Description of the fee\\n}\\n\\n/// Struct representing OFT version information.\\n#[derive(Drop, Serde, Default)]\\npub struct OFTVersion {\\n pub interface_id: u32, // The interface ID (equivalent to Solidity's bytes4)\\n pub version: u64 // The version number\\n}\\n\\n/// Struct representing OFT quote information.\\n#[derive(Debug, Drop, Serde, Default, PartialEq)]\\npub struct OFTQuote {\\n pub limit: OFTLimit, // The OFT limit information\\n pub oft_fee_details: Array<OFTFeeDetail>, // The details of OFT fees\\n pub receipt: OFTReceipt // The OFT receipt information\\n}\\n\\n/// Struct representing OFT send result.\\n#[derive(Drop, Serde, Default)]\\npub struct OFTSendResult {\\n pub message_receipt: MessageReceipt, // The LayerZero messaging receipt\\n pub oft_receipt: OFTReceipt // The OFT receipt information\\n}\\n\\n#[derive(Drop, Serde, Default)]\\npub struct OFTDebit {\\n pub amount_sent_ld: u256, // Amount of tokens ACTUALLY debited from the sender in local decimals\\n pub amount_received_ld: u256 // Amount of tokens to be received on the remote side\\n}\\n\\n#[derive(Drop, Serde, Default)]\\npub struct OFTMsgAndOptions {\\n pub message: ByteArray, // The encoded message\\n pub options: ByteArray // The encoded options\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/treasury/errors.cairo\": \"use lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum TreasuryError {\\n LzTokenNotEnabled,\\n TransferFailed,\\n}\\n\\nimpl ErrorImpl of Error<TreasuryError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_TREASURY\\\"\\n }\\n\\n fn name(self: TreasuryError) -> ByteArray {\\n match self {\\n TreasuryError::LzTokenNotEnabled => \\\"LZ_TOKEN_NOT_ENABLED\\\",\\n TreasuryError::TransferFailed => \\\"LZ_TRANSFER_FAILED\\\",\\n }\\n }\\n}\\n\\npub fn err_lz_token_not_enabled() -> ByteArray {\\n format_error(TreasuryError::LzTokenNotEnabled, \\\"\\\")\\n}\\n\\npub fn err_transfer_failed() -> ByteArray {\\n format_error(TreasuryError::TransferFailed, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/treasury/events.cairo\": \"#[derive(Drop, starknet::Event)]\\npub struct BasisPointsUpdated {\\n pub old_bp: u256,\\n pub new_bp: u256,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/treasury/interfaces/layerzero_treasury.cairo\": \"//! LayerZero treasury interface\\n\\nuse starknet::ContractAddress;\\n\\n/// Interface for Treasury component\\n///\\n/// The Treasury collects treasury fees.\\n#[starknet::interface]\\npub trait ILayerZeroTreasury<TContractState> {\\n /// Calculates the treasury fee based on the worker fee and whether the fee should be paid in\\n /// LZ tokens. If the fee should be paid in LZ tokens, the fee is returned in ZRO, or otherwise\\n /// in native tokens.\\n ///\\n /// # Arguments\\n /// * `sender` - The sender address\\n /// * `dst_eid` - The destination endpoint ID\\n /// * `worker_fee` - The total worker fee\\n /// * `pay_in_lz_token` - The flag indicating whether a fee is paid in LZ tokens or not\\n ///\\n /// # Returns\\n /// * `u256` - The amount of tokens to be paid\\n ///\\n /// # Panics\\n /// * If `pay_in_lz_token` is true while LZ token payment is disabled in the treasury\\n fn get_fee(\\n self: @TContractState,\\n sender: ContractAddress,\\n dst_eid: u32,\\n worker_fee: u256,\\n pay_in_lz_token: bool,\\n ) -> u256;\\n\\n /// Pays the fee to the treasury. The fee is calculated based on the worker fee and whether the\\n /// fee should be paid in LZ tokens.\\n ///\\n /// # Arguments\\n /// * `sender` - The sender address\\n /// * `dst_eid` - The destination endpoint ID\\n /// * `worker_fee` - The total worker fee\\n /// * `pay_in_lz_token` - The flag indicating whether a fee is paid in LZ tokens or not\\n ///\\n /// # Returns\\n /// * `u256` - The amount of tokens to be paid\\n ///\\n /// # Panics\\n /// * If `pay_in_lz_token` is true while LZ token payment is disabled in the treasury\\n fn pay_fee(\\n ref self: TContractState,\\n sender: ContractAddress,\\n dst_eid: u32,\\n worker_fee: u256,\\n pay_in_lz_token: bool,\\n ) -> u256;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/treasury/interfaces/lz_token_fee_lib.cairo\": \"//! LayerZero token fee library interface\\n\\nuse starknet::ContractAddress;\\n\\n/// Interface for LayerZero token fee library component.\\n///\\n/// LayerZero token fee library calculates treasury fees.\\n#[starknet::interface]\\npub trait ILzTokenFeeLib<TContractState> {\\n /// Calculates the treasury fee based on the worker fee.\\n ///\\n /// # Arguments\\n /// * `sender` - The sender address\\n /// * `dst_eid` - The destination endpoint ID\\n /// * `worker_fee` - The total worker fee\\n /// * `native_treasury_fee` - The treasury fee in native tokens\\n ///\\n /// # Returns\\n /// * `u256` - The amount of tokens to be paid in LayerZero tokens\\n fn get_fee(\\n self: @TContractState,\\n sender: ContractAddress,\\n dst_eid: u32,\\n worker_fee: u256,\\n native_treasury_fee: u256,\\n ) -> u256;\\n\\n /// Calculates the treasury fee based on the worker fee for later payment.\\n ///\\n /// # Arguments\\n /// * `sender` - The sender address\\n /// * `dst_eid` - The destination endpoint ID\\n /// * `worker_fee` - The total worker fee\\n /// * `native_treasury_fee` - The treasury fee in native tokens\\n ///\\n /// # Returns\\n /// * `u256` - The amount of tokens to be paid in LayerZero tokens\\n fn pay_fee(\\n ref self: TContractState,\\n sender: ContractAddress,\\n dst_eid: u32,\\n worker_fee: u256,\\n native_treasury_fee: u256,\\n ) -> u256;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/treasury/interfaces/treasury_admin.cairo\": \"//! Treasury admin interface\\n\\nuse starknet::ContractAddress;\\n\\n/// Interface for TreasuryAdmin component\\n///\\n/// The TreasuryAdmin allows administrators of the treasury to manage the treasury\\n/// fee configuration, and withdraw collected fees.\\n#[starknet::interface]\\npub trait ITreasuryAdmin<TContractState> {\\n /// Gets the basis points of the treasury fee.\\n ///\\n /// # Returns\\n /// * `u256` - The basis points\\n fn get_fee_bp(self: @TContractState) -> u256;\\n\\n /// Sets the basis points of the treasury fee.\\n ///\\n /// # Arguments\\n /// * `basis_points` - The basis points\\n fn set_fee_bp(ref self: TContractState, basis_points: u256);\\n\\n /// Withdraws the collected fee of a given token address.\\n fn withdraw_tokens(\\n ref self: TContractState, token_address: ContractAddress, to: ContractAddress, amount: u256,\\n );\\n\\n /// Gets the LZ token fee library.\\n ///\\n /// # Returns\\n /// * `Option<ContractAddress>` - The LZ token fee library if any\\n fn get_lz_token_fee_lib(self: @TContractState) -> Option<ContractAddress>;\\n\\n /// Sets the LZ token fee library.\\n ///\\n /// # Arguments\\n /// * `library` - The LZ token fee library\\n fn set_lz_token_fee_lib(ref self: TContractState, library: Option<ContractAddress>);\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/treasury/treasury.cairo\": \"//! Treasury component implementation\\n\\n#[starknet::contract]\\npub mod Treasury {\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use starknet::ContractAddress;\\n use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};\\n use crate::common::constants::BPS_DENOMINATOR;\\n use crate::treasury::errors::{err_lz_token_not_enabled, err_transfer_failed};\\n use crate::treasury::events::BasisPointsUpdated;\\n use crate::treasury::interfaces::layerzero_treasury::ILayerZeroTreasury;\\n use crate::treasury::interfaces::lz_token_fee_lib::{\\n ILzTokenFeeLibDispatcher, ILzTokenFeeLibDispatcherTrait,\\n };\\n use crate::treasury::interfaces::treasury_admin::ITreasuryAdmin;\\n\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n\\n #[abi(embed_v0)]\\n impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;\\n impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n basis_points: u256,\\n lz_token_fee_lib: Option<ContractAddress>,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n BasisPointsUpdated: BasisPointsUpdated,\\n }\\n\\n #[constructor]\\n fn constructor(ref self: ContractState, owner: ContractAddress) {\\n self.ownable.initializer(owner);\\n }\\n\\n #[abi(embed_v0)]\\n impl TreasuryImpl of ILayerZeroTreasury<ContractState> {\\n fn get_fee(\\n self: @ContractState,\\n sender: ContractAddress,\\n dst_eid: u32,\\n worker_fee: u256,\\n pay_in_lz_token: bool,\\n ) -> u256 {\\n let native_fee = self._get_native_fee(worker_fee);\\n\\n if pay_in_lz_token {\\n self\\n ._get_lz_token_library_dispatcher()\\n .get_fee(sender, dst_eid, worker_fee, native_fee)\\n } else {\\n native_fee\\n }\\n }\\n\\n fn pay_fee(\\n ref self: ContractState,\\n sender: ContractAddress,\\n dst_eid: u32,\\n worker_fee: u256,\\n pay_in_lz_token: bool,\\n ) -> u256 {\\n let native_fee = self._get_native_fee(worker_fee);\\n\\n if pay_in_lz_token {\\n self\\n ._get_lz_token_library_dispatcher()\\n .pay_fee(sender, dst_eid, worker_fee, native_fee)\\n } else {\\n native_fee\\n }\\n }\\n }\\n\\n #[generate_trait]\\n pub impl TreasuryInternalImpl of TreasuryInternalTrait {\\n fn _get_native_fee(self: @ContractState, worker_fee: u256) -> u256 {\\n worker_fee * self.basis_points.read() / BPS_DENOMINATOR\\n }\\n\\n fn _get_lz_token_library_dispatcher(self: @ContractState) -> ILzTokenFeeLibDispatcher {\\n let library = self.lz_token_fee_lib.read();\\n assert_with_byte_array(library.is_some(), err_lz_token_not_enabled());\\n\\n ILzTokenFeeLibDispatcher {\\n contract_address: library.expect('LZ token fee library exists'),\\n }\\n }\\n }\\n\\n #[abi(embed_v0)]\\n impl TreasuryAdminImpl of ITreasuryAdmin<ContractState> {\\n fn set_fee_bp(ref self: ContractState, basis_points: u256) {\\n self.ownable.assert_only_owner();\\n let old_bp = self.basis_points.read();\\n self.basis_points.write(basis_points);\\n\\n self.emit(BasisPointsUpdated { old_bp, new_bp: basis_points });\\n }\\n\\n fn get_fee_bp(self: @ContractState) -> u256 {\\n self.basis_points.read()\\n }\\n\\n fn withdraw_tokens(\\n ref self: ContractState,\\n token_address: ContractAddress,\\n to: ContractAddress,\\n amount: u256,\\n ) {\\n self.ownable.assert_only_owner();\\n let token_dispatcher = IERC20Dispatcher { contract_address: token_address };\\n\\n let success = token_dispatcher.transfer(to, amount);\\n\\n assert_with_byte_array(success, err_transfer_failed());\\n }\\n\\n fn get_lz_token_fee_lib(self: @ContractState) -> Option<ContractAddress> {\\n self.lz_token_fee_lib.read()\\n }\\n\\n fn set_lz_token_fee_lib(ref self: ContractState, library: Option<ContractAddress>) {\\n self.ownable.assert_only_owner();\\n\\n self.lz_token_fee_lib.write(library);\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/access_control.cairo\": \"//! Worker access control roles\\n\\n/// Default admin role\\n/// - can grant and revoke all roles\\npub use openzeppelin::access::accesscontrol::DEFAULT_ADMIN_ROLE;\\n\\n/// Admin role\\npub const ADMIN_ROLE: felt252 = 'ADMIN_ROLE';\\n\\n/// Message lib role\\npub const MESSAGE_LIB_ROLE: felt252 = 'MESSAGE_LIB_ROLE';\\n\\n/// Allow list role\\npub const ALLOW_LIST_ROLE: felt252 = 'ALLOW_LIST_ROLE';\\n\\n/// Deny list role\\npub const DENY_LIST_ROLE: felt252 = 'DENY_LIST_ROLE';\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/base/base.cairo\": \"//! Base worker component implementation\\n\\n#[starknet::component]\\npub mod WorkerBaseComponent {\\n use core::num::traits::Zero;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::accesscontrol::AccessControlComponent;\\n use openzeppelin::access::accesscontrol::AccessControlComponent::InternalImpl as AccessControlInternalImpl;\\n use openzeppelin::access::accesscontrol::interface::IAccessControl;\\n use openzeppelin::introspection::src5::SRC5Component;\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use starknet::ContractAddress;\\n use starknet::storage::{\\n Map, StoragePathEntry, StoragePointerReadAccess, StoragePointerWriteAccess,\\n };\\n use crate::workers::access_control::{\\n ADMIN_ROLE, ALLOW_LIST_ROLE, DEFAULT_ADMIN_ROLE, DENY_LIST_ROLE, MESSAGE_LIB_ROLE,\\n };\\n use crate::workers::base::errors::{err_sender_not_allowed, err_transfer_failed};\\n use crate::workers::base::events::{\\n DefaultMultiplierBpsSet, FeeWithdrawn, PriceFeedSet, SupportedOptionTypeSet,\\n WorkerFeeLibSet,\\n };\\n use crate::workers::base::interface::IWorkerBase;\\n\\n // =============================== Storage =================================\\n\\n #[storage]\\n pub struct Storage {\\n pub WorkerBase_price_feed: ContractAddress,\\n pub WorkerBase_default_multiplier_bps: u16,\\n /// EID => option type\\n pub WorkerBase_supported_option_types: Map<u32, ByteArray>,\\n pub WorkerBase_worker_fee_lib: ContractAddress,\\n /// Allow list size to check sender permissions\\n pub WorkerBase_allow_list_size: u64,\\n }\\n\\n // =============================== Events =================================\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n PriceFeedSet: PriceFeedSet,\\n FeeWithdrawn: FeeWithdrawn,\\n SupportedOptionTypeSet: SupportedOptionTypeSet,\\n DefaultMultiplierBpsSet: DefaultMultiplierBpsSet,\\n WorkerFeeLibSet: WorkerFeeLibSet,\\n }\\n\\n #[embeddable_as(WorkerBaseImpl)]\\n impl WorkerBase<\\n TContractState,\\n +HasComponent<TContractState>,\\n impl AccessControl: AccessControlComponent::HasComponent<TContractState>,\\n +SRC5Component::HasComponent<TContractState>,\\n +Drop<TContractState>,\\n > of IWorkerBase<ComponentState<TContractState>> {\\n // ===================================== Only Admin =====================================\\n\\n fn set_price_feed(ref self: ComponentState<TContractState>, price_feed: ContractAddress) {\\n self._assert_only_admin();\\n\\n let old_price_feed = self.WorkerBase_price_feed.read();\\n self.WorkerBase_price_feed.write(price_feed);\\n self.emit(PriceFeedSet { old_price_feed, new_price_feed: price_feed });\\n }\\n\\n fn set_supported_option_type(\\n ref self: ComponentState<TContractState>, eid: u32, option_type: ByteArray,\\n ) {\\n self._assert_only_admin();\\n self.WorkerBase_supported_option_types.entry(eid).write(option_type.clone());\\n self.emit(SupportedOptionTypeSet { eid, option_type });\\n }\\n\\n fn set_default_multiplier_bps(\\n ref self: ComponentState<TContractState>, default_multiplier_bps: u16,\\n ) {\\n self._assert_only_admin();\\n self.WorkerBase_default_multiplier_bps.write(default_multiplier_bps);\\n self.emit(DefaultMultiplierBpsSet { default_multiplier_bps });\\n }\\n\\n fn withdraw_fee(\\n ref self: ComponentState<TContractState>,\\n token_address: ContractAddress,\\n to: ContractAddress,\\n amount: u256,\\n ) {\\n self._assert_only_admin();\\n let token = IERC20Dispatcher { contract_address: token_address };\\n let success = token.transfer(to, amount);\\n assert_with_byte_array(success, err_transfer_failed());\\n self.emit(FeeWithdrawn { to, amount });\\n }\\n\\n fn set_worker_fee_lib(\\n ref self: ComponentState<TContractState>, worker_fee_lib: ContractAddress,\\n ) {\\n self._assert_only_admin();\\n\\n let old_worker_fee_lib = self.WorkerBase_worker_fee_lib.read();\\n self.WorkerBase_worker_fee_lib.write(worker_fee_lib);\\n self.emit(WorkerFeeLibSet { old_worker_fee_lib, new_worker_fee_lib: worker_fee_lib });\\n }\\n\\n // ======================================= View ========================================\\n\\n fn get_price_feed(self: @ComponentState<TContractState>) -> ContractAddress {\\n self.WorkerBase_price_feed.read()\\n }\\n\\n fn get_supported_option_type(self: @ComponentState<TContractState>, eid: u32) -> ByteArray {\\n self.WorkerBase_supported_option_types.entry(eid).read()\\n }\\n\\n fn get_default_multiplier_bps(self: @ComponentState<TContractState>) -> u16 {\\n self.WorkerBase_default_multiplier_bps.read()\\n }\\n\\n fn get_worker_fee_lib(self: @ComponentState<TContractState>) -> ContractAddress {\\n self.WorkerBase_worker_fee_lib.read()\\n }\\n\\n fn get_allow_list_size(self: @ComponentState<TContractState>) -> u64 {\\n self.WorkerBase_allow_list_size.read()\\n }\\n\\n fn is_sender_allowed(\\n self: @ComponentState<TContractState>, sender: ContractAddress,\\n ) -> bool {\\n self._is_sender_allowed(sender)\\n }\\n }\\n\\n // internal\\n #[generate_trait]\\n pub impl InternalImpl<\\n TContractState,\\n +HasComponent<TContractState>,\\n impl AccessControl: AccessControlComponent::HasComponent<TContractState>,\\n +SRC5Component::HasComponent<TContractState>,\\n +Drop<TContractState>,\\n > of InternalTrait<TContractState> {\\n /// Initialize the base worker component\\n fn initializer(\\n ref self: ComponentState<TContractState>,\\n message_libs: Array<ContractAddress>,\\n price_feed: ContractAddress,\\n default_multiplier_bps: u16,\\n role_admin: ContractAddress,\\n admins: Array<ContractAddress>,\\n ) {\\n // Set initial values\\n self.WorkerBase_default_multiplier_bps.write(default_multiplier_bps);\\n self.WorkerBase_price_feed.write(price_feed);\\n\\n // Set role admin\\n let mut access_control = get_dep_component_mut!(ref self, AccessControl);\\n if !role_admin.is_zero() {\\n access_control._grant_role(DEFAULT_ADMIN_ROLE, role_admin);\\n }\\n\\n // Set message libs\\n for message_lib in message_libs {\\n access_control._grant_role(MESSAGE_LIB_ROLE, message_lib);\\n }\\n\\n // Set additional admins\\n for admin in admins {\\n access_control._grant_role(ADMIN_ROLE, admin);\\n }\\n }\\n\\n /// Internal grant role to keep track of allow list size\\n fn _grant_role(\\n ref self: ComponentState<TContractState>, role: felt252, account: ContractAddress,\\n ) {\\n let mut access_control = get_dep_component_mut!(ref self, AccessControl);\\n if role == ALLOW_LIST_ROLE && !access_control.has_role(ALLOW_LIST_ROLE, account) {\\n self.WorkerBase_allow_list_size.write(self.WorkerBase_allow_list_size.read() + 1);\\n }\\n access_control._grant_role(role, account);\\n }\\n\\n /// Internal revoke role to keep track of allow list size\\n fn _revoke_role(\\n ref self: ComponentState<TContractState>, role: felt252, account: ContractAddress,\\n ) {\\n let mut access_control = get_dep_component_mut!(ref self, AccessControl);\\n if role == ALLOW_LIST_ROLE && access_control.has_role(ALLOW_LIST_ROLE, account) {\\n self.WorkerBase_allow_list_size.write(self.WorkerBase_allow_list_size.read() - 1);\\n }\\n access_control._revoke_role(role, account);\\n }\\n\\n fn _is_sender_allowed(\\n self: @ComponentState<TContractState>, sender: ContractAddress,\\n ) -> bool {\\n let access_control = get_dep_component!(self, AccessControl);\\n\\n !access_control.has_role(DENY_LIST_ROLE, sender)\\n && (self.WorkerBase_allow_list_size.read() == 0\\n || access_control.has_role(ALLOW_LIST_ROLE, sender))\\n }\\n\\n /// Internal function to check if the sender is allowed to perform the action\\n ///\\n /// it checks if its deny listed, or if there is an allow list, and if there is, if its in\\n /// the allow list\\n fn _assert_sender_allowed(self: @ComponentState<TContractState>, sender: ContractAddress) {\\n assert_with_byte_array(self._is_sender_allowed(sender), err_sender_not_allowed());\\n }\\n\\n\\n fn _assert_only_default_admin(self: @ComponentState<TContractState>) {\\n get_dep_component!(self, AccessControl).assert_only_role(DEFAULT_ADMIN_ROLE);\\n }\\n\\n fn _assert_only_admin(self: @ComponentState<TContractState>) {\\n get_dep_component!(self, AccessControl).assert_only_role(ADMIN_ROLE);\\n }\\n\\n fn _assert_only_message_lib(self: @ComponentState<TContractState>) {\\n get_dep_component!(self, AccessControl).assert_only_role(MESSAGE_LIB_ROLE);\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/base/errors.cairo\": \"//! Base worker errors\\n\\nuse lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop, Clone, Debug, PartialEq)]\\npub enum WorkerBaseError {\\n RoleRenouncingDisabled,\\n SenderNotAllowed,\\n TransferFailed,\\n}\\n\\nimpl WorkerBaseErrorImpl of Error<WorkerBaseError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_WORKER_BASE\\\"\\n }\\n\\n fn name(self: WorkerBaseError) -> ByteArray {\\n match self {\\n WorkerBaseError::RoleRenouncingDisabled => \\\"ROLE_RENOUNCING_DISABLED\\\",\\n WorkerBaseError::SenderNotAllowed => \\\"SENDER_NOT_ALLOWED\\\",\\n WorkerBaseError::TransferFailed => \\\"TRANSFER_FAILED\\\",\\n }\\n }\\n}\\n\\npub fn err_role_renouncing_disabled() -> ByteArray {\\n format_error(WorkerBaseError::RoleRenouncingDisabled, \\\"\\\")\\n}\\n\\npub fn err_sender_not_allowed() -> ByteArray {\\n format_error(WorkerBaseError::SenderNotAllowed, \\\"\\\")\\n}\\n\\npub fn err_transfer_failed() -> ByteArray {\\n format_error(WorkerBaseError::TransferFailed, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/base/events.cairo\": \"//! Base worker events\\n\\nuse starknet::ContractAddress;\\n\\n/// Event emitted when the price feed address is updated\\n#[derive(Drop, starknet::Event)]\\npub struct PriceFeedSet {\\n #[key]\\n pub old_price_feed: ContractAddress,\\n #[key]\\n pub new_price_feed: ContractAddress,\\n}\\n\\n/// Event emitted when fees are withdrawn\\n#[derive(Drop, starknet::Event)]\\npub struct FeeWithdrawn {\\n #[key]\\n pub to: ContractAddress,\\n pub amount: u256,\\n}\\n\\n/// Event emitted when the supported option type for an EID is set\\n#[derive(Drop, starknet::Event)]\\npub struct SupportedOptionTypeSet {\\n #[key]\\n pub eid: u32,\\n pub option_type: ByteArray,\\n}\\n\\n/// Event emitted when the default multiplier basis points is set\\n#[derive(Drop, starknet::Event)]\\npub struct DefaultMultiplierBpsSet {\\n pub default_multiplier_bps: u16,\\n}\\n\\n/// Event emitted when the worker fee lib address is updated\\n#[derive(Drop, starknet::Event)]\\npub struct WorkerFeeLibSet {\\n #[key]\\n pub old_worker_fee_lib: ContractAddress,\\n #[key]\\n pub new_worker_fee_lib: ContractAddress,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/base/interface.cairo\": \"//! Base worker interface\\n\\nuse starknet::ContractAddress;\\n\\n/// Interface for the base worker component\\n#[starknet::interface]\\npub trait IWorkerBase<TContractState> {\\n // ===================================== Only Admin =====================================\\n\\n /// Sets the price feed worker address\\n ///\\n /// # Arguments\\n ///\\n /// * `price_feed`: The address of the price feed worker\\n ///\\n /// @dev This function is only callable by the admin role.\\n fn set_price_feed(ref self: TContractState, price_feed: ContractAddress);\\n\\n /// Sets the supported option type for an endpointID\\n ///\\n /// # Arguments\\n ///\\n /// * `eid`: The EID to set the supported option type for\\n /// * `option_type`: The option type to set for the EID\\n ///\\n /// @dev This function is only callable by the admin role.\\n fn set_supported_option_type(ref self: TContractState, eid: u32, option_type: ByteArray);\\n\\n /// Sets the default multiplier basis points\\n ///\\n /// # Arguments\\n ///\\n /// * `default_multiplier_bps`: The default multiplier basis points to set\\n ///\\n /// @dev This function is only callable by the admin role.\\n fn set_default_multiplier_bps(ref self: TContractState, default_multiplier_bps: u16);\\n\\n /// Withdraw collected fees (only admin)\\n fn withdraw_fee(\\n ref self: TContractState, token_address: ContractAddress, to: ContractAddress, amount: u256,\\n );\\n\\n /// Sets the worker fee lib address\\n ///\\n /// # Arguments\\n ///\\n /// * `worker_fee_lib`: The address of the worker fee lib\\n ///\\n /// @dev This function is only callable by the admin role.\\n fn set_worker_fee_lib(ref self: TContractState, worker_fee_lib: ContractAddress);\\n\\n // ======================================= View ========================================\\n\\n /// Gets the current price feed address\\n ///\\n /// # Returns\\n ///\\n /// The current price feed worker's address\\n fn get_price_feed(self: @TContractState) -> ContractAddress;\\n\\n /// Gets the supported option type for a given EID\\n ///\\n /// # Arguments\\n ///\\n /// * `eid`: The EID to get the supported option type for\\n ///\\n /// # Returns\\n ///\\n /// The supported option type for the EID\\n fn get_supported_option_type(self: @TContractState, eid: u32) -> ByteArray;\\n\\n /// Gets the default multiplier basis points\\n ///\\n /// # Returns\\n ///\\n /// The default multiplier basis points\\n fn get_default_multiplier_bps(self: @TContractState) -> u16;\\n\\n /// Gets the current worker fee lib address\\n ///\\n /// # Returns\\n ///\\n /// The current worker fee lib address\\n fn get_worker_fee_lib(self: @TContractState) -> ContractAddress;\\n\\n /// Gets the allow list size\\n ///\\n /// # Returns\\n ///\\n /// The allow list size\\n fn get_allow_list_size(self: @TContractState) -> u64;\\n\\n /// Checks if the sender is allowed by allow list and deny list\\n ///\\n /// # Arguments\\n ///\\n /// * `sender`: The address of the sender\\n ///\\n /// # Returns\\n ///\\n /// True if the sender is allowed by allow list and deny list, false otherwise\\n fn is_sender_allowed(self: @TContractState, sender: ContractAddress) -> bool;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/base/structs.cairo\": \"use starknet::ContractAddress;\\n\\n#[derive(Drop, Serde, Clone)]\\npub struct QuoteParams {\\n pub dst_eid: u32,\\n pub sender: ContractAddress,\\n pub confirmations: u64,\\n pub calldata_size: u32,\\n pub options: ByteArray,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/common.cairo\": \"use core::cmp::max;\\nuse crate::common::constants::{BPS_DENOMINATOR, NATIVE_DECIMALS_RATE};\\n\\n/// Apply premium and floor margin to the fee\\n///\\n/// Returns the maximum between the fee with a multiplier and fee with the floor margin.\\n///\\n/// # Arguments\\n///\\n/// * `fee` - fee to apply premium to\\n/// * `bps` - base points to apply premium to, where 10000 = 100%\\n/// * `default_bps` - default bps to apply premium to\\n/// * `margin_usd` - margin in usd\\n/// * `native_price_usd` - native price in usd\\n///\\n/// # Returns\\n///\\n/// * `fee_with_premium` - fee with premium applied\\npub fn apply_premium_and_floor_margin(\\n fee: u256, bps: u16, default_bps: u16, margin_usd: u128, native_price_usd: u128,\\n) -> u256 {\\n let multiplier_bps = if bps == 0 {\\n default_bps\\n } else {\\n bps\\n };\\n\\n // fee with multiplier, divides by BPS_DENOMINATOR to get the percentage\\n let fee_with_multiplier = (fee * multiplier_bps.into()) / BPS_DENOMINATOR;\\n if native_price_usd == 0 || margin_usd == 0 {\\n return fee_with_multiplier;\\n }\\n\\n // fee with floor margin, divides by native_price_usd to get the amount of native tokens\\n let fee_with_floor_margin = fee\\n + (margin_usd.into() * NATIVE_DECIMALS_RATE) / native_price_usd.into();\\n\\n max(fee_with_floor_margin, fee_with_multiplier)\\n}\\n\\npub fn convert_and_apply_premium_to_value(\\n value: u256, ratio: u128, denom: u128, bps: u16, default_bps: u16,\\n) -> u256 {\\n let multiplier_bps = if bps == 0 {\\n default_bps\\n } else {\\n bps\\n };\\n\\n if value > 0 {\\n (((value * ratio.into()) / denom.into()) * multiplier_bps.into()) / BPS_DENOMINATOR\\n } else {\\n 0\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/dvn/constants.cairo\": \"//! DVN constants\\n\\n/// The raw bytes of the signature are 65 bytes long, the first 64 bytes are the signature, and the\\n/// last byte is the recovery ID.\\npub const SIGNATURE_RAW_BYTES: usize = 65;\\n\\n/// These values are copied from the EVM implementation assuming the receiver blockchain is\\n/// EVM-based.\\npub const EXECUTE_FIXED_BYTES: u32 = 260;\\npub const VERIFY_BYTES: u32 = 288;\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/dvn/dvn.cairo\": \"//! DVN contract implementation\\n\\n/// DVN contract\\n///\\n/// The DVN contract is a key component of LayerZero's security and validation model, acting as an\\n/// on-chain representation of an off-chain verification network. Its primary responsibility is to\\n/// attest to the validity of cross-chain messages. When a message is sent from another chain to\\n/// Starknet, a DVN is tasked with verifying that message. This contract manages the on-chain part\\n/// of that process: quoting the price for verification, and providing the mechanism for a trusted\\n/// party (the DVN's agent) to submit the verified message for execution.\\n#[starknet::contract]\\npub mod Dvn {\\n use core::num::traits::Zero;\\n use core::panics::panic_with_byte_array;\\n use lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\n use lz_utils::bytes::Bytes32;\\n use lz_utils::error::assert_with_byte_array;\\n use lz_utils::keccak::keccak256;\\n use multisig::MultisigComponent;\\n use openzeppelin::access::accesscontrol::AccessControlComponent;\\n use openzeppelin::access::accesscontrol::interface::IAccessControl;\\n use openzeppelin::introspection::src5::SRC5Component;\\n use openzeppelin::upgrades::upgradeable::UpgradeableComponent;\\n use openzeppelin::upgrades::upgradeable::UpgradeableComponent::InternalTrait as UpgradeableInternalTrait;\\n use starknet::account::Call;\\n use starknet::storage::{\\n Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess,\\n StoragePointerWriteAccess,\\n };\\n use starknet::syscalls::call_contract_syscall;\\n use starknet::{\\n ClassHash, ContractAddress, EthAddress, get_block_timestamp, get_contract_address,\\n };\\n use crate::common::constants::ZERO_ADDRESS;\\n use crate::workers::access_control::{\\n ADMIN_ROLE, ALLOW_LIST_ROLE, DENY_LIST_ROLE, MESSAGE_LIB_ROLE,\\n };\\n use crate::workers::base::base::WorkerBaseComponent;\\n use crate::workers::base::errors::err_role_renouncing_disabled;\\n use crate::workers::base::structs::QuoteParams;\\n use crate::workers::dvn::events::DstConfigSet;\\n use crate::workers::dvn::fee_lib::interface::{\\n FeeParams, IDvnFeeLibDispatcher, IDvnFeeLibDispatcherTrait,\\n };\\n use crate::workers::dvn::interface::IDvn;\\n use crate::workers::dvn::structs::{DstConfig, ExecuteParam, SetDstConfigParams};\\n use crate::workers::dvn::{errors, events};\\n use crate::workers::interface::ILayerZeroWorker;\\n\\n ////////////////\\n // Components //\\n ////////////////\\n\\n // Base worker component\\n component!(path: WorkerBaseComponent, storage: worker_base, event: WorkerBaseEvent);\\n\\n // Access control components\\n component!(path: AccessControlComponent, storage: access_control, event: AccessControlEvent);\\n component!(path: SRC5Component, storage: src5, event: SRC5Event);\\n\\n // Upgradeable component\\n component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);\\n\\n // Multisig component\\n component!(path: MultisigComponent, storage: multisig, event: MultisigEvent);\\n\\n ////////////////\\n // Embeddings //\\n ////////////////\\n\\n #[abi(embed_v0)]\\n impl WorkerBaseImpl = WorkerBaseComponent::WorkerBaseImpl<ContractState>;\\n impl WorkerBaseInternalImpl = WorkerBaseComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl MultisigImpl = MultisigComponent::Multisig<ContractState>;\\n impl MultisigInternalImpl = MultisigComponent::MultisigInternalImpl<ContractState>;\\n\\n // Multisig immutable configuration\\n impl MultisigImmutableConfig of MultisigComponent::ImmutableConfig {\\n // TODO: this value should be set testing the gas limit on testnet\\n // with a value where you can re-set the threshold without hitting the gas limit\\n const MAX_THRESHOLD: u32 = 11;\\n }\\n\\n impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;\\n\\n impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n #[substorage(v0)]\\n worker_base: WorkerBaseComponent::Storage,\\n #[substorage(v0)]\\n access_control: AccessControlComponent::Storage,\\n #[substorage(v0)]\\n src5: SRC5Component::Storage,\\n #[substorage(v0)]\\n upgradeable: UpgradeableComponent::Storage,\\n #[substorage(v0)]\\n multisig: MultisigComponent::Storage,\\n /// Eid => DstConfig\\n dst_configs: Map<u32, DstConfig>,\\n /// Verifier ID\\n vid: u32,\\n /// Record used hashes to prevent reentry and replay attack\\n used_hashes: Map<Bytes32, bool>,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n #[flat]\\n WorkerBaseEvent: WorkerBaseComponent::Event,\\n #[flat]\\n AccessControlEvent: AccessControlComponent::Event,\\n #[flat]\\n SRC5Event: SRC5Component::Event,\\n #[flat]\\n UpgradeableEvent: UpgradeableComponent::Event,\\n #[flat]\\n MultisigEvent: MultisigComponent::Event,\\n // DVN-specific events\\n DstConfigSet: DstConfigSet,\\n VerifySignaturesFailed: events::VerifySignaturesFailed,\\n HashAlreadyUsed: events::HashAlreadyUsed,\\n ExecuteFailed: events::ExecuteFailed,\\n }\\n\\n #[constructor]\\n fn constructor(\\n ref self: ContractState,\\n vid: u32,\\n message_libs: Array<ContractAddress>,\\n price_feed: ContractAddress,\\n default_multiplier_bps: u16,\\n multisig_signers: Span<EthAddress>,\\n multisig_threshold: u32,\\n admins: Array<ContractAddress>,\\n ) {\\n // Initialize access control component\\n self.access_control.initializer();\\n\\n // Initialize base worker & multisig components\\n self\\n .worker_base\\n .initializer(message_libs, price_feed, default_multiplier_bps, ZERO_ADDRESS, admins);\\n self.multisig._init(multisig_signers, multisig_threshold);\\n\\n // Set ID\\n self.vid.write(vid);\\n }\\n\\n #[abi(embed_v0)]\\n impl DvnImpl of IDvn<ContractState> {\\n // ================================== Only Admin =====================================\\n\\n fn set_dst_config(ref self: ContractState, params: Array<SetDstConfigParams>) {\\n self.worker_base._assert_only_admin();\\n\\n let dst_config_set = params.span();\\n for param in params.into_iter() {\\n self.dst_configs.write(param.dst_eid, param.config);\\n }\\n\\n self.emit(DstConfigSet { dst_config_set });\\n }\\n\\n fn execute(ref self: ContractState, params: Array<ExecuteParam>) {\\n self.worker_base._assert_only_admin();\\n\\n for (index, param) in params.into_iter().enumerate() {\\n let ExecuteParam { vid, call_data, expiration, signatures } = param.clone();\\n\\n // Skip if invalid or expired\\n if vid != self.vid.read() || expiration <= get_block_timestamp().into() {\\n continue;\\n }\\n\\n // Verify signatures\\n let hash = self.hash_call_data(vid, call_data, expiration);\\n if let Err(error) = self\\n .multisig\\n ._verify_n_signatures(hash.into(), signatures, self.multisig.get_threshold()) {\\n self.emit(events::VerifySignaturesFailed { error });\\n continue;\\n }\\n\\n // Skip if hash already used, register hash if not\\n if self.used_hashes.read(hash) {\\n self.emit(events::HashAlreadyUsed { execute_param: param, hash });\\n continue;\\n }\\n self.used_hashes.write(hash, true);\\n\\n // Record used hash and execute syscall\\n let result = call_contract_syscall(\\n call_data.to, call_data.selector, call_data.calldata,\\n );\\n\\n if let Err(data) = result {\\n // Un-use hash if syscall fails\\n self.used_hashes.write(hash, false);\\n self.emit(events::ExecuteFailed { index, data });\\n }\\n }\\n }\\n\\n // ================================== Only Quorum =====================================\\n\\n fn quorum_change_admin(ref self: ContractState, param: ExecuteParam) {\\n let ExecuteParam { vid, call_data, expiration, signatures } = param;\\n\\n // Panic if expired\\n assert_with_byte_array(\\n expiration > get_block_timestamp().into(), errors::err_instruction_expired(),\\n );\\n\\n // Panic if target is not the DVN\\n assert_with_byte_array(\\n call_data.to == get_contract_address(), errors::err_invalid_target(call_data.to),\\n );\\n\\n // NOTE: Deviation from EVM spec, we have to check the selector since call_data doesn't\\n // include the selector without this check is possible to use another execute param with\\n // an address argument to change admin\\n assert_with_byte_array(\\n call_data.selector == selector!(\\\"quorum_change_admin\\\"),\\n errors::err_invalid_selector(call_data.selector),\\n );\\n\\n // Panic if invalid VID\\n assert_with_byte_array(vid == self.vid.read(), errors::err_invalid_vid(vid));\\n\\n // Verify signatures\\n let hash = self.hash_call_data(vid, call_data, expiration);\\n self.multisig.verify_signatures(hash.into(), signatures);\\n\\n // Panic if hash already used\\n assert_with_byte_array(!self.used_hashes.read(hash), errors::err_duplicated_hash(hash));\\n\\n // Record used hash\\n self.used_hashes.write(hash, true);\\n\\n // Deserialize the new admin address from calldata & grant admin role or panic\\n let mut calldata = call_data.calldata;\\n let new_admin = Serde::deserialize(ref calldata);\\n assert_with_byte_array(new_admin.is_some(), errors::err_invalid_quorum_admin());\\n self.access_control._grant_role(ADMIN_ROLE, new_admin.unwrap());\\n }\\n\\n // ================================== Only Self =====================================\\n\\n fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {\\n self.multisig._only_multisig();\\n self.upgradeable.upgrade(new_class_hash);\\n }\\n\\n fn upgrade_and_call(\\n ref self: ContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252> {\\n self.multisig._only_multisig();\\n self.upgradeable.upgrade_and_call(new_class_hash, selector, calldata)\\n }\\n\\n // ================================== View ==========================================\\n\\n fn get_dst_config(self: @ContractState, dst_eid: u32) -> DstConfig {\\n self.dst_configs.read(dst_eid)\\n }\\n\\n fn get_vid(self: @ContractState) -> u32 {\\n self.vid.read()\\n }\\n\\n fn get_used_hash(self: @ContractState, hash: Bytes32) -> bool {\\n self.used_hashes.read(hash)\\n }\\n\\n fn hash_call_data(\\n self: @ContractState, vid: u32, call_data: Call, expiration: u256,\\n ) -> Bytes32 {\\n // encode and keccak: vid, to, expiration, selector, call_data\\n let mut payload: ByteArray = Default::default();\\n\\n payload.append_u32(vid);\\n payload.append_address(call_data.to);\\n payload.append_u256(expiration);\\n payload.append_felt252(call_data.selector);\\n\\n for i in call_data.calldata {\\n payload.append_felt252(*i);\\n }\\n\\n keccak256(@payload)\\n }\\n }\\n\\n #[abi(embed_v0)]\\n impl LayerZeroWorkerImpl of ILayerZeroWorker<ContractState> {\\n // ================================== Only Message Lib =====================================\\n\\n fn assign_job(ref self: ContractState, params: QuoteParams) -> u256 {\\n self.worker_base._assert_only_message_lib();\\n self.worker_base._assert_sender_allowed(params.sender);\\n self._quote(params)\\n }\\n\\n // ================================== View =====================================\\n\\n fn quote(self: @ContractState, params: QuoteParams) -> u256 {\\n self.worker_base._assert_sender_allowed(params.sender);\\n self._quote(params)\\n }\\n }\\n\\n /// Access control implementation - same as OpenZeppelin except `renounce_role` is disabled\\n #[abi(embed_v0)]\\n pub impl AccessControlImpl of IAccessControl<ContractState> {\\n fn has_role(self: @ContractState, role: felt252, account: ContractAddress) -> bool {\\n self.access_control.has_role(role, account)\\n }\\n\\n fn get_role_admin(self: @ContractState, role: felt252) -> felt252 {\\n self.access_control.get_role_admin(role)\\n }\\n\\n /// Overriding the `grant_role` function to add allow list management and custom checks:\\n /// - If the role is `ALLOW_LIST_ROLE`, `DENY_LIST_ROLE`, or `MESSAGE_LIB_ROLE`, only\\n /// multisig can grant the role\\n /// - If the role is `ADMIN_ROLE`, only admin can grant the role, as signers can do it\\n /// through `quorum_change_admin`\\n /// - If the role is invalid, panic\\n fn grant_role(ref self: ContractState, role: felt252, account: ContractAddress) {\\n self._assert_edit_role_permission(role, account);\\n self.worker_base._grant_role(role, account)\\n }\\n\\n /// Overriding the `revoke_role` function to add allow list management and custom checks:\\n /// - If the role is `ALLOW_LIST_ROLE`, `DENY_LIST_ROLE`, or `MESSAGE_LIB_ROLE`, only\\n /// multisig can revoke the role\\n /// - If the role is `ADMIN_ROLE`, only admin can grant the role, as signers can do it\\n /// through `quorum_change_admin`\\n /// - If the role is invalid, panic\\n fn revoke_role(ref self: ContractState, role: felt252, account: ContractAddress) {\\n self._assert_edit_role_permission(role, account);\\n self.worker_base._revoke_role(role, account)\\n }\\n\\n fn renounce_role(ref self: ContractState, role: felt252, account: ContractAddress) {\\n panic_with_byte_array(@err_role_renouncing_disabled())\\n }\\n }\\n\\n #[generate_trait]\\n impl InternalImpl of InternalTrait {\\n /// Equivalent to EVM's `onlySelfOrAdmin` modifier\\n fn _assert_edit_role_permission(\\n self: @ContractState, role: felt252, sender: ContractAddress,\\n ) {\\n if role == ALLOW_LIST_ROLE || role == DENY_LIST_ROLE || role == MESSAGE_LIB_ROLE {\\n return self.multisig._only_multisig();\\n }\\n\\n if role == ADMIN_ROLE {\\n return self.worker_base._assert_only_admin();\\n }\\n\\n panic_with_byte_array(@errors::err_invalid_role(role));\\n }\\n\\n /// Internal quote function without permission checks\\n fn _quote(self: @ContractState, params: QuoteParams) -> u256 {\\n // Assert price feed is set\\n let price_feed = self.worker_base.get_price_feed();\\n assert_with_byte_array(price_feed.is_non_zero(), errors::err_price_feed_not_set());\\n\\n // Assert worker fee lib is set\\n let worker_fee_lib_addr = self.worker_base.get_worker_fee_lib();\\n assert_with_byte_array(\\n worker_fee_lib_addr.is_non_zero(), errors::err_worker_fee_lib_not_set(),\\n );\\n\\n let QuoteParams { dst_eid, confirmations, sender, options, .. } = params;\\n\\n let fee_params = FeeParams {\\n price_feed,\\n dst_eid,\\n confirmations,\\n sender,\\n quorum: self.multisig.get_threshold(),\\n default_multiplier_bps: self.worker_base.get_default_multiplier_bps(),\\n };\\n\\n // Call fee lib to get the quote\\n let fee_lib = IDvnFeeLibDispatcher { contract_address: worker_fee_lib_addr };\\n fee_lib.get_fee(fee_params, self.get_dst_config(dst_eid), options)\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/dvn/errors.cairo\": \"//! DVN errors\\n\\nuse lz_utils::bytes::Bytes32;\\nuse lz_utils::error::{Error, format_error};\\nuse starknet::ContractAddress;\\n\\n#[derive(Drop, Clone, Debug, PartialEq)]\\npub enum DvnError {\\n InvalidDvnIdx,\\n InvalidDVNOptions,\\n EidNotSupported,\\n PriceFeedNotSet,\\n WorkerFeeLibNotSet,\\n InstructionExpired,\\n InvalidVid,\\n InvalidTarget,\\n InvalidSelector,\\n InvalidQuorumAdmin,\\n InvalidRole,\\n DuplicatedHash,\\n TransferFailed,\\n}\\n\\nimpl DvnErrorImpl of Error<DvnError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_DVN\\\"\\n }\\n\\n fn name(self: DvnError) -> ByteArray {\\n match self {\\n DvnError::InvalidDvnIdx => \\\"INVALID_DVN_IDX\\\",\\n DvnError::InvalidDVNOptions => \\\"INVALID_DVN_OPTIONS\\\",\\n DvnError::EidNotSupported => \\\"EID_NOT_SUPPORTED\\\",\\n DvnError::PriceFeedNotSet => \\\"PRICE_FEED_NOT_SET\\\",\\n DvnError::WorkerFeeLibNotSet => \\\"WORKER_FEELIB_NOT_SET\\\",\\n DvnError::InstructionExpired => \\\"INSTRUCTION_EXPIRED\\\",\\n DvnError::InvalidVid => \\\"INVALID_VID\\\",\\n DvnError::InvalidTarget => \\\"INVALID_TARGET\\\",\\n DvnError::InvalidSelector => \\\"INVALID_SELECTOR\\\",\\n DvnError::InvalidQuorumAdmin => \\\"INVALID_QUORUM_ADMIN\\\",\\n DvnError::DuplicatedHash => \\\"DUPLICATED_HASH\\\",\\n DvnError::InvalidRole => \\\"INVALID_ROLE\\\",\\n DvnError::TransferFailed => \\\"TRANSFER_FAILED\\\",\\n }\\n }\\n}\\n\\npub fn err_invalid_dvn_idx() -> ByteArray {\\n format_error(DvnError::InvalidDvnIdx, \\\"\\\")\\n}\\n\\npub fn err_invalid_dvn_options(cursor: usize) -> ByteArray {\\n format_error(DvnError::InvalidDVNOptions, format!(\\\"cursor: {}\\\", cursor))\\n}\\n\\npub fn err_eid_not_supported(eid: u32) -> ByteArray {\\n format_error(DvnError::EidNotSupported, format!(\\\"eid: {}\\\", eid))\\n}\\n\\npub fn err_price_feed_not_set() -> ByteArray {\\n format_error(DvnError::PriceFeedNotSet, \\\"\\\")\\n}\\n\\npub fn err_worker_fee_lib_not_set() -> ByteArray {\\n format_error(DvnError::WorkerFeeLibNotSet, \\\"\\\")\\n}\\n\\npub fn err_instruction_expired() -> ByteArray {\\n format_error(DvnError::InstructionExpired, \\\"\\\")\\n}\\n\\npub fn err_invalid_vid(vid: u32) -> ByteArray {\\n format_error(DvnError::InvalidVid, format!(\\\"vid: {}\\\", vid))\\n}\\n\\npub fn err_invalid_target(target: ContractAddress) -> ByteArray {\\n format_error(DvnError::InvalidTarget, format!(\\\"target: {:?}\\\", target))\\n}\\n\\npub fn err_invalid_selector(selector: felt252) -> ByteArray {\\n format_error(DvnError::InvalidSelector, format!(\\\"selector: {}\\\", selector))\\n}\\n\\npub fn err_invalid_quorum_admin() -> ByteArray {\\n format_error(DvnError::InvalidQuorumAdmin, \\\"\\\")\\n}\\n\\npub fn err_duplicated_hash(hash: Bytes32) -> ByteArray {\\n format_error(DvnError::DuplicatedHash, format!(\\\"hash: {:?}\\\", hash))\\n}\\n\\npub fn err_invalid_role(role: felt252) -> ByteArray {\\n format_error(DvnError::InvalidRole, format!(\\\"role: {:?}\\\", role))\\n}\\n\\npub fn err_transfer_failed() -> ByteArray {\\n format_error(DvnError::TransferFailed, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/dvn/events.cairo\": \"//! DVN events\\n\\nuse lz_utils::bytes::Bytes32;\\nuse crate::workers::dvn::structs::{ExecuteParam, SetDstConfigParams};\\n\\n/// Event emitted when the destination config is set\\n#[derive(Drop, starknet::Event)]\\npub struct DstConfigSet {\\n pub dst_config_set: Span<SetDstConfigParams>,\\n}\\n\\n/// Event emitted when the signatures are not valid\\n#[derive(Drop, starknet::Event)]\\npub struct VerifySignaturesFailed {\\n pub error: ByteArray,\\n}\\n\\n/// Event emitted when the hash is already used\\n#[derive(Drop, starknet::Event)]\\npub struct HashAlreadyUsed {\\n pub execute_param: ExecuteParam,\\n pub hash: Bytes32,\\n}\\n\\n/// Event emitted when the execute call fails\\n#[derive(Drop, starknet::Event)]\\npub struct ExecuteFailed {\\n pub index: u32,\\n pub data: Array<felt252>,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/dvn/fee_lib/dvn_fee_lib.cairo\": \"//! DVN Fee Library contract implementation\\n\\n/// DVN Fee Library contract\\n///\\n/// This contract handles fee calculations for DVN operations, separated from the main DVN logic\\n/// to provide modularity and easier maintenance of fee-related functionality.\\n#[starknet::contract]\\npub mod DvnFeeLib {\\n use core::num::traits::Zero;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use starknet::ContractAddress;\\n use starknet::storage::StoragePointerWriteAccess;\\n use crate::workers::common::apply_premium_and_floor_margin;\\n use crate::workers::dvn::constants::{EXECUTE_FIXED_BYTES, SIGNATURE_RAW_BYTES, VERIFY_BYTES};\\n use crate::workers::dvn::errors::{\\n err_eid_not_supported, err_invalid_dvn_options, err_transfer_failed,\\n };\\n use crate::workers::dvn::fee_lib::interface::{FeeParams, IDvnFeeLib};\\n use crate::workers::dvn::structs::DstConfig;\\n use crate::workers::price_feed::interface::{\\n ILayerZeroPriceFeedDispatcher, ILayerZeroPriceFeedDispatcherTrait,\\n };\\n\\n ////////////////\\n // Components //\\n ////////////////\\n\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n\\n ////////////////\\n // Embeddings //\\n ////////////////\\n\\n #[abi(embed_v0)]\\n impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;\\n impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n /// Local endpoint ID v2\\n local_eid_v2: u32,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n }\\n\\n #[constructor]\\n fn constructor(ref self: ContractState, local_eid_v2: u32, owner: ContractAddress) {\\n // Initialize ownable component\\n self.ownable.initializer(owner);\\n\\n // Set immutable values\\n self.local_eid_v2.write(local_eid_v2);\\n }\\n\\n #[abi(embed_v0)]\\n impl DvnFeeLibImpl of IDvnFeeLib<ContractState> {\\n // ================================== Only Owner =====================================\\n\\n fn withdraw_token(\\n ref self: ContractState,\\n token_address: ContractAddress,\\n to: ContractAddress,\\n amount: u256,\\n ) {\\n self.ownable.assert_only_owner();\\n let token = IERC20Dispatcher { contract_address: token_address };\\n\\n let success = token.transfer(to, amount);\\n assert_with_byte_array(success, err_transfer_failed());\\n }\\n\\n // ================================== External =====================================\\n\\n fn get_fee_on_send(\\n ref self: ContractState, params: FeeParams, dst_config: DstConfig, options: ByteArray,\\n ) -> u256 {\\n self.get_fee(params, dst_config, options)\\n }\\n\\n // ================================== View =====================================\\n\\n fn get_fee(\\n self: @ContractState, params: FeeParams, dst_config: DstConfig, options: ByteArray,\\n ) -> u256 {\\n // Check if destination is supported\\n assert_with_byte_array(dst_config.gas > 0, err_eid_not_supported(params.dst_eid));\\n\\n // Validate options (currently just check it's empty like in original DVN)\\n assert_with_byte_array(options.len().is_zero(), err_invalid_dvn_options(0));\\n\\n // NOTE: Deviation from EVM spec, we don't parse the DVN options here because\\n // They're only used in pre-crime and the value is not actually used.\\n // Therefore don't currently see the value in implementing the parsing logic here.\\n\\n // Calculate call data size\\n let calldata_size = self._get_calldata_size(params.quorum);\\n\\n // Get price feed estimate\\n let price_feed = ILayerZeroPriceFeedDispatcher { contract_address: params.price_feed };\\n let estimated_fee = price_feed\\n .estimate_fee_by_eid(params.dst_eid, calldata_size, dst_config.gas.into());\\n\\n // Apply premium and return\\n apply_premium_and_floor_margin(\\n estimated_fee.gas_fee,\\n dst_config.multiplier_bps,\\n params.default_multiplier_bps,\\n dst_config.floor_margin_usd,\\n estimated_fee.native_price_usd,\\n )\\n }\\n\\n fn version(self: @ContractState) -> (u64, u8) {\\n (1, 1)\\n }\\n }\\n\\n #[generate_trait]\\n impl InternalImpl of InternalTrait {\\n /// Get the call data size for the quote function\\n ///\\n /// # Arguments\\n ///\\n /// * `quorum` - The quorum for the multisig\\n ///\\n /// # Returns\\n ///\\n /// * `u32` - The call data size given the quorum amount of signatures\\n fn _get_calldata_size(self: @ContractState, quorum: u32) -> u32 {\\n const NUM_BYTES: u32 = 32;\\n let mut total_signatures_bytes = quorum * SIGNATURE_RAW_BYTES;\\n\\n if total_signatures_bytes % NUM_BYTES != 0 {\\n total_signatures_bytes = total_signatures_bytes\\n - (total_signatures_bytes % NUM_BYTES)\\n + NUM_BYTES;\\n }\\n\\n EXECUTE_FIXED_BYTES + VERIFY_BYTES + total_signatures_bytes + NUM_BYTES\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/dvn/fee_lib/interface.cairo\": \"//! DVN Fee Lib interface\\n\\nuse starknet::ContractAddress;\\nuse crate::workers::dvn::structs::DstConfig;\\n\\n/// Fee parameters for DVN fee calculation\\n#[derive(Drop, Clone, Serde)]\\npub struct FeeParams {\\n pub price_feed: ContractAddress,\\n pub dst_eid: u32,\\n pub confirmations: u64,\\n pub sender: ContractAddress,\\n pub quorum: u32,\\n pub default_multiplier_bps: u16,\\n}\\n\\n/// Interface for DVN Fee Library\\n#[starknet::interface]\\npub trait IDvnFeeLib<TContractState> {\\n // ================================== Only Owner =====================================\\n\\n /// Withdraw tokens from the fee lib\\n /// Enables recovery of funds accidentally sent\\n fn withdraw_token(\\n ref self: TContractState, token_address: ContractAddress, to: ContractAddress, amount: u256,\\n );\\n\\n // ================================== External =====================================\\n\\n /// Get fee function that can change state (e.g. paying price feed)\\n fn get_fee_on_send(\\n ref self: TContractState, params: FeeParams, dst_config: DstConfig, options: ByteArray,\\n ) -> u256;\\n\\n // ================================== View =====================================\\n\\n /// Get fee view function\\n fn get_fee(\\n self: @TContractState, params: FeeParams, dst_config: DstConfig, options: ByteArray,\\n ) -> u256;\\n\\n /// Get version\\n /// Returns (major, minor)\\n fn version(self: @TContractState) -> (u64, u8);\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/dvn/interface.cairo\": \"//! DVN interface\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ClassHash;\\nuse starknet::account::Call;\\nuse crate::workers::dvn::structs::{DstConfig, ExecuteParam, SetDstConfigParams};\\n\\n/// Interface for the DVN contract\\n#[starknet::interface]\\npub trait IDvn<TContractState> {\\n // ================================== Only Admin =====================================\\n\\n /// Set the destination configurations for multiple EIDs\\n ///\\n /// # Arguments\\n ///\\n /// * `params` - Array of parameters for setting the destination configuration\\n ///\\n /// # Access Control\\n ///\\n /// * Only admins can call this function\\n ///\\n /// # Events\\n ///\\n /// * `DstConfigSet` - Emitted when the destination configuration is set\\n fn set_dst_config(ref self: TContractState, params: Array<SetDstConfigParams>);\\n\\n /// Execute jobs\\n ///\\n /// # Arguments\\n ///\\n /// * `params` - Array of parameters for executing the jobs\\n ///\\n /// # Access Control\\n ///\\n /// * Only admins can call this function\\n ///\\n /// # Events\\n ///\\n /// * `VerifySignaturesFailed` - Emitted when the signatures verification fails\\n /// * `HashAlreadyUsed` - Emitted when the hash is already used\\n /// * `ExecuteFailed` - Emitted when the job execution fails\\n fn execute(ref self: TContractState, params: Array<ExecuteParam>);\\n\\n // ================================== Only Quorum =====================================\\n\\n /// Function for quorum to change the admin without going through the execute function\\n ///\\n /// # Arguments\\n ///\\n /// * `param` - Parameter for changing the admin\\n ///\\n /// # Access Control\\n ///\\n /// * Anyone can call this function, but it will only succeed with a quorum of signatures\\n ///\\n /// # Events\\n ///\\n /// * `RoleGranted` - Emitted when the admin role is granted (from OpenZeppelin's\\n /// [`AccessControlComponent`])\\n fn quorum_change_admin(ref self: TContractState, param: ExecuteParam);\\n\\n // ================================== Only Self =====================================\\n\\n /// Upgrade the contract\\n ///\\n /// # Arguments\\n ///\\n /// * `new_class_hash` - The new class hash to upgrade to\\n ///\\n /// # Events\\n ///\\n /// * `Upgraded` - Emitted when the contract is upgraded (from OpenZeppelin's\\n /// [`UpgradeableComponent`])\\n ///\\n /// @dev Only the contract itself can call this function (enforced by multisig)\\n fn upgrade(ref self: TContractState, new_class_hash: ClassHash);\\n\\n /// Upgrade the contract and call a function\\n ///\\n /// # Arguments\\n ///\\n /// * `new_class_hash` - The new class hash to upgrade to\\n /// * `selector` - The selector to call\\n /// * `data` - The data to pass to the function\\n ///\\n /// # Returns\\n ///\\n /// * `Span<felt252>` - The response data from the function call\\n ///\\n /// # Events\\n ///\\n /// * `Upgraded` - Emitted when the contract is upgraded (from OpenZeppelin's\\n /// [`UpgradeableComponent`])\\n ///\\n /// @dev Only the contract itself can call this function (enforced by multisig)\\n fn upgrade_and_call(\\n ref self: TContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252>;\\n\\n // ================================== View ==========================================\\n\\n /// Get the destination configuration\\n ///\\n /// # Arguments\\n ///\\n /// * `dst_eid` - The destination EID\\n ///\\n /// # Returns\\n ///\\n /// * `DstConfig` - The destination configuration\\n fn get_dst_config(self: @TContractState, dst_eid: u32) -> DstConfig;\\n\\n /// Get the Verifier ID, used to identify the verifier\\n ///\\n /// # Returns\\n ///\\n /// * `u32` - The VID\\n fn get_vid(self: @TContractState) -> u32;\\n\\n /// Get the used hash\\n ///\\n /// # Arguments\\n ///\\n /// * `hash` - The hash\\n fn get_used_hash(self: @TContractState, hash: Bytes32) -> bool;\\n\\n /// Hash the call data\\n ///\\n /// # Arguments\\n ///\\n /// * `vid` - The VID of the call data\\n /// * `call_data` - The call data\\n /// * `expiration` - The expiration of the call data\\n ///\\n /// # Returns\\n ///\\n /// * `Bytes32` - The keccak hash of the arguments\\n fn hash_call_data(\\n self: @TContractState, vid: u32, call_data: Call, expiration: u256,\\n ) -> Bytes32;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/dvn/options.cairo\": \"//! DVN options\\n\\nuse core::byte_array::ByteArray;\\nuse core::dict::{Felt252Dict, Felt252DictEntryTrait};\\nuse core::nullable::{FromNullableResult, NullableTrait, match_nullable};\\nuse lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\nuse lz_utils::error::assert_with_byte_array;\\nuse crate::workers::dvn::errors::err_invalid_dvn_options;\\nuse crate::workers::dvn::structs::DvnOption;\\n\\n// Constants\\npub const DVN_WORKER_ID: u8 = 2;\\npub const OPTION_TYPE_PRECRIME: u8 = 1;\\n\\n/// Group DVN options by their index\\n///\\n/// # Arguments\\n/// * `options` - The DVN options in format: [worker_id][dvn_option][worker_id][dvn_option]...\\n/// where dvn_option = [option_size][dvn_idx][option_type][option]\\n/// option_size = len(dvn_idx) + len(option_type) + len(option)\\n/// worker_id: u8, dvn_idx: u8, option_size: u16, option_type: u8, option: bytes\\n///\\n/// # Returns\\n/// * `Felt252Dict<Nullable<ByteArray>>` - The grouped options and their indices\\npub fn group_dvn_options_by_idx(options: @ByteArray) -> Felt252Dict<Nullable<ByteArray>> {\\n let mut ret: Felt252Dict<Nullable<ByteArray>> = Default::default();\\n if options.len() == 0 {\\n return ret;\\n }\\n\\n let mut cursor: usize = 0;\\n\\n while cursor != options.len() {\\n let DvnOption {\\n option_size, dvn_index, option_type, option_data, cursor: new_cursor,\\n } = next_dvn_option(options, cursor);\\n let option = post_process_option(option_size, dvn_index, option_type, @option_data);\\n\\n // Get the existing entry for this dvn_index\\n let (entry, prev_value) = ret.entry(dvn_index.into());\\n\\n // Combine the new option with any existing options for this dvn_index\\n let combined_options = match match_nullable(prev_value) {\\n FromNullableResult::Null => option,\\n FromNullableResult::NotNull(existing) => {\\n let mut result = existing.unbox();\\n result.append(@option);\\n result\\n },\\n };\\n\\n // Store the combined options back in the dictionary\\n ret = entry.finalize(NullableTrait::new(combined_options));\\n cursor = new_cursor;\\n }\\n\\n ret\\n}\\n\\n/// Post-process the option - prefixes other args to the option data\\n///\\n/// # Arguments\\n///\\n/// * `option_size` - The size of the option\\n///\\n/// * `dvn_index` - The index of the DVN\\n///\\n/// * `option_type` - The type of the option (e.g. PRECRIME)\\n///\\n/// * `option_data` - The data of the option\\n///\\n/// # Returns\\n///\\n/// * [`ByteArray`] - The post-processed option\\npub fn post_process_option(\\n option_size: u16, dvn_index: u8, option_type: u8, option_data: @ByteArray,\\n) -> ByteArray {\\n let mut result: ByteArray = Default::default();\\n\\n result.append_byte(DVN_WORKER_ID);\\n result.append_u16(option_size);\\n result.append_byte(dvn_index);\\n result.append_byte(option_type);\\n result.append(option_data);\\n\\n result\\n}\\n\\n/// Decode the next DVN option from options starting from the specified cursor\\n///\\n/// # Arguments\\n///\\n/// * `options` - The DVN options byte array\\n///\\n/// * `cursor` - The cursor position to start decoding from\\n///\\n/// # Returns\\n///\\n/// * [`DvnOption`] - The decoded option type, option data, and new cursor position\\npub fn next_dvn_option(options: @ByteArray, cursor: usize) -> DvnOption {\\n // Ensure we have enough bytes to read worker id\\n assert_with_byte_array(cursor < options.len(), err_invalid_dvn_options(cursor));\\n\\n // skip dvn_id, always equal to DVN_WORKER_ID here = 2;\\n let cursor = cursor + 1;\\n\\n let (cursor, option_size) = options.read_u16(cursor);\\n assert_with_byte_array(option_size > 2, err_invalid_dvn_options(cursor));\\n\\n let (cursor, dvn_index) = options.read_u8(cursor);\\n let (cursor, option_type) = options.read_u8(cursor);\\n\\n // Calculate the length of just the option data (excluding dvn_index and option_type)\\n // option_length includes dvn_index (1 byte) + option_type (1 byte) + option data\\n let option_data_length = option_size - 2; // subtract 2 bytes for dvn_index and option_type\\n\\n // Extract the option data\\n let (final_cursor, option) = options.read_bytes(cursor, option_data_length.into());\\n\\n DvnOption { option_size, dvn_index, option_type, option_data: option, cursor: final_cursor }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/dvn/structs.cairo\": \"//! DVN structs\\n\\nuse starknet::account::Call;\\nuse starknet::secp256_trait::Signature;\\n\\n/// DVN option\\npub struct DvnOption {\\n /// Size of the option\\n pub option_size: u16,\\n /// Index of the DVN\\n pub dvn_index: u8,\\n /// Type of the option\\n pub option_type: u8,\\n /// Data of the option\\n pub option_data: ByteArray,\\n /// Cursor position\\n pub cursor: u32,\\n}\\n\\n/// Destination config\\n#[derive(Copy, Default, Drop, Serde, starknet::Store, PartialEq, Debug)]\\npub struct DstConfig {\\n /// Gas for the destination\\n pub gas: u64,\\n /// Multiplier basis points\\n pub multiplier_bps: u16,\\n /// Floor margin in USD - uses priceFeed PRICE_RATIO_DENOMINATOR\\n pub floor_margin_usd: u128,\\n}\\n\\n/// Parameters for setting the destination config\\n#[derive(Copy, Default, Drop, Serde, PartialEq, Debug)]\\npub struct SetDstConfigParams {\\n /// Destination endpoint ID\\n pub dst_eid: u32,\\n /// Destination config\\n pub config: DstConfig,\\n}\\n\\n/// Parameters for executing a job\\n#[derive(Drop, Serde, Clone)]\\npub struct ExecuteParam {\\n /// Verifier ID\\n pub vid: u32,\\n /// Call data\\n pub call_data: Call,\\n /// Expiration of the instruction\\n pub expiration: u256,\\n /// Signatures for the instruction\\n pub signatures: Span<Signature>,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/executor/errors.cairo\": \"//! Executor errors\\n\\nuse core::byte_array::ByteArray;\\nuse lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum ExecutorError {\\n /// The endpoint ID is not supported.\\n EidNotSupported,\\n /// The `lz_compose` option is invalid.\\n InvalidLzComposeOption,\\n /// The `lz_read` option is invalid.\\n InvalidLzReadOption,\\n /// The `lz_receive` option is invalid.\\n InvalidLzReceiveOption,\\n /// The native drop option is invalid.\\n InvalidNativeDropOption,\\n /// The options are invalid.\\n InvalidOptions,\\n /// The options are malformed.\\n MalformedOptions,\\n /// The native amount exceeds the cap.\\n NativeAmountExceedsCap,\\n /// No options were provided.\\n NoOptions,\\n /// The price feed is not set.\\n PriceFeedNotSet,\\n /// The `lz_compose` option is not supported.\\n UnsupportedOptionLzCompose,\\n /// The `lz_read` option is not supported.\\n UnsupportedOptionLzRead,\\n /// The `lz_receive` option is not supported.\\n UnsupportedOptionLzReceive,\\n /// The native drop option is not supported.\\n UnsupportedOptionNativeDrop,\\n /// The option type is not supported.\\n UnsupportedOptionType,\\n /// Receive with value is not supported.\\n UnsupportedReceiveWithValue,\\n /// The worker fee library is not set.\\n WorkerFeeLibNotSet,\\n /// The calldata size is zero.\\n ZeroCalldataSize,\\n /// The `lz_compose` gas is zero.\\n ZeroLzComposeGas,\\n /// The `lz_receive` gas is zero.\\n ZeroLzReceiveGas,\\n /// ERC-20 transfer failed.\\n TransferFailed,\\n /// ERC-20 approval failed.\\n ApprovalFailed,\\n}\\n\\nimpl ErrorNameImpl of Error<ExecutorError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_EXECUTOR\\\"\\n }\\n\\n fn name(self: ExecutorError) -> ByteArray {\\n match self {\\n ExecutorError::EidNotSupported => \\\"EID_NOT_SUPPORTED\\\",\\n ExecutorError::InvalidLzComposeOption => \\\"INVALID_LZ_COMPOSE_OPTION\\\",\\n ExecutorError::InvalidLzReadOption => \\\"INVALID_LZ_READ_OPTION\\\",\\n ExecutorError::InvalidLzReceiveOption => \\\"INVALID_LZ_RECEIVE_OPTION\\\",\\n ExecutorError::InvalidNativeDropOption => \\\"INVALID_NATIVE_DROP_OPTION\\\",\\n ExecutorError::InvalidOptions => \\\"INVALID_OPTIONS\\\",\\n ExecutorError::MalformedOptions => \\\"MALFORMED_OPTIONS\\\",\\n ExecutorError::NativeAmountExceedsCap => \\\"NATIVE_AMOUNT_EXCEEDS_CAP\\\",\\n ExecutorError::NoOptions => \\\"NO_OPTIONS\\\",\\n ExecutorError::PriceFeedNotSet => \\\"PRICE_FEED_NOT_SET\\\",\\n ExecutorError::UnsupportedOptionLzCompose => \\\"UNSUPPORTED_OPTION_LZ_COMPOSE\\\",\\n ExecutorError::UnsupportedOptionLzRead => \\\"UNSUPPORTED_OPTION_LZ_READ\\\",\\n ExecutorError::UnsupportedOptionLzReceive => \\\"UNSUPPORTED_OPTION_LZ_RECEIVE\\\",\\n ExecutorError::UnsupportedOptionNativeDrop => \\\"UNSUPPORTED_OPTION_NATIVE_DROP\\\",\\n ExecutorError::UnsupportedOptionType => \\\"UNSUPPORTED_OPTION_TYPE\\\",\\n ExecutorError::UnsupportedReceiveWithValue => \\\"UNSUPPORTED_RECEIVE_WITH_VALUE\\\",\\n ExecutorError::WorkerFeeLibNotSet => \\\"WORKER_FEELIB_NOT_SET\\\",\\n ExecutorError::ZeroCalldataSize => \\\"ZERO_CALLDATA_SIZE\\\",\\n ExecutorError::ZeroLzComposeGas => \\\"ZERO_LZ_COMPOSE_GAS\\\",\\n ExecutorError::ZeroLzReceiveGas => \\\"ZERO_LZ_RECEIVE_GAS\\\",\\n ExecutorError::TransferFailed => \\\"TRANSFER_FAILED\\\",\\n ExecutorError::ApprovalFailed => \\\"APPROVAL_FAILED\\\",\\n }\\n }\\n}\\n\\npub fn err_eid_not_supported() -> ByteArray {\\n format_error(ExecutorError::EidNotSupported, \\\"\\\")\\n}\\n\\npub fn err_price_feed_not_set() -> ByteArray {\\n format_error(ExecutorError::PriceFeedNotSet, \\\"\\\")\\n}\\n\\npub fn err_worker_fee_lib_not_set() -> ByteArray {\\n format_error(ExecutorError::WorkerFeeLibNotSet, \\\"\\\")\\n}\\n\\npub fn err_no_options() -> ByteArray {\\n format_error(ExecutorError::NoOptions, \\\"\\\")\\n}\\n\\npub fn err_malformed_options() -> ByteArray {\\n format_error(ExecutorError::MalformedOptions, \\\"\\\")\\n}\\n\\npub fn err_unsupported_option_lz_receive() -> ByteArray {\\n format_error(ExecutorError::UnsupportedOptionLzReceive, \\\"\\\")\\n}\\n\\npub fn err_unsupported_receive_with_value() -> ByteArray {\\n format_error(ExecutorError::UnsupportedReceiveWithValue, \\\"\\\")\\n}\\n\\npub fn err_unsupported_option_native_drop() -> ByteArray {\\n format_error(ExecutorError::UnsupportedOptionNativeDrop, \\\"\\\")\\n}\\n\\npub fn err_unsupported_option_lz_compose() -> ByteArray {\\n format_error(ExecutorError::UnsupportedOptionLzCompose, \\\"\\\")\\n}\\n\\npub fn err_zero_lz_compose_gas() -> ByteArray {\\n format_error(ExecutorError::ZeroLzComposeGas, \\\"\\\")\\n}\\n\\npub fn err_unsupported_option_lz_read() -> ByteArray {\\n format_error(ExecutorError::UnsupportedOptionLzRead, \\\"\\\")\\n}\\n\\npub fn err_unsupported_option_type() -> ByteArray {\\n format_error(ExecutorError::UnsupportedOptionType, \\\"\\\")\\n}\\n\\npub fn err_invalid_options() -> ByteArray {\\n format_error(ExecutorError::InvalidOptions, \\\"\\\")\\n}\\n\\npub fn err_native_amount_exceeds_cap() -> ByteArray {\\n format_error(ExecutorError::NativeAmountExceedsCap, \\\"\\\")\\n}\\n\\npub fn err_zero_lz_receive_gas() -> ByteArray {\\n format_error(ExecutorError::ZeroLzReceiveGas, \\\"\\\")\\n}\\n\\npub fn err_zero_calldata_size() -> ByteArray {\\n format_error(ExecutorError::ZeroCalldataSize, \\\"\\\")\\n}\\n\\npub fn err_invalid_lz_receive_option() -> ByteArray {\\n format_error(ExecutorError::InvalidLzReceiveOption, \\\"\\\")\\n}\\n\\npub fn err_invalid_native_drop_option() -> ByteArray {\\n format_error(ExecutorError::InvalidNativeDropOption, \\\"\\\")\\n}\\n\\npub fn err_invalid_lz_compose_option() -> ByteArray {\\n format_error(ExecutorError::InvalidLzComposeOption, \\\"\\\")\\n}\\n\\npub fn err_invalid_lz_read_option() -> ByteArray {\\n format_error(ExecutorError::InvalidLzReadOption, \\\"\\\")\\n}\\n\\npub fn err_transfer_failed() -> ByteArray {\\n format_error(ExecutorError::TransferFailed, \\\"\\\")\\n}\\n\\npub fn err_approval_failed() -> ByteArray {\\n format_error(ExecutorError::ApprovalFailed, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/executor/events.cairo\": \"//! Executor events\\n\\nuse starknet::ContractAddress;\\nuse crate::Origin;\\nuse crate::workers::executor::structs::{NativeDropParams, SetDstConfigParams};\\n\\n/// Emitted when a destination configuration is set or updated.\\n/// @dev Triggered by the `set_dst_config` function.\\n#[derive(Drop, starknet::Event)]\\npub struct DstConfigSet {\\n /// The destination configurations that were set.\\n pub dst_config_set: Span<SetDstConfigParams>,\\n}\\n\\n/// Emitted when a native token drop is applied.\\n/// @dev Triggered by the `_apply_native_drop` internal function.\\n#[derive(Drop, starknet::Event)]\\npub struct NativeDropApplied {\\n /// The origin information of the message.\\n #[key]\\n pub origin: Origin,\\n /// The destination endpoint ID.\\n #[key]\\n pub dst_eid: u32,\\n /// The OApp that received the native drop.\\n #[key]\\n pub oapp: ContractAddress,\\n /// The parameters for the native drop.\\n pub native_drop_params: Array<NativeDropParams>,\\n /// An array indicating the success of each native drop.\\n pub success: Array<bool>,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/executor/executor.cairo\": \"//! Executor contract\\n\\n/// # Executor contract\\n///\\n/// This contract is responsible for executing LayerZero messages and native token drops.\\n/// It also provides a quote function for the worker to use when assigning a job.\\n#[starknet::contract]\\npub mod Executor {\\n use core::num::traits::Zero;\\n use core::panics::panic_with_byte_array;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::accesscontrol::AccessControlComponent;\\n use openzeppelin::access::accesscontrol::interface::IAccessControl;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::introspection::src5::SRC5Component;\\n use openzeppelin::security::ReentrancyGuardComponent;\\n use openzeppelin::security::pausable::PausableComponent;\\n use openzeppelin::token::erc20::interface::{\\n IERC20Dispatcher, IERC20DispatcherTrait, IERC20SafeDispatcher, IERC20SafeDispatcherTrait,\\n };\\n use openzeppelin::upgrades::upgradeable::UpgradeableComponent;\\n use starknet::storage::{\\n Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess,\\n StoragePointerWriteAccess,\\n };\\n use starknet::{ClassHash, ContractAddress, SyscallResultTrait};\\n use crate::Origin;\\n use crate::common::conversions::FeltArrayIntoByteArrayImpl;\\n use crate::endpoint::interfaces::endpoint_v2::{\\n IEndpointV2Dispatcher, IEndpointV2DispatcherTrait, IEndpointV2SafeDispatcher,\\n IEndpointV2SafeDispatcherTrait,\\n };\\n use crate::endpoint::messaging_composer::interface::{\\n IMessagingComposerSafeDispatcher, IMessagingComposerSafeDispatcherTrait,\\n };\\n use crate::workers::base::base::WorkerBaseComponent;\\n use crate::workers::base::errors::err_role_renouncing_disabled;\\n use crate::workers::base::structs::QuoteParams;\\n use crate::workers::executor::errors::{\\n err_approval_failed, err_price_feed_not_set, err_worker_fee_lib_not_set,\\n };\\n use crate::workers::executor::events::{DstConfigSet, NativeDropApplied};\\n use crate::workers::executor::fee_lib::interface::{\\n FeeParams, IExecutorFeeLibDispatcher, IExecutorFeeLibDispatcherTrait,\\n };\\n use crate::workers::executor::interface::IExecutor;\\n use crate::workers::executor::structs::{\\n ComposeParams, DstConfig, ExecuteParams, NativeDropParams, SetDstConfigParams,\\n };\\n use crate::workers::interface::ILayerZeroWorker;\\n\\n ////////////////\\n // Components //\\n ////////////////\\n\\n // Base worker component\\n component!(path: WorkerBaseComponent, storage: worker_base, event: WorkerBaseEvent);\\n\\n // Access control components\\n component!(path: AccessControlComponent, storage: access_control, event: AccessControlEvent);\\n component!(path: SRC5Component, storage: src5, event: SRC5Event);\\n\\n // Upgradeable component\\n component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);\\n\\n /// Declares the reentrancy guard component which provides:\\n /// - Reentrancy guard to prevent reentrancy attacks during transaction execution,\\n /// similar to the nonReentrant modifier in EVM implementations\\n component!(\\n path: ReentrancyGuardComponent, storage: reentrancy_guard, event: ReentrancyGuardEvent,\\n );\\n\\n // Pausable component\\n component!(path: PausableComponent, storage: pausable, event: PausableEvent);\\n\\n // Ownable component\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n\\n ////////////////\\n // Embeddings //\\n ////////////////\\n\\n #[abi(embed_v0)]\\n impl WorkerBaseImpl = WorkerBaseComponent::WorkerBaseImpl<ContractState>;\\n impl WorkerBaseInternalImpl = WorkerBaseComponent::InternalImpl<ContractState>;\\n\\n impl AccessControlInternalImpl = AccessControlComponent::InternalImpl<ContractState>;\\n\\n #[abi(embed_v0)]\\n impl PausableImpl = PausableComponent::PausableImpl<ContractState>;\\n impl PausableInternalImpl = PausableComponent::InternalImpl<ContractState>;\\n\\n /// Upgradeable component internal implementation\\n impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;\\n\\n /// Implements the reentrancy guard component which provides:\\n /// - Reentrancy guard to prevent reentrancy attacks during transaction execution,\\n /// similar to the nonReentrant modifier in EVM implementations\\n impl ReentrancyGuardInternalImpl = ReentrancyGuardComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n #[substorage(v0)]\\n worker_base: WorkerBaseComponent::Storage,\\n #[substorage(v0)]\\n reentrancy_guard: ReentrancyGuardComponent::Storage,\\n #[substorage(v0)]\\n access_control: AccessControlComponent::Storage,\\n #[substorage(v0)]\\n src5: SRC5Component::Storage,\\n #[substorage(v0)]\\n pausable: PausableComponent::Storage,\\n #[substorage(v0)]\\n upgradeable: UpgradeableComponent::Storage,\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n /// A map of destination endpoint IDs to their configurations.\\n dst_configs: Map<u32, DstConfig>,\\n /// The address of the LayerZero EndpointV2 contract.\\n endpoint: ContractAddress,\\n /// The address of the native token contract.\\n native_token_address: ContractAddress,\\n /// The endpoint ID of the current chain.\\n eid: u32,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n #[flat]\\n WorkerBaseEvent: WorkerBaseComponent::Event,\\n #[flat]\\n ReentrancyGuardEvent: ReentrancyGuardComponent::Event,\\n #[flat]\\n AccessControlEvent: AccessControlComponent::Event,\\n #[flat]\\n SRC5Event: SRC5Component::Event,\\n #[flat]\\n UpgradeableEvent: UpgradeableComponent::Event,\\n #[flat]\\n PausableEvent: PausableComponent::Event,\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n /// Executor-specific events\\n DstConfigSet: DstConfigSet,\\n NativeDropApplied: NativeDropApplied,\\n }\\n\\n #[constructor]\\n fn constructor(\\n ref self: ContractState,\\n endpoint: ContractAddress,\\n message_libs: Array<ContractAddress>,\\n price_feed: ContractAddress,\\n default_multiplier_bps: u16,\\n role_admin: ContractAddress,\\n admins: Array<ContractAddress>,\\n native_token_address: ContractAddress,\\n ) {\\n self.eid.write(IEndpointV2Dispatcher { contract_address: endpoint }.get_eid());\\n\\n self.access_control.initializer();\\n\\n // Initialize base worker\\n self\\n .worker_base\\n .initializer(message_libs, price_feed, default_multiplier_bps, role_admin, admins);\\n\\n // Initialize addresses\\n self.endpoint.write(endpoint);\\n self.native_token_address.write(native_token_address);\\n }\\n\\n #[abi(embed_v0)]\\n impl ExecutorImpl of IExecutor<ContractState> {\\n // ================================== Only Default Admin ===============================\\n\\n /// Pause the contract (only default admin)\\n fn pause(ref self: ContractState) {\\n self.worker_base._assert_only_default_admin();\\n self.pausable.pause();\\n }\\n\\n /// Unpause the contract (only default admin)\\n fn unpause(ref self: ContractState) {\\n self.worker_base._assert_only_default_admin();\\n self.pausable.unpause();\\n }\\n\\n fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {\\n self.worker_base._assert_only_default_admin();\\n self.upgradeable.upgrade(new_class_hash);\\n }\\n\\n fn upgrade_and_call(\\n ref self: ContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252> {\\n self.worker_base._assert_only_default_admin();\\n self.upgradeable.upgrade_and_call(new_class_hash, selector, calldata)\\n }\\n\\n // ================================== Only Admin =====================================\\n\\n fn set_dst_config(ref self: ContractState, params: Array<SetDstConfigParams>) {\\n self.worker_base._assert_only_admin();\\n\\n let dst_config_set = params.span();\\n for param in params.into_iter() {\\n self.dst_configs.write(param.dst_eid, param.config);\\n }\\n\\n self.emit(DstConfigSet { dst_config_set });\\n }\\n\\n fn execute(ref self: ContractState, params: ExecuteParams) {\\n self.worker_base._assert_only_admin();\\n self.reentrancy_guard.start();\\n self._execute(params);\\n self.reentrancy_guard.end();\\n }\\n\\n fn compose(ref self: ContractState, params: ComposeParams) {\\n self.worker_base._assert_only_admin();\\n self.reentrancy_guard.start();\\n self._compose(params);\\n self.reentrancy_guard.end();\\n }\\n\\n fn native_drop(\\n ref self: ContractState,\\n origin: Origin,\\n oapp: ContractAddress,\\n native_drop_params: Array<NativeDropParams>,\\n ) {\\n self.worker_base._assert_only_admin();\\n self._native_drop(origin, oapp, native_drop_params);\\n }\\n\\n fn native_drop_and_execute(\\n ref self: ContractState,\\n native_drop_params: Array<NativeDropParams>,\\n execute_params: ExecuteParams,\\n ) {\\n self.worker_base._assert_only_admin();\\n self.reentrancy_guard.start();\\n self\\n ._native_drop(\\n execute_params.origin.clone(), execute_params.receiver, native_drop_params,\\n );\\n self._execute(execute_params);\\n self.reentrancy_guard.end();\\n }\\n\\n // ================================== View ==========================================\\n\\n fn get_dst_config(self: @ContractState, dst_eid: u32) -> DstConfig {\\n self.dst_configs.read(dst_eid)\\n }\\n\\n fn get_endpoint(self: @ContractState) -> ContractAddress {\\n self.endpoint.read()\\n }\\n\\n fn get_native_token_address(self: @ContractState) -> ContractAddress {\\n self.native_token_address.read()\\n }\\n\\n fn get_eid(self: @ContractState) -> u32 {\\n self.eid.read()\\n }\\n }\\n\\n #[abi(embed_v0)]\\n impl LayerZeroWorkerImpl of ILayerZeroWorker<ContractState> {\\n // ================================== Only Message Lib =====================================\\n\\n /// This executor implementation does not require any additional steps beyond providing\\n /// the quote when assigning a job\\n fn assign_job(ref self: ContractState, params: QuoteParams) -> u256 {\\n self.pausable.assert_not_paused();\\n self.worker_base._assert_only_message_lib();\\n self.worker_base._assert_sender_allowed(params.sender);\\n self._quote(params)\\n }\\n\\n // ================================== View =====================================\\n\\n fn quote(self: @ContractState, params: QuoteParams) -> u256 {\\n self.pausable.assert_not_paused();\\n self.worker_base._assert_sender_allowed(params.sender);\\n self._quote(params)\\n }\\n }\\n\\n /// Access control implementation - same as OpenZeppelin except `renounce_role` is disabled\\n #[abi(embed_v0)]\\n pub impl AccessControlImpl of IAccessControl<ContractState> {\\n fn has_role(self: @ContractState, role: felt252, account: ContractAddress) -> bool {\\n self.access_control.has_role(role, account)\\n }\\n\\n fn get_role_admin(self: @ContractState, role: felt252) -> felt252 {\\n self.access_control.get_role_admin(role)\\n }\\n\\n /// Overriding the grant role function to use the worker base component\\n fn grant_role(ref self: ContractState, role: felt252, account: ContractAddress) {\\n self.worker_base._assert_only_default_admin();\\n self.worker_base._grant_role(role, account)\\n }\\n\\n /// Overriding the revoke role function to use the worker base component\\n fn revoke_role(ref self: ContractState, role: felt252, account: ContractAddress) {\\n self.worker_base._assert_only_default_admin();\\n self.worker_base._revoke_role(role, account)\\n }\\n\\n fn renounce_role(ref self: ContractState, role: felt252, account: ContractAddress) {\\n panic_with_byte_array(@err_role_renouncing_disabled())\\n }\\n }\\n\\n #[generate_trait]\\n impl InternalImpl of InternalTrait {\\n #[feature(\\\"safe_dispatcher\\\")]\\n fn _execute(ref self: ContractState, params: ExecuteParams) {\\n let ExecuteParams {\\n origin, receiver, guid, message, value, extra_data, gas_limit, ..,\\n } = params;\\n\\n let endpoint_address = self.endpoint.read();\\n\\n // Sender gives approval to the endpoint for the specified amount\\n if value > 0 {\\n let token = IERC20Dispatcher { contract_address: self.native_token_address.read() };\\n let success = token.approve(endpoint_address, value);\\n assert_with_byte_array(success, err_approval_failed());\\n }\\n\\n let endpoint = IEndpointV2SafeDispatcher { contract_address: endpoint_address };\\n if let Err(reason) = endpoint\\n .lz_receive(\\n origin.clone(), receiver, guid, message.clone(), extra_data.clone(), value,\\n ) {\\n endpoint\\n .lz_receive_alert(\\n origin, receiver, guid, gas_limit, value, message, extra_data, reason,\\n )\\n .unwrap_syscall();\\n }\\n }\\n\\n #[feature(\\\"safe_dispatcher\\\")]\\n fn _native_drop(\\n ref self: ContractState,\\n origin: Origin,\\n oapp: ContractAddress,\\n native_drop_params: Array<NativeDropParams>,\\n ) {\\n let mut success = array![];\\n\\n for params in @native_drop_params {\\n // Because the OpenZeppelin implementation of ERC-20 reverts with an error or\\n // returns `true` always on the `transfer` function call, we need to use the safe\\n // dispatcher and check the `Result` values.\\n // https://docs.openzeppelin.com/contracts-cairo/2.0.0/erc20#erc20_compatibility\\n let token = IERC20SafeDispatcher {\\n contract_address: self.native_token_address.read(),\\n };\\n\\n let res = token.transfer(*params.receiver, *params.amount);\\n success.append(res.is_ok() && res.unwrap_or(false));\\n }\\n\\n self\\n .emit(\\n NativeDropApplied {\\n origin, dst_eid: self.eid.read(), oapp, native_drop_params, success,\\n },\\n );\\n }\\n\\n #[feature(\\\"safe_dispatcher\\\")]\\n fn _compose(ref self: ContractState, params: ComposeParams) {\\n let ComposeParams {\\n sender, receiver, guid, index, message, gas_limit, extra_data, value,\\n } = params;\\n\\n let endpoint_address = self.endpoint.read();\\n\\n // Sender gives approval to the endpoint for the specified amount\\n if value > 0 {\\n let token = IERC20Dispatcher { contract_address: self.native_token_address.read() };\\n let success = token.approve(endpoint_address, value);\\n assert_with_byte_array(success, err_approval_failed());\\n }\\n\\n let composer = IMessagingComposerSafeDispatcher { contract_address: endpoint_address };\\n if let Err(reason) = composer\\n .lz_compose(\\n sender, receiver, guid, index, message.clone(), extra_data.clone(), value,\\n ) {\\n composer\\n .lz_compose_alert(\\n sender,\\n receiver,\\n guid,\\n index,\\n gas_limit,\\n value,\\n message,\\n extra_data,\\n reason,\\n )\\n .unwrap_syscall();\\n }\\n }\\n\\n /// Internal quote function without permission checks\\n fn _quote(self: @ContractState, params: QuoteParams) -> u256 {\\n let QuoteParams { dst_eid, sender, calldata_size, options, .. } = params;\\n\\n // Assert price feed is set\\n let price_feed = self.worker_base.get_price_feed();\\n assert_with_byte_array(price_feed.is_non_zero(), err_price_feed_not_set());\\n\\n // Assert worker fee lib is set\\n let worker_fee_lib_addr = self.worker_base.get_worker_fee_lib();\\n assert_with_byte_array(worker_fee_lib_addr.is_non_zero(), err_worker_fee_lib_not_set());\\n\\n let fee_params = FeeParams {\\n price_feed,\\n dst_eid,\\n sender,\\n calldata_size,\\n default_multiplier_bps: self.worker_base.get_default_multiplier_bps(),\\n };\\n\\n // Call fee lib to get the quote\\n let fee_lib = IExecutorFeeLibDispatcher { contract_address: worker_fee_lib_addr };\\n fee_lib.get_fee(fee_params, self.dst_configs.read(dst_eid), options)\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/executor/fee_lib/executor_fee_lib.cairo\": \"//! Executor Fee Library contract implementation\\n\\n/// # Executor Fee Library contract\\n///\\n/// This contract handles fee calculations for executor operations, separated from the main executor\\n/// logic to provide modularity and easier maintenance of fee-related functionality.\\n#[starknet::contract]\\npub mod ExecutorFeeLib {\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use starknet::ContractAddress;\\n use starknet::storage::StoragePointerWriteAccess;\\n use crate::common::constants::MAX_V1_EID;\\n use crate::workers::common::{\\n apply_premium_and_floor_margin, convert_and_apply_premium_to_value,\\n };\\n use crate::workers::executor::errors::{err_eid_not_supported, err_transfer_failed};\\n use crate::workers::executor::fee_lib::interface::{FeeParams, IExecutorFeeLib};\\n use crate::workers::executor::options::_decode_executor_options;\\n use crate::workers::executor::structs::DstConfig;\\n use crate::workers::price_feed::interface::{\\n ILayerZeroPriceFeedDispatcher, ILayerZeroPriceFeedDispatcherTrait,\\n };\\n\\n ////////////////\\n // Components //\\n ////////////////\\n\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n\\n ////////////////\\n // Embeddings //\\n ////////////////\\n\\n #[abi(embed_v0)]\\n impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;\\n impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;\\n\\n #[storage]\\n struct Storage {\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n /// Local endpoint ID v2\\n local_eid_v2: u32,\\n }\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n }\\n\\n #[constructor]\\n fn constructor(ref self: ContractState, local_eid_v2: u32, owner: ContractAddress) {\\n // Initialize ownable component\\n self.ownable.initializer(owner);\\n\\n // Set immutable values\\n self.local_eid_v2.write(local_eid_v2);\\n }\\n\\n #[abi(embed_v0)]\\n impl ExecutorFeeLibImpl of IExecutorFeeLib<ContractState> {\\n // ================================== Only Owner =====================================\\n\\n fn withdraw_token(\\n ref self: ContractState,\\n token_address: ContractAddress,\\n to: ContractAddress,\\n amount: u256,\\n ) {\\n self.ownable.assert_only_owner();\\n let token = IERC20Dispatcher { contract_address: token_address };\\n\\n // NOTE: (from https://docs.openzeppelin.com/contracts-cairo/2.0.0/api/erc20)\\n // transfer, transfer_from and approve will never return anything different from true\\n // because they will revert on any error.\\n let success = token.transfer(to, amount);\\n assert_with_byte_array(success, err_transfer_failed());\\n }\\n\\n // ================================== External =====================================\\n\\n fn get_fee_on_send(\\n ref self: ContractState, params: FeeParams, dst_config: DstConfig, options: ByteArray,\\n ) -> u256 {\\n self.get_fee(params, dst_config, options)\\n }\\n\\n // ================================== View =====================================\\n\\n fn get_fee(\\n self: @ContractState, params: FeeParams, dst_config: DstConfig, options: ByteArray,\\n ) -> u256 {\\n // Check if destination is supported\\n assert_with_byte_array(dst_config.lz_receive_base_gas != 0, err_eid_not_supported());\\n\\n // Decode executor options\\n let price_feed_params = _decode_executor_options(\\n false,\\n self._is_v1_eid(params.dst_eid),\\n dst_config.lz_receive_base_gas.into(),\\n dst_config.lz_compose_base_gas.into(),\\n dst_config.native_cap,\\n @options,\\n );\\n\\n // Get price feed estimate\\n let price_feed = ILayerZeroPriceFeedDispatcher { contract_address: params.price_feed };\\n let estimated_fee = price_feed\\n .estimate_fee_by_eid(\\n params.dst_eid, params.calldata_size, price_feed_params.total_gas,\\n );\\n\\n // Apply premium to gas fee\\n let mut fee = apply_premium_and_floor_margin(\\n estimated_fee.gas_fee,\\n dst_config.multiplier_bps,\\n params.default_multiplier_bps,\\n dst_config.floor_margin_usd,\\n estimated_fee.native_price_usd,\\n );\\n\\n // Apply premium to value\\n fee +=\\n convert_and_apply_premium_to_value(\\n price_feed_params.total_value,\\n estimated_fee.price_ratio,\\n estimated_fee.price_ratio_denominator,\\n dst_config.multiplier_bps,\\n params.default_multiplier_bps,\\n );\\n\\n fee\\n }\\n\\n fn version(self: @ContractState) -> (u64, u8) {\\n (1, 1)\\n }\\n }\\n\\n #[generate_trait]\\n impl InternalImpl of InternalTrait {\\n /// Check if EID is v1 (endpoint v1)\\n ///\\n /// # Arguments\\n ///\\n /// * `eid` - The endpoint ID to check\\n ///\\n /// # Returns\\n ///\\n /// * `bool` - True if the EID is of an endpoint v1, false otherwise\\n fn _is_v1_eid(self: @ContractState, eid: u32) -> bool {\\n eid < MAX_V1_EID\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/executor/fee_lib/interface.cairo\": \"//! Executor Fee Lib interface\\n\\nuse starknet::ContractAddress;\\nuse crate::workers::executor::structs::DstConfig;\\n\\n/// Fee parameters for executor fee calculation\\n#[derive(Drop, Clone, Serde)]\\npub struct FeeParams {\\n /// The address of the price feed contract\\n pub price_feed: ContractAddress,\\n /// The destination endpoint ID\\n pub dst_eid: u32,\\n /// The address of the sender\\n pub sender: ContractAddress,\\n /// The size of the calldata\\n pub calldata_size: u32,\\n /// The default multiplier basis points\\n pub default_multiplier_bps: u16,\\n}\\n\\n/// # Executor Fee Library Interface\\n///\\n/// This interface defines the standard functions for a LayerZero Executor Fee Library.\\n///\\n/// ## Key Responsibilities\\n/// 1. **Fee Calculation:** Calculating the cost of message execution on a destination chain.\\n/// The fee is determined by factors such as the destination endpoint ID (EID), the size of the\\n/// message payload, and the gas price on the destination chain, which is obtained from a price\\n/// feed.\\n/// 2. **Versioning:** Exposing its version number to allow for upgrades and compatibility checks.\\n///\\n/// The fee calculation can be performed in two ways:\\n/// - `get_fee`: A view function that returns the fee without any state changes. This is useful for\\n/// quoting.\\n/// - `get_fee_on_send`: An external function that calculates the fee and may perform state changes,\\n/// for example, to record fee-related data.\\n#[starknet::interface]\\npub trait IExecutorFeeLib<TContractState> {\\n // ================================== Only Owner =====================================\\n\\n /// Withdraws tokens from the fee library.\\n /// Enables recovery of funds accidentally sent\\n ///\\n /// # Arguments\\n /// * `token_address` - The address of the token to withdraw\\n /// * `to` - The address to send the withdrawn tokens to\\n /// * `amount` - The amount of tokens to withdraw\\n fn withdraw_token(\\n ref self: TContractState, token_address: ContractAddress, to: ContractAddress, amount: u256,\\n );\\n\\n // ================================== External =====================================\\n\\n /// Gets the fee for sending a message, potentially changing state.\\n ///\\n /// # Arguments\\n /// * `params` - The fee parameters\\n /// * `dst_config` - The destination configuration\\n /// * `options` - The message options\\n ///\\n /// # Returns\\n /// * `u256` - The calculated fee\\n fn get_fee_on_send(\\n ref self: TContractState, params: FeeParams, dst_config: DstConfig, options: ByteArray,\\n ) -> u256;\\n\\n // ================================== View =====================================\\n\\n /// Gets the fee for a message without changing state.\\n ///\\n /// # Arguments\\n /// * `params` - The fee parameters\\n /// * `dst_config` - The destination configuration\\n /// * `options` - The message options\\n ///\\n /// # Returns\\n /// * `u256` - The calculated fee\\n fn get_fee(\\n self: @TContractState, params: FeeParams, dst_config: DstConfig, options: ByteArray,\\n ) -> u256;\\n\\n /// Gets the version of the fee library.\\n ///\\n /// # Returns\\n /// * `(u64, u8)` - The major and minor version numbers\\n fn version(self: @TContractState) -> (u64, u8);\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/executor/interface.cairo\": \"//! Executor interface\\n\\nuse starknet::{ClassHash, ContractAddress};\\nuse crate::Origin;\\nuse crate::workers::executor::structs::{\\n ComposeParams, DstConfig, ExecuteParams, NativeDropParams, SetDstConfigParams,\\n};\\n\\n/// Interface for the executor contract\\n#[starknet::interface]\\npub trait IExecutor<TContractState> {\\n // ================================== Only Default Admin ===============================\\n\\n /// Pause the contract\\n fn pause(ref self: TContractState);\\n\\n /// Unpause the contract\\n fn unpause(ref self: TContractState);\\n\\n /// Upgrades the contract\\n ///\\n /// # Arguments\\n /// * `new_class_hash` - The new class hash to upgrade to\\n ///\\n /// # Events\\n /// * `Upgraded` - Emitted when the contract is upgraded (from OpenZeppelin's\\n /// [`UpgradeableComponent`])\\n ///\\n /// @dev This function is only callable by the owner.\\n fn upgrade(ref self: TContractState, new_class_hash: ClassHash);\\n\\n /// Upgrades the contract and calls a function\\n ///\\n /// # Arguments\\n /// * `new_class_hash` - The new class hash to upgrade to\\n /// * `selector` - The selector to call\\n /// * `data` - The data to pass to the function\\n ///\\n /// # Returns\\n /// * `Span<felt252>` - The response data from the function call\\n ///\\n /// # Events\\n /// * `Upgraded` - Emitted when the contract is upgraded (from OpenZeppelin's\\n /// [`UpgradeableComponent`])\\n ///\\n /// @dev This function is only callable by the owner.\\n fn upgrade_and_call(\\n ref self: TContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252>;\\n\\n // ================================== Only Admin =====================================\\n\\n /// Sets the destination configurations for one or more endpoint IDs.\\n ///\\n /// # Arguments\\n /// * `params` - An array of `SetDstConfigParams` structs, each specifying a destination EID and\\n /// its configuration.\\n ///\\n /// # Events\\n /// * `DstConfigSet` - Emitted when the destination configurations are set.\\n ///\\n /// @dev This function is only callable by the admin.\\n fn set_dst_config(ref self: TContractState, params: Array<SetDstConfigParams>);\\n\\n /// Execute a job\\n ///\\n /// # Arguments\\n /// * `params` - The execution parameters\\n ///\\n /// # Events\\n /// * `ExecuteFailed` - Emitted when the job execution fails\\n ///\\n /// @dev This function is only callable by the admin.\\n fn execute(ref self: TContractState, params: ExecuteParams);\\n\\n /// Compose a message\\n ///\\n /// # Arguments\\n /// * `params` - The composition parameters\\n ///\\n /// # Events\\n /// * `ComposeFailed` - Emitted when the message composition fails\\n ///\\n /// @dev This function is only callable by the admin.\\n fn compose(ref self: TContractState, params: ComposeParams);\\n\\n /// Drop native tokens to receivers.\\n ///\\n /// # Arguments\\n /// * `origin` - The message origin\\n /// * `oapp` - The OApp address\\n /// * `native_drop_params` - The native drop parameters.\\n ///\\n /// # Events\\n /// * `NativeDropFailed` - Emitted when the native drop fails\\n ///\\n /// @dev This function is only callable by the admin.\\n fn native_drop(\\n ref self: TContractState,\\n origin: Origin,\\n oapp: ContractAddress,\\n native_drop_params: Array<NativeDropParams>,\\n );\\n\\n /// Drop native tokens to receivers and execute a message.\\n ///\\n /// # Arguments\\n /// * `native_drop_params` - The native drop parameters.\\n /// * `execute_params` - The execution parameters.\\n ///\\n /// # Events\\n /// * `NativeDropFailed` - Emitted when the native drop fails\\n /// * `ExecuteFailed` - Emitted when the job execution fails\\n ///\\n /// @dev This function is only callable by the admin.\\n fn native_drop_and_execute(\\n ref self: TContractState,\\n native_drop_params: Array<NativeDropParams>,\\n execute_params: ExecuteParams,\\n );\\n\\n // ================================== View ==========================================\\n\\n /// Get the destination configuration\\n ///\\n /// # Arguments\\n /// * `dst_eid` - The destination endpoint ID\\n ///\\n /// # Returns\\n /// * `DstConfig` - The destination configuration\\n ///\\n /// @dev This function is only callable by anyone.\\n fn get_dst_config(self: @TContractState, dst_eid: u32) -> DstConfig;\\n\\n /// Get the endpoint address\\n ///\\n /// # Returns\\n /// * `ContractAddress` - The endpoint address\\n ///\\n /// @dev This function is only callable by anyone.\\n fn get_endpoint(self: @TContractState) -> ContractAddress;\\n\\n /// Get the native token address\\n ///\\n /// # Returns\\n /// * `ContractAddress` - The native token address\\n ///\\n /// @dev This function is only callable by anyone.\\n fn get_native_token_address(self: @TContractState) -> ContractAddress;\\n\\n /// Get the endpoint ID\\n ///\\n /// # Returns\\n /// * `u32` - The endpoint ID\\n ///\\n /// @dev This function is only callable by anyone.\\n fn get_eid(self: @TContractState) -> u32;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/executor/options.cairo\": \"//! Executor options\\n\\nuse core::byte_array::{ByteArray, ByteArrayTrait};\\nuse lz_utils::byte_array_ext::byte_array_ext::ByteArrayTraitExt;\\nuse lz_utils::error::assert_with_byte_array;\\nuse crate::workers::executor::errors;\\nuse crate::workers::executor::structs::{\\n ExecutorOption, LzComposeOption, LzReadOption, LzReceiveOption, NativeDropOption,\\n};\\n\\n// Constants\\npub const OPTION_TYPE_LZRECEIVE: u8 = 1;\\npub const OPTION_TYPE_NATIVE_DROP: u8 = 2;\\npub const OPTION_TYPE_LZCOMPOSE: u8 = 3;\\npub const OPTION_TYPE_ORDERED_EXECUTION: u8 = 4;\\npub const OPTION_TYPE_LZREAD: u8 = 5;\\n\\npub const EXECUTOR_WORKER_ID: u8 = 1;\\n\\n// This struct holds the aggregated values from parsing the executor options.\\n#[derive(Default, Drop, Serde, Debug)]\\npub struct ExecutorOptionsAggregated {\\n // The total native value to be sent with the message.\\n pub total_value: u128,\\n // The total gas limit for the message execution.\\n pub total_gas: u128,\\n // A flag indicating if ordered execution is requested.\\n pub ordered: bool,\\n // The number of `lz_compose` options.\\n pub num_lz_compose: u32,\\n // The size of the calldata.\\n pub calldata_size: u32,\\n // The gas for `lzReceive`.\\n pub lz_receive_gas: u128,\\n}\\n\\n// This struct holds the decoded/calculated values needed for quoting.\\n#[derive(Copy, Drop, Serde, Debug, PartialEq)]\\npub struct PriceFeedParams {\\n // The total native value to be sent with the message.\\n pub total_value: u256,\\n // The total gas limit for the message execution.\\n pub total_gas: u256,\\n // The size of the calldata.\\n pub calldata_size: u32,\\n}\\n\\npub fn _decode_executor_options(\\n is_read: bool,\\n is_v1_eid: bool,\\n lz_receive_base_gas: u256,\\n lz_compose_base_gas: u256,\\n native_cap: u128,\\n options: @ByteArray,\\n) -> PriceFeedParams {\\n let parsed_options = _parse_options_to_array(options);\\n let agg_options = _aggregate_options(parsed_options.span(), is_read, is_v1_eid, native_cap);\\n\\n // lz receive only called once\\n // lz compose can be called multiple times, based on unique index\\n // to simplify the quoting, we add lzComposeBaseGas for each lzComposeOption received\\n // if the same index has multiple compose options, the gas will be added multiple times\\n let mut total_gas: u256 = lz_receive_base_gas\\n + agg_options.total_gas.into()\\n + lz_compose_base_gas * agg_options.num_lz_compose.into();\\n if agg_options.ordered {\\n total_gas = (total_gas * 102) / 100;\\n }\\n\\n PriceFeedParams {\\n total_value: agg_options.total_value.into(),\\n total_gas: total_gas,\\n calldata_size: agg_options.calldata_size,\\n }\\n}\\n\\n\\npub fn _parse_options_to_array(options_bytes: @ByteArray) -> Array<ExecutorOption> {\\n assert_with_byte_array(options_bytes.len() > 0, errors::err_no_options());\\n\\n let mut options_arr = array![];\\n let mut cursor: usize = 0;\\n let total_len = options_bytes.len();\\n\\n while cursor != total_len {\\n assert_with_byte_array(cursor < total_len, errors::err_malformed_options());\\n // skip worker id\\n cursor += 1;\\n\\n let (cursor_after_len, option_len_total_u16) = options_bytes.read_u16(cursor);\\n let option_len_total: usize = option_len_total_u16.into();\\n cursor = cursor_after_len;\\n\\n // ensure we have at least one byte for the option type\\n assert_with_byte_array(cursor < total_len, errors::err_malformed_options());\\n let (cursor_after_type, option_type) = options_bytes.read_u8(cursor);\\n cursor = cursor_after_type;\\n\\n // option_len_total includes the type byte; payload length excludes it\\n assert_with_byte_array(option_len_total > 0, errors::err_malformed_options());\\n let option_len: usize = option_len_total - 1;\\n\\n let option_data_start_offset = cursor;\\n // ensure payload fits within the total buffer\\n assert_with_byte_array(\\n option_data_start_offset + option_len <= total_len, errors::err_malformed_options(),\\n );\\n\\n if option_type == OPTION_TYPE_LZRECEIVE {\\n let lz_receive_option = _read_lz_receive_option(\\n options_bytes, option_data_start_offset, option_len,\\n );\\n options_arr.append(ExecutorOption::LzReceive(lz_receive_option));\\n } else if option_type == OPTION_TYPE_NATIVE_DROP {\\n let native_drop_option = _read_native_drop_option(\\n options_bytes, option_data_start_offset, option_len,\\n );\\n options_arr.append(ExecutorOption::NativeDrop(native_drop_option));\\n } else if option_type == OPTION_TYPE_LZCOMPOSE {\\n let lz_compose_option = _read_lz_compose_option(\\n options_bytes, option_data_start_offset, option_len,\\n );\\n options_arr.append(ExecutorOption::LzCompose(lz_compose_option));\\n } else if option_type == OPTION_TYPE_ORDERED_EXECUTION {\\n options_arr.append(ExecutorOption::OrderedExecution);\\n } else {\\n assert_with_byte_array(\\n option_type == OPTION_TYPE_LZREAD, errors::err_unsupported_option_type(),\\n );\\n let lz_read_option = _read_lz_read_option(\\n options_bytes, option_data_start_offset, option_len,\\n );\\n options_arr.append(ExecutorOption::LzRead(lz_read_option));\\n }\\n cursor = option_data_start_offset + option_len;\\n }\\n\\n options_arr\\n}\\n\\n// equivalent to _parseExecutorOptions in ExecutorFeeLib.sol\\npub fn _aggregate_options(\\n options_span: Span<ExecutorOption>, is_read: bool, is_v1_eid: bool, native_cap: u128,\\n) -> ExecutorOptionsAggregated {\\n let mut options = ExecutorOptionsAggregated {\\n total_value: 0,\\n total_gas: 0,\\n ordered: false,\\n num_lz_compose: 0,\\n calldata_size: 0,\\n lz_receive_gas: 0,\\n };\\n\\n let mut temp_options = options_span;\\n while let Option::Some(option) = temp_options.pop_front() {\\n match option {\\n ExecutorOption::LzReceive(lz_receive_option) => {\\n assert_with_byte_array(!is_read, errors::err_unsupported_option_lz_receive());\\n assert_with_byte_array(\\n !is_v1_eid || *lz_receive_option.value == 0,\\n errors::err_unsupported_receive_with_value(),\\n );\\n options.total_value += *lz_receive_option.value;\\n options.lz_receive_gas += *lz_receive_option.gas;\\n },\\n ExecutorOption::NativeDrop(native_drop_option) => {\\n assert_with_byte_array(!is_read, errors::err_unsupported_option_native_drop());\\n options.total_value += *native_drop_option.amount;\\n },\\n ExecutorOption::LzCompose(lz_compose_option) => {\\n assert_with_byte_array(!is_v1_eid, errors::err_unsupported_option_lz_compose());\\n assert_with_byte_array(\\n *lz_compose_option.gas > 0, errors::err_zero_lz_compose_gas(),\\n );\\n options.total_value += *lz_compose_option.value;\\n options.total_gas += *lz_compose_option.gas;\\n options.num_lz_compose += 1;\\n },\\n ExecutorOption::OrderedExecution => { options.ordered = true; },\\n ExecutorOption::LzRead(lz_read_option) => {\\n assert_with_byte_array(is_read, errors::err_unsupported_option_lz_read());\\n options.total_value += *lz_read_option.value;\\n options.lz_receive_gas += *lz_read_option.gas;\\n options.calldata_size += *lz_read_option.size;\\n },\\n }\\n }\\n\\n assert_with_byte_array(\\n options.total_value <= native_cap, errors::err_native_amount_exceeds_cap(),\\n );\\n assert_with_byte_array(options.lz_receive_gas > 0, errors::err_zero_lz_receive_gas());\\n if is_read {\\n assert_with_byte_array(options.calldata_size > 0, errors::err_zero_calldata_size());\\n }\\n options.total_gas += options.lz_receive_gas;\\n options\\n}\\n\\n// Decoding helper functions\\npub fn _read_lz_receive_option(b: @ByteArray, offset: usize, len: usize) -> LzReceiveOption {\\n assert_with_byte_array(len == 16 || len == 32, errors::err_invalid_lz_receive_option());\\n let (offset, gas) = b.read_u128(offset);\\n let value = if len == 32 {\\n let (_, value) = b.read_u128(offset);\\n value\\n } else {\\n 0\\n };\\n LzReceiveOption { gas, value }\\n}\\n\\npub fn _read_native_drop_option(b: @ByteArray, offset: usize, len: usize) -> NativeDropOption {\\n assert_with_byte_array(len == 48, errors::err_invalid_native_drop_option());\\n let (offset, amount) = b.read_u128(offset);\\n let (_, receiver) = b.read_u256(offset);\\n NativeDropOption { amount, receiver: receiver.into() }\\n}\\n\\npub fn _read_lz_compose_option(b: @ByteArray, offset: usize, len: usize) -> LzComposeOption {\\n assert_with_byte_array(len == 18 || len == 34, errors::err_invalid_lz_compose_option());\\n let (offset, index) = b.read_u16(offset);\\n let (offset, gas) = b.read_u128(offset);\\n let value = if len == 34 {\\n let (_, value) = b.read_u128(offset);\\n value\\n } else {\\n 0\\n };\\n LzComposeOption { index, gas, value }\\n}\\n\\npub fn _read_lz_read_option(b: @ByteArray, offset: usize, len: usize) -> LzReadOption {\\n assert_with_byte_array(len == 20 || len == 36, errors::err_invalid_lz_read_option());\\n let (offset, gas) = b.read_u128(offset);\\n let (offset, size) = b.read_u32(offset);\\n let value = if len == 36 {\\n let (_, value) = b.read_u128(offset);\\n value\\n } else {\\n 0\\n };\\n LzReadOption { gas, size, value }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/executor/structs.cairo\": \"//! Executor structs\\n\\nuse lz_utils::bytes::Bytes32;\\nuse starknet::ContractAddress;\\nuse crate::Origin;\\n\\n#[derive(Copy, Drop, Serde, starknet::Store, PartialEq, Default, Debug)]\\npub struct DstConfig {\\n /// The base gas for `lz_receive`\\n pub lz_receive_base_gas: u64,\\n /// The gas multiplier in basis points\\n pub multiplier_bps: u16,\\n /// The floor margin in USD (uses priceFeed PRICE_RATIO_DENOMINATOR)\\n pub floor_margin_usd: u128,\\n /// The native token cap\\n pub native_cap: u128,\\n /// The base gas for `lz_compose`\\n pub lz_compose_base_gas: u64,\\n}\\n\\n#[derive(Copy, Drop, Serde, PartialEq)]\\npub struct SetDstConfigParams {\\n /// The destination endpoint ID\\n pub dst_eid: u32,\\n /// The destination configuration\\n pub config: DstConfig,\\n}\\n\\n#[derive(Drop, Serde, Clone)]\\npub struct ExecuteParams {\\n /// The address of the receiver contract\\n pub receiver: ContractAddress,\\n /// The origin information of the message\\n pub origin: Origin,\\n /// The globally unique identifier for the message\\n pub guid: Bytes32,\\n /// The amount of native tokens to be sent with the message\\n pub value: u256,\\n /// The message payload\\n pub message: ByteArray,\\n /// The gas limit for the execution\\n pub gas_limit: u256,\\n /// Extra data for the execution\\n pub extra_data: ByteArray,\\n}\\n\\n#[derive(Drop, Serde, Clone)]\\npub struct ComposeParams {\\n /// The address of the receiver contract\\n pub receiver: ContractAddress,\\n /// The address of the sender contract\\n pub sender: ContractAddress,\\n /// The globally unique identifier for the message\\n pub guid: Bytes32,\\n /// The index for composing messages\\n pub index: u16,\\n /// The amount of native tokens to be sent with the message\\n pub value: u256,\\n /// The message payload\\n pub message: ByteArray,\\n /// Extra data for composing the message\\n pub extra_data: ByteArray,\\n /// The gas limit for the composition\\n pub gas_limit: u256,\\n}\\n\\n#[derive(Drop, Serde)]\\npub enum ExecutorOption {\\n LzReceive: LzReceiveOption,\\n NativeDrop: NativeDropOption,\\n LzCompose: LzComposeOption,\\n OrderedExecution,\\n LzRead: LzReadOption,\\n}\\n\\n#[derive(Debug, Drop, Serde, Clone)]\\npub struct LzReceiveOption {\\n /// The gas limit for `lz_receive`\\n pub gas: u128,\\n /// The native token value to be sent with `lz_receive`\\n pub value: u128,\\n}\\n\\n#[derive(Drop, Serde, Clone)]\\npub struct NativeDropOption {\\n /// The amount of native tokens to drop\\n pub amount: u128,\\n /// The recipient address for the native drop\\n pub receiver: Bytes32,\\n}\\n\\n/// Native drop parameters.\\n#[derive(Drop, Serde, Clone)]\\npub struct NativeDropParams {\\n /// Amount of the native tokens\\n pub amount: u256,\\n /// Receiver of the native tokens\\n pub receiver: ContractAddress,\\n}\\n\\n#[derive(Debug, Drop, Serde, Clone)]\\npub struct LzComposeOption {\\n /// The index for composing messages\\n pub index: u16,\\n /// The gas limit for `lz_compose`\\n pub gas: u128,\\n /// The native token value to be sent with `lz_compose`\\n pub value: u128,\\n}\\n\\n#[derive(Drop, Serde, Clone)]\\npub struct LzReadOption {\\n /// The gas limit for the read operation\\n pub gas: u128,\\n /// The size of the data to be read\\n pub size: u32,\\n /// The native token value to be sent with the read operation\\n pub value: u128,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/interface.cairo\": \"//! ILayerZeroWorker interface used by the DVN and Executor workers\\n\\nuse crate::workers::base::structs::QuoteParams;\\n\\n#[starknet::interface]\\npub trait ILayerZeroWorker<TContractState> {\\n // ================================== Only Message Lib =====================================\\n\\n /// Assign a job\\n ///\\n /// # Arguments\\n /// * `params` - Parameters for assigning a job\\n ///\\n /// # Returns\\n /// * `u256` - The fee for the job\\n ///\\n /// @dev This function is only callable by message libs.\\n fn assign_job(ref self: TContractState, params: QuoteParams) -> u256;\\n\\n // ================================== View =====================================\\n\\n /// Quote the fee for a job\\n ///\\n /// # Arguments\\n /// * `params` - Parameters for quoting the fee\\n ///\\n /// # Returns\\n /// * `u256` - The fee for the job\\n ///\\n /// @dev This function is callable by anyone.\\n fn quote(self: @TContractState, params: QuoteParams) -> u256;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/price_feed/constants.cairo\": \"//! Price feed constants\\n\\n/// Price ratio denominator (10^20)\\npub const PRICE_RATIO_DENOMINATOR: u128 = 100_000_000_000_000_000_000_u128;\\n\\n/// Arbitrum compression percent\\npub const ARBITRUM_COMPRESSION_PERCENT: u32 = 47;\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/price_feed/errors.cairo\": \"use lz_utils::error::{Error, format_error};\\n\\n#[derive(Drop)]\\npub enum PriceFeedError {\\n OnlyPriceUpdater,\\n NotAnOpStack,\\n PriceRatioDenominatorZero,\\n TransferFailed,\\n}\\n\\nimpl ErrorNameImpl of Error<PriceFeedError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_PRICE_FEED\\\"\\n }\\n\\n fn name(self: PriceFeedError) -> ByteArray {\\n match self {\\n PriceFeedError::OnlyPriceUpdater => \\\"ONLY_PRICE_UPDATER\\\",\\n PriceFeedError::NotAnOpStack => \\\"NOT_AN_OP_STACK\\\",\\n PriceFeedError::PriceRatioDenominatorZero => \\\"PRICE_RATIO_DENOMINATOR_ZERO\\\",\\n PriceFeedError::TransferFailed => \\\"TRANSFER_FAILED\\\",\\n }\\n }\\n}\\n\\npub fn err_lz_price_feed_only_price_updater() -> ByteArray {\\n format_error(PriceFeedError::OnlyPriceUpdater, \\\"\\\")\\n}\\n\\npub fn err_lz_pricefeed_not_an_op_stack() -> ByteArray {\\n format_error(PriceFeedError::NotAnOpStack, \\\"\\\")\\n}\\n\\npub fn err_price_ratio_denominator_zero() -> ByteArray {\\n format_error(PriceFeedError::PriceRatioDenominatorZero, \\\"\\\")\\n}\\n\\npub fn err_transfer_failed() -> ByteArray {\\n format_error(PriceFeedError::TransferFailed, \\\"\\\")\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/price_feed/events.cairo\": \"//! Price feed events\\n\\nuse starknet::ContractAddress;\\n\\n/// Event emitted when fees are withdrawn\\n#[derive(Drop, starknet::Event)]\\npub struct FeeWithdrawn {\\n #[key]\\n pub token_address: ContractAddress,\\n #[key]\\n pub to: ContractAddress,\\n pub amount: u256,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/price_feed/interface.cairo\": \"//! Price feed worker interface\\n\\nuse starknet::{ClassHash, ContractAddress};\\nuse crate::workers::price_feed::structs::{\\n ArbitrumPriceExt, GetFeeResponse, ModelType, Price, SetEidToModelTypeParam, SetPriceParam,\\n UpdatePriceExt,\\n};\\n\\n/// Interface for the price feed worker\\n#[starknet::interface]\\npub trait IPriceFeed<TContractState> {\\n // ===================================== Only Owner =====================================\\n\\n /// Set the price updater\\n ///\\n /// # Arguments\\n ///\\n /// * `address`: The address of the price updater\\n /// * `active`: Whether the price updater is active\\n ///\\n /// @dev This function is only callable by the owner\\n fn set_price_updater(ref self: TContractState, address: ContractAddress, active: bool);\\n\\n /// Set EIDs to model types\\n ///\\n /// # Arguments\\n ///\\n /// * `params`: The parameters to set the EIDs to model types\\n ///\\n /// @dev This function is only callable by the owner\\n fn set_eid_to_model_type(ref self: TContractState, params: Array<SetEidToModelTypeParam>);\\n\\n /// Upgrade the contract\\n ///\\n /// # Arguments\\n ///\\n /// * `new_class_hash`: The class hash of the new contract\\n ///\\n /// @dev This function is only callable by the owner\\n fn upgrade(ref self: TContractState, new_class_hash: ClassHash);\\n\\n /// Upgrade the contract and call a function\\n ///\\n /// # Arguments\\n ///\\n /// * `new_class_hash` - The new class hash to upgrade to\\n /// * `selector` - The selector to call\\n /// * `data` - The data to pass to the function\\n ///\\n /// # Returns\\n ///\\n /// * `Span<felt252>` - The response data from the function call\\n ///\\n /// # Events\\n ///\\n /// * `Upgraded` - Emitted when the contract is upgraded (from OpenZeppelin's\\n /// [`UpgradeableComponent`])\\n ///\\n /// @dev This function is only callable by the owner\\n fn upgrade_and_call(\\n ref self: TContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252>;\\n\\n /// Set the price ratio denominator\\n ///\\n /// # Arguments\\n ///\\n /// * `denominator`: The price ratio denominator\\n ///\\n /// @dev This function is only callable by the owner\\n fn set_price_ratio_denominator(ref self: TContractState, denominator: u128);\\n\\n /// Set the arbitrum compression percent\\n ///\\n /// # Arguments\\n ///\\n /// * `compression_percent`: The arbitrum compression percent\\n ///\\n /// @dev This function is only callable by the owner\\n fn set_arbitrum_compression_percent(ref self: TContractState, compression_percent: u32);\\n\\n /// Set the endpoint address\\n ///\\n /// # Arguments\\n ///\\n /// * `endpoint`: The endpoint address\\n ///\\n /// @dev This function is only callable by the owner\\n fn set_endpoint(ref self: TContractState, endpoint: ContractAddress);\\n\\n /// Withdraw collected fees\\n ///\\n /// # Arguments\\n ///\\n /// * `token_address`: The address of the token to withdraw\\n /// * `to`: The address to withdraw the fees to\\n /// * `amount`: The amount of fees to withdraw\\n ///\\n /// @dev This function is only callable by the owner\\n fn withdraw_fee(\\n ref self: TContractState, token_address: ContractAddress, to: ContractAddress, amount: u256,\\n );\\n\\n // ========================= Only Price Updater or Owner ==================================\\n\\n /// Set the price for a given EID\\n ///\\n /// # Arguments\\n ///\\n /// * `params`: The parameters to set the price\\n ///\\n /// @dev This function is only callable by the price updater or owner\\n fn set_price(ref self: TContractState, params: Array<SetPriceParam>);\\n\\n /// Set the arbitrum price for a given EID\\n ///\\n /// # Arguments\\n ///\\n /// * `update`: The parameters to set the arbitrum price\\n ///\\n /// @dev This function is only callable by the price updater or owner\\n fn set_price_for_arbitrum(ref self: TContractState, update: UpdatePriceExt);\\n\\n /// Set the native price in USD\\n ///\\n /// # Arguments\\n ///\\n /// * `price`: The native price in USD\\n ///\\n /// @dev This function is only callable by the price updater or owner\\n fn set_native_price_usd(ref self: TContractState, price: u128);\\n\\n // ======================================= View ========================================\\n\\n /// Get the arbitrum price ext for a given endpoint ID\\n ///\\n /// # Arguments\\n ///\\n /// * `eid`: The endpoint ID of the destination chain\\n ///\\n /// # Returns\\n ///\\n /// `ArbitrumPriceExt` - The arbitrum price ext for the given EID\\n fn get_price_arbitrum_ext(self: @TContractState, eid: u32) -> ArbitrumPriceExt;\\n\\n /// Get the price updater for a given address\\n ///\\n /// # Arguments\\n ///\\n /// * `address`: The address of the price updater\\n ///\\n /// # Returns\\n ///\\n /// `bool` - Whether the price updater is active\\n fn get_price_updater(self: @TContractState, address: ContractAddress) -> bool;\\n\\n /// Get the model type for a given endpoint ID\\n ///\\n /// # Arguments\\n ///\\n /// * `eid`: The endpoint ID of the destination chain\\n ///\\n /// # Returns\\n ///\\n /// `ModelType` - The model type\\n fn get_eid_to_model_type(self: @TContractState, eid: u32) -> ModelType;\\n\\n /// Get the arbitrum compression percent\\n ///\\n /// # Returns\\n ///\\n /// `u32` - The arbitrum compression percent\\n fn get_arbitrum_compression_percent(self: @TContractState) -> u32;\\n\\n /// Get the endpoint address\\n ///\\n /// # Returns\\n ///\\n /// `ContractAddress` - The endpoint address\\n fn get_endpoint(self: @TContractState) -> ContractAddress;\\n}\\n\\n/// Interface for the LayerZero price feed\\n#[starknet::interface]\\npub trait ILayerZeroPriceFeed<TContractState> {\\n // ============================ View =====================================\\n\\n /// Get the native price in USD\\n ///\\n /// # Returns\\n ///\\n /// `u128` - The native price in USD\\n fn native_price_usd(self: @TContractState) -> u128;\\n\\n /// Get the fee to be paid to the price feed\\n ///\\n /// # Arguments\\n ///\\n /// * `dst_eid`: The endpoint ID of the destination chain\\n /// * `calldata_size`: The size of the call data\\n /// * `gas`: The gas used\\n ///\\n /// # Returns\\n ///\\n /// `u256` - The fee to be paid to the price feed\\n fn get_fee(self: @TContractState, dst_eid: u32, calldata_size: u256, gas: u256) -> u256;\\n\\n /// Get the price for a given EID\\n ///\\n /// # Arguments\\n ///\\n /// * `eid`: The endpoint ID of the destination chain\\n ///\\n /// # Returns\\n ///\\n /// `Price` - The price for the given EID\\n fn get_price(self: @TContractState, eid: u32) -> Price;\\n\\n /// Get the price ratio denominator\\n ///\\n /// # Returns\\n ///\\n /// `u128` - The price ratio denominator\\n fn get_price_ratio_denominator(self: @TContractState) -> u128;\\n\\n /// Estimate the fee for a given EID, call data size, and gas\\n ///\\n /// # Arguments\\n ///\\n /// * `dst_eid`: The endpoint ID of the destination chain\\n /// * `calldata_size`: The size of the call data\\n /// * `gas`: The gas used\\n ///\\n /// # Returns\\n ///\\n /// * `GetFeeResponse` - The fee estimate for the given EID, call data size, and gas\\n fn estimate_fee_by_eid(\\n self: @TContractState, dst_eid: u32, calldata_size: u32, gas: u256,\\n ) -> GetFeeResponse;\\n\\n // ============================ External =====================================\\n\\n /// Estimate the fee on send for a given EID, call data size, and gas\\n ///\\n /// # Arguments\\n ///\\n /// * `dst_eid`: The endpoint ID of the destination chain\\n /// * `calldata_size`: The size of the call data\\n /// * `gas`: The gas used\\n ///\\n /// # Returns\\n ///\\n /// * `GetFeeResponse` - The fee estimate for the given EID, call data size, and gas\\n fn estimate_fee_on_send(\\n ref self: TContractState, dst_eid: u32, calldata_size: u32, gas: u256,\\n ) -> GetFeeResponse;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/price_feed/price_feed.cairo\": \"//! Price feed component implementation\\n\\n#[starknet::contract]\\npub mod PriceFeed {\\n use core::num::traits::Zero;\\n use lz_utils::error::assert_with_byte_array;\\n use openzeppelin::access::ownable::OwnableComponent;\\n use openzeppelin::token::erc20::interface::{IERC20Dispatcher, IERC20DispatcherTrait};\\n use openzeppelin::upgrades::upgradeable::UpgradeableComponent;\\n use starknet::storage::{\\n Map, StorageMapReadAccess, StorageMapWriteAccess, StoragePointerReadAccess,\\n StoragePointerWriteAccess,\\n };\\n use starknet::{ClassHash, ContractAddress, get_caller_address};\\n use crate::common::constants::MAX_V1_EID;\\n use crate::workers::price_feed::constants::{\\n ARBITRUM_COMPRESSION_PERCENT, PRICE_RATIO_DENOMINATOR,\\n };\\n use crate::workers::price_feed::errors::{\\n err_lz_price_feed_only_price_updater, err_lz_pricefeed_not_an_op_stack,\\n err_price_ratio_denominator_zero, err_transfer_failed,\\n };\\n use crate::workers::price_feed::events::FeeWithdrawn;\\n use crate::workers::price_feed::interface::{ILayerZeroPriceFeed, IPriceFeed};\\n use crate::workers::price_feed::structs::{\\n ArbitrumPriceExt, FeeEstimate, GetFeeResponse, ModelType, Price, SetEidToModelTypeParam,\\n SetPriceParam, UpdatePriceExt,\\n };\\n\\n // ================================ Constants =============================================\\n\\n /// Ethereum Mainnet EID\\n pub const ETHEREUM_MAINNET_EID: u32 = 101;\\n\\n /// Ethereum Goerli V1 EID\\n pub const ETHEREUM_GOERLI_V1_EID: u32 = 10121;\\n\\n /// Ethereum Goerli V2 EID\\n pub const ETHEREUM_GOERLI_V2_EID: u32 = 20121;\\n\\n /// Ethereum Sepolia EID\\n pub const ETHEREUM_SEPOLIA_EID: u32 = 10161;\\n\\n /// Optimism L1 overhead\\n pub const OP_L1_OVERHEAD: u32 = 3188;\\n\\n // ================================ Components =============================================\\n\\n // Ownable component\\n component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);\\n\\n // Upgradeable component\\n component!(path: UpgradeableComponent, storage: upgradeable, event: UpgradeableEvent);\\n\\n // Ownable Mixin\\n #[abi(embed_v0)]\\n impl OwnableImpl = OwnableComponent::OwnableImpl<ContractState>;\\n impl OwnableInternalImpl = OwnableComponent::InternalImpl<ContractState>;\\n\\n /// Upgradeable component internal implementation\\n impl UpgradeableInternalImpl = UpgradeableComponent::InternalImpl<ContractState>;\\n\\n // =============================== Storage =================================\\n\\n #[storage]\\n struct Storage {\\n #[substorage(v0)]\\n ownable: OwnableComponent::Storage,\\n #[substorage(v0)]\\n upgradeable: UpgradeableComponent::Storage,\\n // Native Price in USD\\n native_price_usd: u128,\\n // Price Updater => Active\\n price_updater: Map<ContractAddress, bool>,\\n // Eid => Price\\n default_model_price: Map<u32, Price>,\\n // Eid => ModelType\\n eid_to_model_type: Map<u32, ModelType>,\\n // Arbitrum Price Ext\\n arbitrum_price_ext: ArbitrumPriceExt,\\n // Price Ratio Denominator\\n price_ratio_denominator: u128,\\n // Arbitrum Compression Percent\\n arbitrum_compression_percent: u32,\\n // EndpointV2 address\\n endpoint: ContractAddress,\\n }\\n\\n // =============================== Events =================================\\n\\n #[event]\\n #[derive(Drop, starknet::Event)]\\n pub enum Event {\\n #[flat]\\n OwnableEvent: OwnableComponent::Event,\\n #[flat]\\n UpgradeableEvent: UpgradeableComponent::Event,\\n FeeWithdrawn: FeeWithdrawn,\\n }\\n\\n #[constructor]\\n fn constructor(\\n ref self: ContractState, owner: ContractAddress, price_updater: ContractAddress,\\n ) {\\n // Initialize Ownable\\n self.ownable.initializer(owner);\\n\\n // Initialize Price Updater\\n self.price_updater.write(price_updater, true);\\n\\n // Set price ratio denominator\\n self.price_ratio_denominator.write(PRICE_RATIO_DENOMINATOR);\\n\\n // Set arbitrum compression percent\\n self.arbitrum_compression_percent.write(ARBITRUM_COMPRESSION_PERCENT);\\n }\\n\\n #[abi(embed_v0)]\\n impl PriceFeedImpl of IPriceFeed<ContractState> {\\n // ===================================== Only Owner =====================================\\n\\n fn set_price_updater(ref self: ContractState, address: ContractAddress, active: bool) {\\n self.ownable.assert_only_owner();\\n self.price_updater.write(address, active);\\n }\\n\\n fn set_eid_to_model_type(ref self: ContractState, params: Array<SetEidToModelTypeParam>) {\\n self.ownable.assert_only_owner();\\n for param in params {\\n self.eid_to_model_type.write(param.eid, param.model_type);\\n }\\n }\\n\\n fn upgrade(ref self: ContractState, new_class_hash: ClassHash) {\\n self.ownable.assert_only_owner();\\n self.upgradeable.upgrade(new_class_hash);\\n }\\n\\n fn upgrade_and_call(\\n ref self: ContractState,\\n new_class_hash: ClassHash,\\n selector: felt252,\\n calldata: Span<felt252>,\\n ) -> Span<felt252> {\\n self.ownable.assert_only_owner();\\n self.upgradeable.upgrade_and_call(new_class_hash, selector, calldata)\\n }\\n\\n fn set_price_ratio_denominator(ref self: ContractState, denominator: u128) {\\n assert_with_byte_array(denominator.is_non_zero(), err_price_ratio_denominator_zero());\\n self.ownable.assert_only_owner();\\n self.price_ratio_denominator.write(denominator);\\n }\\n\\n fn set_arbitrum_compression_percent(ref self: ContractState, compression_percent: u32) {\\n self.ownable.assert_only_owner();\\n self.arbitrum_compression_percent.write(compression_percent);\\n }\\n\\n fn set_endpoint(ref self: ContractState, endpoint: ContractAddress) {\\n self.ownable.assert_only_owner();\\n self.endpoint.write(endpoint);\\n }\\n\\n fn withdraw_fee(\\n ref self: ContractState,\\n token_address: ContractAddress,\\n to: ContractAddress,\\n amount: u256,\\n ) {\\n self.ownable.assert_only_owner();\\n let token = IERC20Dispatcher { contract_address: token_address };\\n let success = token.transfer(to, amount);\\n assert_with_byte_array(success, err_transfer_failed());\\n self.emit(FeeWithdrawn { token_address, to, amount });\\n }\\n\\n // ========================= Only Price Updater or Owner ==================================\\n\\n fn set_price(ref self: ContractState, params: Array<SetPriceParam>) {\\n self._only_price_updater_or_owner();\\n for param in params.into_iter() {\\n self.default_model_price.write(param.eid, param.price);\\n }\\n }\\n\\n fn set_price_for_arbitrum(ref self: ContractState, update: UpdatePriceExt) {\\n self._only_price_updater_or_owner();\\n self.default_model_price.write(update.eid, update.price);\\n self.arbitrum_price_ext.write(update.extend);\\n }\\n\\n fn set_native_price_usd(ref self: ContractState, price: u128) {\\n self._only_price_updater_or_owner();\\n self.native_price_usd.write(price);\\n }\\n\\n // ===================================== View =================================\\n\\n fn get_price_arbitrum_ext(self: @ContractState, eid: u32) -> ArbitrumPriceExt {\\n self.arbitrum_price_ext.read()\\n }\\n\\n fn get_price_updater(self: @ContractState, address: ContractAddress) -> bool {\\n self.price_updater.read(address)\\n }\\n\\n fn get_eid_to_model_type(self: @ContractState, eid: u32) -> ModelType {\\n self.eid_to_model_type.read(eid)\\n }\\n\\n fn get_arbitrum_compression_percent(self: @ContractState) -> u32 {\\n self.arbitrum_compression_percent.read()\\n }\\n\\n fn get_endpoint(self: @ContractState) -> ContractAddress {\\n self.endpoint.read()\\n }\\n }\\n\\n #[abi(embed_v0)]\\n impl LayerZeroPriceFeedImpl of ILayerZeroPriceFeed<ContractState> {\\n fn native_price_usd(self: @ContractState) -> u128 {\\n self.native_price_usd.read()\\n }\\n\\n fn get_fee(self: @ContractState, dst_eid: u32, calldata_size: u256, gas: u256) -> u256 {\\n 0\\n }\\n\\n fn get_price(self: @ContractState, eid: u32) -> Price {\\n self.default_model_price.read(eid)\\n }\\n\\n fn get_price_ratio_denominator(self: @ContractState) -> u128 {\\n self.price_ratio_denominator.read()\\n }\\n\\n fn estimate_fee_by_eid(\\n self: @ContractState, dst_eid: u32, calldata_size: u32, gas: u256,\\n ) -> GetFeeResponse {\\n self._estimate_fee_by_eid(dst_eid, calldata_size, gas)\\n }\\n\\n // ============================ External =====================================\\n\\n fn estimate_fee_on_send(\\n ref self: ContractState, dst_eid: u32, calldata_size: u32, gas: u256,\\n ) -> GetFeeResponse {\\n self._estimate_fee_by_eid(dst_eid, calldata_size, gas)\\n }\\n }\\n\\n // internal\\n #[generate_trait]\\n impl InternalImpl of InternalTrait {\\n fn _only_price_updater_or_owner(self: @ContractState) {\\n let caller = get_caller_address();\\n let is_owner_or_price_updater = caller == self.ownable.owner()\\n || self.price_updater.read(caller);\\n\\n assert_with_byte_array(\\n is_owner_or_price_updater, err_lz_price_feed_only_price_updater(),\\n );\\n }\\n\\n /// Estimates fee with default model\\n ///\\n /// @param dst_eid The destination EID\\n /// @param calldata_size The size of the call data\\n /// @param gas The gas used\\n /// @return The gas fee and the price ratio\\n fn _estimate_fee_with_default_model(\\n self: @ContractState, dst_eid: u32, calldata_size: u32, gas: u256,\\n ) -> FeeEstimate {\\n let remote_price = self.default_model_price.read(dst_eid);\\n\\n // Calculate fee on the destination chain and convert it to the source chain's token.\\n // 1. `gas_for_call_data`: Gas cost for the message payload on the destination chain.\\n // 2. `remote_fee`: Total fee in the destination chain's native token (e.g., wei).\\n // It's `(calldata_gas + execution_gas) * gas_price`.\\n // 3. `gas_fee`: The `remote_fee` converted to the source chain's native token.\\n let gas_for_call_data: u256 = calldata_size.into() * remote_price.gas_per_byte.into();\\n let remote_fee: u256 = (gas_for_call_data + gas)\\n * remote_price.gas_price_in_unit.into();\\n let gas_fee = (remote_fee * remote_price.price_ratio.into())\\n / self.price_ratio_denominator.read().into();\\n\\n FeeEstimate { gas_fee, price_ratio: remote_price.price_ratio }\\n }\\n\\n fn _estimate_fee_with_arbitrum_model(\\n self: @ContractState, dst_eid: u32, calldata_size: u32, gas: u256,\\n ) -> FeeEstimate {\\n let arbitrum_price = self.default_model_price.read(dst_eid);\\n let arbitrum_price_ext = self.arbitrum_price_ext.read();\\n\\n // L1 fee\\n let gas_for_l1_call_data: u256 = ((calldata_size.into()\\n * self.arbitrum_compression_percent.read().into())\\n / 100)\\n * arbitrum_price_ext.gas_per_l1_call_data_byte.into();\\n\\n // L2 Fee\\n let gas_for_l2_call_data: u256 = calldata_size.into()\\n * arbitrum_price.gas_per_byte.into();\\n let total_gas = gas\\n + arbitrum_price_ext.gas_per_l2_tx.into()\\n + gas_for_l1_call_data\\n + gas_for_l2_call_data;\\n let gas_fee = total_gas * arbitrum_price.gas_price_in_unit.into();\\n let gas_fee = (gas_fee * arbitrum_price.price_ratio.into())\\n / self.price_ratio_denominator.read().into();\\n\\n FeeEstimate { gas_fee, price_ratio: arbitrum_price.price_ratio }\\n }\\n\\n fn _estimate_fee_with_optimism_model(\\n self: @ContractState, dst_eid: u32, calldata_size: u32, gas: u256,\\n ) -> FeeEstimate {\\n let ethereum_id = self._get_l1_lookup_id_for_optimism_model(dst_eid);\\n\\n // L1 fee\\n let ethereum_price = self.default_model_price.read(ethereum_id);\\n let gas_for_l1_call_data: u256 = (calldata_size.into()\\n * ethereum_price.gas_per_byte.into())\\n + OP_L1_OVERHEAD.into();\\n let l1_fee: u256 = gas_for_l1_call_data * ethereum_price.gas_price_in_unit.into();\\n\\n // L2 fee\\n let optimism_price = self.default_model_price.read(dst_eid);\\n let gas_for_l2_call_data: u256 = calldata_size.into()\\n * optimism_price.gas_per_byte.into();\\n let total_gas = gas_for_l2_call_data + gas;\\n let l2_fee = total_gas * optimism_price.gas_price_in_unit.into();\\n\\n let l1_fee_in_src_price = (l1_fee * ethereum_price.price_ratio.into())\\n / self.price_ratio_denominator.read().into();\\n let l2_fee_in_src_price = (l2_fee * optimism_price.price_ratio.into())\\n / self.price_ratio_denominator.read().into();\\n let gas_fee = l1_fee_in_src_price + l2_fee_in_src_price;\\n\\n FeeEstimate { gas_fee, price_ratio: optimism_price.price_ratio }\\n }\\n\\n fn _get_l1_lookup_id_for_optimism_model(self: @ContractState, l2_eid: u32) -> u32 {\\n let l2_eid = l2_eid % MAX_V1_EID;\\n if l2_eid == 111 {\\n return ETHEREUM_MAINNET_EID;\\n } else if l2_eid == 10132 {\\n return ETHEREUM_GOERLI_V1_EID;\\n } else if l2_eid == 20132 {\\n return ETHEREUM_GOERLI_V2_EID;\\n }\\n\\n assert_with_byte_array(\\n self.eid_to_model_type.read(l2_eid) == ModelType::OP_STACK,\\n err_lz_pricefeed_not_an_op_stack(),\\n );\\n\\n if l2_eid < 10000 {\\n ETHEREUM_MAINNET_EID\\n } else if l2_eid < 20000 {\\n ETHEREUM_SEPOLIA_EID\\n } else {\\n ETHEREUM_GOERLI_V2_EID\\n }\\n }\\n\\n fn _estimate_fee_by_eid(\\n self: @ContractState, dst_eid: u32, calldata_size: u32, gas: u256,\\n ) -> GetFeeResponse {\\n let dst_eid = dst_eid % MAX_V1_EID;\\n\\n let model_type = self.eid_to_model_type.read(dst_eid);\\n let FeeEstimate {\\n gas_fee, price_ratio,\\n } =\\n match model_type {\\n ModelType::ARB_STACK => self\\n ._estimate_fee_with_arbitrum_model(dst_eid, calldata_size, gas),\\n ModelType::OP_STACK => self\\n ._estimate_fee_with_optimism_model(dst_eid, calldata_size, gas),\\n ModelType::DEFAULT => self\\n ._estimate_fee_with_default_model(dst_eid, calldata_size, gas),\\n };\\n\\n GetFeeResponse {\\n gas_fee,\\n price_ratio,\\n price_ratio_denominator: self.price_ratio_denominator.read(),\\n native_price_usd: self.native_price_usd.read(),\\n }\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/src/workers/price_feed/structs.cairo\": \"//! Price feed structs\\n\\n/// Fee estimate\\n#[derive(Drop, Serde, Default, PartialEq, Debug)]\\npub struct FeeEstimate {\\n pub gas_fee: u256,\\n pub price_ratio: u128,\\n}\\n\\n/// Response for a fee estimation\\n#[derive(Drop, Serde, Default, PartialEq, Debug)]\\npub struct GetFeeResponse {\\n pub gas_fee: u256,\\n pub price_ratio: u128,\\n pub price_ratio_denominator: u128,\\n pub native_price_usd: u128,\\n}\\n\\n/// Price for a given EID\\n#[derive(Drop, Serde, starknet::Store, Default, PartialEq, Clone, Debug)]\\npub struct Price {\\n /// Conversion multiplier used to translate the destination chain's native token value\\n /// into the source chain's native token units.\\n ///\\n /// This is a fixed-point number encoded as a `u128`, where the float value is scaled\\n /// by 10^20 for precision (i.e., 1.0 = 10^20).\\n ///\\n /// The `price_ratio` incorporates two factors:\\n /// 1. Decimal normalization between destination and source tokens.\\n /// 2. The actual relative price (exchange rate) between the two tokens.\\n ///\\n /// For example, if the source is an EVM chain (18 decimals) and the destination is Aptos (8\\n /// decimals), with a 1:1 token price, the base multiplier would be (10^18 / 10^8) = 10^10.\\n /// To represent this in fixed-point form, you multiply by 10^20, giving a `price_ratio` of\\n /// 10^30.\\n ///\\n /// In real usage, `price_ratio` reflects both decimal scaling and fluctuating market prices.\\n pub price_ratio: u128,\\n pub gas_price_in_unit: u64, // for evm, it is in wei, for aptos, it is in octas.\\n pub gas_per_byte: u32,\\n}\\n\\n#[derive(Drop, Serde, Default, PartialEq)]\\npub struct SetEidToModelTypeParam {\\n pub eid: u32,\\n pub model_type: ModelType,\\n}\\n\\n#[derive(Drop, Serde, Default, PartialEq)]\\npub struct SetPriceParam {\\n pub eid: u32,\\n pub price: Price,\\n}\\n\\n#[derive(Drop, Serde, starknet::Store, Default, PartialEq, Clone, Debug)]\\npub struct ArbitrumPriceExt {\\n pub gas_per_l2_tx: u64,\\n pub gas_per_l1_call_data_byte: u32,\\n}\\n\\n#[derive(Drop, Serde, Default, PartialEq, Clone)]\\npub struct UpdatePriceExt {\\n pub eid: u32,\\n pub price: Price,\\n pub extend: ArbitrumPriceExt,\\n}\\n\\n#[derive(Drop, Serde, starknet::Store, Default, PartialEq, Debug)]\\npub enum ModelType {\\n #[default]\\n DEFAULT,\\n OP_STACK,\\n ARB_STACK,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/layerzero/Scarb.toml\": \"[package]\\nname = \\\"layerzero\\\"\\nversion = \\\"0.1.0\\\"\\nedition = \\\"2024_07\\\"\\n\\n# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html\\n\\n[features]\\ngas_profile = []\\n\\n[dependencies]\\nstarknet = \\\"2.14.0\\\"\\nopenzeppelin = \\\"2.0.0\\\"\\nlz_utils = { path = \\\"../libs/lz_utils\\\" }\\nenumerable_set = { path = \\\"../libs/enumerable_set\\\" }\\nmultisig = { path = \\\"../libs/multisig\\\" }\\n\\n[dev-dependencies]\\nsnforge_std = \\\"0.49.0\\\"\\nassert_macros = \\\"2.12.0\\\"\\nstarkware_utils_testing = { git = \\\"https://github.com/starkware-libs/starkware-starknet-utils\\\", rev = \\\"e1955423808045de868987b8fb0b43f5cbdf5699\\\" }\\n\\n[lib]\\n\\n[[target.starknet-contract]]\\nsierra = true\\ncasm = true\\n\\n[scripts]\\ntest = \\\"snforge test\\\"\\n\\n[tool.scarb]\\nallow-prebuilt-plugins = [\\\"snforge_scarb_plugin\\\", \\\"snforge_std\\\"]\\n\\n[profile.dev.cairo]\\nunstable-add-statements-functions-debug-info = true\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/enumerable_set/src/enumerable_set.cairo\": \"use core::hash::Hash;\\nuse core::num::traits::Zero;\\nuse core::pedersen::HashState;\\nuse starknet::storage::{\\n Map, Mutable, StorageMapReadAccess, StorageMapWriteAccess, StoragePath,\\n StoragePointerReadAccess, StoragePointerWriteAccess,\\n};\\n\\n/// `EnumerableSet` struct for managing a set of values with efficient\\n/// add, remove, lookup and list operations\\n#[starknet::storage_node]\\npub struct EnumerableSet<T, +starknet::Store<T>, +Hash<T, HashState>> {\\n pub count: u32,\\n // slot(1-based index) to element\\n pub slot_to_element: Map<u32, T>,\\n // element to slot(1-based index)\\n pub element_to_slot: Map<T, u32>,\\n}\\n\\n#[generate_trait]\\npub impl EnumerableSetImpl<\\n T, +starknet::Store<T>, +Hash<T, HashState>, +PartialEq<T>, +Drop<T>, +Zero<T>, +Copy<T>,\\n> of EnumerableSetTrait<T> {\\n /// Adds an element to the set. Returns true if the element was added,\\n /// false if it was already present\\n fn add(self: StoragePath<Mutable<EnumerableSet<T>>>, element: T) -> bool {\\n if self.contains_mut(element) {\\n return false;\\n }\\n\\n let slot = self.count.read() + 1;\\n self.slot_to_element.write(slot, element);\\n self.element_to_slot.write(element, slot);\\n self.count.write(slot);\\n\\n true\\n }\\n\\n /// Removes an element from the set. Returns true if the element was removed,\\n /// false if it wasn't present\\n fn remove(self: StoragePath<Mutable<EnumerableSet<T>>>, element: T) -> bool {\\n // Check if exists\\n if !self.contains_mut(element) {\\n return false;\\n }\\n\\n let last_slot = self.count.read();\\n let slot = self.element_to_slot.read(element);\\n\\n if slot != last_slot {\\n // Swap element to remove with the last element\\n let last_element = self.slot_to_element.read(last_slot);\\n self.element_to_slot.write(last_element, slot);\\n self.slot_to_element.write(slot, last_element);\\n }\\n\\n // Remove the element\\n self.element_to_slot.write(element, 0);\\n self.slot_to_element.write(last_slot, Zero::zero());\\n self.count.write(last_slot - 1);\\n\\n true\\n }\\n\\n // Mutable storage function so we can use it in mutable functions\\n fn contains_mut(self: StoragePath<Mutable<EnumerableSet<T>>>, element: T) -> bool {\\n self.element_to_slot.read(element) != 0\\n }\\n\\n /// Checks if an element is in the set\\n fn contains(self: StoragePath<EnumerableSet<T>>, element: T) -> bool {\\n self.element_to_slot.read(element) != 0\\n }\\n\\n /// Returns the total number of elements in the set\\n fn length(self: StoragePath<EnumerableSet<T>>) -> u32 {\\n self.count.read()\\n }\\n\\n /// Returns all elements in the set as an array\\n /// WARNING: This assumes the count of entries is bounded. If it is unbounded, use at(i) to\\n /// manually paginate\\n fn values(self: StoragePath<EnumerableSet<T>>) -> Array<T> {\\n let mut elements: Array<T> = array![];\\n let count = self.count.read();\\n\\n for i in 1..=count {\\n let element = self.slot_to_element.read(i);\\n elements.append(element);\\n }\\n\\n elements\\n }\\n\\n /// Checks if the set is empty\\n fn is_empty(self: StoragePath<EnumerableSet<T>>) -> bool {\\n self.count.read() == 0\\n }\\n\\n /// Clears all elements from the set\\n /// WARNING: This assumes the count of entries is bounded\\n fn clear(self: StoragePath<Mutable<EnumerableSet<T>>>) {\\n let count = self.count.read();\\n\\n for i in 1..=count {\\n let element = self.slot_to_element.read(i);\\n self.element_to_slot.write(element, 0);\\n self.slot_to_element.write(i, Zero::zero());\\n }\\n\\n self.count.write(0);\\n }\\n\\n fn at(self: StoragePath<EnumerableSet<T>>, index: u32) -> T {\\n assert!(index < self.count.read(), \\\"Index out of bounds\\\");\\n self.slot_to_element.read(index + 1)\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/enumerable_set/src/lib.cairo\": \"pub mod enumerable_set;\\n\\n// Re-export commonly used types for easier access\\npub use crate::enumerable_set::{EnumerableSet, EnumerableSetImpl, EnumerableSetTrait};\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/enumerable_set/Scarb.toml\": \"[package]\\nname = \\\"enumerable_set\\\"\\nversion = \\\"0.1.0\\\"\\nedition = \\\"2024_07\\\"\\n\\n[dependencies]\\nstarknet = \\\"2.14.0\\\"\\n\\n[dev-dependencies]\\nsnforge_std = \\\"0.49.0\\\"\\nassert_macros = \\\"2.12.0\\\"\\n\\n[scripts]\\ntest = \\\"snforge test\\\"\\n\\n[tool.scarb]\\nallow-prebuilt-plugins = [\\\"snforge_scarb_plugin\\\", \\\"snforge_std\\\"]\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/multisig/src/errors.cairo\": \"use lz_utils::error::{Error, format_error};\\nuse starknet::EthAddress;\\nuse starknet::secp256_trait::Signature;\\n\\n#[derive(Drop)]\\npub enum MultisigError {\\n TotalSignersLessThanThreshold,\\n OnlyMultisig,\\n ZeroThreshold,\\n InvalidSigner,\\n SignerAlreadyAdded,\\n SignerNotFound,\\n SignatureError,\\n UnsortedSigners,\\n ThresholdGreaterThanMaxThreshold,\\n InvalidSignature,\\n}\\n\\nimpl ErrorNameImpl of Error<MultisigError> {\\n fn prefix() -> ByteArray {\\n \\\"LZ_MULTISIG\\\"\\n }\\n\\n fn name(self: MultisigError) -> ByteArray {\\n match self {\\n MultisigError::TotalSignersLessThanThreshold => \\\"TOTAL_SIGNERS_LESS_THAN_THRESHOLD\\\",\\n MultisigError::OnlyMultisig => \\\"ONLY_MULTISIG\\\",\\n MultisigError::ZeroThreshold => \\\"ZERO_THRESHOLD\\\",\\n MultisigError::InvalidSigner => \\\"INVALID_SIGNER\\\",\\n MultisigError::SignerAlreadyAdded => \\\"SIGNER_ALREADY_ADDED\\\",\\n MultisigError::SignerNotFound => \\\"SIGNER_NOT_FOUND\\\",\\n MultisigError::SignatureError => \\\"SIGNATURE_ERROR\\\",\\n MultisigError::UnsortedSigners => \\\"UNSORTED_SIGNERS\\\",\\n MultisigError::ThresholdGreaterThanMaxThreshold => \\\"THRESHOLD_GREATER_THAN_MAX_THRESHOLD\\\",\\n MultisigError::InvalidSignature => \\\"INVALID_SIGNATURE\\\",\\n }\\n }\\n}\\n\\n\\n/// Error messages for the Multisig component\\n\\npub fn err_total_signers_less_than_threshold(total_signers: u32, threshold: u32) -> ByteArray {\\n let message = format!(\\\"total_signers: {:?}, threshold: {:?}\\\", total_signers, threshold);\\n format_error(MultisigError::TotalSignersLessThanThreshold, message)\\n}\\n\\npub fn err_only_multisig() -> ByteArray {\\n format_error(MultisigError::OnlyMultisig, \\\"\\\")\\n}\\n\\npub fn err_zero_threshold() -> ByteArray {\\n format_error(MultisigError::ZeroThreshold, \\\"\\\")\\n}\\n\\npub fn err_invalid_signer() -> ByteArray {\\n format_error(MultisigError::InvalidSigner, \\\"\\\")\\n}\\n\\npub fn err_signer_already_added(signer: EthAddress) -> ByteArray {\\n format_error(MultisigError::SignerAlreadyAdded, format!(\\\"signer: {:?}\\\", signer))\\n}\\n\\npub fn err_signer_not_found(signer: EthAddress) -> ByteArray {\\n format_error(MultisigError::SignerNotFound, format!(\\\"signer: {:?}\\\", signer))\\n}\\n\\npub fn err_signature_error() -> ByteArray {\\n format_error(MultisigError::SignatureError, \\\"\\\")\\n}\\n\\npub fn err_invalid_signature(signature: @Signature) -> ByteArray {\\n format_error(MultisigError::InvalidSignature, format!(\\\"signature: {:?}\\\", signature))\\n}\\n\\npub fn err_unsorted_signers() -> ByteArray {\\n format_error(MultisigError::UnsortedSigners, \\\"\\\")\\n}\\n\\npub fn err_threshold_greater_than_max_threshold(threshold: u32) -> ByteArray {\\n format_error(\\n MultisigError::ThresholdGreaterThanMaxThreshold, format!(\\\"threshold: {:?}\\\", threshold),\\n )\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/multisig/src/events.cairo\": \"use starknet::EthAddress;\\n\\n#[derive(Drop, Debug, PartialEq, starknet::Event)]\\npub struct ThresholdSet {\\n pub threshold: u32,\\n}\\n\\n#[derive(Drop, Debug, PartialEq, starknet::Event)]\\npub struct SignerSet {\\n #[key]\\n pub signer: EthAddress,\\n pub active: bool,\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/multisig/src/interface.cairo\": \"use starknet::EthAddress;\\nuse starknet::secp256_trait::Signature;\\n\\n/// Multisig\\n/// Multisig contract interface for a multisig component\\n/// Designed to be used by contracts requiring multi-signature verification with ECDSA verification\\n/// Addresses are held as u256 integers but are converted as Bytes from the `alexandria_bytes`\\n/// crate to allow better byte manipulation\\n#[starknet::interface]\\npub trait IMultisig<TContractState> {\\n /// Allows the Multisig contract to update the signature threshold\\n /// This function can only be called by the MultiSig contract itself\\n ///\\n /// # Arguments\\n ///\\n /// * `threshold`: The new threshold for the Multisig contract\\n fn set_threshold(ref self: TContractState, threshold: u32);\\n\\n /// Gets the current signature threshold for the multisig contract\\n ///\\n /// # Returns\\n ///\\n /// * The current threshold as a u32\\n fn get_threshold(self: @TContractState) -> u32;\\n\\n /// Adds or removes a signer from this Multisig\\n /// Only callable via the Multisig contract itself\\n ///\\n /// # Arguments\\n ///\\n /// * `signer`: The address of the signer to add or remove\\n /// * `active`: True to add signer, false to remove signer\\n fn set_signer(ref self: TContractState, signer: EthAddress, active: bool);\\n\\n /// Checks if a given address is in the set of signers.\\n ///\\n /// # Arguments\\n ///\\n /// * `signer`: The address to check\\n ///\\n /// # Returns\\n ///\\n /// True if the address is in the set of signers, false otherwise.\\n fn is_signer(self: @TContractState, signer: EthAddress) -> bool;\\n\\n /// Returns the list of all active signers\\n ///\\n /// # Returns\\n /// An array of addresses representing the current set of signers.\\n fn get_signers(self: @TContractState) -> Array<EthAddress>;\\n\\n /// Returns the total number of active signers.\\n ///\\n /// # Returns\\n ///\\n /// The total number of signers currently active.\\n fn total_signers(self: @TContractState) -> u32;\\n\\n /// Verifies a list of signatures against a digest\\n ///\\n /// # Arguments\\n ///\\n /// * `digest`: The digest to verify the signatures against\\n /// * `signatures`: The list of signatures to verify\\n fn verify_signatures(self: @TContractState, digest: u256, signatures: Span<Signature>);\\n\\n /// Returns the maximum threshold for the multisig\\n ///\\n /// # Returns\\n ///\\n /// The maximum threshold for the multisig\\n fn get_max_threshold(self: @TContractState) -> u32;\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/multisig/src/lib.cairo\": \"pub mod errors;\\npub mod events;\\npub mod interface;\\npub mod multisig;\\n\\n// Re-export commonly used types for easier access\\npub use crate::multisig::MultisigComponent;\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/multisig/src/multisig.cairo\": \"#[starknet::component]\\npub mod MultisigComponent {\\n use core::integer::u256;\\n use core::num::traits::Zero;\\n use core::panics::panic_with_byte_array;\\n use enumerable_set::{EnumerableSet, EnumerableSetImpl, EnumerableSetTrait};\\n use lz_utils::error::assert_with_byte_array;\\n use starknet::eth_signature::public_key_point_to_eth_address;\\n use starknet::secp256_trait::{Signature, recover_public_key};\\n use starknet::secp256k1::Secp256k1Point;\\n use starknet::storage::{StoragePointerReadAccess, StoragePointerWriteAccess};\\n use starknet::{EthAddress, get_caller_address, get_contract_address};\\n use crate::errors::{\\n err_invalid_signature, err_invalid_signer, err_only_multisig, err_signature_error,\\n err_signer_already_added, err_signer_not_found, err_threshold_greater_than_max_threshold,\\n err_total_signers_less_than_threshold, err_unsorted_signers, err_zero_threshold,\\n };\\n use crate::events;\\n\\n\\n /// =============================== Storage =================================\\n #[storage]\\n pub struct Storage {\\n pub multisig_threshold: u32,\\n pub multisig_signer_set: EnumerableSet<EthAddress>,\\n }\\n\\n\\n /// =============================== Events =================================\\n #[event]\\n #[derive(Drop, Debug, PartialEq, starknet::Event)]\\n pub enum Event {\\n ThresholdSet: events::ThresholdSet,\\n SignerSet: events::SignerSet,\\n }\\n\\n /// =============================== Traits =================================\\n\\n /// Constants expected to be defined at the contract level used to configure the component\\n /// behaviour.\\n ///\\n /// - `MAX_THRESHOLD`: Returns the maximum threshold for the multisig.\\n pub trait ImmutableConfig {\\n const MAX_THRESHOLD: u32;\\n }\\n\\n /// =============================== External Functions =================================\\n #[embeddable_as(Multisig)]\\n impl MultisigImpl<\\n TContractState, +HasComponent<TContractState>, impl Immutable: ImmutableConfig,\\n > of crate::interface::IMultisig<ComponentState<TContractState>> {\\n fn set_threshold(ref self: ComponentState<TContractState>, threshold: u32) {\\n self._only_multisig();\\n self._set_threshold(threshold);\\n }\\n\\n // View function to get the current threshold\\n fn get_threshold(self: @ComponentState<TContractState>) -> u32 {\\n self.multisig_threshold.read()\\n }\\n\\n fn set_signer(ref self: ComponentState<TContractState>, signer: EthAddress, active: bool) {\\n self._only_multisig();\\n if active {\\n self._add_signer(signer);\\n } else {\\n self._remove_signer(signer);\\n }\\n }\\n\\n fn is_signer(self: @ComponentState<TContractState>, signer: EthAddress) -> bool {\\n self.multisig_signer_set.contains(signer)\\n }\\n\\n fn get_signers(self: @ComponentState<TContractState>) -> Array<EthAddress> {\\n self.multisig_signer_set.values()\\n }\\n\\n fn total_signers(self: @ComponentState<TContractState>) -> u32 {\\n self.multisig_signer_set.length()\\n }\\n\\n fn verify_signatures(\\n self: @ComponentState<TContractState>, digest: u256, signatures: Span<Signature>,\\n ) {\\n match self._verify_n_signatures(digest, signatures, self.multisig_threshold.read()) {\\n Ok(()) => (),\\n Err(err) => panic_with_byte_array(@err),\\n }\\n }\\n\\n fn get_max_threshold(self: @ComponentState<TContractState>) -> u32 {\\n Immutable::MAX_THRESHOLD\\n }\\n }\\n\\n\\n /// =============================== Internal Functions =================================\\n #[generate_trait]\\n pub impl MultisigInternalImpl<\\n TContractState, +HasComponent<TContractState>, impl Immutable: ImmutableConfig,\\n > of MultisigInternalTrait<TContractState> {\\n fn _init(\\n ref self: ComponentState<TContractState>, mut signers: Span<EthAddress>, threshold: u32,\\n ) {\\n for signer in signers {\\n self._add_signer(*signer);\\n }\\n self._set_threshold(threshold);\\n }\\n\\n /// Restricts access to functions so they can only be called via this contract itself\\n fn _only_multisig(self: @ComponentState<TContractState>) {\\n let multisig_address = get_contract_address();\\n let caller_address = get_caller_address();\\n assert_with_byte_array(multisig_address == caller_address, err_only_multisig());\\n }\\n\\n /// Internal function to set the threshold for this MultiSig\\n /// The threshold must be greater than zero and less than or equal to the number of signers\\n ///\\n /// # Arguments\\n ///\\n /// * `threshold`: The new threshold value\\n fn _set_threshold(ref self: ComponentState<TContractState>, threshold: u32) {\\n let current_signer_count = self.total_signers();\\n assert_with_byte_array(threshold != 0, err_zero_threshold());\\n\\n assert_with_byte_array(\\n current_signer_count >= threshold,\\n err_total_signers_less_than_threshold(current_signer_count, threshold),\\n );\\n\\n assert_with_byte_array(\\n threshold <= Immutable::MAX_THRESHOLD,\\n err_threshold_greater_than_max_threshold(threshold),\\n );\\n\\n self.multisig_threshold.write(threshold);\\n self.emit(events::ThresholdSet { threshold });\\n }\\n\\n /// Internal function to add a signer to the Multisig\\n /// - `address(0)` is not a valid signer\\n /// - A signer cannot be added twice\\n /// # Arguments\\n ///\\n /// * `signer`: The address of the signer to add\\n fn _add_signer(ref self: ComponentState<TContractState>, signer: EthAddress) {\\n assert_with_byte_array(signer != Zero::<EthAddress>::zero(), err_invalid_signer());\\n assert_with_byte_array(!self.is_signer(signer), err_signer_already_added(signer));\\n\\n self.multisig_signer_set.add(signer);\\n self.emit(events::SignerSet { signer, active: true });\\n }\\n\\n /// Internal function to remove a signer from the Multisig\\n /// - Signer must be part of the existing set of signers\\n /// - The threshold must be less than or equal to the number of remaining signers\\n /// # Arguments\\n ///\\n /// * `signer`: The address of the signer to remove\\n fn _remove_signer(ref self: ComponentState<TContractState>, signer: EthAddress) {\\n assert_with_byte_array(self.is_signer(signer), err_signer_not_found(signer));\\n let current_signer_count = self.total_signers();\\n let threshold = self.multisig_threshold.read();\\n assert_with_byte_array(\\n current_signer_count > threshold,\\n err_total_signers_less_than_threshold(current_signer_count - 1, threshold),\\n );\\n self.multisig_signer_set.remove(signer);\\n\\n self.emit(events::SignerSet { signer, active: false });\\n }\\n\\n\\n fn _verify_n_signatures(\\n self: @ComponentState<TContractState>,\\n digest: u256,\\n signatures: Span<Signature>,\\n threshold: u32,\\n ) -> Result<(), ByteArray> {\\n if threshold == 0 {\\n return Err(err_zero_threshold());\\n }\\n if signatures.len() < threshold {\\n return Err(err_signature_error());\\n }\\n\\n let mut last_signer = 0_u256;\\n for signature_index in 0..signatures.len() {\\n let signature = signatures.at(signature_index);\\n // Each call to recover_public_key consumes approximately 23,000,000 L2 gas.\\n // https://github.com/starkware-libs/sequencer/blob/667ad92c9936cdefae4191e30437fe7beaf65962/config/sequencer/default_config.json#L37\\n // https://github.com/0xSpaceShard/starknet-devnet/blob/b989e0c8c78f8e1907c7fff208d7eb873f6f6a1f/crates/starknet-devnet-core/src/utils.rs#L56\\n let public_key_point = recover_public_key::<Secp256k1Point>(digest, *signature);\\n if !public_key_point.is_some() {\\n return Err(err_invalid_signature(signature));\\n }\\n\\n let current_signer: EthAddress = public_key_point_to_eth_address(\\n public_key_point.unwrap(),\\n );\\n // EthAddress does not implement PartialOrd, so we need to convert to u256\\n let current_signer_256: u256 = Into::<_, felt252>::into(current_signer).into();\\n\\n if current_signer_256 <= last_signer {\\n return Err(err_unsorted_signers());\\n }\\n let is_signer = self.is_signer(current_signer);\\n if !is_signer {\\n return Err(err_signer_not_found(current_signer));\\n }\\n last_signer = current_signer_256;\\n }\\n Ok(())\\n }\\n }\\n}\\n\",\n \"node_modules/@layerzerolabs/protocol-starknet-v2/libs/multisig/Scarb.toml\": \"[package]\\nname = \\\"multisig\\\"\\nversion = \\\"0.1.0\\\"\\nedition = \\\"2024_07\\\"\\n\\n# See more keys and their definitions at https://docs.swmansion.com/scarb/docs/reference/manifest.html\\n\\n[dependencies]\\nstarknet = \\\"2.14.0\\\"\\nenumerable_set = { path = \\\"../enumerable_set\\\" }\\nlz_utils = { path = \\\"../lz_utils\\\" }\\n\\n[dev-dependencies]\\nsnforge_std = \\\"0.49.0\\\"\\nassert_macros = \\\"2.12.0\\\"\\nstarkware_utils_testing = { git = \\\"https://github.com/starkware-libs/starkware-starknet-utils\\\", rev = \\\"e1955423808045de868987b8fb0b43f5cbdf5699\\\" }\\n\\n[scripts]\\ntest = \\\"snforge test\\\"\\n\\n[tool.scarb]\\nallow-prebuilt-plugins = [\\\"snforge_scarb_plugin\\\", \\\"snforge_std\\\"]\\n\",\n \"Scarb.toml\": \"[workspace]\\nmembers = [\\\"contracts/*\\\"]\\n\\n\"\n },\n \"compilerVersion\": \"2.14.0\",\n \"packageName\": \"oft_mint_burn\",\n \"projectDirPath\": \".\",\n \"contractFilePath\": \"contracts/oft_mint_burn/src/lib.cairo\"\n};\n\nexport default verificationInfo;\n"]}
|