import {RpcProvider, Account, Contract} from 'starknet';
import {
getEndpointV2Contract,
getOAppContract,
encodeUlnConfig,
encodeExecutorConfig,
MessageLibConfigType,
} from '@layerzerolabs/lz-v2-protocol-starknet';
import {Options} from '@layerzerolabs/lz-v2-utilities';
import {EndpointId, ChainName, Environment} from '@layerzerolabs/lz-definitions';
import compiledArtifact from './path/to/contract_class.json';
async function configureOApp() {
const provider = new RpcProvider({nodeUrl: RPC_URL});
const account = new Account({provider, address: ACCOUNT_ADDRESS, signer: PRIVATE_KEY});
const endpoint = await getEndpointV2Contract(ChainName.STARKNET, Environment.TESTNET, provider);
const oapp = await getOAppContract(OFT_ADDRESS, provider);
const oappOptions = new Contract({
abi: compiledArtifact.abi,
address: OFT_ADDRESS,
provider,
}).typedv2(compiledArtifact.abi);
const remoteEid = EndpointId.ETHEREUM_V2_MAINNET;
const ULN_ADDRESS = '0x...'; // ULN302 send library address
// Authorize the account to configure endpoint settings (owner-only)
const setDelegateCall = oapp.populateTransaction.set_delegate(ACCOUNT_ADDRESS);
// Set libraries (required if defaults aren't configured for the EID)
const setSendLibCall = endpoint.populateTransaction.set_send_library(
OFT_ADDRESS,
remoteEid,
ULN_ADDRESS,
);
const setReceiveLibCall = endpoint.populateTransaction.set_receive_library(
OFT_ADDRESS,
remoteEid,
ULN_ADDRESS,
0,
);
// 1. Configure send DVN + Executor
const sendConfigCall = endpoint.populateTransaction.set_send_configs(OFT_ADDRESS, ULN_ADDRESS, [
{
eid: remoteEid,
config_type: MessageLibConfigType.ULN,
config: encodeUlnConfig({
confirmations: 15,
has_confirmations: true,
required_dvns: [LAYERZERO_DVN, PARTNER_DVN],
has_required_dvns: true,
optional_dvns: [],
optional_dvn_threshold: 0,
has_optional_dvns: false,
}),
},
{
eid: remoteEid,
config_type: MessageLibConfigType.EXECUTOR,
config: encodeExecutorConfig({
max_message_size: 10000,
executor: EXECUTOR_ADDRESS,
}),
},
]);
// 2. Configure receive DVN
const receiveConfigCall = endpoint.populateTransaction.set_receive_configs(
OFT_ADDRESS,
ULN_ADDRESS,
[
{
eid: remoteEid,
config_type: MessageLibConfigType.ULN,
config: encodeUlnConfig({
confirmations: 15,
has_confirmations: true,
required_dvns: [LAYERZERO_DVN],
has_required_dvns: true,
optional_dvns: [],
optional_dvn_threshold: 0,
has_optional_dvns: false,
}),
},
],
);
// 3. Set enforced options
const enforcedOptionsCall = oappOptions.populateTransaction.set_enforced_options([
{
eid: remoteEid,
msg_type: 1, // SEND message type
options: Options.newOptions().addExecutorLzReceiveOption(200000, 0).toBytes(),
},
]);
// 4. Set peer (LAST!)
const setPeerCall = oapp.populateTransaction.set_peer(remoteEid, {
value: BigInt('0x000000000000000000000000' + EVM_OFT_ADDRESS.slice(2)),
});
// Execute all in atomic transaction
await account.execute([
setDelegateCall,
setSendLibCall,
setReceiveLibCall,
sendConfigCall,
receiveConfigCall,
enforcedOptionsCall,
setPeerCall,
]);
console.log('Configuration complete!');
}